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