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