0026937: Eliminate NO_CXX_EXCEPTION macro support
[occt.git] / src / LocOpe / LocOpe_BuildWires.cxx
1 // Created on: 1997-05-27
2 // Created by: Jacques GOUSSARD
3 // Copyright (c) 1997-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 //  Modified by skv - Mon May 31 12:58:34 2004 OCC5865
18
19 #include <BRep_Builder.hxx>
20 #include <LocOpe_BuildWires.hxx>
21 #include <LocOpe_WiresOnShape.hxx>
22 #include <Standard_ConstructionError.hxx>
23 #include <StdFail_NotDone.hxx>
24 #include <TopExp.hxx>
25 #include <TopoDS.hxx>
26 #include <TopoDS_Compound.hxx>
27 #include <TopoDS_Edge.hxx>
28 #include <TopoDS_Vertex.hxx>
29 #include <TopoDS_Wire.hxx>
30 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
31 #include <TopTools_IndexedMapOfShape.hxx>
32 #include <TopTools_ListIteratorOfListOfShape.hxx>
33 #include <TopTools_MapIteratorOfMapOfShape.hxx>
34 #include <TopTools_MapOfShape.hxx>
35
36 static Standard_Integer FindFirstEdge
37    (const TopTools_IndexedDataMapOfShapeListOfShape&,
38     const TopTools_MapOfShape&);
39
40
41
42 //=======================================================================
43 //function : LocOpe_BuildWires
44 //purpose  : 
45 //=======================================================================
46
47 LocOpe_BuildWires::LocOpe_BuildWires () : myDone(Standard_False)
48 {}
49
50
51 //=======================================================================
52 //function : LocOpe_BuildWires
53 //purpose  : 
54 //=======================================================================
55
56 //  Modified by skv - Mon May 31 12:58:27 2004 OCC5865 Begin
57 LocOpe_BuildWires::LocOpe_BuildWires (const TopTools_ListOfShape& L,
58                                       const Handle(LocOpe_WiresOnShape)& PW)
59 {
60   Perform(L, PW);
61 }
62 //  Modified by skv - Mon May 31 12:58:28 2004 OCC5865 End
63
64
65 //=======================================================================
66 //function : Perform
67 //purpose  : 
68 //=======================================================================
69
70 //  Modified by skv - Mon May 31 12:59:09 2004 OCC5865 Begin
71 void LocOpe_BuildWires::Perform(const TopTools_ListOfShape& L,
72                                 const Handle(LocOpe_WiresOnShape)& PW)
73 {
74 //  Modified by skv - Mon May 31 12:59:10 2004 OCC5865 End
75   myDone = Standard_False;
76   myRes.Clear();
77
78   BRep_Builder B;
79   TopoDS_Compound C;
80   B.MakeCompound(C);
81
82   TopTools_MapOfShape theMap;
83   TopTools_ListIteratorOfListOfShape itl(L);
84   for (; itl.More(); itl.Next()) {
85     const TopoDS_Shape& edg = itl.Value();
86     if (theMap.Add(edg) && edg.ShapeType() == TopAbs_EDGE) {
87       B.Add(C,edg.Oriented(TopAbs_FORWARD)); // orientation importante pour
88       // appel a TopExp::Vertices
89     }
90   }
91
92   TopTools_IndexedDataMapOfShapeListOfShape theMapVE;
93   TopExp::MapShapesAndAncestors(C,TopAbs_VERTEX,TopAbs_EDGE,theMapVE);
94
95   TopTools_MapOfShape Bords;
96 //  for (Standard_Integer i = 1; i <= theMapVE.Extent(); i++) {
97   Standard_Integer i ;
98  
99   for ( i = 1; i <= theMapVE.Extent(); i++) {
100 //  Modified by skv - Mon May 31 13:07:50 2004 OCC5865 Begin
101 //     if (theMapVE(i).Extent() == 1) {
102     TopoDS_Vertex vtx = TopoDS::Vertex(theMapVE.FindKey(i));
103     TopoDS_Edge   etmp;
104     TopoDS_Vertex aV_border;
105     Standard_Real partmp;
106     if (theMapVE(i).Extent() == 1 || (PW->OnVertex(vtx, aV_border) || PW->OnEdge(vtx, etmp, partmp)) ) {
107       Bords.Add(vtx);
108 //  Modified by skv - Mon May 31 13:07:50 2004 OCC5865 End
109     }
110   }
111
112
113   while ((i=FindFirstEdge(theMapVE,Bords)) <= theMapVE.Extent()) {
114     TopTools_IndexedMapOfShape mapE;
115     TopTools_MapOfShape mapV;
116     const TopoDS_Edge&  edgf = TopoDS::Edge(theMapVE(i).First());
117
118     TopoDS_Vertex VF,VL;
119     TopExp::Vertices(edgf,VF,VL);
120
121     if (Bords.Contains(VL) && !Bords.Contains(VF)) {
122       mapE.Add(edgf.Oriented(TopAbs_REVERSED));
123       TopoDS_Vertex temp = VF;
124       VF = VL;
125       VL = temp;
126     }
127     else {
128       mapE.Add(edgf.Oriented(TopAbs_FORWARD));
129     }
130     mapV.Add(VF);
131     
132     while (!(mapV.Contains(VL) || Bords.Contains(VL))) {
133       Standard_Integer ind = theMapVE.FindIndex(VL);
134       TopTools_ListIteratorOfListOfShape anIterl(theMapVE(ind));
135       for (; anIterl.More(); anIterl.Next()) {
136         if (!mapE.Contains(anIterl.Value())) {
137           break;
138         }
139       }
140
141       if (!anIterl.More()) {
142         throw Standard_ConstructionError();
143       }
144       const TopoDS_Edge& theEdge = TopoDS::Edge(anIterl.Value());
145       TopoDS_Vertex Vf,Vl;
146       TopExp::Vertices(theEdge,Vf,Vl);
147       mapV.Add(VL);
148       if (Vf.IsSame(VL)) {
149         mapE.Add(theEdge.Oriented(TopAbs_FORWARD));
150         VL = Vl;
151       }
152       else { // on doit avoir Vl == VL
153         mapE.Add(theEdge.Oriented(TopAbs_REVERSED));
154         VL = Vf;
155       }
156     }
157
158     TopoDS_Wire newWire;
159     B.MakeWire(newWire);
160
161     if (mapV.Contains(VL)) { // on sort avec une boucle a recreer
162       TopoDS_Vertex Vf;
163 //      for (Standard_Integer j = 1; j<= mapE.Extent(); j++) {
164       Standard_Integer j ;
165       for ( j = 1; j<= mapE.Extent(); j++) {
166         const TopoDS_Edge& edg = TopoDS::Edge(mapE(j));
167         if (edg.Orientation() == TopAbs_FORWARD) {
168           Vf = TopExp::FirstVertex(edg);
169         }
170         else {
171           Vf = TopExp::LastVertex(edg);
172         }
173         if (Vf.IsSame(VL)) {
174           break;
175         }
176         mapV.Remove(Vf);
177       }
178       for (; j<= mapE.Extent(); j++) {
179         B.Add(newWire,mapE(j));
180       }
181       newWire.Closed(Standard_True);
182     }
183     else { // on sort sur un bord : wire ouvert...
184       mapV.Add(VL);
185       for (Standard_Integer j = 1; j <= mapE.Extent(); j++) {
186         B.Add(newWire,mapE(j));
187       }
188       newWire.Closed(Standard_False);
189     }
190
191     myRes.Append(newWire);
192     TopTools_MapIteratorOfMapOfShape itm;
193     for (itm.Initialize(mapV);
194          itm.More();itm.Next()) {
195       const TopoDS_Vertex& vtx = TopoDS::Vertex(itm.Key());
196       Bords.Add(vtx);
197       Standard_Integer ind = theMapVE.FindIndex(vtx);
198       itl.Initialize(theMapVE(ind));
199       while (itl.More()) {
200         if (mapE.Contains(itl.Value())) {
201           theMapVE(ind).Remove(itl);
202         }
203         else {
204           itl.Next();
205         }
206       }
207     }
208   }
209
210   myDone = Standard_True;
211 }
212
213
214
215 //=======================================================================
216 //function : IsDone
217 //purpose  : 
218 //=======================================================================
219
220 Standard_Boolean LocOpe_BuildWires::IsDone() const
221 {
222   return myDone;
223 }
224
225
226
227 //=======================================================================
228 //function : Result
229 //purpose  : 
230 //=======================================================================
231
232 const TopTools_ListOfShape& LocOpe_BuildWires::Result () const
233 {
234   if (!myDone) {
235     throw StdFail_NotDone();
236   }
237   return myRes;
238 }
239
240
241 //=======================================================================
242 //function : FindFirstEdge
243 //purpose  : 
244 //=======================================================================
245
246 static Standard_Integer FindFirstEdge
247    (const TopTools_IndexedDataMapOfShapeListOfShape& theMapVE,
248     const TopTools_MapOfShape& theBord)
249 {
250   Standard_Integer i = 1;
251
252   for (; i<=theMapVE.Extent(); i++) {
253     if (theMapVE(i).Extent() >0) {
254       break;
255     }
256   }
257
258   if (i>theMapVE.Extent()) {
259     return i;
260   }
261
262   Standard_Integer goodi = i;
263   for (; i <= theMapVE.Extent(); i++) {
264     const TopoDS_Shape& vtx = theMapVE.FindKey(i);
265     if (theMapVE(i).Extent() >0 && theBord.Contains(vtx)) {
266       goodi = i;
267       break;
268     }
269   }
270   return goodi;
271 }
272