7fd59977 |
1 | // File: TopOpeBRepBuild_Builder_1.cxx |
2 | // Created: Thu Oct 7 09:38:29 1999 |
3 | // Author: Peter KURNEV |
4 | // <pkv@irinox.nnov.matra-dtv.fr> |
5 | |
6 | #include <TopOpeBRepBuild_Builder.ixx> |
7 | |
8 | #include <BRepTools.hxx> |
9 | #include <BRep_Builder.hxx> |
10 | |
11 | #include <TopExp.hxx> |
12 | |
13 | #include <TopoDS.hxx> |
14 | #include <TopoDS_Vertex.hxx> |
15 | #include <TopoDS_Wire.hxx> |
16 | |
17 | #include <TopTools_MapOfShape.hxx> |
18 | #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx> |
19 | #include <TopTools_MapIteratorOfMapOfShape.hxx> |
20 | #include <TopTools_IndexedMapOfShape.hxx> |
21 | |
22 | #include <TopOpeBRepBuild_PaveSet.hxx> |
23 | #include <TopOpeBRepBuild_GTool.hxx> |
24 | #include <TopOpeBRepBuild_Pave.hxx> |
25 | #include <TopOpeBRepBuild_Loop.hxx> |
26 | #include <TopOpeBRepBuild_EdgeBuilder.hxx> |
27 | #include <TopOpeBRepBuild_ListOfListOfLoop.hxx> |
28 | #include <TopOpeBRepBuild_Tools.hxx> |
29 | #include <TopOpeBRepBuild_GTopo.hxx> |
30 | |
31 | #include <TopOpeBRepDS_DataMapOfShapeState.hxx> |
32 | #include <TopOpeBRepDS_DataMapIteratorOfDataMapOfShapeState.hxx> |
33 | #include <TopOpeBRepDS_Interference.hxx> |
34 | #include <TopOpeBRepDS_ListOfInterference.hxx> |
35 | #include <TopOpeBRepDS_ListIteratorOfListOfInterference.hxx> |
36 | #include <TopOpeBRepDS_IndexedDataMapOfShapeWithState.hxx> |
37 | #include <TopOpeBRepDS_ShapeWithState.hxx> |
38 | #include <TopOpeBRepDS_DataStructure.hxx> |
39 | #include <BRep_Tool.hxx> |
40 | #include <TopOpeBRepDS_ListOfShapeOn1State.hxx> |
41 | #include <Geom_Curve.hxx> |
42 | #include <Precision.hxx> |
43 | #include <BRepAdaptor_Curve.hxx> |
44 | #include <TopTools_DataMapOfShapeListOfInteger.hxx> |
45 | #include <TColStd_ListIteratorOfListOfInteger.hxx> |
46 | |
47 | //define parameter division number as 10*e^(-PI) = 0.43213918 |
48 | const Standard_Real PAR_T = 0.43213918; |
49 | |
50 | static TopAbs_State ClassifyEdgeToSolidByOnePoint(const TopoDS_Edge& E, |
51 | TopOpeBRepTool_ShapeClassifier& SC); |
52 | |
53 | //======================================================================= |
54 | // : Definition the States of Shape's Entities for an Object |
55 | // : and a Tool. Thu Oct 7 09:38:29 1999 |
56 | //======================================================================= |
57 | |
58 | static TopTools_IndexedMapOfShape processedEdges; |
59 | static TopTools_IndexedMapOfShape theUsedVertexMap; |
60 | static TopTools_MapOfShape theUnkStateVer; |
61 | |
62 | Standard_IMPORT Standard_Boolean GLOBAL_faces2d; |
63 | |
64 | //modified by NIZNHY-PKV Mon Dec 16 11:38:55 2002 f |
65 | //======================================================================= |
66 | //function : Destroy |
67 | //purpose : |
68 | //======================================================================= |
69 | void TopOpeBRepBuild_Builder1::Destroy() |
70 | { |
71 | processedEdges.Clear(); |
72 | theUsedVertexMap.Clear(); |
73 | theUnkStateVer.Clear(); |
74 | } |
75 | //modified by NIZNHY-PKV Mon Dec 16 11:38:59 2002 t |
76 | |
77 | //======================================================================= |
78 | //function : PerformShapeWithStates |
79 | //purpose : |
80 | //======================================================================= |
81 | void TopOpeBRepBuild_Builder1::PerformShapeWithStates() |
82 | { |
83 | theUsedVertexMap.Clear(); |
84 | theUnkStateVer.Clear(); |
85 | myDataStructure -> ChangeDS().ChangeMapOfShapeWithStateObj().Clear(); |
86 | myDataStructure -> ChangeDS().ChangeMapOfShapeWithStateTool().Clear(); |
87 | //modified by NIZHNY-MZV Mon Feb 21 13:30:05 2000 |
88 | //process section curves |
89 | Standard_Integer i, nbC = myDataStructure -> DS().NbCurves(); |
90 | for(i = 1; i <= nbC; i++) { |
91 | TopTools_ListOfShape& LSE = ChangeNewEdges(i); |
92 | TopTools_ListIteratorOfListOfShape it(LSE); |
93 | for(; it.More(); it.Next()) { |
94 | const TopoDS_Shape& E = it.Value(); |
95 | TopoDS_Vertex Vf, Vl; |
96 | TopExp::Vertices(TopoDS::Edge(E), Vf, Vl); |
97 | theUsedVertexMap.Add(Vf); |
98 | theUsedVertexMap.Add(Vl); |
99 | } |
100 | } |
101 | |
102 | //process section edges |
103 | const TopOpeBRepDS_DataStructure& BDS = myDataStructure->DS(); |
104 | Standard_Integer n = BDS.NbSectionEdges(); |
105 | for (i = 1; i <= n; i++) { |
106 | TopTools_ListIteratorOfListOfShape anIt; |
107 | const TopoDS_Edge& E = TopoDS::Edge(BDS.SectionEdge(i)); |
108 | if(E.IsNull()) continue; |
109 | |
110 | const TopTools_ListOfShape& SplitsON = Splits(E, TopAbs_ON); |
111 | anIt.Initialize (SplitsON); |
112 | for (; anIt.More(); anIt.Next()) { |
113 | TopoDS_Shape aNewEdge=anIt.Value(); |
114 | TopoDS_Vertex Vf, Vl; |
115 | TopExp::Vertices(TopoDS::Edge(aNewEdge), Vf, Vl); |
116 | theUsedVertexMap.Add(Vf); |
117 | theUsedVertexMap.Add(Vl); |
118 | } |
119 | |
120 | // IN |
121 | const TopTools_ListOfShape& SplitsIN = Splits(E, TopAbs_IN); |
122 | anIt.Initialize (SplitsIN); |
123 | for (; anIt.More(); anIt.Next()) { |
124 | TopoDS_Shape aNewEdge=anIt.Value(); |
125 | TopoDS_Vertex Vf, Vl; |
126 | TopExp::Vertices(TopoDS::Edge(aNewEdge), Vf, Vl); |
127 | theUsedVertexMap.Add(Vf); |
128 | theUsedVertexMap.Add(Vl); |
129 | } |
130 | |
131 | // OUT |
132 | const TopTools_ListOfShape& SplitsOUT = Splits(E, TopAbs_OUT); |
133 | anIt.Initialize (SplitsOUT); |
134 | for (; anIt.More(); anIt.Next()) { |
135 | TopoDS_Shape aNewEdge=anIt.Value(); |
136 | TopoDS_Vertex Vf, Vl; |
137 | TopExp::Vertices(TopoDS::Edge(aNewEdge), Vf, Vl); |
138 | theUsedVertexMap.Add(Vf); |
139 | theUsedVertexMap.Add(Vl); |
140 | } |
141 | } |
142 | |
143 | //modified by NIZHNY-MZV Tue Apr 11 17:32:05 2000 |
144 | //1) Add both arguments to facilitate the search |
145 | TopOpeBRepDS_ShapeWithState aShapeWithState; |
146 | TopOpeBRepDS_DataStructure& aDataStructure=myDataStructure->ChangeDS(); |
147 | |
148 | TopOpeBRepDS_IndexedDataMapOfShapeWithState& aMapOfShapeWithStateObj= |
149 | aDataStructure.ChangeMapOfShapeWithStateObj(); |
150 | TopOpeBRepDS_IndexedDataMapOfShapeWithState& aMapOfShapeWithStateTool= |
151 | aDataStructure.ChangeMapOfShapeWithStateTool(); |
152 | |
153 | aMapOfShapeWithStateObj.Add(myShape1, aShapeWithState); |
154 | aMapOfShapeWithStateTool.Add(myShape2, aShapeWithState); |
155 | |
156 | //2) Add all rejected shapes as OUT |
157 | |
158 | TopTools_IndexedMapOfShape& aMapOfRejectedShapesObj= |
159 | aDataStructure.ChangeMapOfRejectedShapesObj(); |
160 | TopTools_IndexedMapOfShape& aMapOfRejectedShapesTool= |
161 | aDataStructure.ChangeMapOfRejectedShapesTool(); |
162 | |
163 | aShapeWithState.SetIsSplitted (Standard_False); |
164 | aShapeWithState.SetState (TopAbs_OUT); |
165 | |
166 | Standard_Integer iW, j, nW, nE, |
167 | nRSObj = aMapOfRejectedShapesObj.Extent(), |
168 | nRSTool = aMapOfRejectedShapesTool.Extent(); |
169 | |
170 | for(i = 1; i <= nRSObj; i++) { |
171 | const TopoDS_Shape& aFace = aMapOfRejectedShapesObj(i); |
172 | if(aFace.ShapeType() != TopAbs_FACE) |
173 | continue; |
174 | TopTools_IndexedMapOfShape aWiresMap; |
175 | |
176 | TopExp::MapShapes (aFace, TopAbs_WIRE, aWiresMap); |
177 | nW=aWiresMap.Extent (); |
178 | for (iW=1; iW<=nW; iW++) { |
179 | const TopoDS_Shape& aWire=aWiresMap(iW); |
180 | // |
181 | TopTools_IndexedMapOfShape anEdgesMap; |
182 | TopExp::MapShapes (aWire, TopAbs_EDGE, anEdgesMap); |
183 | nE=anEdgesMap.Extent (); |
184 | for (j=1; j<=nE; j++) |
185 | aMapOfShapeWithStateObj.Add(anEdgesMap(j), aShapeWithState); // add edge |
186 | |
187 | aMapOfShapeWithStateObj.Add(aWire, aShapeWithState); // add wire |
188 | } |
189 | aMapOfShapeWithStateObj.Add(aFace, aShapeWithState); // add face |
190 | } |
191 | |
192 | for(i = 1; i <= nRSTool; i++) { |
193 | const TopoDS_Shape& aFace = aMapOfRejectedShapesTool(i); |
194 | //modified by NIZHNY-MZV Wed Apr 5 10:27:18 2000 |
195 | if(aFace.ShapeType() != TopAbs_FACE) |
196 | continue; |
197 | TopTools_IndexedMapOfShape aWiresMap; |
198 | TopExp::MapShapes (aFace, TopAbs_WIRE, aWiresMap); |
199 | nW=aWiresMap.Extent (); |
200 | for (iW=1; iW<=nW; iW++) { |
201 | const TopoDS_Shape& aWire=aWiresMap(iW); |
202 | // |
203 | TopTools_IndexedMapOfShape anEdgesMap; |
204 | TopExp::MapShapes (aWire, TopAbs_EDGE, anEdgesMap); |
205 | nE=anEdgesMap.Extent (); |
206 | for (j=1; j<=nE; j++) |
207 | aMapOfShapeWithStateTool.Add(anEdgesMap(j), aShapeWithState); // add edge |
208 | |
209 | aMapOfShapeWithStateTool.Add(aWire, aShapeWithState); // add wire |
210 | } |
211 | aMapOfShapeWithStateTool.Add(aFace, aShapeWithState); // add face |
212 | } |
213 | |
214 | PerformShapeWithStates (myShape1, myShape2); |
215 | processedEdges.Clear(); |
216 | PerformShapeWithStates (myShape2, myShape1); |
217 | processedEdges.Clear(); |
218 | // Print Block |
219 | // printf(" ..::PerformShapeWithStates() [Dump is off]\n"); |
220 | |
221 | /* printf(" ..::PerformShapeWithStates() [Dump is on]\n"); |
222 | |
223 | TopOpeBRepDS_DataStructure& aDS= myDataStructure-> ChangeDS(); |
224 | |
225 | TopOpeBRepDS_IndexedDataMapOfShapeWithState& aMapOfShapeWithStateObj= |
226 | aDS.ChangeMapOfShapeWithStateObj(); |
227 | |
228 | TopOpeBRepDS_IndexedDataMapOfShapeWithState& aMapOfShapeWithStateTool= |
229 | aDS.ChangeMapOfShapeWithStateTool(); |
230 | |
231 | TopOpeBRepBuild_Tools::DumpMapOfShapeWithState(0, aMapOfShapeWithStateObj); |
232 | TopOpeBRepBuild_Tools::DumpMapOfShapeWithState(1, aMapOfShapeWithStateTool); |
233 | */ |
234 | |
235 | // Phase#2 Phase ON |
236 | // PerformOn2D (); |
237 | } |
238 | |
239 | //======================================================================= |
240 | //function :PerformShapeWithStates |
241 | //purpose : |
242 | //======================================================================= |
243 | void TopOpeBRepBuild_Builder1::PerformShapeWithStates (const TopoDS_Shape& anObj, |
244 | const TopoDS_Shape& aReference) |
245 | { |
246 | myShapeClassifier.SetReference(aReference); |
247 | TopOpeBRepDS_DataStructure& aDS= myDataStructure-> ChangeDS(); |
248 | // Get aMapOfShapeWithState for Obj |
249 | Standard_Boolean aFlag; |
250 | TopOpeBRepDS_IndexedDataMapOfShapeWithState& aMapOfShapeWithState= |
251 | aDS.ChangeMapOfShapeWithState(anObj, aFlag); |
252 | if (!aFlag) return; |
253 | // |
254 | Standard_Integer i, j, k, nS, nF, nE; |
255 | |
256 | TopTools_IndexedMapOfShape aFacesMap, aFacesWithInterferencesMap, aFacesToRestMap; |
257 | TopOpeBRepDS_DataMapOfShapeState aSplFacesState; |
258 | |
259 | TopTools_IndexedMapOfShape aShellsMap; |
260 | TopExp::MapShapes(anObj, TopAbs_SHELL, aShellsMap); |
261 | |
262 | nS=aShellsMap.Extent(); |
263 | for (i=1; i<=nS; i++) { |
264 | const TopoDS_Shape& aShell = aShellsMap(i); |
265 | |
266 | if (aMapOfShapeWithState.Contains (aShell)) continue; |
267 | |
268 | else if (!myDataStructure -> HasShape(aShell)) { |
269 | // Shell has no interference. |
270 | // So, define its state and push into the Map as is.// A.1 |
271 | TopOpeBRepBuild_Tools::FindStateThroughVertex (aShell, myShapeClassifier, |
272 | aMapOfShapeWithState, theUnkStateVer); |
273 | continue; |
274 | } |
275 | |
276 | else {// A.2 |
277 | // Shell has interference. Try to separate it into FacesToRest and InterferredFace |
278 | aFacesMap.Clear(); |
279 | aFacesWithInterferencesMap.Clear(); |
280 | aFacesToRestMap.Clear(); |
281 | aSplFacesState.Clear(); |
282 | |
283 | TopExp::MapShapes (aShell, TopAbs_FACE, aFacesMap); |
284 | nF=aFacesMap.Extent(); |
285 | for (j=1; j<=nF; j++) { |
286 | const TopoDS_Shape& aFace = aFacesMap(j); |
287 | |
288 | if (aMapOfShapeWithState.Contains (aFace)) { |
289 | |
290 | // if the face is known, its edges are also known. |
291 | // We just insert this info. into aSplFacesState in order to |
292 | // propagate the state for faces with unknown states. |
293 | TopTools_IndexedMapOfShape anEdgesMap; |
294 | TopExp::MapShapes (aFace, TopAbs_EDGE, anEdgesMap); |
295 | nE=anEdgesMap.Extent(); |
296 | for (k=1; k<=nE; k++) { |
297 | const TopoDS_Shape& anEdge=anEdgesMap(k); |
298 | const TopOpeBRepDS_ShapeWithState& aSWS= |
299 | aMapOfShapeWithState.FindFromKey(anEdge); |
300 | TopAbs_State aState=aSWS.State(); |
301 | aSplFacesState.Bind (anEdge, aState); |
302 | } |
303 | continue; |
304 | } |
305 | else if (myDataStructure -> HasShape(aFace)) |
306 | aFacesWithInterferencesMap.Add (aFace); |
307 | else { |
308 | aFacesToRestMap.Add (aFace); |
309 | } |
310 | } // ... next Face |
311 | // work with aFacesWithInterferencesMap |
312 | PerformFacesWithStates (anObj, aFacesWithInterferencesMap, aSplFacesState); |
313 | |
314 | // Propagate the States for all unknown faces from aFacesToRestMap |
315 | TopTools_MapOfShape anUnkStateEdge; |
316 | TopOpeBRepBuild_Tools::PropagateState (aSplFacesState,aFacesToRestMap, |
317 | TopAbs_EDGE, TopAbs_FACE, myShapeClassifier, |
318 | aMapOfShapeWithState, anUnkStateEdge); |
319 | ///// Propagate on WIres from aFacesToRestMap |
320 | TopOpeBRepBuild_Tools::PropagateStateForWires (aFacesToRestMap, aMapOfShapeWithState); |
321 | } // end of else A.2 |
322 | } // next Shell |
323 | } |
324 | |
325 | //======================================================================= |
326 | //function :PerformFacesWithStates |
327 | //purpose : |
328 | //======================================================================= |
329 | void TopOpeBRepBuild_Builder1::PerformFacesWithStates (const TopoDS_Shape& anObj, |
330 | const TopTools_IndexedMapOfShape& aFacesWithInterferencesMap, |
331 | TopOpeBRepDS_DataMapOfShapeState& aSplFacesState) |
332 | { |
333 | TopOpeBRepDS_DataStructure& aDS= myDataStructure-> ChangeDS(); |
334 | // Get aMapOfShapeWithState for Obj |
335 | Standard_Boolean aFlag; |
336 | TopOpeBRepDS_IndexedDataMapOfShapeWithState& aMapOfShapeWithState=aDS.ChangeMapOfShapeWithState(anObj, aFlag); |
337 | if (!aFlag) return; |
338 | // |
339 | |
340 | Standard_Integer i, j, k, nF, nW, nE; |
341 | |
342 | nF=aFacesWithInterferencesMap.Extent(); |
343 | |
344 | for (i=1; i<=nF; i++) { |
345 | TopTools_IndexedMapOfShape anEdgesToSplitMap, anEdgesToRestMap; |
346 | |
347 | const TopoDS_Shape& aFace = aFacesWithInterferencesMap(i); |
348 | |
349 | TopTools_IndexedMapOfShape aWireMap; |
350 | TopExp::MapShapes (aFace, TopAbs_WIRE, aWireMap); |
351 | nW=aWireMap.Extent(); |
352 | for (j=1; j<=nW; j++) { |
353 | const TopoDS_Shape& aWire=aWireMap(j); |
354 | |
355 | if (!myDataStructure -> HasShape(aWire)) { |
356 | // Wire has no interference. |
357 | // So, define its state and push into the Map as is. |
358 | TopOpeBRepBuild_Tools::FindStateThroughVertex (aWire, myShapeClassifier, |
359 | aMapOfShapeWithState, theUnkStateVer); |
360 | continue; |
361 | } |
362 | |
363 | else { |
364 | // Wire has an interferences |
365 | TopTools_IndexedMapOfShape anEdgeMap; |
366 | TopExp::MapShapes (aWire, TopAbs_EDGE, anEdgeMap); |
367 | nE=anEdgeMap.Extent (); |
368 | for (k=1; k<=nE; k++) { |
369 | const TopoDS_Shape& anEdge=anEdgeMap(k); |
370 | |
371 | if (myDataStructure -> HasShape(anEdge)) { |
372 | anEdgesToSplitMap.Add(anEdge); |
373 | } |
374 | else { |
375 | anEdgesToRestMap.Add(anEdge); |
376 | } |
377 | } |
378 | |
379 | // split edges and define the states for all edges and parts of edges |
380 | StatusEdgesToSplit (anObj, anEdgesToSplitMap, anEdgesToRestMap); |
381 | |
382 | ////// After StatusEdgesToSplit we can find the status of each Rest Edge |
383 | ////// in aMapOfShapeWithState. So we can insert this info. into |
384 | ////// aSplFacesState in order to propagate the state for faces. |
385 | nE=anEdgesToRestMap.Extent(); |
386 | for (k=1; k<=nE; k++) { |
387 | const TopoDS_Shape anEdge=anEdgesToRestMap(k); |
388 | if (aMapOfShapeWithState.Contains (anEdge)) { |
389 | const TopOpeBRepDS_ShapeWithState& aSWS=aMapOfShapeWithState.FindFromKey(anEdge); |
390 | TopAbs_State aState=aSWS.State(); |
391 | aSplFacesState.Bind (anEdge, aState); |
392 | } |
393 | } |
394 | } //end of else {// Wire has an interferences |
395 | } // next Wire |
396 | } // next interferred Face ... for (i=1; i<=nF; i++) ... |
397 | } |
398 | |
399 | //======================================================================= |
400 | //function :StatusEdgesToSplit |
401 | //purpose : |
402 | //======================================================================= |
403 | void TopOpeBRepBuild_Builder1::StatusEdgesToSplit (const TopoDS_Shape& anObj, |
404 | const TopTools_IndexedMapOfShape& anEdgesToSplitMap, |
405 | const TopTools_IndexedMapOfShape& anEdgesToRestMap) |
406 | { |
407 | |
408 | |
409 | TopOpeBRepDS_DataStructure& aDS= myDataStructure-> ChangeDS(); |
410 | // Get aMapOfShapeWithState for Obj |
411 | Standard_Boolean aFlag; |
412 | TopOpeBRepDS_IndexedDataMapOfShapeWithState& aMapOfShapeWithState=aDS.ChangeMapOfShapeWithState(anObj, aFlag); |
413 | if (!aFlag) return; |
414 | // |
415 | |
416 | Standard_Integer i, nE=anEdgesToSplitMap.Extent(); |
417 | if (!nE) return; |
418 | |
419 | TopOpeBRepDS_DataMapOfShapeState aSplEdgesState; |
420 | TopTools_ListIteratorOfListOfShape anIt; |
421 | TopAbs_State aState; |
422 | |
423 | for (i=1; i<=nE; i++) { |
424 | const TopoDS_Shape& anEdge=anEdgesToSplitMap(i); |
425 | |
426 | if(processedEdges.Contains(anEdge)) { |
427 | if (aMapOfShapeWithState.Contains(anEdge)) { |
428 | const TopOpeBRepDS_ShapeWithState& aSWS= |
429 | aMapOfShapeWithState.FindFromKey(anEdge); |
430 | if (aSWS.IsSplitted()) { |
431 | |
432 | const TopTools_ListOfShape& SplitsON=aSWS.Part(TopAbs_ON); |
433 | anIt.Initialize (SplitsON); |
434 | for (; anIt.More(); anIt.Next()) |
435 | aSplEdgesState.Bind(anIt.Value(), TopAbs_ON); |
436 | |
437 | const TopTools_ListOfShape& SplitsOUT=aSWS.Part(TopAbs_OUT); |
438 | anIt.Initialize (SplitsOUT); |
439 | for (; anIt.More(); anIt.Next()) |
440 | aSplEdgesState.Bind(anIt.Value(), TopAbs_OUT); |
441 | |
442 | const TopTools_ListOfShape& SplitsIN=aSWS.Part(TopAbs_IN); |
443 | anIt.Initialize (SplitsIN); |
444 | for (; anIt.More(); anIt.Next()) |
445 | aSplEdgesState.Bind(anIt.Value(), TopAbs_IN); |
446 | |
447 | } |
448 | } |
449 | continue; |
450 | } |
451 | |
452 | processedEdges.Add(anEdge); |
453 | |
454 | TopOpeBRepDS_ShapeWithState aShapeWithState; |
455 | |
456 | // if IsSplit - it is the case of edges from SameDomain faces |
457 | Standard_Boolean IsSplitON = IsSplit(anEdge, TopAbs_ON); |
458 | if(IsSplitON) { |
459 | // ON |
460 | const TopTools_ListOfShape& SplitsON = Splits(anEdge, TopAbs_ON); |
461 | anIt.Initialize (SplitsON); |
462 | for (; anIt.More(); anIt.Next()) { |
463 | TopoDS_Shape aNewEdge=anIt.Value(); |
464 | aNewEdge.Orientation (anEdge.Orientation()); |
465 | aShapeWithState.AddPart (aNewEdge, TopAbs_ON); |
466 | aSplEdgesState.Bind(anIt.Value(), TopAbs_ON); |
467 | } |
468 | |
469 | // IN |
470 | const TopTools_ListOfShape& SplitsIN = Splits(anEdge, TopAbs_IN); |
471 | anIt.Initialize (SplitsIN); |
472 | for (; anIt.More(); anIt.Next()) { |
473 | TopoDS_Shape aNewEdge=anIt.Value(); |
474 | aNewEdge.Orientation (anEdge.Orientation()); |
475 | aShapeWithState.AddPart (aNewEdge, TopAbs_IN); |
476 | aSplEdgesState.Bind(anIt.Value(), TopAbs_IN); |
477 | } |
478 | |
479 | // OUT |
480 | const TopTools_ListOfShape& SplitsOUT = Splits(anEdge, TopAbs_OUT); |
481 | anIt.Initialize (SplitsOUT); |
482 | for (; anIt.More(); anIt.Next()) { |
483 | TopoDS_Shape aNewEdge=anIt.Value(); |
484 | aNewEdge.Orientation (anEdge.Orientation()); |
485 | aShapeWithState.AddPart (aNewEdge, TopAbs_OUT); |
486 | aSplEdgesState.Bind(anIt.Value(), TopAbs_OUT); |
487 | } |
488 | |
489 | aShapeWithState.SetIsSplitted(Standard_True); |
490 | aMapOfShapeWithState.Add(anEdge, aShapeWithState); |
491 | continue; |
492 | } |
493 | |
494 | // Attempt to split the Edge (for all other edges (from non SameDomain Faces)) |
495 | TopOpeBRepDS_DataMapOfShapeState aDataMapOfShapeState; |
496 | TopTools_ListOfShape aLNew; |
497 | |
498 | Standard_Boolean oldState = GLOBAL_faces2d; |
499 | |
500 | GLOBAL_faces2d = Standard_True; |
501 | SplitEdge (anEdge, aLNew, aDataMapOfShapeState); |
502 | GLOBAL_faces2d = oldState; |
503 | |
504 | // |
505 | if (!aLNew.Extent()) { |
506 | // * It means that whole Edge is IN (see SplitEdge(...) at line |
507 | // G1=TopOpeBRepBuild_GTool::GFusSame(tf,tf); Operation Fuse |
508 | // loses all parts of the Edge with IN state, but we need |
509 | // to have all parts. So, we have to rest the Edge as is ... |
510 | // ** But the edge itself will have UNKNOWN state and one split Part with state =IN. |
511 | TopoDS_Vertex Vf, Vl; |
512 | TopExp::Vertices(TopoDS::Edge(anEdge), Vf, Vl); |
513 | |
514 | Standard_Boolean HasSDV1 = myDataStructure->HasSameDomain(Vf); |
515 | Standard_Boolean HasSDV2 = myDataStructure->HasSameDomain(Vl); |
516 | |
517 | TopoDS_Edge aNewEdge = TopoDS::Edge(anEdge); |
518 | |
519 | //if edge has SD edges , it is error because it must be processed in SplitSectionEdges |
520 | //but if we here we don't do anything with it |
521 | if(myDataStructure -> HasSameDomain(aNewEdge)) { |
522 | HasSDV1 = Standard_False; |
523 | HasSDV2 = Standard_False; |
524 | } |
525 | //if vertices has SD we must update edge, so we copy it |
526 | if(HasSDV1 || HasSDV2) { |
527 | TopoDS_Shape EOR = anEdge; |
528 | EOR.Orientation(TopAbs_FORWARD); |
529 | |
530 | Standard_Real ParF = BRep_Tool::Parameter(Vf, TopoDS::Edge(EOR)); |
531 | Standard_Real ParL = BRep_Tool::Parameter(Vl, TopoDS::Edge(EOR)); |
532 | myBuildTool.CopyEdge (EOR, aNewEdge); |
533 | |
534 | if (HasSDV1) { // on prend le vertex reference de V |
535 | Standard_Integer iref = myDataStructure->SameDomainReference(Vf); |
536 | Vf = TopoDS::Vertex(myDataStructure->Shape(iref)); |
537 | Vf.Orientation(TopAbs_FORWARD); |
538 | } |
539 | |
540 | if (HasSDV2) { // on prend le vertex reference de V |
541 | Standard_Integer iref = myDataStructure->SameDomainReference(Vl); |
542 | Vl = TopoDS::Vertex(myDataStructure->Shape(iref)); |
543 | Vl.Orientation(TopAbs_REVERSED); |
544 | } |
545 | Standard_Boolean bitclosed = Vf.IsSame(Vl); |
546 | aNewEdge.Closed(bitclosed); |
547 | |
548 | myBuildTool.AddEdgeVertex (aNewEdge, Vf); |
549 | myBuildTool.Parameter (aNewEdge, Vf, ParF); |
550 | |
551 | myBuildTool.AddEdgeVertex (aNewEdge, Vl); |
552 | myBuildTool.Parameter (aNewEdge, Vl, ParL); |
553 | |
554 | aNewEdge.Orientation (anEdge.Orientation()); |
555 | } |
556 | |
557 | aState= ClassifyEdgeToSolidByOnePoint(aNewEdge, myShapeClassifier); |
558 | aShapeWithState.SetIsSplitted (Standard_True); |
559 | |
560 | aShapeWithState.AddPart (aNewEdge, aState); |
561 | aSplEdgesState.Bind(aNewEdge, aState); |
562 | |
563 | TopExp::Vertices(aNewEdge, Vf, Vl); |
564 | theUsedVertexMap.Add(Vf); |
565 | theUsedVertexMap.Add(Vl); |
566 | if (!BRep_Tool::Degenerated(TopoDS::Edge(aNewEdge))) { |
567 | // MSV: it may be the case when an edge has one state but its vertex |
568 | // has another state. We should clarify this to avoid incorrect |
569 | // propagation of state. |
570 | myShapeClassifier.StateP3DReference(BRep_Tool::Pnt(Vf)); |
571 | if (myShapeClassifier.State() != aState && myShapeClassifier.State() != TopAbs_ON) |
572 | theUnkStateVer.Add(Vf); |
573 | if (!Vf.IsSame(Vl)) { |
574 | myShapeClassifier.StateP3DReference(BRep_Tool::Pnt(Vl)); |
575 | if (myShapeClassifier.State() != aState && myShapeClassifier.State() != TopAbs_ON) |
576 | theUnkStateVer.Add(Vl); |
577 | } |
578 | } |
579 | } |
580 | else { |
581 | // Usual case. The Edge was splitted onto several parts: |
582 | TopTools_ListIteratorOfListOfShape aLIt(aLNew); |
583 | for (; aLIt.More(); aLIt.Next()) { |
584 | const TopoDS_Shape& aS = aLIt.Value(); |
585 | aState = aDataMapOfShapeState(aS); |
586 | //////////////////////////////////////////////////////////////////////////// |
587 | // ** When aState==TopAbs_IN it is not evidence that it is realy so. |
588 | // There are some cases when JYL does not define ON parts completely. |
589 | // So, as we want to have right states, we have to do it ourselves. |
590 | // PKV Mon 25 Oct 1999 |
591 | Standard_Boolean isdegen = BRep_Tool::Degenerated(TopoDS::Edge(aS)); |
592 | //if edge is degenerated we trust that it have IN state without classify |
593 | |
594 | if (aState==TopAbs_IN && !isdegen) |
595 | aState= ClassifyEdgeToSolidByOnePoint(TopoDS::Edge(aS), myShapeClassifier); |
596 | |
597 | //////////////////////////////////////////////////////////////////////////// |
598 | aShapeWithState.AddPart (aS, aState); |
599 | aShapeWithState.SetIsSplitted (Standard_True); |
600 | |
601 | aSplEdgesState.Bind(aS, aState); |
602 | TopoDS_Vertex Vf, Vl; |
603 | TopExp::Vertices(TopoDS::Edge(aS), Vf, Vl); |
604 | theUsedVertexMap.Add(Vf); |
605 | theUsedVertexMap.Add(Vl); |
606 | if (!isdegen) { |
607 | // MSV: clarify state of vertices (see my above comment) |
608 | myShapeClassifier.StateP3DReference(BRep_Tool::Pnt(Vf)); |
609 | if (myShapeClassifier.State() != aState && myShapeClassifier.State() != TopAbs_ON) |
610 | theUnkStateVer.Add(Vf); |
611 | if (!Vf.IsSame(Vl)) { |
612 | myShapeClassifier.StateP3DReference(BRep_Tool::Pnt(Vl)); |
613 | if (myShapeClassifier.State() != aState && myShapeClassifier.State() != TopAbs_ON) |
614 | theUnkStateVer.Add(Vl); |
615 | } |
616 | } |
617 | } |
618 | } |
619 | |
620 | const TopTools_ListOfShape& EspON = aShapeWithState.Part(TopAbs_ON); |
621 | |
622 | Standard_Integer nON = EspON.Extent(); |
623 | if(!IsSplitON && nON) { |
624 | TopOpeBRepDS_ListOfShapeOn1State ONspl; |
625 | TopTools_ListOfShape& lON = ONspl.ChangeListOnState(); |
626 | lON.Assign(EspON); |
627 | ONspl.Split(Standard_True); |
628 | mySplitON.Bind(anEdge, ONspl); |
629 | myDataStructure -> ChangeDS().AddSectionEdge(TopoDS::Edge(anEdge)); |
630 | } |
631 | |
632 | aMapOfShapeWithState.Add(anEdge, aShapeWithState); |
633 | } // end for (i=1; i<=nE; i++) |
634 | |
635 | nE=anEdgesToRestMap.Extent(); |
636 | for (i=1; i<=nE; i++) { |
637 | const TopoDS_Shape& anEdge=anEdgesToRestMap.FindKey(i); |
638 | if (aMapOfShapeWithState.Contains (anEdge)) { |
639 | const TopOpeBRepDS_ShapeWithState& aSWS= |
640 | aMapOfShapeWithState.FindFromKey(anEdge); |
641 | if (!aSWS.IsSplitted()) { |
642 | // just in case |
643 | aState=aSWS.State(); |
644 | aSplEdgesState.Bind (anEdge, aState); |
645 | continue; |
646 | } |
647 | } |
648 | } |
649 | |
650 | if (nE) |
651 | // Propagate the status for anEdgesToRestMap edges |
652 | TopOpeBRepBuild_Tools::PropagateState (aSplEdgesState, anEdgesToRestMap, |
653 | TopAbs_VERTEX, TopAbs_EDGE, myShapeClassifier, |
654 | aMapOfShapeWithState, theUnkStateVer); |
655 | |
656 | } |
657 | |
658 | |
659 | |
660 | //======================================================================= |
661 | //function : SplitEdge |
662 | //purpose : |
663 | //======================================================================= |
664 | void TopOpeBRepBuild_Builder1::SplitEdge (const TopoDS_Shape& anEdge, |
665 | TopTools_ListOfShape& aLNew, |
666 | TopOpeBRepDS_DataMapOfShapeState& aDataMapOfShapeState) |
667 | { |
668 | Standard_Real aPar1, aPar2; |
669 | TopAbs_Orientation anOr1, anOr2; |
670 | |
671 | // Attention! If you didn't do the orientation of the Edge =FORWARD, |
672 | // the GFillPointTopologyPVS() method will give you a garbage! |
673 | TopoDS_Shape EdgeF=anEdge; |
674 | EdgeF.Orientation(TopAbs_FORWARD); |
675 | |
676 | // Make a PaveSet PVS on edge EF |
677 | TopOpeBRepBuild_PaveSet PVS (EdgeF); |
678 | TopOpeBRepBuild_GTopo G1; |
679 | TopAbs_ShapeEnum tf = TopAbs_FACE; |
680 | G1=TopOpeBRepBuild_GTool::GFusSame(tf,tf); |
681 | myEdgeReference = TopoDS::Edge(EdgeF); |
682 | |
683 | GFillPointTopologyPVS(EdgeF, G1, PVS); |
684 | |
685 | PVS.InitLoop(); |
686 | |
687 | //firstly we detect paves with equal params |
688 | |
689 | // MSV Oct 23, 2001: |
690 | // Add Paves to a standard list rather than to a PaveSet to avoid |
691 | // possible sequence disturbance in InitLoop. |
692 | // Check points for equality in both 3d and 1d spaces using maximum |
693 | // of tolerances of the edge and compared vertices, in 1d using resolution |
694 | // on edge from that value |
695 | |
696 | TopOpeBRepBuild_ListOfPave aPVSlist; |
697 | TopTools_DataMapOfShapeListOfInteger aVerOriMap; |
698 | |
699 | BRepAdaptor_Curve aCurveAdaptor(TopoDS::Edge(anEdge)); |
700 | Standard_Real tolEdge = BRep_Tool::Tolerance(TopoDS::Edge(anEdge)); |
701 | |
702 | while (PVS.MoreLoop()) { |
703 | Handle(TopOpeBRepBuild_Pave) aPave1=Handle(TopOpeBRepBuild_Pave)::DownCast(PVS.Loop()); |
704 | const TopoDS_Vertex& aV1= TopoDS::Vertex(aPave1->Vertex()); |
705 | aPar1 = aPave1->Parameter(); |
706 | |
707 | PVS.NextLoop(); |
708 | if (!PVS.MoreLoop()) { |
709 | aPVSlist.Append(aPave1); |
710 | break; |
711 | } |
712 | |
713 | Handle(TopOpeBRepBuild_Pave) aPave2=Handle(TopOpeBRepBuild_Pave)::DownCast(PVS.Loop()); |
714 | const TopoDS_Vertex& aV2= TopoDS::Vertex(aPave2->Vertex()); |
715 | aPar2 = aPave2->Parameter(); |
716 | |
717 | Standard_Real tolV1 = BRep_Tool::Tolerance(aV1); |
718 | Standard_Real tolV2 = BRep_Tool::Tolerance(aV2); |
719 | Standard_Real tolMax = Max(tolEdge,Max(tolV1,tolV2)); |
720 | Standard_Real resol = aCurveAdaptor.Resolution(tolMax); |
721 | Standard_Real delta = Abs(aPar1 - aPar2); |
722 | |
723 | if(delta < resol) { |
724 | Standard_Real dist = BRep_Tool::Pnt(aV1).Distance(BRep_Tool::Pnt(aV2)); |
725 | if (dist < tolMax || delta < Precision::PConfusion()) { |
726 | |
727 | TopOpeBRepDS_Kind IntType1 = aPave1 -> InterferenceType(); |
728 | Standard_Boolean Int3d1 = (IntType1 == TopOpeBRepDS_FACE); |
729 | Standard_Boolean HasSDV1 = myDataStructure->HasSameDomain(aV1); |
730 | Standard_Boolean HasSDV2 = myDataStructure->HasSameDomain(aV2); |
731 | Standard_Boolean UsedV1 = theUsedVertexMap.Contains(aV1); |
732 | Standard_Boolean UsedV2 = theUsedVertexMap.Contains(aV2); |
733 | |
734 | Standard_Boolean takeFirst = Standard_True; |
735 | if(HasSDV1) ; |
736 | else if(HasSDV2) takeFirst = Standard_False; |
737 | else if(UsedV1) ; |
738 | else if(UsedV2) takeFirst = Standard_False; |
739 | else if(Int3d1) ; |
740 | else takeFirst = Standard_False; |
741 | TopoDS_Shape aVer; |
742 | Standard_Boolean HasSDV; |
743 | TopAbs_Orientation anOriOpp; |
744 | if (takeFirst) { |
745 | aPVSlist.Append(aPave1); |
746 | aVer = aV1; HasSDV = HasSDV1; anOriOpp = aV2.Orientation(); |
747 | } |
748 | else { |
749 | aPVSlist.Append(aPave2); |
750 | aVer = aV2; HasSDV = HasSDV2; anOriOpp = aV1.Orientation(); |
751 | } |
752 | |
753 | if (aV1.Orientation() != aV2.Orientation()) { |
754 | // MSV: save orientation of removed vertex |
755 | TColStd_ListOfInteger thelist; |
756 | if (!aVerOriMap.IsBound(aVer)) aVerOriMap.Bind(aVer, thelist); |
757 | TColStd_ListOfInteger& anOriList = aVerOriMap(aVer); |
758 | anOriList.Append(takeFirst); |
759 | anOriList.Append(anOriOpp); |
760 | // mark this vertex as having unknown state |
761 | if (HasSDV) { |
762 | Standard_Integer iref = myDataStructure->SameDomainReference(aVer); |
763 | aVer = myDataStructure->Shape(iref); |
764 | } |
765 | theUnkStateVer.Add(aVer); |
766 | } |
767 | |
768 | PVS.NextLoop(); |
769 | continue; |
770 | } |
771 | } |
772 | aPVSlist.Append(aPave1); |
773 | } |
774 | |
775 | TopOpeBRepBuild_ListIteratorOfListOfPave aPVSit(aPVSlist); |
776 | while (aPVSit.More()) { |
777 | Handle(TopOpeBRepBuild_Pave) aPave1 = aPVSit.Value(); |
778 | TopoDS_Shape aV1= aPave1->Vertex(); |
779 | aV1.Orientation(TopAbs_FORWARD); |
780 | aPar1 = aPave1->Parameter(); |
781 | anOr1=(aPave1->Vertex()).Orientation(); |
782 | if (aVerOriMap.IsBound(aV1)) { |
783 | // MSV: restore orientation of removed vertex |
784 | TColStd_ListOfInteger& anOriList = aVerOriMap(aV1); |
785 | if (!anOriList.IsEmpty()) { |
786 | if (anOriList.First()) { |
787 | TColStd_ListIteratorOfListOfInteger it(anOriList); it.Next(); |
788 | anOr1 = (TopAbs_Orientation) it.Value(); |
789 | } |
790 | anOriList.RemoveFirst(); anOriList.RemoveFirst(); |
791 | } |
792 | } |
793 | |
794 | aPVSit.Next(); |
795 | |
796 | if (!aPVSit.More()) break; |
797 | |
798 | Handle(TopOpeBRepBuild_Pave) aPave2 = aPVSit.Value(); |
799 | TopoDS_Shape aV2= aPave2->Vertex(); |
800 | aV2.Orientation(TopAbs_REVERSED); |
801 | aPar2 = aPave2->Parameter(); |
802 | anOr2=(aPave2->Vertex()).Orientation(); |
803 | if (aVerOriMap.IsBound(aV2)) { |
804 | TColStd_ListOfInteger& anOriList = aVerOriMap(aV2); |
805 | if (!anOriList.IsEmpty()) { |
806 | if (!anOriList.First()) { |
807 | TColStd_ListIteratorOfListOfInteger it(anOriList); it.Next(); |
808 | anOr2 = (TopAbs_Orientation) it.Value(); |
809 | } |
810 | } |
811 | } |
812 | |
813 | // MSV: avoid creation of an edge with invalid range |
814 | if (aPar1 > aPar2) continue; |
815 | |
816 | Standard_Boolean HasSDV1 = myDataStructure->HasSameDomain(aV1); |
817 | Standard_Boolean HasSDV2 = myDataStructure->HasSameDomain(aV2); |
818 | if (HasSDV1) { // on prend le vertex reference de V |
819 | Standard_Integer iref = myDataStructure->SameDomainReference(aV1); |
820 | aV1 = myDataStructure->Shape(iref); |
821 | aV1.Orientation(TopAbs_FORWARD); |
822 | } |
823 | |
824 | if (HasSDV2) { // on prend le vertex reference de V |
825 | Standard_Integer iref = myDataStructure->SameDomainReference(aV2); |
826 | aV2 = myDataStructure->Shape(iref); |
827 | aV2.Orientation(TopAbs_REVERSED); |
828 | } |
829 | |
830 | // Make new edge from EdgeF |
831 | TopoDS_Edge aNewEdge; |
832 | myBuildTool.CopyEdge (EdgeF, aNewEdge); |
833 | |
834 | Standard_Boolean bitclosed = aV1.IsSame(aV2); |
835 | aNewEdge.Closed(bitclosed); |
836 | |
837 | myBuildTool.AddEdgeVertex (aNewEdge, aV1); |
838 | myBuildTool.Parameter (aNewEdge, aV1, aPar1); |
839 | |
840 | myBuildTool.AddEdgeVertex (aNewEdge, aV2); |
841 | myBuildTool.Parameter (aNewEdge, aV2, aPar2); |
842 | // State of piece |
843 | |
844 | |
845 | TopAbs_State aState=TopAbs_IN; |
846 | |
847 | if (anOr1==TopAbs_FORWARD && anOr2==TopAbs_REVERSED) aState=TopAbs_OUT; |
848 | if (anOr1==TopAbs_FORWARD && anOr2==TopAbs_INTERNAL) aState=TopAbs_OUT; |
849 | if (anOr1==TopAbs_INTERNAL && anOr2==TopAbs_REVERSED) aState=TopAbs_OUT; |
850 | ///* Added |
851 | if (anOr1==TopAbs_INTERNAL && anOr2==TopAbs_INTERNAL) aState=TopAbs_OUT; |
852 | //printf(" anOr1=%d, anOr2=%d\n", anOr1, anOr2); |
853 | |
854 | // set old orientation to new edge; |
855 | aNewEdge.Orientation (anEdge.Orientation()); |
856 | aLNew.Append(aNewEdge); |
857 | aDataMapOfShapeState.Bind(aNewEdge, aState); |
858 | } |
859 | //GEDBUMakeEdges(EdgeF,EDBU,aListOfShape); |
860 | } |
861 | |
862 | static TopAbs_State ClassifyEdgeToSolidByOnePoint(const TopoDS_Edge& E, |
863 | TopOpeBRepTool_ShapeClassifier& SC) |
864 | { |
865 | Standard_Real f2 = 0., l2 = 0., par = 0.; |
866 | |
867 | Handle(Geom_Curve) C3D = BRep_Tool::Curve(E, f2, l2); |
868 | gp_Pnt aP3d; |
869 | |
870 | if(C3D.IsNull()) { |
871 | //it means that we are in degenerated edge |
872 | const TopoDS_Vertex& fv = TopExp::FirstVertex(E); |
873 | if(fv.IsNull()) |
874 | return TopAbs_UNKNOWN; |
875 | aP3d = BRep_Tool::Pnt(fv); |
876 | } |
877 | else {//usual case |
878 | par = f2*PAR_T + (1 - PAR_T)*l2; |
879 | C3D -> D0(par, aP3d); |
880 | } |
881 | |
882 | SC.StateP3DReference(aP3d); |
883 | |
884 | return SC.State(); |
885 | } |