0026515: Exponential memory usage problems with BOPDS_IndexedMapOfPaveBlock and NColl...
[occt.git] / src / BOPAlgo / BOPAlgo_PaveFiller_8.cxx
1 // Created by: Peter KURNEV
2 // Copyright (c) 2010-2014 OPEN CASCADE SAS
3 // Copyright (c) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE
4 // Copyright (c) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, CEDRAT,
5 //                         EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 //
7 // This file is part of Open CASCADE Technology software library.
8 //
9 // This library is free software; you can redistribute it and/or modify it under
10 // the terms of the GNU Lesser General Public License version 2.1 as published
11 // by the Free Software Foundation, with special exception defined in the file
12 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
13 // distribution for complete text of the license and disclaimer of any warranty.
14 //
15 // Alternatively, this file may be used under the terms of Open CASCADE
16 // commercial license or contractual agreement.
17
18 #include <BOPAlgo_PaveFiller.hxx>
19 #include <BOPAlgo_SectionAttribute.hxx>
20 #include <BOPCol_ListOfInteger.hxx>
21 #include <BOPDS_Curve.hxx>
22 #include <BOPDS_DS.hxx>
23 #include <BOPDS_FaceInfo.hxx>
24 #include <BOPDS_MapOfPaveBlock.hxx>
25 #include <BOPDS_Pave.hxx>
26 #include <BOPDS_PaveBlock.hxx>
27 #include <BOPDS_ShapeInfo.hxx>
28 #include <BRep_Builder.hxx>
29 #include <BRep_Tool.hxx>
30 #include <ElCLib.hxx>
31 #include <Geom2d_Curve.hxx>
32 #include <Geom2d_Line.hxx>
33 #include <Geom2d_TrimmedCurve.hxx>
34 #include <Geom2dAdaptor_Curve.hxx>
35 #include <Geom2dInt_GInter.hxx>
36 #include <gp_Lin2d.hxx>
37 #include <gp_Pnt.hxx>
38 #include <gp_Pnt2d.hxx>
39 #include <IntRes2d_IntersectionPoint.hxx>
40 #include <IntTools_Context.hxx>
41 #include <Precision.hxx>
42 #include <TopoDS_Edge.hxx>
43 #include <TopoDS_Face.hxx>
44 #include <TopoDS_Vertex.hxx>
45
46 static
47   void MakeSplitEdge1 (const TopoDS_Edge&   aE,
48                        const TopoDS_Face&   aF,
49                        const TopoDS_Vertex& aV1,
50                        const Standard_Real  aP1,
51                        const TopoDS_Vertex& aV2,
52                        const Standard_Real  aP2,
53                        TopoDS_Edge& aNewEdge);
54
55 //=======================================================================
56 //function : ProcessDE
57 //purpose  : 
58 //=======================================================================
59 void BOPAlgo_PaveFiller::ProcessDE()
60 {
61   Standard_Integer nF, aNb, nE, nV, nVSD, aNbPB;
62   Handle(NCollection_BaseAllocator) aAllocator;
63   Handle(BOPDS_PaveBlock) aPBD;
64   BOPCol_ListIteratorOfListOfInteger aItLI;
65   //
66   myErrorStatus=0;
67   //
68   // 1. Find degnerated edges
69   //-----------------------------------------------------scope f
70   //
71   aAllocator=
72     NCollection_BaseAllocator::CommonBaseAllocator();
73   BOPDS_ListOfPaveBlock aLPBOut(aAllocator);
74   //
75   aNb=myDS->NbSourceShapes();
76   for (nE=0; nE<aNb; ++nE) {
77     const BOPDS_ShapeInfo& aSIE=myDS->ShapeInfo(nE);
78     if (aSIE.ShapeType()==TopAbs_EDGE) {
79       if (aSIE.HasFlag(nF)) {
80         const BOPDS_ShapeInfo& aSIF=myDS->ShapeInfo(nF);
81         nV=aSIE.SubShapes().First();
82         if (myDS->HasShapeSD(nV, nVSD)) {
83           nV=nVSD;
84         }
85         //nV,nE,nF
86         //
87         if (aSIF.ShapeType() == TopAbs_FACE) {
88           // 1. Find PaveBlocks that are go through nV for nF
89           FindPaveBlocks(nV, nF, aLPBOut);
90           aNbPB=aLPBOut.Extent();
91           if (!aNbPB) {
92             continue;
93           }
94           //
95           // 2.
96           BOPDS_ListOfPaveBlock& aLPBD=myDS->ChangePaveBlocks(nE);
97           aPBD=aLPBD.First();
98           //
99           FillPaves(nV, nE, nF, aLPBOut, aPBD);
100           //
101           myDS->UpdatePaveBlock(aPBD);
102           //
103           MakeSplitEdge(nE, nF);
104           //
105           aLPBOut.Clear();
106         }
107         if (aSIF.ShapeType() == TopAbs_EDGE) {
108           Standard_Real aTol=1.e-7;
109           Standard_Integer nEn;
110           BRep_Builder BB;
111           const TopoDS_Edge& aDE=(*(TopoDS_Edge *)(&myDS->Shape(nE))); 
112           const TopoDS_Vertex& aVn = (*(TopoDS_Vertex *)(&myDS->Shape(nV)));
113           //
114           TopoDS_Edge aE=aDE;
115           aE.EmptyCopy();
116           BB.Add(aE, aVn);
117           BB.Degenerated(aE, Standard_True);
118           BB.UpdateEdge(aE, aTol);
119           BOPDS_ShapeInfo aSI;
120           aSI.SetShapeType(TopAbs_EDGE);
121           aSI.SetShape(aE);
122           nEn=myDS->Append(aSI);
123           BOPDS_ListOfPaveBlock& aLPBD=myDS->ChangePaveBlocks(nE);
124           aPBD=aLPBD.First();
125           aPBD->SetEdge(nEn);
126         }
127       }
128     }
129   }
130 }
131
132 //=======================================================================
133 //function : FindPaveBlocks
134 //purpose  : 
135 //=======================================================================
136   void BOPAlgo_PaveFiller::FindPaveBlocks(const Standard_Integer nV,
137                                           const Standard_Integer nF,
138                                           BOPDS_ListOfPaveBlock& aLPBOut)
139 {
140   Standard_Integer i, aNbPBOn, aNbPBIn, aNbPBSc, nV1, nV2;
141   //
142   const BOPDS_FaceInfo& aFI=myDS->ChangeFaceInfo(nF);
143   // In
144   const BOPDS_IndexedMapOfPaveBlock& aMPBIn=aFI.PaveBlocksIn();
145   aNbPBIn = aMPBIn.Extent();
146   for (i = 1; i <= aNbPBIn; ++i) {
147     const Handle(BOPDS_PaveBlock)& aPB = aMPBIn(i);
148     aPB->Indices(nV1, nV2);
149     if (nV==nV1 || nV==nV2) {
150       aLPBOut.Append(aPB);
151     }
152   }
153   // On
154   const BOPDS_IndexedMapOfPaveBlock& aMPBOn=aFI.PaveBlocksOn();
155   aNbPBOn = aMPBOn.Extent();
156   for (i = 1; i <= aNbPBOn; ++i) {
157     const Handle(BOPDS_PaveBlock)& aPB = aMPBOn(i);
158     aPB->Indices(nV1, nV2);
159     if (nV==nV1 || nV==nV2) {
160       aLPBOut.Append(aPB);
161     }
162   }
163   // Sections
164   const BOPDS_IndexedMapOfPaveBlock& aMPBSc=aFI.PaveBlocksSc();
165   aNbPBSc = aMPBSc.Extent();
166   for (i = 1; i <= aNbPBSc; ++i) {
167     const Handle(BOPDS_PaveBlock)& aPB = aMPBSc(i);
168     aPB->Indices(nV1, nV2);
169     if (nV==nV1 || nV==nV2) {
170       aLPBOut.Append(aPB);
171     }
172   }
173 }
174
175 //=======================================================================
176 //function : MakeSplitEdge
177 //purpose  : 
178 //=======================================================================
179   void BOPAlgo_PaveFiller::MakeSplitEdge (const Standard_Integer nDE,
180                                           const Standard_Integer nDF)
181
182   Standard_Integer nSp, nV1, nV2, aNbPB;
183   Standard_Real aT1, aT2;
184   TopoDS_Edge aDE, aSp;
185   TopoDS_Vertex aV1, aV2;
186   BOPDS_ListIteratorOfListOfPaveBlock aItLPB;
187   BOPDS_ShapeInfo aSI;
188   //
189   aSI.SetShapeType(TopAbs_EDGE);
190   //
191   aDE=(*(TopoDS_Edge *)(&myDS->Shape(nDE))); 
192   aDE.Orientation(TopAbs_FORWARD);
193   //
194   const TopoDS_Face& aDF=(*(TopoDS_Face *)(&myDS->Shape(nDF)));
195   //
196   BOPDS_ListOfPaveBlock& aLPB=myDS->ChangePaveBlocks(nDE);
197   aNbPB=aLPB.Extent();
198   //
199   aItLPB.Initialize(aLPB);
200   for (; aItLPB.More(); aItLPB.Next()) {
201     Handle(BOPDS_PaveBlock)& aPB=aItLPB.ChangeValue();
202     //
203     const BOPDS_Pave& aPave1=aPB->Pave1();
204     aPave1.Contents(nV1, aT1);
205     //
206     const BOPDS_Pave& aPave2=aPB->Pave2();
207     aPave2.Contents(nV2, aT2);
208     //
209     if (myDS->IsNewShape(nV1) || aNbPB>1) {
210       aV1=(*(TopoDS_Vertex *)(&myDS->Shape(nV1)));
211       aV1.Orientation(TopAbs_FORWARD); 
212       //
213       aV2=(*(TopoDS_Vertex *)(&myDS->Shape(nV2)));
214       aV2.Orientation(TopAbs_REVERSED); 
215       //
216       MakeSplitEdge1(aDE, aDF, aV1, aT1, aV2, aT2, aSp); 
217       //
218       aSI.SetShape(aSp);
219       nSp=myDS->Append(aSI);
220       aPB->SetEdge(nSp);
221     }
222     else {
223       //aPB->SetEdge(nDE);
224       aLPB.Clear();
225       break;
226     }
227   }
228 }
229
230 //=======================================================================
231 //function : FillPaves
232 //purpose  : 
233 //=======================================================================
234   void BOPAlgo_PaveFiller::FillPaves(const Standard_Integer nVD,
235                                      const Standard_Integer nED,
236                                      const Standard_Integer nFD,
237                                      const BOPDS_ListOfPaveBlock& aLPBOut,
238                                      const Handle(BOPDS_PaveBlock)& aPBD)
239 {
240   Standard_Boolean bXDir, bIsDone;
241   Standard_Integer nE, aNbPoints, j, anInd;
242   Standard_Real aTD1, aTD2, aT1, aT2, aTolInter, aX, aDT;
243   Standard_Real aTolCmp;
244   gp_Pnt2d aP2d1, aP2d2, aP2D;
245   gp_Lin2d aLDE;
246   Handle(Geom2d_Line) aCLDE;
247   Handle(Geom2d_Curve) aC2DDE1, aC2D;
248   Handle(Geom2d_TrimmedCurve)aC2DDE;
249   BOPDS_ListIteratorOfListOfPaveBlock aItLPB;
250   BOPDS_Pave aPave;
251   //
252   aDT=Precision::PConfusion();
253   //
254   aPave.SetIndex(nVD);
255   //
256   const TopoDS_Edge& aDE=(*(TopoDS_Edge *)(&myDS->Shape(nED)));
257   const TopoDS_Face& aDF=(*(TopoDS_Face *)(&myDS->Shape(nFD)));
258   //aC2DDE
259   aC2DDE1=BRep_Tool::CurveOnSurface(aDE, aDF, aTD1, aTD2);
260   aC2DDE=new Geom2d_TrimmedCurve(aC2DDE1, aTD1, aTD2);
261   //aCLDE
262   Handle(Geom2d_TrimmedCurve) aCLDET1=Handle(Geom2d_TrimmedCurve)::DownCast(aC2DDE1);
263   if (aCLDET1.IsNull()) {
264     aCLDE=Handle(Geom2d_Line)::DownCast(aC2DDE1);
265   }
266   else {
267     Handle(Geom2d_Curve) aBasisCurve=aCLDET1->BasisCurve();
268     aCLDE=Handle(Geom2d_Line)::DownCast(aBasisCurve);
269   }
270   //
271   // Choose direction for degenerated edge
272   aC2DDE->D0(aTD1, aP2d1);
273   aC2DDE->D0(aTD2, aP2d2);
274   //
275   bXDir=Standard_False;
276   if (fabs(aP2d1.Y()-aP2d2.Y()) < aDT){
277     bXDir=!bXDir;
278   }
279   //
280   aItLPB.Initialize(aLPBOut);
281   for (; aItLPB.More(); aItLPB.Next()) {
282     const Handle(BOPDS_PaveBlock)& aPB=aItLPB.Value();
283     nE=aPB->Edge();
284     const TopoDS_Edge& aE=(*(TopoDS_Edge *)(&myDS->Shape(nE)));
285     aC2D=BRep_Tool::CurveOnSurface(aE, aDF, aT1, aT2);
286     if (aC2D.IsNull()) {
287       continue;
288     }
289     //
290     // Intersection
291     Geom2dAdaptor_Curve aGAC1, aGAC2;
292     aGAC1.Load(aC2DDE, aTD1, aTD2);
293     //
294     Handle(Geom2d_Line) aL2D= Handle(Geom2d_Line)::DownCast(aC2D);
295     if (!aL2D.IsNull()) {
296       aGAC2.Load(aC2D);
297     }
298     else {
299       aGAC2.Load(aC2D, aT1, aT2);
300     }
301     //
302     aTolInter=0.001;
303     aTolCmp=1.414213562*aTolInter+aDT;
304     Geom2dInt_GInter aGInter(aGAC1, aGAC2, aTolInter, aTolInter);
305     bIsDone=aGInter.IsDone();
306     if(!bIsDone) {
307       continue;
308     }
309     //
310     aNbPoints=aGInter.NbPoints();
311     if (!aNbPoints){
312       continue;
313     }
314     //
315     for (j=1; j<=aNbPoints; ++j) {
316       aP2D=aGInter.Point(j).Value();
317       aX=aGInter.Point(j).ParamOnFirst();
318       //
319       if (fabs (aX-aTD1) < aTolCmp || fabs (aX-aTD2) < aTolCmp) {
320         continue; 
321       }
322       if (aX < aTD1 || aX > aTD2) {
323         continue; 
324       }
325       //
326       if (aPBD->ContainsParameter(aX, aDT, anInd)) {
327         continue;
328       }
329       aPave.SetParameter(aX);
330       aPBD->AppendExtPave1(aPave);
331     }
332   }//for (; aItLPB.More(); aItLPB.Next()) {
333   //
334   myDS->UpdatePaveBlock(aPBD);
335 }
336 //=======================================================================
337 // function:  MakeSplitEdge1
338 // purpose: 
339 //=======================================================================
340   void MakeSplitEdge1 (const TopoDS_Edge&   aE,
341                        const TopoDS_Face&   aF,
342                        const TopoDS_Vertex& aV1,
343                        const Standard_Real  aP1,
344                        const TopoDS_Vertex& aV2,
345                        const Standard_Real  aP2,
346                        TopoDS_Edge& aNewEdge)
347 {
348   Standard_Real aTol=1.e-7;
349
350   TopoDS_Edge E=aE;
351
352   E.EmptyCopy();
353   BRep_Builder BB;
354   BB.Add  (E, aV1);
355   BB.Add  (E, aV2);
356
357   BB.Range(E, aF, aP1, aP2);
358
359   BB.Degenerated(E, Standard_True);
360
361   BB.UpdateEdge(E, aTol);
362   aNewEdge=E;
363 }