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