1 // File: BRepLib_MakeWire.cxx
2 // Created: Fri Jul 23 15:51:57 1993
3 // Author: Remi LEQUETTE
7 #include <BRepLib_MakeWire.ixx>
9 #include <BRepLib_MakeEdge.hxx>
10 #include <BRep_Tool.hxx>
11 #include <BRep_Builder.hxx>
13 #include <TopExp_Explorer.hxx>
14 #include <TopTools_MapOfShape.hxx>
15 #include <TopTools_MapIteratorOfMapOfShape.hxx>
17 #include <TopoDS_Iterator.hxx>
19 #include <Geom_Curve.hxx>
23 //=======================================================================
24 //function : BRepLib_MakeWire
26 //=======================================================================
28 BRepLib_MakeWire::BRepLib_MakeWire() :
29 myError(BRepLib_EmptyWire)
34 //=======================================================================
35 //function : BRepLib_MakeWire
37 //=======================================================================
39 BRepLib_MakeWire::BRepLib_MakeWire(const TopoDS_Edge& E)
45 //=======================================================================
46 //function : BRepLib_MakeWire
48 //=======================================================================
50 BRepLib_MakeWire::BRepLib_MakeWire(const TopoDS_Edge& E1,
51 const TopoDS_Edge& E2)
58 //=======================================================================
59 //function : BRepLib_MakeWire
61 //=======================================================================
63 BRepLib_MakeWire::BRepLib_MakeWire(const TopoDS_Edge& E1,
64 const TopoDS_Edge& E2,
65 const TopoDS_Edge& E3)
73 //=======================================================================
74 //function : BRepLib_MakeWire
76 //=======================================================================
78 BRepLib_MakeWire::BRepLib_MakeWire(const TopoDS_Edge& E1,
79 const TopoDS_Edge& E2,
80 const TopoDS_Edge& E3,
81 const TopoDS_Edge& E4)
90 //=======================================================================
91 //function : BRepLib_MakeWire
93 //=======================================================================
95 BRepLib_MakeWire::BRepLib_MakeWire(const TopoDS_Wire& W)
101 //=======================================================================
102 //function : BRepLib_MakeWire
104 //=======================================================================
106 BRepLib_MakeWire::BRepLib_MakeWire(const TopoDS_Wire& W,
107 const TopoDS_Edge& E)
114 //=======================================================================
117 //=======================================================================
119 void BRepLib_MakeWire::Add(const TopoDS_Wire& W)
121 TopExp_Explorer ex(W,TopAbs_EDGE);
123 Add(TopoDS::Edge(ex.Current()));
128 //=======================================================================
131 // PMN 19/03/1998 For the Problem of performance TopExp::Vertices are not used on wire
132 // PMN 10/09/1998 In case if the wire is previously closed (or degenerated)
133 // TopExp::Vertices is used to reduce the ambiguity.
134 //=======================================================================
136 void BRepLib_MakeWire::Add(const TopoDS_Edge& E)
139 Standard_Boolean forward = Standard_False;
140 // to tell if it has been decided to add forward
141 Standard_Boolean reverse = Standard_False;
142 // to tell if it has been decided to add reversed
143 Standard_Boolean init = Standard_False;
144 // To know if it is necessary to calculate VL, VF
148 if (myEdge.IsNull()) {
149 init = Standard_True;
150 // first edge, create the wire
151 B.MakeWire(TopoDS::Wire(myShape));
157 for (it.Initialize(myEdge); it.More(); it.Next())
158 myVertices.Add(it.Value());
162 init = myShape.Closed(); // If it is closed no control
163 TopoDS_Shape aLocalShape = E.Oriented(TopAbs_FORWARD);
164 TopoDS_Edge EE = TopoDS::Edge(aLocalShape);
165 // TopoDS_Edge EE = TopoDS::Edge(E.Oriented(TopAbs_FORWARD));
167 // test the vertices of the edge
169 Standard_Boolean connected = Standard_False;
170 Standard_Boolean copyedge = Standard_False;
172 if (myError != BRepLib_NonManifoldWire) {
173 if (VF.IsNull() || VL.IsNull())
174 myError = BRepLib_NonManifoldWire;
177 for (it.Initialize(EE); it.More(); it.Next()) {
179 const TopoDS_Vertex& VE = TopoDS::Vertex(it.Value());
181 // if the vertex is in the wire, ok for the connection
182 if (myVertices.Contains(VE)) {
183 connected = Standard_True;
185 if (myError != BRepLib_NonManifoldWire) {
188 // Orientation indetermined (in 3d) : Preserve the initial
189 if (!VF.IsSame(VE)) myError = BRepLib_NonManifoldWire;
193 if (VE.Orientation() == TopAbs_FORWARD)
194 reverse = Standard_True;
196 forward = Standard_True;
198 else if (VL.IsSame(VE)) {
199 if (VE.Orientation() == TopAbs_REVERSED)
200 reverse = Standard_True;
202 forward = Standard_True;
205 myError = BRepLib_NonManifoldWire;
210 // search if there is a similar vertex in the edge
211 gp_Pnt PE = BRep_Tool::Pnt(VE);
213 // Standard_Boolean newvertex = Standard_False;
214 TopTools_MapIteratorOfMapOfShape itm(myVertices);
217 const TopoDS_Vertex& VW = TopoDS::Vertex(itm.Key());
218 gp_Pnt PW = BRep_Tool::Pnt(VW);
219 Standard_Real l = PE.Distance(PW);
221 if ((l < BRep_Tool::Tolerance(VE)) ||
222 (l < BRep_Tool::Tolerance(VW))) {
223 copyedge = Standard_True;
224 if (myError != BRepLib_NonManifoldWire) {
227 // Orientation indetermined (in 3d) : Preserve the initial
228 if (!VF.IsSame(VW)) myError = BRepLib_NonManifoldWire;
232 if (VE.Orientation() == TopAbs_FORWARD)
233 reverse = Standard_True;
235 forward = Standard_True;
237 else if (VL.IsSame(VW)) {
238 if (VE.Orientation() == TopAbs_REVERSED)
239 reverse = Standard_True;
241 forward = Standard_True;
244 myError = BRepLib_NonManifoldWire;
252 connected = Standard_True;
258 myError = BRepLib_DisconnectedWire;
265 for (it.Initialize(EE); it.More(); it.Next())
266 myVertices.Add(it.Value());
270 TopoDS_Shape Dummy = EE.EmptyCopied();
271 myEdge = TopoDS::Edge(Dummy);
272 myEdge.Closed(EE.Closed());
274 for (it.Initialize(EE); it.More(); it.Next()) {
276 const TopoDS_Vertex& VE = TopoDS::Vertex(it.Value());
277 gp_Pnt PE = BRep_Tool::Pnt(VE);
279 Standard_Boolean newvertex = Standard_False;
280 TopTools_MapIteratorOfMapOfShape itm(myVertices);
283 const TopoDS_Vertex& VW = TopoDS::Vertex(itm.Key());
284 gp_Pnt PW = BRep_Tool::Pnt(VW);
285 Standard_Real l = PE.Distance(PW), tolE, tolW;
286 tolW = BRep_Tool::Tolerance(VW);
287 tolE = BRep_Tool::Tolerance(VE);
289 if ((l < tolE) || (l < tolW)) {
291 Standard_Real maxtol = .5*(tolW + tolE + l), cW, cE;
292 if(maxtol > tolW && maxtol > tolE) {
293 cW = (maxtol - tolE)/l;
296 else if (maxtol > tolW) {maxtol = tolE; cW = 0.; cE = 1.;}
297 else {maxtol = tolW; cW = 1.; cE = 0.;}
299 gp_Pnt PC(cW*PW.X() + cE*PE.X(),cW*PW.Y() + cE*PE.Y(),cW*PW.Z() + cE*PE.Z());
301 B.UpdateVertex(VW, PC, maxtol);
303 newvertex = Standard_True;
305 myVertex.Orientation(VE.Orientation());
306 B.Add(myEdge,myVertex);
307 B.Transfert(EE,myEdge,VE,myVertex);
316 B.Transfert(EE,myEdge,VE,VE);
321 // Make a decision about the orientation of the edge
322 // If there is an ambiguity (in 3d) preserve the orientation given at input
323 // Case of ambiguity :
324 // reverse and forward are false as nothing has been decided :
325 // closed wire, internal vertex ...
326 // reverse and forward are true : closed or degenerated edge
327 if ( ((forward == reverse) && (E.Orientation() == TopAbs_REVERSED)) ||
328 ( reverse && !forward) ) myEdge.Reverse();
331 // add myEdge to myShape
332 B.Add(myShape,myEdge);
333 myShape.Closed(Standard_False);
336 if (init) TopExp::Vertices(TopoDS::Wire(myShape), VF,VL);
338 if (myError == BRepLib_WireDone){ // Update only
339 TopoDS_Vertex V1,V2,VRef;
340 TopExp::Vertices(myEdge, V1, V2);
341 if (V1.IsSame(myVertex)) VRef = V2;
342 else if (V2.IsSame(myVertex)) VRef = V1;
345 cout << "MakeWire : There is a PROBLEM !!" << endl;
347 myError = BRepLib_NonManifoldWire;
351 // Particular case: it is required to control the orientation
353 if (!VF.IsSame(myVertex))
354 cout << "MakeWire : There is a PROBLEM !!" << endl;
358 else { // General case
359 if (VF.IsSame(myVertex)) VF = VRef;
360 else if (VL.IsSame(myVertex)) VL = VRef;
363 cout << "MakeWire : Y A UN PROBLEME !!" << endl;
365 myError = BRepLib_NonManifoldWire;
369 if (myError == BRepLib_NonManifoldWire) {
370 VF = VL = TopoDS_Vertex(); // nullify
373 // Test myShape is closed
374 if (!VF.IsNull() && !VL.IsNull() && VF.IsSame(VL))
375 myShape.Closed(Standard_True);
377 myError = BRepLib_WireDone;
382 //=======================================================================
385 //=======================================================================
387 const TopoDS_Wire& BRepLib_MakeWire::Wire()const
389 return TopoDS::Wire(Shape());
393 //=======================================================================
396 //=======================================================================
398 const TopoDS_Edge& BRepLib_MakeWire::Edge()const
404 //=======================================================================
407 //=======================================================================
409 const TopoDS_Vertex& BRepLib_MakeWire::Vertex()const
415 //=======================================================================
416 //function : operator
418 //=======================================================================
420 BRepLib_MakeWire::operator TopoDS_Wire() const
427 //=======================================================================
430 //=======================================================================
432 BRepLib_WireError BRepLib_MakeWire::Error() const