1 // Created on: 1999-10-07
2 // Created by: Peter KURNEV
3 // Copyright (c) 1999-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
6 // This file is part of Open CASCADE Technology software library.
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
17 #include <TopOpeBRepBuild_Builder.ixx>
19 #include <BRepTools.hxx>
20 #include <BRep_Builder.hxx>
25 #include <TopoDS_Vertex.hxx>
26 #include <TopoDS_Wire.hxx>
28 #include <TopTools_MapOfShape.hxx>
29 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
30 #include <TopTools_MapIteratorOfMapOfShape.hxx>
31 #include <TopTools_IndexedMapOfShape.hxx>
33 #include <TopOpeBRepBuild_PaveSet.hxx>
34 #include <TopOpeBRepBuild_GTool.hxx>
35 #include <TopOpeBRepBuild_Pave.hxx>
36 #include <TopOpeBRepBuild_Loop.hxx>
37 #include <TopOpeBRepBuild_EdgeBuilder.hxx>
38 #include <TopOpeBRepBuild_ListOfListOfLoop.hxx>
39 #include <TopOpeBRepBuild_Tools.hxx>
40 #include <TopOpeBRepBuild_GTopo.hxx>
42 #include <TopOpeBRepDS_DataMapOfShapeState.hxx>
43 #include <TopOpeBRepDS_DataMapIteratorOfDataMapOfShapeState.hxx>
44 #include <TopOpeBRepDS_Interference.hxx>
45 #include <TopOpeBRepDS_ListOfInterference.hxx>
46 #include <TopOpeBRepDS_ListIteratorOfListOfInterference.hxx>
47 #include <TopOpeBRepDS_IndexedDataMapOfShapeWithState.hxx>
48 #include <TopOpeBRepDS_ShapeWithState.hxx>
49 #include <TopOpeBRepDS_DataStructure.hxx>
50 #include <BRep_Tool.hxx>
51 #include <TopOpeBRepDS_ListOfShapeOn1State.hxx>
52 #include <Geom_Curve.hxx>
53 #include <Precision.hxx>
54 #include <BRepAdaptor_Curve.hxx>
55 #include <TopTools_DataMapOfShapeListOfInteger.hxx>
56 #include <TColStd_ListIteratorOfListOfInteger.hxx>
58 //define parameter division number as 10*e^(-PI) = 0.43213918
59 const Standard_Real PAR_T = 0.43213918;
61 static TopAbs_State ClassifyEdgeToSolidByOnePoint(const TopoDS_Edge& E,
62 TopOpeBRepTool_ShapeClassifier& SC);
64 //=======================================================================
65 // : Definition the States of Shape's Entities for an Object
66 // : and a Tool. Thu Oct 7 09:38:29 1999
67 //=======================================================================
69 static TopTools_IndexedMapOfShape processedEdges;
70 static TopTools_IndexedMapOfShape theUsedVertexMap;
71 static TopTools_MapOfShape theUnkStateVer;
73 extern Standard_Boolean GLOBAL_faces2d;
75 //modified by NIZNHY-PKV Mon Dec 16 11:38:55 2002 f
76 //=======================================================================
79 //=======================================================================
80 void TopOpeBRepBuild_Builder1::Destroy()
82 processedEdges.Clear();
83 theUsedVertexMap.Clear();
84 theUnkStateVer.Clear();
86 //modified by NIZNHY-PKV Mon Dec 16 11:38:59 2002 t
88 //=======================================================================
89 //function : PerformShapeWithStates
91 //=======================================================================
92 void TopOpeBRepBuild_Builder1::PerformShapeWithStates()
94 theUsedVertexMap.Clear();
95 theUnkStateVer.Clear();
96 myDataStructure -> ChangeDS().ChangeMapOfShapeWithStateObj().Clear();
97 myDataStructure -> ChangeDS().ChangeMapOfShapeWithStateTool().Clear();
98 //modified by NIZHNY-MZV Mon Feb 21 13:30:05 2000
99 //process section curves
100 Standard_Integer i, nbC = myDataStructure -> DS().NbCurves();
101 for(i = 1; i <= nbC; i++) {
102 TopTools_ListOfShape& LSE = ChangeNewEdges(i);
103 TopTools_ListIteratorOfListOfShape it(LSE);
104 for(; it.More(); it.Next()) {
105 const TopoDS_Shape& E = it.Value();
106 TopoDS_Vertex Vf, Vl;
107 TopExp::Vertices(TopoDS::Edge(E), Vf, Vl);
108 theUsedVertexMap.Add(Vf);
109 theUsedVertexMap.Add(Vl);
113 //process section edges
114 const TopOpeBRepDS_DataStructure& BDS = myDataStructure->DS();
115 Standard_Integer n = BDS.NbSectionEdges();
116 for (i = 1; i <= n; i++) {
117 TopTools_ListIteratorOfListOfShape anIt;
118 const TopoDS_Edge& E = TopoDS::Edge(BDS.SectionEdge(i));
119 if(E.IsNull()) continue;
121 const TopTools_ListOfShape& SplitsON = Splits(E, TopAbs_ON);
122 anIt.Initialize (SplitsON);
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);
132 const TopTools_ListOfShape& SplitsIN = Splits(E, TopAbs_IN);
133 anIt.Initialize (SplitsIN);
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);
143 const TopTools_ListOfShape& SplitsOUT = Splits(E, TopAbs_OUT);
144 anIt.Initialize (SplitsOUT);
145 for (; anIt.More(); anIt.Next()) {
146 TopoDS_Shape aNewEdge=anIt.Value();
147 TopoDS_Vertex Vf, Vl;
148 TopExp::Vertices(TopoDS::Edge(aNewEdge), Vf, Vl);
149 theUsedVertexMap.Add(Vf);
150 theUsedVertexMap.Add(Vl);
154 //modified by NIZHNY-MZV Tue Apr 11 17:32:05 2000
155 //1) Add both arguments to facilitate the search
156 TopOpeBRepDS_ShapeWithState aShapeWithState;
157 TopOpeBRepDS_DataStructure& aDataStructure=myDataStructure->ChangeDS();
159 TopOpeBRepDS_IndexedDataMapOfShapeWithState& aMapOfShapeWithStateObj=
160 aDataStructure.ChangeMapOfShapeWithStateObj();
161 TopOpeBRepDS_IndexedDataMapOfShapeWithState& aMapOfShapeWithStateTool=
162 aDataStructure.ChangeMapOfShapeWithStateTool();
164 aMapOfShapeWithStateObj.Add(myShape1, aShapeWithState);
165 aMapOfShapeWithStateTool.Add(myShape2, aShapeWithState);
167 //2) Add all rejected shapes as OUT
169 TopTools_IndexedMapOfShape& aMapOfRejectedShapesObj=
170 aDataStructure.ChangeMapOfRejectedShapesObj();
171 TopTools_IndexedMapOfShape& aMapOfRejectedShapesTool=
172 aDataStructure.ChangeMapOfRejectedShapesTool();
174 aShapeWithState.SetIsSplitted (Standard_False);
175 aShapeWithState.SetState (TopAbs_OUT);
177 Standard_Integer iW, j, nW, nE,
178 nRSObj = aMapOfRejectedShapesObj.Extent(),
179 nRSTool = aMapOfRejectedShapesTool.Extent();
181 for(i = 1; i <= nRSObj; i++) {
182 const TopoDS_Shape& aFace = aMapOfRejectedShapesObj(i);
183 if(aFace.ShapeType() != TopAbs_FACE)
185 TopTools_IndexedMapOfShape aWiresMap;
187 TopExp::MapShapes (aFace, TopAbs_WIRE, aWiresMap);
188 nW=aWiresMap.Extent ();
189 for (iW=1; iW<=nW; iW++) {
190 const TopoDS_Shape& aWire=aWiresMap(iW);
192 TopTools_IndexedMapOfShape anEdgesMap;
193 TopExp::MapShapes (aWire, TopAbs_EDGE, anEdgesMap);
194 nE=anEdgesMap.Extent ();
195 for (j=1; j<=nE; j++)
196 aMapOfShapeWithStateObj.Add(anEdgesMap(j), aShapeWithState); // add edge
198 aMapOfShapeWithStateObj.Add(aWire, aShapeWithState); // add wire
200 aMapOfShapeWithStateObj.Add(aFace, aShapeWithState); // add face
203 for(i = 1; i <= nRSTool; i++) {
204 const TopoDS_Shape& aFace = aMapOfRejectedShapesTool(i);
205 //modified by NIZHNY-MZV Wed Apr 5 10:27:18 2000
206 if(aFace.ShapeType() != TopAbs_FACE)
208 TopTools_IndexedMapOfShape aWiresMap;
209 TopExp::MapShapes (aFace, TopAbs_WIRE, aWiresMap);
210 nW=aWiresMap.Extent ();
211 for (iW=1; iW<=nW; iW++) {
212 const TopoDS_Shape& aWire=aWiresMap(iW);
214 TopTools_IndexedMapOfShape anEdgesMap;
215 TopExp::MapShapes (aWire, TopAbs_EDGE, anEdgesMap);
216 nE=anEdgesMap.Extent ();
217 for (j=1; j<=nE; j++)
218 aMapOfShapeWithStateTool.Add(anEdgesMap(j), aShapeWithState); // add edge
220 aMapOfShapeWithStateTool.Add(aWire, aShapeWithState); // add wire
222 aMapOfShapeWithStateTool.Add(aFace, aShapeWithState); // add face
225 PerformShapeWithStates (myShape1, myShape2);
226 processedEdges.Clear();
227 PerformShapeWithStates (myShape2, myShape1);
228 processedEdges.Clear();
230 // printf(" ..::PerformShapeWithStates() [Dump is off]\n");
232 /* printf(" ..::PerformShapeWithStates() [Dump is on]\n");
234 TopOpeBRepDS_DataStructure& aDS= myDataStructure-> ChangeDS();
236 TopOpeBRepDS_IndexedDataMapOfShapeWithState& aMapOfShapeWithStateObj=
237 aDS.ChangeMapOfShapeWithStateObj();
239 TopOpeBRepDS_IndexedDataMapOfShapeWithState& aMapOfShapeWithStateTool=
240 aDS.ChangeMapOfShapeWithStateTool();
242 TopOpeBRepBuild_Tools::DumpMapOfShapeWithState(0, aMapOfShapeWithStateObj);
243 TopOpeBRepBuild_Tools::DumpMapOfShapeWithState(1, aMapOfShapeWithStateTool);
250 //=======================================================================
251 //function :PerformShapeWithStates
253 //=======================================================================
254 void TopOpeBRepBuild_Builder1::PerformShapeWithStates (const TopoDS_Shape& anObj,
255 const TopoDS_Shape& aReference)
257 myShapeClassifier.SetReference(aReference);
258 TopOpeBRepDS_DataStructure& aDS= myDataStructure-> ChangeDS();
259 // Get aMapOfShapeWithState for Obj
260 Standard_Boolean aFlag;
261 TopOpeBRepDS_IndexedDataMapOfShapeWithState& aMapOfShapeWithState=
262 aDS.ChangeMapOfShapeWithState(anObj, aFlag);
265 Standard_Integer i, j, k, nS, nF, nE;
267 TopTools_IndexedMapOfShape aFacesMap, aFacesWithInterferencesMap, aFacesToRestMap;
268 TopOpeBRepDS_DataMapOfShapeState aSplFacesState;
270 TopTools_IndexedMapOfShape aShellsMap;
271 TopExp::MapShapes(anObj, TopAbs_SHELL, aShellsMap);
273 nS=aShellsMap.Extent();
274 for (i=1; i<=nS; i++) {
275 const TopoDS_Shape& aShell = aShellsMap(i);
277 if (aMapOfShapeWithState.Contains (aShell)) continue;
279 else if (!myDataStructure -> HasShape(aShell)) {
280 // Shell has no interference.
281 // So, define its state and push into the Map as is.// A.1
282 TopOpeBRepBuild_Tools::FindStateThroughVertex (aShell, myShapeClassifier,
283 aMapOfShapeWithState, theUnkStateVer);
288 // Shell has interference. Try to separate it into FacesToRest and InterferredFace
290 aFacesWithInterferencesMap.Clear();
291 aFacesToRestMap.Clear();
292 aSplFacesState.Clear();
294 TopExp::MapShapes (aShell, TopAbs_FACE, aFacesMap);
295 nF=aFacesMap.Extent();
296 for (j=1; j<=nF; j++) {
297 const TopoDS_Shape& aFace = aFacesMap(j);
299 if (aMapOfShapeWithState.Contains (aFace)) {
301 // if the face is known, its edges are also known.
302 // We just insert this info. into aSplFacesState in order to
303 // propagate the state for faces with unknown states.
304 TopTools_IndexedMapOfShape anEdgesMap;
305 TopExp::MapShapes (aFace, TopAbs_EDGE, anEdgesMap);
306 nE=anEdgesMap.Extent();
307 for (k=1; k<=nE; k++) {
308 const TopoDS_Shape& anEdge=anEdgesMap(k);
309 const TopOpeBRepDS_ShapeWithState& aSWS=
310 aMapOfShapeWithState.FindFromKey(anEdge);
311 TopAbs_State aState=aSWS.State();
312 aSplFacesState.Bind (anEdge, aState);
316 else if (myDataStructure -> HasShape(aFace))
317 aFacesWithInterferencesMap.Add (aFace);
319 aFacesToRestMap.Add (aFace);
322 // work with aFacesWithInterferencesMap
323 PerformFacesWithStates (anObj, aFacesWithInterferencesMap, aSplFacesState);
325 // Propagate the States for all unknown faces from aFacesToRestMap
326 TopTools_MapOfShape anUnkStateEdge;
327 TopOpeBRepBuild_Tools::PropagateState (aSplFacesState,aFacesToRestMap,
328 TopAbs_EDGE, TopAbs_FACE, myShapeClassifier,
329 aMapOfShapeWithState, anUnkStateEdge);
330 ///// Propagate on WIres from aFacesToRestMap
331 TopOpeBRepBuild_Tools::PropagateStateForWires (aFacesToRestMap, aMapOfShapeWithState);
336 //=======================================================================
337 //function :PerformFacesWithStates
339 //=======================================================================
340 void TopOpeBRepBuild_Builder1::PerformFacesWithStates (const TopoDS_Shape& anObj,
341 const TopTools_IndexedMapOfShape& aFacesWithInterferencesMap,
342 TopOpeBRepDS_DataMapOfShapeState& aSplFacesState)
344 TopOpeBRepDS_DataStructure& aDS= myDataStructure-> ChangeDS();
345 // Get aMapOfShapeWithState for Obj
346 Standard_Boolean aFlag;
347 TopOpeBRepDS_IndexedDataMapOfShapeWithState& aMapOfShapeWithState=aDS.ChangeMapOfShapeWithState(anObj, aFlag);
351 Standard_Integer i, j, k, nF, nW, nE;
353 nF=aFacesWithInterferencesMap.Extent();
355 for (i=1; i<=nF; i++) {
356 TopTools_IndexedMapOfShape anEdgesToSplitMap, anEdgesToRestMap;
358 const TopoDS_Shape& aFace = aFacesWithInterferencesMap(i);
360 TopTools_IndexedMapOfShape aWireMap;
361 TopExp::MapShapes (aFace, TopAbs_WIRE, aWireMap);
362 nW=aWireMap.Extent();
363 for (j=1; j<=nW; j++) {
364 const TopoDS_Shape& aWire=aWireMap(j);
366 if (!myDataStructure -> HasShape(aWire)) {
367 // Wire has no interference.
368 // So, define its state and push into the Map as is.
369 TopOpeBRepBuild_Tools::FindStateThroughVertex (aWire, myShapeClassifier,
370 aMapOfShapeWithState, theUnkStateVer);
375 // Wire has an interferences
376 TopTools_IndexedMapOfShape anEdgeMap;
377 TopExp::MapShapes (aWire, TopAbs_EDGE, anEdgeMap);
378 nE=anEdgeMap.Extent ();
379 for (k=1; k<=nE; k++) {
380 const TopoDS_Shape& anEdge=anEdgeMap(k);
382 if (myDataStructure -> HasShape(anEdge)) {
383 anEdgesToSplitMap.Add(anEdge);
386 anEdgesToRestMap.Add(anEdge);
390 // split edges and define the states for all edges and parts of edges
391 StatusEdgesToSplit (anObj, anEdgesToSplitMap, anEdgesToRestMap);
393 ////// After StatusEdgesToSplit we can find the status of each Rest Edge
394 ////// in aMapOfShapeWithState. So we can insert this info. into
395 ////// aSplFacesState in order to propagate the state for faces.
396 nE=anEdgesToRestMap.Extent();
397 for (k=1; k<=nE; k++) {
398 const TopoDS_Shape anEdge=anEdgesToRestMap(k);
399 if (aMapOfShapeWithState.Contains (anEdge)) {
400 const TopOpeBRepDS_ShapeWithState& aSWS=aMapOfShapeWithState.FindFromKey(anEdge);
401 TopAbs_State aState=aSWS.State();
402 aSplFacesState.Bind (anEdge, aState);
405 } //end of else {// Wire has an interferences
407 } // next interferred Face ... for (i=1; i<=nF; i++) ...
410 //=======================================================================
411 //function :StatusEdgesToSplit
413 //=======================================================================
414 void TopOpeBRepBuild_Builder1::StatusEdgesToSplit (const TopoDS_Shape& anObj,
415 const TopTools_IndexedMapOfShape& anEdgesToSplitMap,
416 const TopTools_IndexedMapOfShape& anEdgesToRestMap)
420 TopOpeBRepDS_DataStructure& aDS= myDataStructure-> ChangeDS();
421 // Get aMapOfShapeWithState for Obj
422 Standard_Boolean aFlag;
423 TopOpeBRepDS_IndexedDataMapOfShapeWithState& aMapOfShapeWithState=aDS.ChangeMapOfShapeWithState(anObj, aFlag);
427 Standard_Integer i, nE=anEdgesToSplitMap.Extent();
430 TopOpeBRepDS_DataMapOfShapeState aSplEdgesState;
431 TopTools_ListIteratorOfListOfShape anIt;
434 for (i=1; i<=nE; i++) {
435 const TopoDS_Shape& anEdge=anEdgesToSplitMap(i);
437 if(processedEdges.Contains(anEdge)) {
438 if (aMapOfShapeWithState.Contains(anEdge)) {
439 const TopOpeBRepDS_ShapeWithState& aSWS=
440 aMapOfShapeWithState.FindFromKey(anEdge);
441 if (aSWS.IsSplitted()) {
443 const TopTools_ListOfShape& SplitsON=aSWS.Part(TopAbs_ON);
444 anIt.Initialize (SplitsON);
445 for (; anIt.More(); anIt.Next())
446 aSplEdgesState.Bind(anIt.Value(), TopAbs_ON);
448 const TopTools_ListOfShape& SplitsOUT=aSWS.Part(TopAbs_OUT);
449 anIt.Initialize (SplitsOUT);
450 for (; anIt.More(); anIt.Next())
451 aSplEdgesState.Bind(anIt.Value(), TopAbs_OUT);
453 const TopTools_ListOfShape& SplitsIN=aSWS.Part(TopAbs_IN);
454 anIt.Initialize (SplitsIN);
455 for (; anIt.More(); anIt.Next())
456 aSplEdgesState.Bind(anIt.Value(), TopAbs_IN);
463 processedEdges.Add(anEdge);
465 TopOpeBRepDS_ShapeWithState aShapeWithState;
467 // if IsSplit - it is the case of edges from SameDomain faces
468 Standard_Boolean IsSplitON = IsSplit(anEdge, TopAbs_ON);
471 const TopTools_ListOfShape& SplitsON = Splits(anEdge, TopAbs_ON);
472 anIt.Initialize (SplitsON);
473 for (; anIt.More(); anIt.Next()) {
474 TopoDS_Shape aNewEdge=anIt.Value();
475 aNewEdge.Orientation (anEdge.Orientation());
476 aShapeWithState.AddPart (aNewEdge, TopAbs_ON);
477 aSplEdgesState.Bind(anIt.Value(), TopAbs_ON);
481 const TopTools_ListOfShape& SplitsIN = Splits(anEdge, TopAbs_IN);
482 anIt.Initialize (SplitsIN);
483 for (; anIt.More(); anIt.Next()) {
484 TopoDS_Shape aNewEdge=anIt.Value();
485 aNewEdge.Orientation (anEdge.Orientation());
486 aShapeWithState.AddPart (aNewEdge, TopAbs_IN);
487 aSplEdgesState.Bind(anIt.Value(), TopAbs_IN);
491 const TopTools_ListOfShape& SplitsOUT = Splits(anEdge, TopAbs_OUT);
492 anIt.Initialize (SplitsOUT);
493 for (; anIt.More(); anIt.Next()) {
494 TopoDS_Shape aNewEdge=anIt.Value();
495 aNewEdge.Orientation (anEdge.Orientation());
496 aShapeWithState.AddPart (aNewEdge, TopAbs_OUT);
497 aSplEdgesState.Bind(anIt.Value(), TopAbs_OUT);
500 aShapeWithState.SetIsSplitted(Standard_True);
501 aMapOfShapeWithState.Add(anEdge, aShapeWithState);
505 // Attempt to split the Edge (for all other edges (from non SameDomain Faces))
506 TopOpeBRepDS_DataMapOfShapeState aDataMapOfShapeState;
507 TopTools_ListOfShape aLNew;
509 Standard_Boolean oldState = GLOBAL_faces2d;
511 GLOBAL_faces2d = Standard_True;
512 SplitEdge (anEdge, aLNew, aDataMapOfShapeState);
513 GLOBAL_faces2d = oldState;
516 if (!aLNew.Extent()) {
517 // * It means that whole Edge is IN (see SplitEdge(...) at line
518 // G1=TopOpeBRepBuild_GTool::GFusSame(tf,tf); Operation Fuse
519 // loses all parts of the Edge with IN state, but we need
520 // to have all parts. So, we have to rest the Edge as is ...
521 // ** But the edge itself will have UNKNOWN state and one split Part with state =IN.
522 TopoDS_Vertex Vf, Vl;
523 TopExp::Vertices(TopoDS::Edge(anEdge), Vf, Vl);
525 Standard_Boolean HasSDV1 = myDataStructure->HasSameDomain(Vf);
526 Standard_Boolean HasSDV2 = myDataStructure->HasSameDomain(Vl);
528 TopoDS_Edge aNewEdge = TopoDS::Edge(anEdge);
530 //if edge has SD edges , it is error because it must be processed in SplitSectionEdges
531 //but if we here we don't do anything with it
532 if(myDataStructure -> HasSameDomain(aNewEdge)) {
533 HasSDV1 = Standard_False;
534 HasSDV2 = Standard_False;
536 //if vertices has SD we must update edge, so we copy it
537 if(HasSDV1 || HasSDV2) {
538 TopoDS_Shape EOR = anEdge;
539 EOR.Orientation(TopAbs_FORWARD);
541 Standard_Real ParF = BRep_Tool::Parameter(Vf, TopoDS::Edge(EOR));
542 Standard_Real ParL = BRep_Tool::Parameter(Vl, TopoDS::Edge(EOR));
543 myBuildTool.CopyEdge (EOR, aNewEdge);
545 if (HasSDV1) { // on prend le vertex reference de V
546 Standard_Integer iref = myDataStructure->SameDomainReference(Vf);
547 Vf = TopoDS::Vertex(myDataStructure->Shape(iref));
548 Vf.Orientation(TopAbs_FORWARD);
551 if (HasSDV2) { // on prend le vertex reference de V
552 Standard_Integer iref = myDataStructure->SameDomainReference(Vl);
553 Vl = TopoDS::Vertex(myDataStructure->Shape(iref));
554 Vl.Orientation(TopAbs_REVERSED);
557 myBuildTool.AddEdgeVertex (aNewEdge, Vf);
558 myBuildTool.Parameter (aNewEdge, Vf, ParF);
560 myBuildTool.AddEdgeVertex (aNewEdge, Vl);
561 myBuildTool.Parameter (aNewEdge, Vl, ParL);
563 aNewEdge.Orientation (anEdge.Orientation());
566 aState= ClassifyEdgeToSolidByOnePoint(aNewEdge, myShapeClassifier);
567 aShapeWithState.SetIsSplitted (Standard_True);
569 aShapeWithState.AddPart (aNewEdge, aState);
570 aSplEdgesState.Bind(aNewEdge, aState);
572 TopExp::Vertices(aNewEdge, Vf, Vl);
573 theUsedVertexMap.Add(Vf);
574 theUsedVertexMap.Add(Vl);
575 if (!BRep_Tool::Degenerated(TopoDS::Edge(aNewEdge))) {
576 // MSV: it may be the case when an edge has one state but its vertex
577 // has another state. We should clarify this to avoid incorrect
578 // propagation of state.
579 myShapeClassifier.StateP3DReference(BRep_Tool::Pnt(Vf));
580 if (myShapeClassifier.State() != aState && myShapeClassifier.State() != TopAbs_ON)
581 theUnkStateVer.Add(Vf);
582 if (!Vf.IsSame(Vl)) {
583 myShapeClassifier.StateP3DReference(BRep_Tool::Pnt(Vl));
584 if (myShapeClassifier.State() != aState && myShapeClassifier.State() != TopAbs_ON)
585 theUnkStateVer.Add(Vl);
590 // Usual case. The Edge was splitted onto several parts:
591 TopTools_ListIteratorOfListOfShape aLIt(aLNew);
592 for (; aLIt.More(); aLIt.Next()) {
593 const TopoDS_Shape& aS = aLIt.Value();
594 aState = aDataMapOfShapeState(aS);
595 ////////////////////////////////////////////////////////////////////////////
596 // ** When aState==TopAbs_IN it is not evidence that it is realy so.
597 // There are some cases when JYL does not define ON parts completely.
598 // So, as we want to have right states, we have to do it ourselves.
599 // PKV Mon 25 Oct 1999
600 Standard_Boolean isdegen = BRep_Tool::Degenerated(TopoDS::Edge(aS));
601 //if edge is degenerated we trust that it have IN state without classify
603 if (aState==TopAbs_IN && !isdegen)
604 aState= ClassifyEdgeToSolidByOnePoint(TopoDS::Edge(aS), myShapeClassifier);
606 ////////////////////////////////////////////////////////////////////////////
607 aShapeWithState.AddPart (aS, aState);
608 aShapeWithState.SetIsSplitted (Standard_True);
610 aSplEdgesState.Bind(aS, aState);
611 TopoDS_Vertex Vf, Vl;
612 TopExp::Vertices(TopoDS::Edge(aS), Vf, Vl);
613 theUsedVertexMap.Add(Vf);
614 theUsedVertexMap.Add(Vl);
616 // MSV: clarify state of vertices (see my above comment)
617 myShapeClassifier.StateP3DReference(BRep_Tool::Pnt(Vf));
618 if (myShapeClassifier.State() != aState && myShapeClassifier.State() != TopAbs_ON)
619 theUnkStateVer.Add(Vf);
620 if (!Vf.IsSame(Vl)) {
621 myShapeClassifier.StateP3DReference(BRep_Tool::Pnt(Vl));
622 if (myShapeClassifier.State() != aState && myShapeClassifier.State() != TopAbs_ON)
623 theUnkStateVer.Add(Vl);
629 const TopTools_ListOfShape& EspON = aShapeWithState.Part(TopAbs_ON);
631 Standard_Integer nON = EspON.Extent();
632 if(!IsSplitON && nON) {
633 TopOpeBRepDS_ListOfShapeOn1State ONspl;
634 TopTools_ListOfShape& lON = ONspl.ChangeListOnState();
636 ONspl.Split(Standard_True);
637 mySplitON.Bind(anEdge, ONspl);
638 myDataStructure -> ChangeDS().AddSectionEdge(TopoDS::Edge(anEdge));
641 aMapOfShapeWithState.Add(anEdge, aShapeWithState);
642 } // end for (i=1; i<=nE; i++)
644 nE=anEdgesToRestMap.Extent();
645 for (i=1; i<=nE; i++) {
646 const TopoDS_Shape& anEdge=anEdgesToRestMap.FindKey(i);
647 if (aMapOfShapeWithState.Contains (anEdge)) {
648 const TopOpeBRepDS_ShapeWithState& aSWS=
649 aMapOfShapeWithState.FindFromKey(anEdge);
650 if (!aSWS.IsSplitted()) {
653 aSplEdgesState.Bind (anEdge, aState);
660 // Propagate the status for anEdgesToRestMap edges
661 TopOpeBRepBuild_Tools::PropagateState (aSplEdgesState, anEdgesToRestMap,
662 TopAbs_VERTEX, TopAbs_EDGE, myShapeClassifier,
663 aMapOfShapeWithState, theUnkStateVer);
669 //=======================================================================
670 //function : SplitEdge
672 //=======================================================================
673 void TopOpeBRepBuild_Builder1::SplitEdge (const TopoDS_Shape& anEdge,
674 TopTools_ListOfShape& aLNew,
675 TopOpeBRepDS_DataMapOfShapeState& aDataMapOfShapeState)
677 Standard_Real aPar1, aPar2;
678 TopAbs_Orientation anOr1, anOr2;
680 // Attention! If you didn't do the orientation of the Edge =FORWARD,
681 // the GFillPointTopologyPVS() method will give you a garbage!
682 TopoDS_Shape EdgeF=anEdge;
683 EdgeF.Orientation(TopAbs_FORWARD);
685 // Make a PaveSet PVS on edge EF
686 TopOpeBRepBuild_PaveSet PVS (EdgeF);
687 TopOpeBRepBuild_GTopo G1;
688 TopAbs_ShapeEnum tf = TopAbs_FACE;
689 G1=TopOpeBRepBuild_GTool::GFusSame(tf,tf);
690 myEdgeReference = TopoDS::Edge(EdgeF);
692 GFillPointTopologyPVS(EdgeF, G1, PVS);
696 //firstly we detect paves with equal params
699 // Add Paves to a standard list rather than to a PaveSet to avoid
700 // possible sequence disturbance in InitLoop.
701 // Check points for equality in both 3d and 1d spaces using maximum
702 // of tolerances of the edge and compared vertices, in 1d using resolution
703 // on edge from that value
705 TopOpeBRepBuild_ListOfPave aPVSlist;
706 TopTools_DataMapOfShapeListOfInteger aVerOriMap;
708 BRepAdaptor_Curve aCurveAdaptor(TopoDS::Edge(anEdge));
709 Standard_Real tolEdge = BRep_Tool::Tolerance(TopoDS::Edge(anEdge));
711 while (PVS.MoreLoop()) {
712 Handle(TopOpeBRepBuild_Pave) aPave1=Handle(TopOpeBRepBuild_Pave)::DownCast(PVS.Loop());
713 const TopoDS_Vertex& aV1= TopoDS::Vertex(aPave1->Vertex());
714 aPar1 = aPave1->Parameter();
717 if (!PVS.MoreLoop()) {
718 aPVSlist.Append(aPave1);
722 Handle(TopOpeBRepBuild_Pave) aPave2=Handle(TopOpeBRepBuild_Pave)::DownCast(PVS.Loop());
723 const TopoDS_Vertex& aV2= TopoDS::Vertex(aPave2->Vertex());
724 aPar2 = aPave2->Parameter();
726 Standard_Real tolV1 = BRep_Tool::Tolerance(aV1);
727 Standard_Real tolV2 = BRep_Tool::Tolerance(aV2);
728 Standard_Real tolMax = Max(tolEdge,Max(tolV1,tolV2));
729 Standard_Real resol = aCurveAdaptor.Resolution(tolMax);
730 Standard_Real delta = Abs(aPar1 - aPar2);
733 Standard_Real dist = BRep_Tool::Pnt(aV1).Distance(BRep_Tool::Pnt(aV2));
734 if (dist < tolMax || delta < Precision::PConfusion()) {
736 TopOpeBRepDS_Kind IntType1 = aPave1 -> InterferenceType();
737 Standard_Boolean Int3d1 = (IntType1 == TopOpeBRepDS_FACE);
738 Standard_Boolean HasSDV1 = myDataStructure->HasSameDomain(aV1);
739 Standard_Boolean HasSDV2 = myDataStructure->HasSameDomain(aV2);
740 Standard_Boolean UsedV1 = theUsedVertexMap.Contains(aV1);
741 Standard_Boolean UsedV2 = theUsedVertexMap.Contains(aV2);
743 Standard_Boolean takeFirst = Standard_True;
745 else if(HasSDV2) takeFirst = Standard_False;
747 else if(UsedV2) takeFirst = Standard_False;
749 else takeFirst = Standard_False;
751 Standard_Boolean HasSDV;
752 TopAbs_Orientation anOriOpp;
754 aPVSlist.Append(aPave1);
755 aVer = aV1; HasSDV = HasSDV1; anOriOpp = aV2.Orientation();
758 aPVSlist.Append(aPave2);
759 aVer = aV2; HasSDV = HasSDV2; anOriOpp = aV1.Orientation();
762 if (aV1.Orientation() != aV2.Orientation()) {
763 // MSV: save orientation of removed vertex
764 TColStd_ListOfInteger thelist;
765 if (!aVerOriMap.IsBound(aVer)) aVerOriMap.Bind(aVer, thelist);
766 TColStd_ListOfInteger& anOriList = aVerOriMap(aVer);
767 anOriList.Append(takeFirst);
768 anOriList.Append(anOriOpp);
769 // mark this vertex as having unknown state
771 Standard_Integer iref = myDataStructure->SameDomainReference(aVer);
772 aVer = myDataStructure->Shape(iref);
774 theUnkStateVer.Add(aVer);
781 aPVSlist.Append(aPave1);
784 TopOpeBRepBuild_ListIteratorOfListOfPave aPVSit(aPVSlist);
785 while (aPVSit.More()) {
786 Handle(TopOpeBRepBuild_Pave) aPave1 = aPVSit.Value();
787 TopoDS_Shape aV1= aPave1->Vertex();
788 aV1.Orientation(TopAbs_FORWARD);
789 aPar1 = aPave1->Parameter();
790 anOr1=(aPave1->Vertex()).Orientation();
791 if (aVerOriMap.IsBound(aV1)) {
792 // MSV: restore orientation of removed vertex
793 TColStd_ListOfInteger& anOriList = aVerOriMap(aV1);
794 if (!anOriList.IsEmpty()) {
795 if (anOriList.First()) {
796 TColStd_ListIteratorOfListOfInteger it(anOriList); it.Next();
797 anOr1 = (TopAbs_Orientation) it.Value();
799 anOriList.RemoveFirst(); anOriList.RemoveFirst();
805 if (!aPVSit.More()) break;
807 Handle(TopOpeBRepBuild_Pave) aPave2 = aPVSit.Value();
808 TopoDS_Shape aV2= aPave2->Vertex();
809 aV2.Orientation(TopAbs_REVERSED);
810 aPar2 = aPave2->Parameter();
811 anOr2=(aPave2->Vertex()).Orientation();
812 if (aVerOriMap.IsBound(aV2)) {
813 TColStd_ListOfInteger& anOriList = aVerOriMap(aV2);
814 if (!anOriList.IsEmpty()) {
815 if (!anOriList.First()) {
816 TColStd_ListIteratorOfListOfInteger it(anOriList); it.Next();
817 anOr2 = (TopAbs_Orientation) it.Value();
822 // MSV: avoid creation of an edge with invalid range
823 if (aPar1 > aPar2) continue;
825 Standard_Boolean HasSDV1 = myDataStructure->HasSameDomain(aV1);
826 Standard_Boolean HasSDV2 = myDataStructure->HasSameDomain(aV2);
827 if (HasSDV1) { // on prend le vertex reference de V
828 Standard_Integer iref = myDataStructure->SameDomainReference(aV1);
829 aV1 = myDataStructure->Shape(iref);
830 aV1.Orientation(TopAbs_FORWARD);
833 if (HasSDV2) { // on prend le vertex reference de V
834 Standard_Integer iref = myDataStructure->SameDomainReference(aV2);
835 aV2 = myDataStructure->Shape(iref);
836 aV2.Orientation(TopAbs_REVERSED);
839 // Make new edge from EdgeF
840 TopoDS_Edge aNewEdge;
841 myBuildTool.CopyEdge (EdgeF, aNewEdge);
843 myBuildTool.AddEdgeVertex (aNewEdge, aV1);
844 myBuildTool.Parameter (aNewEdge, aV1, aPar1);
846 myBuildTool.AddEdgeVertex (aNewEdge, aV2);
847 myBuildTool.Parameter (aNewEdge, aV2, aPar2);
851 TopAbs_State aState=TopAbs_IN;
853 if (anOr1==TopAbs_FORWARD && anOr2==TopAbs_REVERSED) aState=TopAbs_OUT;
854 if (anOr1==TopAbs_FORWARD && anOr2==TopAbs_INTERNAL) aState=TopAbs_OUT;
855 if (anOr1==TopAbs_INTERNAL && anOr2==TopAbs_REVERSED) aState=TopAbs_OUT;
857 if (anOr1==TopAbs_INTERNAL && anOr2==TopAbs_INTERNAL) aState=TopAbs_OUT;
858 //printf(" anOr1=%d, anOr2=%d\n", anOr1, anOr2);
860 // set old orientation to new edge;
861 aNewEdge.Orientation (anEdge.Orientation());
862 aLNew.Append(aNewEdge);
863 aDataMapOfShapeState.Bind(aNewEdge, aState);
865 //GEDBUMakeEdges(EdgeF,EDBU,aListOfShape);
868 static TopAbs_State ClassifyEdgeToSolidByOnePoint(const TopoDS_Edge& E,
869 TopOpeBRepTool_ShapeClassifier& SC)
871 Standard_Real f2 = 0., l2 = 0., par = 0.;
873 Handle(Geom_Curve) C3D = BRep_Tool::Curve(E, f2, l2);
877 //it means that we are in degenerated edge
878 const TopoDS_Vertex& fv = TopExp::FirstVertex(E);
880 return TopAbs_UNKNOWN;
881 aP3d = BRep_Tool::Pnt(fv);
884 par = f2*PAR_T + (1 - PAR_T)*l2;
885 C3D -> D0(par, aP3d);
888 SC.StateP3DReference(aP3d);