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