Salome HOME
1c6ea3068088670a6fd102c51f72a66f45ebe086
[modules/geom.git] / src / NMTTools / NMTTools_DEProcessor.cxx
1 // File:        BOPTools_DEProcessor.cxx
2 // Created:     Wed Sep 12 12:10:52 2001
3 // Author:      Peter KURNEV
4 //              <pkv@irinox>
5
6 #include <NMTTools_DEProcessor.ixx>
7
8 #include <Precision.hxx>
9
10 #include <TColStd_ListIteratorOfListOfInteger.hxx>
11 #include <TColStd_ListOfInteger.hxx>
12
13 #include <gp_Pnt2d.hxx>
14 #include <gp_Pnt.hxx>
15 #include <gp_Sphere.hxx>
16
17 #include <Geom2d_Curve.hxx>
18 #include <Geom2d_Line.hxx>
19 #include <Geom2dAdaptor_Curve.hxx>
20 #include <Geom2dInt_GInter.hxx>
21
22 #include <IntRes2d_IntersectionPoint.hxx>
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 <BRep_Tool.hxx>
37 #include <BRep_Builder.hxx>
38
39 #include <BRepAdaptor_Surface.hxx>
40
41 #include <BooleanOperations_AncestorsSeqAndSuccessorsSeq.hxx>
42
43 #include <IntTools_Tools.hxx>
44 #include <IntTools_Context.hxx>
45
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>
61
62 #include <NMTDS_ShapesDataStructure.hxx>
63
64 //#include <NMTTools_DSFiller.hxx>
65 #include <NMTTools_PaveFiller.hxx>
66 //
67 #include <BOPTools_SequenceOfCurves.hxx>
68 #include <BOPTools_Curve.hxx>
69
70
71
72 //=======================================================================
73 // function: NMTTools_DEProcessor::NMTTools_DEProcessor
74 // purpose: 
75 //=======================================================================
76   NMTTools_DEProcessor::NMTTools_DEProcessor(NMTTools_PaveFiller& aPaveFiller)
77 :
78   myIsDone(Standard_False)
79 {
80   myFiller=(NMTTools_PaveFiller*) &aPaveFiller;
81   myDS=myFiller->DS();
82 }
83 //=======================================================================
84 // function: IsDone
85 // purpose: 
86 //=======================================================================
87   Standard_Boolean NMTTools_DEProcessor::IsDone() const
88 {
89   return myIsDone;
90 }
91 //=======================================================================
92 // function:  Do
93 // purpose: 
94 //=======================================================================
95   void NMTTools_DEProcessor::Do()
96 {
97   Standard_Integer aNbE;
98   myIsDone=Standard_False;
99
100   FindDegeneratedEdges();
101   aNbE=myDEMap.Extent();
102   
103   if (!aNbE) {
104     myIsDone=Standard_True;
105     return;
106   }
107   DoPaves();
108 }
109 //=======================================================================
110 // function:  FindDegeneratedEdges
111 // purpose: 
112 //=======================================================================
113   void NMTTools_DEProcessor::FindDegeneratedEdges()
114 {
115   Standard_Integer i, aNb, nV, nF, nVx, ip, iRankE;
116   TopTools_IndexedDataMapOfShapeListOfShape aMEF;
117   //
118   aNb=myDS->NumberOfShapesOfTheObject();
119   //
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);
124     }
125   }
126   //
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);
131       
132       if (BRep_Tool::Degenerated(aE)) {
133         iRankE=myDS->Rank(i);
134
135         TopoDS_Vertex aV=TopExp::FirstVertex(aE);
136
137         nVx=myDS->ShapeIndex(aV, iRankE);
138         //
139         nV=nVx;
140         ip=myFiller->FindSDVertex(nV);
141         if (ip) {
142           nV=ip;
143         }
144         //
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);
151           aLFn.Append(nF);
152         }
153         BOPTools_DEInfo aDEInfo;
154         aDEInfo.SetVertex(nV);
155         aDEInfo.SetFaces(aLFn);
156
157         myDEMap.Add (i, aDEInfo);
158       }
159     }
160   }
161 }
162 //=======================================================================
163 // function:  DoPaves
164 // purpose: 
165 //=======================================================================
166   void NMTTools_DEProcessor::DoPaves()
167 {
168
169   Standard_Integer i, aNbE, nED, nVD, nFD=0;
170   //
171   aNbE=myDEMap.Extent();
172   for (i=1; i<=aNbE; i++) {
173     nED=myDEMap.FindKey(i);
174     
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()) {
181       nFD=anIt.Value();
182       
183       BOPTools_ListOfPaveBlock aLPB;
184       FindPaveBlocks(nED, nVD, nFD, aLPB);
185       FillPaveSet (nED, nVD, nFD, aLPB);
186     }
187     // 
188     // Fill aSplitEdges for the edge nED
189     FillSplitEdgesPool(nED);
190     //
191     // MakeSplitEdges
192     MakeSplitEdges(nED, nFD);
193     //
194   }// next nED
195 }
196 //=======================================================================
197 // function:  FindPaveBlocks
198 // purpose: 
199 //=======================================================================
200   void NMTTools_DEProcessor::FindPaveBlocks(const Standard_Integer ,
201                                             const Standard_Integer nVD,
202                                             const Standard_Integer nFD,
203                                             BOPTools_ListOfPaveBlock& aLPBOut)
204 {
205   BOPTools_ListIteratorOfListOfPaveBlock anIt;
206   Standard_Integer i, aNb, nF2, nV;
207   //
208   BOPTools_CArray1OfSSInterference& aFFs=(myFiller->InterfPool())->SSInterferences();
209   //
210   aNb=aFFs.Extent();
211   for (i=1; i<=aNb; ++i) {
212     BOPTools_SSInterference& aFF=aFFs(i);
213     //
214     nF2=aFF.OppositeIndex(nFD);
215     if (!nF2) {
216       continue;
217     }
218     //
219     // Split Parts 
220     const BOPTools_ListOfPaveBlock& aLPBSplits=aFF.PaveBlocks();
221     anIt.Initialize(aLPBSplits);
222     for (; anIt.More(); anIt.Next()) {
223       const BOPTools_PaveBlock& aPBSp=anIt.Value();
224       //
225       const BOPTools_Pave& aPave1=aPBSp.Pave1();
226       nV=aPave1.Index();
227       if (nV==nVD) {
228         aLPBOut.Append(aPBSp);
229         continue;
230       }
231       //
232       const BOPTools_Pave& aPave2=aPBSp.Pave2();
233       nV=aPave2.Index();
234       if (nV==nVD) {
235         aLPBOut.Append(aPBSp);
236         continue;
237       }
238     }
239     //
240     // Section Parts
241     Standard_Integer j, aNbCurves;   
242     BOPTools_SequenceOfCurves& aSC=aFF.Curves();
243     aNbCurves=aSC.Length();
244     
245     for (j=1; j<=aNbCurves; j++) {
246       const BOPTools_Curve& aBC=aSC(j);
247       const BOPTools_ListOfPaveBlock& aLPBSe=aBC.NewPaveBlocks();
248
249       anIt.Initialize(aLPBSe);
250       for (; anIt.More(); anIt.Next()) {
251         const BOPTools_PaveBlock& aPBSe=anIt.Value();
252         
253         const BOPTools_Pave& aPv1=aPBSe.Pave1();
254         nV=aPv1.Index();
255         if (nV==nVD) {
256           aLPBOut.Append(aPBSe);
257           continue;
258         }
259         
260         const BOPTools_Pave& aPv2=aPBSe.Pave2();
261         nV=aPv2.Index();
262         if (nV==nVD) {
263           aLPBOut.Append(aPBSe);
264           continue;
265         }
266       }
267     }
268   }
269 }
270 //=======================================================================
271 // function:  FillPaveSet
272 // purpose: 
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)
278 {
279   Standard_Boolean bIsDone, bXDir, bRejectFlag;
280   Standard_Integer nE, aNbPoints, j;
281   Standard_Real aTD1, aTD2, aT1, aT2, aTolInter, aX, aDT;
282   //
283   aDT=Precision::PConfusion();
284   //
285   BOPTools_PaveSet& aPaveSet= (myFiller->ChangePavePool()).ChangeValue(myDS->RefEdge(nED));
286   //
287   // Clear aPaveSet, aSplitEdges
288   aPaveSet.ChangeSet().Clear();
289   //
290   const TopoDS_Edge& aDE=TopoDS::Edge(myDS->Shape(nED));
291   const TopoDS_Face& aDF=TopoDS::Face(myDS->Shape(nFD));
292   //
293   // 2D Curve of degenerated edge on the face aDF
294   Handle(Geom2d_Curve) aC2DDE=BRep_Tool::CurveOnSurface(aDE, aDF, aTD1, aTD2);
295   //
296   // Choose direction for Degenerated Edge
297   gp_Pnt2d aP2d1, aP2d2;
298   aC2DDE->D0(aTD1, aP2d1);
299   aC2DDE->D0(aTD2, aP2d2);
300
301   bXDir=Standard_False;
302   if (fabs(aP2d1.Y()-aP2d2.Y()) < aDT){
303     bXDir=!bXDir;
304   }
305   //
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);
311   //
312   // Fill other paves 
313   BOPTools_ListIteratorOfListOfPaveBlock anIt(aLPB);
314   for (; anIt.More(); anIt.Next()) {
315     const BOPTools_PaveBlock& aPB=anIt.Value();
316     nE=aPB.Edge();
317     const TopoDS_Edge& aE=TopoDS::Edge(myDS->Shape(nE));
318     
319     Handle(Geom2d_Curve) aC2D=BRep_Tool::CurveOnSurface(aE, aDF, aT1, aT2);
320     //
321     // Intersection
322     aTolInter=0.001;
323         
324     Geom2dAdaptor_Curve aGAC1, aGAC2;
325     
326     aGAC1.Load(aC2DDE, aTD1, aTD2);
327     Handle(Geom2d_Line) aL2D= Handle(Geom2d_Line)::DownCast(aC2D);
328     if (!aL2D.IsNull()) {
329       aGAC2.Load(aC2D);
330     }
331     else {
332       aGAC2.Load(aC2D, aT1, aT2);
333     }
334     
335     Geom2dInt_GInter aGInter(aGAC1, aGAC2, aTolInter, aTolInter);
336     
337     bIsDone=aGInter.IsDone();
338     if(bIsDone) {
339       aNbPoints=aGInter.NbPoints();
340       if (aNbPoints) { 
341         for (j=1; j<=aNbPoints; ++j) {
342           gp_Pnt2d aP2D=aGInter.Point(j).Value();
343           //
344           aX=(bXDir) ? aP2D.X(): aP2D.Y();
345           //
346           if (fabs (aX-aTD1) < aDT || fabs (aX-aTD2) < aDT) {
347             continue; 
348           }
349           if (aX < aTD1 || aX > aTD2) {
350             continue; 
351           }
352           //
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;
361               break;
362             }
363           }
364           if (bRejectFlag) {
365             continue; 
366           }
367           //
368           BOPTools_Pave aPave(nVD, aX, BooleanOperations_UnknownInterference);
369           aPaveSet.Append(aPave);
370         }
371       }
372     }
373   }
374 }
375 //=======================================================================
376 // function:  FillSplitEdgesPool
377 // purpose: 
378 //=======================================================================
379   void NMTTools_DEProcessor::FillSplitEdgesPool (const Standard_Integer nED)
380 {
381   BOPTools_SplitShapesPool& aSplitShapesPool=myFiller->ChangeSplitShapesPool();
382   BOPTools_ListOfPaveBlock& aSplitEdges=aSplitShapesPool.ChangeValue(myDS->RefEdge(nED));
383   //
384   aSplitEdges.Clear();
385   //
386   const BOPTools_PavePool& aPavePool=myFiller->PavePool();
387   BOPTools_PavePool* pPavePool=(BOPTools_PavePool*) &aPavePool;
388   BOPTools_PaveSet& aPaveSet= pPavePool->ChangeValue(myDS->RefEdge(nED));
389   
390   BOPTools_PaveBlockIterator aPBIt(nED, aPaveSet);
391   for (; aPBIt.More(); aPBIt.Next()) {
392     BOPTools_PaveBlock& aPB=aPBIt.Value();
393     aSplitEdges.Append(aPB);
394   }
395 }
396 //=======================================================================
397 // function:  MakeSplitEdges
398 // purpose: 
399 //=======================================================================
400   void NMTTools_DEProcessor::MakeSplitEdges (const Standard_Integer nED,
401                                              const Standard_Integer nFD)
402 {
403   const BOPTools_SplitShapesPool& aSplitShapesPool=myFiller->SplitShapesPool();
404   const BOPTools_ListOfPaveBlock& aSplitEdges=aSplitShapesPool(myDS->RefEdge(nED));
405
406   Standard_Integer nV1, nV2, aNewShapeIndex;
407   Standard_Real    t1, t2;
408   TopoDS_Edge aE, aESplit;
409   TopoDS_Vertex aV1, aV2;
410
411   const TopoDS_Edge& aDE=TopoDS::Edge(myDS->Shape(nED));
412   const TopoDS_Face& aDF=TopoDS::Face(myDS->Shape(nFD));
413
414   BOPTools_ListIteratorOfListOfPaveBlock aPBIt(aSplitEdges);
415
416   for (; aPBIt.More(); aPBIt.Next()) {
417     BOPTools_PaveBlock& aPB=aPBIt.Value();
418     
419     const BOPTools_Pave& aPave1=aPB.Pave1();
420     nV1=aPave1.Index();
421     t1=aPave1.Param();
422     aV1=TopoDS::Vertex(myDS->GetShape(nV1));
423     aV1.Orientation(TopAbs_FORWARD);
424     
425     const BOPTools_Pave& aPave2=aPB.Pave2();
426     nV2=aPave2.Index();
427     t2=aPave2.Param();
428     aV2=TopoDS::Vertex(myDS->GetShape(nV2));
429     aV2.Orientation(TopAbs_REVERSED);
430     
431     MakeSplitEdge(aDE, aDF, aV1, t1, aV2, t2, aESplit); 
432     //
433     // Add Split Part of the Original Edge to the DS
434     BooleanOperations_AncestorsSeqAndSuccessorsSeq anASSeq;
435     
436     anASSeq.SetNewSuccessor(nV1);
437     anASSeq.SetNewOrientation(aV1.Orientation());
438     
439     anASSeq.SetNewSuccessor(nV2);
440     anASSeq.SetNewOrientation(aV2.Orientation());
441     
442     myDS->InsertShapeAndAncestorsSuccessors(aESplit, anASSeq);
443     aNewShapeIndex=myDS->NumberOfInsertedShapes();
444     myDS->SetState(aNewShapeIndex, BooleanOperations_UNKNOWN);
445     //
446     // Fill Split Set for the Original Edge
447     aPB.SetEdge(aNewShapeIndex);
448     //
449   }
450 }
451 //=======================================================================
452 // function:  MakeSplitEdge
453 // purpose: 
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)
462 {
463   Standard_Real aTol=1.e-7;
464
465   TopoDS_Edge E=aE;
466
467   E.EmptyCopy();
468   BRep_Builder BB;
469   BB.Add  (E, aV1);
470   BB.Add  (E, aV2);
471
472   BB.Range(E, aF, aP1, aP2);
473
474   BB.Degenerated(E, Standard_True);
475
476   BB.UpdateEdge(E, aTol);
477   aNewEdge=E;
478 }
479 /*
480 //=======================================================================
481 // function: NMTTools_DEProcessor::NMTTools_DEProcessor
482 // purpose: 
483 //=======================================================================
484   NMTTools_DEProcessor::NMTTools_DEProcessor(NMTTools_PDSFiller& pDSFiller)
485 :
486   myIsDone(Standard_False)
487 {
488   myDSFiller=pDSFiller;
489   myFiller=(NMTTools_PaveFiller*) &(myDSFiller->PaveFiller());
490   myDS=myFiller->DS();
491 }
492 */