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