1 // File: BOPTools_DEProcessor.cxx
2 // Created: Wed Sep 12 12:10:52 2001
3 // Author: Peter KURNEV
6 #include <NMTTools_DEProcessor.ixx>
8 #include <Precision.hxx>
10 #include <TColStd_ListIteratorOfListOfInteger.hxx>
11 #include <TColStd_ListOfInteger.hxx>
13 #include <gp_Pnt2d.hxx>
15 #include <gp_Sphere.hxx>
17 #include <Geom2d_Curve.hxx>
18 #include <Geom2d_Line.hxx>
19 #include <Geom2dAdaptor_Curve.hxx>
20 #include <Geom2dInt_GInter.hxx>
22 #include <IntRes2d_IntersectionPoint.hxx>
24 #include <TopoDS_Shape.hxx>
25 #include <TopoDS_Edge.hxx>
27 #include <TopoDS_Face.hxx>
28 #include <TopoDS_Vertex.hxx>
29 #include <TopoDS_Solid.hxx>
32 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
33 #include <TopTools_ListOfShape.hxx>
34 #include <TopTools_ListIteratorOfListOfShape.hxx>
36 #include <BRep_Tool.hxx>
37 #include <BRep_Builder.hxx>
39 #include <BRepAdaptor_Surface.hxx>
41 #include <BooleanOperations_AncestorsSeqAndSuccessorsSeq.hxx>
43 #include <IntTools_Tools.hxx>
44 #include <IntTools_Context.hxx>
46 #include <BOPTools_DEInfo.hxx>
47 #include <BOPTools_Pave.hxx>
48 #include <BOPTools_ListOfPave.hxx>
49 #include <BOPTools_ListIteratorOfListOfPave.hxx>
50 #include <BOPTools_PaveBlock.hxx>
51 #include <BOPTools_ListOfPaveBlock.hxx>
52 #include <BOPTools_ListIteratorOfListOfPaveBlock.hxx>
53 #include <BOPTools_PaveBlockIterator.hxx>
54 #include <BOPTools_SSInterference.hxx>
55 #include <BOPTools_PavePool.hxx>
56 #include <BOPTools_PaveSet.hxx>
57 #include <BOPTools_Tools3D.hxx>
58 #include <BOPTools_InterferencePool.hxx>
59 #include <BOPTools_CArray1OfSSInterference.hxx>
60 #include <BOPTools_SplitShapesPool.hxx>
62 #include <NMTDS_ShapesDataStructure.hxx>
64 //#include <NMTTools_DSFiller.hxx>
65 #include <NMTTools_PaveFiller.hxx>
67 #include <BOPTools_SequenceOfCurves.hxx>
68 #include <BOPTools_Curve.hxx>
72 //=======================================================================
73 // function: NMTTools_DEProcessor::NMTTools_DEProcessor
75 //=======================================================================
76 NMTTools_DEProcessor::NMTTools_DEProcessor(NMTTools_PaveFiller& aPaveFiller)
78 myIsDone(Standard_False)
80 myFiller=(NMTTools_PaveFiller*) &aPaveFiller;
83 //=======================================================================
86 //=======================================================================
87 Standard_Boolean NMTTools_DEProcessor::IsDone() const
91 //=======================================================================
94 //=======================================================================
95 void NMTTools_DEProcessor::Do()
97 Standard_Integer aNbE;
98 myIsDone=Standard_False;
100 FindDegeneratedEdges();
101 aNbE=myDEMap.Extent();
104 myIsDone=Standard_True;
109 //=======================================================================
110 // function: FindDegeneratedEdges
112 //=======================================================================
113 void NMTTools_DEProcessor::FindDegeneratedEdges()
115 Standard_Integer i, aNb, nV, nF, nVx, ip, iRankE;
116 TopTools_IndexedDataMapOfShapeListOfShape aMEF;
118 aNb=myDS->NumberOfShapesOfTheObject();
120 for (i=1; i<=aNb; i++) {
121 const TopoDS_Shape& aF=myDS->Shape(i);
122 if (aF.ShapeType()==TopAbs_FACE) {
123 TopExp::MapShapesAndAncestors (aF, TopAbs_EDGE, TopAbs_FACE, aMEF);
127 for (i=1; i<=aNb; i++) {
128 const TopoDS_Shape& aS=myDS->Shape(i);
129 if (aS.ShapeType()==TopAbs_EDGE) {
130 const TopoDS_Edge& aE=TopoDS::Edge(aS);
132 if (BRep_Tool::Degenerated(aE)) {
133 iRankE=myDS->Rank(i);
135 TopoDS_Vertex aV=TopExp::FirstVertex(aE);
137 nVx=myDS->ShapeIndex(aV, iRankE);
140 ip=myFiller->FindSDVertex(nV);
145 TColStd_ListOfInteger aLFn;
146 const TopTools_ListOfShape& aLF=aMEF.FindFromKey(aE);
147 TopTools_ListIteratorOfListOfShape anIt(aLF);
148 for (; anIt.More(); anIt.Next()) {
149 const TopoDS_Shape& aF=anIt.Value();
150 nF=myDS->ShapeIndex(aF, iRankE);
153 BOPTools_DEInfo aDEInfo;
154 aDEInfo.SetVertex(nV);
155 aDEInfo.SetFaces(aLFn);
157 myDEMap.Add (i, aDEInfo);
162 //=======================================================================
165 //=======================================================================
166 void NMTTools_DEProcessor::DoPaves()
169 Standard_Integer i, aNbE, nED, nVD, nFD=0;
171 aNbE=myDEMap.Extent();
172 for (i=1; i<=aNbE; i++) {
173 nED=myDEMap.FindKey(i);
175 const BOPTools_DEInfo& aDEInfo=myDEMap(i);
176 nVD=aDEInfo.Vertex();
177 // Fill PaveSet for the edge nED
178 const TColStd_ListOfInteger& nLF=aDEInfo.Faces();
179 TColStd_ListIteratorOfListOfInteger anIt(nLF);
180 for (; anIt.More(); anIt.Next()) {
183 BOPTools_ListOfPaveBlock aLPB;
184 FindPaveBlocks(nED, nVD, nFD, aLPB);
185 FillPaveSet (nED, nVD, nFD, aLPB);
188 // Fill aSplitEdges for the edge nED
189 FillSplitEdgesPool(nED);
192 MakeSplitEdges(nED, nFD);
196 //=======================================================================
197 // function: FindPaveBlocks
199 //=======================================================================
200 void NMTTools_DEProcessor::FindPaveBlocks(const Standard_Integer ,
201 const Standard_Integer nVD,
202 const Standard_Integer nFD,
203 BOPTools_ListOfPaveBlock& aLPBOut)
205 BOPTools_ListIteratorOfListOfPaveBlock anIt;
206 Standard_Integer i, aNb, nF2, nV;
208 BOPTools_CArray1OfSSInterference& aFFs=(myFiller->InterfPool())->SSInterferences();
211 for (i=1; i<=aNb; ++i) {
212 BOPTools_SSInterference& aFF=aFFs(i);
214 nF2=aFF.OppositeIndex(nFD);
220 const BOPTools_ListOfPaveBlock& aLPBSplits=aFF.PaveBlocks();
221 anIt.Initialize(aLPBSplits);
222 for (; anIt.More(); anIt.Next()) {
223 const BOPTools_PaveBlock& aPBSp=anIt.Value();
225 const BOPTools_Pave& aPave1=aPBSp.Pave1();
228 aLPBOut.Append(aPBSp);
232 const BOPTools_Pave& aPave2=aPBSp.Pave2();
235 aLPBOut.Append(aPBSp);
241 Standard_Integer j, aNbCurves;
242 BOPTools_SequenceOfCurves& aSC=aFF.Curves();
243 aNbCurves=aSC.Length();
245 for (j=1; j<=aNbCurves; j++) {
246 const BOPTools_Curve& aBC=aSC(j);
247 const BOPTools_ListOfPaveBlock& aLPBSe=aBC.NewPaveBlocks();
249 anIt.Initialize(aLPBSe);
250 for (; anIt.More(); anIt.Next()) {
251 const BOPTools_PaveBlock& aPBSe=anIt.Value();
253 const BOPTools_Pave& aPv1=aPBSe.Pave1();
256 aLPBOut.Append(aPBSe);
260 const BOPTools_Pave& aPv2=aPBSe.Pave2();
263 aLPBOut.Append(aPBSe);
270 //=======================================================================
271 // function: FillPaveSet
273 //=======================================================================
274 void NMTTools_DEProcessor::FillPaveSet (const Standard_Integer nED,
275 const Standard_Integer nVD,
276 const Standard_Integer nFD,
277 const BOPTools_ListOfPaveBlock& aLPB)
279 Standard_Boolean bIsDone, bXDir, bRejectFlag;
280 Standard_Integer nE, aNbPoints, j;
281 Standard_Real aTD1, aTD2, aT1, aT2, aTolInter, aX, aDT;
283 aDT=Precision::PConfusion();
285 BOPTools_PaveSet& aPaveSet= (myFiller->ChangePavePool()).ChangeValue(myDS->RefEdge(nED));
287 // Clear aPaveSet, aSplitEdges
288 aPaveSet.ChangeSet().Clear();
290 const TopoDS_Edge& aDE=TopoDS::Edge(myDS->Shape(nED));
291 const TopoDS_Face& aDF=TopoDS::Face(myDS->Shape(nFD));
293 // 2D Curve of degenerated edge on the face aDF
294 Handle(Geom2d_Curve) aC2DDE=BRep_Tool::CurveOnSurface(aDE, aDF, aTD1, aTD2);
296 // Choose direction for Degenerated Edge
297 gp_Pnt2d aP2d1, aP2d2;
298 aC2DDE->D0(aTD1, aP2d1);
299 aC2DDE->D0(aTD2, aP2d2);
301 bXDir=Standard_False;
302 if (fabs(aP2d1.Y()-aP2d2.Y()) < aDT){
306 // Prepare bounding Paves
307 BOPTools_Pave aPave1 (nVD, aTD1, BooleanOperations_UnknownInterference);
308 aPaveSet.Append(aPave1);
309 BOPTools_Pave aPave2 (nVD, aTD2, BooleanOperations_UnknownInterference);
310 aPaveSet.Append(aPave2);
313 BOPTools_ListIteratorOfListOfPaveBlock anIt(aLPB);
314 for (; anIt.More(); anIt.Next()) {
315 const BOPTools_PaveBlock& aPB=anIt.Value();
317 const TopoDS_Edge& aE=TopoDS::Edge(myDS->Shape(nE));
319 Handle(Geom2d_Curve) aC2D=BRep_Tool::CurveOnSurface(aE, aDF, aT1, aT2);
324 Geom2dAdaptor_Curve aGAC1, aGAC2;
326 aGAC1.Load(aC2DDE, aTD1, aTD2);
327 Handle(Geom2d_Line) aL2D= Handle(Geom2d_Line)::DownCast(aC2D);
328 if (!aL2D.IsNull()) {
332 aGAC2.Load(aC2D, aT1, aT2);
335 Geom2dInt_GInter aGInter(aGAC1, aGAC2, aTolInter, aTolInter);
337 bIsDone=aGInter.IsDone();
339 aNbPoints=aGInter.NbPoints();
341 for (j=1; j<=aNbPoints; ++j) {
342 gp_Pnt2d aP2D=aGInter.Point(j).Value();
344 aX=(bXDir) ? aP2D.X(): aP2D.Y();
346 if (fabs (aX-aTD1) < aDT || fabs (aX-aTD2) < aDT) {
349 if (aX < aTD1 || aX > aTD2) {
353 bRejectFlag=Standard_False;
354 const BOPTools_ListOfPave& aListOfPave=aPaveSet.Set();
355 BOPTools_ListIteratorOfListOfPave aPaveIt(aListOfPave);
356 for (; aPaveIt.More(); aPaveIt.Next()) {
357 const BOPTools_Pave& aPavex=aPaveIt.Value();
358 Standard_Real aXx=aPavex.Param();
359 if (fabs (aX-aXx) < aDT) {
360 bRejectFlag=Standard_True;
368 BOPTools_Pave aPave(nVD, aX, BooleanOperations_UnknownInterference);
369 aPaveSet.Append(aPave);
375 //=======================================================================
376 // function: FillSplitEdgesPool
378 //=======================================================================
379 void NMTTools_DEProcessor::FillSplitEdgesPool (const Standard_Integer nED)
381 BOPTools_SplitShapesPool& aSplitShapesPool=myFiller->ChangeSplitShapesPool();
382 BOPTools_ListOfPaveBlock& aSplitEdges=aSplitShapesPool.ChangeValue(myDS->RefEdge(nED));
386 const BOPTools_PavePool& aPavePool=myFiller->PavePool();
387 BOPTools_PavePool* pPavePool=(BOPTools_PavePool*) &aPavePool;
388 BOPTools_PaveSet& aPaveSet= pPavePool->ChangeValue(myDS->RefEdge(nED));
390 BOPTools_PaveBlockIterator aPBIt(nED, aPaveSet);
391 for (; aPBIt.More(); aPBIt.Next()) {
392 BOPTools_PaveBlock& aPB=aPBIt.Value();
393 aSplitEdges.Append(aPB);
396 //=======================================================================
397 // function: MakeSplitEdges
399 //=======================================================================
400 void NMTTools_DEProcessor::MakeSplitEdges (const Standard_Integer nED,
401 const Standard_Integer nFD)
403 const BOPTools_SplitShapesPool& aSplitShapesPool=myFiller->SplitShapesPool();
404 const BOPTools_ListOfPaveBlock& aSplitEdges=aSplitShapesPool(myDS->RefEdge(nED));
406 Standard_Integer nV1, nV2, aNewShapeIndex;
407 Standard_Real t1, t2;
408 TopoDS_Edge aE, aESplit;
409 TopoDS_Vertex aV1, aV2;
411 const TopoDS_Edge& aDE=TopoDS::Edge(myDS->Shape(nED));
412 const TopoDS_Face& aDF=TopoDS::Face(myDS->Shape(nFD));
414 BOPTools_ListIteratorOfListOfPaveBlock aPBIt(aSplitEdges);
416 for (; aPBIt.More(); aPBIt.Next()) {
417 BOPTools_PaveBlock& aPB=aPBIt.Value();
419 const BOPTools_Pave& aPave1=aPB.Pave1();
422 aV1=TopoDS::Vertex(myDS->GetShape(nV1));
423 aV1.Orientation(TopAbs_FORWARD);
425 const BOPTools_Pave& aPave2=aPB.Pave2();
428 aV2=TopoDS::Vertex(myDS->GetShape(nV2));
429 aV2.Orientation(TopAbs_REVERSED);
431 MakeSplitEdge(aDE, aDF, aV1, t1, aV2, t2, aESplit);
433 // Add Split Part of the Original Edge to the DS
434 BooleanOperations_AncestorsSeqAndSuccessorsSeq anASSeq;
436 anASSeq.SetNewSuccessor(nV1);
437 anASSeq.SetNewOrientation(aV1.Orientation());
439 anASSeq.SetNewSuccessor(nV2);
440 anASSeq.SetNewOrientation(aV2.Orientation());
442 myDS->InsertShapeAndAncestorsSuccessors(aESplit, anASSeq);
443 aNewShapeIndex=myDS->NumberOfInsertedShapes();
444 myDS->SetState(aNewShapeIndex, BooleanOperations_UNKNOWN);
446 // Fill Split Set for the Original Edge
447 aPB.SetEdge(aNewShapeIndex);
451 //=======================================================================
452 // function: MakeSplitEdge
454 //=======================================================================
455 void NMTTools_DEProcessor::MakeSplitEdge (const TopoDS_Edge& aE,
456 const TopoDS_Face& aF,
457 const TopoDS_Vertex& aV1,
458 const Standard_Real aP1,
459 const TopoDS_Vertex& aV2,
460 const Standard_Real aP2,
461 TopoDS_Edge& aNewEdge)
463 Standard_Real aTol=1.e-7;
472 BB.Range(E, aF, aP1, aP2);
474 BB.Degenerated(E, Standard_True);
476 BB.UpdateEdge(E, aTol);
480 //=======================================================================
481 // function: NMTTools_DEProcessor::NMTTools_DEProcessor
483 //=======================================================================
484 NMTTools_DEProcessor::NMTTools_DEProcessor(NMTTools_PDSFiller& pDSFiller)
486 myIsDone(Standard_False)
488 myDSFiller=pDSFiller;
489 myFiller=(NMTTools_PaveFiller*) &(myDSFiller->PaveFiller());