b011b50c7c112d4084058f04124e392138ad9a59
[occt.git] / src / TopExp / TopExp.cxx
1 // Created on: 1993-01-19
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 #define No_Standard_NoMoreObject
18 #define No_Standard_NoSuchObject
19 #define No_Standard_TypeMismatch
20
21
22 #include <TopExp.hxx>
23 #include <TopExp_Explorer.hxx>
24 #include <TopoDS.hxx>
25 #include <TopoDS_Edge.hxx>
26 #include <TopoDS_Iterator.hxx>
27 #include <TopoDS_Shape.hxx>
28 #include <TopoDS_Vertex.hxx>
29 #include <TopoDS_Wire.hxx>
30 #include <TopTools_ListOfShape.hxx>
31 #include <TopTools_MapIteratorOfMapOfShape.hxx>
32 #include <TopTools_MapOfShape.hxx>
33
34 //=======================================================================
35 //function : MapShapes
36 //purpose  : 
37 //=======================================================================
38 void TopExp::MapShapes(const TopoDS_Shape& S,
39                        const TopAbs_ShapeEnum T,
40                        TopTools_IndexedMapOfShape& M)
41 {
42   TopExp_Explorer Ex(S,T);
43   while (Ex.More()) {
44     M.Add(Ex.Current());
45     Ex.Next();
46   }
47 }
48
49 //=======================================================================
50 //function : MapShapes
51 //purpose  : 
52 //=======================================================================
53
54 void TopExp::MapShapes(const TopoDS_Shape& S,
55                        TopTools_IndexedMapOfShape& M)
56 {
57   M.Add(S);
58   TopoDS_Iterator It(S);
59   while (It.More()) {
60     MapShapes(It.Value(),M);
61     It.Next();
62   }
63 }
64
65 //=======================================================================
66 //function : MapShapesAndAncestors
67 //purpose  : 
68 //=======================================================================
69
70 void  TopExp::MapShapesAndAncestors
71   (const TopoDS_Shape& S, 
72    const TopAbs_ShapeEnum TS, 
73    const TopAbs_ShapeEnum TA, 
74    TopTools_IndexedDataMapOfShapeListOfShape& M)
75 {
76   TopTools_ListOfShape empty;
77   
78   // visit ancestors
79   TopExp_Explorer exa(S,TA);
80   while (exa.More()) {
81     // visit shapes
82     const TopoDS_Shape& anc = exa.Current();
83     TopExp_Explorer exs(anc,TS);
84     while (exs.More()) {
85       Standard_Integer index = M.FindIndex(exs.Current());
86       if (index == 0) index = M.Add(exs.Current(),empty);
87       M(index).Append(anc);
88       exs.Next();
89     }
90     exa.Next();
91   }
92   
93   // visit shapes not under ancestors
94   TopExp_Explorer ex(S,TS,TA);
95   while (ex.More()) {
96     Standard_Integer index = M.FindIndex(ex.Current());
97     if (index == 0) index = M.Add(ex.Current(),empty);
98     ex.Next();
99   }
100 }
101
102 //=======================================================================
103 //function : MapShapesAndUniqueAncestors
104 //purpose  : 
105 //=======================================================================
106
107 void  TopExp::MapShapesAndUniqueAncestors
108   (const TopoDS_Shape& S, 
109    const TopAbs_ShapeEnum TS, 
110    const TopAbs_ShapeEnum TA, 
111    TopTools_IndexedDataMapOfShapeListOfShape& M,
112    const Standard_Boolean useOrientation)
113 {
114   TopTools_ListOfShape empty;
115   
116   // visit ancestors
117   TopExp_Explorer exa(S,TA);
118   while (exa.More())
119   {
120     // visit shapes
121     const TopoDS_Shape& anc = exa.Current();
122     TopExp_Explorer exs(anc,TS);
123     while (exs.More())
124     {
125       Standard_Integer index = M.FindIndex(exs.Current());
126       if (index == 0)
127         index = M.Add(exs.Current(),empty);
128       TopTools_ListOfShape& aList = M(index);
129       // check if anc already exists in a list
130       TopTools_ListIteratorOfListOfShape it(aList);
131       for (; it.More(); it.Next())
132         if (useOrientation? anc.IsEqual(it.Value()) : anc.IsSame(it.Value()))
133           break;
134       if (!it.More())
135         aList.Append(anc);
136       exs.Next();
137     }
138     exa.Next();
139   }
140
141   // visit shapes not under ancestors
142   TopExp_Explorer ex(S,TS,TA);
143   while (ex.More())
144   {
145     Standard_Integer index = M.FindIndex(ex.Current());
146     if (index == 0) 
147       M.Add(ex.Current(),empty);
148     ex.Next();
149   }
150 }
151
152 //=======================================================================
153 //function : FirstVertex
154 //purpose  : 
155 //=======================================================================
156
157 TopoDS_Vertex  TopExp::FirstVertex(const TopoDS_Edge& E,
158                                    const Standard_Boolean CumOri)
159 {
160   TopoDS_Iterator ite(E,CumOri);
161   while (ite.More()) {
162     if (ite.Value().Orientation() == TopAbs_FORWARD) 
163       return TopoDS::Vertex(ite.Value());
164     ite.Next();
165   }
166   return TopoDS_Vertex();
167 }
168
169
170 //=======================================================================
171 //function : LastVertex
172 //purpose  : 
173 //=======================================================================
174
175 TopoDS_Vertex  TopExp::LastVertex(const TopoDS_Edge& E,
176                                   const Standard_Boolean CumOri)
177 {
178   TopoDS_Iterator ite(E,CumOri);
179   while (ite.More()) {
180     if (ite.Value().Orientation() == TopAbs_REVERSED) 
181       return TopoDS::Vertex(ite.Value());
182     ite.Next();
183   }
184   return TopoDS_Vertex();
185 }
186
187
188 //=======================================================================
189 //function : Vertices
190 //purpose  : 
191 //=======================================================================
192
193 void  TopExp::Vertices(const TopoDS_Edge& E,
194                        TopoDS_Vertex& Vfirst,
195                        TopoDS_Vertex& Vlast,
196                        const Standard_Boolean CumOri)
197 {
198   // minor optimization for case when Vfirst and Vlast are non-null:
199   // at least for VC++ 10, it is faster if we use boolean flags than 
200   // if we nullify vertices at that point (see #27021)
201   Standard_Boolean isFirstDefined = Standard_False;
202   Standard_Boolean isLastDefined = Standard_False;
203   
204   TopoDS_Iterator ite(E, CumOri);
205   while (ite.More()) {
206     const TopoDS_Shape& aV = ite.Value();
207     if (aV.Orientation() == TopAbs_FORWARD)
208     {
209       Vfirst = TopoDS::Vertex (aV);
210       isFirstDefined = Standard_True;
211     }
212     else if (aV.Orientation() == TopAbs_REVERSED)
213     {
214       Vlast = TopoDS::Vertex (aV);
215       isLastDefined = Standard_True;
216     }
217     ite.Next();
218   }
219
220   if (!isFirstDefined)
221     Vfirst.Nullify();
222
223   if (!isLastDefined)
224     Vlast.Nullify();
225 }
226
227
228 //=======================================================================
229 //function : Vertices
230 //purpose  : 
231 //=======================================================================
232
233 void  TopExp::Vertices(const TopoDS_Wire& W,
234                        TopoDS_Vertex& Vfirst,
235                        TopoDS_Vertex& Vlast)
236 {
237   Vfirst = Vlast = TopoDS_Vertex(); // nullify
238
239   TopTools_MapOfShape vmap;
240   TopoDS_Iterator it(W);
241   TopoDS_Vertex   V1,V2;
242
243   while (it.More()) {
244     const TopoDS_Edge& E = TopoDS::Edge(it.Value());
245     if (E.Orientation() == TopAbs_REVERSED)
246       TopExp::Vertices(E,V2,V1);
247     else
248       TopExp::Vertices(E,V1,V2);
249     // add or remove in the vertex map
250     V1.Orientation(TopAbs_FORWARD);
251     V2.Orientation(TopAbs_REVERSED);
252     if (!vmap.Add(V1)) vmap.Remove(V1);
253     if (!vmap.Add(V2)) vmap.Remove(V2);
254
255     it.Next();
256   }
257   if (vmap.IsEmpty()) { // closed
258     TopoDS_Shape aLocalShape = V2.Oriented(TopAbs_FORWARD);
259     Vfirst = TopoDS::Vertex(aLocalShape);
260     aLocalShape = V2.Oriented(TopAbs_REVERSED);
261     Vlast  = TopoDS::Vertex(aLocalShape);
262 //    Vfirst = TopoDS::Vertex(V2.Oriented(TopAbs_FORWARD));
263 //    Vlast  = TopoDS::Vertex(V2.Oriented(TopAbs_REVERSED));
264   }
265   else if (vmap.Extent() == 2) { //open
266     TopTools_MapIteratorOfMapOfShape ite(vmap);
267     
268     while (ite.More() && ite.Key().Orientation() != TopAbs_FORWARD) 
269       ite.Next();
270     if (ite.More()) Vfirst = TopoDS::Vertex(ite.Key());
271     ite.Initialize(vmap);
272     while (ite.More() && ite.Key().Orientation() != TopAbs_REVERSED) 
273       ite.Next();
274     if (ite.More()) Vlast = TopoDS::Vertex(ite.Key());
275   }
276 }
277
278
279 //=======================================================================
280 //function : CommonVertex
281 //purpose  : 
282 //=======================================================================
283 Standard_Boolean TopExp::CommonVertex(const TopoDS_Edge& E1, 
284                                       const TopoDS_Edge& E2,
285                                       TopoDS_Vertex& V)
286 {
287   TopoDS_Vertex firstVertex1, lastVertex1, firstVertex2, lastVertex2;
288   TopExp::Vertices(E1, firstVertex1, lastVertex1);
289   TopExp::Vertices(E2, firstVertex2, lastVertex2);
290
291   if (firstVertex1.IsSame(firstVertex2) || 
292       firstVertex1.IsSame(lastVertex2)) {
293     V = firstVertex1;
294     return Standard_True;
295   }
296   if (lastVertex1.IsSame(firstVertex2) ||
297            lastVertex1.IsSame(lastVertex2)) {
298     V = lastVertex1;
299     return Standard_True;
300   }
301   return Standard_False;
302 } // CommonVertex
303