0024624: Lost word in license statement in source files
[occt.git] / src / BRepLib / BRepLib_MakeWire.cxx
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
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
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.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17 #include <BRepLib_MakeWire.ixx>
18 #include <BRepLib.hxx>
19 #include <BRepLib_MakeEdge.hxx>
20 #include <BRep_Tool.hxx>
21 #include <BRep_Builder.hxx>
22 #include <TopExp.hxx>
23 #include <TopExp_Explorer.hxx>
24 #include <TopTools_MapOfShape.hxx>
25 #include <TopTools_MapIteratorOfMapOfShape.hxx>
26 #include <TopoDS.hxx>
27 #include <TopoDS_Iterator.hxx>
28 #include <gp_Pnt.hxx>
29 #include <Geom_Curve.hxx>
30 #include <gp.hxx>
31
32
33 //=======================================================================
34 //function : BRepLib_MakeWire
35 //purpose  : 
36 //=======================================================================
37
38 BRepLib_MakeWire::BRepLib_MakeWire() :
39      myError(BRepLib_EmptyWire)
40 {
41 }
42
43
44 //=======================================================================
45 //function : BRepLib_MakeWire
46 //purpose  : 
47 //=======================================================================
48
49 BRepLib_MakeWire::BRepLib_MakeWire(const TopoDS_Edge& E)
50 {
51   Add(E);
52 }
53
54
55 //=======================================================================
56 //function : BRepLib_MakeWire
57 //purpose  : 
58 //=======================================================================
59
60 BRepLib_MakeWire::BRepLib_MakeWire(const TopoDS_Edge& E1, 
61                                    const TopoDS_Edge& E2)
62 {
63   Add(E1);
64   Add(E2);
65 }
66
67
68 //=======================================================================
69 //function : BRepLib_MakeWire
70 //purpose  : 
71 //=======================================================================
72
73 BRepLib_MakeWire::BRepLib_MakeWire(const TopoDS_Edge& E1,
74                                    const TopoDS_Edge& E2, 
75                                    const TopoDS_Edge& E3)
76 {
77   Add(E1);
78   Add(E2);
79   Add(E3);
80 }
81
82
83 //=======================================================================
84 //function : BRepLib_MakeWire
85 //purpose  : 
86 //=======================================================================
87
88 BRepLib_MakeWire::BRepLib_MakeWire(const TopoDS_Edge& E1, 
89                                    const TopoDS_Edge& E2,
90                                    const TopoDS_Edge& E3, 
91                                    const TopoDS_Edge& E4)
92 {
93   Add(E1);
94   Add(E2);
95   Add(E3);
96   Add(E4);
97 }
98
99
100 //=======================================================================
101 //function : BRepLib_MakeWire
102 //purpose  : 
103 //=======================================================================
104
105 BRepLib_MakeWire::BRepLib_MakeWire(const TopoDS_Wire& W)
106 {
107   Add(W);
108 }
109
110
111 //=======================================================================
112 //function : BRepLib_MakeWire
113 //purpose  : 
114 //=======================================================================
115
116 BRepLib_MakeWire::BRepLib_MakeWire(const TopoDS_Wire& W, 
117                                    const TopoDS_Edge& E)
118 {
119   Add(W);
120   Add(E);
121 }
122
123
124 //=======================================================================
125 //function : Add
126 //purpose  : 
127 //=======================================================================
128
129 void  BRepLib_MakeWire::Add(const TopoDS_Wire& W)
130 {
131   TopExp_Explorer ex(W,TopAbs_EDGE);
132   while (ex.More()) {
133     Add(TopoDS::Edge(ex.Current()));
134     ex.Next();
135   }
136 }
137
138 //=======================================================================
139 //function : Add
140 //purpose  : 
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 //=======================================================================
145
146 void  BRepLib_MakeWire::Add(const TopoDS_Edge& E)
147 {
148
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
155   BRep_Builder B;
156   TopoDS_Iterator it;
157
158   if (myEdge.IsNull()) {
159     init = Standard_True;
160     // first edge, create the wire
161     B.MakeWire(TopoDS::Wire(myShape));
162
163     // set the edge
164     myEdge = E;
165
166     // add the vertices
167     for (it.Initialize(myEdge); it.More(); it.Next()) 
168       myVertices.Add(it.Value());
169   }
170   
171   else {
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));
176
177     // test the vertices of the edge
178     
179     Standard_Boolean connected = Standard_False;
180     Standard_Boolean copyedge  = Standard_False;
181     
182     if (myError != BRepLib_NonManifoldWire) {
183       if (VF.IsNull() || VL.IsNull()) 
184         myError = BRepLib_NonManifoldWire;
185     }
186
187     for (it.Initialize(EE); it.More(); it.Next()) {
188
189       const TopoDS_Vertex& VE = TopoDS::Vertex(it.Value());
190
191       // if the vertex is in the wire, ok for the connection
192       if (myVertices.Contains(VE)) {
193         connected = Standard_True;
194         myVertex = VE;
195         if (myError != BRepLib_NonManifoldWire) {
196           // is it always so ?
197           if (VF.IsSame(VL)) {
198             // Orientation indetermined (in 3d) : Preserve the initial
199             if (!VF.IsSame(VE)) myError = BRepLib_NonManifoldWire;
200           }
201           else {
202             if (VF.IsSame(VE)) {
203               if  (VE.Orientation() == TopAbs_FORWARD) 
204                 reverse = Standard_True;
205               else 
206                 forward = Standard_True;
207             }
208             else if (VL.IsSame(VE)) {
209               if (VE.Orientation() == TopAbs_REVERSED)
210                 reverse = Standard_True;
211               else 
212                 forward = Standard_True;
213             }
214             else 
215               myError = BRepLib_NonManifoldWire;
216           }
217         }
218       }
219       else {
220           // search if there is a similar vertex in the edge    
221         gp_Pnt PE = BRep_Tool::Pnt(VE);
222         
223 //      Standard_Boolean newvertex = Standard_False;
224         TopTools_MapIteratorOfMapOfShape itm(myVertices);
225         while (itm.More()) {
226           
227           const TopoDS_Vertex& VW = TopoDS::Vertex(itm.Key());
228           gp_Pnt PW = BRep_Tool::Pnt(VW);
229           Standard_Real l = PE.Distance(PW);
230           
231           if ((l < BRep_Tool::Tolerance(VE)) ||
232               (l < BRep_Tool::Tolerance(VW))) {
233             copyedge = Standard_True;
234             if (myError != BRepLib_NonManifoldWire) {
235               // is it always so ?
236               if (VF.IsSame(VL)) {
237                 // Orientation indetermined (in 3d) : Preserve the initial
238                 if (!VF.IsSame(VW)) myError = BRepLib_NonManifoldWire;
239               }
240               else {
241                 if (VF.IsSame(VW)) {
242                  if  (VE.Orientation() == TopAbs_FORWARD) 
243                    reverse = Standard_True;
244                  else 
245                    forward = Standard_True; 
246                 }
247                 else if (VL.IsSame(VW)) { 
248                   if (VE.Orientation() == TopAbs_REVERSED)
249                     reverse = Standard_True;
250                   else 
251                     forward = Standard_True;
252                 }
253                 else 
254                   myError = BRepLib_NonManifoldWire;
255               }
256             }      
257             break;
258           }
259           itm.Next();
260         }
261         if (copyedge) {
262           connected = Standard_True;
263         }
264       }
265     }
266     
267     if (!connected) {
268       myError = BRepLib_DisconnectedWire;
269       NotDone();
270       return;
271     }
272     else {
273       if (!copyedge) {
274         myEdge = EE;
275         for (it.Initialize(EE); it.More(); it.Next())
276           myVertices.Add(it.Value());
277       }
278       else {
279         // copy the edge
280         TopoDS_Shape Dummy = EE.EmptyCopied();
281         myEdge = TopoDS::Edge(Dummy);
282         myEdge.Closed(EE.Closed());
283         
284         for (it.Initialize(EE); it.More(); it.Next()) {
285
286           const TopoDS_Vertex& VE = TopoDS::Vertex(it.Value());
287           gp_Pnt PE = BRep_Tool::Pnt(VE);
288           
289           Standard_Boolean newvertex = Standard_False;
290           TopTools_MapIteratorOfMapOfShape itm(myVertices);
291           while (itm.More()) {
292           
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);
298             
299             if ((l < tolE) || (l < tolW)) {
300
301               Standard_Real maxtol = .5*(tolW + tolE + l), cW, cE;
302               if(maxtol > tolW && maxtol > tolE) {
303                 cW = (maxtol - tolE)/l; 
304                 cE = 1. - cW;
305               }
306               else if (maxtol > tolW) {maxtol = tolE; cW = 0.; cE = 1.;}
307               else {maxtol = tolW; cW = 1.; cE = 0.;}
308
309               gp_Pnt PC(cW*PW.X() + cE*PE.X(),cW*PW.Y() + cE*PE.Y(),cW*PW.Z() + cE*PE.Z());
310
311               B.UpdateVertex(VW, PC, maxtol);
312               
313               newvertex = Standard_True;
314               myVertex = VW;
315               myVertex.Orientation(VE.Orientation());
316               B.Add(myEdge,myVertex);
317               B.Transfert(EE,myEdge,VE,myVertex);
318               break;
319             }
320             
321             itm.Next();
322           }
323           if (!newvertex) {
324             myVertices.Add(VE);
325             B.Add(myEdge,VE);
326             B.Transfert(EE,myEdge,VE,VE);
327           }
328         }
329       }
330     }
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();
339   }
340  
341   // add myEdge to myShape
342   B.Add(myShape,myEdge);
343   myShape.Closed(Standard_False);
344
345   // Initialize VF, VL
346   if (init) TopExp::Vertices(TopoDS::Wire(myShape), VF,VL);
347   else {
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;
353       else {
354 #if DEB
355         cout << "MakeWire : There is a PROBLEM !!" << endl;
356 #endif
357         myError = BRepLib_NonManifoldWire;
358       }
359       
360       if (VF.IsSame(VL)) {
361         // Particular case: it is required to control the orientation
362 #if DEB
363         if (!VF.IsSame(myVertex))
364           cout << "MakeWire : There is a PROBLEM !!" << endl;
365 #endif
366         
367       }
368       else { // General case
369         if (VF.IsSame(myVertex)) VF = VRef;
370         else if (VL.IsSame(myVertex)) VL = VRef;
371         else {
372 #if DEB
373           cout << "MakeWire : Y A UN PROBLEME !!" << endl;
374 #endif
375           myError = BRepLib_NonManifoldWire;
376         }
377       }
378     }
379     if (myError == BRepLib_NonManifoldWire) {
380       VF = VL = TopoDS_Vertex(); // nullify
381     }
382   }
383   // Test myShape is closed
384   if (!VF.IsNull() && !VL.IsNull() && VF.IsSame(VL))
385     myShape.Closed(Standard_True);
386   
387   myError = BRepLib_WireDone;
388   Done();
389 }
390
391
392 //=======================================================================
393 //function : Wire
394 //purpose  : 
395 //=======================================================================
396
397 const TopoDS_Wire&  BRepLib_MakeWire::Wire()const 
398 {
399   return TopoDS::Wire(Shape());
400 }
401
402
403 //=======================================================================
404 //function : Edge
405 //purpose  : 
406 //=======================================================================
407
408 const TopoDS_Edge&  BRepLib_MakeWire::Edge()const 
409 {
410   return myEdge;
411 }
412
413
414 //=======================================================================
415 //function : Vertex
416 //purpose  : 
417 //=======================================================================
418
419 const TopoDS_Vertex&  BRepLib_MakeWire::Vertex()const 
420 {
421   return myVertex;
422 }
423
424
425 //=======================================================================
426 //function : operator
427 //purpose  : 
428 //=======================================================================
429
430 BRepLib_MakeWire::operator TopoDS_Wire() const
431 {
432   return Wire();
433 }
434
435
436
437 //=======================================================================
438 //function : Error
439 //purpose  : 
440 //=======================================================================
441
442 BRepLib_WireError BRepLib_MakeWire::Error() const
443 {
444   return myError;
445 }