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