7fd59977 |
1 | // File: BRepLib_MakeWire.cxx |
2 | // Created: Fri Jul 23 15:51:57 1993 |
3 | // Author: Remi LEQUETTE |
4 | // <rle@nonox> |
5 | |
6 | |
7 | #include <BRepLib_MakeWire.ixx> |
8 | #include <BRepLib.hxx> |
9 | #include <BRepLib_MakeEdge.hxx> |
10 | #include <BRep_Tool.hxx> |
11 | #include <BRep_Builder.hxx> |
12 | #include <TopExp.hxx> |
13 | #include <TopExp_Explorer.hxx> |
14 | #include <TopTools_MapOfShape.hxx> |
15 | #include <TopTools_MapIteratorOfMapOfShape.hxx> |
16 | #include <TopoDS.hxx> |
17 | #include <TopoDS_Iterator.hxx> |
18 | #include <gp_Pnt.hxx> |
19 | #include <Geom_Curve.hxx> |
20 | #include <gp.hxx> |
21 | |
22 | |
23 | //======================================================================= |
24 | //function : BRepLib_MakeWire |
25 | //purpose : |
26 | //======================================================================= |
27 | |
28 | BRepLib_MakeWire::BRepLib_MakeWire() : |
29 | myError(BRepLib_EmptyWire) |
30 | { |
31 | } |
32 | |
33 | |
34 | //======================================================================= |
35 | //function : BRepLib_MakeWire |
36 | //purpose : |
37 | //======================================================================= |
38 | |
39 | BRepLib_MakeWire::BRepLib_MakeWire(const TopoDS_Edge& E) |
40 | { |
41 | Add(E); |
42 | } |
43 | |
44 | |
45 | //======================================================================= |
46 | //function : BRepLib_MakeWire |
47 | //purpose : |
48 | //======================================================================= |
49 | |
50 | BRepLib_MakeWire::BRepLib_MakeWire(const TopoDS_Edge& E1, |
51 | const TopoDS_Edge& E2) |
52 | { |
53 | Add(E1); |
54 | Add(E2); |
55 | } |
56 | |
57 | |
58 | //======================================================================= |
59 | //function : BRepLib_MakeWire |
60 | //purpose : |
61 | //======================================================================= |
62 | |
63 | BRepLib_MakeWire::BRepLib_MakeWire(const TopoDS_Edge& E1, |
64 | const TopoDS_Edge& E2, |
65 | const TopoDS_Edge& E3) |
66 | { |
67 | Add(E1); |
68 | Add(E2); |
69 | Add(E3); |
70 | } |
71 | |
72 | |
73 | //======================================================================= |
74 | //function : BRepLib_MakeWire |
75 | //purpose : |
76 | //======================================================================= |
77 | |
78 | BRepLib_MakeWire::BRepLib_MakeWire(const TopoDS_Edge& E1, |
79 | const TopoDS_Edge& E2, |
80 | const TopoDS_Edge& E3, |
81 | const TopoDS_Edge& E4) |
82 | { |
83 | Add(E1); |
84 | Add(E2); |
85 | Add(E3); |
86 | Add(E4); |
87 | } |
88 | |
89 | |
90 | //======================================================================= |
91 | //function : BRepLib_MakeWire |
92 | //purpose : |
93 | //======================================================================= |
94 | |
95 | BRepLib_MakeWire::BRepLib_MakeWire(const TopoDS_Wire& W) |
96 | { |
97 | Add(W); |
98 | } |
99 | |
100 | |
101 | //======================================================================= |
102 | //function : BRepLib_MakeWire |
103 | //purpose : |
104 | //======================================================================= |
105 | |
106 | BRepLib_MakeWire::BRepLib_MakeWire(const TopoDS_Wire& W, |
107 | const TopoDS_Edge& E) |
108 | { |
109 | Add(W); |
110 | Add(E); |
111 | } |
112 | |
113 | |
114 | //======================================================================= |
115 | //function : Add |
116 | //purpose : |
117 | //======================================================================= |
118 | |
119 | void BRepLib_MakeWire::Add(const TopoDS_Wire& W) |
120 | { |
121 | TopExp_Explorer ex(W,TopAbs_EDGE); |
122 | while (ex.More()) { |
123 | Add(TopoDS::Edge(ex.Current())); |
124 | ex.Next(); |
125 | } |
126 | } |
127 | |
128 | //======================================================================= |
129 | //function : Add |
130 | //purpose : |
131 | // PMN 19/03/1998 Pour des Probleme de performances on n'utilise pas |
132 | // TopExp::Vertices sur des wire |
133 | // PMN 10/09/1998 Dans le cas ou le wire est precedament ferme (ou degenere) |
134 | // on emploie quand meme TopExp::Vertices ... Afin de lever |
135 | // les ambiguites. |
136 | //======================================================================= |
137 | |
138 | void BRepLib_MakeWire::Add(const TopoDS_Edge& E) |
139 | { |
140 | |
141 | Standard_Boolean forward = Standard_False; |
142 | // pour dire si on decider d'ajouter forward |
143 | Standard_Boolean reverse = Standard_False; |
144 | // pour dire si on decide d'ajouter reversed |
145 | Standard_Boolean init = Standard_False; |
146 | // Pour savoir s'il on doit calculer VL, VF |
147 | BRep_Builder B; |
148 | TopoDS_Iterator it; |
149 | |
150 | if (myEdge.IsNull()) { |
151 | init = Standard_True; |
152 | // first edge, create the wire |
153 | B.MakeWire(TopoDS::Wire(myShape)); |
154 | |
155 | // set the edge |
156 | myEdge = E; |
157 | |
158 | // add the vertices |
159 | for (it.Initialize(myEdge); it.More(); it.Next()) |
160 | myVertices.Add(it.Value()); |
161 | } |
162 | |
163 | else { |
164 | init = myShape.Closed(); // Si c'est ferme, on ne controle |
165 | TopoDS_Shape aLocalShape = E.Oriented(TopAbs_FORWARD); |
166 | TopoDS_Edge EE = TopoDS::Edge(aLocalShape); |
167 | // TopoDS_Edge EE = TopoDS::Edge(E.Oriented(TopAbs_FORWARD)); |
168 | |
169 | // test the vertices of the edge |
170 | |
171 | Standard_Boolean connected = Standard_False; |
172 | Standard_Boolean copyedge = Standard_False; |
173 | |
174 | if (myError != BRepLib_NonManifoldWire) { |
175 | if (VF.IsNull() || VL.IsNull()) |
176 | myError = BRepLib_NonManifoldWire; |
177 | } |
178 | |
179 | for (it.Initialize(EE); it.More(); it.Next()) { |
180 | |
181 | const TopoDS_Vertex& VE = TopoDS::Vertex(it.Value()); |
182 | |
183 | // if the vertex is in the wire, ok for the connection |
184 | if (myVertices.Contains(VE)) { |
185 | connected = Standard_True; |
186 | myVertex = VE; |
187 | if (myError != BRepLib_NonManifoldWire) { |
188 | // l est on toujours ? |
189 | if (VF.IsSame(VL)) { |
190 | // Orientation indetermine (en 3d) : On garde l'init |
191 | if (!VF.IsSame(VE)) myError = BRepLib_NonManifoldWire; |
192 | } |
193 | else { |
194 | if (VF.IsSame(VE)) { |
195 | if (VE.Orientation() == TopAbs_FORWARD) |
196 | reverse = Standard_True; |
197 | else |
198 | forward = Standard_True; |
199 | } |
200 | else if (VL.IsSame(VE)) { |
201 | if (VE.Orientation() == TopAbs_REVERSED) |
202 | reverse = Standard_True; |
203 | else |
204 | forward = Standard_True; |
205 | } |
206 | else |
207 | myError = BRepLib_NonManifoldWire; |
208 | } |
209 | } |
210 | } |
211 | else { |
212 | // search if there is a similar vertex in the edge |
213 | gp_Pnt PE = BRep_Tool::Pnt(VE); |
214 | |
215 | // Standard_Boolean newvertex = Standard_False; |
216 | TopTools_MapIteratorOfMapOfShape itm(myVertices); |
217 | while (itm.More()) { |
218 | |
219 | const TopoDS_Vertex& VW = TopoDS::Vertex(itm.Key()); |
220 | gp_Pnt PW = BRep_Tool::Pnt(VW); |
221 | Standard_Real l = PE.Distance(PW); |
222 | |
223 | if ((l < BRep_Tool::Tolerance(VE)) || |
224 | (l < BRep_Tool::Tolerance(VW))) { |
225 | copyedge = Standard_True; |
226 | if (myError != BRepLib_NonManifoldWire) { |
227 | // l est on toujours ? |
228 | if (VF.IsSame(VL)) { |
229 | // Orientation indetermine (en 3d) : On garde l'init |
230 | if (!VF.IsSame(VW)) myError = BRepLib_NonManifoldWire; |
231 | } |
232 | else { |
233 | if (VF.IsSame(VW)) { |
234 | if (VE.Orientation() == TopAbs_FORWARD) |
235 | reverse = Standard_True; |
236 | else |
237 | forward = Standard_True; |
238 | } |
239 | else if (VL.IsSame(VW)) { |
240 | if (VE.Orientation() == TopAbs_REVERSED) |
241 | reverse = Standard_True; |
242 | else |
243 | forward = Standard_True; |
244 | } |
245 | else |
246 | myError = BRepLib_NonManifoldWire; |
247 | } |
248 | } |
249 | break; |
250 | } |
251 | itm.Next(); |
252 | } |
253 | if (copyedge) { |
254 | connected = Standard_True; |
255 | } |
256 | } |
257 | } |
258 | |
259 | if (!connected) { |
260 | myError = BRepLib_DisconnectedWire; |
261 | NotDone(); |
262 | return; |
263 | } |
264 | else { |
265 | if (!copyedge) { |
266 | myEdge = EE; |
267 | for (it.Initialize(EE); it.More(); it.Next()) |
268 | myVertices.Add(it.Value()); |
269 | } |
270 | else { |
271 | // copy the edge |
272 | TopoDS_Shape Dummy = EE.EmptyCopied(); |
273 | myEdge = TopoDS::Edge(Dummy); |
274 | myEdge.Closed(EE.Closed()); |
275 | |
276 | for (it.Initialize(EE); it.More(); it.Next()) { |
277 | |
278 | const TopoDS_Vertex& VE = TopoDS::Vertex(it.Value()); |
279 | gp_Pnt PE = BRep_Tool::Pnt(VE); |
280 | |
281 | Standard_Boolean newvertex = Standard_False; |
282 | TopTools_MapIteratorOfMapOfShape itm(myVertices); |
283 | while (itm.More()) { |
284 | |
285 | const TopoDS_Vertex& VW = TopoDS::Vertex(itm.Key()); |
286 | gp_Pnt PW = BRep_Tool::Pnt(VW); |
287 | Standard_Real l = PE.Distance(PW), tolE, tolW; |
288 | tolW = BRep_Tool::Tolerance(VW); |
289 | tolE = BRep_Tool::Tolerance(VE); |
290 | |
291 | if ((l < tolE) || (l < tolW)) { |
292 | |
293 | Standard_Real maxtol = .5*(tolW + tolE + l), cW, cE; |
294 | if(maxtol > tolW && maxtol > tolE) { |
295 | cW = (maxtol - tolE)/l; |
296 | cE = 1. - cW; |
297 | } |
298 | else if (maxtol > tolW) {maxtol = tolE; cW = 0.; cE = 1.;} |
299 | else {maxtol = tolW; cW = 1.; cE = 0.;} |
300 | |
301 | gp_Pnt PC(cW*PW.X() + cE*PE.X(),cW*PW.Y() + cE*PE.Y(),cW*PW.Z() + cE*PE.Z()); |
302 | |
303 | B.UpdateVertex(VW, PC, maxtol); |
304 | |
305 | newvertex = Standard_True; |
306 | myVertex = VW; |
307 | myVertex.Orientation(VE.Orientation()); |
308 | B.Add(myEdge,myVertex); |
309 | B.Transfert(EE,myEdge,VE,myVertex); |
310 | break; |
311 | } |
312 | |
313 | itm.Next(); |
314 | } |
315 | if (!newvertex) { |
316 | myVertices.Add(VE); |
317 | B.Add(myEdge,VE); |
318 | B.Transfert(EE,myEdge,VE,VE); |
319 | } |
320 | } |
321 | } |
322 | } |
323 | // On decide ici de l'orientation de l'arete |
324 | // S'il y a ambiguite (en 3d) on garde l'orientation donnee en entree |
325 | // Cas d'ambiguite : |
326 | // reverse et forward sont faux car on n'a rien decider : |
327 | // wire ferme, vertex interne ... |
328 | // reverse et forward sont vrai : Edge ferme ou degenere |
329 | if ( ((forward == reverse) && (E.Orientation() == TopAbs_REVERSED)) || |
330 | ( reverse && !forward) ) myEdge.Reverse(); |
331 | } |
332 | |
333 | // add myEdge to myShape |
334 | B.Add(myShape,myEdge); |
335 | myShape.Closed(Standard_False); |
336 | |
337 | // Initialize VF, VL |
338 | if (init) TopExp::Vertices(TopoDS::Wire(myShape), VF,VL); |
339 | else { |
340 | if (myError == BRepLib_WireDone){ // Update only |
341 | TopoDS_Vertex V1,V2,VRef; |
342 | TopExp::Vertices(myEdge, V1, V2); |
343 | if (V1.IsSame(myVertex)) VRef = V2; |
344 | else if (V2.IsSame(myVertex)) VRef = V1; |
345 | else { |
346 | #if DEB |
347 | cout << "MakeWire : Y A UN PROBLEME !!" << endl; |
348 | #endif |
349 | myError = BRepLib_NonManifoldWire; |
350 | } |
351 | |
352 | if (VF.IsSame(VL)) { |
353 | // Cas particulier: il faut controler les orientations |
354 | #if DEB |
355 | if (!VF.IsSame(myVertex)) |
356 | cout << "MakeWire : Y A UN PROBLEME !!" << endl; |
357 | #endif |
358 | |
359 | } |
360 | else { // Cas general |
361 | if (VF.IsSame(myVertex)) VF = VRef; |
362 | else if (VL.IsSame(myVertex)) VL = VRef; |
363 | else { |
364 | #if DEB |
365 | cout << "MakeWire : Y A UN PROBLEME !!" << endl; |
366 | #endif |
367 | myError = BRepLib_NonManifoldWire; |
368 | } |
369 | } |
370 | } |
371 | if (myError == BRepLib_NonManifoldWire) { |
372 | VF = VL = TopoDS_Vertex(); // nullify |
373 | } |
374 | } |
375 | // Test myShape is closed |
376 | if (!VF.IsNull() && !VL.IsNull() && VF.IsSame(VL)) |
377 | myShape.Closed(Standard_True); |
378 | |
379 | myError = BRepLib_WireDone; |
380 | Done(); |
381 | } |
382 | |
383 | |
384 | //======================================================================= |
385 | //function : Wire |
386 | //purpose : |
387 | //======================================================================= |
388 | |
389 | const TopoDS_Wire& BRepLib_MakeWire::Wire()const |
390 | { |
391 | return TopoDS::Wire(Shape()); |
392 | } |
393 | |
394 | |
395 | //======================================================================= |
396 | //function : Edge |
397 | //purpose : |
398 | //======================================================================= |
399 | |
400 | const TopoDS_Edge& BRepLib_MakeWire::Edge()const |
401 | { |
402 | return myEdge; |
403 | } |
404 | |
405 | |
406 | //======================================================================= |
407 | //function : Vertex |
408 | //purpose : |
409 | //======================================================================= |
410 | |
411 | const TopoDS_Vertex& BRepLib_MakeWire::Vertex()const |
412 | { |
413 | return myVertex; |
414 | } |
415 | |
416 | |
417 | //======================================================================= |
418 | //function : operator |
419 | //purpose : |
420 | //======================================================================= |
421 | |
422 | BRepLib_MakeWire::operator TopoDS_Wire() const |
423 | { |
424 | return Wire(); |
425 | } |
426 | |
427 | |
428 | |
429 | //======================================================================= |
430 | //function : Error |
431 | //purpose : |
432 | //======================================================================= |
433 | |
434 | BRepLib_WireError BRepLib_MakeWire::Error() const |
435 | { |
436 | return myError; |
437 | } |