Salome HOME
Join modifications from branch BR_DEBUG_3_2_0b1
[modules/geom.git] / src / NMTTools / NMTTools_DEProcessor.cxx
1 // Copyright (C) 2005  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
2 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
3 // 
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either 
7 // version 2.1 of the License.
8 // 
9 // This library is distributed in the hope that it will be useful 
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
12 // Lesser General Public License for more details.
13 //
14 // You should have received a copy of the GNU Lesser General Public  
15 // License along with this library; if not, write to the Free Software 
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
17 //
18 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 //
20 // File:        BOPTools_DEProcessor.cxx
21 // Created:     Wed Sep 12 12:10:52 2001
22 // Author:      Peter KURNEV
23 //              <pkv@irinox>
24
25 #include <NMTTools_DEProcessor.ixx>
26
27 #include <Precision.hxx>
28
29 #include <TColStd_ListIteratorOfListOfInteger.hxx>
30 #include <TColStd_ListOfInteger.hxx>
31
32 #include <gp_Pnt2d.hxx>
33 #include <gp_Pnt.hxx>
34 #include <gp_Sphere.hxx>
35
36 #include <Geom2d_Curve.hxx>
37 #include <Geom2d_Line.hxx>
38 #include <Geom2dAdaptor_Curve.hxx>
39 #include <Geom2dInt_GInter.hxx>
40
41 #include <IntRes2d_IntersectionPoint.hxx>
42
43 #include <TopoDS_Shape.hxx>
44 #include <TopoDS_Edge.hxx>
45 #include <TopoDS.hxx>
46 #include <TopoDS_Face.hxx>
47 #include <TopoDS_Vertex.hxx>
48 #include <TopoDS_Solid.hxx>
49
50 #include <TopExp.hxx>
51 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
52 #include <TopTools_ListOfShape.hxx>
53 #include <TopTools_ListIteratorOfListOfShape.hxx>
54
55 #include <BRep_Tool.hxx>
56 #include <BRep_Builder.hxx>
57
58 #include <BRepAdaptor_Surface.hxx>
59
60 #include <BooleanOperations_AncestorsSeqAndSuccessorsSeq.hxx>
61
62 #include <IntTools_Tools.hxx>
63 #include <IntTools_Context.hxx>
64
65 #include <BOPTools_DEInfo.hxx>
66 #include <BOPTools_Pave.hxx>
67 #include <BOPTools_ListOfPave.hxx>
68 #include <BOPTools_ListIteratorOfListOfPave.hxx>
69 #include <BOPTools_PaveBlock.hxx>
70 #include <BOPTools_ListOfPaveBlock.hxx>
71 #include <BOPTools_ListIteratorOfListOfPaveBlock.hxx>
72 #include <BOPTools_PaveBlockIterator.hxx>
73 #include <BOPTools_SSInterference.hxx>
74 #include <BOPTools_PavePool.hxx>
75 #include <BOPTools_PaveSet.hxx>
76 #include <BOPTools_Tools3D.hxx>
77 #include <BOPTools_InterferencePool.hxx>
78 #include <BOPTools_CArray1OfSSInterference.hxx>
79 #include <BOPTools_SplitShapesPool.hxx>
80
81 #include <NMTDS_ShapesDataStructure.hxx>
82
83 //#include <NMTTools_DSFiller.hxx>
84 #include <NMTTools_PaveFiller.hxx>
85 //
86 #include <BOPTools_SequenceOfCurves.hxx>
87 #include <BOPTools_Curve.hxx>
88
89
90
91 //=======================================================================
92 // function: NMTTools_DEProcessor::NMTTools_DEProcessor
93 // purpose: 
94 //=======================================================================
95   NMTTools_DEProcessor::NMTTools_DEProcessor(NMTTools_PaveFiller& aPaveFiller)
96 :
97   myIsDone(Standard_False)
98 {
99   myFiller=(NMTTools_PaveFiller*) &aPaveFiller;
100   myDS=myFiller->DS();
101 }
102 //=======================================================================
103 // function: IsDone
104 // purpose: 
105 //=======================================================================
106   Standard_Boolean NMTTools_DEProcessor::IsDone() const
107 {
108   return myIsDone;
109 }
110 //=======================================================================
111 // function:  Do
112 // purpose: 
113 //=======================================================================
114   void NMTTools_DEProcessor::Do()
115 {
116   Standard_Integer aNbE;
117   myIsDone=Standard_False;
118
119   FindDegeneratedEdges();
120   aNbE=myDEMap.Extent();
121   
122   if (!aNbE) {
123     myIsDone=Standard_True;
124     return;
125   }
126   DoPaves();
127 }
128 //=======================================================================
129 // function:  FindDegeneratedEdges
130 // purpose: 
131 //=======================================================================
132   void NMTTools_DEProcessor::FindDegeneratedEdges()
133 {
134   Standard_Integer i, aNb, nV, nF, nVx, ip, iRankE;
135   TopTools_IndexedDataMapOfShapeListOfShape aMEF;
136   //
137   aNb=myDS->NumberOfShapesOfTheObject();
138   //
139   for (i=1; i<=aNb; i++) {
140     const TopoDS_Shape& aF=myDS->Shape(i);
141     if (aF.ShapeType()==TopAbs_FACE) {
142       TopExp::MapShapesAndAncestors (aF, TopAbs_EDGE, TopAbs_FACE, aMEF);
143     }
144   }
145   //
146   for (i=1; i<=aNb; i++) {
147     const TopoDS_Shape& aS=myDS->Shape(i);
148     if (aS.ShapeType()==TopAbs_EDGE) {
149       const TopoDS_Edge& aE=TopoDS::Edge(aS);
150       
151       if (BRep_Tool::Degenerated(aE)) {
152         iRankE=myDS->Rank(i);
153
154         TopoDS_Vertex aV=TopExp::FirstVertex(aE);
155
156         nVx=myDS->ShapeIndex(aV, iRankE);
157         //
158         nV=nVx;
159         ip=myFiller->FindSDVertex(nV);
160         if (ip) {
161           nV=ip;
162         }
163         //
164         TColStd_ListOfInteger aLFn;
165         const TopTools_ListOfShape& aLF=aMEF.FindFromKey(aE);
166         TopTools_ListIteratorOfListOfShape anIt(aLF);
167         for (; anIt.More(); anIt.Next()) {
168           const TopoDS_Shape& aF=anIt.Value();
169           nF=myDS->ShapeIndex(aF, iRankE);
170           aLFn.Append(nF);
171         }
172         BOPTools_DEInfo aDEInfo;
173         aDEInfo.SetVertex(nV);
174         aDEInfo.SetFaces(aLFn);
175
176         myDEMap.Add (i, aDEInfo);
177       }
178     }
179   }
180 }
181 //=======================================================================
182 // function:  DoPaves
183 // purpose: 
184 //=======================================================================
185   void NMTTools_DEProcessor::DoPaves()
186 {
187
188   Standard_Integer i, aNbE, nED, nVD, nFD=0;
189   //
190   aNbE=myDEMap.Extent();
191   for (i=1; i<=aNbE; i++) {
192     nED=myDEMap.FindKey(i);
193     
194     const BOPTools_DEInfo& aDEInfo=myDEMap(i);
195     nVD=aDEInfo.Vertex();
196     // Fill PaveSet for the edge nED
197     const TColStd_ListOfInteger& nLF=aDEInfo.Faces();
198     TColStd_ListIteratorOfListOfInteger anIt(nLF);
199     for (; anIt.More(); anIt.Next()) {
200       nFD=anIt.Value();
201       
202       BOPTools_ListOfPaveBlock aLPB;
203       FindPaveBlocks(nED, nVD, nFD, aLPB);
204       FillPaveSet (nED, nVD, nFD, aLPB);
205     }
206     // 
207     // Fill aSplitEdges for the edge nED
208     FillSplitEdgesPool(nED);
209     //
210     // MakeSplitEdges
211     MakeSplitEdges(nED, nFD);
212     //
213   }// next nED
214 }
215 //=======================================================================
216 // function:  FindPaveBlocks
217 // purpose: 
218 //=======================================================================
219   void NMTTools_DEProcessor::FindPaveBlocks(const Standard_Integer ,
220                                             const Standard_Integer nVD,
221                                             const Standard_Integer nFD,
222                                             BOPTools_ListOfPaveBlock& aLPBOut)
223 {
224   BOPTools_ListIteratorOfListOfPaveBlock anIt;
225   Standard_Integer i, aNb, nF2, nV;
226   //
227   BOPTools_CArray1OfSSInterference& aFFs=(myFiller->InterfPool())->SSInterferences();
228   //
229   aNb=aFFs.Extent();
230   for (i=1; i<=aNb; ++i) {
231     BOPTools_SSInterference& aFF=aFFs(i);
232     //
233     nF2=aFF.OppositeIndex(nFD);
234     if (!nF2) {
235       continue;
236     }
237     //
238     // Split Parts 
239     const BOPTools_ListOfPaveBlock& aLPBSplits=aFF.PaveBlocks();
240     anIt.Initialize(aLPBSplits);
241     for (; anIt.More(); anIt.Next()) {
242       const BOPTools_PaveBlock& aPBSp=anIt.Value();
243       //
244       const BOPTools_Pave& aPave1=aPBSp.Pave1();
245       nV=aPave1.Index();
246       if (nV==nVD) {
247         aLPBOut.Append(aPBSp);
248         continue;
249       }
250       //
251       const BOPTools_Pave& aPave2=aPBSp.Pave2();
252       nV=aPave2.Index();
253       if (nV==nVD) {
254         aLPBOut.Append(aPBSp);
255         continue;
256       }
257     }
258     //
259     // Section Parts
260     Standard_Integer j, aNbCurves;   
261     BOPTools_SequenceOfCurves& aSC=aFF.Curves();
262     aNbCurves=aSC.Length();
263     
264     for (j=1; j<=aNbCurves; j++) {
265       const BOPTools_Curve& aBC=aSC(j);
266       const BOPTools_ListOfPaveBlock& aLPBSe=aBC.NewPaveBlocks();
267
268       anIt.Initialize(aLPBSe);
269       for (; anIt.More(); anIt.Next()) {
270         const BOPTools_PaveBlock& aPBSe=anIt.Value();
271         
272         const BOPTools_Pave& aPv1=aPBSe.Pave1();
273         nV=aPv1.Index();
274         if (nV==nVD) {
275           aLPBOut.Append(aPBSe);
276           continue;
277         }
278         
279         const BOPTools_Pave& aPv2=aPBSe.Pave2();
280         nV=aPv2.Index();
281         if (nV==nVD) {
282           aLPBOut.Append(aPBSe);
283           continue;
284         }
285       }
286     }
287   }
288 }
289 //=======================================================================
290 // function:  FillPaveSet
291 // purpose: 
292 //=======================================================================
293   void NMTTools_DEProcessor::FillPaveSet (const Standard_Integer nED,
294                                           const Standard_Integer nVD,
295                                           const Standard_Integer nFD,
296                                           const BOPTools_ListOfPaveBlock& aLPB)
297 {
298   Standard_Boolean bIsDone, bXDir, bRejectFlag;
299   Standard_Integer nE, aNbPoints, j;
300   Standard_Real aTD1, aTD2, aT1, aT2, aTolInter, aX, aDT;
301   //
302   aDT=Precision::PConfusion();
303   //
304   BOPTools_PaveSet& aPaveSet= (myFiller->ChangePavePool()).ChangeValue(myDS->RefEdge(nED));
305   //
306   // Clear aPaveSet, aSplitEdges
307   aPaveSet.ChangeSet().Clear();
308   //
309   const TopoDS_Edge& aDE=TopoDS::Edge(myDS->Shape(nED));
310   const TopoDS_Face& aDF=TopoDS::Face(myDS->Shape(nFD));
311   //
312   // 2D Curve of degenerated edge on the face aDF
313   Handle(Geom2d_Curve) aC2DDE=BRep_Tool::CurveOnSurface(aDE, aDF, aTD1, aTD2);
314   //
315   // Choose direction for Degenerated Edge
316   gp_Pnt2d aP2d1, aP2d2;
317   aC2DDE->D0(aTD1, aP2d1);
318   aC2DDE->D0(aTD2, aP2d2);
319
320   bXDir=Standard_False;
321   if (fabs(aP2d1.Y()-aP2d2.Y()) < aDT){
322     bXDir=!bXDir;
323   }
324   //
325   // Prepare bounding Paves
326   BOPTools_Pave aPave1 (nVD, aTD1, BooleanOperations_UnknownInterference);
327   aPaveSet.Append(aPave1);
328   BOPTools_Pave aPave2 (nVD, aTD2, BooleanOperations_UnknownInterference);
329   aPaveSet.Append(aPave2);
330   //
331   // Fill other paves 
332   BOPTools_ListIteratorOfListOfPaveBlock anIt(aLPB);
333   for (; anIt.More(); anIt.Next()) {
334     const BOPTools_PaveBlock& aPB=anIt.Value();
335     nE=aPB.Edge();
336     const TopoDS_Edge& aE=TopoDS::Edge(myDS->Shape(nE));
337     
338     Handle(Geom2d_Curve) aC2D=BRep_Tool::CurveOnSurface(aE, aDF, aT1, aT2);
339     //
340     // Intersection
341     aTolInter=0.001;
342         
343     Geom2dAdaptor_Curve aGAC1, aGAC2;
344     
345     aGAC1.Load(aC2DDE, aTD1, aTD2);
346     Handle(Geom2d_Line) aL2D= Handle(Geom2d_Line)::DownCast(aC2D);
347     if (!aL2D.IsNull()) {
348       aGAC2.Load(aC2D);
349     }
350     else {
351       aGAC2.Load(aC2D, aT1, aT2);
352     }
353     
354     Geom2dInt_GInter aGInter(aGAC1, aGAC2, aTolInter, aTolInter);
355     
356     bIsDone=aGInter.IsDone();
357     if(bIsDone) {
358       aNbPoints=aGInter.NbPoints();
359       if (aNbPoints) { 
360         for (j=1; j<=aNbPoints; ++j) {
361           gp_Pnt2d aP2D=aGInter.Point(j).Value();
362           //
363           aX=(bXDir) ? aP2D.X(): aP2D.Y();
364           //
365           if (fabs (aX-aTD1) < aDT || fabs (aX-aTD2) < aDT) {
366             continue; 
367           }
368           if (aX < aTD1 || aX > aTD2) {
369             continue; 
370           }
371           //
372           bRejectFlag=Standard_False;
373           const BOPTools_ListOfPave& aListOfPave=aPaveSet.Set();
374           BOPTools_ListIteratorOfListOfPave aPaveIt(aListOfPave);
375           for (; aPaveIt.More(); aPaveIt.Next()) {
376             const BOPTools_Pave& aPavex=aPaveIt.Value();
377             Standard_Real aXx=aPavex.Param();
378             if (fabs (aX-aXx) < aDT) {
379               bRejectFlag=Standard_True;
380               break;
381             }
382           }
383           if (bRejectFlag) {
384             continue; 
385           }
386           //
387           BOPTools_Pave aPave(nVD, aX, BooleanOperations_UnknownInterference);
388           aPaveSet.Append(aPave);
389         }
390       }
391     }
392   }
393 }
394 //=======================================================================
395 // function:  FillSplitEdgesPool
396 // purpose: 
397 //=======================================================================
398   void NMTTools_DEProcessor::FillSplitEdgesPool (const Standard_Integer nED)
399 {
400   BOPTools_SplitShapesPool& aSplitShapesPool=myFiller->ChangeSplitShapesPool();
401   BOPTools_ListOfPaveBlock& aSplitEdges=aSplitShapesPool.ChangeValue(myDS->RefEdge(nED));
402   //
403   aSplitEdges.Clear();
404   //
405   const BOPTools_PavePool& aPavePool=myFiller->PavePool();
406   BOPTools_PavePool* pPavePool=(BOPTools_PavePool*) &aPavePool;
407   BOPTools_PaveSet& aPaveSet= pPavePool->ChangeValue(myDS->RefEdge(nED));
408   
409   BOPTools_PaveBlockIterator aPBIt(nED, aPaveSet);
410   for (; aPBIt.More(); aPBIt.Next()) {
411     BOPTools_PaveBlock& aPB=aPBIt.Value();
412     aSplitEdges.Append(aPB);
413   }
414 }
415 //=======================================================================
416 // function:  MakeSplitEdges
417 // purpose: 
418 //=======================================================================
419   void NMTTools_DEProcessor::MakeSplitEdges (const Standard_Integer nED,
420                                              const Standard_Integer nFD)
421 {
422   const BOPTools_SplitShapesPool& aSplitShapesPool=myFiller->SplitShapesPool();
423   const BOPTools_ListOfPaveBlock& aSplitEdges=aSplitShapesPool(myDS->RefEdge(nED));
424
425   Standard_Integer nV1, nV2, aNewShapeIndex;
426   Standard_Real    t1, t2;
427   TopoDS_Edge aE, aESplit;
428   TopoDS_Vertex aV1, aV2;
429
430   const TopoDS_Edge& aDE=TopoDS::Edge(myDS->Shape(nED));
431   const TopoDS_Face& aDF=TopoDS::Face(myDS->Shape(nFD));
432
433   BOPTools_ListIteratorOfListOfPaveBlock aPBIt(aSplitEdges);
434
435   for (; aPBIt.More(); aPBIt.Next()) {
436     BOPTools_PaveBlock& aPB=aPBIt.Value();
437     
438     const BOPTools_Pave& aPave1=aPB.Pave1();
439     nV1=aPave1.Index();
440     t1=aPave1.Param();
441     aV1=TopoDS::Vertex(myDS->GetShape(nV1));
442     aV1.Orientation(TopAbs_FORWARD);
443     
444     const BOPTools_Pave& aPave2=aPB.Pave2();
445     nV2=aPave2.Index();
446     t2=aPave2.Param();
447     aV2=TopoDS::Vertex(myDS->GetShape(nV2));
448     aV2.Orientation(TopAbs_REVERSED);
449     
450     MakeSplitEdge(aDE, aDF, aV1, t1, aV2, t2, aESplit); 
451     //
452     // Add Split Part of the Original Edge to the DS
453     BooleanOperations_AncestorsSeqAndSuccessorsSeq anASSeq;
454     
455     anASSeq.SetNewSuccessor(nV1);
456     anASSeq.SetNewOrientation(aV1.Orientation());
457     
458     anASSeq.SetNewSuccessor(nV2);
459     anASSeq.SetNewOrientation(aV2.Orientation());
460     
461     myDS->InsertShapeAndAncestorsSuccessors(aESplit, anASSeq);
462     aNewShapeIndex=myDS->NumberOfInsertedShapes();
463     myDS->SetState(aNewShapeIndex, BooleanOperations_UNKNOWN);
464     //
465     // Fill Split Set for the Original Edge
466     aPB.SetEdge(aNewShapeIndex);
467     //
468   }
469 }
470 //=======================================================================
471 // function:  MakeSplitEdge
472 // purpose: 
473 //=======================================================================
474   void NMTTools_DEProcessor::MakeSplitEdge (const TopoDS_Edge&   aE,
475                                             const TopoDS_Face&   aF,
476                                             const TopoDS_Vertex& aV1,
477                                             const Standard_Real  aP1,
478                                             const TopoDS_Vertex& aV2,
479                                             const Standard_Real  aP2,
480                                             TopoDS_Edge& aNewEdge)
481 {
482   Standard_Real aTol=1.e-7;
483
484   TopoDS_Edge E=aE;
485
486   E.EmptyCopy();
487   BRep_Builder BB;
488   BB.Add  (E, aV1);
489   BB.Add  (E, aV2);
490
491   BB.Range(E, aF, aP1, aP2);
492
493   BB.Degenerated(E, Standard_True);
494
495   BB.UpdateEdge(E, aTol);
496   aNewEdge=E;
497 }
498 /*
499 //=======================================================================
500 // function: NMTTools_DEProcessor::NMTTools_DEProcessor
501 // purpose: 
502 //=======================================================================
503   NMTTools_DEProcessor::NMTTools_DEProcessor(NMTTools_PDSFiller& pDSFiller)
504 :
505   myIsDone(Standard_False)
506 {
507   myDSFiller=pDSFiller;
508   myFiller=(NMTTools_PaveFiller*) &(myDSFiller->PaveFiller());
509   myDS=myFiller->DS();
510 }
511 */