1 // Created by: Peter KURNEV
2 // Copyright (c) 2010-2014 OPEN CASCADE SAS
4 // This file is part of Open CASCADE Technology software library.
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
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.
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
16 #include <BOPAlgo_ArgumentAnalyzer.hxx>
17 #include <BOPAlgo_CheckerSI.hxx>
18 #include <BOPAlgo_CheckResult.hxx>
19 #include <BOPCol_ListOfShape.hxx>
20 #include <BOPDS_DS.hxx>
21 #include <BOPDS_MapOfPassKey.hxx>
22 #include <BOPTest.hxx>
23 #include <BOPTest_Objects.hxx>
24 #include <BOPTools_AlgoTools.hxx>
25 #include <BRep_Builder.hxx>
26 #include <BRepBuilderAPI_Copy.hxx>
29 #include <OSD_Timer.hxx>
30 #include <TCollection_AsciiString.hxx>
31 #include <TopExp_Explorer.hxx>
32 #include <TopoDS_Compound.hxx>
33 #include <TopoDS_Shape.hxx>
34 #include <TopTools_MapOfShape.hxx>
35 #include <TopTools_ShapeMapHasher.hxx>
42 void MakeShapeForFullOutput (const TCollection_AsciiString&,
43 const Standard_Integer,
44 const BOPCol_ListOfShape&,
47 Standard_Boolean bCurveOnSurf = Standard_False,
48 Standard_Real aMaxDist = 0.,
49 Standard_Real aMaxParameter = 0.);
51 static Standard_Integer bopcheck (Draw_Interpretor&, Standard_Integer, const char** );
52 static Standard_Integer bopargcheck(Draw_Interpretor&, Standard_Integer, const char** );
53 static Standard_Integer xdistef(Draw_Interpretor&, Standard_Integer, const char** );
54 static Standard_Integer checkcurveonsurf (Draw_Interpretor&, Standard_Integer, const char**);
56 //=======================================================================
57 //function : CheckCommands
59 //=======================================================================
60 void BOPTest::CheckCommands(Draw_Interpretor& theCommands)
62 static Standard_Boolean done = Standard_False;
68 const char* g = "BOPTest commands";
70 theCommands.Add("bopcheck",
71 "use bopcheck Shape [level of check: 0 - 9] [-t]",
72 __FILE__, bopcheck, g);
73 theCommands.Add("bopargcheck" ,
74 "use bopargcheck without parameters to get ",
75 __FILE__, bopargcheck, g);
76 theCommands.Add ("xdistef" ,
77 "use xdistef edge face",
78 __FILE__, xdistef, g);
79 theCommands.Add("checkcurveonsurf",
80 "use checkcurveonsurf shape",
81 __FILE__, checkcurveonsurf, g);
83 //=======================================================================
84 //class : BOPTest_Interf
85 //purpose : Auxiliary class
86 //=======================================================================
87 class BOPTest_Interf {
89 BOPTest_Interf() : myIndex1(-1), myIndex2(-1), myType(-1) {
95 void SetIndices(const Standard_Integer theIndex1,
96 const Standard_Integer theIndex2) {
101 void Indices(Standard_Integer& theIndex1,
102 Standard_Integer& theIndex2) const {
107 void SetType(const Standard_Integer theType) {
111 Standard_Integer Type() const {
115 bool operator < (const BOPTest_Interf& aOther) const {
118 if (myType==aOther.myType) {
119 if (myIndex1 == aOther.myIndex1) {
120 bFlag=(myIndex2 < aOther.myIndex2);
123 bFlag=(myIndex1 < aOther.myIndex1);
127 bFlag=(myType < aOther.myType);
134 Standard_Integer myIndex1;
135 Standard_Integer myIndex2;
136 Standard_Integer myType;
138 //=======================================================================
139 //function : bopcheck
141 //=======================================================================
142 Standard_Integer bopcheck (Draw_Interpretor& di,
147 di << " use bopcheck Shape [level of check: 0 - 9] [-t]\n";
148 di << " The level of check defines ";
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";
164 TopoDS_Shape aS = DBRep::Get(a[1]);
166 di << "null shapes are not allowed here!";
170 Standard_Boolean bRunParallel, bShowTime;
171 Standard_Integer i, aLevel, aNbInterfTypes;
174 aNbInterfTypes=BOPDS_DS::NbInterfTypes();
176 aLevel=aNbInterfTypes-1;
179 if (a[2][0] != '-') {
180 aLevel=Draw::Atoi(a[2]);
184 if (aLevel < 0 || aLevel > aNbInterfTypes-1) {
185 di << "Invalid level";
189 bShowTime=Standard_False;
190 aTol=BOPTest_Objects::FuzzyValue();
191 bRunParallel=BOPTest_Objects::RunParallel();
193 for (i=2; i<n; ++i) {
194 if (!strcmp(a[i], "-t")) {
195 bShowTime=Standard_True;
199 //aLevel = (n==3) ? Draw::Atoi(a[2]) : aNbInterfTypes-1;
200 //-------------------------------------------------------------------
201 char buf[256], aName1[32], aName2[32];
202 char aInterfTypes[10][4] = {
203 "V/V", "V/E", "E/E","V/F", "E/F", "F/F", "V/Z", "E/Z", "F/Z", "Z/Z"
206 Standard_Integer iErr, iCnt, n1, n2, iT;
207 TopAbs_ShapeEnum aType1, aType2;
208 BOPAlgo_CheckerSI aChecker;
209 BOPCol_ListOfShape aLS;
210 BOPDS_MapIteratorMapOfPassKey aItMPK;
212 if (aLevel < (aNbInterfTypes-1)) {
213 di << "Info:\nThe level of check is set to "
214 << aInterfTypes[aLevel] << ", i.e. intersection(s)\n";
216 for (i=aLevel+1; i<aNbInterfTypes; ++i) {
217 di << aInterfTypes[i];
218 if (i<aNbInterfTypes-1) {
222 di << " will not be checked.\n\n";
226 aChecker.SetArguments(aLS);
227 aChecker.SetLevelOfCheck(aLevel);
228 aChecker.SetRunParallel(bRunParallel);
229 aChecker.SetFuzzyValue(aTol);
238 iErr=aChecker.ErrorStatus();
240 const BOPDS_DS& aDS=*(aChecker.PDS());
242 const BOPDS_MapOfPassKey& aMPK=aDS.Interferences();
243 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
245 vector <BOPTest_Interf> aVec;
246 vector <BOPTest_Interf>::iterator aIt;
247 BOPTest_Interf aBInterf;
249 aItMPK.Initialize(aMPK);
250 for (; aItMPK.More(); aItMPK.Next()) {
251 const BOPDS_PassKey& aPK=aItMPK.Value();
253 if(aDS.IsNewShape(n1) || aDS.IsNewShape(n2)) {
257 const BOPDS_ShapeInfo& aSI1=aDS.ShapeInfo(n1);
258 const BOPDS_ShapeInfo& aSI2=aDS.ShapeInfo(n2);
259 aType1=aSI1.ShapeType();
260 aType2=aSI2.ShapeType();
262 iT=BOPDS_Tools::TypeToInteger(aType1, aType2);
264 aBInterf.SetIndices(n1, n2);
265 aBInterf.SetType(iT);
267 aVec.push_back(aBInterf);
270 sort( aVec.begin(), aVec.end(), less<BOPTest_Interf>());
273 for (aIt=aVec.begin(); aIt!=aVec.end(); aIt++) {
274 const BOPTest_Interf& aBI=*aIt;
277 if(aDS.IsNewShape(n1) || aDS.IsNewShape(n2)) {
281 const TopoDS_Shape& aS1=aDS.Shape(n1);
282 const TopoDS_Shape& aS2=aDS.Shape(n2);
285 di << aInterfTypes[iT] << ": ";
287 sprintf(aName1, "x%d", n1);
288 //sprintf(aName1, "x%d", iCnt);
289 DBRep::Set (aName1, aS1);
292 sprintf(aName2, "x%d", n2);
293 //sprintf(aName2, "x%d", iCnt);
294 DBRep::Set (aName2, aS2);
297 sprintf(buf, "%s %s \n", aName1, aName2);
302 di << "There were errors during the operation, ";
303 di << "so the list may be incomplete." << "\n";
307 di << " This shape seems to be OK." << "\n";
311 Sprintf(buf, " Tps: %7.2lf\n", aTimer.ElapsedTime());
316 //=======================================================================
317 //function : bopargcheck
319 //=======================================================================
320 Standard_Integer bopargcheck (Draw_Interpretor& di,
326 di << " Use >bopargcheck Shape1 [[Shape2] ";
327 di << "[-F/O/C/T/S/U] [/R|F|T|V|E|I|P|C|S]] [#BF]\n\n";
328 di << " -<Boolean Operation>" << "\n";
329 di << " F (fuse)" << "\n";
330 di << " O (common)" << "\n";
331 di << " C (cut)" << "\n";
332 di << " T (cut21)" << "\n";
333 di << " S (section)" << "\n";
334 di << " U (unknown)" << "\n";
335 di << " For example: \"bopargcheck s1 s2 -F\" enables" ;
336 di << " checking for Fuse operation" << "\n";
337 di << " default - section" << "\n" << "\n";
338 di << " /<Test Options>" << "\n";
339 di << " R (disable small edges (shrank range) test)" << "\n";
340 di << " F (disable faces verification test)" << "\n";
341 di << " T (disable tangent faces searching test)" << "\n";
342 di << " V (disable test possibility to merge vertices)" << "\n";
343 di << " E (disable test possibility to merge edges)" << "\n";
344 di << " I (disable self-interference test)" << "\n";
345 di << " P (disable shape type test)" << "\n";
346 di << " C (disable test for shape continuity)" << "\n";
347 di << " S (disable curve on surface check)" << "\n";
348 di << " For example: \"bopargcheck s1 s2 /RI\" disables ";
349 di << "small edge detection and self-intersection detection" << "\n";
350 di << " default - all options are enabled" << "\n" << "\n";
351 di << " #<Additional Test Options>" << "\n";
352 di << " B (stop test on first faulty found); default OFF" << "\n";
353 di << " F (full output for faulty shapes); default - output ";
354 di << "in a short format" << "\n" << "\n";
355 di << " NOTE: <Boolean Operation> and <Test Options> are ";
356 di << "used only for couple" << "\n";
357 di << " of argument shapes, except I and P options ";
358 di << "that are always used for" << "\n";
359 di << " couple of shapes as well as for ";
360 di <<"single shape test." << "\n";
364 TopoDS_Shape aS1 = DBRep::Get(a[1]);
367 di << "Error: null shape not allowed!" << "\n";
368 di << "Type bopargcheck without arguments for more ";
369 di <<"information" << "\n";
373 Standard_Boolean isBO = Standard_False;
374 Standard_Integer indxBO = 0;
375 Standard_Boolean isOP = Standard_False;
376 Standard_Integer indxOP = 0;
377 Standard_Boolean isAD = Standard_False;
378 Standard_Integer indxAD = 0;
379 Standard_Boolean isS2 = Standard_False;
380 Standard_Integer indxS2 = 0;
381 Standard_Real aTolerance = 0;
383 aTolerance=BOPTest_Objects::FuzzyValue();
386 Standard_Integer iIndex = 0;
387 for(iIndex = 2; iIndex < n; iIndex++) {
388 if(a[iIndex][0] == '-') {
389 isBO = Standard_True;
392 else if(a[iIndex][0] == '/') {
393 isOP = Standard_True;
396 else if(a[iIndex][0] == '#') {
397 isAD = Standard_True;
401 isS2 = Standard_True;
407 // set & test second shape
408 TopoDS_Shape aS22, aS2;
411 di << "Error: second shape should follow the first one!" << "\n";
412 di << "Type bopargcheck without arguments for more information" << "\n";
416 aS22 = DBRep::Get(a[2]);
418 di << "Error: second shape is null!" << "\n";
419 di << "Type bopargcheck without arguments for more information" << "\n";
426 BOPAlgo_ArgumentAnalyzer aChecker;
427 aChecker.SetFuzzyValue(aTolerance);
428 aChecker.SetShape1(aS1);
430 // set default options (always tested!) for single and couple shapes
431 aChecker.ArgumentTypeMode() = Standard_True;
432 aChecker.SelfInterMode() = Standard_True;
433 aChecker.SmallEdgeMode() = Standard_True;
434 aChecker.RebuildFaceMode() = Standard_True;
435 aChecker.ContinuityMode() = Standard_True;
436 aChecker.CurveOnSurfaceMode() = Standard_True;
438 // test & set options and operation for two shapes
440 aS2 = BRepBuilderAPI_Copy(aS22).Shape();
441 aChecker.SetShape2(aS2);
442 // set operation (default - Section)
444 if(a[indxBO][1] == 'F' || a[indxBO][1] == 'f') {
445 aChecker.OperationType() = BOPAlgo_FUSE;
447 else if(a[indxBO][1] == 'O' || a[indxBO][1] == 'o') {
448 aChecker.OperationType() = BOPAlgo_COMMON;
450 else if(a[indxBO][1] == 'C' || a[indxBO][1] == 'c') {
451 aChecker.OperationType() = BOPAlgo_CUT;
453 else if(a[indxBO][1] == 'T' || a[indxBO][1] == 't') {
454 aChecker.OperationType() = BOPAlgo_CUT21;
456 else if(a[indxBO][1] == 'S' || a[indxBO][1] == 's') {
457 aChecker.OperationType() = BOPAlgo_SECTION;
459 else if(a[indxBO][1] == 'U' || a[indxBO][1] == 'u') {
460 aChecker.OperationType() = BOPAlgo_UNKNOWN;
463 di << "Error: invalid boolean operation type!" << "\n";
464 di << "Type bopargcheck without arguments for more information" << "\n";
469 aChecker.OperationType() = BOPAlgo_SECTION;
471 aChecker.TangentMode() = Standard_True;
472 aChecker.MergeVertexMode() = Standard_True;
473 aChecker.MergeEdgeMode() = Standard_True;
476 // set options (default - all ON)
478 Standard_Integer ind = 1;
479 while(a[indxOP][ind] != 0) {
480 if(a[indxOP][ind] == 'R' || a[indxOP][ind] == 'r') {
481 aChecker.SmallEdgeMode() = Standard_False;
483 else if(a[indxOP][ind] == 'F' || a[indxOP][ind] == 'f') {
484 aChecker.RebuildFaceMode() = Standard_False;
486 else if(a[indxOP][ind] == 'T' || a[indxOP][ind] == 't') {
487 aChecker.TangentMode() = Standard_False;
489 else if(a[indxOP][ind] == 'V' || a[indxOP][ind] == 'v') {
490 aChecker.MergeVertexMode() = Standard_False;
492 else if(a[indxOP][ind] == 'E' || a[indxOP][ind] == 'e') {
493 aChecker.MergeEdgeMode() = Standard_False;
495 else if(a[indxOP][ind] == 'I' || a[indxOP][ind] == 'i') {
496 aChecker.SelfInterMode() = Standard_False;
498 else if(a[indxOP][ind] == 'P' || a[indxOP][ind] == 'p') {
499 aChecker.ArgumentTypeMode() = Standard_False;
501 else if(a[indxOP][ind] == 'C' || a[indxOP][ind] == 'c') {
502 aChecker.ContinuityMode() = Standard_False;
504 else if(a[indxOP][ind] == 'S' || a[indxOP][ind] == 's') {
505 aChecker.CurveOnSurfaceMode() = Standard_False;
508 di << "Error: invalid test option(s)!" << "\n";
509 di << "Type bopargcheck without arguments for more information" << "\n";
516 // set additional options
517 Standard_Boolean fullOutput = Standard_False;
519 Standard_Integer ind = 1;
520 while(a[indxAD][ind] != 0) {
521 if(a[indxAD][ind] == 'B' || a[indxAD][ind] == 'b') {
522 aChecker.StopOnFirstFaulty() = Standard_True;
524 else if(a[indxAD][ind] == 'F' || a[indxAD][ind] == 'f') {
525 fullOutput = Standard_True;
528 di << "Error: invalid additional test option(s)!" << "\n";
529 di << "Type bopargcheck without arguments for more information" << "\n";
539 // process result of checking
540 if(!aChecker.HasFaulty()) {
541 di << "Shape(s) seem(s) to be valid for BOP." << "\n";
545 di << "Faulties, that can not be treated by BOP, are detected." << "\n";
548 const BOPAlgo_ListOfCheckResult& aResultList = aChecker.GetCheckResult();
549 BOPAlgo_ListIteratorOfListOfCheckResult anIt(aResultList);
551 Standard_Integer S1_BadType = 0, S1_SelfInt = 0, S1_SmalE = 0, S1_BadF = 0, S1_BadV = 0, S1_BadE = 0;
552 Standard_Integer S1_SelfIntAll = 0, S1_SmalEAll = 0, S1_BadFAll = 0, S1_BadVAll = 0, S1_BadEAll = 0;
553 Standard_Integer S2_BadType = 0, S2_SelfInt = 0, S2_SmalE = 0, S2_BadF = 0, S2_BadV = 0, S2_BadE = 0;
554 Standard_Integer S2_SelfIntAll = 0, S2_SmalEAll = 0, S2_BadFAll = 0, S2_BadVAll = 0, S2_BadEAll = 0;
555 Standard_Integer S1_OpAb = 0, S2_OpAb = 0;
556 Standard_Integer S1_C0 = 0, S2_C0 = 0, S1_C0All = 0, S2_C0All = 0;
557 Standard_Integer S1_COnS = 0, S2_COnS = 0, S1_COnSAll = 0, S2_COnSAll = 0;
558 Standard_Boolean hasUnknown = Standard_False;
560 TCollection_AsciiString aS1SIBaseName("s1si_");
561 TCollection_AsciiString aS1SEBaseName("s1se_");
562 TCollection_AsciiString aS1BFBaseName("s1bf_");
563 TCollection_AsciiString aS1BVBaseName("s1bv_");
564 TCollection_AsciiString aS1BEBaseName("s1be_");
565 TCollection_AsciiString aS1C0BaseName("s1C0_");
566 TCollection_AsciiString aS1COnSBaseName("s1COnS_");
567 TCollection_AsciiString aS2SIBaseName("s2si_");
568 TCollection_AsciiString aS2SEBaseName("s2se_");
569 TCollection_AsciiString aS2BFBaseName("s2bf_");
570 TCollection_AsciiString aS2BVBaseName("s2bv_");
571 TCollection_AsciiString aS2BEBaseName("s2be_");
572 TCollection_AsciiString aS2C0BaseName("s2C0_");
573 TCollection_AsciiString aS2COnSBaseName("s2COnS_");
575 for(; anIt.More(); anIt.Next()) {
576 const BOPAlgo_CheckResult& aResult = anIt.Value();
577 const TopoDS_Shape & aSS1 = aResult.GetShape1();
578 const TopoDS_Shape & aSS2 = aResult.GetShape2();
579 const BOPCol_ListOfShape & aLS1 = aResult.GetFaultyShapes1();
580 const BOPCol_ListOfShape & aLS2 = aResult.GetFaultyShapes2();
581 Standard_Boolean isL1 = !aLS1.IsEmpty();
582 Standard_Boolean isL2 = !aLS2.IsEmpty();
584 switch(aResult.GetCheckStatus()) {
585 case BOPAlgo_BadType: {
586 if(!aSS1.IsNull()) S1_BadType++;
587 if(!aSS2.IsNull()) S2_BadType++;
590 case BOPAlgo_SelfIntersect: {
594 MakeShapeForFullOutput(aS1SIBaseName, S1_SelfInt, aLS1, S1_SelfIntAll, di);
599 MakeShapeForFullOutput(aS2SIBaseName, S2_SelfInt, aLS2, S2_SelfIntAll, di);
603 case BOPAlgo_TooSmallEdge: {
607 MakeShapeForFullOutput(aS1SEBaseName, S1_SmalE, aLS1, S1_SmalEAll, di);
612 MakeShapeForFullOutput(aS2SEBaseName, S2_SmalE, aLS2, S2_SmalEAll, di);
616 case BOPAlgo_NonRecoverableFace: {
620 MakeShapeForFullOutput(aS1BFBaseName, S1_BadF, aLS1, S1_BadFAll, di);
625 MakeShapeForFullOutput(aS2BFBaseName, S2_BadF, aLS2, S2_BadFAll, di);
629 case BOPAlgo_IncompatibilityOfVertex: {
633 MakeShapeForFullOutput(aS1BVBaseName, S1_BadV, aLS1, S1_BadVAll, di);
639 MakeShapeForFullOutput(aS2BVBaseName, S2_BadV, aLS2, S2_BadVAll, di);
644 case BOPAlgo_IncompatibilityOfEdge: {
648 MakeShapeForFullOutput(aS1BEBaseName, S1_BadE, aLS1, S1_BadEAll, di);
654 MakeShapeForFullOutput(aS2BEBaseName, S2_BadE, aLS2, S2_BadEAll, di);
659 case BOPAlgo_IncompatibilityOfFace: {
660 // not yet implemented
663 case BOPAlgo_GeomAbs_C0: {
667 MakeShapeForFullOutput(aS1C0BaseName, S1_C0, aLS1, S1_C0All, di);
673 MakeShapeForFullOutput(aS2C0BaseName, S2_C0, aLS2, S2_C0All, di);
678 case BOPAlgo_InvalidCurveOnSurface: {
682 Standard_Real aMaxDist = aResult.GetMaxDistance1();
683 Standard_Real aMaxParameter = aResult.GetMaxParameter1();
684 MakeShapeForFullOutput(aS1COnSBaseName, S1_COnS, aLS1, S1_COnSAll, di,
685 Standard_True, aMaxDist, aMaxParameter);
691 Standard_Real aMaxDist = aResult.GetMaxDistance2();
692 Standard_Real aMaxParameter = aResult.GetMaxParameter2();
693 MakeShapeForFullOutput(aS2COnSBaseName, S2_COnS, aLS2, S2_COnSAll, di,
694 Standard_True, aMaxDist, aMaxParameter);
699 case BOPAlgo_OperationAborted: {
700 if(!aSS1.IsNull()) S1_OpAb++;
701 if(!aSS2.IsNull()) S2_OpAb++;
704 case BOPAlgo_CheckUnknown:
706 hasUnknown = Standard_True;
712 Standard_Integer FS1 = S1_SelfInt + S1_SmalE + S1_BadF + S1_BadV + S1_BadE + S1_OpAb + S1_C0 + S1_COnS;
713 FS1 += (S1_BadType != 0) ? 1 : 0;
714 Standard_Integer FS2 = S2_SelfInt + S2_SmalE + S2_BadF + S2_BadV + S2_BadE + S2_OpAb + S2_C0 + S2_COnS;
715 FS2 += (S2_BadType != 0) ? 1 : 0;
717 // output for first shape
718 di << "Faulties for FIRST shape found : " << FS1 << "\n";
720 di << "---------------------------------" << "\n";
721 Standard_CString CString1;
725 CString1=aChecker.ArgumentTypeMode() ? "NO" : "DISABLED";
726 di << "Shapes are not suppotrted by BOP: " << CString1 << "\n";
727 Standard_CString CString2;
731 CString2=aChecker.SelfInterMode() ? "NO" : "DISABLED";
732 di << "Self-Intersections : " << CString2;
734 di << " Cases(" << S1_SelfInt << ") Total shapes(" << S1_SelfIntAll << ")" << "\n";
737 Standard_CString CString13;
741 CString13=aChecker.SelfInterMode() ? "NO" : "DISABLED";
742 di << "Check for SI has been aborted : " << CString13 << "\n";
743 Standard_CString CString3;
747 CString3=aChecker.SmallEdgeMode() ? "NO" : "DISABLED";
748 di << "Too small edges : " << CString3;
750 di << " Cases(" << S1_SmalE << ") Total shapes(" << S1_SmalEAll << ")" << "\n";
753 Standard_CString CString4;
757 CString4=aChecker.RebuildFaceMode() ? "NO" : "DISABLED";
758 di << "Bad faces : " << CString4;
760 di << " Cases(" << S1_BadF << ") Total shapes(" << S1_BadFAll << ")" << "\n";
763 Standard_CString CString5;
767 CString5=aChecker.MergeVertexMode() ? "NO" : "DISABLED";
768 di << "Too close vertices : " << CString5;
770 di << " Cases(" << S1_BadV << ") Total shapes(" << S1_BadVAll << ")" << "\n";
773 Standard_CString CString6;
777 CString6=aChecker.MergeEdgeMode() ? "NO" : "DISABLED";
778 di << "Too close edges : " << CString6;
780 di << " Cases(" << S1_BadE << ") Total shapes(" << S1_BadEAll << ")" << "\n";
783 Standard_CString CString15;
787 CString15=aChecker.ContinuityMode() ? "NO" : "DISABLED";
788 di << "Shapes with Continuity C0 : " << CString15;
790 di << " Cases(" << S1_C0 << ") Total shapes(" << S1_C0All << ")" << "\n";
794 Standard_CString CString17;
798 CString17=aChecker.CurveOnSurfaceMode() ? "NO" : "DISABLED";
799 di << "Invalid Curve on Surface : " << CString17;
801 di << " Cases(" << S1_COnS << ") Total shapes(" << S1_COnSAll << ")" << "\n";
806 // output for second shape
808 di << "Faulties for SECOND shape found : " << FS2 << "\n";
810 di << "---------------------------------" << "\n";
811 Standard_CString CString7;
815 CString7=aChecker.ArgumentTypeMode() ? "NO" : "DISABLED";
816 di << "Shapes are not suppotrted by BOP: " << CString7 << "\n";
817 Standard_CString CString8;
821 CString8=aChecker.SelfInterMode() ? "NO" : "DISABLED";
822 di << "Self-Intersections : " << CString8;
824 di << " Cases(" << S2_SelfInt << ") Total shapes(" << S2_SelfIntAll << ")" << "\n";
828 Standard_CString CString14;
832 CString14=aChecker.SelfInterMode() ? "NO" : "DISABLED";
833 di << "Check for SI has been aborted : " << CString14 << "\n";
834 Standard_CString CString9;
838 CString9=aChecker.SmallEdgeMode() ? "NO" : "DISABLED";
839 di << "Too small edges : " << CString9;
841 di << " Cases(" << S2_SmalE << ") Total shapes(" << S2_SmalEAll << ")" << "\n";
844 Standard_CString CString10;
848 CString10=aChecker.RebuildFaceMode() ? "NO" : "DISABLED";
849 di << "Bad faces : " << CString10;
851 di << " Cases(" << S2_BadF << ") Total shapes(" << S2_BadFAll << ")" << "\n";
854 Standard_CString CString11;
858 CString11=aChecker.MergeVertexMode() ? "NO" : "DISABLED";
859 di << "Too close vertices : " << CString11;
861 di << " Cases(" << S2_BadV << ") Total shapes(" << S2_BadVAll << ")" << "\n";
864 Standard_CString CString12;
868 CString12=aChecker.MergeEdgeMode() ? "NO" : "DISABLED";
869 di << "Too close edges : " << CString12;
871 di << " Cases(" << S2_BadE << ") Total shapes(" << S2_BadEAll << ")" << "\n";
874 Standard_CString CString16;
878 CString16=aChecker.ContinuityMode() ? "NO" : "DISABLED";
879 di << "Shapes with Continuity C0 : " << CString16;
881 di << " Cases(" << S2_C0 << ") Total shapes(" << S2_C0All << ")" << "\n";
885 Standard_CString CString18;
889 CString18=aChecker.CurveOnSurfaceMode() ? "NO" : "DISABLED";
890 di << "Invalid Curve on Surface : " << CString18;
892 di << " Cases(" << S2_COnS << ") Total shapes(" << S2_COnSAll << ")" << "\n";
899 di << "WARNING: The unexpected test break occurs!" << "\n";
907 //=======================================================================
910 //=======================================================================
911 Standard_Integer xdistef(Draw_Interpretor& di,
916 di << "use xdistef edge face\n";
920 const TopoDS_Shape aS1 = DBRep::Get(a[1]);
921 const TopoDS_Shape aS2 = DBRep::Get(a[2]);
923 if (aS1.IsNull() || aS2.IsNull()) {
924 di << "null shapes\n";
928 if (aS1.ShapeType() != TopAbs_EDGE ||
929 aS2.ShapeType() != TopAbs_FACE) {
930 di << "type mismatch\n";
934 Standard_Real aMaxDist = 0.0, aMaxPar = 0.0;
936 const TopoDS_Edge& anEdge = *(TopoDS_Edge*)&aS1;
937 const TopoDS_Face& aFace = *(TopoDS_Face*)&aS2;
939 if(!BOPTools_AlgoTools::ComputeTolerance
940 (aFace, anEdge, aMaxDist, aMaxPar)) {
941 di << "Tolerance cannot be computed\n";
945 di << "Max Distance = " << aMaxDist
946 << "; Parameter on curve = " << aMaxPar << "\n";
951 //=======================================================================
952 //function : checkcurveonsurf
954 //=======================================================================
955 Standard_Integer checkcurveonsurf(Draw_Interpretor& di,
960 di << "use checkcurveonsurf shape\n";
964 TopoDS_Shape aS = DBRep::Get(a[1]);
966 di << "null shape\n";
970 Standard_Integer nE, nF, anECounter, aFCounter;
971 Standard_Real aT, aTolE, aDMax;
972 TopExp_Explorer aExpF, aExpE;
973 char buf[200], aFName[10], anEName[10];
974 NCollection_DataMap<TopoDS_Shape, Standard_Real, TopTools_ShapeMapHasher> aDMETol;
975 BOPCol_DataMapOfShapeInteger aMSI;
980 aExpF.Init(aS, TopAbs_FACE);
981 for (; aExpF.More(); aExpF.Next()) {
982 const TopoDS_Face& aF = *(TopoDS_Face*)&aExpF.Current();
984 aExpE.Init(aF, TopAbs_EDGE);
985 for (; aExpE.More(); aExpE.Next()) {
986 const TopoDS_Edge& aE = *(TopoDS_Edge*)&aExpE.Current();
988 if (!BOPTools_AlgoTools::ComputeTolerance(aF, aE, aDMax, aT)) {
992 aTolE = BRep_Tool::Tolerance(aE);
993 if (!(aDMax > aTolE)) {
997 if (aDMETol.IsBound(aE)) {
998 Standard_Real& aD = aDMETol.ChangeFind(aE);
1004 aDMETol.Bind(aE, aDMax);
1007 if (anECounter == 0) {
1008 di << "Invalid curves on surface:\n";
1011 if (aMSI.IsBound(aE)) {
1020 if (aMSI.IsBound(aF)) {
1028 sprintf(anEName, "e_%d", nE);
1029 sprintf(aFName , "f_%d", nF);
1030 sprintf(buf, "edge %s on face %s (max dist: %3.16f, parameter on curve: %3.16f)\n",
1031 anEName, aFName, aDMax, aT);
1034 DBRep::Set(anEName, aE);
1035 DBRep::Set(aFName , aF);
1039 if (anECounter > 0) {
1040 di << "\n\nSugestions to fix the shape:\n";
1041 di << "explode " << a[1] << " e;\n";
1043 TopTools_MapOfShape M;
1044 aExpE.Init(aS, TopAbs_EDGE);
1045 for (anECounter = 0; aExpE.More(); aExpE.Next()) {
1046 const TopoDS_Shape& aE = aExpE.Current();
1052 if (!aDMETol.IsBound(aE)) {
1056 aTolE = aDMETol.Find(aE);
1058 sprintf(buf, "settolerance %s_%d %3.16f;\n", a[1], anECounter, aTolE);
1063 di << "This shape seems to be OK.\n";
1069 //=======================================================================
1070 //function : MakeShapeForFullOutput
1072 //=======================================================================
1073 void MakeShapeForFullOutput (const TCollection_AsciiString & aBaseName,
1074 const Standard_Integer aIndex,
1075 const BOPCol_ListOfShape & aList,
1076 Standard_Integer& aCount,
1077 Draw_Interpretor& di,
1078 Standard_Boolean bCurveOnSurf,
1079 Standard_Real aMaxDist,
1080 Standard_Real aMaxParameter)
1082 TCollection_AsciiString aNum(aIndex);
1083 TCollection_AsciiString aName = aBaseName + aNum;
1084 Standard_CString name = aName.ToCString();
1086 TopoDS_Compound cmp;
1088 BB.MakeCompound(cmp);
1090 BOPCol_ListIteratorOfListOfShape anIt(aList);
1091 for(; anIt.More(); anIt.Next()) {
1092 const TopoDS_Shape & aS = anIt.Value();
1096 di << "Made faulty shape: " << name;
1099 di << " (MaxDist = " << aMaxDist
1100 << ", MaxPar = " << aMaxParameter << ")";
1105 DBRep::Set(name, cmp);