0023024: Update headers of OCCT files
[occt.git] / src / BOPTools / BOPTools_DEProcessor.cxx
1 // Created on: 2001-09-12
2 // Created by: Peter KURNEV
3 // Copyright (c) 2001-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 #include <BOPTools_DEProcessor.ixx>
22
23
24 #include <TopoDS_Shape.hxx>
25 #include <TopoDS_Edge.hxx>
26 #include <TopoDS.hxx>
27 #include <TopoDS_Face.hxx>
28 #include <TopoDS_Vertex.hxx>
29 #include <TopoDS_Solid.hxx>
30
31 #include <TopExp.hxx>
32 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
33 #include <TopTools_ListOfShape.hxx>
34 #include <TopTools_ListIteratorOfListOfShape.hxx>
35
36 #include <gp_Pnt2d.hxx>
37 #include <gp_Pnt.hxx>
38 #include <gp_Sphere.hxx>
39
40 #include <IntRes2d_IntersectionPoint.hxx>
41
42 #include <Precision.hxx>
43
44 #include <Geom2d_Curve.hxx>
45 #include <Geom2d_Line.hxx>
46 #include <Geom2dAdaptor_Curve.hxx>
47 #include <Geom2dInt_GInter.hxx>
48
49 #include <BRep_Tool.hxx>
50 #include <BRep_Builder.hxx>
51 #include <BRepClass3d_SolidClassifier.hxx>
52 #include <BRepAdaptor_Surface.hxx>
53
54 #include <BRepExtrema_DistShapeShape.hxx>
55
56 #include <TColStd_ListIteratorOfListOfInteger.hxx>
57 #include <TColStd_ListOfInteger.hxx>
58
59 #include <BooleanOperations_ShapesDataStructure.hxx>
60 #include <BooleanOperations_AncestorsSeqAndSuccessorsSeq.hxx>
61
62 #include <IntTools_Range.hxx>
63 #include <IntTools_Tools.hxx>
64 #include <IntTools_Context.hxx>
65
66 #include <BOPTools_DEInfo.hxx>
67 #include <BOPTools_ListOfPaveBlock.hxx>
68 #include <BOPTools_SSInterference.hxx>
69 #include <BOPTools_PaveBlock.hxx>
70 #include <BOPTools_ListIteratorOfListOfPaveBlock.hxx>
71 #include <BOPTools_SequenceOfCurves.hxx>
72 #include <BOPTools_Curve.hxx>
73 #include <BOPTools_PavePool.hxx>
74 #include <BOPTools_Pave.hxx>
75 #include <BOPTools_PaveSet.hxx>
76 #include <BOPTools_Tools3D.hxx>
77 #include <BOPTools_PaveBlockIterator.hxx>
78 #include <BOPTools_ListOfPave.hxx>
79 #include <BOPTools_ListIteratorOfListOfPave.hxx>
80 #include <BOPTools_InterferencePool.hxx>
81 #include <BOPTools_CArray1OfSSInterference.hxx>
82 #include <BOPTools_ListIteratorOfListOfPaveBlock.hxx>
83 #include <BOPTools_PaveFiller.hxx>
84 #include <BOPTools_ListOfPaveBlock.hxx>
85 #include <BOPTools_SplitShapesPool.hxx>
86 #include <BOPTools_StateFiller.hxx>
87
88 //=======================================================================
89 // function: BOPTools_DEProcessor::BOPTools_DEProcessor
90 // purpose: 
91 //=======================================================================
92 BOPTools_DEProcessor::BOPTools_DEProcessor(const BOPTools_PaveFiller& aFiller,
93                                              const Standard_Integer aDim)
94 :
95    myIsDone(Standard_False)
96 {
97   myFiller=(BOPTools_PaveFiller*) &aFiller;
98   myDS=myFiller->DS();
99   
100   myDim=aDim;
101   if (aDim<2 || aDim>3) {
102     myDim=3;
103   }
104   
105 }
106
107 //=======================================================================
108 // function: IsDone
109 // purpose: 
110 //=======================================================================
111   Standard_Boolean BOPTools_DEProcessor::IsDone() const
112 {
113   return myIsDone;
114 }
115 //=======================================================================
116 // function:  Do
117 // purpose: 
118 //=======================================================================
119   void BOPTools_DEProcessor::Do()
120 {
121   Standard_Integer aNbE;
122   myIsDone=Standard_False;
123
124   FindDegeneratedEdges();
125   aNbE=myDEMap.Extent();
126   
127   if (!aNbE) {
128     myIsDone=Standard_True;
129     return;
130   }
131   
132   DoPaves();
133 }
134
135 //=======================================================================
136 // function:  FindDegeneratedEdges
137 // purpose: 
138 //=======================================================================
139   void BOPTools_DEProcessor::FindDegeneratedEdges()
140 {
141   const BooleanOperations_ShapesDataStructure& aDS=*myDS;
142   const BOPTools_PaveFiller& aPaveFiller=*myFiller;
143
144   Standard_Integer i, aNbSourceShapes, nV, nF, nVx, ip, iRankE;
145   TopAbs_ShapeEnum aType;
146
147   const TopoDS_Shape& anObj=aDS.Object();
148   const TopoDS_Shape& aTool=aDS.Tool();
149   
150   TopTools_IndexedDataMapOfShapeListOfShape aMEF;
151   TopExp::MapShapesAndAncestors (anObj, TopAbs_EDGE, TopAbs_FACE, aMEF);
152   TopExp::MapShapesAndAncestors (aTool, TopAbs_EDGE, TopAbs_FACE, aMEF);
153
154   aNbSourceShapes=aDS.NumberOfSourceShapes();
155   for (i=1; i<=aNbSourceShapes; i++) {
156     const TopoDS_Shape& aS=aDS.Shape(i);
157     aType=aS.ShapeType();
158     if (aType==TopAbs_EDGE) {
159       const TopoDS_Edge& aE=TopoDS::Edge(aS);
160       if (BRep_Tool::Degenerated(aE)) {
161
162         iRankE=aDS.Rank(i);
163
164         TopoDS_Vertex aV=TopExp::FirstVertex(aE);
165
166         nVx=aDS.ShapeIndex(aV, iRankE);
167         //
168         nV=nVx;
169         ip=aPaveFiller.FindSDVertex(nV);
170         if (ip) {
171           nV=ip;
172         }
173         //
174         TColStd_ListOfInteger aLFn;
175         const TopTools_ListOfShape& aLF=aMEF.FindFromKey(aE);
176         TopTools_ListIteratorOfListOfShape anIt(aLF);
177         for (; anIt.More(); anIt.Next()) {
178           const TopoDS_Shape& aF=anIt.Value();
179
180           nF=aDS.ShapeIndex(aF, iRankE);
181
182           aLFn.Append(nF);
183         }
184         BOPTools_DEInfo aDEInfo;
185         aDEInfo.SetVertex(nV);
186         aDEInfo.SetFaces(aLFn);
187
188         myDEMap.Add (i, aDEInfo);
189
190       }
191     }
192   }
193   
194 }
195 //=======================================================================
196 // function:  DoPaves
197 // purpose: 
198 //=======================================================================
199   void BOPTools_DEProcessor::DoPaves()
200 {
201
202   Standard_Integer i, aNbE, nED, nVD, nFD=0;
203   
204   aNbE=myDEMap.Extent();
205   for (i=1; i<=aNbE; i++) {
206     nED=myDEMap.FindKey(i);
207     
208     const BOPTools_DEInfo& aDEInfo=myDEMap(i);
209     nVD=aDEInfo.Vertex();
210     // Fill PaveSet for the edge nED
211     const TColStd_ListOfInteger& nLF=aDEInfo.Faces();
212     TColStd_ListIteratorOfListOfInteger anIt(nLF);
213     for (; anIt.More(); anIt.Next()) {
214       nFD=anIt.Value();
215       
216       BOPTools_ListOfPaveBlock aLPB;
217       FindPaveBlocks(nED, nVD, nFD, aLPB);
218       FillPaveSet (nED, nVD, nFD, aLPB);
219     }
220     // 
221     // Fill aSplitEdges for the edge nED
222     FillSplitEdgesPool(nED);
223     //
224     // MakeSplitEdges
225     MakeSplitEdges(nED, nFD);
226     //
227     // Compute States for Split parts
228     if (myDim==3) {
229       DoStates(nED, nFD);
230     }
231     if (myDim==2) {
232       DoStates2D(nED, nFD);
233     }
234   }// next nED
235 }
236
237 //=======================================================================
238 // function:  DoStates
239 // purpose: 
240 //=======================================================================
241   void BOPTools_DEProcessor::DoStates (const Standard_Integer nED, 
242                                        const Standard_Integer nFD)
243 {
244   
245   
246   const BOPTools_SplitShapesPool& aSplitShapesPool=myFiller->SplitShapesPool();
247   const BOPTools_ListOfPaveBlock& aSplitEdges=aSplitShapesPool(myDS->RefEdge(nED));
248
249   const TopoDS_Edge& aDE=TopoDS::Edge(myDS->Shape(nED));
250   const TopoDS_Face& aDF=TopoDS::Face(myDS->Shape(nFD));
251   
252   Standard_Integer nSp, iRank;
253   Standard_Real aT, aT1, aT2, aTol=1e-7;
254   TopoDS_Face aF;
255   gp_Pnt2d aPx2DNear;
256   gp_Pnt aPxNear;
257
258   iRank=myDS->Rank(nED);
259   const TopoDS_Shape& aReference=(iRank==1) ? myDS->Tool() : myDS->Object();
260
261   BRepExtrema_DistShapeShape aDSS;
262   aDSS.LoadS1(aReference);
263
264   aF=aDF;
265   aF.Orientation(TopAbs_FORWARD);
266
267   BOPTools_ListIteratorOfListOfPaveBlock aPBIt(aSplitEdges);
268
269   for (; aPBIt.More(); aPBIt.Next()) {
270     BOPTools_PaveBlock& aPB=aPBIt.Value();
271     
272     nSp=aPB.Edge();
273     const TopoDS_Edge& aSp=TopoDS::Edge(myDS->Shape(nSp));
274     
275     aPB.Parameters(aT1, aT2);
276     aT=IntTools_Tools::IntermediatePoint(aT1, aT2);
277
278     TopoDS_Edge aDERight, aSpRight;
279     aDERight=aDE;
280     aSpRight=aSp;
281
282     BOPTools_Tools3D::OrientEdgeOnFace (aDE, aF, aDERight);
283     aSpRight.Orientation(aDERight.Orientation());
284     //
285     {
286       BRepAdaptor_Surface aBAS;
287       aBAS.Initialize (aDF, Standard_False);
288
289       if (aBAS.GetType()==GeomAbs_Sphere) {
290         Standard_Real aDt2D, aR, aDelta=1.e-14;
291         
292         gp_Sphere aSphere=aBAS.Sphere();
293         aR=aSphere.Radius();
294         //
295         aDt2D=acos (1.-4.*aTol/aR)+aDelta ;
296         //
297         BOPTools_Tools3D::PointNearEdge(aSpRight, aF, aT, aDt2D, aPx2DNear, aPxNear);
298       }
299       else {
300         BOPTools_Tools3D::PointNearEdge(aSpRight, aF, aT, aPx2DNear, aPxNear);
301       }
302     }
303     // 
304     TopAbs_State aState;
305     //
306     TopAbs_ShapeEnum aTypeReference;
307     aTypeReference=aReference.ShapeType();
308
309     if (aTypeReference==TopAbs_SOLID) {
310       // ... \ Solid processing 
311       const Handle(IntTools_Context)& aContext=myFiller->Context();
312       const TopoDS_Solid& aReferenceSolid=TopoDS::Solid(aReference);
313       BRepClass3d_SolidClassifier& SC=aContext->SolidClassifier(aReferenceSolid);
314       //
315       SC.Perform(aPxNear, aTol);
316       //
317       aState=SC.State();
318     }
319     //
320     
321     else if (aTypeReference==TopAbs_SHELL || 
322              aTypeReference==TopAbs_FACE) {
323       // ... \ Shell processing 
324       TopoDS_Vertex aVxNear;
325       BRep_Builder BB;
326       
327       BB.MakeVertex(aVxNear, aPxNear, aTol);
328
329       aDSS.LoadS2(aVxNear);
330       aDSS.Perform();
331       
332       aState=TopAbs_OUT;
333       if (aDSS.IsDone()) {
334         Standard_Real aDist=aDSS.Value();
335         if (aDist < aTol) {
336           aState=TopAbs_ON;
337         }
338       }
339     }
340     else {
341       // unknown aTypeReference
342       aState=TopAbs_OUT;
343     }
344     //
345     BooleanOperations_StateOfShape aSt;
346
347     aSt=BOPTools_StateFiller::ConvertState(aState);
348
349     myDS->SetState(nSp, aSt);
350   }
351 }
352 //=======================================================================
353 // function:  DoStates2D
354 // purpose: 
355 //=======================================================================
356   void BOPTools_DEProcessor::DoStates2D (const Standard_Integer nED, 
357                                          const Standard_Integer nFD)
358 {
359   
360   
361   const BOPTools_SplitShapesPool& aSplitShapesPool=myFiller->SplitShapesPool();
362   const BOPTools_ListOfPaveBlock& aSplitEdges=aSplitShapesPool(myDS->RefEdge(nED));
363
364   const TopoDS_Edge& aDE=TopoDS::Edge(myDS->Shape(nED));
365   const TopoDS_Face& aDF=TopoDS::Face(myDS->Shape(nFD));
366   
367   Standard_Integer nSp, iRank;
368   Standard_Real aT, aT1, aT2;
369   TopoDS_Face aF;
370   gp_Pnt2d aPx2DNear;
371   gp_Pnt aPxNear;
372
373   iRank=myDS->Rank(nED);
374   const TopoDS_Shape& aReference=(iRank==1) ? myDS->Tool() : myDS->Object();
375   const TopoDS_Face& aFaceReference=TopoDS::Face(aReference);
376
377   aF=aDF;
378   aF.Orientation(TopAbs_FORWARD);
379
380   BOPTools_ListIteratorOfListOfPaveBlock aPBIt(aSplitEdges);
381
382   for (; aPBIt.More(); aPBIt.Next()) {
383     BOPTools_PaveBlock& aPB=aPBIt.Value();
384     
385     nSp=aPB.Edge();
386     const TopoDS_Edge& aSp=TopoDS::Edge(myDS->Shape(nSp));
387     
388     aPB.Parameters(aT1, aT2);
389     aT=IntTools_Tools::IntermediatePoint(aT1, aT2);
390
391     TopoDS_Edge aDERight, aSpRight;
392     aDERight=aDE;
393     aSpRight=aSp;
394
395     BOPTools_Tools3D::OrientEdgeOnFace (aDE, aF, aDERight);
396     aSpRight.Orientation(aDERight.Orientation());
397     //
398     BOPTools_Tools3D::PointNearEdge(aSpRight, aDF, aT, aPx2DNear, aPxNear);
399     //
400     Standard_Boolean bIsValidPoint;
401     TopAbs_State aState=TopAbs_OUT;
402     //
403     const Handle(IntTools_Context)& aContext=myFiller->Context();
404     bIsValidPoint=aContext->IsValidPointForFace(aPxNear, aFaceReference, 1.e-3);
405     //
406     if (bIsValidPoint) {
407       aState=TopAbs_IN;
408     }
409     //
410     BooleanOperations_StateOfShape aSt;
411     
412     aSt=BOPTools_StateFiller::ConvertState(aState);
413
414     myDS->SetState(nSp, aSt);
415   }
416 }
417
418 //=======================================================================
419 // function:  FillSplitEdgesPool
420 // purpose: 
421 //=======================================================================
422   void BOPTools_DEProcessor::FillSplitEdgesPool (const Standard_Integer nED)
423 {
424   BOPTools_SplitShapesPool& aSplitShapesPool=myFiller->ChangeSplitShapesPool();
425   //
426   BOPTools_ListOfPaveBlock& aSplitEdges=aSplitShapesPool.ChangeValue(myDS->RefEdge(nED));
427   //
428   aSplitEdges.Clear();
429   //
430   const BOPTools_PavePool& aPavePool=myFiller->PavePool();
431   BOPTools_PavePool* pPavePool=(BOPTools_PavePool*) &aPavePool;
432   BOPTools_PaveSet& aPaveSet= pPavePool->ChangeValue(myDS->RefEdge(nED));
433   
434   BOPTools_PaveBlockIterator aPBIt(nED, aPaveSet);
435   for (; aPBIt.More(); aPBIt.Next()) {
436     BOPTools_PaveBlock& aPB=aPBIt.Value();
437     aSplitEdges.Append(aPB);
438   }
439 }
440
441 //=======================================================================
442 // function:  MakeSplitEdges
443 // purpose: 
444 //=======================================================================
445   void BOPTools_DEProcessor::MakeSplitEdges (const Standard_Integer nED,
446                                              const Standard_Integer nFD)
447 {
448   const BOPTools_SplitShapesPool& aSplitShapesPool=myFiller->SplitShapesPool();
449   const BOPTools_ListOfPaveBlock& aSplitEdges=aSplitShapesPool(myDS->RefEdge(nED));
450
451   Standard_Integer nV1, nV2, aNewShapeIndex;
452   Standard_Real    t1, t2;
453   TopoDS_Edge aE, aESplit;
454   TopoDS_Vertex aV1, aV2;
455
456   const TopoDS_Edge aDE=TopoDS::Edge(myDS->Shape(nED));
457   const TopoDS_Face aDF=TopoDS::Face(myDS->Shape(nFD));
458
459   BOPTools_ListIteratorOfListOfPaveBlock aPBIt(aSplitEdges);
460
461   for (; aPBIt.More(); aPBIt.Next()) {
462     BOPTools_PaveBlock& aPB=aPBIt.Value();
463     
464     const BOPTools_Pave& aPave1=aPB.Pave1();
465     nV1=aPave1.Index();
466     t1=aPave1.Param();
467     aV1=TopoDS::Vertex(myDS->GetShape(nV1));
468     aV1.Orientation(TopAbs_FORWARD);
469     
470     const BOPTools_Pave& aPave2=aPB.Pave2();
471     nV2=aPave2.Index();
472     t2=aPave2.Param();
473     aV2=TopoDS::Vertex(myDS->GetShape(nV2));
474     aV2.Orientation(TopAbs_REVERSED);
475     
476     MakeSplitEdge(aDE, aDF, aV1, t1, aV2, t2, aESplit); 
477     //
478     // Add Split Part of the Original Edge to the DS
479     BooleanOperations_AncestorsSeqAndSuccessorsSeq anASSeq;
480     
481     anASSeq.SetNewSuccessor(nV1);
482     anASSeq.SetNewOrientation(aV1.Orientation());
483     
484     anASSeq.SetNewSuccessor(nV2);
485     anASSeq.SetNewOrientation(aV2.Orientation());
486     
487     myDS->InsertShapeAndAncestorsSuccessors(aESplit, anASSeq);
488     aNewShapeIndex=myDS->NumberOfInsertedShapes();
489     myDS->SetState(aNewShapeIndex, BooleanOperations_UNKNOWN);
490     //
491     // Fill Split Set for the Original Edge
492     aPB.SetEdge(aNewShapeIndex);
493     //
494   }
495 }
496 //=======================================================================
497 // function:  MakeSplitEdge
498 // purpose: 
499 //=======================================================================
500   void BOPTools_DEProcessor::MakeSplitEdge (const TopoDS_Edge&   aE,
501                                             const TopoDS_Face&   aF,
502                                             const TopoDS_Vertex& aV1,
503                                             const Standard_Real  aP1,
504                                             const TopoDS_Vertex& aV2,
505                                             const Standard_Real  aP2,
506                                             TopoDS_Edge& aNewEdge)
507 {
508   Standard_Real aTol=1.e-7;
509
510   TopoDS_Edge E=aE;
511
512   E.EmptyCopy();
513   BRep_Builder BB;
514   BB.Add  (E, aV1);
515   BB.Add  (E, aV2);
516
517   BB.Range(E, aF, aP1, aP2);
518
519   BB.Degenerated(E, Standard_True);
520
521   BB.UpdateEdge(E, aTol);
522   aNewEdge=E;
523 }
524
525
526                         
527 //=======================================================================
528 // function:  FillPaveSet
529 // purpose: 
530 //=======================================================================
531   void BOPTools_DEProcessor::FillPaveSet (const Standard_Integer nED,
532                                           const Standard_Integer nVD,
533                                           const Standard_Integer nFD,
534                                           BOPTools_ListOfPaveBlock& aLPB)
535 {
536   Standard_Boolean bIsDone, bXDir;
537   Standard_Integer nE, aNbPoints, j;
538   Standard_Real aTD1, aTD2, aT1, aT2, aTolInter, aX, aDT;
539   //
540   aDT=Precision::PConfusion();
541   //
542   BOPTools_PaveSet& aPaveSet= (myFiller->ChangePavePool()).ChangeValue(myDS->RefEdge(nED));
543   //
544   // Clear aPaveSet, aSplitEdges
545   aPaveSet.ChangeSet().Clear();
546   //
547   const TopoDS_Edge& aDE=TopoDS::Edge(myDS->Shape(nED));
548   const TopoDS_Face& aDF=TopoDS::Face(myDS->Shape(nFD));
549   //
550   // 2D Curve of degenerated edge on the face aDF
551   Handle(Geom2d_Curve) aC2DDE=BRep_Tool::CurveOnSurface(aDE, aDF, aTD1, aTD2);
552   //
553   // Choose direction for Degenerated Edge
554   gp_Pnt2d aP2d1, aP2d2;
555   aC2DDE->D0(aTD1, aP2d1);
556   aC2DDE->D0(aTD2, aP2d2);
557
558   bXDir=Standard_False;
559   if (fabs(aP2d1.Y()-aP2d2.Y()) < aDT){
560     bXDir=!bXDir;
561   }
562   //
563   // Prepare bounding Paves
564   BOPTools_Pave aPave1 (nVD, aTD1, BooleanOperations_UnknownInterference);
565   aPaveSet.Append(aPave1);
566   BOPTools_Pave aPave2 (nVD, aTD2, BooleanOperations_UnknownInterference);
567   aPaveSet.Append(aPave2);
568   //
569   // Fill other paves 
570   BOPTools_ListIteratorOfListOfPaveBlock anIt(aLPB);
571   for (; anIt.More(); anIt.Next()) {
572     const BOPTools_PaveBlock& aPB=anIt.Value();
573     nE=aPB.Edge();
574     const TopoDS_Edge& aE=TopoDS::Edge(myDS->Shape(nE));
575     
576     Handle(Geom2d_Curve) aC2D=BRep_Tool::CurveOnSurface(aE, aDF, aT1, aT2);
577     //
578     // Intersection
579     aTolInter=0.001;
580     
581     
582     Geom2dAdaptor_Curve aGAC1, aGAC2;
583     
584     aGAC1.Load(aC2DDE, aTD1, aTD2);
585     Handle(Geom2d_Line) aL2D= Handle(Geom2d_Line)::DownCast(aC2D);
586     if (!aL2D.IsNull()) {
587       aGAC2.Load(aC2D);
588     }
589     else {
590       aGAC2.Load(aC2D, aT1, aT2);
591     }
592     
593     Geom2dInt_GInter aGInter(aGAC1, aGAC2, aTolInter, aTolInter);
594     
595     bIsDone=aGInter.IsDone();
596     if(bIsDone) {
597       aNbPoints=aGInter.NbPoints();
598       if (aNbPoints) { 
599         for (j=1; j<=aNbPoints; ++j) {
600           gp_Pnt2d aP2D=aGInter.Point(j).Value();
601           //
602           aX=(bXDir) ? aP2D.X(): aP2D.Y();
603           //
604           if (fabs (aX-aTD1) < aDT || fabs (aX-aTD2) < aDT) {
605             continue; 
606           }
607           if (aX < aTD1 || aX > aTD2) {
608             continue; 
609           }
610           //
611           Standard_Boolean bRejectFlag=Standard_False;
612           const BOPTools_ListOfPave& aListOfPave=aPaveSet.Set();
613           BOPTools_ListIteratorOfListOfPave aPaveIt(aListOfPave);
614           for (; aPaveIt.More(); aPaveIt.Next()) {
615             const BOPTools_Pave& aPavex=aPaveIt.Value();
616             Standard_Real aXx=aPavex.Param();
617             if (fabs (aX-aXx) < aDT) {
618               bRejectFlag=Standard_True;
619               break;
620             }
621           }
622           if (bRejectFlag) {
623             continue; 
624           }
625           //
626           BOPTools_Pave aPave(nVD, aX, BooleanOperations_UnknownInterference);
627           aPaveSet.Append(aPave);
628         }
629       }
630     }
631   }
632 }
633
634 //=======================================================================
635 // function:  FindPaveBlocks
636 // purpose: 
637 //=======================================================================
638   void BOPTools_DEProcessor::FindPaveBlocks(const Standard_Integer ,
639                                             const Standard_Integer nVD,
640                                             const Standard_Integer nFD,
641                                             BOPTools_ListOfPaveBlock& aLPBOut)
642 {
643
644   BOPTools_CArray1OfSSInterference& aFFs=(myFiller->InterfPool())->SSInterferences();
645   
646   BOPTools_ListIteratorOfListOfPaveBlock anIt;
647   Standard_Integer i, aNb, nF2, nSp, nV;
648
649   //ZZ const TopoDS_Edge& aDE=TopoDS::Edge(myDS->Shape(nED));
650   
651   aNb=aFFs.Extent();
652   for (i=1; i<=aNb; i++) {
653     BOPTools_SSInterference& aFF=aFFs(i);
654     //
655     nF2=aFF.OppositeIndex(nFD);
656     if (!nF2) {
657       continue;
658     }
659     //
660     // Split Parts 
661     const BOPTools_ListOfPaveBlock& aLPBSplits=aFF.PaveBlocks();
662     anIt.Initialize(aLPBSplits);
663     for (; anIt.More(); anIt.Next()) {
664       const BOPTools_PaveBlock& aPBSp=anIt.Value();
665       nSp=aPBSp.Edge();
666       
667       const BOPTools_Pave& aPave1=aPBSp.Pave1();
668       nV=aPave1.Index();
669       if (nV==nVD) {
670         aLPBOut.Append(aPBSp);
671         continue;
672       }
673       
674       const BOPTools_Pave& aPave2=aPBSp.Pave2();
675       nV=aPave2.Index();
676       if (nV==nVD) {
677         aLPBOut.Append(aPBSp);
678         continue;
679       }
680     }
681     //
682     // Section Parts
683     Standard_Integer j, aNbCurves;   
684     BOPTools_SequenceOfCurves& aSC=aFF.Curves();
685     aNbCurves=aSC.Length();
686     
687     for (j=1; j<=aNbCurves; j++) {
688       const BOPTools_Curve& aBC=aSC(j);
689       const BOPTools_ListOfPaveBlock& aLPBSe=aBC.NewPaveBlocks();
690
691       anIt.Initialize(aLPBSe);
692       for (; anIt.More(); anIt.Next()) {
693         const BOPTools_PaveBlock& aPBSe=anIt.Value();
694         
695         const BOPTools_Pave& aPv1=aPBSe.Pave1();
696         nV=aPv1.Index();
697         if (nV==nVD) {
698           aLPBOut.Append(aPBSe);
699           continue;
700         }
701         
702         const BOPTools_Pave& aPv2=aPBSe.Pave2();
703         nV=aPv2.Index();
704         if (nV==nVD) {
705           aLPBOut.Append(aPBSe);
706           continue;
707         }
708       }
709     }
710
711   } // for (i=1; i<=aNb; i++) Next FF interference
712   
713 }