Commit | Line | Data |
---|---|---|
b311480e | 1 | // Created on: 1993-07-23 |
2 | // Created by: Remi LEQUETTE | |
3 | // Copyright (c) 1993-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 | |
18 | #include <BRep_Builder.hxx> | |
19 | #include <BRep_Tool.hxx> | |
7fd59977 | 20 | #include <BRepLib.hxx> |
21 | #include <BRepLib_MakeEdge.hxx> | |
42cf5bc1 | 22 | #include <BRepLib_MakeWire.hxx> |
23 | #include <Geom_Curve.hxx> | |
24 | #include <gp.hxx> | |
25 | #include <gp_Pnt.hxx> | |
26 | #include <StdFail_NotDone.hxx> | |
7fd59977 | 27 | #include <TopExp.hxx> |
28 | #include <TopExp_Explorer.hxx> | |
7fd59977 | 29 | #include <TopoDS.hxx> |
42cf5bc1 | 30 | #include <TopoDS_Edge.hxx> |
7fd59977 | 31 | #include <TopoDS_Iterator.hxx> |
42cf5bc1 | 32 | #include <TopoDS_Vertex.hxx> |
33 | #include <TopoDS_Wire.hxx> | |
34 | #include <TopTools_MapIteratorOfMapOfShape.hxx> | |
35 | #include <TopTools_MapOfShape.hxx> | |
7fd59977 | 36 | |
37 | //======================================================================= | |
38 | //function : BRepLib_MakeWire | |
39 | //purpose : | |
40 | //======================================================================= | |
7fd59977 | 41 | BRepLib_MakeWire::BRepLib_MakeWire() : |
42 | myError(BRepLib_EmptyWire) | |
43 | { | |
44 | } | |
45 | ||
46 | ||
47 | //======================================================================= | |
48 | //function : BRepLib_MakeWire | |
49 | //purpose : | |
50 | //======================================================================= | |
51 | ||
52 | BRepLib_MakeWire::BRepLib_MakeWire(const TopoDS_Edge& E) | |
53 | { | |
54 | Add(E); | |
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 | { | |
66 | Add(E1); | |
67 | Add(E2); | |
68 | } | |
69 | ||
70 | ||
71 | //======================================================================= | |
72 | //function : BRepLib_MakeWire | |
73 | //purpose : | |
74 | //======================================================================= | |
75 | ||
76 | BRepLib_MakeWire::BRepLib_MakeWire(const TopoDS_Edge& E1, | |
77 | const TopoDS_Edge& E2, | |
78 | const TopoDS_Edge& E3) | |
79 | { | |
80 | Add(E1); | |
81 | Add(E2); | |
82 | Add(E3); | |
83 | } | |
84 | ||
85 | ||
86 | //======================================================================= | |
87 | //function : BRepLib_MakeWire | |
88 | //purpose : | |
89 | //======================================================================= | |
90 | ||
91 | BRepLib_MakeWire::BRepLib_MakeWire(const TopoDS_Edge& E1, | |
92 | const TopoDS_Edge& E2, | |
93 | const TopoDS_Edge& E3, | |
94 | const TopoDS_Edge& E4) | |
95 | { | |
96 | Add(E1); | |
97 | Add(E2); | |
98 | Add(E3); | |
99 | Add(E4); | |
100 | } | |
101 | ||
102 | ||
103 | //======================================================================= | |
104 | //function : BRepLib_MakeWire | |
105 | //purpose : | |
106 | //======================================================================= | |
107 | ||
108 | BRepLib_MakeWire::BRepLib_MakeWire(const TopoDS_Wire& W) | |
109 | { | |
110 | Add(W); | |
111 | } | |
112 | ||
113 | ||
114 | //======================================================================= | |
115 | //function : BRepLib_MakeWire | |
116 | //purpose : | |
117 | //======================================================================= | |
118 | ||
119 | BRepLib_MakeWire::BRepLib_MakeWire(const TopoDS_Wire& W, | |
120 | const TopoDS_Edge& E) | |
121 | { | |
122 | Add(W); | |
123 | Add(E); | |
124 | } | |
125 | ||
126 | ||
127 | //======================================================================= | |
128 | //function : Add | |
129 | //purpose : | |
130 | //======================================================================= | |
131 | ||
132 | void BRepLib_MakeWire::Add(const TopoDS_Wire& W) | |
133 | { | |
134 | TopExp_Explorer ex(W,TopAbs_EDGE); | |
135 | while (ex.More()) { | |
136 | Add(TopoDS::Edge(ex.Current())); | |
137 | ex.Next(); | |
138 | } | |
139 | } | |
140 | ||
07ef8bdf | 141 | //======================================================================= |
142 | //function : Add | |
143 | //purpose : | |
144 | //======================================================================= | |
145 | void BRepLib_MakeWire::Add(const TopoDS_Edge& E) | |
146 | { | |
147 | Add(E, Standard_True); | |
148 | } | |
149 | ||
7fd59977 | 150 | //======================================================================= |
151 | //function : Add | |
152 | //purpose : | |
0d969553 Y |
153 | // PMN 19/03/1998 For the Problem of performance TopExp::Vertices are not used on wire |
154 | // PMN 10/09/1998 In case if the wire is previously closed (or degenerated) | |
155 | // TopExp::Vertices is used to reduce the ambiguity. | |
07ef8bdf | 156 | // IsCheckGeometryProximity flag : If true => check for the geometry proximity of vertices |
7fd59977 | 157 | //======================================================================= |
07ef8bdf | 158 | void BRepLib_MakeWire::Add(const TopoDS_Edge& E, Standard_Boolean IsCheckGeometryProximity) |
7fd59977 | 159 | { |
160 | ||
161 | Standard_Boolean forward = Standard_False; | |
0d969553 | 162 | // to tell if it has been decided to add forward |
7fd59977 | 163 | Standard_Boolean reverse = Standard_False; |
0d969553 | 164 | // to tell if it has been decided to add reversed |
7fd59977 | 165 | Standard_Boolean init = Standard_False; |
0d969553 | 166 | // To know if it is necessary to calculate VL, VF |
7fd59977 | 167 | BRep_Builder B; |
168 | TopoDS_Iterator it; | |
169 | ||
170 | if (myEdge.IsNull()) { | |
171 | init = Standard_True; | |
172 | // first edge, create the wire | |
173 | B.MakeWire(TopoDS::Wire(myShape)); | |
174 | ||
175 | // set the edge | |
176 | myEdge = E; | |
177 | ||
178 | // add the vertices | |
179 | for (it.Initialize(myEdge); it.More(); it.Next()) | |
180 | myVertices.Add(it.Value()); | |
181 | } | |
182 | ||
183 | else { | |
0d969553 | 184 | init = myShape.Closed(); // If it is closed no control |
7fd59977 | 185 | TopoDS_Shape aLocalShape = E.Oriented(TopAbs_FORWARD); |
186 | TopoDS_Edge EE = TopoDS::Edge(aLocalShape); | |
187 | // TopoDS_Edge EE = TopoDS::Edge(E.Oriented(TopAbs_FORWARD)); | |
188 | ||
189 | // test the vertices of the edge | |
190 | ||
191 | Standard_Boolean connected = Standard_False; | |
192 | Standard_Boolean copyedge = Standard_False; | |
193 | ||
194 | if (myError != BRepLib_NonManifoldWire) { | |
195 | if (VF.IsNull() || VL.IsNull()) | |
196 | myError = BRepLib_NonManifoldWire; | |
197 | } | |
198 | ||
199 | for (it.Initialize(EE); it.More(); it.Next()) { | |
200 | ||
201 | const TopoDS_Vertex& VE = TopoDS::Vertex(it.Value()); | |
202 | ||
203 | // if the vertex is in the wire, ok for the connection | |
204 | if (myVertices.Contains(VE)) { | |
205 | connected = Standard_True; | |
206 | myVertex = VE; | |
207 | if (myError != BRepLib_NonManifoldWire) { | |
0d969553 | 208 | // is it always so ? |
7fd59977 | 209 | if (VF.IsSame(VL)) { |
0d969553 | 210 | // Orientation indetermined (in 3d) : Preserve the initial |
7fd59977 | 211 | if (!VF.IsSame(VE)) myError = BRepLib_NonManifoldWire; |
212 | } | |
213 | else { | |
214 | if (VF.IsSame(VE)) { | |
215 | if (VE.Orientation() == TopAbs_FORWARD) | |
216 | reverse = Standard_True; | |
217 | else | |
218 | forward = Standard_True; | |
219 | } | |
220 | else if (VL.IsSame(VE)) { | |
221 | if (VE.Orientation() == TopAbs_REVERSED) | |
222 | reverse = Standard_True; | |
223 | else | |
224 | forward = Standard_True; | |
225 | } | |
226 | else | |
227 | myError = BRepLib_NonManifoldWire; | |
228 | } | |
229 | } | |
230 | } | |
07ef8bdf | 231 | else if (IsCheckGeometryProximity) |
232 | { | |
7fd59977 | 233 | // search if there is a similar vertex in the edge |
234 | gp_Pnt PE = BRep_Tool::Pnt(VE); | |
235 | ||
07ef8bdf | 236 | for (Standard_Integer i = 1; i <= myVertices.Extent(); i++) { |
237 | const TopoDS_Vertex& VW = TopoDS::Vertex(myVertices.FindKey(i)); | |
7fd59977 | 238 | gp_Pnt PW = BRep_Tool::Pnt(VW); |
239 | Standard_Real l = PE.Distance(PW); | |
240 | ||
241 | if ((l < BRep_Tool::Tolerance(VE)) || | |
242 | (l < BRep_Tool::Tolerance(VW))) { | |
243 | copyedge = Standard_True; | |
244 | if (myError != BRepLib_NonManifoldWire) { | |
0d969553 | 245 | // is it always so ? |
7fd59977 | 246 | if (VF.IsSame(VL)) { |
0d969553 | 247 | // Orientation indetermined (in 3d) : Preserve the initial |
7fd59977 | 248 | if (!VF.IsSame(VW)) myError = BRepLib_NonManifoldWire; |
249 | } | |
250 | else { | |
251 | if (VF.IsSame(VW)) { | |
252 | if (VE.Orientation() == TopAbs_FORWARD) | |
253 | reverse = Standard_True; | |
254 | else | |
255 | forward = Standard_True; | |
256 | } | |
257 | else if (VL.IsSame(VW)) { | |
258 | if (VE.Orientation() == TopAbs_REVERSED) | |
259 | reverse = Standard_True; | |
260 | else | |
261 | forward = Standard_True; | |
262 | } | |
263 | else | |
264 | myError = BRepLib_NonManifoldWire; | |
265 | } | |
266 | } | |
267 | break; | |
268 | } | |
7fd59977 | 269 | } |
270 | if (copyedge) { | |
271 | connected = Standard_True; | |
272 | } | |
273 | } | |
274 | } | |
275 | ||
276 | if (!connected) { | |
277 | myError = BRepLib_DisconnectedWire; | |
278 | NotDone(); | |
279 | return; | |
280 | } | |
281 | else { | |
282 | if (!copyedge) { | |
283 | myEdge = EE; | |
284 | for (it.Initialize(EE); it.More(); it.Next()) | |
285 | myVertices.Add(it.Value()); | |
286 | } | |
287 | else { | |
288 | // copy the edge | |
289 | TopoDS_Shape Dummy = EE.EmptyCopied(); | |
290 | myEdge = TopoDS::Edge(Dummy); | |
7fd59977 | 291 | |
292 | for (it.Initialize(EE); it.More(); it.Next()) { | |
293 | ||
294 | const TopoDS_Vertex& VE = TopoDS::Vertex(it.Value()); | |
295 | gp_Pnt PE = BRep_Tool::Pnt(VE); | |
296 | ||
297 | Standard_Boolean newvertex = Standard_False; | |
07ef8bdf | 298 | for (Standard_Integer i = 1; i <= myVertices.Extent(); i++) { |
299 | const TopoDS_Vertex& VW = TopoDS::Vertex(myVertices.FindKey(i)); | |
7fd59977 | 300 | gp_Pnt PW = BRep_Tool::Pnt(VW); |
301 | Standard_Real l = PE.Distance(PW), tolE, tolW; | |
302 | tolW = BRep_Tool::Tolerance(VW); | |
303 | tolE = BRep_Tool::Tolerance(VE); | |
304 | ||
305 | if ((l < tolE) || (l < tolW)) { | |
306 | ||
307 | Standard_Real maxtol = .5*(tolW + tolE + l), cW, cE; | |
308 | if(maxtol > tolW && maxtol > tolE) { | |
309 | cW = (maxtol - tolE)/l; | |
310 | cE = 1. - cW; | |
311 | } | |
312 | else if (maxtol > tolW) {maxtol = tolE; cW = 0.; cE = 1.;} | |
313 | else {maxtol = tolW; cW = 1.; cE = 0.;} | |
314 | ||
315 | gp_Pnt PC(cW*PW.X() + cE*PE.X(),cW*PW.Y() + cE*PE.Y(),cW*PW.Z() + cE*PE.Z()); | |
316 | ||
317 | B.UpdateVertex(VW, PC, maxtol); | |
318 | ||
319 | newvertex = Standard_True; | |
320 | myVertex = VW; | |
321 | myVertex.Orientation(VE.Orientation()); | |
322 | B.Add(myEdge,myVertex); | |
323 | B.Transfert(EE,myEdge,VE,myVertex); | |
324 | break; | |
325 | } | |
326 | ||
7fd59977 | 327 | } |
328 | if (!newvertex) { | |
329 | myVertices.Add(VE); | |
330 | B.Add(myEdge,VE); | |
331 | B.Transfert(EE,myEdge,VE,VE); | |
332 | } | |
333 | } | |
334 | } | |
335 | } | |
0d969553 Y |
336 | // Make a decision about the orientation of the edge |
337 | // If there is an ambiguity (in 3d) preserve the orientation given at input | |
338 | // Case of ambiguity : | |
339 | // reverse and forward are false as nothing has been decided : | |
340 | // closed wire, internal vertex ... | |
341 | // reverse and forward are true : closed or degenerated edge | |
7fd59977 | 342 | if ( ((forward == reverse) && (E.Orientation() == TopAbs_REVERSED)) || |
343 | ( reverse && !forward) ) myEdge.Reverse(); | |
344 | } | |
345 | ||
346 | // add myEdge to myShape | |
347 | B.Add(myShape,myEdge); | |
348 | myShape.Closed(Standard_False); | |
349 | ||
350 | // Initialize VF, VL | |
351 | if (init) TopExp::Vertices(TopoDS::Wire(myShape), VF,VL); | |
352 | else { | |
353 | if (myError == BRepLib_WireDone){ // Update only | |
354 | TopoDS_Vertex V1,V2,VRef; | |
355 | TopExp::Vertices(myEdge, V1, V2); | |
356 | if (V1.IsSame(myVertex)) VRef = V2; | |
357 | else if (V2.IsSame(myVertex)) VRef = V1; | |
358 | else { | |
0797d9d3 | 359 | #ifdef OCCT_DEBUG |
0d969553 | 360 | cout << "MakeWire : There is a PROBLEM !!" << endl; |
7fd59977 | 361 | #endif |
362 | myError = BRepLib_NonManifoldWire; | |
363 | } | |
364 | ||
365 | if (VF.IsSame(VL)) { | |
0d969553 | 366 | // Particular case: it is required to control the orientation |
0797d9d3 | 367 | #ifdef OCCT_DEBUG |
7fd59977 | 368 | if (!VF.IsSame(myVertex)) |
0d969553 | 369 | cout << "MakeWire : There is a PROBLEM !!" << endl; |
7fd59977 | 370 | #endif |
371 | ||
372 | } | |
0d969553 | 373 | else { // General case |
7fd59977 | 374 | if (VF.IsSame(myVertex)) VF = VRef; |
375 | else if (VL.IsSame(myVertex)) VL = VRef; | |
376 | else { | |
0797d9d3 | 377 | #ifdef OCCT_DEBUG |
7fd59977 | 378 | cout << "MakeWire : Y A UN PROBLEME !!" << endl; |
379 | #endif | |
380 | myError = BRepLib_NonManifoldWire; | |
381 | } | |
382 | } | |
383 | } | |
384 | if (myError == BRepLib_NonManifoldWire) { | |
385 | VF = VL = TopoDS_Vertex(); // nullify | |
386 | } | |
387 | } | |
388 | // Test myShape is closed | |
389 | if (!VF.IsNull() && !VL.IsNull() && VF.IsSame(VL)) | |
390 | myShape.Closed(Standard_True); | |
391 | ||
392 | myError = BRepLib_WireDone; | |
393 | Done(); | |
394 | } | |
395 | ||
396 | ||
397 | //======================================================================= | |
398 | //function : Wire | |
399 | //purpose : | |
400 | //======================================================================= | |
401 | ||
ecac41a9 | 402 | const TopoDS_Wire& BRepLib_MakeWire::Wire() |
7fd59977 | 403 | { |
404 | return TopoDS::Wire(Shape()); | |
405 | } | |
406 | ||
407 | ||
408 | //======================================================================= | |
409 | //function : Edge | |
410 | //purpose : | |
411 | //======================================================================= | |
412 | ||
413 | const TopoDS_Edge& BRepLib_MakeWire::Edge()const | |
414 | { | |
415 | return myEdge; | |
416 | } | |
417 | ||
418 | ||
419 | //======================================================================= | |
420 | //function : Vertex | |
421 | //purpose : | |
422 | //======================================================================= | |
423 | ||
424 | const TopoDS_Vertex& BRepLib_MakeWire::Vertex()const | |
425 | { | |
426 | return myVertex; | |
427 | } | |
428 | ||
429 | ||
430 | //======================================================================= | |
431 | //function : operator | |
432 | //purpose : | |
433 | //======================================================================= | |
434 | ||
ecac41a9 | 435 | BRepLib_MakeWire::operator TopoDS_Wire() |
7fd59977 | 436 | { |
437 | return Wire(); | |
438 | } | |
439 | ||
440 | ||
441 | ||
442 | //======================================================================= | |
443 | //function : Error | |
444 | //purpose : | |
445 | //======================================================================= | |
446 | ||
447 | BRepLib_WireError BRepLib_MakeWire::Error() const | |
448 | { | |
449 | return myError; | |
450 | } |