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 | |
4e57c75e |
18 | |
42cf5bc1 |
19 | #include <BOPAlgo_PaveFiller.hxx> |
20 | #include <BOPAlgo_SectionAttribute.hxx> |
21 | #include <BOPCol_ListOfInteger.hxx> |
22 | #include <BOPDS_Curve.hxx> |
23 | #include <BOPDS_DS.hxx> |
24 | #include <BOPDS_FaceInfo.hxx> |
25 | #include <BOPDS_MapOfPaveBlock.hxx> |
26 | #include <BOPDS_Pave.hxx> |
27 | #include <BOPDS_PaveBlock.hxx> |
28 | #include <BOPDS_ShapeInfo.hxx> |
29 | #include <BRep_Builder.hxx> |
30 | #include <BRep_Tool.hxx> |
4e57c75e |
31 | #include <ElCLib.hxx> |
4e57c75e |
32 | #include <Geom2d_Curve.hxx> |
4e57c75e |
33 | #include <Geom2d_Line.hxx> |
42cf5bc1 |
34 | #include <Geom2d_TrimmedCurve.hxx> |
4e57c75e |
35 | #include <Geom2dAdaptor_Curve.hxx> |
36 | #include <Geom2dInt_GInter.hxx> |
42cf5bc1 |
37 | #include <gp_Lin2d.hxx> |
38 | #include <gp_Pnt.hxx> |
39 | #include <gp_Pnt2d.hxx> |
40 | #include <IntRes2d_IntersectionPoint.hxx> |
41 | #include <IntTools_Context.hxx> |
42 | #include <NCollection_IncAllocator.hxx> |
43 | #include <Precision.hxx> |
4e57c75e |
44 | #include <TopoDS_Edge.hxx> |
45 | #include <TopoDS_Face.hxx> |
46 | #include <TopoDS_Vertex.hxx> |
47 | |
4e57c75e |
48 | static |
49 | void MakeSplitEdge1 (const TopoDS_Edge& aE, |
50 | const TopoDS_Face& aF, |
51 | const TopoDS_Vertex& aV1, |
52 | const Standard_Real aP1, |
53 | const TopoDS_Vertex& aV2, |
54 | const Standard_Real aP2, |
55 | TopoDS_Edge& aNewEdge); |
56 | |
57 | //======================================================================= |
58 | //function : ProcessDE |
59 | //purpose : |
60 | //======================================================================= |
61 | void BOPAlgo_PaveFiller::ProcessDE() |
62 | { |
63 | Standard_Integer nF, aNb, nE, nV, nVSD, aNbPB; |
64 | Handle(NCollection_IncAllocator) aAllocator; |
65 | Handle(BOPDS_PaveBlock) aPBD; |
66 | BOPCol_ListIteratorOfListOfInteger aItLI; |
67 | // |
68 | myErrorStatus=0; |
69 | // |
70 | // 1. Find degnerated edges |
71 | //-----------------------------------------------------scope f |
72 | // |
73 | aAllocator=new NCollection_IncAllocator(); |
74 | BOPDS_ListOfPaveBlock aLPBOut(aAllocator); |
75 | // |
76 | aNb=myDS->NbSourceShapes(); |
77 | for (nE=0; nE<aNb; ++nE) { |
78 | const BOPDS_ShapeInfo& aSIE=myDS->ShapeInfo(nE); |
79 | if (aSIE.ShapeType()==TopAbs_EDGE) { |
80 | if (aSIE.HasFlag(nF)) { |
81 | const BOPDS_ShapeInfo& aSIF=myDS->ShapeInfo(nF); |
82 | nV=aSIE.SubShapes().First(); |
83 | if (myDS->HasShapeSD(nV, nVSD)) { |
84 | nV=nVSD; |
85 | } |
86 | //nV,nE,nF |
87 | // |
88 | if (aSIF.ShapeType() == TopAbs_FACE) { |
89 | // 1. Find PaveBlocks that are go through nV for nF |
90 | FindPaveBlocks(nV, nF, aLPBOut); |
91 | aNbPB=aLPBOut.Extent(); |
92 | if (!aNbPB) { |
93 | continue; |
94 | } |
95 | // |
96 | // 2. |
97 | BOPDS_ListOfPaveBlock& aLPBD=myDS->ChangePaveBlocks(nE); |
98 | aPBD=aLPBD.First(); |
99 | // |
100 | FillPaves(nV, nE, nF, aLPBOut, aPBD); |
101 | // |
102 | myDS->UpdatePaveBlock(aPBD); |
103 | // |
104 | MakeSplitEdge(nE, nF); |
105 | // |
106 | aLPBOut.Clear(); |
107 | } |
108 | if (aSIF.ShapeType() == TopAbs_EDGE) { |
109 | Standard_Real aTol=1.e-7; |
110 | Standard_Integer nEn; |
111 | BRep_Builder BB; |
112 | const TopoDS_Edge& aDE=(*(TopoDS_Edge *)(&myDS->Shape(nE))); |
113 | const TopoDS_Vertex& aVn = (*(TopoDS_Vertex *)(&myDS->Shape(nV))); |
114 | // |
115 | TopoDS_Edge aE=aDE; |
116 | aE.EmptyCopy(); |
117 | BB.Add(aE, aVn); |
118 | BB.Degenerated(aE, Standard_True); |
119 | BB.UpdateEdge(aE, aTol); |
120 | BOPDS_ShapeInfo aSI; |
121 | aSI.SetShapeType(TopAbs_EDGE); |
122 | aSI.SetShape(aE); |
123 | nEn=myDS->Append(aSI); |
124 | BOPDS_ListOfPaveBlock& aLPBD=myDS->ChangePaveBlocks(nE); |
125 | aPBD=aLPBD.First(); |
126 | aPBD->SetEdge(nEn); |
127 | } |
128 | } |
129 | } |
130 | } |
131 | } |
132 | |
133 | //======================================================================= |
134 | //function : FindPaveBlocks |
135 | //purpose : |
136 | //======================================================================= |
137 | void BOPAlgo_PaveFiller::FindPaveBlocks(const Standard_Integer nV, |
138 | const Standard_Integer nF, |
139 | BOPDS_ListOfPaveBlock& aLPBOut) |
140 | { |
141 | Standard_Integer nV1, nV2; |
142 | BOPDS_MapIteratorOfMapOfPaveBlock aItMPB; |
143 | // |
144 | const BOPDS_FaceInfo& aFI=myDS->ChangeFaceInfo(nF); |
145 | // In |
146 | const BOPDS_IndexedMapOfPaveBlock& aMPBIn=aFI.PaveBlocksIn(); |
147 | aItMPB.Initialize(aMPBIn); |
148 | for(; aItMPB.More(); aItMPB.Next()) { |
149 | const Handle(BOPDS_PaveBlock)& aPB=aItMPB.Value(); |
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(); |
157 | aItMPB.Initialize(aMPBOn); |
158 | for(; aItMPB.More(); aItMPB.Next()) { |
159 | const Handle(BOPDS_PaveBlock)& aPB=aItMPB.Value(); |
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(); |
167 | aItMPB.Initialize(aMPBSc); |
168 | for(; aItMPB.More(); aItMPB.Next()) { |
169 | const Handle(BOPDS_PaveBlock)& aPB=aItMPB.Value(); |
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; |
4e57c75e |
243 | Standard_Integer nE, aNbPoints, j; |
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(); |
286 | const TopoDS_Edge& aE=(*(TopoDS_Edge *)(&myDS->Shape(nE))); |
287 | aC2D=BRep_Tool::CurveOnSurface(aE, aDF, aT1, aT2); |
288 | if (aC2D.IsNull()) { |
289 | continue; |
290 | } |
291 | // |
292 | // Intersection |
293 | Geom2dAdaptor_Curve aGAC1, aGAC2; |
294 | aGAC1.Load(aC2DDE, aTD1, aTD2); |
295 | // |
296 | Handle(Geom2d_Line) aL2D= Handle(Geom2d_Line)::DownCast(aC2D); |
297 | if (!aL2D.IsNull()) { |
298 | aGAC2.Load(aC2D); |
299 | } |
300 | else { |
301 | aGAC2.Load(aC2D, aT1, aT2); |
302 | } |
303 | // |
304 | aTolInter=0.001; |
305 | aTolCmp=1.414213562*aTolInter+aDT; |
306 | Geom2dInt_GInter aGInter(aGAC1, aGAC2, aTolInter, aTolInter); |
307 | bIsDone=aGInter.IsDone(); |
308 | if(!bIsDone) { |
309 | continue; |
310 | } |
311 | // |
312 | aNbPoints=aGInter.NbPoints(); |
313 | if (!aNbPoints){ |
314 | continue; |
315 | } |
316 | // |
317 | for (j=1; j<=aNbPoints; ++j) { |
318 | aP2D=aGInter.Point(j).Value(); |
319 | aX=aGInter.Point(j).ParamOnFirst(); |
320 | // |
321 | if (fabs (aX-aTD1) < aTolCmp || fabs (aX-aTD2) < aTolCmp) { |
322 | continue; |
323 | } |
324 | if (aX < aTD1 || aX > aTD2) { |
325 | continue; |
326 | } |
327 | // |
4e57c75e |
328 | if (aPBD->ContainsParameter(aX, aDT)) { |
329 | continue; |
330 | } |
331 | aPave.SetParameter(aX); |
332 | aPBD->AppendExtPave1(aPave); |
333 | } |
334 | }//for (; aItLPB.More(); aItLPB.Next()) { |
335 | // |
336 | myDS->UpdatePaveBlock(aPBD); |
337 | } |
338 | //======================================================================= |
339 | // function: MakeSplitEdge1 |
340 | // purpose: |
341 | //======================================================================= |
342 | void MakeSplitEdge1 (const TopoDS_Edge& aE, |
343 | const TopoDS_Face& aF, |
344 | const TopoDS_Vertex& aV1, |
345 | const Standard_Real aP1, |
346 | const TopoDS_Vertex& aV2, |
347 | const Standard_Real aP2, |
348 | TopoDS_Edge& aNewEdge) |
349 | { |
350 | Standard_Real aTol=1.e-7; |
351 | |
352 | TopoDS_Edge E=aE; |
353 | |
354 | E.EmptyCopy(); |
355 | BRep_Builder BB; |
356 | BB.Add (E, aV1); |
357 | BB.Add (E, aV2); |
358 | |
359 | BB.Range(E, aF, aP1, aP2); |
360 | |
361 | BB.Degenerated(E, Standard_True); |
362 | |
363 | BB.UpdateEdge(E, aTol); |
364 | aNewEdge=E; |
365 | } |