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.
18 #include <BRep_Builder.hxx>
19 #include <BRep_Tool.hxx>
20 #include <BRepAdaptor_Curve.hxx>
21 #include <BRepTools.hxx>
22 #include <Geom_Curve.hxx>
24 #include <Precision.hxx>
25 #include <Standard_NoSuchObject.hxx>
26 #include <TCollection_AsciiString.hxx>
27 #include <TColStd_ListIteratorOfListOfInteger.hxx>
30 #include <TopoDS_Edge.hxx>
31 #include <TopoDS_Face.hxx>
32 #include <TopoDS_Shape.hxx>
33 #include <TopoDS_Vertex.hxx>
34 #include <TopoDS_Wire.hxx>
35 #include <TopOpeBRepBuild_Builder.hxx>
36 #include <TopOpeBRepBuild_EdgeBuilder.hxx>
37 #include <TopOpeBRepBuild_FaceBuilder.hxx>
38 #include <TopOpeBRepBuild_GTool.hxx>
39 #include <TopOpeBRepBuild_GTopo.hxx>
40 #include <TopOpeBRepBuild_HBuilder.hxx>
41 #include <TopOpeBRepBuild_ListOfListOfLoop.hxx>
42 #include <TopOpeBRepBuild_Loop.hxx>
43 #include <TopOpeBRepBuild_Pave.hxx>
44 #include <TopOpeBRepBuild_PaveSet.hxx>
45 #include <TopOpeBRepBuild_ShapeSet.hxx>
46 #include <TopOpeBRepBuild_ShellFaceSet.hxx>
47 #include <TopOpeBRepBuild_SolidBuilder.hxx>
48 #include <TopOpeBRepBuild_Tools.hxx>
49 #include <TopOpeBRepBuild_WireEdgeSet.hxx>
50 #include <TopOpeBRepDS_BuildTool.hxx>
51 #include <TopOpeBRepDS_CurveIterator.hxx>
52 #include <TopOpeBRepDS_DataMapIteratorOfDataMapOfShapeState.hxx>
53 #include <TopOpeBRepDS_DataMapOfShapeState.hxx>
54 #include <TopOpeBRepDS_DataStructure.hxx>
55 #include <TopOpeBRepDS_HDataStructure.hxx>
56 #include <TopOpeBRepDS_IndexedDataMapOfShapeWithState.hxx>
57 #include <TopOpeBRepDS_Interference.hxx>
58 #include <TopOpeBRepDS_ListIteratorOfListOfInterference.hxx>
59 #include <TopOpeBRepDS_ListOfInterference.hxx>
60 #include <TopOpeBRepDS_ListOfShapeOn1State.hxx>
61 #include <TopOpeBRepDS_PointIterator.hxx>
62 #include <TopOpeBRepDS_ShapeWithState.hxx>
63 #include <TopOpeBRepDS_SurfaceIterator.hxx>
64 #include <TopOpeBRepTool_ShapeExplorer.hxx>
65 #include <TopTools_DataMapOfShapeListOfInteger.hxx>
66 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
67 #include <TopTools_IndexedMapOfShape.hxx>
68 #include <TopTools_MapIteratorOfMapOfShape.hxx>
69 #include <TopTools_MapOfShape.hxx>
71 //define parameter division number as 10*e^(-PI) = 0.43213918
72 const Standard_Real PAR_T = 0.43213918;
74 static TopAbs_State ClassifyEdgeToSolidByOnePoint(const TopoDS_Edge& E,
75 TopOpeBRepTool_ShapeClassifier& SC);
77 //=======================================================================
78 // : Definition the States of Shape's Entities for an Object
79 // : and a Tool. Thu Oct 7 09:38:29 1999
80 //=======================================================================
82 static TopTools_IndexedMapOfShape processedEdges;
83 static TopTools_IndexedMapOfShape theUsedVertexMap;
84 static TopTools_MapOfShape theUnkStateVer;
86 extern Standard_Boolean GLOBAL_faces2d;
88 //=======================================================================
89 //function : ~TopOpeBRepBuild_Builder1
91 //=======================================================================
92 TopOpeBRepBuild_Builder1::~TopOpeBRepBuild_Builder1()
94 processedEdges.Clear();
95 theUsedVertexMap.Clear();
96 theUnkStateVer.Clear();
102 void DumpMapOfShapeWithState (const Standard_Integer iP,
103 const TopOpeBRepDS_IndexedDataMapOfShapeWithState& aMapOfShapeWithState)
105 static Standard_Integer cnt=0;
106 TCollection_AsciiString aFName1 ("/DEBUG/TOPOPE/"), postfix;
108 Standard_CString ShapeType [9] = {"COMPO", "COMPS", "SOLID", "SHELL", "FACE ", "WIRE ", "EDGE ", "VERTX"};
109 Standard_CString ShapeState[4] = {"IN ", "OUT", "ON ", "UNKNOWN"};
111 printf("\n\n********************************\n");
113 Standard_Integer i, n=aMapOfShapeWithState.Extent();
115 printf("* Object comparing with TOOL *\n");
116 postfix=TCollection_AsciiString("Obj");
120 printf("* Tool comparing with Object *\n");
121 postfix=TCollection_AsciiString("Tool");
125 printf("********************************\n");
126 printf("*** aMapOfShapeWithState.Extent()=%d\n", n);
127 printf(" C O N T E N T S\n");
129 TCollection_AsciiString aFName;
133 for (i=1; i<=n; i++) {
134 TCollection_AsciiString aI(i), aName;
135 aName+=aFName; aName+=aI;
137 const TopoDS_Shape& aShape=aMapOfShapeWithState.FindKey(i);
138 const TopOpeBRepDS_ShapeWithState& aShapeWithState=
139 aMapOfShapeWithState.FindFromIndex(i);
141 BRepTools::Write (aShape, aName.ToCString());
143 TCollection_AsciiString ann;
144 ann+=postfix; ann+=aI;
146 printf("Key: %-8s , " , ann.ToCString());
147 printf("%s, ", ShapeType[aShape.ShapeType()]);
149 printf("State comp.with Tool=%s\n", ShapeState[aShapeWithState.State()]);
152 printf("State comp.with Obj =%s\n", ShapeState[aShapeWithState.State()]);
154 if (aShapeWithState.IsSplitted()) {
156 const TopTools_ListOfShape& aListOfShape=aShapeWithState.Part(TopAbs_IN);
157 TopTools_ListIteratorOfListOfShape anIt(aListOfShape);
158 for (;anIt.More(); anIt.Next()) {
159 const TopoDS_Shape& aS=anIt.Value();
161 TCollection_AsciiString cn(cnt), prefix("_S_"), sn;
162 sn+=aFName; sn+=prefix; sn+=cn;
163 BRepTools::Write (aS, sn.ToCString());
165 TCollection_AsciiString an;//=postfix+prefix+cn;
166 an+=postfix; an+=prefix; an+=cn;
167 printf(" -> Splitted Part IN : %s\n", an.ToCString());
171 const TopTools_ListOfShape& aListOfShapeOut=aShapeWithState.Part(TopAbs_OUT);
172 anIt.Initialize (aListOfShapeOut);
173 for (;anIt.More(); anIt.Next()) {
174 const TopoDS_Shape& aS=anIt.Value();
176 TCollection_AsciiString cn(cnt), prefix("_S_"), sn;//=aFName+prefix+cn;
177 sn+=aFName; sn+=prefix; sn+=cn;
178 BRepTools::Write (aS, sn.ToCString());
180 TCollection_AsciiString an;//=postfix+prefix+cn;
181 an+=postfix; an+=prefix; an+=cn;
182 printf(" -> Splitted Part OUT: %-s\n", an.ToCString());
186 const TopTools_ListOfShape& aListOfShapeOn=aShapeWithState.Part(TopAbs_ON);
187 anIt.Initialize (aListOfShapeOn);
188 for (;anIt.More(); anIt.Next()) {
189 const TopoDS_Shape& aS=anIt.Value();
191 TCollection_AsciiString cn(cnt), prefix("_S_"), sn;//=aFName+prefix+cn;
192 sn+=aFName; sn+=prefix; sn+=cn;
193 BRepTools::Write (aS, sn.ToCString());
195 TCollection_AsciiString an;//=postfix+prefix+cn;
196 an+=postfix; an+=prefix; an+=cn;
197 printf(" -> Splitted Part ON : %s\n", an.ToCString());
206 } // anonymous namespace
209 //=======================================================================
210 //function : PerformShapeWithStates
212 //=======================================================================
213 void TopOpeBRepBuild_Builder1::PerformShapeWithStates()
215 theUsedVertexMap.Clear();
216 theUnkStateVer.Clear();
217 myDataStructure -> ChangeDS().ChangeMapOfShapeWithStateObj().Clear();
218 myDataStructure -> ChangeDS().ChangeMapOfShapeWithStateTool().Clear();
219 //modified by NIZHNY-MZV Mon Feb 21 13:30:05 2000
220 //process section curves
221 Standard_Integer i, nbC = myDataStructure -> DS().NbCurves();
222 for(i = 1; i <= nbC; i++) {
223 TopTools_ListOfShape& LSE = ChangeNewEdges(i);
224 TopTools_ListIteratorOfListOfShape it(LSE);
225 for(; it.More(); it.Next()) {
226 const TopoDS_Shape& E = it.Value();
227 TopoDS_Vertex Vf, Vl;
228 TopExp::Vertices(TopoDS::Edge(E), Vf, Vl);
229 theUsedVertexMap.Add(Vf);
230 theUsedVertexMap.Add(Vl);
234 //process section edges
235 const TopOpeBRepDS_DataStructure& BDS = myDataStructure->DS();
236 Standard_Integer n = BDS.NbSectionEdges();
237 for (i = 1; i <= n; i++) {
238 TopTools_ListIteratorOfListOfShape anIt;
239 const TopoDS_Edge& E = TopoDS::Edge(BDS.SectionEdge(i));
240 if(E.IsNull()) continue;
242 const TopTools_ListOfShape& SplitsON = Splits(E, TopAbs_ON);
243 anIt.Initialize (SplitsON);
244 for (; anIt.More(); anIt.Next()) {
245 TopoDS_Shape aNewEdge=anIt.Value();
246 TopoDS_Vertex Vf, Vl;
247 TopExp::Vertices(TopoDS::Edge(aNewEdge), Vf, Vl);
248 theUsedVertexMap.Add(Vf);
249 theUsedVertexMap.Add(Vl);
253 const TopTools_ListOfShape& SplitsIN = Splits(E, TopAbs_IN);
254 anIt.Initialize (SplitsIN);
255 for (; anIt.More(); anIt.Next()) {
256 TopoDS_Shape aNewEdge=anIt.Value();
257 TopoDS_Vertex Vf, Vl;
258 TopExp::Vertices(TopoDS::Edge(aNewEdge), Vf, Vl);
259 theUsedVertexMap.Add(Vf);
260 theUsedVertexMap.Add(Vl);
264 const TopTools_ListOfShape& SplitsOUT = Splits(E, TopAbs_OUT);
265 anIt.Initialize (SplitsOUT);
266 for (; anIt.More(); anIt.Next()) {
267 TopoDS_Shape aNewEdge=anIt.Value();
268 TopoDS_Vertex Vf, Vl;
269 TopExp::Vertices(TopoDS::Edge(aNewEdge), Vf, Vl);
270 theUsedVertexMap.Add(Vf);
271 theUsedVertexMap.Add(Vl);
275 //modified by NIZHNY-MZV Tue Apr 11 17:32:05 2000
276 //1) Add both arguments to facilitate the search
277 TopOpeBRepDS_ShapeWithState aShapeWithState;
278 TopOpeBRepDS_DataStructure& aDataStructure=myDataStructure->ChangeDS();
280 TopOpeBRepDS_IndexedDataMapOfShapeWithState& aMapOfShapeWithStateObj=
281 aDataStructure.ChangeMapOfShapeWithStateObj();
282 TopOpeBRepDS_IndexedDataMapOfShapeWithState& aMapOfShapeWithStateTool=
283 aDataStructure.ChangeMapOfShapeWithStateTool();
285 aMapOfShapeWithStateObj.Add(myShape1, aShapeWithState);
286 aMapOfShapeWithStateTool.Add(myShape2, aShapeWithState);
288 //2) Add all rejected shapes as OUT
290 TopTools_IndexedMapOfShape& aMapOfRejectedShapesObj=
291 aDataStructure.ChangeMapOfRejectedShapesObj();
292 TopTools_IndexedMapOfShape& aMapOfRejectedShapesTool=
293 aDataStructure.ChangeMapOfRejectedShapesTool();
295 aShapeWithState.SetIsSplitted (Standard_False);
296 aShapeWithState.SetState (TopAbs_OUT);
298 Standard_Integer iW, j, nW, nE,
299 nRSObj = aMapOfRejectedShapesObj.Extent(),
300 nRSTool = aMapOfRejectedShapesTool.Extent();
302 for(i = 1; i <= nRSObj; i++) {
303 const TopoDS_Shape& aFace = aMapOfRejectedShapesObj(i);
304 if(aFace.ShapeType() != TopAbs_FACE)
306 TopTools_IndexedMapOfShape aWiresMap;
308 TopExp::MapShapes (aFace, TopAbs_WIRE, aWiresMap);
309 nW=aWiresMap.Extent ();
310 for (iW=1; iW<=nW; iW++) {
311 const TopoDS_Shape& aWire=aWiresMap(iW);
313 TopTools_IndexedMapOfShape anEdgesMap;
314 TopExp::MapShapes (aWire, TopAbs_EDGE, anEdgesMap);
315 nE=anEdgesMap.Extent ();
316 for (j=1; j<=nE; j++)
317 aMapOfShapeWithStateObj.Add(anEdgesMap(j), aShapeWithState); // add edge
319 aMapOfShapeWithStateObj.Add(aWire, aShapeWithState); // add wire
321 aMapOfShapeWithStateObj.Add(aFace, aShapeWithState); // add face
324 for(i = 1; i <= nRSTool; i++) {
325 const TopoDS_Shape& aFace = aMapOfRejectedShapesTool(i);
326 //modified by NIZHNY-MZV Wed Apr 5 10:27:18 2000
327 if(aFace.ShapeType() != TopAbs_FACE)
329 TopTools_IndexedMapOfShape aWiresMap;
330 TopExp::MapShapes (aFace, TopAbs_WIRE, aWiresMap);
331 nW=aWiresMap.Extent ();
332 for (iW=1; iW<=nW; iW++) {
333 const TopoDS_Shape& aWire=aWiresMap(iW);
335 TopTools_IndexedMapOfShape anEdgesMap;
336 TopExp::MapShapes (aWire, TopAbs_EDGE, anEdgesMap);
337 nE=anEdgesMap.Extent ();
338 for (j=1; j<=nE; j++)
339 aMapOfShapeWithStateTool.Add(anEdgesMap(j), aShapeWithState); // add edge
341 aMapOfShapeWithStateTool.Add(aWire, aShapeWithState); // add wire
343 aMapOfShapeWithStateTool.Add(aFace, aShapeWithState); // add face
346 PerformShapeWithStates (myShape1, myShape2);
347 processedEdges.Clear();
348 PerformShapeWithStates (myShape2, myShape1);
349 processedEdges.Clear();
351 // printf(" ..::PerformShapeWithStates() [Dump is off]\n");
353 /* printf(" ..::PerformShapeWithStates() [Dump is on]\n");
355 TopOpeBRepDS_DataStructure& aDS= myDataStructure-> ChangeDS();
357 TopOpeBRepDS_IndexedDataMapOfShapeWithState& aMapOfShapeWithStateObj=
358 aDS.ChangeMapOfShapeWithStateObj();
360 TopOpeBRepDS_IndexedDataMapOfShapeWithState& aMapOfShapeWithStateTool=
361 aDS.ChangeMapOfShapeWithStateTool();
363 DumpMapOfShapeWithState(0, aMapOfShapeWithStateObj);
364 DumpMapOfShapeWithState(1, aMapOfShapeWithStateTool);
371 //=======================================================================
372 //function :PerformShapeWithStates
374 //=======================================================================
375 void TopOpeBRepBuild_Builder1::PerformShapeWithStates (const TopoDS_Shape& anObj,
376 const TopoDS_Shape& aReference)
378 myShapeClassifier.SetReference(aReference);
379 TopOpeBRepDS_DataStructure& aDS= myDataStructure-> ChangeDS();
380 // Get aMapOfShapeWithState for Obj
381 Standard_Boolean aFlag;
382 TopOpeBRepDS_IndexedDataMapOfShapeWithState& aMapOfShapeWithState=
383 aDS.ChangeMapOfShapeWithState(anObj, aFlag);
386 Standard_Integer i, j, k, nS, nF, nE;
388 TopTools_IndexedMapOfShape aFacesMap, aFacesWithInterferencesMap, aFacesToRestMap;
389 TopOpeBRepDS_DataMapOfShapeState aSplFacesState;
391 TopTools_IndexedMapOfShape aShellsMap;
392 TopExp::MapShapes(anObj, TopAbs_SHELL, aShellsMap);
394 nS=aShellsMap.Extent();
395 for (i=1; i<=nS; i++) {
396 const TopoDS_Shape& aShell = aShellsMap(i);
398 if (aMapOfShapeWithState.Contains (aShell)) continue;
400 else if (!myDataStructure -> HasShape(aShell)) {
401 // Shell has no interference.
402 // So, define its state and push into the Map as is.// A.1
403 TopOpeBRepBuild_Tools::FindStateThroughVertex (aShell, myShapeClassifier,
404 aMapOfShapeWithState, theUnkStateVer);
409 // Shell has interference. Try to separate it into FacesToRest and InterferredFace
411 aFacesWithInterferencesMap.Clear();
412 aFacesToRestMap.Clear();
413 aSplFacesState.Clear();
415 TopExp::MapShapes (aShell, TopAbs_FACE, aFacesMap);
416 nF=aFacesMap.Extent();
417 for (j=1; j<=nF; j++) {
418 const TopoDS_Shape& aFace = aFacesMap(j);
420 if (aMapOfShapeWithState.Contains (aFace)) {
422 // if the face is known, its edges are also known.
423 // We just insert this info. into aSplFacesState in order to
424 // propagate the state for faces with unknown states.
425 TopTools_IndexedMapOfShape anEdgesMap;
426 TopExp::MapShapes (aFace, TopAbs_EDGE, anEdgesMap);
427 nE=anEdgesMap.Extent();
428 for (k=1; k<=nE; k++) {
429 const TopoDS_Shape& anEdge=anEdgesMap(k);
430 const TopOpeBRepDS_ShapeWithState& aSWS=
431 aMapOfShapeWithState.FindFromKey(anEdge);
432 TopAbs_State aState=aSWS.State();
433 aSplFacesState.Bind (anEdge, aState);
437 else if (myDataStructure -> HasShape(aFace))
438 aFacesWithInterferencesMap.Add (aFace);
440 aFacesToRestMap.Add (aFace);
443 // work with aFacesWithInterferencesMap
444 PerformFacesWithStates (anObj, aFacesWithInterferencesMap, aSplFacesState);
446 // Propagate the States for all unknown faces from aFacesToRestMap
447 TopTools_MapOfShape anUnkStateEdge;
448 TopOpeBRepBuild_Tools::PropagateState (aSplFacesState,aFacesToRestMap,
449 TopAbs_EDGE, TopAbs_FACE, myShapeClassifier,
450 aMapOfShapeWithState, anUnkStateEdge);
451 ///// Propagate on WIres from aFacesToRestMap
452 TopOpeBRepBuild_Tools::PropagateStateForWires (aFacesToRestMap, aMapOfShapeWithState);
457 //=======================================================================
458 //function :PerformFacesWithStates
460 //=======================================================================
461 void TopOpeBRepBuild_Builder1::PerformFacesWithStates (const TopoDS_Shape& anObj,
462 const TopTools_IndexedMapOfShape& aFacesWithInterferencesMap,
463 TopOpeBRepDS_DataMapOfShapeState& aSplFacesState)
465 TopOpeBRepDS_DataStructure& aDS= myDataStructure-> ChangeDS();
466 // Get aMapOfShapeWithState for Obj
467 Standard_Boolean aFlag;
468 TopOpeBRepDS_IndexedDataMapOfShapeWithState& aMapOfShapeWithState=aDS.ChangeMapOfShapeWithState(anObj, aFlag);
472 Standard_Integer i, j, k, nF, nW, nE;
474 nF=aFacesWithInterferencesMap.Extent();
476 for (i=1; i<=nF; i++) {
477 TopTools_IndexedMapOfShape anEdgesToSplitMap, anEdgesToRestMap;
479 const TopoDS_Shape& aFace = aFacesWithInterferencesMap(i);
481 TopTools_IndexedMapOfShape aWireMap;
482 TopExp::MapShapes (aFace, TopAbs_WIRE, aWireMap);
483 nW=aWireMap.Extent();
484 for (j=1; j<=nW; j++) {
485 const TopoDS_Shape& aWire=aWireMap(j);
487 if (!myDataStructure -> HasShape(aWire)) {
488 // Wire has no interference.
489 // So, define its state and push into the Map as is.
490 TopOpeBRepBuild_Tools::FindStateThroughVertex (aWire, myShapeClassifier,
491 aMapOfShapeWithState, theUnkStateVer);
496 // Wire has an interferences
497 TopTools_IndexedMapOfShape anEdgeMap;
498 TopExp::MapShapes (aWire, TopAbs_EDGE, anEdgeMap);
499 nE=anEdgeMap.Extent ();
500 for (k=1; k<=nE; k++) {
501 const TopoDS_Shape& anEdge=anEdgeMap(k);
503 if (myDataStructure -> HasShape(anEdge)) {
504 anEdgesToSplitMap.Add(anEdge);
507 anEdgesToRestMap.Add(anEdge);
511 // split edges and define the states for all edges and parts of edges
512 StatusEdgesToSplit (anObj, anEdgesToSplitMap, anEdgesToRestMap);
514 ////// After StatusEdgesToSplit we can find the status of each Rest Edge
515 ////// in aMapOfShapeWithState. So we can insert this info. into
516 ////// aSplFacesState in order to propagate the state for faces.
517 nE=anEdgesToRestMap.Extent();
518 for (k=1; k<=nE; k++) {
519 const TopoDS_Shape anEdge=anEdgesToRestMap(k);
520 if (aMapOfShapeWithState.Contains (anEdge)) {
521 const TopOpeBRepDS_ShapeWithState& aSWS=aMapOfShapeWithState.FindFromKey(anEdge);
522 TopAbs_State aState=aSWS.State();
523 aSplFacesState.Bind (anEdge, aState);
526 } //end of else {// Wire has an interferences
528 } // next interferred Face ... for (i=1; i<=nF; i++) ...
531 //=======================================================================
532 //function :StatusEdgesToSplit
534 //=======================================================================
535 void TopOpeBRepBuild_Builder1::StatusEdgesToSplit (const TopoDS_Shape& anObj,
536 const TopTools_IndexedMapOfShape& anEdgesToSplitMap,
537 const TopTools_IndexedMapOfShape& anEdgesToRestMap)
541 TopOpeBRepDS_DataStructure& aDS= myDataStructure-> ChangeDS();
542 // Get aMapOfShapeWithState for Obj
543 Standard_Boolean aFlag;
544 TopOpeBRepDS_IndexedDataMapOfShapeWithState& aMapOfShapeWithState=aDS.ChangeMapOfShapeWithState(anObj, aFlag);
548 Standard_Integer i, nE=anEdgesToSplitMap.Extent();
551 TopOpeBRepDS_DataMapOfShapeState aSplEdgesState;
552 TopTools_ListIteratorOfListOfShape anIt;
555 for (i=1; i<=nE; i++) {
556 const TopoDS_Shape& anEdge=anEdgesToSplitMap(i);
558 if(processedEdges.Contains(anEdge)) {
559 if (aMapOfShapeWithState.Contains(anEdge)) {
560 const TopOpeBRepDS_ShapeWithState& aSWS=
561 aMapOfShapeWithState.FindFromKey(anEdge);
562 if (aSWS.IsSplitted()) {
564 const TopTools_ListOfShape& SplitsON=aSWS.Part(TopAbs_ON);
565 anIt.Initialize (SplitsON);
566 for (; anIt.More(); anIt.Next())
567 aSplEdgesState.Bind(anIt.Value(), TopAbs_ON);
569 const TopTools_ListOfShape& SplitsOUT=aSWS.Part(TopAbs_OUT);
570 anIt.Initialize (SplitsOUT);
571 for (; anIt.More(); anIt.Next())
572 aSplEdgesState.Bind(anIt.Value(), TopAbs_OUT);
574 const TopTools_ListOfShape& SplitsIN=aSWS.Part(TopAbs_IN);
575 anIt.Initialize (SplitsIN);
576 for (; anIt.More(); anIt.Next())
577 aSplEdgesState.Bind(anIt.Value(), TopAbs_IN);
584 processedEdges.Add(anEdge);
586 TopOpeBRepDS_ShapeWithState aShapeWithState;
588 // if IsSplit - it is the case of edges from SameDomain faces
589 Standard_Boolean IsSplitON = IsSplit(anEdge, TopAbs_ON);
592 const TopTools_ListOfShape& SplitsON = Splits(anEdge, TopAbs_ON);
593 anIt.Initialize (SplitsON);
594 for (; anIt.More(); anIt.Next()) {
595 TopoDS_Shape aNewEdge=anIt.Value();
596 aNewEdge.Orientation (anEdge.Orientation());
597 aShapeWithState.AddPart (aNewEdge, TopAbs_ON);
598 aSplEdgesState.Bind(anIt.Value(), TopAbs_ON);
602 const TopTools_ListOfShape& SplitsIN = Splits(anEdge, TopAbs_IN);
603 anIt.Initialize (SplitsIN);
604 for (; anIt.More(); anIt.Next()) {
605 TopoDS_Shape aNewEdge=anIt.Value();
606 aNewEdge.Orientation (anEdge.Orientation());
607 aShapeWithState.AddPart (aNewEdge, TopAbs_IN);
608 aSplEdgesState.Bind(anIt.Value(), TopAbs_IN);
612 const TopTools_ListOfShape& SplitsOUT = Splits(anEdge, TopAbs_OUT);
613 anIt.Initialize (SplitsOUT);
614 for (; anIt.More(); anIt.Next()) {
615 TopoDS_Shape aNewEdge=anIt.Value();
616 aNewEdge.Orientation (anEdge.Orientation());
617 aShapeWithState.AddPart (aNewEdge, TopAbs_OUT);
618 aSplEdgesState.Bind(anIt.Value(), TopAbs_OUT);
621 aShapeWithState.SetIsSplitted(Standard_True);
622 aMapOfShapeWithState.Add(anEdge, aShapeWithState);
626 // Attempt to split the Edge (for all other edges (from non SameDomain Faces))
627 TopOpeBRepDS_DataMapOfShapeState aDataMapOfShapeState;
628 TopTools_ListOfShape aLNew;
630 Standard_Boolean oldState = GLOBAL_faces2d;
632 GLOBAL_faces2d = Standard_True;
633 SplitEdge (anEdge, aLNew, aDataMapOfShapeState);
634 GLOBAL_faces2d = oldState;
637 if (!aLNew.Extent()) {
638 // * It means that whole Edge is IN (see SplitEdge(...) at line
639 // G1=TopOpeBRepBuild_GTool::GFusSame(tf,tf); Operation Fuse
640 // loses all parts of the Edge with IN state, but we need
641 // to have all parts. So, we have to rest the Edge as is ...
642 // ** But the edge itself will have UNKNOWN state and one split Part with state =IN.
643 TopoDS_Vertex Vf, Vl;
644 TopExp::Vertices(TopoDS::Edge(anEdge), Vf, Vl);
646 Standard_Boolean HasSDV1 = myDataStructure->HasSameDomain(Vf);
647 Standard_Boolean HasSDV2 = myDataStructure->HasSameDomain(Vl);
649 TopoDS_Edge aNewEdge = TopoDS::Edge(anEdge);
651 //if edge has SD edges , it is error because it must be processed in SplitSectionEdges
652 //but if we here we don't do anything with it
653 if(myDataStructure -> HasSameDomain(aNewEdge)) {
654 HasSDV1 = Standard_False;
655 HasSDV2 = Standard_False;
657 //if vertices has SD we must update edge, so we copy it
658 if(HasSDV1 || HasSDV2) {
659 TopoDS_Shape EOR = anEdge;
660 EOR.Orientation(TopAbs_FORWARD);
662 Standard_Real ParF = BRep_Tool::Parameter(Vf, TopoDS::Edge(EOR));
663 Standard_Real ParL = BRep_Tool::Parameter(Vl, TopoDS::Edge(EOR));
664 myBuildTool.CopyEdge (EOR, aNewEdge);
666 if (HasSDV1) { // on prend le vertex reference de V
667 Standard_Integer iref = myDataStructure->SameDomainReference(Vf);
668 Vf = TopoDS::Vertex(myDataStructure->Shape(iref));
669 Vf.Orientation(TopAbs_FORWARD);
672 if (HasSDV2) { // on prend le vertex reference de V
673 Standard_Integer iref = myDataStructure->SameDomainReference(Vl);
674 Vl = TopoDS::Vertex(myDataStructure->Shape(iref));
675 Vl.Orientation(TopAbs_REVERSED);
678 myBuildTool.AddEdgeVertex (aNewEdge, Vf);
679 myBuildTool.Parameter (aNewEdge, Vf, ParF);
681 myBuildTool.AddEdgeVertex (aNewEdge, Vl);
682 myBuildTool.Parameter (aNewEdge, Vl, ParL);
684 aNewEdge.Orientation (anEdge.Orientation());
687 aState= ClassifyEdgeToSolidByOnePoint(aNewEdge, myShapeClassifier);
688 aShapeWithState.SetIsSplitted (Standard_True);
690 aShapeWithState.AddPart (aNewEdge, aState);
691 aSplEdgesState.Bind(aNewEdge, aState);
693 TopExp::Vertices(aNewEdge, Vf, Vl);
694 theUsedVertexMap.Add(Vf);
695 theUsedVertexMap.Add(Vl);
696 if (!BRep_Tool::Degenerated(TopoDS::Edge(aNewEdge))) {
697 // MSV: it may be the case when an edge has one state but its vertex
698 // has another state. We should clarify this to avoid incorrect
699 // propagation of state.
700 myShapeClassifier.StateP3DReference(BRep_Tool::Pnt(Vf));
701 if (myShapeClassifier.State() != aState && myShapeClassifier.State() != TopAbs_ON)
702 theUnkStateVer.Add(Vf);
703 if (!Vf.IsSame(Vl)) {
704 myShapeClassifier.StateP3DReference(BRep_Tool::Pnt(Vl));
705 if (myShapeClassifier.State() != aState && myShapeClassifier.State() != TopAbs_ON)
706 theUnkStateVer.Add(Vl);
711 // Usual case. The Edge was splitted onto several parts:
712 TopTools_ListIteratorOfListOfShape aLIt(aLNew);
713 for (; aLIt.More(); aLIt.Next()) {
714 const TopoDS_Shape& aS = aLIt.Value();
715 aState = aDataMapOfShapeState(aS);
716 ////////////////////////////////////////////////////////////////////////////
717 // ** When aState==TopAbs_IN it is not evidence that it is realy so.
718 // There are some cases when JYL does not define ON parts completely.
719 // So, as we want to have right states, we have to do it ourselves.
720 // PKV Mon 25 Oct 1999
721 Standard_Boolean isdegen = BRep_Tool::Degenerated(TopoDS::Edge(aS));
722 //if edge is degenerated we trust that it have IN state without classify
724 if (aState==TopAbs_IN && !isdegen)
725 aState= ClassifyEdgeToSolidByOnePoint(TopoDS::Edge(aS), myShapeClassifier);
727 ////////////////////////////////////////////////////////////////////////////
728 aShapeWithState.AddPart (aS, aState);
729 aShapeWithState.SetIsSplitted (Standard_True);
731 aSplEdgesState.Bind(aS, aState);
732 TopoDS_Vertex Vf, Vl;
733 TopExp::Vertices(TopoDS::Edge(aS), Vf, Vl);
734 theUsedVertexMap.Add(Vf);
735 theUsedVertexMap.Add(Vl);
737 // MSV: clarify state of vertices (see my above comment)
738 myShapeClassifier.StateP3DReference(BRep_Tool::Pnt(Vf));
739 if (myShapeClassifier.State() != aState && myShapeClassifier.State() != TopAbs_ON)
740 theUnkStateVer.Add(Vf);
741 if (!Vf.IsSame(Vl)) {
742 myShapeClassifier.StateP3DReference(BRep_Tool::Pnt(Vl));
743 if (myShapeClassifier.State() != aState && myShapeClassifier.State() != TopAbs_ON)
744 theUnkStateVer.Add(Vl);
750 const TopTools_ListOfShape& EspON = aShapeWithState.Part(TopAbs_ON);
752 Standard_Integer nON = EspON.Extent();
753 if(!IsSplitON && nON) {
754 TopOpeBRepDS_ListOfShapeOn1State ONspl;
755 TopTools_ListOfShape& lON = ONspl.ChangeListOnState();
757 ONspl.Split(Standard_True);
758 mySplitON.Bind(anEdge, ONspl);
759 myDataStructure -> ChangeDS().AddSectionEdge(TopoDS::Edge(anEdge));
762 aMapOfShapeWithState.Add(anEdge, aShapeWithState);
763 } // end for (i=1; i<=nE; i++)
765 nE=anEdgesToRestMap.Extent();
766 for (i=1; i<=nE; i++) {
767 const TopoDS_Shape& anEdge=anEdgesToRestMap.FindKey(i);
768 if (aMapOfShapeWithState.Contains (anEdge)) {
769 const TopOpeBRepDS_ShapeWithState& aSWS=
770 aMapOfShapeWithState.FindFromKey(anEdge);
771 if (!aSWS.IsSplitted()) {
774 aSplEdgesState.Bind (anEdge, aState);
781 // Propagate the status for anEdgesToRestMap edges
782 TopOpeBRepBuild_Tools::PropagateState (aSplEdgesState, anEdgesToRestMap,
783 TopAbs_VERTEX, TopAbs_EDGE, myShapeClassifier,
784 aMapOfShapeWithState, theUnkStateVer);
790 //=======================================================================
791 //function : SplitEdge
793 //=======================================================================
794 void TopOpeBRepBuild_Builder1::SplitEdge (const TopoDS_Shape& anEdge,
795 TopTools_ListOfShape& aLNew,
796 TopOpeBRepDS_DataMapOfShapeState& aDataMapOfShapeState)
798 Standard_Real aPar1, aPar2;
799 TopAbs_Orientation anOr1, anOr2;
801 // Attention! If you didn't do the orientation of the Edge =FORWARD,
802 // the GFillPointTopologyPVS() method will give you a garbage!
803 TopoDS_Shape EdgeF=anEdge;
804 EdgeF.Orientation(TopAbs_FORWARD);
806 // Make a PaveSet PVS on edge EF
807 TopOpeBRepBuild_PaveSet PVS (EdgeF);
808 TopOpeBRepBuild_GTopo G1;
809 TopAbs_ShapeEnum tf = TopAbs_FACE;
810 G1=TopOpeBRepBuild_GTool::GFusSame(tf,tf);
811 myEdgeReference = TopoDS::Edge(EdgeF);
813 GFillPointTopologyPVS(EdgeF, G1, PVS);
817 //firstly we detect paves with equal params
820 // Add Paves to a standard list rather than to a PaveSet to avoid
821 // possible sequence disturbance in InitLoop.
822 // Check points for equality in both 3d and 1d spaces using maximum
823 // of tolerances of the edge and compared vertices, in 1d using resolution
824 // on edge from that value
826 TopOpeBRepBuild_ListOfPave aPVSlist;
827 TopTools_DataMapOfShapeListOfInteger aVerOriMap;
829 BRepAdaptor_Curve aCurveAdaptor(TopoDS::Edge(anEdge));
830 Standard_Real tolEdge = BRep_Tool::Tolerance(TopoDS::Edge(anEdge));
832 while (PVS.MoreLoop()) {
833 Handle(TopOpeBRepBuild_Pave) aPave1=Handle(TopOpeBRepBuild_Pave)::DownCast(PVS.Loop());
834 const TopoDS_Vertex& aV1= TopoDS::Vertex(aPave1->Vertex());
835 aPar1 = aPave1->Parameter();
838 if (!PVS.MoreLoop()) {
839 aPVSlist.Append(aPave1);
843 Handle(TopOpeBRepBuild_Pave) aPave2=Handle(TopOpeBRepBuild_Pave)::DownCast(PVS.Loop());
844 const TopoDS_Vertex& aV2= TopoDS::Vertex(aPave2->Vertex());
845 aPar2 = aPave2->Parameter();
847 Standard_Real tolV1 = BRep_Tool::Tolerance(aV1);
848 Standard_Real tolV2 = BRep_Tool::Tolerance(aV2);
849 Standard_Real tolMax = Max(tolEdge,Max(tolV1,tolV2));
850 Standard_Real resol = aCurveAdaptor.Resolution(tolMax);
851 Standard_Real delta = Abs(aPar1 - aPar2);
854 Standard_Real dist = BRep_Tool::Pnt(aV1).Distance(BRep_Tool::Pnt(aV2));
855 if (dist < tolMax || delta < Precision::PConfusion()) {
857 TopOpeBRepDS_Kind IntType1 = aPave1 -> InterferenceType();
858 Standard_Boolean Int3d1 = (IntType1 == TopOpeBRepDS_FACE);
859 Standard_Boolean HasSDV1 = myDataStructure->HasSameDomain(aV1);
860 Standard_Boolean HasSDV2 = myDataStructure->HasSameDomain(aV2);
861 Standard_Boolean UsedV1 = theUsedVertexMap.Contains(aV1);
862 Standard_Boolean UsedV2 = theUsedVertexMap.Contains(aV2);
864 Standard_Boolean takeFirst = Standard_True;
866 else if(HasSDV2) takeFirst = Standard_False;
868 else if(UsedV2) takeFirst = Standard_False;
870 else takeFirst = Standard_False;
872 Standard_Boolean HasSDV;
873 TopAbs_Orientation anOriOpp;
875 aPVSlist.Append(aPave1);
876 aVer = aV1; HasSDV = HasSDV1; anOriOpp = aV2.Orientation();
879 aPVSlist.Append(aPave2);
880 aVer = aV2; HasSDV = HasSDV2; anOriOpp = aV1.Orientation();
883 if (aV1.Orientation() != aV2.Orientation()) {
884 // MSV: save orientation of removed vertex
885 TColStd_ListOfInteger thelist;
886 if (!aVerOriMap.IsBound(aVer)) aVerOriMap.Bind(aVer, thelist);
887 TColStd_ListOfInteger& anOriList = aVerOriMap(aVer);
888 anOriList.Append(takeFirst);
889 anOriList.Append(anOriOpp);
890 // mark this vertex as having unknown state
892 Standard_Integer iref = myDataStructure->SameDomainReference(aVer);
893 aVer = myDataStructure->Shape(iref);
895 theUnkStateVer.Add(aVer);
902 aPVSlist.Append(aPave1);
905 TopOpeBRepBuild_ListIteratorOfListOfPave aPVSit(aPVSlist);
906 while (aPVSit.More()) {
907 Handle(TopOpeBRepBuild_Pave) aPave1 = aPVSit.Value();
908 TopoDS_Shape aV1= aPave1->Vertex();
909 aV1.Orientation(TopAbs_FORWARD);
910 aPar1 = aPave1->Parameter();
911 anOr1=(aPave1->Vertex()).Orientation();
912 if (aVerOriMap.IsBound(aV1)) {
913 // MSV: restore orientation of removed vertex
914 TColStd_ListOfInteger& anOriList = aVerOriMap(aV1);
915 if (!anOriList.IsEmpty()) {
916 if (anOriList.First()) {
917 TColStd_ListIteratorOfListOfInteger it(anOriList); it.Next();
918 anOr1 = (TopAbs_Orientation) it.Value();
920 anOriList.RemoveFirst(); anOriList.RemoveFirst();
926 if (!aPVSit.More()) break;
928 Handle(TopOpeBRepBuild_Pave) aPave2 = aPVSit.Value();
929 TopoDS_Shape aV2= aPave2->Vertex();
930 aV2.Orientation(TopAbs_REVERSED);
931 aPar2 = aPave2->Parameter();
932 anOr2=(aPave2->Vertex()).Orientation();
933 if (aVerOriMap.IsBound(aV2)) {
934 TColStd_ListOfInteger& anOriList = aVerOriMap(aV2);
935 if (!anOriList.IsEmpty()) {
936 if (!anOriList.First()) {
937 TColStd_ListIteratorOfListOfInteger it(anOriList); it.Next();
938 anOr2 = (TopAbs_Orientation) it.Value();
943 // MSV: avoid creation of an edge with invalid range
944 if (aPar1 > aPar2) continue;
946 Standard_Boolean HasSDV1 = myDataStructure->HasSameDomain(aV1);
947 Standard_Boolean HasSDV2 = myDataStructure->HasSameDomain(aV2);
948 if (HasSDV1) { // on prend le vertex reference de V
949 Standard_Integer iref = myDataStructure->SameDomainReference(aV1);
950 aV1 = myDataStructure->Shape(iref);
951 aV1.Orientation(TopAbs_FORWARD);
954 if (HasSDV2) { // on prend le vertex reference de V
955 Standard_Integer iref = myDataStructure->SameDomainReference(aV2);
956 aV2 = myDataStructure->Shape(iref);
957 aV2.Orientation(TopAbs_REVERSED);
960 // Make new edge from EdgeF
961 TopoDS_Edge aNewEdge;
962 myBuildTool.CopyEdge (EdgeF, aNewEdge);
964 myBuildTool.AddEdgeVertex (aNewEdge, aV1);
965 myBuildTool.Parameter (aNewEdge, aV1, aPar1);
967 myBuildTool.AddEdgeVertex (aNewEdge, aV2);
968 myBuildTool.Parameter (aNewEdge, aV2, aPar2);
972 TopAbs_State aState=TopAbs_IN;
974 if (anOr1==TopAbs_FORWARD && anOr2==TopAbs_REVERSED) aState=TopAbs_OUT;
975 if (anOr1==TopAbs_FORWARD && anOr2==TopAbs_INTERNAL) aState=TopAbs_OUT;
976 if (anOr1==TopAbs_INTERNAL && anOr2==TopAbs_REVERSED) aState=TopAbs_OUT;
978 if (anOr1==TopAbs_INTERNAL && anOr2==TopAbs_INTERNAL) aState=TopAbs_OUT;
979 //printf(" anOr1=%d, anOr2=%d\n", anOr1, anOr2);
981 // set old orientation to new edge;
982 aNewEdge.Orientation (anEdge.Orientation());
983 aLNew.Append(aNewEdge);
984 aDataMapOfShapeState.Bind(aNewEdge, aState);
986 //GEDBUMakeEdges(EdgeF,EDBU,aListOfShape);
989 static TopAbs_State ClassifyEdgeToSolidByOnePoint(const TopoDS_Edge& E,
990 TopOpeBRepTool_ShapeClassifier& SC)
992 Standard_Real f2 = 0., l2 = 0., par = 0.;
994 Handle(Geom_Curve) C3D = BRep_Tool::Curve(E, f2, l2);
998 //it means that we are in degenerated edge
999 const TopoDS_Vertex& fv = TopExp::FirstVertex(E);
1001 return TopAbs_UNKNOWN;
1002 aP3d = BRep_Tool::Pnt(fv);
1005 par = f2*PAR_T + (1 - PAR_T)*l2;
1006 C3D -> D0(par, aP3d);
1009 SC.StateP3DReference(aP3d);