1 // Created on: 1993-07-23
2 // Created by: Remi LEQUETTE
3 // Copyright (c) 1993-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
6 // This file is part of Open CASCADE Technology software library.
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
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.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
17 #include <BRepLib_MakeWire.ixx>
18 #include <BRepLib.hxx>
19 #include <BRepLib_MakeEdge.hxx>
20 #include <BRep_Tool.hxx>
21 #include <BRep_Builder.hxx>
23 #include <TopExp_Explorer.hxx>
24 #include <TopTools_MapOfShape.hxx>
25 #include <TopTools_MapIteratorOfMapOfShape.hxx>
27 #include <TopoDS_Iterator.hxx>
29 #include <Geom_Curve.hxx>
33 //=======================================================================
34 //function : BRepLib_MakeWire
36 //=======================================================================
38 BRepLib_MakeWire::BRepLib_MakeWire() :
39 myError(BRepLib_EmptyWire)
44 //=======================================================================
45 //function : BRepLib_MakeWire
47 //=======================================================================
49 BRepLib_MakeWire::BRepLib_MakeWire(const TopoDS_Edge& E)
55 //=======================================================================
56 //function : BRepLib_MakeWire
58 //=======================================================================
60 BRepLib_MakeWire::BRepLib_MakeWire(const TopoDS_Edge& E1,
61 const TopoDS_Edge& E2)
68 //=======================================================================
69 //function : BRepLib_MakeWire
71 //=======================================================================
73 BRepLib_MakeWire::BRepLib_MakeWire(const TopoDS_Edge& E1,
74 const TopoDS_Edge& E2,
75 const TopoDS_Edge& E3)
83 //=======================================================================
84 //function : BRepLib_MakeWire
86 //=======================================================================
88 BRepLib_MakeWire::BRepLib_MakeWire(const TopoDS_Edge& E1,
89 const TopoDS_Edge& E2,
90 const TopoDS_Edge& E3,
91 const TopoDS_Edge& E4)
100 //=======================================================================
101 //function : BRepLib_MakeWire
103 //=======================================================================
105 BRepLib_MakeWire::BRepLib_MakeWire(const TopoDS_Wire& W)
111 //=======================================================================
112 //function : BRepLib_MakeWire
114 //=======================================================================
116 BRepLib_MakeWire::BRepLib_MakeWire(const TopoDS_Wire& W,
117 const TopoDS_Edge& E)
124 //=======================================================================
127 //=======================================================================
129 void BRepLib_MakeWire::Add(const TopoDS_Wire& W)
131 TopExp_Explorer ex(W,TopAbs_EDGE);
133 Add(TopoDS::Edge(ex.Current()));
138 //=======================================================================
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.
144 //=======================================================================
146 void BRepLib_MakeWire::Add(const TopoDS_Edge& E)
149 Standard_Boolean forward = Standard_False;
150 // to tell if it has been decided to add forward
151 Standard_Boolean reverse = Standard_False;
152 // to tell if it has been decided to add reversed
153 Standard_Boolean init = Standard_False;
154 // To know if it is necessary to calculate VL, VF
158 if (myEdge.IsNull()) {
159 init = Standard_True;
160 // first edge, create the wire
161 B.MakeWire(TopoDS::Wire(myShape));
167 for (it.Initialize(myEdge); it.More(); it.Next())
168 myVertices.Add(it.Value());
172 init = myShape.Closed(); // If it is closed no control
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));
177 // test the vertices of the edge
179 Standard_Boolean connected = Standard_False;
180 Standard_Boolean copyedge = Standard_False;
182 if (myError != BRepLib_NonManifoldWire) {
183 if (VF.IsNull() || VL.IsNull())
184 myError = BRepLib_NonManifoldWire;
187 for (it.Initialize(EE); it.More(); it.Next()) {
189 const TopoDS_Vertex& VE = TopoDS::Vertex(it.Value());
191 // if the vertex is in the wire, ok for the connection
192 if (myVertices.Contains(VE)) {
193 connected = Standard_True;
195 if (myError != BRepLib_NonManifoldWire) {
198 // Orientation indetermined (in 3d) : Preserve the initial
199 if (!VF.IsSame(VE)) myError = BRepLib_NonManifoldWire;
203 if (VE.Orientation() == TopAbs_FORWARD)
204 reverse = Standard_True;
206 forward = Standard_True;
208 else if (VL.IsSame(VE)) {
209 if (VE.Orientation() == TopAbs_REVERSED)
210 reverse = Standard_True;
212 forward = Standard_True;
215 myError = BRepLib_NonManifoldWire;
220 // search if there is a similar vertex in the edge
221 gp_Pnt PE = BRep_Tool::Pnt(VE);
223 // Standard_Boolean newvertex = Standard_False;
224 TopTools_MapIteratorOfMapOfShape itm(myVertices);
227 const TopoDS_Vertex& VW = TopoDS::Vertex(itm.Key());
228 gp_Pnt PW = BRep_Tool::Pnt(VW);
229 Standard_Real l = PE.Distance(PW);
231 if ((l < BRep_Tool::Tolerance(VE)) ||
232 (l < BRep_Tool::Tolerance(VW))) {
233 copyedge = Standard_True;
234 if (myError != BRepLib_NonManifoldWire) {
237 // Orientation indetermined (in 3d) : Preserve the initial
238 if (!VF.IsSame(VW)) myError = BRepLib_NonManifoldWire;
242 if (VE.Orientation() == TopAbs_FORWARD)
243 reverse = Standard_True;
245 forward = Standard_True;
247 else if (VL.IsSame(VW)) {
248 if (VE.Orientation() == TopAbs_REVERSED)
249 reverse = Standard_True;
251 forward = Standard_True;
254 myError = BRepLib_NonManifoldWire;
262 connected = Standard_True;
268 myError = BRepLib_DisconnectedWire;
275 for (it.Initialize(EE); it.More(); it.Next())
276 myVertices.Add(it.Value());
280 TopoDS_Shape Dummy = EE.EmptyCopied();
281 myEdge = TopoDS::Edge(Dummy);
282 myEdge.Closed(EE.Closed());
284 for (it.Initialize(EE); it.More(); it.Next()) {
286 const TopoDS_Vertex& VE = TopoDS::Vertex(it.Value());
287 gp_Pnt PE = BRep_Tool::Pnt(VE);
289 Standard_Boolean newvertex = Standard_False;
290 TopTools_MapIteratorOfMapOfShape itm(myVertices);
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);
299 if ((l < tolE) || (l < tolW)) {
301 Standard_Real maxtol = .5*(tolW + tolE + l), cW, cE;
302 if(maxtol > tolW && maxtol > tolE) {
303 cW = (maxtol - tolE)/l;
306 else if (maxtol > tolW) {maxtol = tolE; cW = 0.; cE = 1.;}
307 else {maxtol = tolW; cW = 1.; cE = 0.;}
309 gp_Pnt PC(cW*PW.X() + cE*PE.X(),cW*PW.Y() + cE*PE.Y(),cW*PW.Z() + cE*PE.Z());
311 B.UpdateVertex(VW, PC, maxtol);
313 newvertex = Standard_True;
315 myVertex.Orientation(VE.Orientation());
316 B.Add(myEdge,myVertex);
317 B.Transfert(EE,myEdge,VE,myVertex);
326 B.Transfert(EE,myEdge,VE,VE);
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
337 if ( ((forward == reverse) && (E.Orientation() == TopAbs_REVERSED)) ||
338 ( reverse && !forward) ) myEdge.Reverse();
341 // add myEdge to myShape
342 B.Add(myShape,myEdge);
343 myShape.Closed(Standard_False);
346 if (init) TopExp::Vertices(TopoDS::Wire(myShape), VF,VL);
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;
355 cout << "MakeWire : There is a PROBLEM !!" << endl;
357 myError = BRepLib_NonManifoldWire;
361 // Particular case: it is required to control the orientation
363 if (!VF.IsSame(myVertex))
364 cout << "MakeWire : There is a PROBLEM !!" << endl;
368 else { // General case
369 if (VF.IsSame(myVertex)) VF = VRef;
370 else if (VL.IsSame(myVertex)) VL = VRef;
373 cout << "MakeWire : Y A UN PROBLEME !!" << endl;
375 myError = BRepLib_NonManifoldWire;
379 if (myError == BRepLib_NonManifoldWire) {
380 VF = VL = TopoDS_Vertex(); // nullify
383 // Test myShape is closed
384 if (!VF.IsNull() && !VL.IsNull() && VF.IsSame(VL))
385 myShape.Closed(Standard_True);
387 myError = BRepLib_WireDone;
392 //=======================================================================
395 //=======================================================================
397 const TopoDS_Wire& BRepLib_MakeWire::Wire()const
399 return TopoDS::Wire(Shape());
403 //=======================================================================
406 //=======================================================================
408 const TopoDS_Edge& BRepLib_MakeWire::Edge()const
414 //=======================================================================
417 //=======================================================================
419 const TopoDS_Vertex& BRepLib_MakeWire::Vertex()const
425 //=======================================================================
426 //function : operator
428 //=======================================================================
430 BRepLib_MakeWire::operator TopoDS_Wire() const
437 //=======================================================================
440 //=======================================================================
442 BRepLib_WireError BRepLib_MakeWire::Error() const