b311480e |
1 | // Created on: 1998-05-20 |
2 | // Created by: Didier PIFFAULT |
3 | // Copyright (c) 1998-1999 Matra Datavision |
973c2be1 |
4 | // Copyright (c) 1999-2014 OPEN CASCADE SAS |
b311480e |
5 | // |
973c2be1 |
6 | // This file is part of Open CASCADE Technology software library. |
b311480e |
7 | // |
d5f74e42 |
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 |
973c2be1 |
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. |
b311480e |
13 | // |
973c2be1 |
14 | // Alternatively, this file may be used under the terms of Open CASCADE |
15 | // commercial license or contractual agreement. |
7fd59977 |
16 | |
42cf5bc1 |
17 | |
7fd59977 |
18 | #include <BRep_Builder.hxx> |
42cf5bc1 |
19 | #include <BRep_Tool.hxx> |
20 | #include <BRepLib.hxx> |
21 | #include <BRepLib_MakeWire.hxx> |
22 | #include <gp_Pnt.hxx> |
23 | #include <StdFail_NotDone.hxx> |
7fd59977 |
24 | #include <TopExp.hxx> |
25 | #include <TopExp_Explorer.hxx> |
26 | #include <TopoDS.hxx> |
7fd59977 |
27 | #include <TopoDS_Compound.hxx> |
42cf5bc1 |
28 | #include <TopoDS_Edge.hxx> |
29 | #include <TopoDS_Vertex.hxx> |
30 | #include <TopoDS_Wire.hxx> |
31 | #include <TopTools_DataMapOfShapeShape.hxx> |
7fd59977 |
32 | #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx> |
42cf5bc1 |
33 | #include <TopTools_ListIteratorOfListOfShape.hxx> |
34 | #include <TopTools_ListOfShape.hxx> |
35 | #include <TopTools_MapIteratorOfMapOfOrientedShape.hxx> |
36 | #include <TopTools_MapIteratorOfMapOfShape.hxx> |
37 | #include <TopTools_MapOfOrientedShape.hxx> |
38 | #include <TopTools_MapOfShape.hxx> |
7fd59977 |
39 | |
40 | //======================================================================= |
41 | //function : Add |
42 | //purpose : Add the list of edges to the current wire |
43 | //======================================================================= |
7fd59977 |
44 | void BRepLib_MakeWire::Add(const TopTools_ListOfShape& L) |
45 | { |
46 | myError = BRepLib_WireDone; |
47 | if (!myShape.IsNull()) myShape.Closed(Standard_False); |
48 | |
49 | if (!L.IsEmpty()) { |
50 | NotDone(); |
51 | TopTools_MapOfShape mapLocale; |
52 | mapLocale.Assign(myVertices); |
53 | TopTools_DataMapOfShapeShape toCopy; |
54 | TopTools_ListOfShape toAdd, nlist, rlist; |
55 | BRep_Builder BB; |
56 | |
57 | TopExp_Explorer exv; |
58 | TopTools_MapIteratorOfMapOfShape itMS; |
59 | TopTools_ListIteratorOfListOfShape itList(L); |
60 | for (;itList.More(); itList.Next()) { |
61 | const TopoDS_Edge& curEd=TopoDS::Edge(itList.Value()); |
62 | if (!curEd.IsNull()) { |
63 | rlist.Clear(); |
64 | nlist.Clear(); |
65 | Standard_Boolean copEd=Standard_False; |
66 | if (myEdge.IsNull()) { |
67 | Add(curEd); |
68 | if (!VF.IsNull()) mapLocale.Add(VF); |
69 | if (!VL.IsNull()) mapLocale.Add(VL); |
70 | NotDone(); |
71 | continue; |
72 | } |
73 | for (exv.Init(curEd, TopAbs_VERTEX); exv.More(); exv.Next()) { |
74 | const TopoDS_Vertex& edVer=TopoDS::Vertex(exv.Current()); |
75 | rlist.Prepend(edVer); |
76 | nlist.Prepend(edVer); |
77 | if (!mapLocale.Contains(edVer)) { |
7fd59977 |
78 | Standard_Boolean notYetFound = Standard_True; |
7fd59977 |
79 | Standard_Real gap=BRep_Tool::Tolerance(edVer); |
80 | gp_Pnt pVer=BRep_Tool::Pnt(edVer); |
81 | for (itMS.Initialize(mapLocale); itMS.More(); itMS.Next()) { |
82 | notYetFound=Standard_True; |
83 | const TopoDS_Vertex& refVer=TopoDS::Vertex(itMS.Key()); |
84 | gap +=BRep_Tool::Tolerance(refVer); |
85 | if (pVer.Distance(BRep_Tool::Pnt(TopoDS::Vertex(refVer))) <= gap) { |
86 | nlist.RemoveFirst(); |
87 | nlist.Prepend(refVer.Oriented(edVer.Orientation())); |
88 | copEd=Standard_True; |
89 | notYetFound=Standard_False; |
90 | break; |
91 | } |
92 | } |
93 | if (notYetFound) mapLocale.Add(edVer); |
94 | } |
95 | } |
96 | if (copEd) { |
97 | TopoDS_Shape aLocalShape = curEd.EmptyCopied(); |
98 | TopoDS_Edge newEd=TopoDS::Edge(aLocalShape); |
99 | // TopoDS_Edge newEd=TopoDS::Edge(curEd.EmptyCopied()); |
100 | BB.Transfert(curEd, newEd); |
7fd59977 |
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())); |
105 | rlist.RemoveFirst(); |
106 | } |
107 | toAdd.Append(newEd); |
108 | } |
109 | else { |
110 | toAdd.Append(curEd); |
111 | } |
112 | } |
113 | } |
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()); |
122 | } |
123 | TopTools_IndexedDataMapOfShapeListOfShape lesMeres; |
124 | TopExp::MapShapesAndAncestors(comp, TopAbs_VERTEX, TopAbs_EDGE, lesMeres); |
125 | TopoDS_Vertex vf, vl; |
126 | TopoDS_Shape theKey; |
127 | Standard_Boolean usedVertex; |
7fd59977 |
128 | Standard_Boolean closedEdge = Standard_False; |
7fd59977 |
129 | Standard_Integer vvInd, lastInd; |
130 | do { |
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); |
139 | if (vf.IsSame(VL)) { |
140 | BB.Add(myShape, itList.Value()); |
141 | myVertices.Add(vl); |
142 | VL=vl; |
143 | } |
144 | else { |
145 | if (closedEdge) { |
146 | BB.Add(myShape, itList.Value()); |
147 | VF=vf; |
148 | } |
149 | else { |
150 | BB.Add(myShape, itList.Value().Reversed()); |
151 | vf.Reverse(); |
152 | VL=vf; |
153 | } |
154 | myVertices.Add(vf); |
155 | } |
156 | } |
157 | } |
158 | if (usedVertex) { |
159 | lastInd=lesMeres.Extent(); |
160 | vvInd=lesMeres.FindIndex(VL); |
161 | if (vvInd != lastInd) { |
162 | theKey=lesMeres.FindKey(lastInd); |
163 | nlist=lesMeres.FindFromIndex(lastInd); |
164 | } |
165 | lesMeres.RemoveLast(); |
166 | if (vvInd != lastInd) { |
167 | lesMeres.Substitute(vvInd, theKey, nlist); |
168 | } |
169 | } |
170 | } |
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); |
178 | if (vl.IsSame(VF)) { |
179 | BB.Add(myShape, itList.Value()); |
180 | myVertices.Add(vf); |
181 | VF=vf; |
182 | } |
183 | else { |
184 | BB.Add(myShape, itList.Value().Reversed()); |
185 | vl.Reverse(); |
186 | myVertices.Add(vl); |
187 | VF=vl; |
188 | } |
189 | } |
190 | } |
191 | if (usedVertex) { |
192 | lastInd=lesMeres.Extent(); |
193 | vvInd=lesMeres.FindIndex(VF); |
194 | if (vvInd != lastInd) { |
195 | theKey=lesMeres.FindKey(lastInd); |
196 | nlist=lesMeres.FindFromIndex(lastInd); |
197 | } |
198 | lesMeres.RemoveLast(); |
199 | if (vvInd != lastInd) { |
200 | lesMeres.Substitute(vvInd, theKey, nlist); |
201 | } |
202 | } |
203 | } |
204 | else { |
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()); |
212 | myVertices.Add(vf); |
213 | VF=vf; |
214 | noCandidat=Standard_False; |
215 | break; |
216 | } |
217 | else if (myVertices.Contains(vf)) { |
218 | if (myError==BRepLib_WireDone) myError = BRepLib_NonManifoldWire; |
219 | BB.Add(myShape, itMOS.Key()); |
220 | myVertices.Add(vl); |
221 | VL=vl; |
222 | noCandidat=Standard_False; |
223 | break; |
224 | } |
225 | } |
226 | if (noCandidat) { |
227 | theEdges.Clear(); |
228 | // Some Edges are not connected to first edge and the diagnosis is as follows |
0d969553 |
229 | // but the "Maker" is Done() because otherwise it is not possible to return the constructed connected part... |
7fd59977 |
230 | myError=BRepLib_DisconnectedWire; |
231 | } |
232 | else theEdges.Remove(itMOS.Key()); |
233 | } |
234 | } |
235 | } while (theEdges.Extent()>0); |
236 | } |
237 | } |
238 | |
239 | if (!VF.IsNull() && !VL.IsNull() && VF.IsSame(VL)) |
240 | myShape.Closed(Standard_True); |
241 | Done(); |
242 | } |