0025609: Clean up the duplicate classes in TKBO project
[occt.git] / src / BOPTest / BOPTest_CheckCommands.cxx
CommitLineData
b311480e 1// Created by: Peter KURNEV
973c2be1 2// Copyright (c) 2010-2014 OPEN CASCADE SAS
b311480e 3//
973c2be1 4// This file is part of Open CASCADE Technology software library.
b311480e 5//
d5f74e42 6// This library is free software; you can redistribute it and/or modify it under
7// the terms of the GNU Lesser General Public License version 2.1 as published
973c2be1 8// by the Free Software Foundation, with special exception defined in the file
9// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10// distribution for complete text of the license and disclaimer of any warranty.
b311480e 11//
973c2be1 12// Alternatively, this file may be used under the terms of Open CASCADE
13// commercial license or contractual agreement.
7fd59977 14
80db5701 15
42cf5bc1 16#include <BOPAlgo_ArgumentAnalyzer.hxx>
17#include <BOPAlgo_CheckerSI.hxx>
18#include <BOPAlgo_CheckResult.hxx>
80db5701 19#include <BOPDS_DS.hxx>
25dfc507 20#include <BOPDS_MapOfPair.hxx>
42cf5bc1 21#include <BOPTest.hxx>
22#include <BOPTest_Objects.hxx>
e98e3990 23#include <BOPTools_AlgoTools.hxx>
42cf5bc1 24#include <BRep_Builder.hxx>
25#include <BRepBuilderAPI_Copy.hxx>
26#include <DBRep.hxx>
27#include <Draw.hxx>
c7b59798 28#include <OSD_Timer.hxx>
42cf5bc1 29#include <TCollection_AsciiString.hxx>
30#include <TopExp_Explorer.hxx>
31#include <TopoDS_Compound.hxx>
32#include <TopoDS_Shape.hxx>
1155d05a 33#include <TopTools_ListOfShape.hxx>
42cf5bc1 34#include <TopTools_MapOfShape.hxx>
35#include <TopTools_ShapeMapHasher.hxx>
43cb0011 36
42cf5bc1 37#include <algorithm>
38#include <functional>
39#include <vector>
63def8e6 40//
7fd59977 41static
63def8e6 42 void MakeShapeForFullOutput (const TCollection_AsciiString&,
43 const Standard_Integer,
1155d05a 44 const TopTools_ListOfShape&,
63def8e6 45 Standard_Integer& ,
e98e3990 46 Draw_Interpretor&,
47 Standard_Boolean bCurveOnSurf = Standard_False,
48 Standard_Real aMaxDist = 0.,
49 Standard_Real aMaxParameter = 0.);
7fd59977 50//
63def8e6 51static Standard_Integer bopcheck (Draw_Interpretor&, Standard_Integer, const char** );
52static Standard_Integer bopargcheck(Draw_Interpretor&, Standard_Integer, const char** );
e98e3990 53static Standard_Integer xdistef(Draw_Interpretor&, Standard_Integer, const char** );
54static Standard_Integer checkcurveonsurf (Draw_Interpretor&, Standard_Integer, const char**);
7fd59977 55
56//=======================================================================
57//function : CheckCommands
58//purpose :
59//=======================================================================
63def8e6 60void BOPTest::CheckCommands(Draw_Interpretor& theCommands)
7fd59977 61{
62 static Standard_Boolean done = Standard_False;
63 if (done)
64 return;
65
66 done = Standard_True;
67 // Chapter's name
43cb0011 68 const char* g = "BOPTest commands";
7fd59977 69 //
6f31882a 70 theCommands.Add("bopcheck",
43cb0011 71 "use bopcheck Shape [level of check: 0 - 9] [-t]",
6f31882a 72 __FILE__, bopcheck, g);
73 theCommands.Add("bopargcheck" ,
43cb0011 74 "use bopargcheck without parameters to get ",
6f31882a 75 __FILE__, bopargcheck, g);
e98e3990 76 theCommands.Add ("xdistef" ,
43cb0011 77 "use xdistef edge face",
e98e3990 78 __FILE__, xdistef, g);
79 theCommands.Add("checkcurveonsurf",
43cb0011 80 "use checkcurveonsurf shape",
e98e3990 81 __FILE__, checkcurveonsurf, g);
7fd59977 82}
63def8e6 83//=======================================================================
84//class : BOPTest_Interf
85//purpose : Auxiliary class
86//=======================================================================
87class BOPTest_Interf {
88 public:
89 BOPTest_Interf() : myIndex1(-1), myIndex2(-1), myType(-1) {
90 }
91 //
92 ~BOPTest_Interf() {
93 }
94 //
95 void SetIndices(const Standard_Integer theIndex1,
96 const Standard_Integer theIndex2) {
97 myIndex1=theIndex1;
98 myIndex2=theIndex2;
99 }
100 //
101 void Indices(Standard_Integer& theIndex1,
102 Standard_Integer& theIndex2) const {
103 theIndex1=myIndex1;
104 theIndex2=myIndex2;
105 }
106 //
107 void SetType(const Standard_Integer theType) {
108 myType=theType;
109 }
110 //
111 Standard_Integer Type() const {
112 return myType;
113 }
114 //
115 bool operator < (const BOPTest_Interf& aOther) const {
116 bool bFlag;
117 //
118 if (myType==aOther.myType) {
119 if (myIndex1 == aOther.myIndex1) {
120 bFlag=(myIndex2 < aOther.myIndex2);
121 }
122 else {
123 bFlag=(myIndex1 < aOther.myIndex1);
124 }
125 }
126 else {
127 bFlag=(myType < aOther.myType);
128 }
129 //
130 return bFlag;
131 }
132 //
133 protected:
134 Standard_Integer myIndex1;
135 Standard_Integer myIndex2;
136 Standard_Integer myType;
137};
7fd59977 138//=======================================================================
139//function : bopcheck
140//purpose :
141//=======================================================================
63def8e6 142Standard_Integer bopcheck (Draw_Interpretor& di,
143 Standard_Integer n,
144 const char** a )
7fd59977 145{
7fd59977 146 if (n<2) {
43cb0011 147 di << " use bopcheck Shape [level of check: 0 - 9] [-t]\n";
6f31882a 148 di << " The level of check defines ";
80db5701 149 di << " which interferences will be checked:\n";
150 di << " 0 - V/V only\n";
151 di << " 1 - V/V, V/E\n";
152 di << " 2 - V/V, V/E, E/E\n";
153 di << " 3 - V/V, V/E, E/E , V/F\n";
154 di << " 4 - V/V, V/E, E/E, V/F , E/F\n";
155 di << " 5 - V/V, V/E, E/E, V/F, E/F, F/F;\n";
156 di << " 6 - V/V, V/E, E/E, V/F, E/F, F/F, V/Z\n";
157 di << " 7 - V/V, V/E, E/E, V/F, E/F, F/F, E/Z\n";
158 di << " 8 - V/V, V/E, E/E, V/F, E/F, F/F, E/Z, F/Z\n";
159 di << " 9 - V/V, V/E, E/E, V/F, E/F, F/F, E/Z, F/Z, Z/Z\n";
160 di << " Default level is 9\n";
7fd59977 161 return 1;
162 }
80db5701 163 //
164 TopoDS_Shape aS = DBRep::Get(a[1]);
165 if (aS.IsNull()) {
4e57c75e 166 di << "null shapes are not allowed here!";
167 return 1;
168 }
7fd59977 169 //
63def8e6 170 Standard_Boolean bRunParallel, bShowTime;
171 Standard_Integer i, aLevel, aNbInterfTypes;
43cb0011 172 Standard_Real aTol;
80db5701 173 //
174 aNbInterfTypes=BOPDS_DS::NbInterfTypes();
175 //
63def8e6 176 aLevel=aNbInterfTypes-1;
177 //
178 if (n>2) {
b1d15f53 179 if (a[2][0] != '-') {
180 aLevel=Draw::Atoi(a[2]);
181 }
63def8e6 182 }
183 //
184 if (aLevel < 0 || aLevel > aNbInterfTypes-1) {
80db5701 185 di << "Invalid level";
186 return 1;
187 }
63def8e6 188 //
189 bShowTime=Standard_False;
43cb0011 190 aTol=BOPTest_Objects::FuzzyValue();
191 bRunParallel=BOPTest_Objects::RunParallel();
192 //
b1d15f53 193 for (i=2; i<n; ++i) {
43cb0011 194 if (!strcmp(a[i], "-t")) {
63def8e6 195 bShowTime=Standard_True;
196 }
c7b59798 197 }
63def8e6 198 //
199 //aLevel = (n==3) ? Draw::Atoi(a[2]) : aNbInterfTypes-1;
80db5701 200 //-------------------------------------------------------------------
63def8e6 201 char buf[256], aName1[32], aName2[32];
202 char aInterfTypes[10][4] = {
80db5701 203 "V/V", "V/E", "E/E","V/F", "E/F", "F/F", "V/Z", "E/Z", "F/Z", "Z/Z"
204 };
80db5701 205 //
63def8e6 206 Standard_Integer iErr, iCnt, n1, n2, iT;
207 TopAbs_ShapeEnum aType1, aType2;
208 BOPAlgo_CheckerSI aChecker;
1155d05a 209 TopTools_ListOfShape aLS;
25dfc507 210 BOPDS_MapIteratorOfMapOfPair aItMPK;
63def8e6 211 //
212 if (aLevel < (aNbInterfTypes-1)) {
6f31882a 213 di << "Info:\nThe level of check is set to "
63def8e6 214 << aInterfTypes[aLevel] << ", i.e. intersection(s)\n";
215
216 for (i=aLevel+1; i<aNbInterfTypes; ++i) {
217 di << aInterfTypes[i];
80db5701 218 if (i<aNbInterfTypes-1) {
c1fe53c6 219 di << ", ";
220 }
221 }
222 di << " will not be checked.\n\n";
223 }
80db5701 224 //
63def8e6 225 aLS.Append(aS);
226 aChecker.SetArguments(aLS);
227 aChecker.SetLevelOfCheck(aLevel);
228 aChecker.SetRunParallel(bRunParallel);
43cb0011 229 aChecker.SetFuzzyValue(aTol);
80db5701 230 //
c7b59798 231 OSD_Timer aTimer;
232 aTimer.Start();
4e57c75e 233 //
234 aChecker.Perform();
4e57c75e 235 //
c7b59798 236 aTimer.Stop();
4e57c75e 237 //
ad8b073e 238 BOPTest::ReportAlerts(aChecker);
239 //
33ba8565 240 iErr=aChecker.HasErrors();
4e57c75e 241 //
63def8e6 242 const BOPDS_DS& aDS=*(aChecker.PDS());
243 //
25dfc507 244 const BOPDS_MapOfPair& aMPK=aDS.Interferences();
63def8e6 245 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
246 using namespace std;
247 vector <BOPTest_Interf> aVec;
248 vector <BOPTest_Interf>::iterator aIt;
249 BOPTest_Interf aBInterf;
250 //
251 aItMPK.Initialize(aMPK);
252 for (; aItMPK.More(); aItMPK.Next()) {
25dfc507 253 const BOPDS_Pair& aPK=aItMPK.Value();
254 aPK.Indices(n1, n2);
63def8e6 255 if(aDS.IsNewShape(n1) || aDS.IsNewShape(n2)) {
256 continue;
257 }
258 //
259 const BOPDS_ShapeInfo& aSI1=aDS.ShapeInfo(n1);
260 const BOPDS_ShapeInfo& aSI2=aDS.ShapeInfo(n2);
261 aType1=aSI1.ShapeType();
262 aType2=aSI2.ShapeType();
263 //
264 iT=BOPDS_Tools::TypeToInteger(aType1, aType2);
265 //
266 aBInterf.SetIndices(n1, n2);
267 aBInterf.SetType(iT);
268 //
269 aVec.push_back(aBInterf);
270 }
271 //
272 sort( aVec.begin(), aVec.end(), less<BOPTest_Interf>());
273 //
274 iCnt=0;
275 for (aIt=aVec.begin(); aIt!=aVec.end(); aIt++) {
276 const BOPTest_Interf& aBI=*aIt;
277 //
278 aBI.Indices(n1, n2);
279 if(aDS.IsNewShape(n1) || aDS.IsNewShape(n2)) {
280 continue;
7fd59977 281 }
63def8e6 282 //
283 const TopoDS_Shape& aS1=aDS.Shape(n1);
284 const TopoDS_Shape& aS2=aDS.Shape(n2);
285 //
286 iT=aBI.Type();
287 di << aInterfTypes[iT] << ": ";
288 //
289 sprintf(aName1, "x%d", n1);
290 //sprintf(aName1, "x%d", iCnt);
291 DBRep::Set (aName1, aS1);
292 //
293 ++iCnt;
294 sprintf(aName2, "x%d", n2);
295 //sprintf(aName2, "x%d", iCnt);
296 DBRep::Set (aName2, aS2);
297 ++iCnt;
298 //
299 sprintf(buf, "%s %s \n", aName1, aName2);
300 di << buf;
7fd59977 301 }
6f31882a 302 //
4e57c75e 303 if (iErr) {
6f31882a 304 di << "There were errors during the operation, ";
586db386 305 di << "so the list may be incomplete.\n";
4e57c75e 306 }
6f31882a 307 //
63def8e6 308 if (!iCnt) {
586db386 309 di << " This shape seems to be OK.\n";
7fd59977 310 }
c7b59798 311 if (bShowTime)
312 {
313 Sprintf(buf, " Tps: %7.2lf\n", aTimer.ElapsedTime());
63def8e6 314 di << buf;
7fd59977 315 }
63def8e6 316 return 0;
7fd59977 317}
6f31882a 318//=======================================================================
319//function : bopargcheck
320//purpose :
321//=======================================================================
e98e3990 322Standard_Integer bopargcheck (Draw_Interpretor& di,
323 Standard_Integer n,
63def8e6 324 const char** a )
7fd59977 325{
326 if (n<2) {
327 di << "\n";
6f31882a 328 di << " Use >bopargcheck Shape1 [[Shape2] ";
43cb0011 329 di << "[-F/O/C/T/S/U] [/R|F|T|V|E|I|P|C|S]] [#BF]\n\n";
586db386 330 di << " -<Boolean Operation>\n";
331 di << " F (fuse)\n";
332 di << " O (common)\n";
333 di << " C (cut)\n";
334 di << " T (cut21)\n";
335 di << " S (section)\n";
336 di << " U (unknown)\n";
6f31882a 337 di << " For example: \"bopargcheck s1 s2 -F\" enables" ;
586db386 338 di << " checking for Fuse operation\n";
339 di << " default - section\n\n";
340 di << " /<Test Options>\n";
341 di << " R (disable small edges (shrank range) test)\n";
342 di << " F (disable faces verification test)\n";
343 di << " T (disable tangent faces searching test)\n";
344 di << " V (disable test possibility to merge vertices)\n";
345 di << " E (disable test possibility to merge edges)\n";
346 di << " I (disable self-interference test)\n";
347 di << " P (disable shape type test)\n";
348 di << " C (disable test for shape continuity)\n";
349 di << " S (disable curve on surface check)\n";
6f31882a 350 di << " For example: \"bopargcheck s1 s2 /RI\" disables ";
586db386 351 di << "small edge detection and self-intersection detection\n";
352 di << " default - all options are enabled\n\n";
353 di << " #<Additional Test Options>\n";
354 di << " B (stop test on first faulty found); default OFF\n";
6f31882a 355 di << " F (full output for faulty shapes); default - output ";
586db386 356 di << "in a short format\n\n";
6f31882a 357 di << " NOTE: <Boolean Operation> and <Test Options> are ";
586db386 358 di << "used only for couple\n";
6f31882a 359 di << " of argument shapes, except I and P options ";
586db386 360 di << "that are always used for\n";
6f31882a 361 di << " couple of shapes as well as for ";
586db386 362 di <<"single shape test.\n";
7fd59977 363 return 1;
364 }
365
6f31882a 366 TopoDS_Shape aS1 = DBRep::Get(a[1]);
7fd59977 367
6f31882a 368 if(aS1.IsNull()) {
586db386 369 di << "Error: null shape not allowed!\n";
6f31882a 370 di << "Type bopargcheck without arguments for more ";
586db386 371 di <<"information\n";
7fd59977 372 return 1;
373 }
374
375 Standard_Boolean isBO = Standard_False;
376 Standard_Integer indxBO = 0;
377 Standard_Boolean isOP = Standard_False;
378 Standard_Integer indxOP = 0;
379 Standard_Boolean isAD = Standard_False;
380 Standard_Integer indxAD = 0;
381 Standard_Boolean isS2 = Standard_False;
382 Standard_Integer indxS2 = 0;
b1d15f53 383 Standard_Real aTolerance = 0;
7321e9fb 384 Standard_Boolean bRunParallel;
385 //
386 bRunParallel=BOPTest_Objects::RunParallel();
43cb0011 387 aTolerance=BOPTest_Objects::FuzzyValue();
388
7fd59977 389 if(n >= 3) {
390 Standard_Integer iIndex = 0;
391 for(iIndex = 2; iIndex < n; iIndex++) {
43cb0011 392 if(a[iIndex][0] == '-') {
7fd59977 393 isBO = Standard_True;
394 indxBO = iIndex;
395 }
43cb0011 396 else if(a[iIndex][0] == '/') {
7fd59977 397 isOP = Standard_True;
398 indxOP = iIndex;
399 }
43cb0011 400 else if(a[iIndex][0] == '#') {
7fd59977 401 isAD = Standard_True;
402 indxAD = iIndex;
403 }
404 else {
405 isS2 = Standard_True;
406 indxS2 = iIndex;
407 }
408 }
409 }
b1d15f53 410
7fd59977 411 // set & test second shape
4e57c75e 412 TopoDS_Shape aS22, aS2;
7fd59977 413 if(isS2) {
414 if(indxS2 != 2) {
586db386 415 di << "Error: second shape should follow the first one!\n";
416 di << "Type bopargcheck without arguments for more information\n";
7fd59977 417 return 1;
418 }
419 else {
4e57c75e 420 aS22 = DBRep::Get(a[2]);
421 if(aS22.IsNull()) {
586db386 422 di << "Error: second shape is null!\n";
423 di << "Type bopargcheck without arguments for more information\n";
7fd59977 424 return 1;
425 }
426 }
427 }
b1d15f53 428
7fd59977 429 // init checker
4e57c75e 430 BOPAlgo_ArgumentAnalyzer aChecker;
7321e9fb 431 aChecker.SetRunParallel(bRunParallel);
b1d15f53 432 aChecker.SetFuzzyValue(aTolerance);
7fd59977 433 aChecker.SetShape1(aS1);
434
435 // set default options (always tested!) for single and couple shapes
e98e3990 436 aChecker.ArgumentTypeMode() = Standard_True;
437 aChecker.SelfInterMode() = Standard_True;
438 aChecker.SmallEdgeMode() = Standard_True;
439 aChecker.RebuildFaceMode() = Standard_True;
440 aChecker.ContinuityMode() = Standard_True;
441 aChecker.CurveOnSurfaceMode() = Standard_True;
7fd59977 442
443 // test & set options and operation for two shapes
4e57c75e 444 if(!aS22.IsNull()) {
445 aS2 = BRepBuilderAPI_Copy(aS22).Shape();
7fd59977 446 aChecker.SetShape2(aS2);
447 // set operation (default - Section)
448 if(isBO) {
449 if(a[indxBO][1] == 'F' || a[indxBO][1] == 'f') {
4e57c75e 450 aChecker.OperationType() = BOPAlgo_FUSE;
7fd59977 451 }
452 else if(a[indxBO][1] == 'O' || a[indxBO][1] == 'o') {
4e57c75e 453 aChecker.OperationType() = BOPAlgo_COMMON;
7fd59977 454 }
455 else if(a[indxBO][1] == 'C' || a[indxBO][1] == 'c') {
4e57c75e 456 aChecker.OperationType() = BOPAlgo_CUT;
7fd59977 457 }
458 else if(a[indxBO][1] == 'T' || a[indxBO][1] == 't') {
4e57c75e 459 aChecker.OperationType() = BOPAlgo_CUT21;
7fd59977 460 }
461 else if(a[indxBO][1] == 'S' || a[indxBO][1] == 's') {
4e57c75e 462 aChecker.OperationType() = BOPAlgo_SECTION;
7fd59977 463 }
464 else if(a[indxBO][1] == 'U' || a[indxBO][1] == 'u') {
4e57c75e 465 aChecker.OperationType() = BOPAlgo_UNKNOWN;
7fd59977 466 }
467 else {
586db386 468 di << "Error: invalid boolean operation type!\n";
469 di << "Type bopargcheck without arguments for more information\n";
7fd59977 470 return 1;
471 }
472 }
473 else
4e57c75e 474 aChecker.OperationType() = BOPAlgo_SECTION;
7fd59977 475
7fd59977 476 aChecker.TangentMode() = Standard_True;
477 aChecker.MergeVertexMode() = Standard_True;
478 aChecker.MergeEdgeMode() = Standard_True;
7fd59977 479 }
0e09ee8e 480
481 // set options (default - all ON)
482 if(isOP) {
483 Standard_Integer ind = 1;
484 while(a[indxOP][ind] != 0) {
485 if(a[indxOP][ind] == 'R' || a[indxOP][ind] == 'r') {
486 aChecker.SmallEdgeMode() = Standard_False;
487 }
488 else if(a[indxOP][ind] == 'F' || a[indxOP][ind] == 'f') {
489 aChecker.RebuildFaceMode() = Standard_False;
490 }
491 else if(a[indxOP][ind] == 'T' || a[indxOP][ind] == 't') {
492 aChecker.TangentMode() = Standard_False;
7fd59977 493 }
0e09ee8e 494 else if(a[indxOP][ind] == 'V' || a[indxOP][ind] == 'v') {
495 aChecker.MergeVertexMode() = Standard_False;
496 }
497 else if(a[indxOP][ind] == 'E' || a[indxOP][ind] == 'e') {
498 aChecker.MergeEdgeMode() = Standard_False;
499 }
500 else if(a[indxOP][ind] == 'I' || a[indxOP][ind] == 'i') {
501 aChecker.SelfInterMode() = Standard_False;
502 }
503 else if(a[indxOP][ind] == 'P' || a[indxOP][ind] == 'p') {
504 aChecker.ArgumentTypeMode() = Standard_False;
505 }
506 else if(a[indxOP][ind] == 'C' || a[indxOP][ind] == 'c') {
507 aChecker.ContinuityMode() = Standard_False;
508 }
e98e3990 509 else if(a[indxOP][ind] == 'S' || a[indxOP][ind] == 's') {
510 aChecker.CurveOnSurfaceMode() = Standard_False;
511 }
0e09ee8e 512 else {
586db386 513 di << "Error: invalid test option(s)!\n";
514 di << "Type bopargcheck without arguments for more information\n";
0e09ee8e 515 return 1;
516 }
517 ind++;
7fd59977 518 }
519 }
520
521 // set additional options
522 Standard_Boolean fullOutput = Standard_False;
523 if(isAD) {
524 Standard_Integer ind = 1;
525 while(a[indxAD][ind] != 0) {
526 if(a[indxAD][ind] == 'B' || a[indxAD][ind] == 'b') {
527 aChecker.StopOnFirstFaulty() = Standard_True;
528 }
529 else if(a[indxAD][ind] == 'F' || a[indxAD][ind] == 'f') {
530 fullOutput = Standard_True;
531 }
532 else {
586db386 533 di << "Error: invalid additional test option(s)!\n";
534 di << "Type bopargcheck without arguments for more information\n";
7fd59977 535 return 1;
536 }
537 ind++;
538 }
539 }
540
541 // run checker
542 aChecker.Perform();
543
544 // process result of checking
545 if(!aChecker.HasFaulty()) {
546 di << "Shape(s) seem(s) to be valid for BOP." << "\n";
547 }
548 else {
549 if(!fullOutput) {
586db386 550 di << "Faulties, that can not be treated by BOP, are detected.\n";
7fd59977 551 }
552 else {
4e57c75e 553 const BOPAlgo_ListOfCheckResult& aResultList = aChecker.GetCheckResult();
554 BOPAlgo_ListIteratorOfListOfCheckResult anIt(aResultList);
7fd59977 555
556 Standard_Integer S1_BadType = 0, S1_SelfInt = 0, S1_SmalE = 0, S1_BadF = 0, S1_BadV = 0, S1_BadE = 0;
557 Standard_Integer S1_SelfIntAll = 0, S1_SmalEAll = 0, S1_BadFAll = 0, S1_BadVAll = 0, S1_BadEAll = 0;
558 Standard_Integer S2_BadType = 0, S2_SelfInt = 0, S2_SmalE = 0, S2_BadF = 0, S2_BadV = 0, S2_BadE = 0;
559 Standard_Integer S2_SelfIntAll = 0, S2_SmalEAll = 0, S2_BadFAll = 0, S2_BadVAll = 0, S2_BadEAll = 0;
4e57c75e 560 Standard_Integer S1_OpAb = 0, S2_OpAb = 0;
0e09ee8e 561 Standard_Integer S1_C0 = 0, S2_C0 = 0, S1_C0All = 0, S2_C0All = 0;
e98e3990 562 Standard_Integer S1_COnS = 0, S2_COnS = 0, S1_COnSAll = 0, S2_COnSAll = 0;
7fd59977 563 Standard_Boolean hasUnknown = Standard_False;
564
565 TCollection_AsciiString aS1SIBaseName("s1si_");
566 TCollection_AsciiString aS1SEBaseName("s1se_");
567 TCollection_AsciiString aS1BFBaseName("s1bf_");
568 TCollection_AsciiString aS1BVBaseName("s1bv_");
569 TCollection_AsciiString aS1BEBaseName("s1be_");
0e09ee8e 570 TCollection_AsciiString aS1C0BaseName("s1C0_");
e98e3990 571 TCollection_AsciiString aS1COnSBaseName("s1COnS_");
7fd59977 572 TCollection_AsciiString aS2SIBaseName("s2si_");
573 TCollection_AsciiString aS2SEBaseName("s2se_");
574 TCollection_AsciiString aS2BFBaseName("s2bf_");
575 TCollection_AsciiString aS2BVBaseName("s2bv_");
576 TCollection_AsciiString aS2BEBaseName("s2be_");
0e09ee8e 577 TCollection_AsciiString aS2C0BaseName("s2C0_");
e98e3990 578 TCollection_AsciiString aS2COnSBaseName("s2COnS_");
7fd59977 579
580 for(; anIt.More(); anIt.Next()) {
4e57c75e 581 const BOPAlgo_CheckResult& aResult = anIt.Value();
7fd59977 582 const TopoDS_Shape & aSS1 = aResult.GetShape1();
583 const TopoDS_Shape & aSS2 = aResult.GetShape2();
1155d05a 584 const TopTools_ListOfShape & aLS1 = aResult.GetFaultyShapes1();
585 const TopTools_ListOfShape & aLS2 = aResult.GetFaultyShapes2();
7fd59977 586 Standard_Boolean isL1 = !aLS1.IsEmpty();
587 Standard_Boolean isL2 = !aLS2.IsEmpty();
588
589 switch(aResult.GetCheckStatus()) {
4e57c75e 590 case BOPAlgo_BadType: {
7fd59977 591 if(!aSS1.IsNull()) S1_BadType++;
592 if(!aSS2.IsNull()) S2_BadType++;
593 }
4e57c75e 594 break;
595 case BOPAlgo_SelfIntersect: {
7fd59977 596 if(!aSS1.IsNull()) {
597 S1_SelfInt++;
598 if(isL1)
599 MakeShapeForFullOutput(aS1SIBaseName, S1_SelfInt, aLS1, S1_SelfIntAll, di);
600 }
601 if(!aSS2.IsNull()) {
602 S2_SelfInt++;
603 if(isL2)
604 MakeShapeForFullOutput(aS2SIBaseName, S2_SelfInt, aLS2, S2_SelfIntAll, di);
605 }
606 }
4e57c75e 607 break;
608 case BOPAlgo_TooSmallEdge: {
7fd59977 609 if(!aSS1.IsNull()) {
610 S1_SmalE++;
611 if(isL1)
612 MakeShapeForFullOutput(aS1SEBaseName, S1_SmalE, aLS1, S1_SmalEAll, di);
613 }
614 if(!aSS2.IsNull()) {
615 S2_SmalE++;
616 if(isL2)
617 MakeShapeForFullOutput(aS2SEBaseName, S2_SmalE, aLS2, S2_SmalEAll, di);
618 }
619 }
4e57c75e 620 break;
621 case BOPAlgo_NonRecoverableFace: {
7fd59977 622 if(!aSS1.IsNull()) {
623 S1_BadF++;
624 if(isL1)
625 MakeShapeForFullOutput(aS1BFBaseName, S1_BadF, aLS1, S1_BadFAll, di);
626 }
627 if(!aSS2.IsNull()) {
628 S2_BadF++;
629 if(isL2)
630 MakeShapeForFullOutput(aS2BFBaseName, S2_BadF, aLS2, S2_BadFAll, di);
631 }
632 }
4e57c75e 633 break;
634 case BOPAlgo_IncompatibilityOfVertex: {
7fd59977 635 if(!aSS1.IsNull()) {
636 S1_BadV++;
637 if(isL1) {
638 MakeShapeForFullOutput(aS1BVBaseName, S1_BadV, aLS1, S1_BadVAll, di);
4e57c75e 639 }
7fd59977 640 }
641 if(!aSS2.IsNull()) {
642 S2_BadV++;
643 if(isL2){
644 MakeShapeForFullOutput(aS2BVBaseName, S2_BadV, aLS2, S2_BadVAll, di);
4e57c75e 645 }
7fd59977 646 }
647 }
4e57c75e 648 break;
649 case BOPAlgo_IncompatibilityOfEdge: {
7fd59977 650 if(!aSS1.IsNull()) {
651 S1_BadE++;
652 if(isL1) {
653 MakeShapeForFullOutput(aS1BEBaseName, S1_BadE, aLS1, S1_BadEAll, di);
4e57c75e 654 }
7fd59977 655 }
656 if(!aSS2.IsNull()) {
657 S2_BadE++;
658 if(isL2) {
659 MakeShapeForFullOutput(aS2BEBaseName, S2_BadE, aLS2, S2_BadEAll, di);
4e57c75e 660 }
7fd59977 661 }
662 }
4e57c75e 663 break;
664 case BOPAlgo_IncompatibilityOfFace: {
7fd59977 665 // not yet implemented
666 }
4e57c75e 667 break;
0e09ee8e 668 case BOPAlgo_GeomAbs_C0: {
669 if(!aSS1.IsNull()) {
670 S1_C0++;
671 if(isL1) {
672 MakeShapeForFullOutput(aS1C0BaseName, S1_C0, aLS1, S1_C0All, di);
673 }
674 }
675 if(!aSS2.IsNull()) {
676 S2_C0++;
677 if(isL2) {
678 MakeShapeForFullOutput(aS2C0BaseName, S2_C0, aLS2, S2_C0All, di);
679 }
680 }
681 }
682 break;
e98e3990 683 case BOPAlgo_InvalidCurveOnSurface: {
684 if(!aSS1.IsNull()) {
685 S1_COnS++;
686 if(isL1) {
687 Standard_Real aMaxDist = aResult.GetMaxDistance1();
688 Standard_Real aMaxParameter = aResult.GetMaxParameter1();
689 MakeShapeForFullOutput(aS1COnSBaseName, S1_COnS, aLS1, S1_COnSAll, di,
690 Standard_True, aMaxDist, aMaxParameter);
691 }
692 }
693 if(!aSS2.IsNull()) {
694 S2_COnS++;
695 if(isL2) {
696 Standard_Real aMaxDist = aResult.GetMaxDistance2();
697 Standard_Real aMaxParameter = aResult.GetMaxParameter2();
698 MakeShapeForFullOutput(aS2COnSBaseName, S2_COnS, aLS2, S2_COnSAll, di,
699 Standard_True, aMaxDist, aMaxParameter);
700 }
701 }
702 }
703 break;
4e57c75e 704 case BOPAlgo_OperationAborted: {
705 if(!aSS1.IsNull()) S1_OpAb++;
706 if(!aSS2.IsNull()) S2_OpAb++;
707 }
708 break;
709 case BOPAlgo_CheckUnknown:
7fd59977 710 default: {
711 hasUnknown = Standard_True;
712 }
4e57c75e 713 break;
7fd59977 714 } // switch
715 }// faulties
716
e98e3990 717 Standard_Integer FS1 = S1_SelfInt + S1_SmalE + S1_BadF + S1_BadV + S1_BadE + S1_OpAb + S1_C0 + S1_COnS;
7fd59977 718 FS1 += (S1_BadType != 0) ? 1 : 0;
e98e3990 719 Standard_Integer FS2 = S2_SelfInt + S2_SmalE + S2_BadF + S2_BadV + S2_BadE + S2_OpAb + S2_C0 + S2_COnS;
7fd59977 720 FS2 += (S2_BadType != 0) ? 1 : 0;
721
722 // output for first shape
723 di << "Faulties for FIRST shape found : " << FS1 << "\n";
724 if(FS1 != 0) {
586db386 725 di << "---------------------------------\n";
7fd59977 726 Standard_CString CString1;
4e57c75e 727 if (S1_BadType != 0)
728 CString1="YES";
729 else
b1d15f53 730 CString1=aChecker.ArgumentTypeMode() ? "NO" : "DISABLED";
7fd59977 731 di << "Shapes are not suppotrted by BOP: " << CString1 << "\n";
732 Standard_CString CString2;
4e57c75e 733 if (S1_SelfInt != 0)
734 CString2="YES";
735 else
b1d15f53 736 CString2=aChecker.SelfInterMode() ? "NO" : "DISABLED";
7fd59977 737 di << "Self-Intersections : " << CString2;
738 if(S1_SelfInt != 0)
586db386 739 di << " Cases(" << S1_SelfInt << ") Total shapes(" << S1_SelfIntAll << ")\n";
7fd59977 740 else
741 di << "\n";
4e57c75e 742 Standard_CString CString13;
743 if (S1_OpAb != 0)
744 CString13="YES";
745 else
b1d15f53 746 CString13=aChecker.SelfInterMode() ? "NO" : "DISABLED";
4e57c75e 747 di << "Check for SI has been aborted : " << CString13 << "\n";
7fd59977 748 Standard_CString CString3;
4e57c75e 749 if (S1_SmalE != 0)
750 CString3="YES";
751 else
b1d15f53 752 CString3=aChecker.SmallEdgeMode() ? "NO" : "DISABLED";
7fd59977 753 di << "Too small edges : " << CString3;
754 if(S1_SmalE != 0)
586db386 755 di << " Cases(" << S1_SmalE << ") Total shapes(" << S1_SmalEAll << ")\n";
7fd59977 756 else
757 di << "\n";
758 Standard_CString CString4;
4e57c75e 759 if (S1_BadF != 0)
760 CString4="YES";
761 else
b1d15f53 762 CString4=aChecker.RebuildFaceMode() ? "NO" : "DISABLED";
7fd59977 763 di << "Bad faces : " << CString4;
764 if(S1_BadF != 0)
586db386 765 di << " Cases(" << S1_BadF << ") Total shapes(" << S1_BadFAll << ")\n";
7fd59977 766 else
767 di << "\n";
768 Standard_CString CString5;
4e57c75e 769 if (S1_BadV != 0)
770 CString5="YES";
771 else
b1d15f53 772 CString5=aChecker.MergeVertexMode() ? "NO" : "DISABLED";
7fd59977 773 di << "Too close vertices : " << CString5;
774 if(S1_BadV != 0)
586db386 775 di << " Cases(" << S1_BadV << ") Total shapes(" << S1_BadVAll << ")\n";
7fd59977 776 else
777 di << "\n";
778 Standard_CString CString6;
4e57c75e 779 if (S1_BadE != 0)
780 CString6="YES";
781 else
b1d15f53 782 CString6=aChecker.MergeEdgeMode() ? "NO" : "DISABLED";
7fd59977 783 di << "Too close edges : " << CString6;
784 if(S1_BadE != 0)
586db386 785 di << " Cases(" << S1_BadE << ") Total shapes(" << S1_BadEAll << ")\n";
7fd59977 786 else
787 di << "\n";
0e09ee8e 788 Standard_CString CString15;
789 if (S1_C0 != 0)
790 CString15="YES";
791 else
b1d15f53 792 CString15=aChecker.ContinuityMode() ? "NO" : "DISABLED";
0e09ee8e 793 di << "Shapes with Continuity C0 : " << CString15;
794 if(S1_C0 != 0)
586db386 795 di << " Cases(" << S1_C0 << ") Total shapes(" << S1_C0All << ")\n";
0e09ee8e 796 else
797 di << "\n";
e98e3990 798
799 Standard_CString CString17;
800 if (S1_COnS != 0)
801 CString17="YES";
802 else
b1d15f53 803 CString17=aChecker.CurveOnSurfaceMode() ? "NO" : "DISABLED";
e98e3990 804 di << "Invalid Curve on Surface : " << CString17;
805 if(S1_COnS != 0)
586db386 806 di << " Cases(" << S1_COnS << ") Total shapes(" << S1_COnSAll << ")\n";
e98e3990 807 else
808 di << "\n";
7fd59977 809 }
810
811 // output for second shape
812 di << "\n";
813 di << "Faulties for SECOND shape found : " << FS2 << "\n";
814 if(FS2 != 0) {
586db386 815 di << "---------------------------------\n";
7fd59977 816 Standard_CString CString7;
4e57c75e 817 if (S2_BadType != 0)
818 CString7="YES";
819 else
b1d15f53 820 CString7=aChecker.ArgumentTypeMode() ? "NO" : "DISABLED";
7fd59977 821 di << "Shapes are not suppotrted by BOP: " << CString7 << "\n";
822 Standard_CString CString8;
4e57c75e 823 if (S2_SelfInt != 0)
824 CString8="YES";
825 else
b1d15f53 826 CString8=aChecker.SelfInterMode() ? "NO" : "DISABLED";
7fd59977 827 di << "Self-Intersections : " << CString8;
828 if(S2_SelfInt != 0)
586db386 829 di << " Cases(" << S2_SelfInt << ") Total shapes(" << S2_SelfIntAll << ")\n";
7fd59977 830 else
831 di << "\n";
4e57c75e 832
833 Standard_CString CString14;
834 if (S2_OpAb != 0)
835 CString14="YES";
836 else
b1d15f53 837 CString14=aChecker.SelfInterMode() ? "NO" : "DISABLED";
4e57c75e 838 di << "Check for SI has been aborted : " << CString14 << "\n";
7fd59977 839 Standard_CString CString9;
4e57c75e 840 if (S2_SmalE != 0)
841 CString9="YES";
842 else
b1d15f53 843 CString9=aChecker.SmallEdgeMode() ? "NO" : "DISABLED";
7fd59977 844 di << "Too small edges : " << CString9;
845 if(S2_SmalE != 0)
586db386 846 di << " Cases(" << S2_SmalE << ") Total shapes(" << S2_SmalEAll << ")\n";
7fd59977 847 else
848 di << "\n";
849 Standard_CString CString10;
4e57c75e 850 if (S2_BadF != 0)
851 CString10="YES";
852 else
b1d15f53 853 CString10=aChecker.RebuildFaceMode() ? "NO" : "DISABLED";
7fd59977 854 di << "Bad faces : " << CString10;
855 if(S2_BadF != 0)
586db386 856 di << " Cases(" << S2_BadF << ") Total shapes(" << S2_BadFAll << ")\n";
7fd59977 857 else
858 di << "\n";
859 Standard_CString CString11;
4e57c75e 860 if (S2_BadV != 0)
861 CString11="YES";
862 else
b1d15f53 863 CString11=aChecker.MergeVertexMode() ? "NO" : "DISABLED";
7fd59977 864 di << "Too close vertices : " << CString11;
865 if(S2_BadV != 0)
586db386 866 di << " Cases(" << S2_BadV << ") Total shapes(" << S2_BadVAll << ")\n";
7fd59977 867 else
868 di << "\n";
869 Standard_CString CString12;
4e57c75e 870 if (S2_BadE != 0)
871 CString12="YES";
872 else
b1d15f53 873 CString12=aChecker.MergeEdgeMode() ? "NO" : "DISABLED";
7fd59977 874 di << "Too close edges : " << CString12;
875 if(S2_BadE != 0)
586db386 876 di << " Cases(" << S2_BadE << ") Total shapes(" << S2_BadEAll << ")\n";
7fd59977 877 else
878 di << "\n";
0e09ee8e 879 Standard_CString CString16;
880 if (S2_C0 != 0)
881 CString16="YES";
882 else
b1d15f53 883 CString16=aChecker.ContinuityMode() ? "NO" : "DISABLED";
0e09ee8e 884 di << "Shapes with Continuity C0 : " << CString16;
885 if(S2_C0 != 0)
586db386 886 di << " Cases(" << S2_C0 << ") Total shapes(" << S2_C0All << ")\n";
0e09ee8e 887 else
888 di << "\n";
7fd59977 889
e98e3990 890 Standard_CString CString18;
891 if (S2_COnS != 0)
892 CString18="YES";
893 else
b1d15f53 894 CString18=aChecker.CurveOnSurfaceMode() ? "NO" : "DISABLED";
e98e3990 895 di << "Invalid Curve on Surface : " << CString18;
896 if(S2_COnS != 0)
586db386 897 di << " Cases(" << S2_COnS << ") Total shapes(" << S2_COnSAll << ")\n";
e98e3990 898 else
899 di << "\n";
1b7ae951 900 }
901 // warning
902 if(hasUnknown) {
7fd59977 903 di << "\n";
586db386 904 di << "WARNING: The unexpected test break occurs!\n";
7fd59977 905 }
906 } // full output
907 } // has faulties
908
909 return 0;
910}
e98e3990 911
912//=======================================================================
913//function : xdistef
914//purpose :
915//=======================================================================
916Standard_Integer xdistef(Draw_Interpretor& di,
917 Standard_Integer n,
918 const char** a)
919{
c7b59798 920 if(n < 3) {
43cb0011 921 di << "use xdistef edge face\n";
e98e3990 922 return 1;
923 }
924 //
925 const TopoDS_Shape aS1 = DBRep::Get(a[1]);
926 const TopoDS_Shape aS2 = DBRep::Get(a[2]);
927 //
928 if (aS1.IsNull() || aS2.IsNull()) {
929 di << "null shapes\n";
930 return 1;
931 }
932 //
933 if (aS1.ShapeType() != TopAbs_EDGE ||
934 aS2.ShapeType() != TopAbs_FACE) {
935 di << "type mismatch\n";
936 return 1;
937 }
938 //
939 Standard_Real aMaxDist = 0.0, aMaxPar = 0.0;
940 //
941 const TopoDS_Edge& anEdge = *(TopoDS_Edge*)&aS1;
942 const TopoDS_Face& aFace = *(TopoDS_Face*)&aS2;
943 //
944 if(!BOPTools_AlgoTools::ComputeTolerance
945 (aFace, anEdge, aMaxDist, aMaxPar)) {
946 di << "Tolerance cannot be computed\n";
947 return 1;
948 }
949 //
950 di << "Max Distance = " << aMaxDist
951 << "; Parameter on curve = " << aMaxPar << "\n";
952 //
953 return 0;
954}
955
956//=======================================================================
957//function : checkcurveonsurf
958//purpose :
959//=======================================================================
960Standard_Integer checkcurveonsurf(Draw_Interpretor& di,
961 Standard_Integer n,
962 const char** a)
963{
964 if (n != 2) {
965 di << "use checkcurveonsurf shape\n";
966 return 1;
967 }
968 //
969 TopoDS_Shape aS = DBRep::Get(a[1]);
970 if (aS.IsNull()) {
971 di << "null shape\n";
972 return 1;
973 }
974 //
975 Standard_Integer nE, nF, anECounter, aFCounter;
b1d15f53 976 Standard_Real aT, aTolE, aDMax;
e98e3990 977 TopExp_Explorer aExpF, aExpE;
978 char buf[200], aFName[10], anEName[10];
979 NCollection_DataMap<TopoDS_Shape, Standard_Real, TopTools_ShapeMapHasher> aDMETol;
1155d05a 980 TopTools_DataMapOfShapeInteger aMSI;
e98e3990 981 //
982 anECounter = 0;
983 aFCounter = 0;
984 //
985 aExpF.Init(aS, TopAbs_FACE);
986 for (; aExpF.More(); aExpF.Next()) {
987 const TopoDS_Face& aF = *(TopoDS_Face*)&aExpF.Current();
988 //
989 aExpE.Init(aF, TopAbs_EDGE);
990 for (; aExpE.More(); aExpE.Next()) {
991 const TopoDS_Edge& aE = *(TopoDS_Edge*)&aExpE.Current();
992 //
993 if (!BOPTools_AlgoTools::ComputeTolerance(aF, aE, aDMax, aT)) {
994 continue;
995 }
996 //
997 aTolE = BRep_Tool::Tolerance(aE);
5fe13efc 998 if (!(aDMax > aTolE)) {
e98e3990 999 continue;
1000 }
1001 //
1002 if (aDMETol.IsBound(aE)) {
b1d15f53 1003 Standard_Real& aD = aDMETol.ChangeFind(aE);
e98e3990 1004 if (aDMax > aD) {
b1d15f53 1005 aD = aDMax;
e98e3990 1006 }
1007 }
1008 else {
1009 aDMETol.Bind(aE, aDMax);
1010 }
1011 //
1012 if (anECounter == 0) {
1013 di << "Invalid curves on surface:\n";
1014 }
1015 //
1016 if (aMSI.IsBound(aE)) {
1017 nE = aMSI.Find(aE);
1018 }
1019 else {
1020 nE = anECounter;
1021 aMSI.Bind(aE, nE);
1022 ++anECounter;
1023 }
1024 //
1025 if (aMSI.IsBound(aF)) {
1026 nF = aMSI.Find(aF);
1027 } else {
1028 nF = aFCounter;
1029 aMSI.Bind(aF, nF);
1030 ++aFCounter;
1031 }
1032 //
1033 sprintf(anEName, "e_%d", nE);
1034 sprintf(aFName , "f_%d", nF);
1035 sprintf(buf, "edge %s on face %s (max dist: %3.16f, parameter on curve: %3.16f)\n",
1036 anEName, aFName, aDMax, aT);
1037 di << buf;
1038 //
1039 DBRep::Set(anEName, aE);
1040 DBRep::Set(aFName , aF);
1041 }
1042 }
1043 //
1044 if (anECounter > 0) {
1045 di << "\n\nSugestions to fix the shape:\n";
1046 di << "explode " << a[1] << " e;\n";
1047 //
1048 TopTools_MapOfShape M;
1049 aExpE.Init(aS, TopAbs_EDGE);
1050 for (anECounter = 0; aExpE.More(); aExpE.Next()) {
1051 const TopoDS_Shape& aE = aExpE.Current();
1052 if (!M.Add(aE)) {
1053 continue;
1054 }
1055 ++anECounter;
1056 //
1057 if (!aDMETol.IsBound(aE)) {
1058 continue;
1059 }
1060 //
1061 aTolE = aDMETol.Find(aE);
1062 aTolE *= 1.001;
1063 sprintf(buf, "settolerance %s_%d %3.16f;\n", a[1], anECounter, aTolE);
1064 di << buf;
1065 }
1066 }
1067 else {
1068 di << "This shape seems to be OK.\n";
1069 }
1070 //
1071 return 0;
1072}
1073
63def8e6 1074//=======================================================================
1075//function : MakeShapeForFullOutput
1076//purpose :
1077//=======================================================================
1078void MakeShapeForFullOutput (const TCollection_AsciiString & aBaseName,
1079 const Standard_Integer aIndex,
1155d05a 1080 const TopTools_ListOfShape & aList,
63def8e6 1081 Standard_Integer& aCount,
e98e3990 1082 Draw_Interpretor& di,
1083 Standard_Boolean bCurveOnSurf,
1084 Standard_Real aMaxDist,
1085 Standard_Real aMaxParameter)
63def8e6 1086{
1087 TCollection_AsciiString aNum(aIndex);
1088 TCollection_AsciiString aName = aBaseName + aNum;
1089 Standard_CString name = aName.ToCString();
1090
1091 TopoDS_Compound cmp;
1092 BRep_Builder BB;
1093 BB.MakeCompound(cmp);
1094
1155d05a 1095 TopTools_ListIteratorOfListOfShape anIt(aList);
63def8e6 1096 for(; anIt.More(); anIt.Next()) {
1097 const TopoDS_Shape & aS = anIt.Value();
1098 BB.Add(cmp, aS);
1099 aCount++;
1100 }
e98e3990 1101 di << "Made faulty shape: " << name;
1102 //
1103 if (bCurveOnSurf) {
1104 di << " (MaxDist = " << aMaxDist
1105 << ", MaxPar = " << aMaxParameter << ")";
1106 }
1107 //
1108 di << "\n";
1109 //
63def8e6 1110 DBRep::Set(name, cmp);
1111}