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