973c2be1 |
1 | // Copyright (c) 1999-2014 OPEN CASCADE SAS |
b311480e |
2 | // |
973c2be1 |
3 | // This file is part of Open CASCADE Technology software library. |
b311480e |
4 | // |
d5f74e42 |
5 | // This library is free software; you can redistribute it and/or modify it under |
6 | // the terms of the GNU Lesser General Public License version 2.1 as published |
973c2be1 |
7 | // by the Free Software Foundation, with special exception defined in the file |
8 | // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT |
9 | // distribution for complete text of the license and disclaimer of any warranty. |
b311480e |
10 | // |
973c2be1 |
11 | // Alternatively, this file may be used under the terms of Open CASCADE |
12 | // commercial license or contractual agreement. |
b311480e |
13 | |
7fd59977 |
14 | //:o4 abv 17.02.99: r0301_db.stp #53082: treatment of open wires implemented |
15 | // pdn 11.03.99 S4135 changing reordering algorithm in order to make it independent on tolerance |
16 | //szv#4 S4163 |
17 | // pdn 09.05.99: S4174: preserve order of edges for complete torus |
18 | #include <ShapeAnalysis_WireOrder.ixx> |
19 | |
20 | #include <Precision.hxx> |
21 | |
22 | #include <Standard_TypeMismatch.hxx> |
23 | |
24 | #include <TColgp_Array1OfXYZ.hxx> |
25 | #include <TColStd_Array1OfInteger.hxx> |
26 | #include <TColStd_SequenceOfInteger.hxx> |
27 | #include <TColStd_Array1OfBoolean.hxx> |
28 | #include <TColStd_SequenceOfInteger.hxx> |
29 | #include <gp_Pnt.hxx> |
30 | #include <TColStd_SequenceOfTransient.hxx> |
31 | #include <TColStd_HSequenceOfInteger.hxx> |
32 | |
33 | //======================================================================= |
34 | //function : ShapeAnalysis_WireOrder |
35 | //purpose : |
36 | //======================================================================= |
37 | |
38 | ShapeAnalysis_WireOrder::ShapeAnalysis_WireOrder() |
39 | : myKeepLoops(Standard_False) , myGap (0.) , myStat (0) , myMode (Standard_True) |
40 | { |
41 | myTol = Precision::Confusion(); |
42 | Clear(); |
43 | } |
44 | |
45 | //======================================================================= |
46 | //function : ShapeAnalysis_WireOrder |
47 | //purpose : |
48 | //======================================================================= |
49 | |
50 | ShapeAnalysis_WireOrder::ShapeAnalysis_WireOrder(const Standard_Boolean mode3d, |
51 | const Standard_Real tol) |
52 | : myKeepLoops(Standard_False), myTol (tol), myGap (0.), myStat (0), myMode (mode3d) |
53 | { |
54 | Clear(); |
55 | } |
56 | |
57 | //======================================================================= |
58 | //function : SetMode |
59 | //purpose : |
60 | //======================================================================= |
61 | |
62 | void ShapeAnalysis_WireOrder::SetMode(const Standard_Boolean mode3d,const Standard_Real tol) |
63 | { |
64 | if (mode3d != myMode) Clear(); |
65 | myOrd.Nullify(); myStat = 0; myGap = 0.; |
66 | myMode = mode3d; |
67 | myTol = (tol > 0.)? tol : 1.e-08; //szv#4:S4163:12Mar99 optimized |
68 | } |
69 | |
70 | //======================================================================= |
71 | //function : Tolerance |
72 | //purpose : |
73 | //======================================================================= |
74 | |
75 | Standard_Real ShapeAnalysis_WireOrder::Tolerance() const |
76 | { |
77 | return myTol; |
78 | } |
79 | |
80 | //======================================================================= |
81 | //function : Clear |
82 | //purpose : |
83 | //======================================================================= |
84 | |
85 | void ShapeAnalysis_WireOrder::Clear() |
86 | { |
87 | myXYZ = new TColgp_HSequenceOfXYZ(); |
88 | myStat = 0; |
89 | myGap = 0.; |
90 | } |
91 | |
92 | //======================================================================= |
93 | //function : Add |
94 | //purpose : |
95 | //======================================================================= |
96 | |
97 | void ShapeAnalysis_WireOrder::Add(const gp_XYZ& start3d,const gp_XYZ& end3d) |
98 | { |
99 | //szv#4:S4163:12Mar99 waste raise |
100 | //if (!myMode) |
101 | //Standard_TypeMismatch::Raise("ShapeAnalysis_WireOrder : AddXYZ"); |
102 | if (myMode) { |
103 | myXYZ->Append (start3d); myXYZ->Append (end3d); |
104 | } |
105 | } |
106 | |
107 | //======================================================================= |
108 | //function : Add |
109 | //purpose : |
110 | //======================================================================= |
111 | |
112 | void ShapeAnalysis_WireOrder::Add(const gp_XY& start2d,const gp_XY& end2d) |
113 | { |
114 | //szv#4:S4163:12Mar99 waste raise |
115 | //if ( myMode) |
116 | //Standard_TypeMismatch::Raise("ShapeAnalysis_WireOrder : AddXY"); |
117 | if (!myMode) { |
118 | gp_XYZ val; |
119 | val.SetCoord (start2d.X(),start2d.Y(),0.); |
120 | myXYZ->Append (val); |
121 | val.SetCoord (end2d.X(),end2d.Y(),0.); |
122 | myXYZ->Append (val); |
123 | } |
124 | } |
125 | |
126 | //======================================================================= |
127 | //function : NbEdges |
128 | //purpose : |
129 | //======================================================================= |
130 | |
131 | Standard_Integer ShapeAnalysis_WireOrder::NbEdges() const |
132 | { |
133 | return myXYZ->Length() / 2; |
134 | } |
135 | |
136 | |
137 | static Standard_Real DISTABS (const gp_XYZ& v1, const gp_XYZ& v2) |
138 | { |
139 | return Abs (v1.X() - v2.X()) + Abs (v1.Y() - v2.Y()) + Abs (v1.Z() - v2.Z()); |
140 | } |
141 | |
142 | // La routine qui suit gere les boucles internes a un wire. Questce a dire ? |
143 | // Un wire normalement chaine (meme pas dans l ordre et avec des inverses) |
144 | // balaie toutes ses edges au moins une fois dans une seule liste |
145 | // En 3D il peut y avoir des COUTURES ... une, mais evt plusieurs ... |
146 | // En ce cas le critere fin-debut peut definir des sous-parties fermees du |
147 | // wire, ce sont les boucles en question |
148 | // Exemple (cylindre gentil) : la couture (balayee deux fois) : 1 boucle |
149 | // chaque limite (haute et basse) definit aussi une boucle (1 edge ou +) |
150 | |
151 | // En cours de chainage, il faut donc : |
152 | // 1/ sauter la boucle, pour ne pas la rebalayer 36 fois : NextFree y pourvoit |
153 | // en notant les tetes de boucles, on n a pas le droit de les revoir |
154 | // NB: ca marche car en cours de constitution de liste, on s interdit de |
155 | // repasser plus d une fois sur chaque edge (test fol-pre non nul) |
156 | // 2/ reprendre les boucles pour les fusionner : pas encore fait |
157 | // (pour l instant, on imprime un petit message, c est tout) |
158 | |
7fd59977 |
159 | //======================================================================= |
160 | //function : KeepLoopsMode |
161 | //purpose : |
162 | //======================================================================= |
163 | |
164 | Standard_Boolean& ShapeAnalysis_WireOrder::KeepLoopsMode() |
165 | { |
166 | return myKeepLoops; |
167 | } |
168 | |
169 | //======================================================================= |
170 | //function : Perform |
171 | //purpose : |
172 | //======================================================================= |
173 | |
174 | static Standard_Boolean IsBetter(const Standard_Integer first, |
175 | const Standard_Integer second) |
176 | { |
177 | //rln 23.03.99 bm4_al_eye.stp, entity 5281 |
178 | //Order in the file is better even if another order has the same distance |
179 | //Lexicograhical order of preference: 0 > 2 > 1 > 3 |
180 | if (first == 0 && second > 0 ) return Standard_True; |
181 | if (first == 2 && (second == 1 || second == 3)) return Standard_True; |
182 | if (first == 1 && second == 3 ) return Standard_True; |
183 | return Standard_False; |
184 | } |
185 | |
186 | void ShapeAnalysis_WireOrder::Perform(const Standard_Boolean /*closed*/) |
187 | { |
3e9b53cb |
188 | myStat = 0; |
189 | Standard_Integer i, nb = NbEdges(); |
190 | if(nb == 0) |
191 | return; // no edges loaded, nothing to do -- return with status OK |
192 | myOrd = new TColStd_HArray1OfInteger(1,nb); |
193 | myOrd->Init(0); |
7fd59977 |
194 | |
195 | Handle(TColStd_HSequenceOfInteger) seq = new TColStd_HSequenceOfInteger; |
196 | TColStd_SequenceOfTransient loops; |
197 | |
198 | TColgp_Array1OfXYZ debs(0,nb); |
199 | TColgp_Array1OfXYZ fins(0,nb); |
200 | |
201 | TColStd_Array1OfBoolean idone (1, nb); |
202 | idone.Init (Standard_False); |
203 | |
204 | // Calcul des precedents-suivants |
205 | for (i = 1; i <= nb; i ++) { |
206 | debs(i) = myXYZ->Value(2*i-1); |
207 | fins(i) = myXYZ->Value(2*i); |
208 | } |
209 | |
08cd2f6b |
210 | Standard_Real tol2 = Precision::SquareConfusion(); |
7fd59977 |
211 | idone(1) = Standard_True; |
212 | gp_Pnt wireFirst = debs(1); |
213 | gp_Pnt wireLast = fins(1); |
214 | seq->Append(1); |
215 | Standard_Boolean done = Standard_False; |
216 | |
217 | //pdn 11.03.99 S4135 constructing closed loops of edges |
218 | while(!done) { |
219 | Standard_Integer resultType = 3; |
220 | Standard_Real distmin = RealLast(); |
1d47d8d0 |
221 | Standard_Integer ledge = 0; |
7fd59977 |
222 | Standard_Boolean found = Standard_False; |
223 | Standard_Real closeDist = wireFirst.SquareDistance(wireLast); |
224 | |
225 | for(Standard_Integer iedge = 1; (iedge <= nb) && (distmin||resultType||(resultType!=2)); iedge++) |
226 | if(!idone(iedge)) { |
227 | Standard_Real tailhead = wireLast.SquareDistance(debs(iedge)); |
228 | Standard_Real tailtail = wireLast.SquareDistance(fins(iedge)); |
229 | Standard_Real headtail = wireFirst.SquareDistance(fins(iedge)); |
230 | Standard_Real headhead = wireFirst.SquareDistance(debs(iedge)); |
231 | Standard_Real dm1 = tailhead, dm2 = headtail; |
232 | Standard_Integer res1 = 0, res2 = 2; |
233 | |
234 | if (tailhead > tailtail) {res1 = 1; dm1 = tailtail;} |
235 | if (headtail > headhead) {res2 = 3; dm2 = headhead;} |
236 | Standard_Integer result =0; |
237 | Standard_Real myMin3d = Min (dm1, dm2); |
238 | if(fabs(dm1 - dm2) < tol2 ) { |
239 | Standard_Boolean isB = IsBetter(res1,res2); |
240 | result = (isB ? res1 : res2); |
241 | } |
242 | else |
243 | result = ((dm1 > dm2) ? res2 : res1); // 0 > 2 > 1 > 3 |
244 | |
245 | if (distmin > tol2 || IsBetter(result,resultType)) |
246 | if (myMin3d < distmin || ((myMin3d == distmin || myMin3d < tol2) && IsBetter(result,resultType))) { |
247 | found = Standard_True; |
248 | distmin = myMin3d; |
249 | ledge = iedge; |
250 | resultType = result; |
251 | } |
252 | } |
253 | if(found) { |
254 | if (distmin == 0 || distmin < closeDist) { |
255 | switch(resultType){ |
256 | case 0: seq->Append(ledge); wireLast = fins(ledge); break; |
257 | case 1: seq->Append(-ledge); wireLast = debs(ledge); break; |
258 | case 2: seq->Prepend(ledge); wireFirst = debs(ledge); break; |
259 | case 3: seq->Prepend(-ledge); wireFirst = fins(ledge); break; |
260 | } |
261 | } else { |
262 | //pdn 11.03.99 S4135 closing loop and creating new one |
263 | loops.Append(seq); |
264 | seq = new TColStd_HSequenceOfInteger; |
265 | wireFirst = debs(ledge); |
266 | wireLast = fins(ledge); |
267 | seq->Append(ledge); |
268 | } |
269 | idone(ledge) = Standard_True; |
270 | } else { |
271 | ledge = -1; |
272 | for (i = 1 ; i <= nb && ledge == -1; i++) |
273 | ledge = idone(i) ? ledge : i; |
274 | if (ledge == -1) |
275 | done = 1; |
276 | else { |
277 | wireFirst = debs(ledge); |
278 | wireLast = fins(ledge); |
279 | seq->Append(ledge); |
280 | idone(ledge) = Standard_True; |
281 | } |
282 | } |
283 | } |
284 | loops.Append(seq); |
285 | |
286 | Handle(TColStd_HSequenceOfInteger) mainSeq; |
287 | if (myKeepLoops) { |
288 | |
289 | //pdn Keeping the loops, adding one after another. |
290 | mainSeq = new TColStd_HSequenceOfInteger; |
291 | for (Standard_Integer ii = 1; ii <= loops.Length(); ii++) { |
292 | Handle(TColStd_HSequenceOfInteger) subLoop = |
293 | Handle(TColStd_HSequenceOfInteger)::DownCast(loops(ii)); |
294 | for (Standard_Integer j = 1; j<= subLoop->Length(); j++) |
295 | mainSeq->Append(subLoop->Value(j)); |
296 | } |
297 | } |
298 | else { |
299 | //pdn 11.03.99 S4135 connecting loops. |
300 | mainSeq = Handle(TColStd_HSequenceOfInteger)::DownCast(loops.First()); |
301 | loops.Remove(1); |
302 | while(loops.Length()) { |
303 | Standard_Real minLoopDist = RealLast(); |
304 | Standard_Integer loopNum=0; |
305 | Standard_Integer loopShift=0; |
306 | Standard_Boolean loopDirect=0; |
307 | Standard_Integer numInLoop=0; |
308 | for(i = 1; i <= loops.Length(); i++) { |
309 | Handle(TColStd_HSequenceOfInteger) loop = Handle(TColStd_HSequenceOfInteger)::DownCast(loops.Value(i)); |
310 | Standard_Integer num = loop->Length(); |
311 | Standard_Integer LocShift=0; |
312 | Standard_Integer LocNumInLoop=0; |
313 | Standard_Boolean LocDirect = Standard_False; |
314 | Standard_Real minLocDist = RealLast(); |
315 | for(Standard_Integer ibegin = 1; ibegin <= loop->Length(); ibegin++) { |
316 | Standard_Integer iend = (ibegin==1 ? num : ibegin -1); |
317 | gp_Pnt loopFirst = (loop->Value(ibegin) > 0 ? debs(loop->Value(ibegin)) : fins(-loop->Value(ibegin))); |
318 | gp_Pnt loopLast = (loop->Value(iend) > 0 ? fins(loop->Value(iend)) : debs(-loop->Value(iend))); |
319 | Standard_Real distmin = RealLast(); |
320 | Standard_Integer lloop=0; |
321 | Standard_Boolean direct = Standard_False; |
322 | for(Standard_Integer j = 1; (j <= mainSeq->Length())&& distmin; j++) { |
323 | Standard_Integer k = (j == mainSeq->Length()? 1 : j+1); |
324 | gp_Pnt first = (mainSeq->Value(j) > 0 ? fins(mainSeq->Value(j)) : debs(-mainSeq->Value(j))); |
325 | gp_Pnt last = (mainSeq->Value(k) > 0 ? debs(mainSeq->Value(k)) : fins(-mainSeq->Value(k))); |
326 | Standard_Real dirDist = loopFirst.SquareDistance(first)+loopLast.SquareDistance(last); |
327 | Standard_Real revDist = loopFirst.SquareDistance(last)+loopLast.SquareDistance(first); |
328 | Standard_Real minDist; |
329 | if((dirDist<tol2)||(dirDist < 2.*revDist)) { |
330 | minDist = dirDist; |
331 | revDist = dirDist; |
332 | } |
333 | else |
334 | minDist = revDist; |
fdabc211 |
335 | if(minDist < distmin && Abs(distmin - minDist) > tol2) { |
7fd59977 |
336 | distmin = minDist; |
337 | direct = (dirDist <= revDist); |
338 | lloop = j; |
339 | } |
340 | } |
fdabc211 |
341 | if(distmin < minLocDist && Abs(minLocDist - distmin) > tol2) { |
7fd59977 |
342 | minLocDist = distmin; |
343 | LocDirect = direct; |
344 | LocNumInLoop = lloop; |
345 | LocShift = ibegin; |
346 | } |
347 | |
348 | } |
fdabc211 |
349 | if(minLocDist < minLoopDist && Abs(minLoopDist - minLocDist) > tol2) { |
7fd59977 |
350 | minLoopDist = minLocDist; |
351 | loopNum = i; |
352 | loopDirect = LocDirect; |
353 | numInLoop = LocNumInLoop; |
354 | loopShift = LocShift; |
355 | } |
356 | } |
357 | |
358 | Handle(TColStd_HSequenceOfInteger) loop = Handle(TColStd_HSequenceOfInteger)::DownCast(loops.Value(loopNum)); |
359 | Standard_Integer factor = (loopDirect ? 1: -1); |
360 | // skl : in the next block for{} I change "i" to "ii" |
361 | for(Standard_Integer ii = 1; ii <= loop->Length(); ii++) { |
362 | Standard_Integer num = (ii+loopShift-1>loop->Length() ? ii+loopShift-1-loop->Length() : ii+loopShift-1); |
363 | mainSeq->InsertAfter(numInLoop+ii-1,loop->Value(num)*factor); |
364 | } |
365 | loops.Remove(loopNum); |
366 | } |
367 | } |
368 | |
369 | Standard_Integer stTmp=0; |
370 | for(i = 1; i <= mainSeq->Length(); i++) { |
371 | if(i!=mainSeq->Value(i)) |
372 | if(stTmp>=0) stTmp = (mainSeq->Value(i) > 0 ? 1 : -1); |
373 | myOrd->SetValue(i,mainSeq->Value(i)); |
374 | } |
673693f1 |
375 | if (stTmp == 0) { |
376 | myStat = stTmp; |
377 | return; |
378 | } |
379 | else {//check if edges were only shifted in reverse or forward, not reordered |
380 | Standard_Boolean isShiftReverse = Standard_True, isShiftForward = Standard_True; |
381 | Standard_Integer tmpFirst = 0, tmpSecond = 0, length = mainSeq->Length(); |
382 | for(i = 1; i <= length - 1; i++) { |
383 | tmpFirst = mainSeq->Value(i); |
384 | tmpSecond = mainSeq->Value(i+1); |
385 | if (!(tmpSecond - tmpFirst == 1 || (tmpFirst == length && tmpSecond == 1))) |
386 | isShiftForward = Standard_False; |
387 | if (!(tmpFirst - tmpSecond == 1 || (tmpSecond == length && tmpFirst == 1))) |
388 | isShiftReverse = Standard_False; |
389 | } |
390 | tmpFirst = mainSeq->Value(length); |
391 | tmpSecond = mainSeq->Value(1); |
392 | if (!(tmpSecond - tmpFirst == 1 || (tmpFirst == length && tmpSecond == 1))) |
393 | isShiftForward = Standard_False; |
394 | if (!(tmpFirst - tmpSecond == 1 || (tmpSecond == length && tmpFirst == 1))) |
395 | isShiftReverse = Standard_False; |
396 | if (isShiftForward || isShiftReverse) |
397 | stTmp = 3; |
398 | myStat = stTmp; |
399 | return; |
400 | } |
7fd59977 |
401 | } |
402 | |
403 | //======================================================================= |
404 | //function : IsDone |
405 | //purpose : |
406 | //======================================================================= |
407 | |
408 | Standard_Boolean ShapeAnalysis_WireOrder::IsDone() const |
409 | { |
410 | return !myOrd.IsNull(); |
411 | } |
412 | |
413 | //======================================================================= |
414 | //function : Status |
415 | //purpose : |
416 | //======================================================================= |
417 | |
418 | Standard_Integer ShapeAnalysis_WireOrder::Status() const |
419 | { |
420 | return myStat; |
421 | } |
422 | |
423 | //======================================================================= |
424 | //function : Ordered |
425 | //purpose : |
426 | //======================================================================= |
427 | |
428 | Standard_Integer ShapeAnalysis_WireOrder::Ordered(const Standard_Integer n) const |
429 | { |
430 | if (myOrd.IsNull() || myOrd->Upper() < n) return n; |
431 | Standard_Integer ord = myOrd->Value(n); |
432 | return (ord == 0 ? n : ord); |
433 | } |
434 | |
435 | //======================================================================= |
436 | //function : XYZ |
437 | //purpose : |
438 | //======================================================================= |
439 | |
440 | void ShapeAnalysis_WireOrder::XYZ(const Standard_Integer num,gp_XYZ& start3d,gp_XYZ& end3d) const |
441 | { |
442 | if (num > 0) { |
443 | start3d = myXYZ->Value (2*num-1); |
444 | end3d = myXYZ->Value (2*num); |
445 | } else { |
446 | start3d = myXYZ->Value (-2*num); |
447 | end3d = myXYZ->Value (-2*num-1); |
448 | } |
449 | } |
450 | |
451 | //======================================================================= |
452 | //function : XY |
453 | //purpose : |
454 | //======================================================================= |
455 | |
456 | void ShapeAnalysis_WireOrder::XY(const Standard_Integer num,gp_XY& start2d,gp_XY& end2d) const |
457 | { |
458 | const gp_XYZ& st2d = myXYZ->Value ( (num > 0 ? 2*num-1 : -2*num) ); |
459 | start2d.SetCoord (st2d.X(),st2d.Y()); |
460 | const gp_XYZ& en2d = myXYZ->Value ( (num > 0 ? 2*num : -2*num -1) ); |
461 | end2d.SetCoord (en2d.X(),en2d.Y()); |
462 | } |
463 | |
464 | //======================================================================= |
465 | //function : Gap |
466 | //purpose : |
467 | //======================================================================= |
468 | |
469 | Standard_Real ShapeAnalysis_WireOrder::Gap(const Standard_Integer num) const |
470 | { |
471 | if (num == 0) return myGap; |
472 | Standard_Integer n1 = Ordered (num); |
473 | Standard_Integer n0 = Ordered (num == 1 ? NbEdges() : num-1); |
474 | // Distance entre fin (n0) et debut (n1) |
475 | return DISTABS (myXYZ->Value( (n0 > 0 ? 2*n0 : -2*n0 -1) ) , |
476 | myXYZ->Value( (n1 > 0 ? 2*n1-1 : -2*n1 ) ) ); |
477 | //// return (myXYZ->Value(2*n0)).Distance (myXYZ->Value(2*n1-1)); |
478 | } |
479 | |
480 | //======================================================================= |
481 | //function : SetChains |
482 | //purpose : |
483 | //======================================================================= |
484 | |
485 | void ShapeAnalysis_WireOrder::SetChains(const Standard_Real gap) |
486 | { |
487 | Standard_Integer n0 = 0, n1, n2, nb = NbEdges(); //szv#4:S4163:12Mar99 o0,o1,o2 not needed |
488 | if (nb == 0) return; |
489 | TColStd_SequenceOfInteger chain; |
490 | n0 = 0; |
491 | chain.Append (1); // On demarre la partie |
492 | gp_XYZ f3d, l3d, f13d, l13d; //szv#4:S4163:12Mar99 f03d,l03d unused |
493 | for (n1 = 1; n1 <= nb; n1 ++) { |
494 | if (n0 == 0) { // nouvelle boucle |
495 | n0 = n1; |
496 | //szv#4:S4163:12Mar99 optimized |
497 | XYZ ( Ordered(n0), f13d, l13d ); |
498 | } |
499 | //szv#4:S4163:12Mar99 optimized |
500 | n2 = (n1 == nb)? n0 : (n1 + 1); |
501 | XYZ ( Ordered(n2), f3d, l3d ); |
502 | if (!f3d.IsEqual (l13d,gap)) { chain.Append (n2); n0 = 0; } |
503 | f13d = f3d; l13d = l3d; |
504 | } |
505 | nb = chain.Length(); |
506 | if (nb == 0) return; |
507 | myChains = new TColStd_HArray1OfInteger (1,nb); |
508 | for (n1 = 1; n1 <= nb; n1 ++) myChains->SetValue (n1,chain.Value(n1)); |
509 | } |
510 | |
511 | //======================================================================= |
512 | //function : NbChains |
513 | //purpose : |
514 | //======================================================================= |
515 | |
516 | Standard_Integer ShapeAnalysis_WireOrder::NbChains() const |
517 | { |
518 | return (myChains.IsNull() ? 0 : myChains->Length()); |
519 | } |
520 | |
521 | //======================================================================= |
522 | //function : Chain |
523 | //purpose : |
524 | //======================================================================= |
525 | |
526 | void ShapeAnalysis_WireOrder::Chain(const Standard_Integer num,Standard_Integer& n1,Standard_Integer& n2) const |
527 | { |
528 | n1 = n2 = 0; |
529 | if (myChains.IsNull()) return; |
530 | Standard_Integer nb = myChains->Upper(); |
531 | if (num == 0 || num > nb) return; |
532 | n1 = myChains->Value (num); |
533 | if (num == nb) n2 = NbEdges(); |
534 | else n2 = myChains->Value (num+1) - 1; |
535 | } |
536 | |
537 | //======================================================================= |
538 | //function : SetCouples |
539 | //purpose : |
540 | //======================================================================= |
541 | |
542 | void ShapeAnalysis_WireOrder::SetCouples(const Standard_Real /*gap*/) |
543 | { |
aefdc31b |
544 | #ifdef SHAPEANALYSIS_DEB |
7fd59977 |
545 | cout<<"ShapeAnalysis_WireOrder:SetCouple not yet implemented"<<endl; |
aefdc31b |
546 | #endif |
7fd59977 |
547 | } |
548 | |
549 | //======================================================================= |
550 | //function : NbCouples |
551 | //purpose : |
552 | //======================================================================= |
553 | |
554 | Standard_Integer ShapeAnalysis_WireOrder::NbCouples() const |
555 | { |
556 | return (myCouples.IsNull() ? 0 : myCouples->Length()); |
557 | } |
558 | |
559 | //======================================================================= |
560 | //function : Couple |
561 | //purpose : |
562 | //======================================================================= |
563 | |
564 | void ShapeAnalysis_WireOrder::Couple(const Standard_Integer num,Standard_Integer& n1,Standard_Integer& n2) const |
565 | { |
566 | n1 = n2 = 0; |
567 | if (myCouples.IsNull()) return; |
568 | Standard_Integer nb = myCouples->Upper(); |
569 | if (num == 0 || num*2 > nb) return; |
570 | n1 = myCouples->Value (2*num-1); |
571 | n2 = myCouples->Value (2*num); |
572 | } |
573 | |