Commit | Line | Data |
---|---|---|
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 : | |
0d969553 Y |
131 | // PMN 19/03/1998 For the Problem of performance TopExp::Vertices are not used on wire |
132 | // PMN 10/09/1998 In case if the wire is previously closed (or degenerated) | |
133 | // TopExp::Vertices is used to reduce the ambiguity. | |
7fd59977 | 134 | //======================================================================= |
135 | ||
136 | void BRepLib_MakeWire::Add(const TopoDS_Edge& E) | |
137 | { | |
138 | ||
139 | Standard_Boolean forward = Standard_False; | |
0d969553 | 140 | // to tell if it has been decided to add forward |
7fd59977 | 141 | Standard_Boolean reverse = Standard_False; |
0d969553 | 142 | // to tell if it has been decided to add reversed |
7fd59977 | 143 | Standard_Boolean init = Standard_False; |
0d969553 | 144 | // To know if it is necessary to calculate VL, VF |
7fd59977 | 145 | BRep_Builder B; |
146 | TopoDS_Iterator it; | |
147 | ||
148 | if (myEdge.IsNull()) { | |
149 | init = Standard_True; | |
150 | // first edge, create the wire | |
151 | B.MakeWire(TopoDS::Wire(myShape)); | |
152 | ||
153 | // set the edge | |
154 | myEdge = E; | |
155 | ||
156 | // add the vertices | |
157 | for (it.Initialize(myEdge); it.More(); it.Next()) | |
158 | myVertices.Add(it.Value()); | |
159 | } | |
160 | ||
161 | else { | |
0d969553 | 162 | init = myShape.Closed(); // If it is closed no control |
7fd59977 | 163 | TopoDS_Shape aLocalShape = E.Oriented(TopAbs_FORWARD); |
164 | TopoDS_Edge EE = TopoDS::Edge(aLocalShape); | |
165 | // TopoDS_Edge EE = TopoDS::Edge(E.Oriented(TopAbs_FORWARD)); | |
166 | ||
167 | // test the vertices of the edge | |
168 | ||
169 | Standard_Boolean connected = Standard_False; | |
170 | Standard_Boolean copyedge = Standard_False; | |
171 | ||
172 | if (myError != BRepLib_NonManifoldWire) { | |
173 | if (VF.IsNull() || VL.IsNull()) | |
174 | myError = BRepLib_NonManifoldWire; | |
175 | } | |
176 | ||
177 | for (it.Initialize(EE); it.More(); it.Next()) { | |
178 | ||
179 | const TopoDS_Vertex& VE = TopoDS::Vertex(it.Value()); | |
180 | ||
181 | // if the vertex is in the wire, ok for the connection | |
182 | if (myVertices.Contains(VE)) { | |
183 | connected = Standard_True; | |
184 | myVertex = VE; | |
185 | if (myError != BRepLib_NonManifoldWire) { | |
0d969553 | 186 | // is it always so ? |
7fd59977 | 187 | if (VF.IsSame(VL)) { |
0d969553 | 188 | // Orientation indetermined (in 3d) : Preserve the initial |
7fd59977 | 189 | if (!VF.IsSame(VE)) myError = BRepLib_NonManifoldWire; |
190 | } | |
191 | else { | |
192 | if (VF.IsSame(VE)) { | |
193 | if (VE.Orientation() == TopAbs_FORWARD) | |
194 | reverse = Standard_True; | |
195 | else | |
196 | forward = Standard_True; | |
197 | } | |
198 | else if (VL.IsSame(VE)) { | |
199 | if (VE.Orientation() == TopAbs_REVERSED) | |
200 | reverse = Standard_True; | |
201 | else | |
202 | forward = Standard_True; | |
203 | } | |
204 | else | |
205 | myError = BRepLib_NonManifoldWire; | |
206 | } | |
207 | } | |
208 | } | |
209 | else { | |
210 | // search if there is a similar vertex in the edge | |
211 | gp_Pnt PE = BRep_Tool::Pnt(VE); | |
212 | ||
213 | // Standard_Boolean newvertex = Standard_False; | |
214 | TopTools_MapIteratorOfMapOfShape itm(myVertices); | |
215 | while (itm.More()) { | |
216 | ||
217 | const TopoDS_Vertex& VW = TopoDS::Vertex(itm.Key()); | |
218 | gp_Pnt PW = BRep_Tool::Pnt(VW); | |
219 | Standard_Real l = PE.Distance(PW); | |
220 | ||
221 | if ((l < BRep_Tool::Tolerance(VE)) || | |
222 | (l < BRep_Tool::Tolerance(VW))) { | |
223 | copyedge = Standard_True; | |
224 | if (myError != BRepLib_NonManifoldWire) { | |
0d969553 | 225 | // is it always so ? |
7fd59977 | 226 | if (VF.IsSame(VL)) { |
0d969553 | 227 | // Orientation indetermined (in 3d) : Preserve the initial |
7fd59977 | 228 | if (!VF.IsSame(VW)) myError = BRepLib_NonManifoldWire; |
229 | } | |
230 | else { | |
231 | if (VF.IsSame(VW)) { | |
232 | if (VE.Orientation() == TopAbs_FORWARD) | |
233 | reverse = Standard_True; | |
234 | else | |
235 | forward = Standard_True; | |
236 | } | |
237 | else if (VL.IsSame(VW)) { | |
238 | if (VE.Orientation() == TopAbs_REVERSED) | |
239 | reverse = Standard_True; | |
240 | else | |
241 | forward = Standard_True; | |
242 | } | |
243 | else | |
244 | myError = BRepLib_NonManifoldWire; | |
245 | } | |
246 | } | |
247 | break; | |
248 | } | |
249 | itm.Next(); | |
250 | } | |
251 | if (copyedge) { | |
252 | connected = Standard_True; | |
253 | } | |
254 | } | |
255 | } | |
256 | ||
257 | if (!connected) { | |
258 | myError = BRepLib_DisconnectedWire; | |
259 | NotDone(); | |
260 | return; | |
261 | } | |
262 | else { | |
263 | if (!copyedge) { | |
264 | myEdge = EE; | |
265 | for (it.Initialize(EE); it.More(); it.Next()) | |
266 | myVertices.Add(it.Value()); | |
267 | } | |
268 | else { | |
269 | // copy the edge | |
270 | TopoDS_Shape Dummy = EE.EmptyCopied(); | |
271 | myEdge = TopoDS::Edge(Dummy); | |
272 | myEdge.Closed(EE.Closed()); | |
273 | ||
274 | for (it.Initialize(EE); it.More(); it.Next()) { | |
275 | ||
276 | const TopoDS_Vertex& VE = TopoDS::Vertex(it.Value()); | |
277 | gp_Pnt PE = BRep_Tool::Pnt(VE); | |
278 | ||
279 | Standard_Boolean newvertex = Standard_False; | |
280 | TopTools_MapIteratorOfMapOfShape itm(myVertices); | |
281 | while (itm.More()) { | |
282 | ||
283 | const TopoDS_Vertex& VW = TopoDS::Vertex(itm.Key()); | |
284 | gp_Pnt PW = BRep_Tool::Pnt(VW); | |
285 | Standard_Real l = PE.Distance(PW), tolE, tolW; | |
286 | tolW = BRep_Tool::Tolerance(VW); | |
287 | tolE = BRep_Tool::Tolerance(VE); | |
288 | ||
289 | if ((l < tolE) || (l < tolW)) { | |
290 | ||
291 | Standard_Real maxtol = .5*(tolW + tolE + l), cW, cE; | |
292 | if(maxtol > tolW && maxtol > tolE) { | |
293 | cW = (maxtol - tolE)/l; | |
294 | cE = 1. - cW; | |
295 | } | |
296 | else if (maxtol > tolW) {maxtol = tolE; cW = 0.; cE = 1.;} | |
297 | else {maxtol = tolW; cW = 1.; cE = 0.;} | |
298 | ||
299 | gp_Pnt PC(cW*PW.X() + cE*PE.X(),cW*PW.Y() + cE*PE.Y(),cW*PW.Z() + cE*PE.Z()); | |
300 | ||
301 | B.UpdateVertex(VW, PC, maxtol); | |
302 | ||
303 | newvertex = Standard_True; | |
304 | myVertex = VW; | |
305 | myVertex.Orientation(VE.Orientation()); | |
306 | B.Add(myEdge,myVertex); | |
307 | B.Transfert(EE,myEdge,VE,myVertex); | |
308 | break; | |
309 | } | |
310 | ||
311 | itm.Next(); | |
312 | } | |
313 | if (!newvertex) { | |
314 | myVertices.Add(VE); | |
315 | B.Add(myEdge,VE); | |
316 | B.Transfert(EE,myEdge,VE,VE); | |
317 | } | |
318 | } | |
319 | } | |
320 | } | |
0d969553 Y |
321 | // Make a decision about the orientation of the edge |
322 | // If there is an ambiguity (in 3d) preserve the orientation given at input | |
323 | // Case of ambiguity : | |
324 | // reverse and forward are false as nothing has been decided : | |
325 | // closed wire, internal vertex ... | |
326 | // reverse and forward are true : closed or degenerated edge | |
7fd59977 | 327 | if ( ((forward == reverse) && (E.Orientation() == TopAbs_REVERSED)) || |
328 | ( reverse && !forward) ) myEdge.Reverse(); | |
329 | } | |
330 | ||
331 | // add myEdge to myShape | |
332 | B.Add(myShape,myEdge); | |
333 | myShape.Closed(Standard_False); | |
334 | ||
335 | // Initialize VF, VL | |
336 | if (init) TopExp::Vertices(TopoDS::Wire(myShape), VF,VL); | |
337 | else { | |
338 | if (myError == BRepLib_WireDone){ // Update only | |
339 | TopoDS_Vertex V1,V2,VRef; | |
340 | TopExp::Vertices(myEdge, V1, V2); | |
341 | if (V1.IsSame(myVertex)) VRef = V2; | |
342 | else if (V2.IsSame(myVertex)) VRef = V1; | |
343 | else { | |
344 | #if DEB | |
0d969553 | 345 | cout << "MakeWire : There is a PROBLEM !!" << endl; |
7fd59977 | 346 | #endif |
347 | myError = BRepLib_NonManifoldWire; | |
348 | } | |
349 | ||
350 | if (VF.IsSame(VL)) { | |
0d969553 | 351 | // Particular case: it is required to control the orientation |
7fd59977 | 352 | #if DEB |
353 | if (!VF.IsSame(myVertex)) | |
0d969553 | 354 | cout << "MakeWire : There is a PROBLEM !!" << endl; |
7fd59977 | 355 | #endif |
356 | ||
357 | } | |
0d969553 | 358 | else { // General case |
7fd59977 | 359 | if (VF.IsSame(myVertex)) VF = VRef; |
360 | else if (VL.IsSame(myVertex)) VL = VRef; | |
361 | else { | |
362 | #if DEB | |
363 | cout << "MakeWire : Y A UN PROBLEME !!" << endl; | |
364 | #endif | |
365 | myError = BRepLib_NonManifoldWire; | |
366 | } | |
367 | } | |
368 | } | |
369 | if (myError == BRepLib_NonManifoldWire) { | |
370 | VF = VL = TopoDS_Vertex(); // nullify | |
371 | } | |
372 | } | |
373 | // Test myShape is closed | |
374 | if (!VF.IsNull() && !VL.IsNull() && VF.IsSame(VL)) | |
375 | myShape.Closed(Standard_True); | |
376 | ||
377 | myError = BRepLib_WireDone; | |
378 | Done(); | |
379 | } | |
380 | ||
381 | ||
382 | //======================================================================= | |
383 | //function : Wire | |
384 | //purpose : | |
385 | //======================================================================= | |
386 | ||
387 | const TopoDS_Wire& BRepLib_MakeWire::Wire()const | |
388 | { | |
389 | return TopoDS::Wire(Shape()); | |
390 | } | |
391 | ||
392 | ||
393 | //======================================================================= | |
394 | //function : Edge | |
395 | //purpose : | |
396 | //======================================================================= | |
397 | ||
398 | const TopoDS_Edge& BRepLib_MakeWire::Edge()const | |
399 | { | |
400 | return myEdge; | |
401 | } | |
402 | ||
403 | ||
404 | //======================================================================= | |
405 | //function : Vertex | |
406 | //purpose : | |
407 | //======================================================================= | |
408 | ||
409 | const TopoDS_Vertex& BRepLib_MakeWire::Vertex()const | |
410 | { | |
411 | return myVertex; | |
412 | } | |
413 | ||
414 | ||
415 | //======================================================================= | |
416 | //function : operator | |
417 | //purpose : | |
418 | //======================================================================= | |
419 | ||
420 | BRepLib_MakeWire::operator TopoDS_Wire() const | |
421 | { | |
422 | return Wire(); | |
423 | } | |
424 | ||
425 | ||
426 | ||
427 | //======================================================================= | |
428 | //function : Error | |
429 | //purpose : | |
430 | //======================================================================= | |
431 | ||
432 | BRepLib_WireError BRepLib_MakeWire::Error() const | |
433 | { | |
434 | return myError; | |
435 | } |