1 // Created on: 1998-05-20
2 // Created by: Didier PIFFAULT
3 // Copyright (c) 1998-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
9 // under the terms of the GNU Lesser General Public 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 <BRepLib_MakeWire.ixx>
18 #include <BRepLib.hxx>
19 #include <TopTools_MapOfShape.hxx>
20 #include <TopTools_MapOfOrientedShape.hxx>
21 #include <TopTools_MapIteratorOfMapOfShape.hxx>
22 #include <TopTools_MapIteratorOfMapOfOrientedShape.hxx>
23 #include <TopTools_DataMapOfShapeShape.hxx>
24 #include <TopTools_ListOfShape.hxx>
25 #include <TopTools_ListIteratorOfListOfShape.hxx>
26 #include <BRep_Builder.hxx>
28 #include <TopExp_Explorer.hxx>
30 #include <TopoDS_Vertex.hxx>
31 #include <TopoDS_Edge.hxx>
32 #include <TopoDS_Compound.hxx>
33 #include <BRep_Tool.hxx>
35 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
38 //=======================================================================
40 //purpose : Add the list of edges to the current wire
41 //=======================================================================
43 void BRepLib_MakeWire::Add(const TopTools_ListOfShape& L)
45 myError = BRepLib_WireDone;
46 if (!myShape.IsNull()) myShape.Closed(Standard_False);
50 TopTools_MapOfShape mapLocale;
51 mapLocale.Assign(myVertices);
52 TopTools_DataMapOfShapeShape toCopy;
53 TopTools_ListOfShape toAdd, nlist, rlist;
57 TopTools_MapIteratorOfMapOfShape itMS;
58 TopTools_ListIteratorOfListOfShape itList(L);
59 for (;itList.More(); itList.Next()) {
60 const TopoDS_Edge& curEd=TopoDS::Edge(itList.Value());
61 if (!curEd.IsNull()) {
64 Standard_Boolean copEd=Standard_False;
65 if (myEdge.IsNull()) {
67 if (!VF.IsNull()) mapLocale.Add(VF);
68 if (!VL.IsNull()) mapLocale.Add(VL);
72 for (exv.Init(curEd, TopAbs_VERTEX); exv.More(); exv.Next()) {
73 const TopoDS_Vertex& edVer=TopoDS::Vertex(exv.Current());
76 if (!mapLocale.Contains(edVer)) {
77 Standard_Boolean notYetFound = Standard_True;
78 Standard_Real gap=BRep_Tool::Tolerance(edVer);
79 gp_Pnt pVer=BRep_Tool::Pnt(edVer);
80 for (itMS.Initialize(mapLocale); itMS.More(); itMS.Next()) {
81 notYetFound=Standard_True;
82 const TopoDS_Vertex& refVer=TopoDS::Vertex(itMS.Key());
83 gap +=BRep_Tool::Tolerance(refVer);
84 if (pVer.Distance(BRep_Tool::Pnt(TopoDS::Vertex(refVer))) <= gap) {
86 nlist.Prepend(refVer.Oriented(edVer.Orientation()));
88 notYetFound=Standard_False;
92 if (notYetFound) mapLocale.Add(edVer);
96 TopoDS_Shape aLocalShape = curEd.EmptyCopied();
97 TopoDS_Edge newEd=TopoDS::Edge(aLocalShape);
98 // TopoDS_Edge newEd=TopoDS::Edge(curEd.EmptyCopied());
99 BB.Transfert(curEd, newEd);
100 newEd.Closed(curEd.Closed());
101 TopTools_ListIteratorOfListOfShape itV(nlist);
102 for (; itV.More(); itV.Next()) {
103 BB.Add(newEd, itV.Value());
104 BB.Transfert(curEd, newEd, TopoDS::Vertex(rlist.First()), TopoDS::Vertex(itV.Value()));
114 if (!toAdd.IsEmpty()) {
115 TopoDS_Compound comp;
116 BB.MakeCompound(comp);
117 TopTools_MapIteratorOfMapOfOrientedShape itMOS;
118 TopTools_MapOfOrientedShape theEdges;
119 for (itList.Initialize(toAdd); itList.More(); itList.Next()) {
120 BB.Add(comp, itList.Value());
121 theEdges.Add(itList.Value());
123 TopTools_IndexedDataMapOfShapeListOfShape lesMeres;
124 TopExp::MapShapesAndAncestors(comp, TopAbs_VERTEX, TopAbs_EDGE, lesMeres);
125 TopoDS_Vertex vf, vl;
127 Standard_Boolean usedVertex;
128 Standard_Boolean closedEdge = Standard_False;
129 Standard_Integer vvInd, lastInd;
131 if (!VL.IsNull() && lesMeres.Contains(VL)) {
132 if (!VF.IsNull()) closedEdge=VF.IsSame(VL);
133 usedVertex=Standard_True;
134 for (itList.Initialize(lesMeres.FindFromKey(VL)); itList.More(); itList.Next()) {
135 if (theEdges.Contains(itList.Value())) {
136 usedVertex=Standard_False;
137 theEdges.Remove(itList.Value());
138 TopExp::Vertices(TopoDS::Edge(itList.Value()), vf,vl);
140 BB.Add(myShape, itList.Value());
146 BB.Add(myShape, itList.Value());
150 BB.Add(myShape, itList.Value().Reversed());
159 lastInd=lesMeres.Extent();
160 vvInd=lesMeres.FindIndex(VL);
161 if (vvInd != lastInd) {
162 theKey=lesMeres.FindKey(lastInd);
163 nlist=lesMeres.FindFromIndex(lastInd);
165 lesMeres.RemoveLast();
166 if (vvInd != lastInd) {
167 lesMeres.Substitute(vvInd, theKey, nlist);
171 else if (!VF.IsNull() && lesMeres.Contains(VF)) {
172 usedVertex=Standard_True;
173 for (itList.Initialize(lesMeres.FindFromKey(VF)); itList.More(); itList.Next()) {
174 if (theEdges.Contains(itList.Value())) {
175 usedVertex=Standard_False;
176 theEdges.Remove(itList.Value());
177 TopExp::Vertices(TopoDS::Edge(itList.Value()), vf,vl);
179 BB.Add(myShape, itList.Value());
184 BB.Add(myShape, itList.Value().Reversed());
192 lastInd=lesMeres.Extent();
193 vvInd=lesMeres.FindIndex(VF);
194 if (vvInd != lastInd) {
195 theKey=lesMeres.FindKey(lastInd);
196 nlist=lesMeres.FindFromIndex(lastInd);
198 lesMeres.RemoveLast();
199 if (vvInd != lastInd) {
200 lesMeres.Substitute(vvInd, theKey, nlist);
205 if (theEdges.Extent()>0) {
206 Standard_Boolean noCandidat=Standard_True;
207 for (itMOS.Initialize(theEdges); itMOS.More(); itMOS.Next()) {
208 TopExp::Vertices(TopoDS::Edge(itMOS.Key()), vf,vl);
209 if (myVertices.Contains(vl)) {
210 if (myError==BRepLib_WireDone) myError = BRepLib_NonManifoldWire;
211 BB.Add(myShape, itMOS.Key());
214 noCandidat=Standard_False;
217 else if (myVertices.Contains(vf)) {
218 if (myError==BRepLib_WireDone) myError = BRepLib_NonManifoldWire;
219 BB.Add(myShape, itMOS.Key());
222 noCandidat=Standard_False;
228 // Some Edges are not connected to first edge and the diagnosis is as follows
229 // but the "Maker" is Done() because otherwise it is not possible to return the constructed connected part...
230 myError=BRepLib_DisconnectedWire;
232 else theEdges.Remove(itMOS.Key());
235 } while (theEdges.Extent()>0);
239 if (!VF.IsNull() && !VL.IsNull() && VF.IsSame(VL))
240 myShape.Closed(Standard_True);