Salome HOME
Merging from V3_2_6pre4
[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:        NMTTools_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_PaveFiller.hxx>
84 //
85 #include <BOPTools_SequenceOfCurves.hxx>
86 #include <BOPTools_Curve.hxx>
87 //
88 #include <Geom2d_TrimmedCurve.hxx>
89
90 #include <ElCLib.hxx>
91 #include <gp_Lin2d.hxx>
92
93
94
95 //=======================================================================
96 // function: NMTTools_DEProcessor::NMTTools_DEProcessor
97 // purpose: 
98 //=======================================================================
99   NMTTools_DEProcessor::NMTTools_DEProcessor(NMTTools_PaveFiller& aPaveFiller)
100 :
101   myIsDone(Standard_False)
102 {
103   myFiller=(NMTTools_PaveFiller*) &aPaveFiller;
104   myDS=myFiller->DS();
105 }
106 //=======================================================================
107 // function: IsDone
108 // purpose: 
109 //=======================================================================
110   Standard_Boolean NMTTools_DEProcessor::IsDone() const
111 {
112   return myIsDone;
113 }
114 //=======================================================================
115 // function:  Do
116 // purpose: 
117 //=======================================================================
118   void NMTTools_DEProcessor::Do()
119 {
120   Standard_Integer aNbE;
121   myIsDone=Standard_False;
122
123   FindDegeneratedEdges();
124   aNbE=myDEMap.Extent();
125   
126   if (!aNbE) {
127     myIsDone=Standard_True;
128     return;
129   }
130   DoPaves();
131 }
132 //=======================================================================
133 // function:  FindDegeneratedEdges
134 // purpose: 
135 //=======================================================================
136   void NMTTools_DEProcessor::FindDegeneratedEdges()
137 {
138   Standard_Integer i, aNb, nV, nF, nVx, ip, iRankE;
139   TopTools_IndexedDataMapOfShapeListOfShape aMEF;
140   //
141   aNb=myDS->NumberOfShapesOfTheObject();
142   //
143   for (i=1; i<=aNb; i++) {
144     const TopoDS_Shape aF=myDS->Shape(i);//mpv
145     if (aF.ShapeType()==TopAbs_FACE) {
146       TopExp::MapShapesAndAncestors (aF, TopAbs_EDGE, TopAbs_FACE, aMEF);
147     }
148   }
149   //
150   for (i=1; i<=aNb; i++) {
151     const TopoDS_Shape aS=myDS->Shape(i);//mpv
152     if (aS.ShapeType()==TopAbs_EDGE) {
153       const TopoDS_Edge& aE=TopoDS::Edge(aS);
154       
155       if (BRep_Tool::Degenerated(aE)) {
156         iRankE=myDS->Rank(i);
157
158         TopoDS_Vertex aV=TopExp::FirstVertex(aE);
159
160         nVx=myDS->ShapeIndex(aV, iRankE);
161         //
162         nV=nVx;
163         ip=myFiller->FindSDVertex(nV);
164         if (ip) {
165           nV=ip;
166         }
167         //
168         TColStd_ListOfInteger aLFn;
169         const TopTools_ListOfShape& aLF=aMEF.FindFromKey(aE);
170         TopTools_ListIteratorOfListOfShape anIt(aLF);
171         for (; anIt.More(); anIt.Next()) {
172           const TopoDS_Shape& aF=anIt.Value();
173           nF=myDS->ShapeIndex(aF, iRankE);
174           aLFn.Append(nF);
175         }
176         BOPTools_DEInfo aDEInfo;
177         aDEInfo.SetVertex(nV);
178         aDEInfo.SetFaces(aLFn);
179
180         myDEMap.Add (i, aDEInfo);
181       }
182     }
183   }
184 }
185 //=======================================================================
186 // function:  DoPaves
187 // purpose: 
188 //=======================================================================
189   void NMTTools_DEProcessor::DoPaves()
190 {
191
192   Standard_Integer i, aNbE, nED, nVD, nFD, aNbLPB;
193   //
194   nFD=0;
195   aNbE=myDEMap.Extent();
196   for (i=1; i<=aNbE; i++) {
197     nED=myDEMap.FindKey(i);
198     
199     const BOPTools_DEInfo& aDEInfo=myDEMap(i);
200     nVD=aDEInfo.Vertex();
201     // Fill PaveSet for the edge nED
202     const TColStd_ListOfInteger& nLF=aDEInfo.Faces();
203     TColStd_ListIteratorOfListOfInteger anIt(nLF);
204     for (; anIt.More(); anIt.Next()) {
205       nFD=anIt.Value();
206       //
207       BOPTools_ListOfPaveBlock aLPB;
208       FindPaveBlocks(nED, nVD, nFD, aLPB);
209       //modified by NIZNHY-PKV Fri Mar 23 10:35:27 2007f
210       //
211       aNbLPB=aLPB.Extent();
212       if (!aNbLPB) {
213         continue;
214       }
215       //modified by NIZNHY-PKV Fri Mar 23 10:35:33 2007t
216       FillPaveSet (nED, nVD, nFD, aLPB);
217     }
218     // 
219     // Fill aSplitEdges for the edge nED
220     FillSplitEdgesPool(nED);
221     //
222     // MakeSplitEdges
223     MakeSplitEdges(nED, nFD);
224     //
225   }// next nED
226 }
227 //=======================================================================
228 // function:  FindPaveBlocks
229 // purpose: 
230 //=======================================================================
231   void NMTTools_DEProcessor::FindPaveBlocks(const Standard_Integer ,
232                                             const Standard_Integer nVD,
233                                             const Standard_Integer nFD,
234                                             BOPTools_ListOfPaveBlock& aLPBOut)
235 {
236   BOPTools_ListIteratorOfListOfPaveBlock anIt;
237   Standard_Integer i, aNb, nF2, nV;
238   //
239   BOPTools_CArray1OfSSInterference& aFFs=(myFiller->InterfPool())->SSInterferences();
240   //
241   aNb=aFFs.Extent();
242   for (i=1; i<=aNb; ++i) {
243     BOPTools_SSInterference& aFF=aFFs(i);
244     //
245     nF2=aFF.OppositeIndex(nFD);
246     if (!nF2) {
247       continue;
248     }
249     //
250     // Split Parts 
251     const BOPTools_ListOfPaveBlock& aLPBSplits=aFF.PaveBlocks();
252     anIt.Initialize(aLPBSplits);
253     for (; anIt.More(); anIt.Next()) {
254       const BOPTools_PaveBlock& aPBSp=anIt.Value();
255       //
256       const BOPTools_Pave& aPave1=aPBSp.Pave1();
257       nV=aPave1.Index();
258       if (nV==nVD) {
259         aLPBOut.Append(aPBSp);
260         continue;
261       }
262       //
263       const BOPTools_Pave& aPave2=aPBSp.Pave2();
264       nV=aPave2.Index();
265       if (nV==nVD) {
266         aLPBOut.Append(aPBSp);
267         continue;
268       }
269     }
270     //
271     // Section Parts
272     Standard_Integer j, aNbCurves;   
273     BOPTools_SequenceOfCurves& aSC=aFF.Curves();
274     aNbCurves=aSC.Length();
275     
276     for (j=1; j<=aNbCurves; j++) {
277       const BOPTools_Curve& aBC=aSC(j);
278       const BOPTools_ListOfPaveBlock& aLPBSe=aBC.NewPaveBlocks();
279
280       anIt.Initialize(aLPBSe);
281       for (; anIt.More(); anIt.Next()) {
282         const BOPTools_PaveBlock& aPBSe=anIt.Value();
283         
284         const BOPTools_Pave& aPv1=aPBSe.Pave1();
285         nV=aPv1.Index();
286         if (nV==nVD) {
287           aLPBOut.Append(aPBSe);
288           continue;
289         }
290         
291         const BOPTools_Pave& aPv2=aPBSe.Pave2();
292         nV=aPv2.Index();
293         if (nV==nVD) {
294           aLPBOut.Append(aPBSe);
295           continue;
296         }
297       }
298     }
299   }
300 }
301 //=======================================================================
302 // function:  FillPaveSet
303 // purpose: 
304 //=======================================================================
305   void NMTTools_DEProcessor::FillPaveSet (const Standard_Integer nED,
306                                           const Standard_Integer nVD,
307                                           const Standard_Integer nFD,
308                                           const BOPTools_ListOfPaveBlock& aLPB)
309 {
310   Standard_Boolean bIsDone, bXDir, bRejectFlag;
311   Standard_Integer nE, aNbPoints, j;
312   Standard_Real aTD1, aTD2, aT1, aT2, aTolInter, aX, aDT;
313   //
314   aDT=Precision::PConfusion();
315   //
316   BOPTools_PaveSet& aPaveSet= (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));//mpv
322   const TopoDS_Face aDF=TopoDS::Face(myDS->Shape(nFD));//mpv
323   //
324   // 2D Curve of degenerated edge on the face aDF
325   // Modified  Thu Sep 14 14:35:18 2006 
326   // Contribution of Samtech www.samcef.com BEGIN
327   //Handle(Geom2d_Curve) aC2DDE=BRep_Tool::CurveOnSurface(aDE, aDF, aTD1, aTD2);
328   Handle(Geom2d_Curve) aC2DDE1=BRep_Tool::CurveOnSurface(aDE, aDF, aTD1, aTD2);
329   Handle(Geom2d_TrimmedCurve)aC2DDE=new Geom2d_TrimmedCurve(aC2DDE1, aTD1, aTD2);
330   // Contribution of Samtech www.samcef.com END 
331   //
332   // Choose direction for Degenerated Edge
333   gp_Pnt2d aP2d1, aP2d2;
334   aC2DDE->D0(aTD1, aP2d1);
335   aC2DDE->D0(aTD2, aP2d2);
336
337   bXDir=Standard_False;
338   if (fabs(aP2d1.Y()-aP2d2.Y()) < aDT){
339     bXDir=!bXDir;
340   }
341   //
342   // Prepare bounding Paves
343   BOPTools_Pave aPave1 (nVD, aTD1, BooleanOperations_UnknownInterference);
344   aPaveSet.Append(aPave1);
345   BOPTools_Pave aPave2 (nVD, aTD2, BooleanOperations_UnknownInterference);
346   aPaveSet.Append(aPave2);
347   //
348   // Fill other paves 
349   BOPTools_ListIteratorOfListOfPaveBlock anIt(aLPB);
350   for (; anIt.More(); anIt.Next()) {
351     const BOPTools_PaveBlock& aPB=anIt.Value();
352     nE=aPB.Edge();
353     const TopoDS_Edge aE=TopoDS::Edge(myDS->Shape(nE));//mpv
354     
355     Handle(Geom2d_Curve) aC2D=BRep_Tool::CurveOnSurface(aE, aDF, aT1, aT2);
356     //
357     // Intersection
358     aTolInter=0.001;
359         
360     Geom2dAdaptor_Curve aGAC1, aGAC2;
361     
362     aGAC1.Load(aC2DDE, aTD1, aTD2);
363     Handle(Geom2d_Line) aL2D= Handle(Geom2d_Line)::DownCast(aC2D);
364     if (!aL2D.IsNull()) {
365       aGAC2.Load(aC2D);
366     }
367     else {
368       aGAC2.Load(aC2D, aT1, aT2);
369     }
370     
371     Geom2dInt_GInter aGInter(aGAC1, aGAC2, aTolInter, aTolInter);
372     
373     bIsDone=aGInter.IsDone();
374     if(bIsDone) {
375       aNbPoints=aGInter.NbPoints();
376       if (aNbPoints) { 
377         for (j=1; j<=aNbPoints; ++j) {
378           gp_Pnt2d aP2D=aGInter.Point(j).Value();
379           //
380           // Modified to obtain exact parameter Thu Sep 14 14:35:18 2006 
381           // Contribution of Samtech www.samcef.com BEGIN
382           Handle(Geom2d_Line) aCLDE=Handle(Geom2d_Line)::DownCast(aC2DDE1);
383           if (aCLDE.IsNull()) {
384             continue;
385           }
386           gp_Lin2d aLDE=aCLDE->Lin2d();
387           aX=ElCLib::Parameter(aLDE, aP2D);
388           //
389           //aX=(bXDir) ? aP2D.X(): aP2D.Y();
390           // Contribution of Samtech www.samcef.com END 
391           //
392           if (fabs (aX-aTD1) < aDT || fabs (aX-aTD2) < aDT) {
393             continue; 
394           }
395           if (aX < aTD1 || aX > aTD2) {
396             continue; 
397           }
398           //
399           bRejectFlag=Standard_False;
400           const BOPTools_ListOfPave& aListOfPave=aPaveSet.Set();
401           BOPTools_ListIteratorOfListOfPave aPaveIt(aListOfPave);
402           for (; aPaveIt.More(); aPaveIt.Next()) {
403             const BOPTools_Pave& aPavex=aPaveIt.Value();
404             Standard_Real aXx=aPavex.Param();
405             if (fabs (aX-aXx) < aDT) {
406               bRejectFlag=Standard_True;
407               break;
408             }
409           }
410           if (bRejectFlag) {
411             continue; 
412           }
413           //
414           BOPTools_Pave aPave(nVD, aX, BooleanOperations_UnknownInterference);
415           aPaveSet.Append(aPave);
416         }
417       }
418     }
419   }
420 }
421 //=======================================================================
422 // function:  FillSplitEdgesPool
423 // purpose: 
424 //=======================================================================
425   void NMTTools_DEProcessor::FillSplitEdgesPool (const Standard_Integer nED)
426 {
427   BOPTools_SplitShapesPool& aSplitShapesPool=myFiller->ChangeSplitShapesPool();
428   BOPTools_ListOfPaveBlock& aSplitEdges=aSplitShapesPool.ChangeValue(myDS->RefEdge(nED));
429   //
430   aSplitEdges.Clear();
431   //
432   const BOPTools_PavePool& aPavePool=myFiller->PavePool();
433   BOPTools_PavePool* pPavePool=(BOPTools_PavePool*) &aPavePool;
434   BOPTools_PaveSet& aPaveSet= pPavePool->ChangeValue(myDS->RefEdge(nED));
435   
436   BOPTools_PaveBlockIterator aPBIt(nED, aPaveSet);
437   for (; aPBIt.More(); aPBIt.Next()) {
438     BOPTools_PaveBlock& aPB=aPBIt.Value();
439     aSplitEdges.Append(aPB);
440   }
441 }
442 //=======================================================================
443 // function:  MakeSplitEdges
444 // purpose: 
445 //=======================================================================
446   void NMTTools_DEProcessor::MakeSplitEdges (const Standard_Integer nED,
447                                              const Standard_Integer nFD)
448 {
449   const BOPTools_SplitShapesPool& aSplitShapesPool=myFiller->SplitShapesPool();
450   const BOPTools_ListOfPaveBlock& aSplitEdges=aSplitShapesPool(myDS->RefEdge(nED));
451
452   Standard_Integer nV1, nV2, aNewShapeIndex;
453   Standard_Real    t1, t2;
454   TopoDS_Edge aE, aESplit;
455   TopoDS_Vertex aV1, aV2;
456
457   const TopoDS_Edge aDE=TopoDS::Edge(myDS->Shape(nED));//mpv
458   const TopoDS_Face aDF=TopoDS::Face(myDS->Shape(nFD));//mpv
459
460   BOPTools_ListIteratorOfListOfPaveBlock aPBIt(aSplitEdges);
461
462   for (; aPBIt.More(); aPBIt.Next()) {
463     BOPTools_PaveBlock& aPB=aPBIt.Value();
464     
465     const BOPTools_Pave& aPave1=aPB.Pave1();
466     nV1=aPave1.Index();
467     t1=aPave1.Param();
468     aV1=TopoDS::Vertex(myDS->GetShape(nV1));
469     aV1.Orientation(TopAbs_FORWARD);
470     
471     const BOPTools_Pave& aPave2=aPB.Pave2();
472     nV2=aPave2.Index();
473     t2=aPave2.Param();
474     aV2=TopoDS::Vertex(myDS->GetShape(nV2));
475     aV2.Orientation(TopAbs_REVERSED);
476     
477     MakeSplitEdge(aDE, aDF, aV1, t1, aV2, t2, aESplit); 
478     //
479     // Add Split Part of the Original Edge to the DS
480     BooleanOperations_AncestorsSeqAndSuccessorsSeq anASSeq;
481     
482     anASSeq.SetNewSuccessor(nV1);
483     anASSeq.SetNewOrientation(aV1.Orientation());
484     
485     anASSeq.SetNewSuccessor(nV2);
486     anASSeq.SetNewOrientation(aV2.Orientation());
487     
488     myDS->InsertShapeAndAncestorsSuccessors(aESplit, anASSeq);
489     aNewShapeIndex=myDS->NumberOfInsertedShapes();
490     myDS->SetState(aNewShapeIndex, BooleanOperations_UNKNOWN);
491     //
492     // Fill Split Set for the Original Edge
493     aPB.SetEdge(aNewShapeIndex);
494     //
495   }
496 }
497 //=======================================================================
498 // function:  MakeSplitEdge
499 // purpose: 
500 //=======================================================================
501   void NMTTools_DEProcessor::MakeSplitEdge (const TopoDS_Edge&   aE,
502                                             const TopoDS_Face&   aF,
503                                             const TopoDS_Vertex& aV1,
504                                             const Standard_Real  aP1,
505                                             const TopoDS_Vertex& aV2,
506                                             const Standard_Real  aP2,
507                                             TopoDS_Edge& aNewEdge)
508 {
509   Standard_Real aTol=1.e-7;
510
511   TopoDS_Edge E=aE;
512
513   E.EmptyCopy();
514   BRep_Builder BB;
515   BB.Add  (E, aV1);
516   BB.Add  (E, aV2);
517
518   BB.Range(E, aF, aP1, aP2);
519
520   BB.Degenerated(E, Standard_True);
521
522   BB.UpdateEdge(E, aTol);
523   aNewEdge=E;
524 }
525 /*
526 //=======================================================================
527 // function: NMTTools_DEProcessor::NMTTools_DEProcessor
528 // purpose: 
529 //=======================================================================
530   NMTTools_DEProcessor::NMTTools_DEProcessor(NMTTools_PDSFiller& pDSFiller)
531 :
532   myIsDone(Standard_False)
533 {
534   myDSFiller=pDSFiller;
535   myFiller=(NMTTools_PaveFiller*) &(myDSFiller->PaveFiller());
536   myDS=myFiller->DS();
537 }
538 */