0022967: Boolean operations between two cylinders with orthogonal axis generate a...
[occt.git] / src / BOPTools / BOPTools_Checker.cxx
1 // File:        BOPTools_Checker.cxx
2 // Created:     Mon Aug  5 16:06:12 2002
3 // Author:      Peter KURNEV
4 //              <pkv@irinox>
5
6
7 #include <BOPTools_Checker.ixx>
8
9 #include <stdio.h>  
10 #include <stdlib.h> 
11
12 #include <Precision.hxx>
13
14 #include <gp_Pnt.hxx>
15
16 #include <Geom_CartesianPoint.hxx>
17 #include <Geom_TrimmedCurve.hxx>
18 #include <Geom_Curve.hxx>
19
20 #include <TopoDS.hxx>
21 #include <TopoDS_Vertex.hxx>
22 #include <TopoDS_Shape.hxx>
23 #include <TopoDS_Edge.hxx>
24 #include <TopoDS_Face.hxx>
25
26 #include <TopTools_IndexedMapOfShape.hxx>
27
28 #include <TopExp.hxx>
29
30 #include <Bnd_Box.hxx>
31
32 #include <BRep_Builder.hxx>
33 #include <BRep_Tool.hxx>
34
35 #include <BOPTools_Pave.hxx>
36 #include <BOPTools_PaveSet.hxx>
37 #include <BOPTools_ListOfPaveBlock.hxx>
38 #include <BOPTools_ListIteratorOfListOfPaveBlock.hxx>
39 #include <BOPTools_PaveBlock.hxx>
40 #include <BOPTools_Tools.hxx>
41 #include <BOPTools_PaveBlockIterator.hxx>
42 // modified by NIZHNY-MKK  Fri Sep  3 16:00:15 2004.BEGIN
43 #include <BOPTools_CheckResult.hxx>
44 // modified by NIZHNY-MKK  Fri Sep  3 16:00:18 2004.END
45
46 #include <IntTools_ShrunkRange.hxx>
47 #include <IntTools_Range.hxx>
48 #include <IntTools_EdgeEdge.hxx>
49 #include <IntTools_SequenceOfCommonPrts.hxx>
50 #include <IntTools_CommonPrt.hxx>
51 #include <IntTools_SequenceOfRanges.hxx>
52 #include <IntTools_EdgeFace.hxx>
53 #include <IntTools_FaceFace.hxx>
54 #include <IntTools_Curve.hxx>
55 #include <IntTools_PntOn2Faces.hxx>
56 #include <IntTools_PntOnFace.hxx>
57 #include <IntTools_Tools.hxx>
58
59 #include <BooleanOperations_ShapesDataStructure.hxx>
60 #include <BooleanOperations_AncestorsSeqAndSuccessorsSeq.hxx>
61
62 #include <BOPTColStd_Failure.hxx>
63 #include <IntTools_Context.hxx>
64
65 //=======================================================================
66 // function:  BOPTools_Checker::BOPTools_Checker
67 // purpose: 
68 //=======================================================================
69 BOPTools_Checker::BOPTools_Checker() : BOPTools_PaveFiller()
70 {
71   myEntryType=1;
72   myStopOnFirst = Standard_False;
73 }
74 //=======================================================================
75 // function:  BOPTools_Checker::BOPTools_Checker
76 // purpose: 
77 //=======================================================================
78 BOPTools_Checker::BOPTools_Checker(const TopoDS_Shape& aS) : BOPTools_PaveFiller()
79 {
80   myEntryType=1;
81   myStopOnFirst = Standard_False;
82   SetShape(aS);
83
84 //=======================================================================
85 // function:  BOPTools_Checker::BOPTools_Checker
86 // purpose: 
87 //=======================================================================
88 BOPTools_Checker::BOPTools_Checker(const BOPTools_InterferencePool& aPool) : BOPTools_PaveFiller(aPool)
89 {
90   myStopOnFirst = Standard_False;
91   myEntryType=0;
92   myIsDone=Standard_False;
93   void* p=(void*) &aPool;
94   myIntrPool=(BOPTools_InterferencePool*) p;
95   myDS=myIntrPool->DS();
96   myNbSources=myDS->NumberOfShapesOfTheObject()+myDS->NumberOfShapesOfTheTool();
97   myNbEdges=myDS->NbEdges();
98 }
99
100 //=======================================================================
101 // function: SetShape
102 // purpose: 
103 //=======================================================================
104 void  BOPTools_Checker::SetShape(const TopoDS_Shape& aS)
105 {
106   myShape=aS;
107
108   Destroy();
109   myDS = new BooleanOperations_ShapesDataStructure (aS, aS);
110   
111   myIntrPool = new BOPTools_InterferencePool (*myDS);
112
113   myNbSources=myDS->NumberOfShapesOfTheObject()+myDS->NumberOfShapesOfTheTool();
114   myNbEdges=myDS->NbEdges();
115 }
116
117 //=======================================================================
118 // function: Destroy
119 // purpose: 
120 //=======================================================================
121 void BOPTools_Checker::Destroy()
122 {
123   if (myEntryType) {
124     //
125     if (myIntrPool!=NULL) {
126       delete myIntrPool; myIntrPool = NULL;
127     }
128     if (myDS!=NULL) {
129       delete myDS; myDS = NULL;
130     }
131   }
132   myCheckResults.Clear();
133 }
134
135 //=======================================================================
136 // function: SetPerformType
137 // purpose: 
138 //=======================================================================
139
140 void BOPTools_Checker::SetPerformType(const Standard_Boolean StopOnFirstFaulty)
141 {
142   myStopOnFirst = StopOnFirstFaulty;
143 }
144
145 //=======================================================================
146 // function: Perform
147 // purpose: 
148 //=======================================================================
149 void BOPTools_Checker::Perform()
150 {
151   myCheckResults.Clear();
152   try {
153     //
154     if (myContext.IsNull()) {
155       myContext=new IntTools_Context;
156     }
157     //
158     // 0. Prepare the IteratorOfCoupleOfShape
159     myDSIt.SetDataStructure(myDS);
160     //
161     // 1.VV
162     PerformVV();
163     //
164     // 2.VE
165     myPavePool.Resize (myNbEdges);
166     PrepareEdges();
167     PerformVE();
168     //
169     // 3.VF
170     PerformVF();
171     //
172     // 4.EE
173     myCommonBlockPool.Resize (myNbEdges);
174     mySplitShapesPool.Resize (myNbEdges);
175     myPavePoolNew    .Resize (myNbEdges);
176     
177     PreparePaveBlocks(TopAbs_VERTEX, TopAbs_EDGE);
178     PreparePaveBlocks(TopAbs_EDGE, TopAbs_EDGE);
179     
180     PerformEE();
181     //
182     // 5.EF
183     PreparePaveBlocks(TopAbs_EDGE, TopAbs_FACE);
184     
185     PerformEF();
186     //
187     // 6. FF
188     PerformFF ();
189   }// end of try block
190   //
191   catch (BOPTColStd_Failure& x) {
192     cout << x.Message() << endl << flush;
193   }
194 }
195 //=======================================================================
196 // function: PerformVV
197 // purpose: 
198 //=======================================================================
199 void BOPTools_Checker::PerformVV()
200 {
201   myIsDone=Standard_False;
202   Standard_Boolean bJustAddInterference;
203   Standard_Integer n1, n2, aFlag;
204   //
205   // V/V  BooleanOperations_VertexVertex
206   myDSIt.Initialize(TopAbs_VERTEX, TopAbs_VERTEX);
207   //
208   for (; myDSIt.More(); myDSIt.Next()) {
209     bJustAddInterference = Standard_False;
210     myDSIt.Current(n1, n2, bJustAddInterference);
211     //
212     const TopoDS_Shape& aS1=myDS->Shape(n1);
213     const TopoDS_Shape& aS2=myDS->Shape(n2);
214     //
215     if (aS1.IsSame(aS2)){
216       continue;
217     }
218     //
219     if(bJustAddInterference) {
220       continue;
221     }
222     //
223     const TopoDS_Vertex& aV1=TopoDS::Vertex(aS1);
224     const TopoDS_Vertex& aV2=TopoDS::Vertex(aS2);
225     
226     aFlag=IntTools_Tools::ComputeVV (aV1, aV2);
227     
228     if (!aFlag) {
229       char buf[512];
230       sprintf (buf, "VV: (%d, %d)", n1, n2);
231
232       BOPTools_CheckResult aChRes;
233       aChRes.AddShape(aV1);
234       aChRes.AddShape(aV2);
235       aChRes.SetCheckStatus(BOPTools_VERTEXVERTEX);
236       myCheckResults.Append(aChRes);
237
238       if(myStopOnFirst)
239         throw BOPTColStd_Failure(buf) ;
240     }
241   }
242   myIsDone=Standard_True;
243 }
244
245 //=======================================================================
246 // function: PerformVE
247 // purpose: 
248 //=======================================================================
249 void BOPTools_Checker::PerformVE()
250 {
251   myIsDone=Standard_False;
252   Standard_Boolean bSameFlag, bJustAddInterference;
253   Standard_Integer n1, n2, aFlag, aWhat, aWith;
254   Standard_Real aT;
255   //
256   // V/E Interferences  [BooleanOperations_VertexEdge]
257   myDSIt.Initialize (TopAbs_VERTEX, TopAbs_EDGE);
258   //
259   for (; myDSIt.More(); myDSIt.Next()) {
260     bJustAddInterference = Standard_False;
261     myDSIt.Current(n1, n2, bJustAddInterference);
262     //
263     aWhat=n1; // Vertex
264     aWith=n2; // Edge
265
266     SortTypes(aWhat, aWith);
267     
268     const TopoDS_Shape& aS1=myDS->Shape(aWhat);
269     const TopoDS_Shape& aS2=myDS->Shape(aWith);
270     
271     const TopoDS_Vertex& aV1=TopoDS::Vertex(aS1);
272     const TopoDS_Edge&   aE2=TopoDS::Edge  (aS2);
273     
274     if (BRep_Tool::Degenerated(aE2)){
275       continue;
276     }
277     //
278     TopTools_IndexedMapOfShape aM2;
279     //
280     bSameFlag=Standard_False;
281     //
282     BOPTools_Tools::MapShapes(aE2, aM2);
283     //
284     if (aM2.Contains(aV1)) {
285       bSameFlag=Standard_True;
286     }
287     //
288     if (bSameFlag){
289       continue;
290     }
291     //
292     aFlag=myContext->ComputeVE (aV1, aE2, aT);
293     //
294     if (!aFlag) {
295       char buf[512];
296       sprintf (buf, "VE: (%d, %d)", aWhat, aWith);
297
298       BOPTools_CheckResult aChRes;
299       aChRes.AddShape(aV1);
300       aChRes.AddShape(aE2);
301       aChRes.SetCheckStatus(BOPTools_VERTEXEDGE);
302       myCheckResults.Append(aChRes);
303       //
304       if(myStopOnFirst)
305         throw BOPTColStd_Failure(buf) ;
306     }
307   }
308   myIsDone=Standard_True;
309 }
310
311 //=======================================================================
312 // function: PerformVF
313 // purpose: 
314 //=======================================================================
315 void BOPTools_Checker::PerformVF()
316 {
317   myIsDone=Standard_False;
318   Standard_Boolean justaddinterference, bSameFlag;
319   Standard_Integer n1, n2, aFlag, aWhat, aWith;
320   Standard_Real aU, aV;
321   //
322   // V/V  BooleanOperations_VertexFace
323   myDSIt.Initialize(TopAbs_VERTEX, TopAbs_FACE);
324   //
325   for (; myDSIt.More(); myDSIt.Next()) {
326     justaddinterference = Standard_False;
327     myDSIt.Current(n1, n2, justaddinterference);
328     //
329     aWhat=n1; // Vertex
330     aWith=n2; // Face
331     SortTypes(aWhat, aWith);
332     
333     const TopoDS_Shape& aS1=myDS->Shape(aWhat);
334     const TopoDS_Shape& aS2=myDS->Shape(aWith);
335    
336     const TopoDS_Vertex& aV1=TopoDS::Vertex(aS1);
337     const TopoDS_Face&   aF2=TopoDS::Face  (aS2);
338     //
339     TopTools_IndexedMapOfShape aM2;
340     //
341     bSameFlag=Standard_False;
342     //
343     BOPTools_Tools::MapShapes(aF2, aM2);
344     //
345     if (aM2.Contains(aV1)) {
346       bSameFlag=Standard_True;
347     }
348     //
349     if (bSameFlag){
350       continue;
351     }
352     //
353     aFlag=myContext->ComputeVS (aV1, aF2, aU, aV);
354     //
355     if (!aFlag) {
356       char buf[512];
357       sprintf (buf, "VF: (%d, %d)", aWhat, aWith);
358
359       BOPTools_CheckResult aChRes;
360       aChRes.AddShape(aV1);
361       aChRes.AddShape(aF2);
362       aChRes.SetCheckStatus(BOPTools_VERTEXFACE);
363       myCheckResults.Append(aChRes);
364
365       if(myStopOnFirst)
366         throw BOPTColStd_Failure(buf) ;
367     }
368   }
369   myIsDone=Standard_True;
370 }
371
372 //=======================================================================
373 // function: PerformEE
374 // purpose: 
375 //=======================================================================
376 void BOPTools_Checker::PerformEE()
377 {
378   myIsDone=Standard_False;
379
380   Standard_Boolean justaddinterference;
381   Standard_Integer n1, n2, anIndexIn=0, nE1, nE2;
382   Standard_Integer aTmp, aWhat, aWith;
383   Standard_Integer i, aNbCPrts;
384   //
385   // E/E Interferences  [BooleanOperations_EdgeEdge]
386   myDSIt.Initialize(TopAbs_EDGE, TopAbs_EDGE);
387   //
388   for (; myDSIt.More(); myDSIt.Next()) {
389     justaddinterference = Standard_False;
390     myDSIt.Current(n1, n2, justaddinterference);
391     //
392     nE1=n1; 
393     nE2=n2; 
394     SortTypes(nE1, nE2);
395     //
396     Standard_Real aTolE1, aTolE2, aDeflection=0.01;
397     Standard_Integer aDiscretize=30;
398
399     const TopoDS_Edge& aE1=TopoDS::Edge(myDS->GetShape(nE1));
400     const TopoDS_Edge& aE2=TopoDS::Edge(myDS->GetShape(nE2));
401     //
402     if (BRep_Tool::Degenerated(aE1)){
403       continue;
404     }
405     if (BRep_Tool::Degenerated(aE2)){
406       continue;
407     }
408     //
409     // 
410     Standard_Boolean bSameFlag;
411     TopTools_IndexedMapOfShape aM1, aM2;
412     //
413     bSameFlag=aE1.IsSame(aE2);
414     //
415     if (bSameFlag){
416       continue;
417     }
418     //
419     aTolE1=BRep_Tool::Tolerance(aE1);
420     aTolE2=BRep_Tool::Tolerance(aE2);
421     //
422     BOPTools_ListOfPaveBlock& aLPB1=mySplitShapesPool(myDS->RefEdge(nE1));
423     BOPTools_ListIteratorOfListOfPaveBlock anIt1(aLPB1);
424
425     for (; anIt1.More(); anIt1.Next()) {
426       BOPTools_PaveBlock& aPB1=anIt1.Value();
427       const IntTools_ShrunkRange& aShrunkRange1=aPB1.ShrunkRange();
428     
429       const IntTools_Range& aSR1=aShrunkRange1.ShrunkRange();
430       const Bnd_Box&        aBB1=aShrunkRange1.BndBox();
431
432       BOPTools_ListOfPaveBlock& aLPB2=mySplitShapesPool(myDS->RefEdge(nE2));
433       BOPTools_ListIteratorOfListOfPaveBlock anIt2(aLPB2);
434       
435       for (; anIt2.More(); anIt2.Next()) {
436         BOPTools_PaveBlock& aPB2=anIt2.Value();
437         const IntTools_ShrunkRange& aShrunkRange2=aPB2.ShrunkRange();
438       
439         const IntTools_Range& aSR2=aShrunkRange2.ShrunkRange();
440         const Bnd_Box&        aBB2=aShrunkRange2.BndBox();
441         
442         //////////////////////////////////////////////
443         if (aBB1.IsOut (aBB2)) {
444           continue;
445         }
446         // 
447         // EE
448         IntTools_EdgeEdge aEE;
449         aEE.SetEdge1 (aE1);
450         aEE.SetEdge2 (aE2);
451         aEE.SetTolerance1 (aTolE1);
452         aEE.SetTolerance2 (aTolE2);
453         aEE.SetDiscretize (aDiscretize);
454         aEE.SetDeflection (aDeflection);
455         //
456         IntTools_Range anewSR1 = aSR1;
457         IntTools_Range anewSR2 = aSR2;
458         //
459         BOPTools_Tools::CorrectRange (aE1, aE2, aSR1, anewSR1);
460         BOPTools_Tools::CorrectRange (aE2, aE1, aSR2, anewSR2);
461         //
462         aEE.SetRange1(anewSR1);
463         aEE.SetRange2(anewSR2);
464           
465         aEE.Perform();
466         //
467         anIndexIn=0;
468         //
469         if (aEE.IsDone()) {
470           //
471           // reverse order if it is necessary
472           TopoDS_Edge aEWhat, aEWith;
473           aEWhat=aE1;
474           aEWith=aE2;
475           aWhat=nE1;
476           aWith=nE2;
477           if (aEE.Order()) {
478             aTmp=aWhat;
479             aWhat=aWith;
480             aWith=aTmp;
481             aEWhat=aE2;
482             aEWith=aE1;
483           }
484           //
485           const IntTools_SequenceOfCommonPrts& aCPrts=aEE.CommonParts();
486           
487           aNbCPrts=aCPrts.Length();
488           for (i=1; i<=aNbCPrts; i++) {
489             const IntTools_CommonPrt& aCPart=aCPrts(i);
490             //
491             anIndexIn=0;
492             //
493             TopAbs_ShapeEnum aType=aCPart.Type();
494             switch (aType) {
495               
496               case TopAbs_VERTEX:  {
497                 
498                 Standard_Real aT1, aT2; 
499                 
500                 const IntTools_Range& aR1=aCPart.Range1();
501                 aT1=0.5*(aR1.First()+aR1.Last());
502
503                 if((aCPart.VertexParameter1() >= aR1.First()) &&
504                    (aCPart.VertexParameter1() <= aR1.Last())) {
505                   aT1 = aCPart.VertexParameter1();
506                 }
507
508                 const IntTools_SequenceOfRanges& aRanges2=aCPart.Ranges2();
509                 const IntTools_Range& aR2=aRanges2(1);
510                 aT2=0.5*(aR2.First()+aR2.Last());
511
512                 if((aCPart.VertexParameter2() >= aR2.First()) &&
513                    (aCPart.VertexParameter2() <= aR2.Last())) {
514                   aT2 = aCPart.VertexParameter2();
515                 }
516                 //
517                 char buf[512];
518                 sprintf (buf, "EE: (%d, %d), vertex at t1=%f, t2=%f", aWhat, aWith, aT1, aT2);
519                 //
520                 gp_Pnt aPnt;
521                 BOPTools_Tools::PointOnEdge(aEWhat, aT1, aPnt);
522                 Handle (Geom_CartesianPoint) aCPnt= new Geom_CartesianPoint(aPnt);
523 //              myInerference=aCPnt;
524
525                 BOPTools_CheckResult aChRes;
526                 aChRes.AddShape(aE1);
527                 aChRes.AddShape(aE2);
528                 aChRes.SetCheckStatus(BOPTools_EDGEEDGE);
529 // modified by NIZHNY-MKK  Fri Sep  3 16:01:52 2004
530 //                 aChRes.SetInterferenceGeometry(myInerference);
531                 aChRes.SetInterferenceGeometry(aCPnt);
532                 myCheckResults.Append(aChRes);
533
534                 if(myStopOnFirst)
535                   throw BOPTColStd_Failure(buf) ;
536                 //
537               }
538               break;
539
540               case TopAbs_EDGE: {
541               
542                 const IntTools_SequenceOfRanges& aRanges2=aCPart.Ranges2();
543                 Standard_Integer aNbComPrt2=aRanges2.Length();
544                 
545                 if (aNbComPrt2>1) {
546                   break;
547                 }
548
549                 Standard_Boolean aCoinsideFlag;
550                 
551                 aCoinsideFlag=IsBlocksCoinside(aPB1, aPB2);
552                 //
553                 if (!aCoinsideFlag) {
554                   break;
555                 }
556                 //
557                 char buf[512];
558                 sprintf (buf, "EE: (%d, %d), common block ", aWhat, aWith);
559                 
560                 BOPTools_CheckResult aChRes;
561                 aChRes.AddShape(aE1);
562                 aChRes.AddShape(aE2);
563                 aChRes.SetCheckStatus(BOPTools_EDGEEDGECOMBLK);
564                 myCheckResults.Append(aChRes);
565
566                 if(myStopOnFirst)
567                   throw BOPTColStd_Failure(buf) ;
568                 //
569               }
570               break;
571
572             default:
573               break;
574             } // switch (aType) 
575           } // for (i=1; i<=aNbCPrts; i++) 
576         }// if (aEE.IsDone())
577         
578         //////////////////////////////////////////////
579       } // for (; anIt2.More(); anIt2.Next()) 
580     } // for (; anIt1.More(); anIt1.Next()) 
581   }// for (; myDSIt.More(); myDSIt.Next()) 
582   myIsDone=Standard_True;
583 }
584
585 //=======================================================================
586 // function: PerformEF
587 // purpose: 
588 //=======================================================================
589 void BOPTools_Checker::PerformEF()
590 {
591   myIsDone=Standard_False;
592   //
593   Standard_Boolean justaddinterference, bSameFlag;
594   Standard_Integer n1, n2,  nE, nF, i, aNbCPrts;
595   //
596   // E/F Interferences  [BooleanOperations_EdgeFace]
597   myDSIt.Initialize(TopAbs_EDGE, TopAbs_FACE);
598   //
599   for (; myDSIt.More(); myDSIt.Next()) {
600     justaddinterference = Standard_True;
601     myDSIt.Current(n1, n2, justaddinterference);
602     //
603     nE=n1; 
604     nF=n2; 
605     SortTypes(nE, nF);
606     //
607     Standard_Real aTolE, aTolF, aDeflection=0.01;
608     Standard_Integer aDiscretize=35;
609
610     const TopoDS_Edge& aE=TopoDS::Edge(myDS->GetShape(nE));
611     const TopoDS_Face& aF=TopoDS::Face(myDS->GetShape(nF));
612     //
613     if (BRep_Tool::Degenerated(aE)){
614       continue;
615     }
616     // 
617     TopTools_IndexedMapOfShape aMF;
618     //
619     bSameFlag=Standard_False;
620     //
621     TopExp::MapShapes(aF, TopAbs_EDGE, aMF);
622     if (aMF.Contains(aE)) { 
623       bSameFlag=Standard_True;
624     }
625     //
626     if (bSameFlag){
627       continue;
628     }
629     //
630     aTolE=BRep_Tool::Tolerance(aE);
631     aTolF=BRep_Tool::Tolerance(aF);
632     //
633     const Bnd_Box& aBBF=myDS->GetBoundingBox(nF); 
634     //
635     BOPTools_ListOfPaveBlock& aLPB=mySplitShapesPool(myDS->RefEdge(nE));
636     BOPTools_ListIteratorOfListOfPaveBlock anIt(aLPB);
637
638     for (; anIt.More(); anIt.Next()) {
639       BOPTools_PaveBlock& aPB=anIt.Value();
640       const IntTools_ShrunkRange& aShrunkRange=aPB.ShrunkRange();
641       const IntTools_Range& aSR =aShrunkRange.ShrunkRange();
642       const Bnd_Box&        aBBE=aShrunkRange.BndBox();
643       //
644       if (aBBF.IsOut (aBBE)) {
645         continue;
646       }
647       // 
648       // EF
649       IntTools_EdgeFace aEF;
650       aEF.SetEdge (aE);
651       aEF.SetFace (aF);
652       aEF.SetTolE (aTolE);
653       aEF.SetTolF (aTolF);
654       aEF.SetDiscretize (aDiscretize);
655       aEF.SetDeflection (aDeflection);
656
657       IntTools_Range anewSR = aSR;
658       //
659       BOPTools_Tools::CorrectRange(aE, aF, aSR, anewSR);
660       //
661       aEF.SetRange (anewSR);
662       //
663       aEF.Perform();
664       //
665       if (aEF.IsDone()) {
666         //
667         const IntTools_SequenceOfCommonPrts& aCPrts=aEF.CommonParts();
668         aNbCPrts=aCPrts.Length();
669         for (i=1; i<=aNbCPrts; i++) {
670           const IntTools_CommonPrt& aCPart=aCPrts(i);
671           //
672           TopAbs_ShapeEnum aType=aCPart.Type();
673           switch (aType) {
674               
675             case TopAbs_VERTEX:  {
676                 
677               Standard_Real aT; 
678               
679               const IntTools_Range& aR=aCPart.Range1();
680
681               Standard_Real aRFirst, aRLast;
682
683               aR.Range(aRFirst, aRLast);
684               aT=0.5*(aRFirst+aRLast);
685
686               if((aCPart.VertexParameter1() >= aRFirst) &&
687                  (aCPart.VertexParameter1() <= aRLast)) {
688                 aT = aCPart.VertexParameter1();
689               }
690               //
691               char buf[512];
692               sprintf (buf, "EF: (%d, %d), vertex at t=%f", nE, nF, aT);
693               //
694               gp_Pnt aPnt;
695               BOPTools_Tools::PointOnEdge(aE, aT, aPnt);
696               Handle (Geom_CartesianPoint) aCPnt= new Geom_CartesianPoint(aPnt);
697 //            myInerference=aCPnt;
698
699               BOPTools_CheckResult aChRes;
700               aChRes.AddShape(aE);
701               aChRes.AddShape(aF);
702               aChRes.SetCheckStatus(BOPTools_EDGEFACE);
703 // modified by NIZHNY-MKK  Fri Sep  3 16:02:10 2004
704 //               aChRes.SetInterferenceGeometry(myInerference);
705               aChRes.SetInterferenceGeometry(aCPnt);
706               myCheckResults.Append(aChRes);
707
708               if(myStopOnFirst)
709                 throw BOPTColStd_Failure(buf) ;
710             }// case TopAbs_VERTEX:
711               break;
712
713             case TopAbs_EDGE: {
714               
715               Standard_Boolean aCoinsideFlag;
716               aCoinsideFlag=BOPTools_Tools::IsBlockInOnFace(aPB, aF, myContext);
717               if (!aCoinsideFlag) {
718                 break;
719               }
720               //
721               char buf[512];
722               sprintf (buf, "EF: (%d, %d), common block ", nE, nF);
723
724               BOPTools_CheckResult aChRes;
725               aChRes.AddShape(aE);
726               aChRes.AddShape(aF);
727               aChRes.SetCheckStatus(BOPTools_EDGEFACECOMBLK);
728               myCheckResults.Append(aChRes);
729
730               if(myStopOnFirst)
731                 throw BOPTColStd_Failure(buf) ;
732             }// case TopAbs_EDGE:
733               break;
734
735             default:
736               break;
737           } // switch (aType) 
738         } // for (i=1; i<=aNbCPrts; i++) 
739       } //if (aEF.IsDone())
740     } // for (; anIt.More(); anIt.Next()) 
741   }// for (; myDSIt.More(); myDSIt.Next()) 
742   myIsDone=Standard_True;
743 }
744
745 //=======================================================================
746 // function: PerformFF
747 // purpose: 
748 //=======================================================================
749   void BOPTools_Checker::PerformFF()
750 {
751   myIsDone=Standard_False;
752   //
753   Standard_Boolean justaddinterference, bSameFlag;
754   Standard_Integer n1, n2, nF1, nF2, i, aNbS1;
755   //
756   //  F/F Interferences  [BooleanOperations_SurfaceSurface]
757   myDSIt.Initialize(TopAbs_FACE, TopAbs_FACE);
758   //
759   for (; myDSIt.More(); myDSIt.Next()) {
760     justaddinterference = Standard_True;
761     myDSIt.Current(n1, n2, justaddinterference);
762     //
763     nF1=n1; 
764     nF2=n2; 
765     if (nF1 > nF2) {
766       Standard_Integer iTmp;
767       iTmp=nF1;
768       nF1=nF2;
769       nF2=iTmp;
770     }
771     //
772     const TopoDS_Face& aF1=TopoDS::Face(myDS->Shape(nF1));
773     const TopoDS_Face& aF2=TopoDS::Face(myDS->Shape(nF2));
774     //
775     TopTools_IndexedMapOfShape aM1, aM2;
776     //
777     bSameFlag=Standard_False;
778     //
779     TopExp::MapShapes(aF1, TopAbs_EDGE, aM1);
780     TopExp::MapShapes(aF2, TopAbs_EDGE, aM2);
781     //
782     aNbS1=aM1.Extent();
783
784     for (i=1; i<=aNbS1; ++i) {
785       const TopoDS_Shape& aS1=aM1(i);
786       if (aM2.Contains(aS1)) {
787         bSameFlag=Standard_True;
788         break;
789       }
790     }
791     //
792     if (bSameFlag){
793       continue;
794     }
795     //
796     // FF
797     Standard_Boolean bToApproxC3d, bToApproxC2dOnS1, bToApproxC2dOnS2;
798     Standard_Real anApproxTol, aTolR3D, aTolR2D;
799     //
800     bToApproxC3d     = mySectionAttribute.Approximation();
801     bToApproxC2dOnS1 = mySectionAttribute.PCurveOnS1();
802     bToApproxC2dOnS2 = mySectionAttribute.PCurveOnS2();
803     //
804     anApproxTol=1.e-7;
805
806     IntTools_FaceFace aFF;
807     aFF.SetParameters (bToApproxC3d, 
808                        bToApproxC2dOnS1, 
809                        bToApproxC2dOnS2,
810                        anApproxTol);
811           
812     aFF.Perform(aF1, aF2);
813
814     if (aFF.IsDone()) {
815       // Add Interference to the Pool
816       aTolR3D=aFF.TolReached3d();
817       aTolR2D=aFF.TolReached2d();
818       if (aTolR3D < 1.e-7){
819         aTolR3D=1.e-7;
820       } 
821       aFF.PrepareLines3D();
822       //
823       //
824       Standard_Integer j, aNbCurves, aNbPoints;
825       //
826       const IntTools_SequenceOfCurves& aCvs=aFF.Lines();
827       aNbCurves=aCvs.Length();
828       //
829       const IntTools_SequenceOfPntOn2Faces& aPnts=aFF.Points();
830       aNbPoints=aPnts.Length();
831       
832       if (aNbPoints) {
833         char buf[512];
834         sprintf (buf, "FF: (%d, %d) ", nF1, nF2);
835         //
836         const IntTools_PntOn2Faces& aPntOn2Faces=aPnts(1);
837         const IntTools_PntOnFace& aPntOnFace=aPntOn2Faces.P1();
838         const gp_Pnt& aPnt=aPntOnFace.Pnt();
839         Handle (Geom_CartesianPoint) aCPnt= new Geom_CartesianPoint(aPnt);
840 //      myInerference=aCPnt;
841
842         BOPTools_CheckResult aChRes;
843         aChRes.AddShape(aF1);
844         aChRes.AddShape(aF2);
845         aChRes.SetCheckStatus(BOPTools_FACEFACE);
846 // modified by NIZHNY-MKK  Fri Sep  3 16:02:25 2004
847 //         aChRes.SetInterferenceGeometry(myInerference);
848         aChRes.SetInterferenceGeometry(aCPnt);
849         myCheckResults.Append(aChRes);
850
851         if(myStopOnFirst)
852           throw BOPTColStd_Failure(buf) ;
853       }
854       
855       if (aNbCurves) {
856         for (j=1; j<=aNbCurves; j++) {
857           const IntTools_Curve& aC=aCvs(j);
858           if (aC.HasBounds()) {
859             Standard_Real aT1, aT2;
860             Standard_Boolean bValid;
861             gp_Pnt aP1, aP2;
862             
863             aC.Bounds(aT1, aT2, aP1, aP2);
864             //
865             bValid=myContext->IsValidBlockForFaces(aT1, aT2, aC, aF1, aF2, 1.e-3);
866             //
867             if (bValid) {
868               char buf[512];
869               sprintf (buf, "FF: (%d, %d) ", nF1, nF2);
870               //
871               Handle (Geom_Curve) aC3D=aC.Curve();
872               Handle (Geom_TrimmedCurve) aTC3D=Handle (Geom_TrimmedCurve)::DownCast(aC3D);
873 //            myInerference=aTC3D;
874
875               BOPTools_CheckResult aChRes;
876               aChRes.AddShape(aF1);
877               aChRes.AddShape(aF2);
878               aChRes.SetCheckStatus(BOPTools_FACEFACE);
879 // modified by NIZHNY-MKK  Fri Sep  3 16:02:40 2004
880 //               aChRes.SetInterferenceGeometry(myInerference);
881               aChRes.SetInterferenceGeometry(aTC3D);
882               myCheckResults.Append(aChRes);
883
884               if(myStopOnFirst)
885                 throw BOPTColStd_Failure(buf) ;
886             }
887           }
888         }
889       }// if (aNbCurves)
890       
891     }// if (aFF.IsDone())
892   }// for (; myDSIt.More(); myDSIt.Next()) 
893   myIsDone=Standard_True;
894 }
895 //=======================================================================
896 // function: PrepareEdges
897 // purpose: 
898 //=======================================================================
899   void BOPTools_Checker::PrepareEdges()
900 {
901   Standard_Integer  i, nV, ii, aNBSuc;
902   Standard_Real aT;
903   TopAbs_Orientation anOr;
904   TopoDS_Edge   aE;
905   TopoDS_Vertex aV;
906
907   for (i=1; i<=myNbSources; i++) {
908     if (myDS->GetShapeType(i)==TopAbs_EDGE) {
909       aE=TopoDS::Edge(myDS->GetShape(i));
910       //
911       if (BRep_Tool::Degenerated(aE)){
912         continue;
913       }
914       //
915       BOPTools_PaveSet& aPaveSet= myPavePool(myDS->RefEdge(i));
916       //
917       //                                                   cto900/M2
918       // Some of Edges can be [Semi] Infinite.  Such  Edges have no 
919       // vertices on correspondant INF ends.   So we  must  provide 
920       // these vertices formally (to obtain  Shrunk  Ranges for e.g). 
921       // In reality this vertex(-es) does not belong to the INF Edge.
922       // It just has reference in the DS.
923       //                            PKV Tue Apr 23 10:21:45 2002                 
924       {
925         Standard_Real aT1, aT2, aTolE;
926         Standard_Boolean bInf1, bInf2;
927         gp_Pnt aPx;
928         TopoDS_Vertex aVx; 
929         BRep_Builder aBB;
930         BooleanOperations_AncestorsSeqAndSuccessorsSeq anASSeq; 
931         //
932         aTolE=BRep_Tool::Tolerance(aE);
933         Handle(Geom_Curve) aC3D=BRep_Tool::Curve (aE, aT1, aT2);
934         bInf1=Precision::IsNegativeInfinite(aT1);
935         bInf2=Precision::IsPositiveInfinite(aT2);
936
937         if (bInf1) {
938           aC3D->D0(aT1, aPx);
939           aBB.MakeVertex(aVx, aPx, aTolE);
940           myDS->InsertShapeAndAncestorsSuccessors(aVx, anASSeq);
941           nV=myDS->NumberOfInsertedShapes();
942           BOPTools_Pave aPave(nV, aT1); 
943           aPaveSet.Append (aPave);
944         }
945
946         if (bInf2) {
947           aC3D->D0(aT2, aPx);
948           aBB.MakeVertex(aVx, aPx, aTolE);
949           myDS->InsertShapeAndAncestorsSuccessors(aVx, anASSeq);
950           nV=myDS->NumberOfInsertedShapes();
951           BOPTools_Pave aPave(nV, aT2);
952           aPaveSet.Append (aPave); 
953         }
954       }
955       //
956       aNBSuc=myDS->NumberOfSuccessors(i);
957       for (ii=1; ii <= aNBSuc; ii++) {
958         nV=myDS->GetSuccessor(i, ii);
959         anOr=myDS->GetOrientation(i, ii);
960
961         aV=TopoDS::Vertex(myDS->GetShape(nV));
962         aV.Orientation(anOr);
963         aT=BRep_Tool::Parameter(aV, aE);
964         //
965         BOPTools_Pave aPave(nV, aT); 
966         aPaveSet.Append (aPave);
967       }
968     }
969   }
970 }
971 //=======================================================================
972 // function: PreparePaveBlocks
973 // purpose: 
974 //=======================================================================
975   void BOPTools_Checker::PreparePaveBlocks(const TopAbs_ShapeEnum aType1, 
976                                            const TopAbs_ShapeEnum aType2)
977 {
978   BOPTools_PaveFiller::PreparePaveBlocks(aType1, aType2);
979 }
980 //=======================================================================
981 // function: PreparePaveBlocks
982 // purpose: 
983 //=======================================================================
984   void BOPTools_Checker::PreparePaveBlocks(const Standard_Integer nE)
985 {
986   myIsDone=Standard_False;
987   
988   Standard_Integer nV1, nV2;
989
990   TopoDS_Edge aE;
991   TopoDS_Vertex aV1, aV2;
992     
993   // SplitShapesPool
994   BOPTools_ListOfPaveBlock& aLPB=mySplitShapesPool(myDS->RefEdge(nE));
995   // Edge 
996   aE=TopoDS::Edge(myDS->GetShape(nE));
997   //
998   if (!BRep_Tool::Degenerated(aE)){
999     //
1000     BOPTools_PaveSet& aPS=myPavePool(myDS->RefEdge(nE));
1001     
1002     BOPTools_PaveBlockIterator aPBIt(nE, aPS);
1003     for (; aPBIt.More(); aPBIt.Next()) {
1004       BOPTools_PaveBlock& aPB=aPBIt.Value();
1005       
1006       const IntTools_Range& aRange=aPB.Range();
1007       
1008       const BOPTools_Pave& aPave1=aPB.Pave1();
1009       nV1=aPave1.Index();
1010       aV1=TopoDS::Vertex(myDS->GetShape(nV1));
1011       
1012       const BOPTools_Pave& aPave2=aPB.Pave2();
1013       nV2=aPave2.Index();
1014       aV2=TopoDS::Vertex(myDS->GetShape(nV2));
1015       //
1016       // ShrunkRange
1017       IntTools_ShrunkRange aSR (aE, aV1, aV2, aRange, myContext);
1018       //
1019       Standard_Integer anErrorStatus;
1020       anErrorStatus=aSR.ErrorStatus();
1021
1022       char buf[512];
1023       if (!aSR.IsDone()) {
1024         sprintf (buf, "Can not obtain ShrunkRange for Edge %d", nE);
1025         
1026         BOPTools_CheckResult aChRes;
1027         aChRes.AddShape(aE);
1028         aChRes.SetCheckStatus(BOPTools_BADSHRANKRANGE);
1029         myCheckResults.Append(aChRes);
1030
1031         if(myStopOnFirst)
1032           throw BOPTColStd_Failure(buf) ;
1033       }
1034       //
1035       if (anErrorStatus==6) {
1036         sprintf(buf,
1037                 "Warning: [PreparePaveBlocks()] Max.Dummy Shrunk Range for Edge %d\n", nE);
1038
1039         BOPTools_CheckResult aChRes;
1040         aChRes.AddShape(aE);
1041         aChRes.SetCheckStatus(BOPTools_NULLSRANKRANGE);
1042         myCheckResults.Append(aChRes);
1043
1044         if(myStopOnFirst)
1045           throw BOPTColStd_Failure(buf);
1046       }
1047       else {
1048         // Check left paves and correct ShrunkRange if it is necessary
1049         CorrectShrunkRanges (0, aPave1, aSR);
1050         CorrectShrunkRanges (1, aPave2, aSR);
1051       }
1052       //
1053       aPB.SetShrunkRange(aSR);
1054       aLPB.Append(aPB);
1055     } //for (; aPBIt1.More(); aPBIt1.Next()) 
1056   }
1057   myIsDone=Standard_True;
1058 }
1059
1060 //=======================================================================
1061 // function: GetCheckResult
1062 // purpose: 
1063 //=======================================================================
1064 const BOPTools_ListOfCheckResults& BOPTools_Checker::GetCheckResult() const
1065 {
1066   return myCheckResults;
1067 }
1068
1069 //=======================================================================
1070 // function: HasFaulty
1071 // purpose: 
1072 //=======================================================================
1073   Standard_Boolean BOPTools_Checker::HasFaulty()const 
1074 {
1075   return (!myIsDone || !myCheckResults.IsEmpty());
1076 }
1077
1078 //=======================================================================
1079 // function: Shape
1080 // purpose: 
1081 //=======================================================================
1082   const TopoDS_Shape& BOPTools_Checker::Shape()const 
1083 {
1084   return myShape;
1085 }
1086
1087
1088