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