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