0024220: bopargcheck returns valid for C0 shape but results of boolean operations...
[occt.git] / src / BOPTest / BOPTest_CheckCommands.cxx
1 // Created by: Peter KURNEV
2 // Copyright (c) 2010-2012 OPEN CASCADE SAS
3 //
4 // The content of this file is subject to the Open CASCADE Technology Public
5 // License Version 6.5 (the "License"). You may not use the content of this file
6 // except in compliance with the License. Please obtain a copy of the License
7 // at http://www.opencascade.org and read it completely before using this file.
8 //
9 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
10 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
11 //
12 // The Original Code and all software distributed under the License is
13 // distributed on an "AS IS" basis, without warranty of any kind, and the
14 // Initial Developer hereby disclaims all such warranties, including without
15 // limitation, any warranties of merchantability, fitness for a particular
16 // purpose or non-infringement. Please see the License for the specific terms
17 // and conditions governing the rights and limitations under the License.
18
19
20 #include <BOPTest.ixx>
21 #include <TCollection_AsciiString.hxx>
22
23 #include <gp_Pnt.hxx>
24
25 #include <TopoDS_Shape.hxx>
26 #include <TopoDS_Compound.hxx>
27 #include <BRep_Builder.hxx>
28
29 #include <DBRep.hxx>
30
31 #include <Geom_Geometry.hxx>
32 #include <Geom_CartesianPoint.hxx>
33
34 #include <Draw.hxx>
35 #include <DrawTrSurf.hxx>
36 #include <BOPAlgo_CheckerSI.hxx>
37 #include <BOPDS_VectorOfInterfVV.hxx>
38 #include <BOPDS_VectorOfInterfVE.hxx>
39 #include <BOPDS_VectorOfInterfEE.hxx>
40 #include <BOPDS_VectorOfInterfVF.hxx>
41 #include <BOPDS_VectorOfInterfEF.hxx>
42 #include <BOPDS_VectorOfInterfFF.hxx>
43 #include <BOPDS_DS.hxx>
44
45 #include <BOPCol_ListOfShape.hxx>
46 #include <BOPAlgo_ArgumentAnalyzer.hxx>
47 #include <BOPAlgo_CheckResult.hxx>
48 #include <BRepBuilderAPI_Copy.hxx>
49
50 static 
51   Standard_Integer bopcheck (Draw_Interpretor&, Standard_Integer, const char** );
52
53 static 
54   Standard_Integer bopargcheck (Draw_Interpretor&, Standard_Integer, const char** );
55 //
56
57 //=======================================================================
58 //function : CheckCommands
59 //purpose  : 
60 //=======================================================================
61   void  BOPTest::CheckCommands(Draw_Interpretor& theCommands)
62 {
63   static Standard_Boolean done = Standard_False;
64   if (done) 
65     return;
66
67   done = Standard_True;
68   // Chapter's name
69   const char* g = "CCR commands";
70   //
71   theCommands.Add("bopcheck" ,  "Use >bopcheck Shape [level of check: 0(V/V) - 5(all)]",  __FILE__, bopcheck, g);
72   theCommands.Add("bopargcheck" ,  "Use bopargcheck without parameters to get ",  __FILE__, bopargcheck, g);
73 }
74
75 //=======================================================================
76 //function : bopcheck
77 //purpose  : 
78 //=======================================================================
79 Standard_Integer bopcheck (Draw_Interpretor& di, Standard_Integer n,  const char** a )
80 {
81   
82   if (n<2) {
83     di << " Use >bopcheck Shape [level of check: 0 - 5" << "\n";
84     di << " The level of check defines which interferferences will be checked:\n"; 
85     di << " 0 - only V/V;\n"; 
86     di << " 1 - V/V and V/E;\n";
87     di << " 2 - V/V, V/E and E/E;\n"; 
88     di << " 3 - V/V, V/E, E/E and V/F;\n"; 
89     di << " 4 - V/V, V/E, E/E, V/F and E/F;\n"; 
90     di << " 5 - all interferences, default value.\n"; 
91     return 1;
92   }
93
94   TopoDS_Shape aS1 = DBRep::Get(a[1]);
95   if (aS1.IsNull()) {
96     di << "null shapes are not allowed here!";
97     return 1;
98   }
99   TopoDS_Shape aS = BRepBuilderAPI_Copy(aS1).Shape();
100   //
101   Standard_Integer iErr, aTypeInt, i, ind, j;
102   Standard_Integer nI1, nI2, theLevelOfCheck;
103   Standard_Boolean bSelfInt, bFFInt;
104   char buf[256];
105   char type[6][4] = {"V/V", "V/E", "E/E","V/F", "E/F", "F/F"};
106
107   theLevelOfCheck = (n==3) ? Draw::Atoi(a[2]) : 5;
108   if (theLevelOfCheck >= 0 && theLevelOfCheck < 5) {
109     di << "Info:\nThe level of check is set to " << type[theLevelOfCheck] 
110        << ", i.e. intersection(s)\n";
111     for (i=theLevelOfCheck+1; i<=5; ++i) {
112       di << type[i];
113       if (i<5) {
114         di << ", ";
115       }
116     }
117     di << " will not be checked.\n\n";
118   }
119   
120   BOPAlgo_CheckerSI aChecker;
121   BOPCol_ListOfShape anArgs;
122   anArgs.Append(aS);
123   aChecker.SetArguments(anArgs);
124   aChecker.SetLevelOfCheck(theLevelOfCheck);
125   //
126   aChecker.Perform();
127   iErr = aChecker.ErrorStatus();
128   //
129   const BOPDS_PDS& theDS = aChecker.PDS();
130   BOPDS_VectorOfInterfVV& aVVs=theDS->InterfVV();
131   BOPDS_VectorOfInterfVE& aVEs=theDS->InterfVE();
132   BOPDS_VectorOfInterfEE& aEEs=theDS->InterfEE();
133   BOPDS_VectorOfInterfVF& aVFs=theDS->InterfVF();
134   BOPDS_VectorOfInterfEF& aEFs=theDS->InterfEF();
135   BOPDS_VectorOfInterfFF& aFFs=theDS->InterfFF();
136   //
137   Standard_Integer aNb[6] = {aVVs.Extent(), aVEs.Extent(), aEEs.Extent(), 
138                              aVFs.Extent(), aEFs.Extent(), aFFs.Extent()};
139   //
140   bSelfInt = Standard_False;
141   ind = 0;
142   for (aTypeInt = 0; aTypeInt < 6; ++aTypeInt) {
143     for (i = 0; i < aNb[aTypeInt]; ++i) {
144       BOPDS_Interf* aInt = (aTypeInt==0) ? (BOPDS_Interf*)(&aVVs(i)) : 
145                           ((aTypeInt==1) ? (BOPDS_Interf*)(&aVEs(i)) :
146                           ((aTypeInt==2) ? (BOPDS_Interf*)(&aEEs(i)) : 
147                           ((aTypeInt==3) ? (BOPDS_Interf*)(&aVFs(i)) :
148                           ((aTypeInt==4) ? (BOPDS_Interf*)(&aEFs(i)) : (BOPDS_Interf*)(&aFFs(i))))));
149       //
150       nI1 = aInt->Index1();
151       nI2 = aInt->Index2();
152       if (nI1 == nI2) {
153         continue;
154       }
155       //
156       if (aTypeInt == 4) {
157         BOPDS_InterfEF& aEF=aEFs(i);
158         if (aEF.CommonPart().Type()==TopAbs_SHAPE) {
159           continue;
160         }
161       }
162       //
163       const TopoDS_Shape& aS1 = theDS->Shape(nI1);
164       const TopoDS_Shape& aS2 = theDS->Shape(nI2);
165       //
166       if (aTypeInt == 5) {
167         bFFInt = Standard_False;
168         BOPDS_InterfFF& aFF = aFFs(i);
169         BOPDS_VectorOfPoint& aVP=aFF.ChangePoints();
170         Standard_Integer aNbP=aVP.Extent();
171         BOPDS_VectorOfCurve& aVC=aFF.ChangeCurves();
172         Standard_Integer aNbC=aVC.Extent();
173         if (!aNbP && !aNbC) {
174           continue;
175         }
176         for (j=0; j<aNbC; ++j) {
177           BOPDS_Curve& aNC=aVC(j);
178           BOPDS_ListOfPaveBlock& aLPBC=aNC.ChangePaveBlocks();
179           if (aLPBC.Extent()) {
180             bFFInt = Standard_True;
181             break;
182           }
183         }
184         if (!bFFInt) {
185           continue;
186         }
187       }
188       //
189       di << type[aTypeInt] << ":";
190       //
191       TCollection_AsciiString aBaseName("x");
192       TCollection_AsciiString anumbername(ind);
193       TCollection_AsciiString aXName = aBaseName + anumbername;
194       Standard_CString aname=aXName.ToCString();
195       DBRep::Set (aname, aS1);
196       ++ind;
197       TCollection_AsciiString anumbername1(ind);
198       TCollection_AsciiString aXName1 = aBaseName + anumbername1;
199       Standard_CString aname1=aXName1.ToCString();
200       DBRep::Set (aname1, aS2);
201       ++ind;
202       //
203       Sprintf(buf, "%s, %s \n", aname, aname1);
204       di << buf;
205       bSelfInt = Standard_True;
206     }
207   }
208   
209   if (iErr) {
210     di << "There were errors during the operation, so the list may be incomplete." << "\n";
211   }
212   
213   if (!bSelfInt) {
214     di << " This shape seems to be OK." << "\n";
215   }
216   
217   return 0;
218 }
219
220 static void MakeShapeForFullOutput(const TCollection_AsciiString & aBaseName,
221                                    const Standard_Integer          aIndex,
222                                    const BOPCol_ListOfShape &    aList,
223                                    Standard_Integer&               aCount,
224                                    Draw_Interpretor&               di)
225 {
226   TCollection_AsciiString aNum(aIndex);
227   TCollection_AsciiString aName = aBaseName + aNum;
228   Standard_CString name = aName.ToCString();
229
230   TopoDS_Compound cmp;
231   BRep_Builder BB;
232   BB.MakeCompound(cmp);
233
234   BOPCol_ListIteratorOfListOfShape anIt(aList);
235   for(; anIt.More(); anIt.Next()) {
236     const TopoDS_Shape & aS = anIt.Value();
237     BB.Add(cmp, aS);
238     aCount++;
239   }
240   di << "Made faulty shape: " << name << "\n";
241   DBRep::Set(name, cmp);
242 }
243
244
245 Standard_Integer bopargcheck (Draw_Interpretor& di, Standard_Integer n,  const char** a )
246 {
247   if (n<2) {
248     di << "\n";
249     di << " Use >bopargcheck Shape1 [[Shape2] [-F/O/C/T/S/U] [/R|F|T|V|E|I|P]] [#BF]" << "\n" << "\n";
250     di << " -<Boolean Operation>" << "\n";
251     di << " F (fuse)" << "\n";
252     di << " O (common)" << "\n";
253     di << " C (cut)" << "\n";
254     di << " T (cut21)" << "\n";
255     di << " S (section)" << "\n";
256     di << " U (unknown)" << "\n";
257     di << " For example: \"bopargcheck s1 s2 -F\" enables checking for Fuse operation" << "\n";
258     di << " default - section" << "\n" << "\n";
259     di << " /<Test Options>" << "\n";
260     di << " R (disable small edges (shrank range) test)" << "\n";
261     di << " F (disable faces verification test)" << "\n";
262     di << " T (disable tangent faces searching test)" << "\n";
263     di << " V (disable test possibility to merge vertices)" << "\n";
264     di << " E (disable test possibility to merge edges)" << "\n";
265     di << " I (disable self-interference test)" << "\n";
266     di << " P (disable shape type test)" << "\n";
267     di << " C (disable test for shape continuity)" << "\n";
268     di << " For example: \"bopargcheck s1 s2 /RI\" disables small edge detection and self-intersection detection" << "\n";
269     di << " default - all options are enabled" << "\n" << "\n";
270     di << " #<Additional Test Options>" << "\n";
271     di << " B (stop test on first faulty found); default OFF" << "\n";
272     di << " F (full output for faulty shapes); default - output in a short format" << "\n" << "\n";
273     di << " NOTE: <Boolean Operation> and <Test Options> are used only for couple" << "\n";
274     di << "       of argument shapes, except I and P options that are always used for" << "\n";
275     di << "       couple of shapes as well as for single shape test." << "\n";
276     return 1;
277   }
278
279   TopoDS_Shape aS11 = DBRep::Get(a[1]);
280
281   if(aS11.IsNull()) {
282     di << "Error: null shape not allowed!" << "\n";
283     di << "Type bopargcheck without arguments for more information" << "\n";
284     return 1;
285   }
286   TopoDS_Shape aS1 = BRepBuilderAPI_Copy(aS11).Shape();
287   
288
289   Standard_Boolean isBO = Standard_False;
290   Standard_Integer indxBO = 0;
291   Standard_Boolean isOP = Standard_False;
292   Standard_Integer indxOP = 0;
293   Standard_Boolean isAD = Standard_False;
294   Standard_Integer indxAD = 0;
295   Standard_Boolean isS2 = Standard_False;
296   Standard_Integer indxS2 = 0;
297
298   if(n >= 3) {
299     Standard_Integer iIndex = 0;
300     for(iIndex = 2; iIndex < n; iIndex++) {
301       if(a[iIndex][0] == '-')
302       {
303         isBO = Standard_True;
304         indxBO = iIndex;
305       }
306       //else if(a[iIndex][0] == '+')
307       else if(a[iIndex][0] == '/')
308       {
309         isOP = Standard_True;
310         indxOP = iIndex;
311       }
312       else if(a[iIndex][0] == '#')
313       {
314         isAD = Standard_True;
315         indxAD = iIndex;
316       }
317       else {
318         isS2 = Standard_True;
319         indxS2 = iIndex;
320       }
321     }
322   }
323
324   // set & test second shape
325   TopoDS_Shape aS22, aS2;
326   if(isS2) {
327     if(indxS2 != 2) {
328       di << "Error: second shape should follow the first one!" << "\n";
329       di << "Type bopargcheck without arguments for more information" << "\n";
330       return 1;
331     }
332     else {
333       aS22 = DBRep::Get(a[2]);
334       if(aS22.IsNull()) {
335         di << "Error: second shape is null!" << "\n";
336         di << "Type bopargcheck without arguments for more information" << "\n";
337         return 1;
338       }
339     }
340   }
341
342   // init checker
343   BOPAlgo_ArgumentAnalyzer aChecker;
344   aChecker.SetShape1(aS1);
345
346   // set default options (always tested!) for single and couple shapes
347   aChecker.ArgumentTypeMode() = Standard_True;
348   aChecker.SelfInterMode()    = Standard_True;
349   aChecker.SmallEdgeMode()    = Standard_True;
350   aChecker.RebuildFaceMode()  = Standard_True;
351   aChecker.ContinuityMode()   = Standard_True;
352
353   // test & set options and operation for two shapes
354   if(!aS22.IsNull()) {
355     aS2 = BRepBuilderAPI_Copy(aS22).Shape();
356     aChecker.SetShape2(aS2);
357     // set operation (default - Section)
358     if(isBO) {
359       if(a[indxBO][1] == 'F' || a[indxBO][1] == 'f') {
360         aChecker.OperationType() = BOPAlgo_FUSE;
361       }
362       else if(a[indxBO][1] == 'O' || a[indxBO][1] == 'o') {
363         aChecker.OperationType() = BOPAlgo_COMMON;
364       }
365       else if(a[indxBO][1] == 'C' || a[indxBO][1] == 'c') {
366         aChecker.OperationType() = BOPAlgo_CUT;
367       }
368       else if(a[indxBO][1] == 'T' || a[indxBO][1] == 't') {
369          aChecker.OperationType() = BOPAlgo_CUT21;
370       }
371       else if(a[indxBO][1] == 'S' || a[indxBO][1] == 's') {
372          aChecker.OperationType() = BOPAlgo_SECTION;
373       }
374       else if(a[indxBO][1] == 'U' || a[indxBO][1] == 'u') {
375         aChecker.OperationType() = BOPAlgo_UNKNOWN;
376       }
377       else {
378         di << "Error: invalid boolean operation type!" << "\n";
379         di << "Type bopargcheck without arguments for more information" << "\n";
380         return 1;
381       }
382     }
383     else
384       aChecker.OperationType() = BOPAlgo_SECTION;
385
386     aChecker.TangentMode()     = Standard_True;
387     aChecker.MergeVertexMode() = Standard_True;
388     aChecker.MergeEdgeMode()   = Standard_True;
389   }
390   
391   // set options (default - all ON)
392   if(isOP) {
393     Standard_Integer ind = 1;
394     while(a[indxOP][ind] != 0) {
395       if(a[indxOP][ind] == 'R' || a[indxOP][ind] == 'r') {
396         aChecker.SmallEdgeMode() = Standard_False;
397       }
398       else if(a[indxOP][ind] == 'F' || a[indxOP][ind] == 'f') {
399         aChecker.RebuildFaceMode() = Standard_False;
400       }
401       else if(a[indxOP][ind] == 'T' || a[indxOP][ind] == 't') {
402         aChecker.TangentMode() = Standard_False;
403       }
404       else if(a[indxOP][ind] == 'V' || a[indxOP][ind] == 'v') {
405         aChecker.MergeVertexMode() = Standard_False;
406       }
407       else if(a[indxOP][ind] == 'E' || a[indxOP][ind] == 'e') {
408         aChecker.MergeEdgeMode() = Standard_False;
409       }
410       else if(a[indxOP][ind] == 'I' || a[indxOP][ind] == 'i') {
411         aChecker.SelfInterMode() = Standard_False;
412       }
413       else if(a[indxOP][ind] == 'P' || a[indxOP][ind] == 'p') {
414         aChecker.ArgumentTypeMode() = Standard_False;
415       }
416       else if(a[indxOP][ind] == 'C' || a[indxOP][ind] == 'c') {
417         aChecker.ContinuityMode() = Standard_False;
418       }
419       else {
420         di << "Error: invalid test option(s)!" << "\n";
421         di << "Type bopargcheck without arguments for more information" << "\n";
422         return 1;
423       }
424       ind++;
425     }
426   }
427
428   // set additional options
429   Standard_Boolean fullOutput = Standard_False;
430   if(isAD) {
431     Standard_Integer ind = 1;
432     while(a[indxAD][ind] != 0) {
433       if(a[indxAD][ind] == 'B' || a[indxAD][ind] == 'b') {
434         aChecker.StopOnFirstFaulty() = Standard_True;
435       }
436       else if(a[indxAD][ind] == 'F' || a[indxAD][ind] == 'f') {
437         fullOutput = Standard_True;
438       }
439       else {
440         di << "Error: invalid additional test option(s)!" << "\n";
441         di << "Type bopargcheck without arguments for more information" << "\n";
442         return 1;
443       }
444       ind++;
445     }
446   }
447
448   // run checker
449   aChecker.Perform();
450
451   // process result of checking
452   if(!aChecker.HasFaulty()) {
453     di << "Shape(s) seem(s) to be valid for BOP."  << "\n";
454   }
455   else {
456     if(!fullOutput) {
457       di << "Faulties, that can not be treated by BOP, are detected." << "\n"; 
458     }
459     else {
460       const BOPAlgo_ListOfCheckResult& aResultList = aChecker.GetCheckResult();
461       BOPAlgo_ListIteratorOfListOfCheckResult anIt(aResultList);
462
463       Standard_Integer S1_BadType = 0, S1_SelfInt = 0, S1_SmalE = 0, S1_BadF = 0, S1_BadV = 0, S1_BadE = 0;
464       Standard_Integer S1_SelfIntAll = 0, S1_SmalEAll = 0, S1_BadFAll = 0, S1_BadVAll = 0, S1_BadEAll = 0;
465       Standard_Integer S2_BadType = 0, S2_SelfInt = 0, S2_SmalE = 0, S2_BadF = 0, S2_BadV = 0, S2_BadE = 0;
466       Standard_Integer S2_SelfIntAll = 0, S2_SmalEAll = 0, S2_BadFAll = 0, S2_BadVAll = 0, S2_BadEAll = 0;
467       Standard_Integer S1_OpAb = 0, S2_OpAb = 0;
468       Standard_Integer S1_C0 = 0, S2_C0 = 0, S1_C0All = 0, S2_C0All = 0;
469       Standard_Boolean hasUnknown = Standard_False;
470
471       TCollection_AsciiString aS1SIBaseName("s1si_");
472       TCollection_AsciiString aS1SEBaseName("s1se_");
473       TCollection_AsciiString aS1BFBaseName("s1bf_");
474       TCollection_AsciiString aS1BVBaseName("s1bv_");
475       TCollection_AsciiString aS1BEBaseName("s1be_");
476       TCollection_AsciiString aS1C0BaseName("s1C0_");
477       TCollection_AsciiString aS2SIBaseName("s2si_");
478       TCollection_AsciiString aS2SEBaseName("s2se_");
479       TCollection_AsciiString aS2BFBaseName("s2bf_");
480       TCollection_AsciiString aS2BVBaseName("s2bv_");
481       TCollection_AsciiString aS2BEBaseName("s2be_");
482       TCollection_AsciiString aS2C0BaseName("s2C0_");
483
484       for(; anIt.More(); anIt.Next()) {
485         const BOPAlgo_CheckResult& aResult = anIt.Value();
486         const TopoDS_Shape & aSS1 = aResult.GetShape1();
487         const TopoDS_Shape & aSS2 = aResult.GetShape2();
488         const BOPCol_ListOfShape & aLS1 = aResult.GetFaultyShapes1();
489         const BOPCol_ListOfShape & aLS2 = aResult.GetFaultyShapes2();
490         Standard_Boolean isL1 = !aLS1.IsEmpty();
491         Standard_Boolean isL2 = !aLS2.IsEmpty();
492
493         switch(aResult.GetCheckStatus()) {
494         case BOPAlgo_BadType: {
495           if(!aSS1.IsNull()) S1_BadType++;
496           if(!aSS2.IsNull()) S2_BadType++;
497         }
498           break;
499         case BOPAlgo_SelfIntersect: {
500           if(!aSS1.IsNull()) {
501             S1_SelfInt++;
502             if(isL1)
503               MakeShapeForFullOutput(aS1SIBaseName, S1_SelfInt, aLS1, S1_SelfIntAll, di);
504           }
505           if(!aSS2.IsNull()) {
506             S2_SelfInt++;
507             if(isL2)
508               MakeShapeForFullOutput(aS2SIBaseName, S2_SelfInt, aLS2, S2_SelfIntAll, di);
509           }
510         }
511           break;
512         case BOPAlgo_TooSmallEdge: {
513           if(!aSS1.IsNull()) {
514             S1_SmalE++;
515             if(isL1)
516               MakeShapeForFullOutput(aS1SEBaseName, S1_SmalE, aLS1, S1_SmalEAll, di);
517           }
518           if(!aSS2.IsNull()) {
519             S2_SmalE++;
520             if(isL2)
521               MakeShapeForFullOutput(aS2SEBaseName, S2_SmalE, aLS2, S2_SmalEAll, di);
522           }
523         }
524           break;
525         case BOPAlgo_NonRecoverableFace: {
526           if(!aSS1.IsNull()) {
527             S1_BadF++;
528             if(isL1)
529               MakeShapeForFullOutput(aS1BFBaseName, S1_BadF, aLS1, S1_BadFAll, di);
530           }
531           if(!aSS2.IsNull()) {
532             S2_BadF++;
533             if(isL2)
534               MakeShapeForFullOutput(aS2BFBaseName, S2_BadF, aLS2, S2_BadFAll, di);
535           }
536         }
537           break;
538         case BOPAlgo_IncompatibilityOfVertex: {
539           if(!aSS1.IsNull()) {
540             S1_BadV++;
541             if(isL1) {
542               MakeShapeForFullOutput(aS1BVBaseName, S1_BadV, aLS1, S1_BadVAll, di);
543             }
544           }
545           if(!aSS2.IsNull()) {
546             S2_BadV++;
547             if(isL2){
548               MakeShapeForFullOutput(aS2BVBaseName, S2_BadV, aLS2, S2_BadVAll, di);
549             }
550           }
551         }
552           break;
553         case BOPAlgo_IncompatibilityOfEdge: {
554           if(!aSS1.IsNull()) {
555             S1_BadE++;
556             if(isL1) {
557               MakeShapeForFullOutput(aS1BEBaseName, S1_BadE, aLS1, S1_BadEAll, di);
558             }
559           }
560           if(!aSS2.IsNull()) {
561             S2_BadE++;
562             if(isL2) {
563               MakeShapeForFullOutput(aS2BEBaseName, S2_BadE, aLS2, S2_BadEAll, di);
564             }
565           }
566         }
567           break;
568         case BOPAlgo_IncompatibilityOfFace: {
569           // not yet implemented
570         }
571           break;
572         case BOPAlgo_GeomAbs_C0: {
573           if(!aSS1.IsNull()) {
574             S1_C0++;
575             if(isL1) {
576               MakeShapeForFullOutput(aS1C0BaseName, S1_C0, aLS1, S1_C0All, di);
577             }
578           }
579           if(!aSS2.IsNull()) {
580             S2_C0++;
581             if(isL2) {
582               MakeShapeForFullOutput(aS2C0BaseName, S2_C0, aLS2, S2_C0All, di);
583             }
584           }
585         }
586           break;
587         case BOPAlgo_OperationAborted: {
588           if(!aSS1.IsNull()) S1_OpAb++;
589           if(!aSS2.IsNull()) S2_OpAb++;
590         }
591           break;
592         case BOPAlgo_CheckUnknown:
593         default: {
594           hasUnknown = Standard_True;
595         }
596           break;
597         } // switch
598       }// faulties
599
600       Standard_Integer FS1 = S1_SelfInt + S1_SmalE + S1_BadF + S1_BadV + S1_BadE + S1_OpAb + S1_C0;
601       FS1 += (S1_BadType != 0) ? 1 : 0;
602       Standard_Integer FS2 = S2_SelfInt + S2_SmalE + S2_BadF + S2_BadV + S2_BadE + S2_OpAb + S2_C0;
603       FS2 += (S2_BadType != 0) ? 1 : 0;
604       
605       // output for first shape
606       di << "Faulties for FIRST  shape found : " << FS1 << "\n";
607       if(FS1 != 0) {
608         di << "---------------------------------" << "\n";
609         Standard_CString CString1;
610         if (S1_BadType != 0)
611           CString1="YES";
612         else
613           CString1="NO";
614         di << "Shapes are not suppotrted by BOP: " << CString1 << "\n";
615         Standard_CString CString2;
616         if (S1_SelfInt != 0)
617           CString2="YES";
618         else
619           CString2="NO";
620         di << "Self-Intersections              : " << CString2;
621         if(S1_SelfInt != 0)
622           di << "  Cases(" << S1_SelfInt << ")  Total shapes(" << S1_SelfIntAll << ")" << "\n";
623         else
624           di << "\n";
625         Standard_CString CString13;
626         if (S1_OpAb != 0)
627           CString13="YES";
628         else
629           CString13="NO";
630         di << "Check for SI has been aborted   : " << CString13 << "\n";
631         Standard_CString CString3;
632         if (S1_SmalE != 0)
633           CString3="YES";
634         else
635           CString3="NO";
636         di << "Too small edges                 : " << CString3;
637         if(S1_SmalE != 0)
638           di << "  Cases(" << S1_SmalE << ")  Total shapes(" << S1_SmalEAll << ")" << "\n";
639         else
640           di << "\n";
641         Standard_CString CString4;
642         if (S1_BadF != 0)
643           CString4="YES";
644         else
645           CString4="NO";
646         di << "Bad faces                       : " << CString4;
647         if(S1_BadF != 0)
648           di << "  Cases(" << S1_BadF << ")  Total shapes(" << S1_BadFAll << ")" << "\n";
649         else
650           di << "\n";
651         Standard_CString CString5;
652         if (S1_BadV != 0)
653           CString5="YES";
654         else
655           CString5="NO";
656         di << "Too close vertices              : " << CString5;
657         if(S1_BadV != 0)
658           di << "  Cases(" << S1_BadV << ")  Total shapes(" << S1_BadVAll << ")" << "\n";
659         else
660           di << "\n";
661         Standard_CString CString6;
662         if (S1_BadE != 0)
663           CString6="YES";
664         else
665           CString6="NO";
666         di << "Too close edges                 : " << CString6;
667         if(S1_BadE != 0)
668           di << "  Cases(" << S1_BadE << ")  Total shapes(" << S1_BadEAll << ")" << "\n";
669         else
670           di << "\n";
671         Standard_CString CString15;
672         if (S1_C0 != 0)
673           CString15="YES";
674         else
675           CString15="NO";
676         di << "Shapes with Continuity C0       : " << CString15;
677         if(S1_C0 != 0)
678           di << "  Cases(" << S1_C0 << ")  Total shapes(" << S1_C0All << ")" << "\n";
679         else
680           di << "\n";
681       }
682
683       // output for second shape
684       di << "\n";
685       di << "Faulties for SECOND  shape found : " << FS2 << "\n";
686       if(FS2 != 0) {
687         di << "---------------------------------" << "\n";
688         Standard_CString CString7;
689         if (S2_BadType != 0)
690           CString7="YES";
691         else
692           CString7="NO";
693         di << "Shapes are not suppotrted by BOP: " << CString7 << "\n";
694         Standard_CString CString8;
695         if (S2_SelfInt != 0)
696           CString8="YES";
697         else
698           CString8="NO";
699         di << "Self-Intersections              : " << CString8;
700         if(S2_SelfInt != 0)
701           di << "  Cases(" << S2_SelfInt << ")  Total shapes(" << S2_SelfIntAll << ")" << "\n";
702         else
703           di << "\n";
704
705         Standard_CString CString14;
706         if (S2_OpAb != 0)
707           CString14="YES";
708         else
709           CString14="NO";
710         di << "Check for SI has been aborted   : " << CString14 << "\n";
711         Standard_CString CString9;
712         if (S2_SmalE != 0)
713           CString9="YES";
714         else
715           CString9="NO";
716         di << "Too small edges                 : " << CString9;
717         if(S2_SmalE != 0)
718           di << "  Cases(" << S2_SmalE << ")  Total shapes(" << S2_SmalEAll << ")" << "\n";
719         else
720           di << "\n";
721         Standard_CString CString10;
722         if (S2_BadF != 0)
723           CString10="YES";
724         else
725           CString10="NO";
726         di << "Bad faces                       : " << CString10;
727         if(S2_BadF != 0)
728           di << "  Cases(" << S2_BadF << ")  Total shapes(" << S2_BadFAll << ")" << "\n";
729         else
730           di << "\n";
731         Standard_CString CString11;
732         if (S2_BadV != 0)
733           CString11="YES";
734         else
735           CString11="NO";
736         di << "Too close vertices              : " << CString11;
737         if(S2_BadV != 0)
738           di << "  Cases(" << S2_BadV << ")  Total shapes(" << S2_BadVAll << ")" << "\n";
739         else
740           di << "\n";
741         Standard_CString CString12;
742         if (S2_BadE != 0)
743           CString12="YES";
744         else
745           CString12="NO";
746         di << "Too close edges                 : " << CString12;
747         if(S2_BadE != 0)
748           di << "  Cases(" << S2_BadE << ")  Total shapes(" << S2_BadEAll << ")" << "\n";
749         else
750           di << "\n";
751         Standard_CString CString16;
752         if (S2_C0 != 0)
753           CString16="YES";
754         else
755           CString16="NO";
756         di << "Shapes with Continuity C0       : " << CString16;
757         if(S2_C0 != 0)
758           di << "  Cases(" << S2_C0 << ")  Total shapes(" << S2_C0All << ")" << "\n";
759         else
760           di << "\n";
761
762         // warning
763         di << "\n";
764         if(hasUnknown)
765           di << "WARNING: The unexpected test break occurs!" << "\n";
766       }
767     } // full output
768   } // has faulties
769
770   return 0;
771 }