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 for (TopoDS_Iterator it(W); it.More(); it.Next()) {
135 Add(TopoDS::Edge(it.Value()));
136 if (myError != BRepLib_WireDone)
141 //=======================================================================
144 //=======================================================================
145 void BRepLib_MakeWire::Add(const TopoDS_Edge& E)
147 Add(E, Standard_True);
150 //=======================================================================
153 // PMN 19/03/1998 For the Problem of performance TopExp::Vertices are not used on wire
154 // PMN 10/09/1998 In case if the wire is previously closed (or degenerated)
155 // TopExp::Vertices is used to reduce the ambiguity.
156 // IsCheckGeometryProximity flag : If true => check for the geometry proximity of vertices
157 //=======================================================================
158 void BRepLib_MakeWire::Add(const TopoDS_Edge& E, Standard_Boolean IsCheckGeometryProximity)
161 Standard_Boolean forward = Standard_False;
162 // to tell if it has been decided to add forward
163 Standard_Boolean reverse = Standard_False;
164 // to tell if it has been decided to add reversed
165 Standard_Boolean init = Standard_False;
166 // To know if it is necessary to calculate VL, VF
170 if (myEdge.IsNull()) {
171 init = Standard_True;
172 // first edge, create the wire
173 B.MakeWire(TopoDS::Wire(myShape));
179 for (it.Initialize(myEdge); it.More(); it.Next())
180 myVertices.Add(it.Value());
184 init = myShape.Closed(); // If it is closed no control
185 TopoDS_Shape aLocalShape = E.Oriented(TopAbs_FORWARD);
186 TopoDS_Edge EE = TopoDS::Edge(aLocalShape);
187 // TopoDS_Edge EE = TopoDS::Edge(E.Oriented(TopAbs_FORWARD));
189 // test the vertices of the edge
191 Standard_Boolean connected = Standard_False;
192 Standard_Boolean copyedge = Standard_False;
194 if (myError != BRepLib_NonManifoldWire) {
195 if (VF.IsNull() || VL.IsNull())
196 myError = BRepLib_NonManifoldWire;
199 for (it.Initialize(EE); it.More(); it.Next()) {
201 const TopoDS_Vertex& VE = TopoDS::Vertex(it.Value());
203 // if the vertex is in the wire, ok for the connection
204 if (myVertices.Contains(VE)) {
205 connected = Standard_True;
207 if (myError != BRepLib_NonManifoldWire) {
210 // Orientation indetermined (in 3d) : Preserve the initial
211 if (!VF.IsSame(VE)) myError = BRepLib_NonManifoldWire;
215 if (VE.Orientation() == TopAbs_FORWARD)
216 reverse = Standard_True;
218 forward = Standard_True;
220 else if (VL.IsSame(VE)) {
221 if (VE.Orientation() == TopAbs_REVERSED)
222 reverse = Standard_True;
224 forward = Standard_True;
227 myError = BRepLib_NonManifoldWire;
231 else if (IsCheckGeometryProximity)
233 // search if there is a similar vertex in the edge
234 gp_Pnt PE = BRep_Tool::Pnt(VE);
236 for (Standard_Integer i = 1; i <= myVertices.Extent(); i++) {
237 const TopoDS_Vertex& VW = TopoDS::Vertex(myVertices.FindKey(i));
238 gp_Pnt PW = BRep_Tool::Pnt(VW);
239 Standard_Real l = PE.Distance(PW);
241 if ((l < BRep_Tool::Tolerance(VE)) ||
242 (l < BRep_Tool::Tolerance(VW))) {
243 copyedge = Standard_True;
244 if (myError != BRepLib_NonManifoldWire) {
247 // Orientation indetermined (in 3d) : Preserve the initial
248 if (!VF.IsSame(VW)) myError = BRepLib_NonManifoldWire;
252 if (VE.Orientation() == TopAbs_FORWARD)
253 reverse = Standard_True;
255 forward = Standard_True;
257 else if (VL.IsSame(VW)) {
258 if (VE.Orientation() == TopAbs_REVERSED)
259 reverse = Standard_True;
261 forward = Standard_True;
264 myError = BRepLib_NonManifoldWire;
271 connected = Standard_True;
277 myError = BRepLib_DisconnectedWire;
284 for (it.Initialize(EE); it.More(); it.Next())
285 myVertices.Add(it.Value());
289 TopoDS_Shape Dummy = EE.EmptyCopied();
290 myEdge = TopoDS::Edge(Dummy);
292 for (it.Initialize(EE); it.More(); it.Next()) {
294 const TopoDS_Vertex& VE = TopoDS::Vertex(it.Value());
295 gp_Pnt PE = BRep_Tool::Pnt(VE);
297 Standard_Boolean newvertex = Standard_False;
298 for (Standard_Integer i = 1; i <= myVertices.Extent(); i++) {
299 const TopoDS_Vertex& VW = TopoDS::Vertex(myVertices.FindKey(i));
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);
305 if ((l < tolE) || (l < tolW)) {
307 Standard_Real maxtol = .5*(tolW + tolE + l), cW, cE;
308 if(maxtol > tolW && maxtol > tolE) {
309 cW = (maxtol - tolE)/l;
312 else if (maxtol > tolW) {maxtol = tolE; cW = 0.; cE = 1.;}
313 else {maxtol = tolW; cW = 1.; cE = 0.;}
315 gp_Pnt PC(cW*PW.X() + cE*PE.X(),cW*PW.Y() + cE*PE.Y(),cW*PW.Z() + cE*PE.Z());
317 B.UpdateVertex(VW, PC, maxtol);
319 newvertex = Standard_True;
321 myVertex.Orientation(VE.Orientation());
322 B.Add(myEdge,myVertex);
323 B.Transfert(EE,myEdge,VE,myVertex);
331 B.Transfert(EE,myEdge,VE,VE);
336 // Make a decision about the orientation of the edge
337 // If there is an ambiguity (in 3d) preserve the orientation given at input
338 // Case of ambiguity :
339 // reverse and forward are false as nothing has been decided :
340 // closed wire, internal vertex ...
341 // reverse and forward are true : closed or degenerated edge
342 if ( ((forward == reverse) && (E.Orientation() == TopAbs_REVERSED)) ||
343 ( reverse && !forward) ) myEdge.Reverse();
346 // add myEdge to myShape
347 B.Add(myShape,myEdge);
348 myShape.Closed(Standard_False);
351 if (init) TopExp::Vertices(TopoDS::Wire(myShape), VF,VL);
353 if (myError == BRepLib_WireDone){ // Update only
354 TopoDS_Vertex V1,V2,VRef;
355 TopExp::Vertices(myEdge, V1, V2);
356 if (V1.IsSame(myVertex)) VRef = V2;
357 else if (V2.IsSame(myVertex)) VRef = V1;
360 std::cout << "MakeWire : There is a PROBLEM !!" << std::endl;
362 myError = BRepLib_NonManifoldWire;
366 // Particular case: it is required to control the orientation
368 if (!VF.IsSame(myVertex))
369 std::cout << "MakeWire : There is a PROBLEM !!" << std::endl;
373 else { // General case
374 if (VF.IsSame(myVertex)) VF = VRef;
375 else if (VL.IsSame(myVertex)) VL = VRef;
378 std::cout << "MakeWire : Y A UN PROBLEME !!" << std::endl;
380 myError = BRepLib_NonManifoldWire;
384 if (myError == BRepLib_NonManifoldWire) {
385 VF = VL = TopoDS_Vertex(); // nullify
388 // Test myShape is closed
389 if (!VF.IsNull() && !VL.IsNull() && VF.IsSame(VL))
390 myShape.Closed(Standard_True);
392 myError = BRepLib_WireDone;
397 //=======================================================================
400 //=======================================================================
402 const TopoDS_Wire& BRepLib_MakeWire::Wire()
404 return TopoDS::Wire(Shape());
408 //=======================================================================
411 //=======================================================================
413 const TopoDS_Edge& BRepLib_MakeWire::Edge()const
419 //=======================================================================
422 //=======================================================================
424 const TopoDS_Vertex& BRepLib_MakeWire::Vertex()const
430 //=======================================================================
431 //function : operator
433 //=======================================================================
435 BRepLib_MakeWire::operator TopoDS_Wire()
442 //=======================================================================
445 //=======================================================================
447 BRepLib_WireError BRepLib_MakeWire::Error() const