0026515: Exponential memory usage problems with BOPDS_IndexedMapOfPaveBlock and NColl...
[occt.git] / src / BOPAlgo / BOPAlgo_PaveFiller_8.cxx
CommitLineData
4e57c75e 1// Created by: Peter KURNEV
973c2be1 2// Copyright (c) 2010-2014 OPEN CASCADE SAS
4e57c75e 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//
973c2be1 7// This file is part of Open CASCADE Technology software library.
4e57c75e 8//
d5f74e42 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
973c2be1 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.
4e57c75e 14//
973c2be1 15// Alternatively, this file may be used under the terms of Open CASCADE
16// commercial license or contractual agreement.
4e57c75e 17
42cf5bc1 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>
4e57c75e 30#include <ElCLib.hxx>
4e57c75e 31#include <Geom2d_Curve.hxx>
4e57c75e 32#include <Geom2d_Line.hxx>
42cf5bc1 33#include <Geom2d_TrimmedCurve.hxx>
4e57c75e 34#include <Geom2dAdaptor_Curve.hxx>
35#include <Geom2dInt_GInter.hxx>
42cf5bc1 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>
42cf5bc1 41#include <Precision.hxx>
4e57c75e 42#include <TopoDS_Edge.hxx>
43#include <TopoDS_Face.hxx>
44#include <TopoDS_Vertex.hxx>
45
4e57c75e 46static
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//=======================================================================
488e5b9d 59void BOPAlgo_PaveFiller::ProcessDE()
4e57c75e 60{
61 Standard_Integer nF, aNb, nE, nV, nVSD, aNbPB;
488e5b9d 62 Handle(NCollection_BaseAllocator) aAllocator;
4e57c75e 63 Handle(BOPDS_PaveBlock) aPBD;
64 BOPCol_ListIteratorOfListOfInteger aItLI;
65 //
66 myErrorStatus=0;
67 //
68 // 1. Find degnerated edges
69 //-----------------------------------------------------scope f
70 //
488e5b9d 71 aAllocator=
72 NCollection_BaseAllocator::CommonBaseAllocator();
4e57c75e 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{
319da2e4 140 Standard_Integer i, aNbPBOn, aNbPBIn, aNbPBSc, nV1, nV2;
4e57c75e 141 //
142 const BOPDS_FaceInfo& aFI=myDS->ChangeFaceInfo(nF);
143 // In
144 const BOPDS_IndexedMapOfPaveBlock& aMPBIn=aFI.PaveBlocksIn();
319da2e4 145 aNbPBIn = aMPBIn.Extent();
146 for (i = 1; i <= aNbPBIn; ++i) {
147 const Handle(BOPDS_PaveBlock)& aPB = aMPBIn(i);
4e57c75e 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();
319da2e4 155 aNbPBOn = aMPBOn.Extent();
156 for (i = 1; i <= aNbPBOn; ++i) {
157 const Handle(BOPDS_PaveBlock)& aPB = aMPBOn(i);
4e57c75e 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();
319da2e4 165 aNbPBSc = aMPBSc.Extent();
166 for (i = 1; i <= aNbPBSc; ++i) {
167 const Handle(BOPDS_PaveBlock)& aPB = aMPBSc(i);
4e57c75e 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{
96a95605 240 Standard_Boolean bXDir, bIsDone;
787c4320 241 Standard_Integer nE, aNbPoints, j, anInd;
4e57c75e 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 //
787c4320 326 if (aPBD->ContainsParameter(aX, aDT, anInd)) {
4e57c75e 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}