0027021: TopExp::Vertices performance optimization
[occt.git] / src / TopExp / TopExp.cxx
CommitLineData
b311480e 1// Created on: 1993-01-19
2// Created by: Remi LEQUETTE
3// Copyright (c) 1993-1999 Matra Datavision
973c2be1 4// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 5//
973c2be1 6// This file is part of Open CASCADE Technology software library.
b311480e 7//
d5f74e42 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
973c2be1 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.
b311480e 13//
973c2be1 14// Alternatively, this file may be used under the terms of Open CASCADE
15// commercial license or contractual agreement.
7fd59977 16
17#define No_Standard_NoMoreObject
18#define No_Standard_NoSuchObject
19#define No_Standard_TypeMismatch
20
42cf5bc1 21
22#include <TopExp.hxx>
7fd59977 23#include <TopExp_Explorer.hxx>
42cf5bc1 24#include <TopoDS.hxx>
25#include <TopoDS_Edge.hxx>
7fd59977 26#include <TopoDS_Iterator.hxx>
42cf5bc1 27#include <TopoDS_Shape.hxx>
28#include <TopoDS_Vertex.hxx>
29#include <TopoDS_Wire.hxx>
7fd59977 30#include <TopTools_ListOfShape.hxx>
7fd59977 31#include <TopTools_MapIteratorOfMapOfShape.hxx>
42cf5bc1 32#include <TopTools_MapOfShape.hxx>
7fd59977 33
34//=======================================================================
35//function : MapShapes
36//purpose :
37//=======================================================================
7fd59977 38void 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
54void 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
70void 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
104//=======================================================================
105//function : FirstVertex
106//purpose :
107//=======================================================================
108
109TopoDS_Vertex TopExp::FirstVertex(const TopoDS_Edge& E,
110 const Standard_Boolean CumOri)
111{
112 TopoDS_Iterator ite(E,CumOri);
113 while (ite.More()) {
114 if (ite.Value().Orientation() == TopAbs_FORWARD)
115 return TopoDS::Vertex(ite.Value());
116 ite.Next();
117 }
118 return TopoDS_Vertex();
119}
120
121
122//=======================================================================
123//function : LastVertex
124//purpose :
125//=======================================================================
126
127TopoDS_Vertex TopExp::LastVertex(const TopoDS_Edge& E,
128 const Standard_Boolean CumOri)
129{
130 TopoDS_Iterator ite(E,CumOri);
131 while (ite.More()) {
132 if (ite.Value().Orientation() == TopAbs_REVERSED)
133 return TopoDS::Vertex(ite.Value());
134 ite.Next();
135 }
136 return TopoDS_Vertex();
137}
138
139
140//=======================================================================
141//function : Vertices
142//purpose :
143//=======================================================================
144
145void TopExp::Vertices(const TopoDS_Edge& E,
146 TopoDS_Vertex& Vfirst,
147 TopoDS_Vertex& Vlast,
148 const Standard_Boolean CumOri)
149{
8447359f 150 // minor optimization for case when Vfirst and Vlast are non-null:
151 // at least for VC++ 10, it is faster if we use boolean flags than
152 // if we nullify vertices at that point (see #27021)
153 Standard_Boolean isFirstDefined = Standard_False;
154 Standard_Boolean isLastDefined = Standard_False;
155
156 TopoDS_Iterator ite(E, CumOri);
7fd59977 157 while (ite.More()) {
8447359f 158 const TopoDS_Shape& aV = ite.Value();
159 if (aV.Orientation() == TopAbs_FORWARD)
160 {
161 Vfirst = TopoDS::Vertex (aV);
162 isFirstDefined = Standard_True;
163 }
164 else if (aV.Orientation() == TopAbs_REVERSED)
165 {
166 Vlast = TopoDS::Vertex (aV);
167 isLastDefined = Standard_True;
168 }
7fd59977 169 ite.Next();
170 }
8447359f 171
172 if (!isFirstDefined)
173 Vfirst.Nullify();
174
175 if (!isLastDefined)
176 Vlast.Nullify();
7fd59977 177}
178
179
180//=======================================================================
181//function : Vertices
182//purpose :
183//=======================================================================
184
185void TopExp::Vertices(const TopoDS_Wire& W,
186 TopoDS_Vertex& Vfirst,
187 TopoDS_Vertex& Vlast)
188{
189 Vfirst = Vlast = TopoDS_Vertex(); // nullify
190
191 TopTools_MapOfShape vmap;
192 TopoDS_Iterator it(W);
193 TopoDS_Vertex V1,V2;
194
195 while (it.More()) {
196 const TopoDS_Edge& E = TopoDS::Edge(it.Value());
197 if (E.Orientation() == TopAbs_REVERSED)
198 TopExp::Vertices(E,V2,V1);
199 else
200 TopExp::Vertices(E,V1,V2);
201 // add or remove in the vertex map
202 V1.Orientation(TopAbs_FORWARD);
203 V2.Orientation(TopAbs_REVERSED);
204 if (!vmap.Add(V1)) vmap.Remove(V1);
205 if (!vmap.Add(V2)) vmap.Remove(V2);
206
207 it.Next();
208 }
209 if (vmap.IsEmpty()) { // closed
210 TopoDS_Shape aLocalShape = V2.Oriented(TopAbs_FORWARD);
211 Vfirst = TopoDS::Vertex(aLocalShape);
212 aLocalShape = V2.Oriented(TopAbs_REVERSED);
213 Vlast = TopoDS::Vertex(aLocalShape);
214// Vfirst = TopoDS::Vertex(V2.Oriented(TopAbs_FORWARD));
215// Vlast = TopoDS::Vertex(V2.Oriented(TopAbs_REVERSED));
216 }
217 else if (vmap.Extent() == 2) { //open
218 TopTools_MapIteratorOfMapOfShape ite(vmap);
219
220 while (ite.More() && ite.Key().Orientation() != TopAbs_FORWARD)
221 ite.Next();
222 if (ite.More()) Vfirst = TopoDS::Vertex(ite.Key());
223 ite.Initialize(vmap);
224 while (ite.More() && ite.Key().Orientation() != TopAbs_REVERSED)
225 ite.Next();
226 if (ite.More()) Vlast = TopoDS::Vertex(ite.Key());
227 }
228}
229
230
231//=======================================================================
232//function : CommonVertex
233//purpose :
234//=======================================================================
235Standard_Boolean TopExp::CommonVertex(const TopoDS_Edge& E1,
236 const TopoDS_Edge& E2,
237 TopoDS_Vertex& V)
238{
239 TopoDS_Vertex firstVertex1, lastVertex1, firstVertex2, lastVertex2;
240 TopExp::Vertices(E1, firstVertex1, lastVertex1);
241 TopExp::Vertices(E2, firstVertex2, lastVertex2);
242
243 if (firstVertex1.IsSame(firstVertex2) ||
244 firstVertex1.IsSame(lastVertex2)) {
245 V = firstVertex1;
246 return Standard_True;
247 }
248 if (lastVertex1.IsSame(firstVertex2) ||
249 lastVertex1.IsSame(lastVertex2)) {
250 V = lastVertex1;
251 return Standard_True;
252 }
253 return Standard_False;
254} // CommonVertex
255