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.
18 #include <BRep_Builder.hxx>
19 #include <BRep_Tool.hxx>
20 #include <BRepLib.hxx>
21 #include <BRepLib_MakeEdge.hxx>
22 #include <BRepLib_MakeWire.hxx>
23 #include <Geom_Curve.hxx>
26 #include <StdFail_NotDone.hxx>
28 #include <TopExp_Explorer.hxx>
30 #include <TopoDS_Edge.hxx>
31 #include <TopoDS_Iterator.hxx>
32 #include <TopoDS_Vertex.hxx>
33 #include <TopoDS_Wire.hxx>
34 #include <TopTools_MapIteratorOfMapOfShape.hxx>
35 #include <TopTools_MapOfShape.hxx>
37 //=======================================================================
38 //function : BRepLib_MakeWire
40 //=======================================================================
41 BRepLib_MakeWire::BRepLib_MakeWire() :
42 myError(BRepLib_EmptyWire)
47 //=======================================================================
48 //function : BRepLib_MakeWire
50 //=======================================================================
52 BRepLib_MakeWire::BRepLib_MakeWire(const TopoDS_Edge& E)
58 //=======================================================================
59 //function : BRepLib_MakeWire
61 //=======================================================================
63 BRepLib_MakeWire::BRepLib_MakeWire(const TopoDS_Edge& E1,
64 const TopoDS_Edge& E2)
71 //=======================================================================
72 //function : BRepLib_MakeWire
74 //=======================================================================
76 BRepLib_MakeWire::BRepLib_MakeWire(const TopoDS_Edge& E1,
77 const TopoDS_Edge& E2,
78 const TopoDS_Edge& E3)
86 //=======================================================================
87 //function : BRepLib_MakeWire
89 //=======================================================================
91 BRepLib_MakeWire::BRepLib_MakeWire(const TopoDS_Edge& E1,
92 const TopoDS_Edge& E2,
93 const TopoDS_Edge& E3,
94 const TopoDS_Edge& E4)
103 //=======================================================================
104 //function : BRepLib_MakeWire
106 //=======================================================================
108 BRepLib_MakeWire::BRepLib_MakeWire(const TopoDS_Wire& W)
114 //=======================================================================
115 //function : BRepLib_MakeWire
117 //=======================================================================
119 BRepLib_MakeWire::BRepLib_MakeWire(const TopoDS_Wire& W,
120 const TopoDS_Edge& E)
127 //=======================================================================
130 //=======================================================================
132 void BRepLib_MakeWire::Add(const TopoDS_Wire& W)
134 TopExp_Explorer ex(W,TopAbs_EDGE);
136 Add(TopoDS::Edge(ex.Current()));
141 //=======================================================================
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.
147 //=======================================================================
149 void BRepLib_MakeWire::Add(const TopoDS_Edge& E)
152 Standard_Boolean forward = Standard_False;
153 // to tell if it has been decided to add forward
154 Standard_Boolean reverse = Standard_False;
155 // to tell if it has been decided to add reversed
156 Standard_Boolean init = Standard_False;
157 // To know if it is necessary to calculate VL, VF
161 if (myEdge.IsNull()) {
162 init = Standard_True;
163 // first edge, create the wire
164 B.MakeWire(TopoDS::Wire(myShape));
170 for (it.Initialize(myEdge); it.More(); it.Next())
171 myVertices.Add(it.Value());
175 init = myShape.Closed(); // If it is closed no control
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));
180 // test the vertices of the edge
182 Standard_Boolean connected = Standard_False;
183 Standard_Boolean copyedge = Standard_False;
185 if (myError != BRepLib_NonManifoldWire) {
186 if (VF.IsNull() || VL.IsNull())
187 myError = BRepLib_NonManifoldWire;
190 for (it.Initialize(EE); it.More(); it.Next()) {
192 const TopoDS_Vertex& VE = TopoDS::Vertex(it.Value());
194 // if the vertex is in the wire, ok for the connection
195 if (myVertices.Contains(VE)) {
196 connected = Standard_True;
198 if (myError != BRepLib_NonManifoldWire) {
201 // Orientation indetermined (in 3d) : Preserve the initial
202 if (!VF.IsSame(VE)) myError = BRepLib_NonManifoldWire;
206 if (VE.Orientation() == TopAbs_FORWARD)
207 reverse = Standard_True;
209 forward = Standard_True;
211 else if (VL.IsSame(VE)) {
212 if (VE.Orientation() == TopAbs_REVERSED)
213 reverse = Standard_True;
215 forward = Standard_True;
218 myError = BRepLib_NonManifoldWire;
223 // search if there is a similar vertex in the edge
224 gp_Pnt PE = BRep_Tool::Pnt(VE);
226 // Standard_Boolean newvertex = Standard_False;
227 TopTools_MapIteratorOfMapOfShape itm(myVertices);
230 const TopoDS_Vertex& VW = TopoDS::Vertex(itm.Key());
231 gp_Pnt PW = BRep_Tool::Pnt(VW);
232 Standard_Real l = PE.Distance(PW);
234 if ((l < BRep_Tool::Tolerance(VE)) ||
235 (l < BRep_Tool::Tolerance(VW))) {
236 copyedge = Standard_True;
237 if (myError != BRepLib_NonManifoldWire) {
240 // Orientation indetermined (in 3d) : Preserve the initial
241 if (!VF.IsSame(VW)) myError = BRepLib_NonManifoldWire;
245 if (VE.Orientation() == TopAbs_FORWARD)
246 reverse = Standard_True;
248 forward = Standard_True;
250 else if (VL.IsSame(VW)) {
251 if (VE.Orientation() == TopAbs_REVERSED)
252 reverse = Standard_True;
254 forward = Standard_True;
257 myError = BRepLib_NonManifoldWire;
265 connected = Standard_True;
271 myError = BRepLib_DisconnectedWire;
278 for (it.Initialize(EE); it.More(); it.Next())
279 myVertices.Add(it.Value());
283 TopoDS_Shape Dummy = EE.EmptyCopied();
284 myEdge = TopoDS::Edge(Dummy);
286 for (it.Initialize(EE); it.More(); it.Next()) {
288 const TopoDS_Vertex& VE = TopoDS::Vertex(it.Value());
289 gp_Pnt PE = BRep_Tool::Pnt(VE);
291 Standard_Boolean newvertex = Standard_False;
292 TopTools_MapIteratorOfMapOfShape itm(myVertices);
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);
301 if ((l < tolE) || (l < tolW)) {
303 Standard_Real maxtol = .5*(tolW + tolE + l), cW, cE;
304 if(maxtol > tolW && maxtol > tolE) {
305 cW = (maxtol - tolE)/l;
308 else if (maxtol > tolW) {maxtol = tolE; cW = 0.; cE = 1.;}
309 else {maxtol = tolW; cW = 1.; cE = 0.;}
311 gp_Pnt PC(cW*PW.X() + cE*PE.X(),cW*PW.Y() + cE*PE.Y(),cW*PW.Z() + cE*PE.Z());
313 B.UpdateVertex(VW, PC, maxtol);
315 newvertex = Standard_True;
317 myVertex.Orientation(VE.Orientation());
318 B.Add(myEdge,myVertex);
319 B.Transfert(EE,myEdge,VE,myVertex);
328 B.Transfert(EE,myEdge,VE,VE);
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
339 if ( ((forward == reverse) && (E.Orientation() == TopAbs_REVERSED)) ||
340 ( reverse && !forward) ) myEdge.Reverse();
343 // add myEdge to myShape
344 B.Add(myShape,myEdge);
345 myShape.Closed(Standard_False);
348 if (init) TopExp::Vertices(TopoDS::Wire(myShape), VF,VL);
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;
357 cout << "MakeWire : There is a PROBLEM !!" << endl;
359 myError = BRepLib_NonManifoldWire;
363 // Particular case: it is required to control the orientation
365 if (!VF.IsSame(myVertex))
366 cout << "MakeWire : There is a PROBLEM !!" << endl;
370 else { // General case
371 if (VF.IsSame(myVertex)) VF = VRef;
372 else if (VL.IsSame(myVertex)) VL = VRef;
375 cout << "MakeWire : Y A UN PROBLEME !!" << endl;
377 myError = BRepLib_NonManifoldWire;
381 if (myError == BRepLib_NonManifoldWire) {
382 VF = VL = TopoDS_Vertex(); // nullify
385 // Test myShape is closed
386 if (!VF.IsNull() && !VL.IsNull() && VF.IsSame(VL))
387 myShape.Closed(Standard_True);
389 myError = BRepLib_WireDone;
394 //=======================================================================
397 //=======================================================================
399 const TopoDS_Wire& BRepLib_MakeWire::Wire()const
401 return TopoDS::Wire(Shape());
405 //=======================================================================
408 //=======================================================================
410 const TopoDS_Edge& BRepLib_MakeWire::Edge()const
416 //=======================================================================
419 //=======================================================================
421 const TopoDS_Vertex& BRepLib_MakeWire::Vertex()const
427 //=======================================================================
428 //function : operator
430 //=======================================================================
432 BRepLib_MakeWire::operator TopoDS_Wire() const
439 //=======================================================================
442 //=======================================================================
444 BRepLib_WireError BRepLib_MakeWire::Error() const