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