1 // Created on: 1999-10-07
2 // Created by: Peter KURNEV
3 // Copyright (c) 1999-1999 Matra Datavision
4 // Copyright (c) 1999-2012 OPEN CASCADE SAS
6 // The content of this file is subject to the Open CASCADE Technology Public
7 // License Version 6.5 (the "License"). You may not use the content of this file
8 // except in compliance with the License. Please obtain a copy of the License
9 // at http://www.opencascade.org and read it completely before using this file.
11 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
12 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
14 // The Original Code and all software distributed under the License is
15 // distributed on an "AS IS" basis, without warranty of any kind, and the
16 // Initial Developer hereby disclaims all such warranties, including without
17 // limitation, any warranties of merchantability, fitness for a particular
18 // purpose or non-infringement. Please see the License for the specific terms
19 // and conditions governing the rights and limitations under the License.
22 #include <TopOpeBRepBuild_Builder.ixx>
24 #include <BRepTools.hxx>
25 #include <BRep_Builder.hxx>
30 #include <TopoDS_Vertex.hxx>
31 #include <TopoDS_Wire.hxx>
33 #include <TopTools_MapOfShape.hxx>
34 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
35 #include <TopTools_MapIteratorOfMapOfShape.hxx>
36 #include <TopTools_IndexedMapOfShape.hxx>
38 #include <TopOpeBRepBuild_PaveSet.hxx>
39 #include <TopOpeBRepBuild_GTool.hxx>
40 #include <TopOpeBRepBuild_Pave.hxx>
41 #include <TopOpeBRepBuild_Loop.hxx>
42 #include <TopOpeBRepBuild_EdgeBuilder.hxx>
43 #include <TopOpeBRepBuild_ListOfListOfLoop.hxx>
44 #include <TopOpeBRepBuild_Tools.hxx>
45 #include <TopOpeBRepBuild_GTopo.hxx>
47 #include <TopOpeBRepDS_DataMapOfShapeState.hxx>
48 #include <TopOpeBRepDS_DataMapIteratorOfDataMapOfShapeState.hxx>
49 #include <TopOpeBRepDS_Interference.hxx>
50 #include <TopOpeBRepDS_ListOfInterference.hxx>
51 #include <TopOpeBRepDS_ListIteratorOfListOfInterference.hxx>
52 #include <TopOpeBRepDS_IndexedDataMapOfShapeWithState.hxx>
53 #include <TopOpeBRepDS_ShapeWithState.hxx>
54 #include <TopOpeBRepDS_DataStructure.hxx>
55 #include <BRep_Tool.hxx>
56 #include <TopOpeBRepDS_ListOfShapeOn1State.hxx>
57 #include <Geom_Curve.hxx>
58 #include <Precision.hxx>
59 #include <BRepAdaptor_Curve.hxx>
60 #include <TopTools_DataMapOfShapeListOfInteger.hxx>
61 #include <TColStd_ListIteratorOfListOfInteger.hxx>
63 //define parameter division number as 10*e^(-PI) = 0.43213918
64 const Standard_Real PAR_T = 0.43213918;
66 static TopAbs_State ClassifyEdgeToSolidByOnePoint(const TopoDS_Edge& E,
67 TopOpeBRepTool_ShapeClassifier& SC);
69 //=======================================================================
70 // : Definition the States of Shape's Entities for an Object
71 // : and a Tool. Thu Oct 7 09:38:29 1999
72 //=======================================================================
74 static TopTools_IndexedMapOfShape processedEdges;
75 static TopTools_IndexedMapOfShape theUsedVertexMap;
76 static TopTools_MapOfShape theUnkStateVer;
78 extern Standard_Boolean GLOBAL_faces2d;
80 //modified by NIZNHY-PKV Mon Dec 16 11:38:55 2002 f
81 //=======================================================================
84 //=======================================================================
85 void TopOpeBRepBuild_Builder1::Destroy()
87 processedEdges.Clear();
88 theUsedVertexMap.Clear();
89 theUnkStateVer.Clear();
91 //modified by NIZNHY-PKV Mon Dec 16 11:38:59 2002 t
93 //=======================================================================
94 //function : PerformShapeWithStates
96 //=======================================================================
97 void TopOpeBRepBuild_Builder1::PerformShapeWithStates()
99 theUsedVertexMap.Clear();
100 theUnkStateVer.Clear();
101 myDataStructure -> ChangeDS().ChangeMapOfShapeWithStateObj().Clear();
102 myDataStructure -> ChangeDS().ChangeMapOfShapeWithStateTool().Clear();
103 //modified by NIZHNY-MZV Mon Feb 21 13:30:05 2000
104 //process section curves
105 Standard_Integer i, nbC = myDataStructure -> DS().NbCurves();
106 for(i = 1; i <= nbC; i++) {
107 TopTools_ListOfShape& LSE = ChangeNewEdges(i);
108 TopTools_ListIteratorOfListOfShape it(LSE);
109 for(; it.More(); it.Next()) {
110 const TopoDS_Shape& E = it.Value();
111 TopoDS_Vertex Vf, Vl;
112 TopExp::Vertices(TopoDS::Edge(E), Vf, Vl);
113 theUsedVertexMap.Add(Vf);
114 theUsedVertexMap.Add(Vl);
118 //process section edges
119 const TopOpeBRepDS_DataStructure& BDS = myDataStructure->DS();
120 Standard_Integer n = BDS.NbSectionEdges();
121 for (i = 1; i <= n; i++) {
122 TopTools_ListIteratorOfListOfShape anIt;
123 const TopoDS_Edge& E = TopoDS::Edge(BDS.SectionEdge(i));
124 if(E.IsNull()) continue;
126 const TopTools_ListOfShape& SplitsON = Splits(E, TopAbs_ON);
127 anIt.Initialize (SplitsON);
128 for (; anIt.More(); anIt.Next()) {
129 TopoDS_Shape aNewEdge=anIt.Value();
130 TopoDS_Vertex Vf, Vl;
131 TopExp::Vertices(TopoDS::Edge(aNewEdge), Vf, Vl);
132 theUsedVertexMap.Add(Vf);
133 theUsedVertexMap.Add(Vl);
137 const TopTools_ListOfShape& SplitsIN = Splits(E, TopAbs_IN);
138 anIt.Initialize (SplitsIN);
139 for (; anIt.More(); anIt.Next()) {
140 TopoDS_Shape aNewEdge=anIt.Value();
141 TopoDS_Vertex Vf, Vl;
142 TopExp::Vertices(TopoDS::Edge(aNewEdge), Vf, Vl);
143 theUsedVertexMap.Add(Vf);
144 theUsedVertexMap.Add(Vl);
148 const TopTools_ListOfShape& SplitsOUT = Splits(E, TopAbs_OUT);
149 anIt.Initialize (SplitsOUT);
150 for (; anIt.More(); anIt.Next()) {
151 TopoDS_Shape aNewEdge=anIt.Value();
152 TopoDS_Vertex Vf, Vl;
153 TopExp::Vertices(TopoDS::Edge(aNewEdge), Vf, Vl);
154 theUsedVertexMap.Add(Vf);
155 theUsedVertexMap.Add(Vl);
159 //modified by NIZHNY-MZV Tue Apr 11 17:32:05 2000
160 //1) Add both arguments to facilitate the search
161 TopOpeBRepDS_ShapeWithState aShapeWithState;
162 TopOpeBRepDS_DataStructure& aDataStructure=myDataStructure->ChangeDS();
164 TopOpeBRepDS_IndexedDataMapOfShapeWithState& aMapOfShapeWithStateObj=
165 aDataStructure.ChangeMapOfShapeWithStateObj();
166 TopOpeBRepDS_IndexedDataMapOfShapeWithState& aMapOfShapeWithStateTool=
167 aDataStructure.ChangeMapOfShapeWithStateTool();
169 aMapOfShapeWithStateObj.Add(myShape1, aShapeWithState);
170 aMapOfShapeWithStateTool.Add(myShape2, aShapeWithState);
172 //2) Add all rejected shapes as OUT
174 TopTools_IndexedMapOfShape& aMapOfRejectedShapesObj=
175 aDataStructure.ChangeMapOfRejectedShapesObj();
176 TopTools_IndexedMapOfShape& aMapOfRejectedShapesTool=
177 aDataStructure.ChangeMapOfRejectedShapesTool();
179 aShapeWithState.SetIsSplitted (Standard_False);
180 aShapeWithState.SetState (TopAbs_OUT);
182 Standard_Integer iW, j, nW, nE,
183 nRSObj = aMapOfRejectedShapesObj.Extent(),
184 nRSTool = aMapOfRejectedShapesTool.Extent();
186 for(i = 1; i <= nRSObj; i++) {
187 const TopoDS_Shape& aFace = aMapOfRejectedShapesObj(i);
188 if(aFace.ShapeType() != TopAbs_FACE)
190 TopTools_IndexedMapOfShape aWiresMap;
192 TopExp::MapShapes (aFace, TopAbs_WIRE, aWiresMap);
193 nW=aWiresMap.Extent ();
194 for (iW=1; iW<=nW; iW++) {
195 const TopoDS_Shape& aWire=aWiresMap(iW);
197 TopTools_IndexedMapOfShape anEdgesMap;
198 TopExp::MapShapes (aWire, TopAbs_EDGE, anEdgesMap);
199 nE=anEdgesMap.Extent ();
200 for (j=1; j<=nE; j++)
201 aMapOfShapeWithStateObj.Add(anEdgesMap(j), aShapeWithState); // add edge
203 aMapOfShapeWithStateObj.Add(aWire, aShapeWithState); // add wire
205 aMapOfShapeWithStateObj.Add(aFace, aShapeWithState); // add face
208 for(i = 1; i <= nRSTool; i++) {
209 const TopoDS_Shape& aFace = aMapOfRejectedShapesTool(i);
210 //modified by NIZHNY-MZV Wed Apr 5 10:27:18 2000
211 if(aFace.ShapeType() != TopAbs_FACE)
213 TopTools_IndexedMapOfShape aWiresMap;
214 TopExp::MapShapes (aFace, TopAbs_WIRE, aWiresMap);
215 nW=aWiresMap.Extent ();
216 for (iW=1; iW<=nW; iW++) {
217 const TopoDS_Shape& aWire=aWiresMap(iW);
219 TopTools_IndexedMapOfShape anEdgesMap;
220 TopExp::MapShapes (aWire, TopAbs_EDGE, anEdgesMap);
221 nE=anEdgesMap.Extent ();
222 for (j=1; j<=nE; j++)
223 aMapOfShapeWithStateTool.Add(anEdgesMap(j), aShapeWithState); // add edge
225 aMapOfShapeWithStateTool.Add(aWire, aShapeWithState); // add wire
227 aMapOfShapeWithStateTool.Add(aFace, aShapeWithState); // add face
230 PerformShapeWithStates (myShape1, myShape2);
231 processedEdges.Clear();
232 PerformShapeWithStates (myShape2, myShape1);
233 processedEdges.Clear();
235 // printf(" ..::PerformShapeWithStates() [Dump is off]\n");
237 /* printf(" ..::PerformShapeWithStates() [Dump is on]\n");
239 TopOpeBRepDS_DataStructure& aDS= myDataStructure-> ChangeDS();
241 TopOpeBRepDS_IndexedDataMapOfShapeWithState& aMapOfShapeWithStateObj=
242 aDS.ChangeMapOfShapeWithStateObj();
244 TopOpeBRepDS_IndexedDataMapOfShapeWithState& aMapOfShapeWithStateTool=
245 aDS.ChangeMapOfShapeWithStateTool();
247 TopOpeBRepBuild_Tools::DumpMapOfShapeWithState(0, aMapOfShapeWithStateObj);
248 TopOpeBRepBuild_Tools::DumpMapOfShapeWithState(1, aMapOfShapeWithStateTool);
255 //=======================================================================
256 //function :PerformShapeWithStates
258 //=======================================================================
259 void TopOpeBRepBuild_Builder1::PerformShapeWithStates (const TopoDS_Shape& anObj,
260 const TopoDS_Shape& aReference)
262 myShapeClassifier.SetReference(aReference);
263 TopOpeBRepDS_DataStructure& aDS= myDataStructure-> ChangeDS();
264 // Get aMapOfShapeWithState for Obj
265 Standard_Boolean aFlag;
266 TopOpeBRepDS_IndexedDataMapOfShapeWithState& aMapOfShapeWithState=
267 aDS.ChangeMapOfShapeWithState(anObj, aFlag);
270 Standard_Integer i, j, k, nS, nF, nE;
272 TopTools_IndexedMapOfShape aFacesMap, aFacesWithInterferencesMap, aFacesToRestMap;
273 TopOpeBRepDS_DataMapOfShapeState aSplFacesState;
275 TopTools_IndexedMapOfShape aShellsMap;
276 TopExp::MapShapes(anObj, TopAbs_SHELL, aShellsMap);
278 nS=aShellsMap.Extent();
279 for (i=1; i<=nS; i++) {
280 const TopoDS_Shape& aShell = aShellsMap(i);
282 if (aMapOfShapeWithState.Contains (aShell)) continue;
284 else if (!myDataStructure -> HasShape(aShell)) {
285 // Shell has no interference.
286 // So, define its state and push into the Map as is.// A.1
287 TopOpeBRepBuild_Tools::FindStateThroughVertex (aShell, myShapeClassifier,
288 aMapOfShapeWithState, theUnkStateVer);
293 // Shell has interference. Try to separate it into FacesToRest and InterferredFace
295 aFacesWithInterferencesMap.Clear();
296 aFacesToRestMap.Clear();
297 aSplFacesState.Clear();
299 TopExp::MapShapes (aShell, TopAbs_FACE, aFacesMap);
300 nF=aFacesMap.Extent();
301 for (j=1; j<=nF; j++) {
302 const TopoDS_Shape& aFace = aFacesMap(j);
304 if (aMapOfShapeWithState.Contains (aFace)) {
306 // if the face is known, its edges are also known.
307 // We just insert this info. into aSplFacesState in order to
308 // propagate the state for faces with unknown states.
309 TopTools_IndexedMapOfShape anEdgesMap;
310 TopExp::MapShapes (aFace, TopAbs_EDGE, anEdgesMap);
311 nE=anEdgesMap.Extent();
312 for (k=1; k<=nE; k++) {
313 const TopoDS_Shape& anEdge=anEdgesMap(k);
314 const TopOpeBRepDS_ShapeWithState& aSWS=
315 aMapOfShapeWithState.FindFromKey(anEdge);
316 TopAbs_State aState=aSWS.State();
317 aSplFacesState.Bind (anEdge, aState);
321 else if (myDataStructure -> HasShape(aFace))
322 aFacesWithInterferencesMap.Add (aFace);
324 aFacesToRestMap.Add (aFace);
327 // work with aFacesWithInterferencesMap
328 PerformFacesWithStates (anObj, aFacesWithInterferencesMap, aSplFacesState);
330 // Propagate the States for all unknown faces from aFacesToRestMap
331 TopTools_MapOfShape anUnkStateEdge;
332 TopOpeBRepBuild_Tools::PropagateState (aSplFacesState,aFacesToRestMap,
333 TopAbs_EDGE, TopAbs_FACE, myShapeClassifier,
334 aMapOfShapeWithState, anUnkStateEdge);
335 ///// Propagate on WIres from aFacesToRestMap
336 TopOpeBRepBuild_Tools::PropagateStateForWires (aFacesToRestMap, aMapOfShapeWithState);
341 //=======================================================================
342 //function :PerformFacesWithStates
344 //=======================================================================
345 void TopOpeBRepBuild_Builder1::PerformFacesWithStates (const TopoDS_Shape& anObj,
346 const TopTools_IndexedMapOfShape& aFacesWithInterferencesMap,
347 TopOpeBRepDS_DataMapOfShapeState& aSplFacesState)
349 TopOpeBRepDS_DataStructure& aDS= myDataStructure-> ChangeDS();
350 // Get aMapOfShapeWithState for Obj
351 Standard_Boolean aFlag;
352 TopOpeBRepDS_IndexedDataMapOfShapeWithState& aMapOfShapeWithState=aDS.ChangeMapOfShapeWithState(anObj, aFlag);
356 Standard_Integer i, j, k, nF, nW, nE;
358 nF=aFacesWithInterferencesMap.Extent();
360 for (i=1; i<=nF; i++) {
361 TopTools_IndexedMapOfShape anEdgesToSplitMap, anEdgesToRestMap;
363 const TopoDS_Shape& aFace = aFacesWithInterferencesMap(i);
365 TopTools_IndexedMapOfShape aWireMap;
366 TopExp::MapShapes (aFace, TopAbs_WIRE, aWireMap);
367 nW=aWireMap.Extent();
368 for (j=1; j<=nW; j++) {
369 const TopoDS_Shape& aWire=aWireMap(j);
371 if (!myDataStructure -> HasShape(aWire)) {
372 // Wire has no interference.
373 // So, define its state and push into the Map as is.
374 TopOpeBRepBuild_Tools::FindStateThroughVertex (aWire, myShapeClassifier,
375 aMapOfShapeWithState, theUnkStateVer);
380 // Wire has an interferences
381 TopTools_IndexedMapOfShape anEdgeMap;
382 TopExp::MapShapes (aWire, TopAbs_EDGE, anEdgeMap);
383 nE=anEdgeMap.Extent ();
384 for (k=1; k<=nE; k++) {
385 const TopoDS_Shape& anEdge=anEdgeMap(k);
387 if (myDataStructure -> HasShape(anEdge)) {
388 anEdgesToSplitMap.Add(anEdge);
391 anEdgesToRestMap.Add(anEdge);
395 // split edges and define the states for all edges and parts of edges
396 StatusEdgesToSplit (anObj, anEdgesToSplitMap, anEdgesToRestMap);
398 ////// After StatusEdgesToSplit we can find the status of each Rest Edge
399 ////// in aMapOfShapeWithState. So we can insert this info. into
400 ////// aSplFacesState in order to propagate the state for faces.
401 nE=anEdgesToRestMap.Extent();
402 for (k=1; k<=nE; k++) {
403 const TopoDS_Shape anEdge=anEdgesToRestMap(k);
404 if (aMapOfShapeWithState.Contains (anEdge)) {
405 const TopOpeBRepDS_ShapeWithState& aSWS=aMapOfShapeWithState.FindFromKey(anEdge);
406 TopAbs_State aState=aSWS.State();
407 aSplFacesState.Bind (anEdge, aState);
410 } //end of else {// Wire has an interferences
412 } // next interferred Face ... for (i=1; i<=nF; i++) ...
415 //=======================================================================
416 //function :StatusEdgesToSplit
418 //=======================================================================
419 void TopOpeBRepBuild_Builder1::StatusEdgesToSplit (const TopoDS_Shape& anObj,
420 const TopTools_IndexedMapOfShape& anEdgesToSplitMap,
421 const TopTools_IndexedMapOfShape& anEdgesToRestMap)
425 TopOpeBRepDS_DataStructure& aDS= myDataStructure-> ChangeDS();
426 // Get aMapOfShapeWithState for Obj
427 Standard_Boolean aFlag;
428 TopOpeBRepDS_IndexedDataMapOfShapeWithState& aMapOfShapeWithState=aDS.ChangeMapOfShapeWithState(anObj, aFlag);
432 Standard_Integer i, nE=anEdgesToSplitMap.Extent();
435 TopOpeBRepDS_DataMapOfShapeState aSplEdgesState;
436 TopTools_ListIteratorOfListOfShape anIt;
439 for (i=1; i<=nE; i++) {
440 const TopoDS_Shape& anEdge=anEdgesToSplitMap(i);
442 if(processedEdges.Contains(anEdge)) {
443 if (aMapOfShapeWithState.Contains(anEdge)) {
444 const TopOpeBRepDS_ShapeWithState& aSWS=
445 aMapOfShapeWithState.FindFromKey(anEdge);
446 if (aSWS.IsSplitted()) {
448 const TopTools_ListOfShape& SplitsON=aSWS.Part(TopAbs_ON);
449 anIt.Initialize (SplitsON);
450 for (; anIt.More(); anIt.Next())
451 aSplEdgesState.Bind(anIt.Value(), TopAbs_ON);
453 const TopTools_ListOfShape& SplitsOUT=aSWS.Part(TopAbs_OUT);
454 anIt.Initialize (SplitsOUT);
455 for (; anIt.More(); anIt.Next())
456 aSplEdgesState.Bind(anIt.Value(), TopAbs_OUT);
458 const TopTools_ListOfShape& SplitsIN=aSWS.Part(TopAbs_IN);
459 anIt.Initialize (SplitsIN);
460 for (; anIt.More(); anIt.Next())
461 aSplEdgesState.Bind(anIt.Value(), TopAbs_IN);
468 processedEdges.Add(anEdge);
470 TopOpeBRepDS_ShapeWithState aShapeWithState;
472 // if IsSplit - it is the case of edges from SameDomain faces
473 Standard_Boolean IsSplitON = IsSplit(anEdge, TopAbs_ON);
476 const TopTools_ListOfShape& SplitsON = Splits(anEdge, TopAbs_ON);
477 anIt.Initialize (SplitsON);
478 for (; anIt.More(); anIt.Next()) {
479 TopoDS_Shape aNewEdge=anIt.Value();
480 aNewEdge.Orientation (anEdge.Orientation());
481 aShapeWithState.AddPart (aNewEdge, TopAbs_ON);
482 aSplEdgesState.Bind(anIt.Value(), TopAbs_ON);
486 const TopTools_ListOfShape& SplitsIN = Splits(anEdge, TopAbs_IN);
487 anIt.Initialize (SplitsIN);
488 for (; anIt.More(); anIt.Next()) {
489 TopoDS_Shape aNewEdge=anIt.Value();
490 aNewEdge.Orientation (anEdge.Orientation());
491 aShapeWithState.AddPart (aNewEdge, TopAbs_IN);
492 aSplEdgesState.Bind(anIt.Value(), TopAbs_IN);
496 const TopTools_ListOfShape& SplitsOUT = Splits(anEdge, TopAbs_OUT);
497 anIt.Initialize (SplitsOUT);
498 for (; anIt.More(); anIt.Next()) {
499 TopoDS_Shape aNewEdge=anIt.Value();
500 aNewEdge.Orientation (anEdge.Orientation());
501 aShapeWithState.AddPart (aNewEdge, TopAbs_OUT);
502 aSplEdgesState.Bind(anIt.Value(), TopAbs_OUT);
505 aShapeWithState.SetIsSplitted(Standard_True);
506 aMapOfShapeWithState.Add(anEdge, aShapeWithState);
510 // Attempt to split the Edge (for all other edges (from non SameDomain Faces))
511 TopOpeBRepDS_DataMapOfShapeState aDataMapOfShapeState;
512 TopTools_ListOfShape aLNew;
514 Standard_Boolean oldState = GLOBAL_faces2d;
516 GLOBAL_faces2d = Standard_True;
517 SplitEdge (anEdge, aLNew, aDataMapOfShapeState);
518 GLOBAL_faces2d = oldState;
521 if (!aLNew.Extent()) {
522 // * It means that whole Edge is IN (see SplitEdge(...) at line
523 // G1=TopOpeBRepBuild_GTool::GFusSame(tf,tf); Operation Fuse
524 // loses all parts of the Edge with IN state, but we need
525 // to have all parts. So, we have to rest the Edge as is ...
526 // ** But the edge itself will have UNKNOWN state and one split Part with state =IN.
527 TopoDS_Vertex Vf, Vl;
528 TopExp::Vertices(TopoDS::Edge(anEdge), Vf, Vl);
530 Standard_Boolean HasSDV1 = myDataStructure->HasSameDomain(Vf);
531 Standard_Boolean HasSDV2 = myDataStructure->HasSameDomain(Vl);
533 TopoDS_Edge aNewEdge = TopoDS::Edge(anEdge);
535 //if edge has SD edges , it is error because it must be processed in SplitSectionEdges
536 //but if we here we don't do anything with it
537 if(myDataStructure -> HasSameDomain(aNewEdge)) {
538 HasSDV1 = Standard_False;
539 HasSDV2 = Standard_False;
541 //if vertices has SD we must update edge, so we copy it
542 if(HasSDV1 || HasSDV2) {
543 TopoDS_Shape EOR = anEdge;
544 EOR.Orientation(TopAbs_FORWARD);
546 Standard_Real ParF = BRep_Tool::Parameter(Vf, TopoDS::Edge(EOR));
547 Standard_Real ParL = BRep_Tool::Parameter(Vl, TopoDS::Edge(EOR));
548 myBuildTool.CopyEdge (EOR, aNewEdge);
550 if (HasSDV1) { // on prend le vertex reference de V
551 Standard_Integer iref = myDataStructure->SameDomainReference(Vf);
552 Vf = TopoDS::Vertex(myDataStructure->Shape(iref));
553 Vf.Orientation(TopAbs_FORWARD);
556 if (HasSDV2) { // on prend le vertex reference de V
557 Standard_Integer iref = myDataStructure->SameDomainReference(Vl);
558 Vl = TopoDS::Vertex(myDataStructure->Shape(iref));
559 Vl.Orientation(TopAbs_REVERSED);
561 Standard_Boolean bitclosed = Vf.IsSame(Vl);
562 aNewEdge.Closed(bitclosed);
564 myBuildTool.AddEdgeVertex (aNewEdge, Vf);
565 myBuildTool.Parameter (aNewEdge, Vf, ParF);
567 myBuildTool.AddEdgeVertex (aNewEdge, Vl);
568 myBuildTool.Parameter (aNewEdge, Vl, ParL);
570 aNewEdge.Orientation (anEdge.Orientation());
573 aState= ClassifyEdgeToSolidByOnePoint(aNewEdge, myShapeClassifier);
574 aShapeWithState.SetIsSplitted (Standard_True);
576 aShapeWithState.AddPart (aNewEdge, aState);
577 aSplEdgesState.Bind(aNewEdge, aState);
579 TopExp::Vertices(aNewEdge, Vf, Vl);
580 theUsedVertexMap.Add(Vf);
581 theUsedVertexMap.Add(Vl);
582 if (!BRep_Tool::Degenerated(TopoDS::Edge(aNewEdge))) {
583 // MSV: it may be the case when an edge has one state but its vertex
584 // has another state. We should clarify this to avoid incorrect
585 // propagation of state.
586 myShapeClassifier.StateP3DReference(BRep_Tool::Pnt(Vf));
587 if (myShapeClassifier.State() != aState && myShapeClassifier.State() != TopAbs_ON)
588 theUnkStateVer.Add(Vf);
589 if (!Vf.IsSame(Vl)) {
590 myShapeClassifier.StateP3DReference(BRep_Tool::Pnt(Vl));
591 if (myShapeClassifier.State() != aState && myShapeClassifier.State() != TopAbs_ON)
592 theUnkStateVer.Add(Vl);
597 // Usual case. The Edge was splitted onto several parts:
598 TopTools_ListIteratorOfListOfShape aLIt(aLNew);
599 for (; aLIt.More(); aLIt.Next()) {
600 const TopoDS_Shape& aS = aLIt.Value();
601 aState = aDataMapOfShapeState(aS);
602 ////////////////////////////////////////////////////////////////////////////
603 // ** When aState==TopAbs_IN it is not evidence that it is realy so.
604 // There are some cases when JYL does not define ON parts completely.
605 // So, as we want to have right states, we have to do it ourselves.
606 // PKV Mon 25 Oct 1999
607 Standard_Boolean isdegen = BRep_Tool::Degenerated(TopoDS::Edge(aS));
608 //if edge is degenerated we trust that it have IN state without classify
610 if (aState==TopAbs_IN && !isdegen)
611 aState= ClassifyEdgeToSolidByOnePoint(TopoDS::Edge(aS), myShapeClassifier);
613 ////////////////////////////////////////////////////////////////////////////
614 aShapeWithState.AddPart (aS, aState);
615 aShapeWithState.SetIsSplitted (Standard_True);
617 aSplEdgesState.Bind(aS, aState);
618 TopoDS_Vertex Vf, Vl;
619 TopExp::Vertices(TopoDS::Edge(aS), Vf, Vl);
620 theUsedVertexMap.Add(Vf);
621 theUsedVertexMap.Add(Vl);
623 // MSV: clarify state of vertices (see my above comment)
624 myShapeClassifier.StateP3DReference(BRep_Tool::Pnt(Vf));
625 if (myShapeClassifier.State() != aState && myShapeClassifier.State() != TopAbs_ON)
626 theUnkStateVer.Add(Vf);
627 if (!Vf.IsSame(Vl)) {
628 myShapeClassifier.StateP3DReference(BRep_Tool::Pnt(Vl));
629 if (myShapeClassifier.State() != aState && myShapeClassifier.State() != TopAbs_ON)
630 theUnkStateVer.Add(Vl);
636 const TopTools_ListOfShape& EspON = aShapeWithState.Part(TopAbs_ON);
638 Standard_Integer nON = EspON.Extent();
639 if(!IsSplitON && nON) {
640 TopOpeBRepDS_ListOfShapeOn1State ONspl;
641 TopTools_ListOfShape& lON = ONspl.ChangeListOnState();
643 ONspl.Split(Standard_True);
644 mySplitON.Bind(anEdge, ONspl);
645 myDataStructure -> ChangeDS().AddSectionEdge(TopoDS::Edge(anEdge));
648 aMapOfShapeWithState.Add(anEdge, aShapeWithState);
649 } // end for (i=1; i<=nE; i++)
651 nE=anEdgesToRestMap.Extent();
652 for (i=1; i<=nE; i++) {
653 const TopoDS_Shape& anEdge=anEdgesToRestMap.FindKey(i);
654 if (aMapOfShapeWithState.Contains (anEdge)) {
655 const TopOpeBRepDS_ShapeWithState& aSWS=
656 aMapOfShapeWithState.FindFromKey(anEdge);
657 if (!aSWS.IsSplitted()) {
660 aSplEdgesState.Bind (anEdge, aState);
667 // Propagate the status for anEdgesToRestMap edges
668 TopOpeBRepBuild_Tools::PropagateState (aSplEdgesState, anEdgesToRestMap,
669 TopAbs_VERTEX, TopAbs_EDGE, myShapeClassifier,
670 aMapOfShapeWithState, theUnkStateVer);
676 //=======================================================================
677 //function : SplitEdge
679 //=======================================================================
680 void TopOpeBRepBuild_Builder1::SplitEdge (const TopoDS_Shape& anEdge,
681 TopTools_ListOfShape& aLNew,
682 TopOpeBRepDS_DataMapOfShapeState& aDataMapOfShapeState)
684 Standard_Real aPar1, aPar2;
685 TopAbs_Orientation anOr1, anOr2;
687 // Attention! If you didn't do the orientation of the Edge =FORWARD,
688 // the GFillPointTopologyPVS() method will give you a garbage!
689 TopoDS_Shape EdgeF=anEdge;
690 EdgeF.Orientation(TopAbs_FORWARD);
692 // Make a PaveSet PVS on edge EF
693 TopOpeBRepBuild_PaveSet PVS (EdgeF);
694 TopOpeBRepBuild_GTopo G1;
695 TopAbs_ShapeEnum tf = TopAbs_FACE;
696 G1=TopOpeBRepBuild_GTool::GFusSame(tf,tf);
697 myEdgeReference = TopoDS::Edge(EdgeF);
699 GFillPointTopologyPVS(EdgeF, G1, PVS);
703 //firstly we detect paves with equal params
706 // Add Paves to a standard list rather than to a PaveSet to avoid
707 // possible sequence disturbance in InitLoop.
708 // Check points for equality in both 3d and 1d spaces using maximum
709 // of tolerances of the edge and compared vertices, in 1d using resolution
710 // on edge from that value
712 TopOpeBRepBuild_ListOfPave aPVSlist;
713 TopTools_DataMapOfShapeListOfInteger aVerOriMap;
715 BRepAdaptor_Curve aCurveAdaptor(TopoDS::Edge(anEdge));
716 Standard_Real tolEdge = BRep_Tool::Tolerance(TopoDS::Edge(anEdge));
718 while (PVS.MoreLoop()) {
719 Handle(TopOpeBRepBuild_Pave) aPave1=Handle(TopOpeBRepBuild_Pave)::DownCast(PVS.Loop());
720 const TopoDS_Vertex& aV1= TopoDS::Vertex(aPave1->Vertex());
721 aPar1 = aPave1->Parameter();
724 if (!PVS.MoreLoop()) {
725 aPVSlist.Append(aPave1);
729 Handle(TopOpeBRepBuild_Pave) aPave2=Handle(TopOpeBRepBuild_Pave)::DownCast(PVS.Loop());
730 const TopoDS_Vertex& aV2= TopoDS::Vertex(aPave2->Vertex());
731 aPar2 = aPave2->Parameter();
733 Standard_Real tolV1 = BRep_Tool::Tolerance(aV1);
734 Standard_Real tolV2 = BRep_Tool::Tolerance(aV2);
735 Standard_Real tolMax = Max(tolEdge,Max(tolV1,tolV2));
736 Standard_Real resol = aCurveAdaptor.Resolution(tolMax);
737 Standard_Real delta = Abs(aPar1 - aPar2);
740 Standard_Real dist = BRep_Tool::Pnt(aV1).Distance(BRep_Tool::Pnt(aV2));
741 if (dist < tolMax || delta < Precision::PConfusion()) {
743 TopOpeBRepDS_Kind IntType1 = aPave1 -> InterferenceType();
744 Standard_Boolean Int3d1 = (IntType1 == TopOpeBRepDS_FACE);
745 Standard_Boolean HasSDV1 = myDataStructure->HasSameDomain(aV1);
746 Standard_Boolean HasSDV2 = myDataStructure->HasSameDomain(aV2);
747 Standard_Boolean UsedV1 = theUsedVertexMap.Contains(aV1);
748 Standard_Boolean UsedV2 = theUsedVertexMap.Contains(aV2);
750 Standard_Boolean takeFirst = Standard_True;
752 else if(HasSDV2) takeFirst = Standard_False;
754 else if(UsedV2) takeFirst = Standard_False;
756 else takeFirst = Standard_False;
758 Standard_Boolean HasSDV;
759 TopAbs_Orientation anOriOpp;
761 aPVSlist.Append(aPave1);
762 aVer = aV1; HasSDV = HasSDV1; anOriOpp = aV2.Orientation();
765 aPVSlist.Append(aPave2);
766 aVer = aV2; HasSDV = HasSDV2; anOriOpp = aV1.Orientation();
769 if (aV1.Orientation() != aV2.Orientation()) {
770 // MSV: save orientation of removed vertex
771 TColStd_ListOfInteger thelist;
772 if (!aVerOriMap.IsBound(aVer)) aVerOriMap.Bind(aVer, thelist);
773 TColStd_ListOfInteger& anOriList = aVerOriMap(aVer);
774 anOriList.Append(takeFirst);
775 anOriList.Append(anOriOpp);
776 // mark this vertex as having unknown state
778 Standard_Integer iref = myDataStructure->SameDomainReference(aVer);
779 aVer = myDataStructure->Shape(iref);
781 theUnkStateVer.Add(aVer);
788 aPVSlist.Append(aPave1);
791 TopOpeBRepBuild_ListIteratorOfListOfPave aPVSit(aPVSlist);
792 while (aPVSit.More()) {
793 Handle(TopOpeBRepBuild_Pave) aPave1 = aPVSit.Value();
794 TopoDS_Shape aV1= aPave1->Vertex();
795 aV1.Orientation(TopAbs_FORWARD);
796 aPar1 = aPave1->Parameter();
797 anOr1=(aPave1->Vertex()).Orientation();
798 if (aVerOriMap.IsBound(aV1)) {
799 // MSV: restore orientation of removed vertex
800 TColStd_ListOfInteger& anOriList = aVerOriMap(aV1);
801 if (!anOriList.IsEmpty()) {
802 if (anOriList.First()) {
803 TColStd_ListIteratorOfListOfInteger it(anOriList); it.Next();
804 anOr1 = (TopAbs_Orientation) it.Value();
806 anOriList.RemoveFirst(); anOriList.RemoveFirst();
812 if (!aPVSit.More()) break;
814 Handle(TopOpeBRepBuild_Pave) aPave2 = aPVSit.Value();
815 TopoDS_Shape aV2= aPave2->Vertex();
816 aV2.Orientation(TopAbs_REVERSED);
817 aPar2 = aPave2->Parameter();
818 anOr2=(aPave2->Vertex()).Orientation();
819 if (aVerOriMap.IsBound(aV2)) {
820 TColStd_ListOfInteger& anOriList = aVerOriMap(aV2);
821 if (!anOriList.IsEmpty()) {
822 if (!anOriList.First()) {
823 TColStd_ListIteratorOfListOfInteger it(anOriList); it.Next();
824 anOr2 = (TopAbs_Orientation) it.Value();
829 // MSV: avoid creation of an edge with invalid range
830 if (aPar1 > aPar2) continue;
832 Standard_Boolean HasSDV1 = myDataStructure->HasSameDomain(aV1);
833 Standard_Boolean HasSDV2 = myDataStructure->HasSameDomain(aV2);
834 if (HasSDV1) { // on prend le vertex reference de V
835 Standard_Integer iref = myDataStructure->SameDomainReference(aV1);
836 aV1 = myDataStructure->Shape(iref);
837 aV1.Orientation(TopAbs_FORWARD);
840 if (HasSDV2) { // on prend le vertex reference de V
841 Standard_Integer iref = myDataStructure->SameDomainReference(aV2);
842 aV2 = myDataStructure->Shape(iref);
843 aV2.Orientation(TopAbs_REVERSED);
846 // Make new edge from EdgeF
847 TopoDS_Edge aNewEdge;
848 myBuildTool.CopyEdge (EdgeF, aNewEdge);
850 Standard_Boolean bitclosed = aV1.IsSame(aV2);
851 aNewEdge.Closed(bitclosed);
853 myBuildTool.AddEdgeVertex (aNewEdge, aV1);
854 myBuildTool.Parameter (aNewEdge, aV1, aPar1);
856 myBuildTool.AddEdgeVertex (aNewEdge, aV2);
857 myBuildTool.Parameter (aNewEdge, aV2, aPar2);
861 TopAbs_State aState=TopAbs_IN;
863 if (anOr1==TopAbs_FORWARD && anOr2==TopAbs_REVERSED) aState=TopAbs_OUT;
864 if (anOr1==TopAbs_FORWARD && anOr2==TopAbs_INTERNAL) aState=TopAbs_OUT;
865 if (anOr1==TopAbs_INTERNAL && anOr2==TopAbs_REVERSED) aState=TopAbs_OUT;
867 if (anOr1==TopAbs_INTERNAL && anOr2==TopAbs_INTERNAL) aState=TopAbs_OUT;
868 //printf(" anOr1=%d, anOr2=%d\n", anOr1, anOr2);
870 // set old orientation to new edge;
871 aNewEdge.Orientation (anEdge.Orientation());
872 aLNew.Append(aNewEdge);
873 aDataMapOfShapeState.Bind(aNewEdge, aState);
875 //GEDBUMakeEdges(EdgeF,EDBU,aListOfShape);
878 static TopAbs_State ClassifyEdgeToSolidByOnePoint(const TopoDS_Edge& E,
879 TopOpeBRepTool_ShapeClassifier& SC)
881 Standard_Real f2 = 0., l2 = 0., par = 0.;
883 Handle(Geom_Curve) C3D = BRep_Tool::Curve(E, f2, l2);
887 //it means that we are in degenerated edge
888 const TopoDS_Vertex& fv = TopExp::FirstVertex(E);
890 return TopAbs_UNKNOWN;
891 aP3d = BRep_Tool::Pnt(fv);
894 par = f2*PAR_T + (1 - PAR_T)*l2;
895 C3D -> D0(par, aP3d);
898 SC.StateP3DReference(aP3d);