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