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 |
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 | //======================================================================= |
488e5b9d |
59 | void 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(); |
3510db62 |
91 | if (aNbPB) { |
92 | // |
93 | // 2. |
94 | BOPDS_ListOfPaveBlock& aLPBD = myDS->ChangePaveBlocks(nE); |
0d0481c7 |
95 | Standard_ASSERT_VOID(!aLPBD.IsEmpty(), "ListOfPaveBlock is unexpectedly empty"); |
96 | if (aLPBD.IsEmpty()) |
97 | continue; |
3510db62 |
98 | aPBD = aLPBD.First(); |
99 | // |
100 | FillPaves(nV, nE, nF, aLPBOut, aPBD); |
101 | // |
102 | myDS->UpdatePaveBlock(aPBD); |
4e57c75e |
103 | } |
104 | // |
4e57c75e |
105 | MakeSplitEdge(nE, nF); |
106 | // |
107 | aLPBOut.Clear(); |
108 | } |
109 | if (aSIF.ShapeType() == TopAbs_EDGE) { |
110 | Standard_Real aTol=1.e-7; |
111 | Standard_Integer nEn; |
112 | BRep_Builder BB; |
113 | const TopoDS_Edge& aDE=(*(TopoDS_Edge *)(&myDS->Shape(nE))); |
114 | const TopoDS_Vertex& aVn = (*(TopoDS_Vertex *)(&myDS->Shape(nV))); |
115 | // |
116 | TopoDS_Edge aE=aDE; |
117 | aE.EmptyCopy(); |
118 | BB.Add(aE, aVn); |
119 | BB.Degenerated(aE, Standard_True); |
120 | BB.UpdateEdge(aE, aTol); |
121 | BOPDS_ShapeInfo aSI; |
122 | aSI.SetShapeType(TopAbs_EDGE); |
123 | aSI.SetShape(aE); |
124 | nEn=myDS->Append(aSI); |
125 | BOPDS_ListOfPaveBlock& aLPBD=myDS->ChangePaveBlocks(nE); |
126 | aPBD=aLPBD.First(); |
127 | aPBD->SetEdge(nEn); |
128 | } |
129 | } |
130 | } |
131 | } |
132 | } |
133 | |
134 | //======================================================================= |
135 | //function : FindPaveBlocks |
136 | //purpose : |
137 | //======================================================================= |
138 | void BOPAlgo_PaveFiller::FindPaveBlocks(const Standard_Integer nV, |
139 | const Standard_Integer nF, |
140 | BOPDS_ListOfPaveBlock& aLPBOut) |
141 | { |
319da2e4 |
142 | Standard_Integer i, aNbPBOn, aNbPBIn, aNbPBSc, nV1, nV2; |
4e57c75e |
143 | // |
144 | const BOPDS_FaceInfo& aFI=myDS->ChangeFaceInfo(nF); |
145 | // In |
146 | const BOPDS_IndexedMapOfPaveBlock& aMPBIn=aFI.PaveBlocksIn(); |
319da2e4 |
147 | aNbPBIn = aMPBIn.Extent(); |
148 | for (i = 1; i <= aNbPBIn; ++i) { |
149 | const Handle(BOPDS_PaveBlock)& aPB = aMPBIn(i); |
4e57c75e |
150 | aPB->Indices(nV1, nV2); |
151 | if (nV==nV1 || nV==nV2) { |
152 | aLPBOut.Append(aPB); |
153 | } |
154 | } |
155 | // On |
156 | const BOPDS_IndexedMapOfPaveBlock& aMPBOn=aFI.PaveBlocksOn(); |
319da2e4 |
157 | aNbPBOn = aMPBOn.Extent(); |
158 | for (i = 1; i <= aNbPBOn; ++i) { |
159 | const Handle(BOPDS_PaveBlock)& aPB = aMPBOn(i); |
4e57c75e |
160 | aPB->Indices(nV1, nV2); |
161 | if (nV==nV1 || nV==nV2) { |
162 | aLPBOut.Append(aPB); |
163 | } |
164 | } |
165 | // Sections |
166 | const BOPDS_IndexedMapOfPaveBlock& aMPBSc=aFI.PaveBlocksSc(); |
319da2e4 |
167 | aNbPBSc = aMPBSc.Extent(); |
168 | for (i = 1; i <= aNbPBSc; ++i) { |
169 | const Handle(BOPDS_PaveBlock)& aPB = aMPBSc(i); |
4e57c75e |
170 | aPB->Indices(nV1, nV2); |
171 | if (nV==nV1 || nV==nV2) { |
172 | aLPBOut.Append(aPB); |
173 | } |
174 | } |
175 | } |
176 | |
177 | //======================================================================= |
178 | //function : MakeSplitEdge |
179 | //purpose : |
180 | //======================================================================= |
181 | void BOPAlgo_PaveFiller::MakeSplitEdge (const Standard_Integer nDE, |
182 | const Standard_Integer nDF) |
183 | { |
184 | Standard_Integer nSp, nV1, nV2, aNbPB; |
185 | Standard_Real aT1, aT2; |
186 | TopoDS_Edge aDE, aSp; |
187 | TopoDS_Vertex aV1, aV2; |
188 | BOPDS_ListIteratorOfListOfPaveBlock aItLPB; |
189 | BOPDS_ShapeInfo aSI; |
190 | // |
191 | aSI.SetShapeType(TopAbs_EDGE); |
192 | // |
193 | aDE=(*(TopoDS_Edge *)(&myDS->Shape(nDE))); |
194 | aDE.Orientation(TopAbs_FORWARD); |
195 | // |
196 | const TopoDS_Face& aDF=(*(TopoDS_Face *)(&myDS->Shape(nDF))); |
197 | // |
198 | BOPDS_ListOfPaveBlock& aLPB=myDS->ChangePaveBlocks(nDE); |
199 | aNbPB=aLPB.Extent(); |
200 | // |
201 | aItLPB.Initialize(aLPB); |
202 | for (; aItLPB.More(); aItLPB.Next()) { |
203 | Handle(BOPDS_PaveBlock)& aPB=aItLPB.ChangeValue(); |
204 | // |
205 | const BOPDS_Pave& aPave1=aPB->Pave1(); |
206 | aPave1.Contents(nV1, aT1); |
207 | // |
208 | const BOPDS_Pave& aPave2=aPB->Pave2(); |
209 | aPave2.Contents(nV2, aT2); |
210 | // |
211 | if (myDS->IsNewShape(nV1) || aNbPB>1) { |
212 | aV1=(*(TopoDS_Vertex *)(&myDS->Shape(nV1))); |
213 | aV1.Orientation(TopAbs_FORWARD); |
214 | // |
215 | aV2=(*(TopoDS_Vertex *)(&myDS->Shape(nV2))); |
216 | aV2.Orientation(TopAbs_REVERSED); |
217 | // |
218 | MakeSplitEdge1(aDE, aDF, aV1, aT1, aV2, aT2, aSp); |
219 | // |
220 | aSI.SetShape(aSp); |
221 | nSp=myDS->Append(aSI); |
222 | aPB->SetEdge(nSp); |
223 | } |
224 | else { |
225 | //aPB->SetEdge(nDE); |
226 | aLPB.Clear(); |
227 | break; |
228 | } |
229 | } |
230 | } |
231 | |
232 | //======================================================================= |
233 | //function : FillPaves |
234 | //purpose : |
235 | //======================================================================= |
236 | void BOPAlgo_PaveFiller::FillPaves(const Standard_Integer nVD, |
237 | const Standard_Integer nED, |
238 | const Standard_Integer nFD, |
239 | const BOPDS_ListOfPaveBlock& aLPBOut, |
240 | const Handle(BOPDS_PaveBlock)& aPBD) |
241 | { |
96a95605 |
242 | Standard_Boolean bXDir, bIsDone; |
787c4320 |
243 | Standard_Integer nE, aNbPoints, j, anInd; |
4e57c75e |
244 | Standard_Real aTD1, aTD2, aT1, aT2, aTolInter, aX, aDT; |
245 | Standard_Real aTolCmp; |
246 | gp_Pnt2d aP2d1, aP2d2, aP2D; |
247 | gp_Lin2d aLDE; |
248 | Handle(Geom2d_Line) aCLDE; |
249 | Handle(Geom2d_Curve) aC2DDE1, aC2D; |
250 | Handle(Geom2d_TrimmedCurve)aC2DDE; |
251 | BOPDS_ListIteratorOfListOfPaveBlock aItLPB; |
252 | BOPDS_Pave aPave; |
253 | // |
254 | aDT=Precision::PConfusion(); |
255 | // |
256 | aPave.SetIndex(nVD); |
257 | // |
258 | const TopoDS_Edge& aDE=(*(TopoDS_Edge *)(&myDS->Shape(nED))); |
259 | const TopoDS_Face& aDF=(*(TopoDS_Face *)(&myDS->Shape(nFD))); |
260 | //aC2DDE |
261 | aC2DDE1=BRep_Tool::CurveOnSurface(aDE, aDF, aTD1, aTD2); |
262 | aC2DDE=new Geom2d_TrimmedCurve(aC2DDE1, aTD1, aTD2); |
263 | //aCLDE |
264 | Handle(Geom2d_TrimmedCurve) aCLDET1=Handle(Geom2d_TrimmedCurve)::DownCast(aC2DDE1); |
265 | if (aCLDET1.IsNull()) { |
266 | aCLDE=Handle(Geom2d_Line)::DownCast(aC2DDE1); |
267 | } |
268 | else { |
269 | Handle(Geom2d_Curve) aBasisCurve=aCLDET1->BasisCurve(); |
270 | aCLDE=Handle(Geom2d_Line)::DownCast(aBasisCurve); |
271 | } |
272 | // |
273 | // Choose direction for degenerated edge |
274 | aC2DDE->D0(aTD1, aP2d1); |
275 | aC2DDE->D0(aTD2, aP2d2); |
276 | // |
277 | bXDir=Standard_False; |
278 | if (fabs(aP2d1.Y()-aP2d2.Y()) < aDT){ |
279 | bXDir=!bXDir; |
280 | } |
281 | // |
282 | aItLPB.Initialize(aLPBOut); |
283 | for (; aItLPB.More(); aItLPB.Next()) { |
284 | const Handle(BOPDS_PaveBlock)& aPB=aItLPB.Value(); |
285 | nE=aPB->Edge(); |
01b5b3df |
286 | if (nE < 0) { |
287 | continue; |
288 | } |
4e57c75e |
289 | const TopoDS_Edge& aE=(*(TopoDS_Edge *)(&myDS->Shape(nE))); |
290 | aC2D=BRep_Tool::CurveOnSurface(aE, aDF, aT1, aT2); |
291 | if (aC2D.IsNull()) { |
292 | continue; |
293 | } |
294 | // |
295 | // Intersection |
296 | Geom2dAdaptor_Curve aGAC1, aGAC2; |
297 | aGAC1.Load(aC2DDE, aTD1, aTD2); |
298 | // |
299 | Handle(Geom2d_Line) aL2D= Handle(Geom2d_Line)::DownCast(aC2D); |
300 | if (!aL2D.IsNull()) { |
301 | aGAC2.Load(aC2D); |
302 | } |
303 | else { |
304 | aGAC2.Load(aC2D, aT1, aT2); |
305 | } |
306 | // |
307 | aTolInter=0.001; |
308 | aTolCmp=1.414213562*aTolInter+aDT; |
309 | Geom2dInt_GInter aGInter(aGAC1, aGAC2, aTolInter, aTolInter); |
310 | bIsDone=aGInter.IsDone(); |
311 | if(!bIsDone) { |
312 | continue; |
313 | } |
314 | // |
315 | aNbPoints=aGInter.NbPoints(); |
316 | if (!aNbPoints){ |
317 | continue; |
318 | } |
319 | // |
320 | for (j=1; j<=aNbPoints; ++j) { |
321 | aP2D=aGInter.Point(j).Value(); |
322 | aX=aGInter.Point(j).ParamOnFirst(); |
323 | // |
324 | if (fabs (aX-aTD1) < aTolCmp || fabs (aX-aTD2) < aTolCmp) { |
325 | continue; |
326 | } |
327 | if (aX < aTD1 || aX > aTD2) { |
328 | continue; |
329 | } |
330 | // |
787c4320 |
331 | if (aPBD->ContainsParameter(aX, aDT, anInd)) { |
4e57c75e |
332 | continue; |
333 | } |
334 | aPave.SetParameter(aX); |
335 | aPBD->AppendExtPave1(aPave); |
336 | } |
337 | }//for (; aItLPB.More(); aItLPB.Next()) { |
4e57c75e |
338 | } |
339 | //======================================================================= |
340 | // function: MakeSplitEdge1 |
341 | // purpose: |
342 | //======================================================================= |
343 | void MakeSplitEdge1 (const TopoDS_Edge& aE, |
344 | const TopoDS_Face& aF, |
345 | const TopoDS_Vertex& aV1, |
346 | const Standard_Real aP1, |
347 | const TopoDS_Vertex& aV2, |
348 | const Standard_Real aP2, |
349 | TopoDS_Edge& aNewEdge) |
350 | { |
351 | Standard_Real aTol=1.e-7; |
352 | |
353 | TopoDS_Edge E=aE; |
354 | |
355 | E.EmptyCopy(); |
356 | BRep_Builder BB; |
357 | BB.Add (E, aV1); |
358 | BB.Add (E, aV2); |
359 | |
360 | BB.Range(E, aF, aP1, aP2); |
361 | |
362 | BB.Degenerated(E, Standard_True); |
363 | |
364 | BB.UpdateEdge(E, aTol); |
365 | aNewEdge=E; |
366 | } |