1 // File: BOPTools_DEProcessor.cxx
2 // Created: Wed Sep 12 12:10:52 2001
3 // Author: Peter KURNEV
6 #include <BOPTools_DEProcessor.ixx>
9 #include <TopoDS_Shape.hxx>
10 #include <TopoDS_Edge.hxx>
12 #include <TopoDS_Face.hxx>
13 #include <TopoDS_Vertex.hxx>
14 #include <TopoDS_Solid.hxx>
17 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
18 #include <TopTools_ListOfShape.hxx>
19 #include <TopTools_ListIteratorOfListOfShape.hxx>
21 #include <gp_Pnt2d.hxx>
23 #include <gp_Sphere.hxx>
25 #include <IntRes2d_IntersectionPoint.hxx>
27 #include <Precision.hxx>
29 #include <Geom2d_Curve.hxx>
30 #include <Geom2d_Line.hxx>
31 #include <Geom2dAdaptor_Curve.hxx>
32 #include <Geom2dInt_GInter.hxx>
34 #include <BRep_Tool.hxx>
35 #include <BRep_Builder.hxx>
36 #include <BRepClass3d_SolidClassifier.hxx>
37 #include <BRepAdaptor_Surface.hxx>
39 #include <BRepExtrema_DistShapeShape.hxx>
41 #include <TColStd_ListIteratorOfListOfInteger.hxx>
42 #include <TColStd_ListOfInteger.hxx>
44 #include <BooleanOperations_ShapesDataStructure.hxx>
45 #include <BooleanOperations_AncestorsSeqAndSuccessorsSeq.hxx>
47 #include <IntTools_Range.hxx>
48 #include <IntTools_Tools.hxx>
49 #include <IntTools_Context.hxx>
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>
73 //=======================================================================
74 // function: BOPTools_DEProcessor::BOPTools_DEProcessor
76 //=======================================================================
77 BOPTools_DEProcessor::BOPTools_DEProcessor(const BOPTools_PaveFiller& aFiller,
78 const Standard_Integer aDim)
80 myIsDone(Standard_False)
82 myFiller=(BOPTools_PaveFiller*) &aFiller;
86 if (aDim<2 || aDim>3) {
92 //=======================================================================
95 //=======================================================================
96 Standard_Boolean BOPTools_DEProcessor::IsDone() const
100 //=======================================================================
103 //=======================================================================
104 void BOPTools_DEProcessor::Do()
106 Standard_Integer aNbE;
107 myIsDone=Standard_False;
109 FindDegeneratedEdges();
110 aNbE=myDEMap.Extent();
113 myIsDone=Standard_True;
120 //=======================================================================
121 // function: FindDegeneratedEdges
123 //=======================================================================
124 void BOPTools_DEProcessor::FindDegeneratedEdges()
126 const BooleanOperations_ShapesDataStructure& aDS=*myDS;
127 const BOPTools_PaveFiller& aPaveFiller=*myFiller;
129 Standard_Integer i, aNbSourceShapes, nV, nF, nVx, ip, iRankE;
130 TopAbs_ShapeEnum aType;
132 const TopoDS_Shape& anObj=aDS.Object();
133 const TopoDS_Shape& aTool=aDS.Tool();
135 TopTools_IndexedDataMapOfShapeListOfShape aMEF;
136 TopExp::MapShapesAndAncestors (anObj, TopAbs_EDGE, TopAbs_FACE, aMEF);
137 TopExp::MapShapesAndAncestors (aTool, TopAbs_EDGE, TopAbs_FACE, aMEF);
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)) {
149 TopoDS_Vertex aV=TopExp::FirstVertex(aE);
151 nVx=aDS.ShapeIndex(aV, iRankE);
154 ip=aPaveFiller.FindSDVertex(nV);
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();
165 nF=aDS.ShapeIndex(aF, iRankE);
169 BOPTools_DEInfo aDEInfo;
170 aDEInfo.SetVertex(nV);
171 aDEInfo.SetFaces(aLFn);
173 myDEMap.Add (i, aDEInfo);
180 //=======================================================================
183 //=======================================================================
184 void BOPTools_DEProcessor::DoPaves()
187 Standard_Integer i, aNbE, nED, nVD, nFD=0;
189 aNbE=myDEMap.Extent();
190 for (i=1; i<=aNbE; i++) {
191 nED=myDEMap.FindKey(i);
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()) {
201 BOPTools_ListOfPaveBlock aLPB;
202 FindPaveBlocks(nED, nVD, nFD, aLPB);
203 FillPaveSet (nED, nVD, nFD, aLPB);
206 // Fill aSplitEdges for the edge nED
207 FillSplitEdgesPool(nED);
210 MakeSplitEdges(nED, nFD);
212 // Compute States for Split parts
217 DoStates2D(nED, nFD);
222 //=======================================================================
223 // function: DoStates
225 //=======================================================================
226 void BOPTools_DEProcessor::DoStates (const Standard_Integer nED,
227 const Standard_Integer nFD)
231 const BOPTools_SplitShapesPool& aSplitShapesPool=myFiller->SplitShapesPool();
232 const BOPTools_ListOfPaveBlock& aSplitEdges=aSplitShapesPool(myDS->RefEdge(nED));
234 const TopoDS_Edge& aDE=TopoDS::Edge(myDS->Shape(nED));
235 const TopoDS_Face& aDF=TopoDS::Face(myDS->Shape(nFD));
237 Standard_Integer nSp, iRank;
238 Standard_Real aT, aT1, aT2, aTol=1e-7;
243 iRank=myDS->Rank(nED);
244 const TopoDS_Shape& aReference=(iRank==1) ? myDS->Tool() : myDS->Object();
246 BRepExtrema_DistShapeShape aDSS;
247 aDSS.LoadS1(aReference);
250 aF.Orientation(TopAbs_FORWARD);
252 BOPTools_ListIteratorOfListOfPaveBlock aPBIt(aSplitEdges);
254 for (; aPBIt.More(); aPBIt.Next()) {
255 BOPTools_PaveBlock& aPB=aPBIt.Value();
258 const TopoDS_Edge& aSp=TopoDS::Edge(myDS->Shape(nSp));
260 aPB.Parameters(aT1, aT2);
261 aT=IntTools_Tools::IntermediatePoint(aT1, aT2);
263 TopoDS_Edge aDERight, aSpRight;
267 BOPTools_Tools3D::OrientEdgeOnFace (aDE, aF, aDERight);
268 aSpRight.Orientation(aDERight.Orientation());
271 BRepAdaptor_Surface aBAS;
272 aBAS.Initialize (aDF, Standard_False);
274 if (aBAS.GetType()==GeomAbs_Sphere) {
275 Standard_Real aDt2D, aR, aDelta=1.e-14;
277 gp_Sphere aSphere=aBAS.Sphere();
280 aDt2D=acos (1.-4.*aTol/aR)+aDelta ;
282 BOPTools_Tools3D::PointNearEdge(aSpRight, aF, aT, aDt2D, aPx2DNear, aPxNear);
285 BOPTools_Tools3D::PointNearEdge(aSpRight, aF, aT, aPx2DNear, aPxNear);
291 TopAbs_ShapeEnum aTypeReference;
292 aTypeReference=aReference.ShapeType();
294 if (aTypeReference==TopAbs_SOLID) {
295 // ... \ Solid processing
296 const Handle(IntTools_Context)& aContext=myFiller->Context();
297 const TopoDS_Solid& aReferenceSolid=TopoDS::Solid(aReference);
298 BRepClass3d_SolidClassifier& SC=aContext->SolidClassifier(aReferenceSolid);
300 SC.Perform(aPxNear, aTol);
306 else if (aTypeReference==TopAbs_SHELL ||
307 aTypeReference==TopAbs_FACE) {
308 // ... \ Shell processing
309 TopoDS_Vertex aVxNear;
312 BB.MakeVertex(aVxNear, aPxNear, aTol);
314 aDSS.LoadS2(aVxNear);
319 Standard_Real aDist=aDSS.Value();
326 // unknown aTypeReference
330 BooleanOperations_StateOfShape aSt;
332 aSt=BOPTools_StateFiller::ConvertState(aState);
334 myDS->SetState(nSp, aSt);
337 //=======================================================================
338 // function: DoStates2D
340 //=======================================================================
341 void BOPTools_DEProcessor::DoStates2D (const Standard_Integer nED,
342 const Standard_Integer nFD)
346 const BOPTools_SplitShapesPool& aSplitShapesPool=myFiller->SplitShapesPool();
347 const BOPTools_ListOfPaveBlock& aSplitEdges=aSplitShapesPool(myDS->RefEdge(nED));
349 const TopoDS_Edge& aDE=TopoDS::Edge(myDS->Shape(nED));
350 const TopoDS_Face& aDF=TopoDS::Face(myDS->Shape(nFD));
352 Standard_Integer nSp, iRank;
353 Standard_Real aT, aT1, aT2;
358 iRank=myDS->Rank(nED);
359 const TopoDS_Shape& aReference=(iRank==1) ? myDS->Tool() : myDS->Object();
360 const TopoDS_Face& aFaceReference=TopoDS::Face(aReference);
363 aF.Orientation(TopAbs_FORWARD);
365 BOPTools_ListIteratorOfListOfPaveBlock aPBIt(aSplitEdges);
367 for (; aPBIt.More(); aPBIt.Next()) {
368 BOPTools_PaveBlock& aPB=aPBIt.Value();
371 const TopoDS_Edge& aSp=TopoDS::Edge(myDS->Shape(nSp));
373 aPB.Parameters(aT1, aT2);
374 aT=IntTools_Tools::IntermediatePoint(aT1, aT2);
376 TopoDS_Edge aDERight, aSpRight;
380 BOPTools_Tools3D::OrientEdgeOnFace (aDE, aF, aDERight);
381 aSpRight.Orientation(aDERight.Orientation());
383 BOPTools_Tools3D::PointNearEdge(aSpRight, aDF, aT, aPx2DNear, aPxNear);
385 Standard_Boolean bIsValidPoint;
386 TopAbs_State aState=TopAbs_OUT;
388 const Handle(IntTools_Context)& aContext=myFiller->Context();
389 bIsValidPoint=aContext->IsValidPointForFace(aPxNear, aFaceReference, 1.e-3);
395 BooleanOperations_StateOfShape aSt;
397 aSt=BOPTools_StateFiller::ConvertState(aState);
399 myDS->SetState(nSp, aSt);
403 //=======================================================================
404 // function: FillSplitEdgesPool
406 //=======================================================================
407 void BOPTools_DEProcessor::FillSplitEdgesPool (const Standard_Integer nED)
409 BOPTools_SplitShapesPool& aSplitShapesPool=myFiller->ChangeSplitShapesPool();
411 BOPTools_ListOfPaveBlock& aSplitEdges=aSplitShapesPool.ChangeValue(myDS->RefEdge(nED));
415 const BOPTools_PavePool& aPavePool=myFiller->PavePool();
416 BOPTools_PavePool* pPavePool=(BOPTools_PavePool*) &aPavePool;
417 BOPTools_PaveSet& aPaveSet= pPavePool->ChangeValue(myDS->RefEdge(nED));
419 BOPTools_PaveBlockIterator aPBIt(nED, aPaveSet);
420 for (; aPBIt.More(); aPBIt.Next()) {
421 BOPTools_PaveBlock& aPB=aPBIt.Value();
422 aSplitEdges.Append(aPB);
426 //=======================================================================
427 // function: MakeSplitEdges
429 //=======================================================================
430 void BOPTools_DEProcessor::MakeSplitEdges (const Standard_Integer nED,
431 const Standard_Integer nFD)
433 const BOPTools_SplitShapesPool& aSplitShapesPool=myFiller->SplitShapesPool();
434 const BOPTools_ListOfPaveBlock& aSplitEdges=aSplitShapesPool(myDS->RefEdge(nED));
436 Standard_Integer nV1, nV2, aNewShapeIndex;
437 Standard_Real t1, t2;
438 TopoDS_Edge aE, aESplit;
439 TopoDS_Vertex aV1, aV2;
441 const TopoDS_Edge aDE=TopoDS::Edge(myDS->Shape(nED));
442 const TopoDS_Face aDF=TopoDS::Face(myDS->Shape(nFD));
444 BOPTools_ListIteratorOfListOfPaveBlock aPBIt(aSplitEdges);
446 for (; aPBIt.More(); aPBIt.Next()) {
447 BOPTools_PaveBlock& aPB=aPBIt.Value();
449 const BOPTools_Pave& aPave1=aPB.Pave1();
452 aV1=TopoDS::Vertex(myDS->GetShape(nV1));
453 aV1.Orientation(TopAbs_FORWARD);
455 const BOPTools_Pave& aPave2=aPB.Pave2();
458 aV2=TopoDS::Vertex(myDS->GetShape(nV2));
459 aV2.Orientation(TopAbs_REVERSED);
461 MakeSplitEdge(aDE, aDF, aV1, t1, aV2, t2, aESplit);
463 // Add Split Part of the Original Edge to the DS
464 BooleanOperations_AncestorsSeqAndSuccessorsSeq anASSeq;
466 anASSeq.SetNewSuccessor(nV1);
467 anASSeq.SetNewOrientation(aV1.Orientation());
469 anASSeq.SetNewSuccessor(nV2);
470 anASSeq.SetNewOrientation(aV2.Orientation());
472 myDS->InsertShapeAndAncestorsSuccessors(aESplit, anASSeq);
473 aNewShapeIndex=myDS->NumberOfInsertedShapes();
474 myDS->SetState(aNewShapeIndex, BooleanOperations_UNKNOWN);
476 // Fill Split Set for the Original Edge
477 aPB.SetEdge(aNewShapeIndex);
481 //=======================================================================
482 // function: MakeSplitEdge
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)
493 Standard_Real aTol=1.e-7;
502 BB.Range(E, aF, aP1, aP2);
504 BB.Degenerated(E, Standard_True);
506 BB.UpdateEdge(E, aTol);
512 //=======================================================================
513 // function: FillPaveSet
515 //=======================================================================
516 void BOPTools_DEProcessor::FillPaveSet (const Standard_Integer nED,
517 const Standard_Integer nVD,
518 const Standard_Integer nFD,
519 BOPTools_ListOfPaveBlock& aLPB)
521 Standard_Boolean bIsDone, bXDir;
522 Standard_Integer nE, aNbPoints, j;
523 Standard_Real aTD1, aTD2, aT1, aT2, aTolInter, aX, aDT;
525 aDT=Precision::PConfusion();
527 BOPTools_PaveSet& aPaveSet= (myFiller->ChangePavePool()).ChangeValue(myDS->RefEdge(nED));
529 // Clear aPaveSet, aSplitEdges
530 aPaveSet.ChangeSet().Clear();
532 const TopoDS_Edge& aDE=TopoDS::Edge(myDS->Shape(nED));
533 const TopoDS_Face& aDF=TopoDS::Face(myDS->Shape(nFD));
535 // 2D Curve of degenerated edge on the face aDF
536 Handle(Geom2d_Curve) aC2DDE=BRep_Tool::CurveOnSurface(aDE, aDF, aTD1, aTD2);
538 // Choose direction for Degenerated Edge
539 gp_Pnt2d aP2d1, aP2d2;
540 aC2DDE->D0(aTD1, aP2d1);
541 aC2DDE->D0(aTD2, aP2d2);
543 bXDir=Standard_False;
544 if (fabs(aP2d1.Y()-aP2d2.Y()) < aDT){
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);
555 BOPTools_ListIteratorOfListOfPaveBlock anIt(aLPB);
556 for (; anIt.More(); anIt.Next()) {
557 const BOPTools_PaveBlock& aPB=anIt.Value();
559 const TopoDS_Edge& aE=TopoDS::Edge(myDS->Shape(nE));
561 Handle(Geom2d_Curve) aC2D=BRep_Tool::CurveOnSurface(aE, aDF, aT1, aT2);
567 Geom2dAdaptor_Curve aGAC1, aGAC2;
569 aGAC1.Load(aC2DDE, aTD1, aTD2);
570 Handle(Geom2d_Line) aL2D= Handle(Geom2d_Line)::DownCast(aC2D);
571 if (!aL2D.IsNull()) {
575 aGAC2.Load(aC2D, aT1, aT2);
578 Geom2dInt_GInter aGInter(aGAC1, aGAC2, aTolInter, aTolInter);
580 bIsDone=aGInter.IsDone();
582 aNbPoints=aGInter.NbPoints();
584 for (j=1; j<=aNbPoints; ++j) {
585 gp_Pnt2d aP2D=aGInter.Point(j).Value();
587 aX=(bXDir) ? aP2D.X(): aP2D.Y();
589 if (fabs (aX-aTD1) < aDT || fabs (aX-aTD2) < aDT) {
592 if (aX < aTD1 || aX > aTD2) {
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;
611 BOPTools_Pave aPave(nVD, aX, BooleanOperations_UnknownInterference);
612 aPaveSet.Append(aPave);
619 //=======================================================================
620 // function: FindPaveBlocks
622 //=======================================================================
623 void BOPTools_DEProcessor::FindPaveBlocks(const Standard_Integer ,
624 const Standard_Integer nVD,
625 const Standard_Integer nFD,
626 BOPTools_ListOfPaveBlock& aLPBOut)
629 BOPTools_CArray1OfSSInterference& aFFs=(myFiller->InterfPool())->SSInterferences();
631 BOPTools_ListIteratorOfListOfPaveBlock anIt;
632 Standard_Integer i, aNb, nF2, nSp, nV;
634 //ZZ const TopoDS_Edge& aDE=TopoDS::Edge(myDS->Shape(nED));
637 for (i=1; i<=aNb; i++) {
638 BOPTools_SSInterference& aFF=aFFs(i);
640 nF2=aFF.OppositeIndex(nFD);
646 const BOPTools_ListOfPaveBlock& aLPBSplits=aFF.PaveBlocks();
647 anIt.Initialize(aLPBSplits);
648 for (; anIt.More(); anIt.Next()) {
649 const BOPTools_PaveBlock& aPBSp=anIt.Value();
652 const BOPTools_Pave& aPave1=aPBSp.Pave1();
655 aLPBOut.Append(aPBSp);
659 const BOPTools_Pave& aPave2=aPBSp.Pave2();
662 aLPBOut.Append(aPBSp);
668 Standard_Integer j, aNbCurves;
669 BOPTools_SequenceOfCurves& aSC=aFF.Curves();
670 aNbCurves=aSC.Length();
672 for (j=1; j<=aNbCurves; j++) {
673 const BOPTools_Curve& aBC=aSC(j);
674 const BOPTools_ListOfPaveBlock& aLPBSe=aBC.NewPaveBlocks();
676 anIt.Initialize(aLPBSe);
677 for (; anIt.More(); anIt.Next()) {
678 const BOPTools_PaveBlock& aPBSe=anIt.Value();
680 const BOPTools_Pave& aPv1=aPBSe.Pave1();
683 aLPBOut.Append(aPBSe);
687 const BOPTools_Pave& aPv2=aPBSe.Pave2();
690 aLPBOut.Append(aPBSe);
696 } // for (i=1; i<=aNb; i++) Next FF interference