0022627: Change OCCT memory management defaults
[occt.git] / src / BRepLib / BRepLib_MakeWire.cxx
CommitLineData
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
28BRepLib_MakeWire::BRepLib_MakeWire() :
29 myError(BRepLib_EmptyWire)
30{
31}
32
33
34//=======================================================================
35//function : BRepLib_MakeWire
36//purpose :
37//=======================================================================
38
39BRepLib_MakeWire::BRepLib_MakeWire(const TopoDS_Edge& E)
40{
41 Add(E);
42}
43
44
45//=======================================================================
46//function : BRepLib_MakeWire
47//purpose :
48//=======================================================================
49
50BRepLib_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
63BRepLib_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
78BRepLib_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
95BRepLib_MakeWire::BRepLib_MakeWire(const TopoDS_Wire& W)
96{
97 Add(W);
98}
99
100
101//=======================================================================
102//function : BRepLib_MakeWire
103//purpose :
104//=======================================================================
105
106BRepLib_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
119void 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
136void 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
387const TopoDS_Wire& BRepLib_MakeWire::Wire()const
388{
389 return TopoDS::Wire(Shape());
390}
391
392
393//=======================================================================
394//function : Edge
395//purpose :
396//=======================================================================
397
398const TopoDS_Edge& BRepLib_MakeWire::Edge()const
399{
400 return myEdge;
401}
402
403
404//=======================================================================
405//function : Vertex
406//purpose :
407//=======================================================================
408
409const TopoDS_Vertex& BRepLib_MakeWire::Vertex()const
410{
411 return myVertex;
412}
413
414
415//=======================================================================
416//function : operator
417//purpose :
418//=======================================================================
419
420BRepLib_MakeWire::operator TopoDS_Wire() const
421{
422 return Wire();
423}
424
425
426
427//=======================================================================
428//function : Error
429//purpose :
430//=======================================================================
431
432BRepLib_WireError BRepLib_MakeWire::Error() const
433{
434 return myError;
435}