0030611: Coding Rules - eliminate GCC compiler warnings -Wcatch-value
[occt.git] / src / BOPAlgo / BOPAlgo_ArgumentAnalyzer.cxx
1 // Created on: 2004-09-02
2 // Copyright (c) 2004-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 <BOPAlgo_ArgumentAnalyzer.hxx>
16 #include <BOPAlgo_BuilderFace.hxx>
17 #include <BOPAlgo_CheckerSI.hxx>
18 #include <BOPAlgo_Operation.hxx>
19 #include <BOPDS_DS.hxx>
20 #include <BOPDS_MapOfPair.hxx>
21 #include <BOPTools_AlgoTools.hxx>
22 #include <BOPTools_AlgoTools3D.hxx>
23 #include <BRep_Builder.hxx>
24 #include <BRep_TEdge.hxx>
25 #include <BRep_TFace.hxx>
26 #include <BRep_Tool.hxx>
27 #include <BRep_TVertex.hxx>
28 #include <BRepExtrema_DistShapeShape.hxx>
29 #include <Geom_Surface.hxx>
30 #include <gp_Pnt.hxx>
31 #include <IntTools_CommonPrt.hxx>
32 #include <IntTools_Context.hxx>
33 #include <IntTools_EdgeEdge.hxx>
34 #include <IntTools_Range.hxx>
35 #include <Standard_ErrorHandler.hxx>
36 #include <Standard_Failure.hxx>
37 #include <TColStd_Array2OfBoolean.hxx>
38 #include <TopExp.hxx>
39 #include <TopExp_Explorer.hxx>
40 #include <TopoDS.hxx>
41 #include <TopoDS_Edge.hxx>
42 #include <TopoDS_Shape.hxx>
43 #include <TopoDS_Shell.hxx>
44 #include <TopoDS_Solid.hxx>
45 #include <TopoDS_Vertex.hxx>
46 #include <TopoDS_Wire.hxx>
47 #include <TopTools_IndexedMapOfShape.hxx>
48 #include <TopTools_ListOfShape.hxx>
49 #include <TopTools_MapOfShape.hxx>
50 #include <TopTools_SequenceOfShape.hxx>
51
52 // ================================================================================
53 // function: Constructor
54 // purpose:
55 // ================================================================================
56 BOPAlgo_ArgumentAnalyzer::BOPAlgo_ArgumentAnalyzer() : 
57 BOPAlgo_Algo(),
58 myStopOnFirst(Standard_False),
59 myOperation(BOPAlgo_UNKNOWN),
60 myArgumentTypeMode(Standard_False),
61 mySelfInterMode(Standard_False),
62 mySmallEdgeMode(Standard_False),
63 myRebuildFaceMode(Standard_False),
64 myTangentMode(Standard_False),
65 myMergeVertexMode(Standard_False),
66 myMergeEdgeMode(Standard_False),
67 myContinuityMode(Standard_False),
68 myCurveOnSurfaceMode(Standard_False),
69 myEmpty1(Standard_False),
70 myEmpty2(Standard_False)
71 {
72 }
73 //=======================================================================
74 // function: ~
75 // purpose: 
76 //=======================================================================
77 BOPAlgo_ArgumentAnalyzer::~BOPAlgo_ArgumentAnalyzer()
78 {
79   myResult.Clear();
80 }
81
82 // ================================================================================
83 // function: SetShape1
84 // purpose:
85 // ================================================================================
86 void BOPAlgo_ArgumentAnalyzer::SetShape1(const TopoDS_Shape & TheShape)
87 {
88   myShape1 = TheShape;
89 }
90
91 // ================================================================================
92 // function: SetShape2
93 // purpose:
94 // ================================================================================
95 void BOPAlgo_ArgumentAnalyzer::SetShape2(const TopoDS_Shape & TheShape)
96 {
97   myShape2 = TheShape;
98 }
99
100 // ================================================================================
101 // function: GetShape1
102 // purpose:
103 // ================================================================================
104 const TopoDS_Shape & BOPAlgo_ArgumentAnalyzer::GetShape1() const
105 {
106   return myShape1;
107 }
108
109 // ================================================================================
110 // function: GetShape2
111 // purpose:
112 // ================================================================================
113 const TopoDS_Shape & BOPAlgo_ArgumentAnalyzer::GetShape2() const
114 {
115   return myShape2;
116 }
117
118 // ================================================================================
119 // function: OperationType
120 // purpose:
121 // ================================================================================
122 BOPAlgo_Operation& BOPAlgo_ArgumentAnalyzer::OperationType() 
123 {
124   return myOperation;
125 }
126
127 // ================================================================================
128 // function: StopOnFirstFaulty
129 // purpose:
130 // ================================================================================
131 Standard_Boolean & BOPAlgo_ArgumentAnalyzer::StopOnFirstFaulty()
132 {
133   return myStopOnFirst;
134 }
135
136 // ================================================================================
137 // function: Prepare
138 // purpose:
139 // ================================================================================
140 void BOPAlgo_ArgumentAnalyzer::Prepare()
141 {
142   Standard_Boolean isS1 = myShape1.IsNull(), isS2 = myShape2.IsNull();
143   if (!isS1) {
144     myEmpty1 = BOPTools_AlgoTools3D::IsEmptyShape(myShape1);
145   }
146   if (!isS2) {
147     myEmpty2 = BOPTools_AlgoTools3D::IsEmptyShape(myShape2);
148   }
149 }
150 // ================================================================================
151 // function: Perform
152 // purpose:
153 // ================================================================================
154 void BOPAlgo_ArgumentAnalyzer::Perform()
155 {
156   try {
157     OCC_CATCH_SIGNALS
158     myResult.Clear();
159     //
160     UserBreak();
161     //
162     // 1. Prepare
163     Prepare();
164     //
165     UserBreak();
166     //
167     // 2. Test types
168     if(myArgumentTypeMode) {
169       TestTypes();
170     }
171     //
172     UserBreak();
173     //
174     // 3. Test self-interference
175     if(mySelfInterMode) {
176       TestSelfInterferences();
177     }
178     //
179     UserBreak();
180     //
181     // 4. Test small edges
182     if(mySmallEdgeMode) {
183       if(!(!myResult.IsEmpty() && myStopOnFirst))
184         TestSmallEdge();
185     }
186     //
187     UserBreak();
188     //
189     // 5. Test possibility to rebuild faces
190     if(myRebuildFaceMode) {
191       if(!(!myResult.IsEmpty() && myStopOnFirst))
192         TestRebuildFace();
193     }
194     //
195     UserBreak();
196     //
197     // 6. Test tangent
198     if(myTangentMode) {
199       if(!(!myResult.IsEmpty() && myStopOnFirst))
200         TestTangent();
201     }
202     //
203     UserBreak();
204     //
205     // 7. Test merge vertices
206     if(myMergeVertexMode) {
207       if(!(!myResult.IsEmpty() && myStopOnFirst))
208         TestMergeVertex();
209     }
210     //
211     UserBreak();
212     //
213     // 8. Test merge edges
214     if(myMergeEdgeMode) {
215       if(!(!myResult.IsEmpty() && myStopOnFirst))
216         TestMergeEdge();
217     }
218     //
219     UserBreak();
220     //
221     // 9. Test shapes continuity
222     if(myContinuityMode) {
223       if(!(!myResult.IsEmpty() && myStopOnFirst))
224         TestContinuity();
225     }
226     //
227     UserBreak();
228     //
229     // 10. Test validity of the curves on the surfaces
230     if(myCurveOnSurfaceMode) {
231       if(!(!myResult.IsEmpty() && myStopOnFirst))
232         TestCurveOnSurface();
233     }
234   }
235   catch(Standard_Failure const&) {
236     BOPAlgo_CheckResult aResult;
237     aResult.SetCheckStatus(BOPAlgo_CheckUnknown);
238     myResult.Append(aResult);
239   }
240 }
241
242 // ================================================================================
243 // function: HasFaulty
244 // purpose:
245 // ================================================================================
246 Standard_Boolean BOPAlgo_ArgumentAnalyzer::HasFaulty() const
247 {
248   return ( !myResult.IsEmpty());
249 }
250
251 // ================================================================================
252 // function: GetCheckResult
253 // purpose:
254 // ================================================================================
255 const BOPAlgo_ListOfCheckResult& BOPAlgo_ArgumentAnalyzer::GetCheckResult() const
256 {
257   return myResult;
258 }
259
260 // ================================================================================
261 // function: TestTypes
262 // purpose:
263 // ================================================================================
264 void BOPAlgo_ArgumentAnalyzer::TestTypes()
265 {
266   Standard_Boolean isS1 = myShape1.IsNull(), isS2 = myShape2.IsNull();
267
268   if(isS1 && isS2) {
269     BOPAlgo_CheckResult aResult;
270     aResult.SetCheckStatus(BOPAlgo_BadType);
271     myResult.Append(aResult);
272     return;
273   }
274
275   //single shape check
276   if((isS1 && !isS2) || (!isS1 && isS2)) {
277     Standard_Boolean bIsEmpty = (isS1) ? myEmpty2 : myEmpty1;
278
279     if(bIsEmpty || myOperation!=BOPAlgo_UNKNOWN) {
280       const TopoDS_Shape & aS = (isS1) ? myShape2 : myShape1;
281       BOPAlgo_CheckResult aResult;
282       aResult.SetShape1(aS);
283       aResult.SetCheckStatus(BOPAlgo_BadType);
284       myResult.Append(aResult);
285       return;
286     }
287   }
288   // two shapes check (begin)
289   else {
290     if(myEmpty1 || myEmpty2) {
291       BOPAlgo_CheckResult aResult;
292       if(myEmpty1 && myEmpty2) {
293         aResult.SetShape1(myShape1);
294         aResult.SetShape2(myShape2);
295       }
296       else {
297         const TopoDS_Shape & aS = myEmpty1 ? myShape1 : myShape2;
298         if(myEmpty1)
299           aResult.SetShape1(aS);
300         else
301           aResult.SetShape2(aS);
302       }
303       aResult.SetCheckStatus(BOPAlgo_BadType);
304       myResult.Append(aResult);
305       return;
306     }
307     //
308     Standard_Integer aDim1, aDim2;
309     Standard_Boolean bBadTypes = Standard_False;
310     //
311     aDim1 = BOPTools_AlgoTools::Dimension(myShape1);
312     aDim2 = BOPTools_AlgoTools::Dimension(myShape2);
313     if (aDim1 < aDim2) {
314       if (myOperation == BOPAlgo_FUSE ||
315           myOperation == BOPAlgo_CUT21) {
316         bBadTypes = Standard_True;
317       }
318     }
319     else if (aDim1 > aDim2) {
320       if (myOperation == BOPAlgo_FUSE ||
321           myOperation == BOPAlgo_CUT) {
322         bBadTypes = Standard_True;
323       }
324     }
325     if (bBadTypes) {
326       BOPAlgo_CheckResult aResult;
327       aResult.SetShape1(myShape1);
328       aResult.SetShape2(myShape2);
329       aResult.SetCheckStatus(BOPAlgo_BadType);
330       myResult.Append(aResult);
331     }
332   }
333 }
334 //=======================================================================
335 //function : TestSelfInterferences
336 //purpose  : 
337 //=======================================================================
338 void BOPAlgo_ArgumentAnalyzer::TestSelfInterferences()
339 {
340   Standard_Integer ii;
341   //
342   for(ii = 0; ii < 2; ii++) {
343     const TopoDS_Shape& aS = (ii == 0) ? myShape1 : myShape2;
344     if(aS.IsNull()) {
345       continue;
346     }
347     //
348     Standard_Boolean bIsEmpty = (ii == 0) ? myEmpty1 : myEmpty2;
349     if (bIsEmpty) {
350       continue;
351     }
352     //
353     Standard_Integer n1, n2;
354     BOPDS_MapIteratorOfMapOfPair aItMPK;
355     TopTools_ListOfShape anArgs;
356     BOPAlgo_CheckerSI aChecker;
357     //
358     anArgs.Append(aS);
359     aChecker.SetArguments(anArgs);
360     aChecker.SetNonDestructive(Standard_True);
361     aChecker.SetRunParallel(myRunParallel);
362     aChecker.SetFuzzyValue(myFuzzyValue);
363     aChecker.SetProgressIndicator(myProgressIndicator);
364     //
365     aChecker.Perform();
366     Standard_Boolean hasError = aChecker.HasErrors();
367     //
368     const BOPDS_DS& aDS=*(aChecker.PDS());
369     const BOPDS_MapOfPair& aMPK=aDS.Interferences();
370     //
371     aItMPK.Initialize(aMPK);
372     for (; aItMPK.More(); aItMPK.Next()) {
373       const BOPDS_Pair& aPK=aItMPK.Value();
374       aPK.Indices(n1, n2);
375       if(aDS.IsNewShape(n1) || aDS.IsNewShape(n2)) {
376         continue;
377       }
378       //
379       const TopoDS_Shape& aS1=aDS.Shape(n1);
380       const TopoDS_Shape& aS2=aDS.Shape(n2);
381       //
382       BOPAlgo_CheckResult aResult;
383       if(ii == 0) {
384         aResult.SetShape1(myShape1);
385         aResult.AddFaultyShape1(aS1);
386         if (!aS1.IsSame(aS2))
387           aResult.AddFaultyShape1(aS2);
388       }
389       else {
390         aResult.SetShape2(myShape2);
391         aResult.AddFaultyShape2(aS1);
392         if (!aS1.IsSame(aS2))
393           aResult.AddFaultyShape2(aS2);
394       }
395       aResult.SetCheckStatus(BOPAlgo_SelfIntersect);
396       myResult.Append(aResult);
397     }
398     //
399     if (hasError) {
400       BOPAlgo_CheckResult aResult;
401       if(ii == 0) {
402         aResult.SetShape1(myShape1);
403         aResult.AddFaultyShape1(myShape1);
404       }
405       else {
406         aResult.SetShape2(myShape2);
407         aResult.AddFaultyShape2(myShape2);
408       }
409       aResult.SetCheckStatus(BOPAlgo_OperationAborted);
410       myResult.Append(aResult);
411     }
412   }// for(ii = 0; ii < 2; ii++) {
413 }
414 // ================================================================================
415 // function: TestSmallEdge
416 // purpose:
417 // ================================================================================
418 void BOPAlgo_ArgumentAnalyzer::TestSmallEdge() 
419 {
420   Standard_Integer i = 0;
421   BRepExtrema_DistShapeShape aDist;
422   Handle(IntTools_Context) aCtx;
423   //
424   aCtx = new IntTools_Context;
425   
426   for(i = 0; i < 2; i++) {
427     const TopoDS_Shape& aS = (i == 0) ? myShape1 : myShape2;
428
429     if(aS.IsNull())
430       continue;
431
432     TopExp_Explorer anExp(aS, TopAbs_EDGE);
433
434     for(; anExp.More(); anExp.Next()) {
435       const TopoDS_Edge& anEdge = *(TopoDS_Edge*)&anExp.Current();
436       if (BRep_Tool::Degenerated(anEdge)) {
437         continue;
438       }
439
440       if(BOPTools_AlgoTools::IsMicroEdge(anEdge, aCtx)) {
441         Standard_Boolean bKeepResult = Standard_True;
442         
443         if(myOperation == BOPAlgo_SECTION) {
444           const TopoDS_Shape& anOtherS = (i == 0) ? myShape2 : myShape1;
445           
446           if(!anOtherS.IsNull()) {
447             aDist.LoadS2(anOtherS);
448             
449             Standard_Boolean bVertexIsOnShape = Standard_False;
450             Standard_Integer ii = 0;
451             TopExp_Explorer anExpV(anEdge, TopAbs_VERTEX);
452             
453             for(; anExpV.More(); anExpV.Next()) {
454               const TopoDS_Shape& aV = anExpV.Current();
455               
456               aDist.LoadS1(aV);
457               aDist.Perform();
458               
459               if(aDist.IsDone()) {
460                 
461                 for(ii = 1; ii <= aDist.NbSolution(); ii++) {
462                   Standard_Real aTolerance = BRep_Tool::Tolerance(*(TopoDS_Vertex*)&aV);
463                   const TopoDS_Shape& aSupportShape = aDist.SupportOnShape2(ii);
464                   
465                   switch(aSupportShape.ShapeType()) {
466                   case TopAbs_VERTEX: {
467                     aTolerance += BRep_Tool::Tolerance(*(TopoDS_Vertex*)&(aSupportShape));
468                     break;
469                   }
470                   case TopAbs_EDGE: {
471                     aTolerance += BRep_Tool::Tolerance(*(TopoDS_Edge*)&(aSupportShape));
472                     break;
473                   }
474                   case TopAbs_FACE: {
475                     aTolerance += BRep_Tool::Tolerance(*(TopoDS_Face*)&(aSupportShape));
476                     break;
477                   }
478                   default:
479                     break;
480                   }
481                   
482                   if(aDist.Value() < aTolerance) {
483                     bVertexIsOnShape = Standard_True;
484                     break;
485                   }
486                 }
487               }
488             }
489             
490             if(!bVertexIsOnShape) {
491               bKeepResult = Standard_False;
492             }
493           }
494         }
495         
496         if(bKeepResult) {
497           BOPAlgo_CheckResult aResult;
498           
499           if(i == 0) {
500             aResult.SetShape1(myShape1);
501             aResult.AddFaultyShape1(anEdge);
502           }
503           else {
504             aResult.SetShape2(myShape2);
505             aResult.AddFaultyShape2(anEdge);
506           }
507           
508           aResult.SetCheckStatus(BOPAlgo_TooSmallEdge);
509           myResult.Append(aResult);
510           
511           if(myStopOnFirst) {
512             return;
513           }
514         }
515       }
516     }
517   }
518 }
519 // ================================================================================
520 // function: TestRebuildFace
521 // purpose:
522 // ================================================================================
523 void BOPAlgo_ArgumentAnalyzer::TestRebuildFace() 
524 {
525   if((myOperation == BOPAlgo_SECTION) ||
526      (myOperation == BOPAlgo_UNKNOWN))
527     return;
528   Standard_Integer i = 0;
529
530   for(i = 0; i < 2; i++) {
531     const TopoDS_Shape& aS = (i == 0) ? myShape1 : myShape2;
532
533     if(aS.IsNull())
534       continue;
535
536     TopExp_Explorer anExp(aS, TopAbs_FACE);
537     TopTools_ListOfShape aLS;
538
539     for(; anExp.More(); anExp.Next()) {
540       const TopoDS_Face& aFace = *(TopoDS_Face*)&(anExp.Current());
541
542       TopoDS_Face aFF = aFace;
543       aFF.Orientation(TopAbs_FORWARD);
544       TopExp_Explorer anExpE(aFF, TopAbs_EDGE);
545       Standard_Integer nbstartedges = 0;
546       aLS.Clear();
547       //
548       for(; anExpE.More(); anExpE.Next()) {
549         const TopoDS_Edge& aE=(*(TopoDS_Edge*)(&anExpE.Current()));
550         TopAbs_Orientation anOriE=aE.Orientation();
551         //
552         if (anOriE==TopAbs_INTERNAL) {
553           TopoDS_Edge aEE=aE;
554           aEE.Orientation(TopAbs_FORWARD);
555           aLS.Append(aEE);
556           aEE.Orientation(TopAbs_REVERSED);
557           aLS.Append(aEE);
558         }
559         else {
560           aLS.Append(aE);
561         }
562         nbstartedges++;
563       }
564       BOPAlgo_BuilderFace aBF;
565       aBF.SetFace(aFace);
566       aBF.SetShapes(aLS);
567       aBF.Perform();
568       const TopTools_ListOfShape& aLF = aBF.Areas();
569       Standard_Boolean bBadFace = Standard_False;
570
571       if(aLF.Extent() != 1) {
572         bBadFace = Standard_True;
573       }
574       else {
575         Standard_Integer nbedgeused = 0;
576         anExpE.Init(aLF.First(), TopAbs_EDGE);
577         
578         for(; anExpE.More(); anExpE.Next(), nbedgeused++);
579         
580         if(nbstartedges != nbedgeused) {
581           bBadFace = Standard_True;
582         }
583       }
584
585       if(bBadFace) {
586         BOPAlgo_CheckResult aResult;
587         
588         if(i == 0) {
589           aResult.SetShape1(myShape1);
590           aResult.AddFaultyShape1(aFace);
591         }
592         else {
593           aResult.SetShape2(myShape2);
594           aResult.AddFaultyShape2(aFace);
595         }
596         
597         aResult.SetCheckStatus(BOPAlgo_NonRecoverableFace);
598         myResult.Append(aResult);
599         
600         if(myStopOnFirst) {
601           return;
602         }
603       }
604     }
605   }
606 }
607
608 // ================================================================================
609 // function: TestTangent
610 // purpose:
611 // ================================================================================
612 void BOPAlgo_ArgumentAnalyzer::TestTangent() 
613 {
614  // not implemented
615 }
616
617 // ================================================================================
618 // function: TestMergeSubShapes
619 // purpose:
620 // ================================================================================
621  void BOPAlgo_ArgumentAnalyzer::TestMergeSubShapes(const TopAbs_ShapeEnum theType) 
622 {
623   if(myShape1.IsNull() || myShape2.IsNull())
624     return;
625
626   if (myEmpty1 || myEmpty2) 
627     return;
628
629   BOPAlgo_CheckStatus aStatus = BOPAlgo_CheckUnknown;
630
631   switch(theType) {
632   case TopAbs_VERTEX: {
633     aStatus = BOPAlgo_IncompatibilityOfVertex;
634     break;
635   }
636   case TopAbs_EDGE: {
637     aStatus = BOPAlgo_IncompatibilityOfEdge;
638     break;
639   }
640   case TopAbs_FACE: {
641     aStatus = BOPAlgo_IncompatibilityOfFace;
642     break;
643   }
644   default: 
645     return;
646   }
647   TopExp_Explorer anExp1(myShape1, theType);
648   TopExp_Explorer anExp2(myShape2, theType);
649   TopTools_SequenceOfShape aSeq1, aSeq2;
650   TopTools_MapOfShape aMap1, aMap2;
651
652   for(; anExp1.More(); anExp1.Next()) {
653     const TopoDS_Shape& aS1 = anExp1.Current();
654
655     if(aMap1.Contains(aS1))
656       continue;
657     aSeq1.Append(aS1);
658     aMap1.Add(aS1);
659   }
660
661   for(; anExp2.More(); anExp2.Next()) {
662     const TopoDS_Shape& aS2 = anExp2.Current();
663     if(aMap2.Contains(aS2))
664       continue;
665     aSeq2.Append(aS2);
666     aMap2.Add(aS2);
667   }
668
669   TColStd_Array2OfBoolean anArrayOfFlag(1, aSeq1.Length(), 1, aSeq2.Length());
670   Standard_Integer i = 0, j = 0;
671   for(i = 1; i <= aSeq1.Length(); i++)
672     for(j = 1; j <= aSeq2.Length(); j++)
673       anArrayOfFlag.SetValue(i, j, Standard_False);
674
675   for(i = 1; i <= aSeq1.Length(); i++) {
676     const TopoDS_Shape& aS1 = aSeq1.Value(i);
677     TopTools_ListOfShape aListOfS2;
678     Standard_Integer nbs = 0;
679
680     for(j = 1; j <= aSeq2.Length(); j++) {
681       const TopoDS_Shape& aS2 = aSeq2.Value(j);
682       Standard_Boolean bIsEqual = Standard_False;
683
684       if(theType == TopAbs_VERTEX) {
685
686         const TopoDS_Vertex& aV1 = *(TopoDS_Vertex*)&(aS1);
687         const TopoDS_Vertex& aV2 = *(TopoDS_Vertex*)&(aS2);
688         gp_Pnt aP1 = BRep_Tool::Pnt(aV1);
689         gp_Pnt aP2 = BRep_Tool::Pnt(aV2);
690         Standard_Real aDist = aP1.Distance(aP2);
691
692         if(aDist <= (BRep_Tool::Tolerance(aV1) + BRep_Tool::Tolerance(aV2))) {
693           bIsEqual = Standard_True;
694         }
695       }
696       else if(theType == TopAbs_EDGE) {
697         const TopoDS_Edge& aE1 = *(TopoDS_Edge*)&(aS1);
698         const TopoDS_Edge& aE2 = *(TopoDS_Edge*)&(aS2);
699         //
700         IntTools_EdgeEdge aEE(aE1, aE2);
701         //
702         aEE.Perform();
703         if (aEE.IsDone()) {
704           const IntTools_SequenceOfCommonPrts& aCPrts = aEE.CommonParts();
705           Standard_Integer ii = 0;
706           
707           for (ii = 1; ii <= aCPrts.Length(); ii++) {
708             const IntTools_CommonPrt& aCPart = aCPrts(ii);
709             
710             if (aCPart.Type() == TopAbs_EDGE) {
711               bIsEqual = Standard_True;
712             }
713           }
714         }
715       }
716       else if(theType == TopAbs_FACE) {
717         // not yet implemented!
718       }
719
720       if(bIsEqual) {
721         anArrayOfFlag.SetValue(i, j, Standard_True );
722         aListOfS2.Append(aS2);
723         nbs++;
724       }
725     }
726
727     if(nbs > 1) {
728       BOPAlgo_CheckResult aResult;
729
730       aResult.SetShape1(myShape1);
731       aResult.SetShape2(myShape2);
732       aResult.AddFaultyShape1(aS1);
733       TopTools_ListIteratorOfListOfShape anIt(aListOfS2);
734
735       for(; anIt.More(); anIt.Next()) {
736         aResult.AddFaultyShape2(anIt.Value());
737       }
738
739       aResult.SetCheckStatus(aStatus);
740       myResult.Append(aResult);
741
742       if(myStopOnFirst) {
743         return;
744       }
745     }
746   }
747
748   for(i = 1; i <= aSeq2.Length(); i++) {
749     const TopoDS_Shape& aS2 = aSeq2.Value(i);
750     TopTools_ListOfShape aListOfS1;
751     Standard_Integer nbs = 0;
752
753     for(j = 1; j <= aSeq1.Length(); j++) {
754       const TopoDS_Shape& aS1 = aSeq1.Value(j);
755
756       if(anArrayOfFlag.Value(j, i)) {
757         aListOfS1.Append(aS1);
758         nbs++;
759       }
760     }
761     
762     if(nbs > 1) {
763       BOPAlgo_CheckResult aResult;
764
765       aResult.SetShape1(myShape1);
766       aResult.SetShape2(myShape2);
767       TopTools_ListIteratorOfListOfShape anIt(aListOfS1);
768
769       for(; anIt.More(); anIt.Next()) {
770         aResult.AddFaultyShape1(anIt.Value());
771       }
772       aResult.AddFaultyShape2(aS2);
773
774       aResult.SetCheckStatus(aStatus);
775       myResult.Append(aResult);
776
777       if(myStopOnFirst) {
778         return;
779       }
780     }
781   }
782 }
783
784 // ================================================================================
785 // function: TestMergeVertex
786 // purpose:
787 // ================================================================================
788 void BOPAlgo_ArgumentAnalyzer::TestMergeVertex() 
789 {
790   TestMergeSubShapes(TopAbs_VERTEX); 
791 }
792
793 // ================================================================================
794 // function: TestMergeEdge
795 // purpose:
796 // ================================================================================
797 void BOPAlgo_ArgumentAnalyzer::TestMergeEdge() 
798 {
799   TestMergeSubShapes(TopAbs_EDGE); 
800 }
801
802 // ================================================================================
803 // function: TestContinuity
804 // purpose:
805 // ================================================================================
806 void BOPAlgo_ArgumentAnalyzer::TestContinuity() 
807 {
808   Standard_Integer i, j, aNbS;
809   Standard_Real f, l;
810   TopExp_Explorer aExp;
811   //
812   for (i = 0; i < 2; ++i) {
813     const TopoDS_Shape& aS = !i ? myShape1 : myShape2;
814     if(aS.IsNull()) {
815       continue;
816     }
817     //
818     TopTools_IndexedMapOfShape aMS;
819     //Edges
820     aExp.Init(aS, TopAbs_EDGE);
821     for (; aExp.More(); aExp.Next()) {
822       const TopoDS_Edge& aE = *(TopoDS_Edge*)&aExp.Current();
823       if (BRep_Tool::Degenerated(aE)) {
824         continue;
825       }
826       const Handle(Geom_Curve)& aC = BRep_Tool::Curve(aE, f, l);
827       if (aC->Continuity() == GeomAbs_C0) {
828         aMS.Add(aE);
829       }
830     }
831     //Faces
832     aExp.Init(aS, TopAbs_FACE);
833     for (; aExp.More(); aExp.Next()) {
834       const TopoDS_Face& aF = *(TopoDS_Face*)&aExp.Current();
835       Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aF);
836       if (aSurf->Continuity() == GeomAbs_C0) {
837         aMS.Add(aF);
838       }
839     }
840     //
841     //add shapes with continuity C0 to result
842     aNbS = aMS.Extent();
843     for (j = 1; j <= aNbS; ++j) {
844       const TopoDS_Shape& aFS = aMS(j);
845       BOPAlgo_CheckResult aResult;
846       if(i == 0) {
847         aResult.SetShape1(myShape1);
848         aResult.AddFaultyShape1(aFS);
849       } else {
850         aResult.SetShape2(myShape2);
851         aResult.AddFaultyShape2(aFS);
852       }
853       aResult.SetCheckStatus(BOPAlgo_GeomAbs_C0);
854       myResult.Append(aResult);
855     }
856   }
857 }
858
859 // ================================================================================
860 // function: TestCurveOnSurface
861 // purpose:
862 // ================================================================================
863 void BOPAlgo_ArgumentAnalyzer::TestCurveOnSurface()
864 {
865   Standard_Integer i;
866   Standard_Real aT, aD, aTolE;
867   TopExp_Explorer aExpF, aExpE;
868   //
869   for(i = 0; i < 2; i++) {
870     const TopoDS_Shape& aS = (i == 0) ? myShape1 : myShape2;
871     if(aS.IsNull()) {
872       continue;
873     }
874     //
875     aExpF.Init(aS, TopAbs_FACE);
876     for (; aExpF.More(); aExpF.Next()) {
877       const TopoDS_Face& aF = *(TopoDS_Face*)&aExpF.Current();
878       //
879       aExpE.Init(aF, TopAbs_EDGE);
880       for (; aExpE.More(); aExpE.Next()) {
881         const TopoDS_Edge& aE = *(TopoDS_Edge*)&aExpE.Current();
882         //
883         if (BOPTools_AlgoTools::ComputeTolerance(aF, aE, aD, aT)) {
884           aTolE = BRep_Tool::Tolerance(aE);
885           if (aD > aTolE) {
886             BOPAlgo_CheckResult aResult;
887             aResult.SetCheckStatus(BOPAlgo_InvalidCurveOnSurface);
888             if(i == 0) {
889               aResult.SetShape1(myShape1);
890               aResult.AddFaultyShape1(aE);
891               aResult.AddFaultyShape1(aF);
892               aResult.SetMaxDistance1(aD);
893               aResult.SetMaxParameter1(aT);
894             }
895             else {
896               aResult.SetShape2(myShape2);
897               aResult.AddFaultyShape2(aE);
898               aResult.AddFaultyShape2(aF);
899               aResult.SetMaxDistance2(aD);
900               aResult.SetMaxParameter2(aT);
901             }
902             myResult.Append(aResult);
903           }
904         }
905       }
906     }
907   }
908 }