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