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