4e57c75e |
1 | // Created by: Peter KURNEV |
973c2be1 |
2 | // Copyright (c) 1999-2014 OPEN CASCADE SAS |
4e57c75e |
3 | // |
973c2be1 |
4 | // This file is part of Open CASCADE Technology software library. |
4e57c75e |
5 | // |
d5f74e42 |
6 | // This library is free software; you can redistribute it and/or modify it under |
7 | // the terms of the GNU Lesser General Public License version 2.1 as published |
973c2be1 |
8 | // by the Free Software Foundation, with special exception defined in the file |
9 | // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT |
10 | // distribution for complete text of the license and disclaimer of any warranty. |
4e57c75e |
11 | // |
973c2be1 |
12 | // Alternatively, this file may be used under the terms of Open CASCADE |
13 | // commercial license or contractual agreement. |
4e57c75e |
14 | |
15 | //#include <BOPTools_Set.ixx> |
16 | |
17 | #include <TopExp_Explorer.hxx> |
18 | #include <BRep_Tool.hxx> |
19 | |
20 | |
21 | static |
22 | inline Standard_Boolean operator<(const TopoDS_Shape& theS1, |
23 | const TopoDS_Shape& theS2); |
24 | static |
25 | inline void SortShell(const int n, TopoDS_Shape *a); |
26 | |
27 | static |
28 | inline Standard_Integer NormalizedIds(const Standard_Integer aId, |
29 | const Standard_Integer aDiv); |
30 | //======================================================================= |
31 | //function : |
32 | //purpose : |
33 | //======================================================================= |
34 | inline BOPTools_Set::BOPTools_Set() |
35 | : |
36 | myAllocator(NCollection_BaseAllocator::CommonBaseAllocator()), |
37 | myShapes(myAllocator) |
38 | { |
39 | myNbShapes=0; |
40 | mySum=0; |
41 | myUpper=432123; |
42 | } |
43 | //======================================================================= |
44 | //function : |
45 | //purpose : |
46 | //======================================================================= |
47 | inline BOPTools_Set::BOPTools_Set(const Handle(NCollection_BaseAllocator)& theAllocator) |
48 | : |
49 | myAllocator(theAllocator), |
50 | myShapes(myAllocator) |
51 | { |
52 | myNbShapes=0; |
53 | mySum=0; |
54 | myUpper=432123; |
55 | } |
56 | //======================================================================= |
57 | //function :~ |
58 | //purpose : |
59 | //======================================================================= |
60 | inline BOPTools_Set::~BOPTools_Set() |
61 | { |
62 | Clear(); |
63 | } |
64 | //======================================================================= |
65 | //function : Clear |
66 | //purpose : |
67 | //======================================================================= |
68 | inline void BOPTools_Set::Clear() |
69 | { |
70 | myNbShapes=0; |
71 | mySum=0; |
72 | myShapes.Clear(); |
73 | } |
74 | //======================================================================= |
75 | //function : NbShapes |
76 | //purpose : |
77 | //======================================================================= |
78 | inline Standard_Integer BOPTools_Set::NbShapes()const |
79 | { |
80 | return myNbShapes; |
81 | } |
82 | //======================================================================= |
83 | //function :Assign |
84 | //purpose : |
85 | //======================================================================= |
86 | inline BOPTools_Set& BOPTools_Set::Assign(const BOPTools_Set& theOther) |
87 | { |
88 | BOPCol_ListIteratorOfListOfShape aIt; |
89 | // |
90 | myShape=theOther.myShape; |
91 | myNbShapes=theOther.myNbShapes; |
92 | mySum=theOther.mySum; |
93 | myUpper=theOther.myUpper; |
94 | myAllocator=theOther.myAllocator; |
95 | // |
96 | myShapes.Clear(); |
97 | aIt.Initialize(theOther.myShapes); |
98 | for (; aIt.More(); aIt.Next()) { |
99 | const TopoDS_Shape& aSx=aIt.Value(); |
100 | myShapes.Append(aSx); |
101 | } |
102 | return *this; |
103 | } |
104 | //======================================================================= |
105 | //function : Shape |
106 | //purpose : |
107 | //======================================================================= |
108 | inline const TopoDS_Shape& BOPTools_Set::Shape()const |
109 | { |
110 | return myShape; |
111 | } |
112 | //======================================================================= |
113 | //function : Add |
114 | //purpose : |
115 | //======================================================================= |
116 | inline void BOPTools_Set::Add(const TopoDS_Shape& theS, |
117 | const TopAbs_ShapeEnum theType) |
118 | { |
119 | if (theType==TopAbs_EDGE) { |
120 | AddEdges(theS); |
121 | return; |
122 | } |
123 | // |
124 | Standard_Integer i, aNb, aId, aIdN; |
125 | TopoDS_Shape *pShapes; |
126 | TopExp_Explorer aExp; |
127 | // |
128 | myNbShapes=0; |
129 | mySum=0; |
130 | myShape=theS; |
131 | // |
132 | aExp.Init(theS, theType); |
133 | for (aNb=0; aExp.More(); aExp.Next(), ++aNb) { |
134 | } |
135 | // |
136 | if (!aNb) { |
137 | return; |
138 | } |
139 | // |
140 | myNbShapes=aNb; |
141 | pShapes=(TopoDS_Shape *)myAllocator->Allocate(aNb*sizeof(TopoDS_Shape)); |
142 | // |
143 | aExp.ReInit(); |
144 | for (i=0; aExp.More(); aExp.Next(),++i) { |
145 | const TopoDS_Shape& aSx=aExp.Current(); |
146 | new (pShapes+i) TopoDS_Shape(); |
147 | pShapes[i]=aSx; |
148 | } |
149 | // |
150 | SortShell(aNb, pShapes); |
151 | // |
152 | myShapes.Clear(); |
153 | for (i=0; i<aNb; ++i) { |
154 | const TopoDS_Shape& aSx=pShapes[i]; |
155 | myShapes.Append(aSx); |
156 | // |
157 | aId=aSx.HashCode(myUpper); |
158 | aIdN=NormalizedIds(aId, aNb); |
159 | mySum+=aIdN; |
160 | } |
161 | // |
162 | for (i=0; i<aNb; ++i) { |
163 | pShapes[i].~TopoDS_Shape(); |
164 | } |
547702a1 |
165 | myAllocator->Free(pShapes); |
4e57c75e |
166 | } |
167 | //======================================================================= |
168 | //function : AddEdges |
169 | //purpose : |
170 | //======================================================================= |
171 | inline void BOPTools_Set::AddEdges(const TopoDS_Shape& theS) |
172 | { |
173 | Standard_Integer i, aNb, aId, aIdN; |
174 | TopoDS_Shape *pShapes; |
175 | TopExp_Explorer aExp; |
176 | // |
177 | myNbShapes=0; |
178 | mySum=0; |
179 | myShape=theS; |
180 | // |
181 | aExp.Init(theS, TopAbs_EDGE); |
182 | for (aNb=0; aExp.More(); aExp.Next()) { |
183 | const TopoDS_Edge& aE=(*(TopoDS_Edge*)(&aExp.Current())); |
184 | if (!BRep_Tool::Degenerated(aE)) { |
185 | ++aNb; |
186 | } |
187 | } |
188 | // |
189 | if (!aNb) { |
190 | return; |
191 | } |
192 | // |
193 | myNbShapes=aNb; |
194 | pShapes=(TopoDS_Shape *)myAllocator->Allocate(aNb*sizeof(TopoDS_Shape)); |
195 | // |
196 | i=0; |
197 | aExp.ReInit(); |
198 | for (; aExp.More(); aExp.Next()) { |
199 | const TopoDS_Shape& aSx=aExp.Current(); |
200 | const TopoDS_Edge& aE=(*(TopoDS_Edge*)(&aSx)); |
201 | if (!BRep_Tool::Degenerated(aE)) { |
202 | new (pShapes+i) TopoDS_Shape(); |
203 | pShapes[i]=aSx; |
204 | ++i; |
205 | } |
206 | } |
207 | // |
208 | SortShell(aNb, pShapes); |
209 | // |
210 | myShapes.Clear(); |
211 | for (i=0; i<aNb; ++i) { |
212 | const TopoDS_Shape& aSx=pShapes[i]; |
213 | myShapes.Append(aSx); |
214 | // |
215 | aId=aSx.HashCode(myUpper); |
216 | aIdN=NormalizedIds(aId, aNb); |
217 | mySum+=aIdN; |
218 | } |
219 | // |
220 | for (i=0; i<aNb; ++i) { |
221 | pShapes[i].~TopoDS_Shape(); |
222 | } |
547702a1 |
223 | myAllocator->Free(pShapes); |
4e57c75e |
224 | } |
225 | //======================================================================= |
226 | //function : IsEqual |
227 | //purpose : |
228 | //======================================================================= |
229 | inline Standard_Boolean BOPTools_Set::IsEqual(const BOPTools_Set& theOther)const |
230 | { |
231 | Standard_Boolean bRet; |
232 | // |
233 | bRet=Standard_False; |
234 | // |
235 | if (theOther.myNbShapes!=myNbShapes) { |
236 | return bRet; |
237 | } |
238 | // |
239 | BOPCol_ListIteratorOfListOfShape aIt1, aIt2; |
240 | // |
241 | aIt1.Initialize(myShapes); |
242 | aIt2.Initialize(theOther.myShapes); |
243 | for (; aIt1.More()||aIt2.More(); aIt1.Next(), aIt2.Next()) { |
244 | const TopoDS_Shape& aSx1=aIt1.Value(); |
245 | const TopoDS_Shape& aSx2=aIt2.Value(); |
246 | if (aSx1.TShape().operator->() != aSx2.TShape().operator->()) { |
247 | return bRet; |
248 | } |
249 | } |
250 | return !bRet; |
251 | } |
252 | //======================================================================= |
253 | //function : HashCode |
254 | //purpose : |
255 | //======================================================================= |
256 | inline Standard_Integer BOPTools_Set::HashCode(const Standard_Integer theUpper)const |
257 | { |
258 | return ::HashCode(mySum, theUpper); |
259 | } |
260 | //======================================================================= |
261 | // function: NormalizedIds |
262 | // purpose : |
263 | //======================================================================= |
264 | Standard_Integer NormalizedIds(const Standard_Integer aId, |
265 | const Standard_Integer aDiv) |
266 | { |
267 | Standard_Integer aMax, aTresh, aIdRet; |
268 | // |
269 | aIdRet=aId; |
270 | aMax=::IntegerLast(); |
271 | aTresh=aMax/aDiv; |
272 | if (aId>aTresh) { |
273 | aIdRet=aId%aTresh; |
274 | } |
275 | return aIdRet; |
276 | } |
277 | |
278 | //======================================================================= |
279 | //function : operator< |
280 | //purpose : |
281 | //======================================================================= |
282 | Standard_Boolean operator<(const TopoDS_Shape& theS1, |
283 | const TopoDS_Shape& theS2) |
284 | { |
285 | Standard_Address aAddr1, aAddr2; |
286 | // |
287 | const Handle(TopoDS_TShape)& aTS1=theS1.TShape(); |
288 | aAddr1=aTS1.operator->(); |
289 | // |
290 | const Handle(TopoDS_TShape)& aTS2=theS2.TShape(); |
291 | aAddr2=aTS2.operator->(); |
292 | // |
293 | return (aAddr1<aAddr2); |
294 | } |
295 | //======================================================================= |
296 | // function: SortShell |
297 | // purpose : |
298 | //======================================================================= |
299 | void SortShell(const int n, TopoDS_Shape *a) |
300 | { |
301 | int nd, i, j, l, d=1; |
302 | TopoDS_Shape x; |
303 | // |
304 | while(d<=n) { |
305 | d*=2; |
306 | } |
307 | // |
308 | while (d) { |
309 | d=(d-1)/2; |
310 | // |
311 | nd=n-d; |
312 | for (i=0; i<nd; ++i) { |
313 | j=i; |
314 | m30:; |
315 | l=j+d; |
316 | if (a[l] < a[j]){ |
317 | x=a[j]; |
318 | a[j]=a[l]; |
319 | a[l]=x; |
320 | j-=d; |
321 | if (j > -1) goto m30; |
322 | }//if (a[l] < a[j]){ |
323 | }//for (i=0; i<nd; ++i) |
324 | }//while (1) |
325 | } |