7fd59977 |
1 | // File: Geom2d_BSplineCurve_1.cxx |
2 | // Created: Wed Mar 31 18:11:15 1993 |
3 | // Author: JCV |
4 | // <fid@sdsun2> |
5 | // Copyright: Matra Datavision 1993 |
6 | |
7 | // File: Geom2d_BSplineCurve_1.cxx |
8 | // Created: Fri Jul 5 16:37:59 1991 |
9 | // Author: JCV |
10 | // 03-02-97 : pmn ->LocateU sur Periodic (PRO6963), |
11 | // bon appel a LocateParameter (PRO6973) et mise en conformite avec |
12 | // le cdl de LocateU, lorsque U est un noeud (PRO6988) |
13 | |
14 | #define No_Standard_OutOfRange |
15 | #define No_Standard_DimensionError |
16 | |
17 | #include <Geom2d_BSplineCurve.jxx> |
18 | #include <BSplCLib.hxx> |
19 | #include <gp.hxx> |
20 | |
21 | #include <Geom2d_UndefinedDerivative.hxx> |
22 | #include <Standard_DimensionError.hxx> |
23 | #include <Standard_OutOfRange.hxx> |
24 | #include <Standard_DomainError.hxx> |
25 | #include <Standard_RangeError.hxx> |
26 | |
27 | #define POLES (poles->Array1()) |
28 | #define KNOTS (knots->Array1()) |
29 | #define FKNOTS (flatknots->Array1()) |
30 | #define FMULTS (BSplCLib::NoMults()) |
31 | |
32 | //======================================================================= |
33 | //function : IsCN |
34 | //purpose : |
35 | //======================================================================= |
36 | |
37 | Standard_Boolean Geom2d_BSplineCurve::IsCN ( const Standard_Integer N) const |
38 | { |
39 | Standard_RangeError_Raise_if |
40 | (N < 0, "Geom2d_BSplineCurve::IsCN"); |
41 | |
42 | switch (smooth) { |
43 | case GeomAbs_CN : return Standard_True; |
44 | case GeomAbs_C0 : return N <= 0; |
45 | case GeomAbs_G1 : return N <= 0; |
46 | case GeomAbs_C1 : return N <= 1; |
47 | case GeomAbs_G2 : return N <= 1; |
48 | case GeomAbs_C2 : return N <= 2; |
49 | case GeomAbs_C3 : |
50 | return N <= 3 ? Standard_True : |
51 | N <= deg - BSplCLib::MaxKnotMult (mults->Array1(), mults->Lower() + 1, mults->Upper() - 1); |
52 | default: |
53 | return Standard_False; |
54 | } |
55 | } |
56 | |
57 | //======================================================================= |
58 | //function : IsClosed |
59 | //purpose : |
60 | //======================================================================= |
61 | |
62 | Standard_Boolean Geom2d_BSplineCurve::IsClosed () const |
63 | { return (StartPoint().Distance (EndPoint())) <= gp::Resolution (); } |
64 | |
65 | |
66 | |
67 | //======================================================================= |
68 | //function : IsPeriodic |
69 | //purpose : |
70 | //======================================================================= |
71 | |
72 | Standard_Boolean Geom2d_BSplineCurve::IsPeriodic () const |
73 | { return periodic; } |
74 | |
75 | //======================================================================= |
76 | //function : Continuity |
77 | //purpose : |
78 | //======================================================================= |
79 | |
80 | GeomAbs_Shape Geom2d_BSplineCurve::Continuity () const |
81 | { return smooth; } |
82 | |
83 | //======================================================================= |
84 | //function : Degree |
85 | //purpose : |
86 | //======================================================================= |
87 | |
88 | Standard_Integer Geom2d_BSplineCurve::Degree () const |
89 | { return deg; } |
90 | |
91 | |
92 | //======================================================================= |
93 | //function : D0 |
94 | //purpose : |
95 | //======================================================================= |
96 | |
97 | void Geom2d_BSplineCurve::D0 ( const Standard_Real U, |
98 | gp_Pnt2d& P) const |
99 | { |
100 | Standard_Real NewU = U ; |
101 | PeriodicNormalization(NewU) ; |
102 | if (!IsCacheValid(NewU)) { |
103 | Geom2d_BSplineCurve * MyCurve = (Geom2d_BSplineCurve *) this ; |
104 | MyCurve->ValidateCache(NewU) ; |
105 | } |
106 | |
107 | if ( rational ) { |
108 | BSplCLib::CacheD0(NewU, |
109 | deg, |
110 | parametercache, |
111 | spanlenghtcache, |
112 | (cachepoles->Array1()), |
113 | cacheweights->Array1(), |
114 | P) ; |
115 | } |
116 | else { |
117 | BSplCLib::CacheD0(NewU, |
118 | deg, |
119 | parametercache, |
120 | spanlenghtcache, |
121 | (cachepoles->Array1()), |
122 | BSplCLib::NoWeights(), |
123 | P) ; |
124 | } |
125 | } |
126 | |
127 | |
128 | //======================================================================= |
129 | //function : D1 |
130 | //purpose : |
131 | //======================================================================= |
132 | |
133 | void Geom2d_BSplineCurve::D1 (const Standard_Real U, |
134 | gp_Pnt2d& P, |
135 | gp_Vec2d& V1) const |
136 | { |
137 | Standard_Real NewU = U ; |
138 | PeriodicNormalization(NewU) ; |
139 | if (!IsCacheValid(NewU)) { |
140 | Geom2d_BSplineCurve * MyCurve = (Geom2d_BSplineCurve *) this ; |
141 | MyCurve->ValidateCache(NewU) ; |
142 | } |
143 | |
144 | if ( rational ) { |
145 | BSplCLib::CacheD1(NewU, |
146 | deg, |
147 | parametercache, |
148 | spanlenghtcache, |
149 | (cachepoles->Array1()), |
150 | cacheweights->Array1(), |
151 | P, |
152 | V1) ; |
153 | } |
154 | else { |
155 | BSplCLib::CacheD1(NewU, |
156 | deg, |
157 | parametercache, |
158 | spanlenghtcache, |
159 | (cachepoles->Array1()), |
160 | BSplCLib::NoWeights(), |
161 | P, |
162 | V1) ; |
163 | } |
164 | } |
165 | |
166 | //======================================================================= |
167 | //function : D2 |
168 | //purpose : |
169 | //======================================================================= |
170 | |
171 | void Geom2d_BSplineCurve::D2 (const Standard_Real U , |
172 | gp_Pnt2d& P , |
173 | gp_Vec2d& V1, |
174 | gp_Vec2d& V2 ) const |
175 | { |
176 | Standard_Real NewU = U ; |
177 | PeriodicNormalization(NewU) ; |
178 | if (!IsCacheValid(NewU)) { |
179 | Geom2d_BSplineCurve * MyCurve = (Geom2d_BSplineCurve *) this ; |
180 | MyCurve->ValidateCache(NewU) ; |
181 | } |
182 | |
183 | if ( rational ) { |
184 | BSplCLib::CacheD2(NewU, |
185 | deg, |
186 | parametercache, |
187 | spanlenghtcache, |
188 | (cachepoles->Array1()), |
189 | cacheweights->Array1(), |
190 | P, |
191 | V1, |
192 | V2) ; |
193 | } |
194 | else { |
195 | BSplCLib::CacheD2(NewU, |
196 | deg, |
197 | parametercache, |
198 | spanlenghtcache, |
199 | (cachepoles->Array1()), |
200 | BSplCLib::NoWeights(), |
201 | P, |
202 | V1, |
203 | V2) ; |
204 | } |
205 | } |
206 | |
207 | //======================================================================= |
208 | //function : D3 |
209 | //purpose : |
210 | //======================================================================= |
211 | |
212 | void Geom2d_BSplineCurve::D3 (const Standard_Real U , |
213 | gp_Pnt2d& P , |
214 | gp_Vec2d& V1, |
215 | gp_Vec2d& V2, |
216 | gp_Vec2d& V3 ) const |
217 | { |
218 | Standard_Real NewU = U ; |
219 | PeriodicNormalization(NewU) ; |
220 | if (!IsCacheValid(NewU)) { |
221 | Geom2d_BSplineCurve * MyCurve = (Geom2d_BSplineCurve *) this ; |
222 | MyCurve->ValidateCache(NewU) ; |
223 | } |
224 | |
225 | if ( rational ) { |
226 | BSplCLib::CacheD3(NewU, |
227 | deg, |
228 | parametercache, |
229 | spanlenghtcache, |
230 | (cachepoles->Array1()), |
231 | cacheweights->Array1(), |
232 | P, |
233 | V1, |
234 | V2, |
235 | V3) ; |
236 | } |
237 | else { |
238 | BSplCLib::CacheD3(NewU, |
239 | deg, |
240 | parametercache, |
241 | spanlenghtcache, |
242 | (cachepoles->Array1()), |
243 | BSplCLib::NoWeights(), |
244 | P, |
245 | V1, |
246 | V2, |
247 | V3) ; |
248 | } |
249 | } |
250 | |
251 | //======================================================================= |
252 | //function : DN |
253 | //purpose : |
254 | //======================================================================= |
255 | |
256 | gp_Vec2d Geom2d_BSplineCurve::DN (const Standard_Real U, |
257 | const Standard_Integer N ) const |
258 | { |
259 | gp_Vec2d V; |
260 | |
261 | if ( rational ) { |
262 | BSplCLib::DN(U,N,0,deg,periodic,POLES, |
263 | weights->Array1(), |
264 | FKNOTS,FMULTS,V); |
265 | } |
266 | else { |
267 | BSplCLib::DN(U,N,0,deg,periodic,POLES, |
268 | *((TColStd_Array1OfReal*) NULL), |
269 | FKNOTS,FMULTS,V); |
270 | } |
271 | return V; |
272 | } |
273 | |
274 | //======================================================================= |
275 | //function : EndPoint |
276 | //purpose : |
277 | //======================================================================= |
278 | |
279 | gp_Pnt2d Geom2d_BSplineCurve::EndPoint () const |
280 | { |
281 | if (mults->Value (knots->Upper ()) == deg + 1) |
282 | return poles->Value (poles->Upper()); |
283 | else |
284 | return Value(LastParameter()); |
285 | } |
286 | |
287 | //======================================================================= |
288 | //function : FirstUKnotIndex |
289 | //purpose : |
290 | //======================================================================= |
291 | |
292 | Standard_Integer Geom2d_BSplineCurve::FirstUKnotIndex () const |
293 | { |
294 | if (periodic) return 1; |
295 | else return BSplCLib::FirstUKnotIndex (deg, mults->Array1()); |
296 | } |
297 | |
298 | //======================================================================= |
299 | //function : FirstParameter |
300 | //purpose : |
301 | //======================================================================= |
302 | |
303 | Standard_Real Geom2d_BSplineCurve::FirstParameter () const |
304 | { |
305 | return flatknots->Value (deg+1); |
306 | } |
307 | |
308 | //======================================================================= |
309 | //function : Knot |
310 | //purpose : |
311 | //======================================================================= |
312 | |
313 | Standard_Real Geom2d_BSplineCurve::Knot (const Standard_Integer Index) const |
314 | { |
315 | Standard_OutOfRange_Raise_if |
316 | (Index < 1 || Index > knots->Length(), "Geom2d_BSplineCurve::Knot"); |
317 | return knots->Value (Index); |
318 | } |
319 | |
320 | //======================================================================= |
321 | //function : KnotDistribution |
322 | //purpose : |
323 | //======================================================================= |
324 | |
325 | GeomAbs_BSplKnotDistribution Geom2d_BSplineCurve::KnotDistribution () const |
326 | { |
327 | return knotSet; |
328 | } |
329 | |
330 | //======================================================================= |
331 | //function : Knots |
332 | //purpose : |
333 | //======================================================================= |
334 | |
335 | void Geom2d_BSplineCurve::Knots (TColStd_Array1OfReal& K) const |
336 | { |
337 | Standard_DimensionError_Raise_if |
338 | (K.Length() != knots->Length(), "Geom2d_BSplineCurve::Knots"); |
339 | K = knots->Array1(); |
340 | } |
341 | |
342 | //======================================================================= |
343 | //function : KnotSequence |
344 | //purpose : |
345 | //======================================================================= |
346 | |
347 | void Geom2d_BSplineCurve::KnotSequence (TColStd_Array1OfReal& K) const |
348 | { |
349 | Standard_DimensionError_Raise_if |
350 | (K.Length() != flatknots->Length(), "Geom2d_BSplineCurve::KnotSequence"); |
351 | K = flatknots->Array1(); |
352 | } |
353 | |
354 | //======================================================================= |
355 | //function : LastUKnotIndex |
356 | //purpose : |
357 | //======================================================================= |
358 | |
359 | Standard_Integer Geom2d_BSplineCurve::LastUKnotIndex() const |
360 | { |
361 | if (periodic) return knots->Length(); |
362 | else return BSplCLib::LastUKnotIndex (deg, mults->Array1()); |
363 | } |
364 | |
365 | //======================================================================= |
366 | //function : LastParameter |
367 | //purpose : |
368 | //======================================================================= |
369 | |
370 | Standard_Real Geom2d_BSplineCurve::LastParameter () const |
371 | { |
372 | return flatknots->Value (flatknots->Upper()-deg); |
373 | } |
374 | |
375 | //======================================================================= |
376 | //function : LocalValue |
377 | //purpose : |
378 | //======================================================================= |
379 | |
380 | gp_Pnt2d Geom2d_BSplineCurve::LocalValue |
381 | (const Standard_Real U, |
382 | const Standard_Integer FromK1, |
383 | const Standard_Integer ToK2) const |
384 | { |
385 | gp_Pnt2d P; |
386 | LocalD0(U,FromK1,ToK2,P); |
387 | return P; |
388 | } |
389 | |
390 | //======================================================================= |
391 | //function : LocalD0 |
392 | //purpose : |
393 | //======================================================================= |
394 | |
395 | void Geom2d_BSplineCurve::LocalD0 |
396 | (const Standard_Real U, |
397 | const Standard_Integer FromK1, |
398 | const Standard_Integer ToK2, |
399 | gp_Pnt2d& P) const |
400 | { |
401 | Standard_DomainError_Raise_if (FromK1 == ToK2, |
402 | "Geom2d_BSplineCurve::LocalValue"); |
403 | |
404 | Standard_Real u = U; |
405 | Standard_Integer index = 0; |
406 | BSplCLib::LocateParameter(deg, FKNOTS, U, periodic,FromK1,ToK2, index,u); |
407 | index = BSplCLib::FlatIndex(deg,index,mults->Array1(),periodic); |
408 | |
409 | if ( rational ) { |
410 | BSplCLib::D0(u,index,deg,periodic,POLES, |
411 | weights->Array1(), |
412 | FKNOTS,FMULTS,P); |
413 | } |
414 | else { |
415 | BSplCLib::D0(u,index,deg,periodic,POLES, |
416 | *((TColStd_Array1OfReal*) NULL), |
417 | FKNOTS,FMULTS,P); |
418 | } |
419 | } |
420 | |
421 | //======================================================================= |
422 | //function : LocalD1 |
423 | //purpose : |
424 | //======================================================================= |
425 | |
426 | void Geom2d_BSplineCurve::LocalD1 (const Standard_Real U, |
427 | const Standard_Integer FromK1, |
428 | const Standard_Integer ToK2, |
429 | gp_Pnt2d& P, |
430 | gp_Vec2d& V1) const |
431 | { |
432 | Standard_DomainError_Raise_if (FromK1 == ToK2, |
433 | "Geom2d_BSplineCurve::LocalD1"); |
434 | |
435 | Standard_Real u = U; |
436 | Standard_Integer index = 0; |
437 | BSplCLib::LocateParameter(deg, FKNOTS, U, periodic, FromK1,ToK2, index, u); |
438 | index = BSplCLib::FlatIndex(deg,index,mults->Array1(),periodic); |
439 | |
440 | if (rational) { |
441 | BSplCLib::D1(u,index,deg,periodic,POLES, |
442 | weights->Array1(), |
443 | FKNOTS,FMULTS,P,V1); |
444 | } |
445 | else { |
446 | BSplCLib::D1(u,index,deg,periodic,POLES, |
447 | *((TColStd_Array1OfReal*) NULL), |
448 | FKNOTS,FMULTS,P,V1); |
449 | } |
450 | } |
451 | |
452 | //======================================================================= |
453 | //function : LocalD2 |
454 | //purpose : |
455 | //======================================================================= |
456 | |
457 | void Geom2d_BSplineCurve::LocalD2 |
458 | (const Standard_Real U, |
459 | const Standard_Integer FromK1, |
460 | const Standard_Integer ToK2, |
461 | gp_Pnt2d& P, |
462 | gp_Vec2d& V1, |
463 | gp_Vec2d& V2) const |
464 | { |
465 | Standard_DomainError_Raise_if (FromK1 == ToK2, |
466 | "Geom2d_BSplineCurve::LocalD2"); |
467 | |
468 | Standard_Real u = U; |
469 | Standard_Integer index = 0; |
470 | BSplCLib::LocateParameter(deg, FKNOTS, U, periodic, FromK1,ToK2, index, u); |
471 | index = BSplCLib::FlatIndex(deg,index,mults->Array1(),periodic); |
472 | |
473 | if ( rational ) { |
474 | BSplCLib::D2(u,index,deg,periodic,POLES, |
475 | weights->Array1(), |
476 | FKNOTS,FMULTS,P,V1,V2); |
477 | } |
478 | else { |
479 | BSplCLib::D2(u,index,deg,periodic,POLES, |
480 | *((TColStd_Array1OfReal*) NULL), |
481 | FKNOTS,FMULTS,P,V1,V2); |
482 | } |
483 | } |
484 | |
485 | //======================================================================= |
486 | //function : LocalD3 |
487 | //purpose : |
488 | //======================================================================= |
489 | |
490 | void Geom2d_BSplineCurve::LocalD3 |
491 | (const Standard_Real U, |
492 | const Standard_Integer FromK1, |
493 | const Standard_Integer ToK2, |
494 | gp_Pnt2d& P, |
495 | gp_Vec2d& V1, |
496 | gp_Vec2d& V2, |
497 | gp_Vec2d& V3) const |
498 | { |
499 | Standard_DomainError_Raise_if (FromK1 == ToK2, |
500 | "Geom2d_BSplineCurve::LocalD3"); |
501 | |
502 | Standard_Real u = U; |
503 | Standard_Integer index = 0; |
504 | BSplCLib::LocateParameter(deg, FKNOTS, U, periodic, FromK1,ToK2, index, u); |
505 | index = BSplCLib::FlatIndex(deg,index,mults->Array1(),periodic); |
506 | |
507 | if ( rational ) { |
508 | BSplCLib::D3(u,index,deg,periodic,POLES, |
509 | weights->Array1(), |
510 | FKNOTS,FMULTS,P,V1,V2,V3); |
511 | } |
512 | else { |
513 | BSplCLib::D3(u,index,deg,periodic,POLES, |
514 | *((TColStd_Array1OfReal*) NULL), |
515 | FKNOTS,FMULTS,P,V1,V2,V3); |
516 | } |
517 | } |
518 | |
519 | //======================================================================= |
520 | //function : LocalDN |
521 | //purpose : |
522 | //======================================================================= |
523 | |
524 | gp_Vec2d Geom2d_BSplineCurve::LocalDN |
525 | (const Standard_Real U, |
526 | const Standard_Integer FromK1, |
527 | const Standard_Integer ToK2, |
528 | const Standard_Integer N ) const |
529 | { |
530 | Standard_DomainError_Raise_if (FromK1 == ToK2, |
531 | "Geom2d_BSplineCurve::LocalD3"); |
532 | |
533 | Standard_Real u = U; |
534 | Standard_Integer index = 0; |
535 | BSplCLib::LocateParameter(deg, FKNOTS, U, periodic, FromK1,ToK2, index, u); |
536 | index = BSplCLib::FlatIndex(deg,index,mults->Array1(),periodic); |
537 | |
538 | gp_Vec2d V; |
539 | |
540 | if ( rational ) { |
541 | BSplCLib::DN(u,N,index,deg,periodic,POLES, |
542 | weights->Array1(), |
543 | FKNOTS,FMULTS,V); |
544 | } |
545 | else { |
546 | BSplCLib::DN(u,N,index,deg,periodic,POLES, |
547 | *((TColStd_Array1OfReal*) NULL), |
548 | FKNOTS,FMULTS,V); |
549 | } |
550 | return V; |
551 | } |
552 | |
553 | //======================================================================= |
554 | //function : Multiplicity |
555 | //purpose : |
556 | //======================================================================= |
557 | |
558 | Standard_Integer Geom2d_BSplineCurve::Multiplicity |
559 | (const Standard_Integer Index) const |
560 | { |
561 | Standard_OutOfRange_Raise_if (Index < 1 || Index > mults->Length(), |
562 | "Geom2d_BSplineCurve::Multiplicity"); |
563 | return mults->Value (Index); |
564 | } |
565 | |
566 | //======================================================================= |
567 | //function : Multiplicities |
568 | //purpose : |
569 | //======================================================================= |
570 | |
571 | void Geom2d_BSplineCurve::Multiplicities (TColStd_Array1OfInteger& M) const |
572 | { |
573 | Standard_DimensionError_Raise_if (M.Length() != mults->Length(), |
574 | "Geom2d_BSplineCurve::Multiplicities"); |
575 | M = mults->Array1(); |
576 | } |
577 | |
578 | //======================================================================= |
579 | //function : NbKnots |
580 | //purpose : |
581 | //======================================================================= |
582 | |
583 | Standard_Integer Geom2d_BSplineCurve::NbKnots () const |
584 | { return knots->Length(); } |
585 | |
586 | //======================================================================= |
587 | //function : NbPoles |
588 | //purpose : |
589 | //======================================================================= |
590 | |
591 | Standard_Integer Geom2d_BSplineCurve::NbPoles () const |
592 | { return poles->Length(); } |
593 | |
594 | //======================================================================= |
595 | //function : Pole |
596 | //purpose : |
597 | //======================================================================= |
598 | |
599 | gp_Pnt2d Geom2d_BSplineCurve::Pole (const Standard_Integer Index) const |
600 | { |
601 | Standard_OutOfRange_Raise_if (Index < 1 || Index > poles->Length(), |
602 | "Geom2d_BSplineCurve::Pole"); |
603 | return poles->Value (Index); |
604 | } |
605 | |
606 | //======================================================================= |
607 | //function : Poles |
608 | //purpose : |
609 | //======================================================================= |
610 | |
611 | void Geom2d_BSplineCurve::Poles (TColgp_Array1OfPnt2d& P) const |
612 | { |
613 | Standard_DimensionError_Raise_if (P.Length() != poles->Length(), |
614 | "Geom2d_BSplineCurve::Poles"); |
615 | P = poles->Array1(); |
616 | } |
617 | |
618 | //======================================================================= |
619 | //function : StartPoint |
620 | //purpose : |
621 | //======================================================================= |
622 | |
623 | gp_Pnt2d Geom2d_BSplineCurve::StartPoint () const |
624 | { |
625 | if (mults->Value (1) == deg + 1) |
626 | return poles->Value (1); |
627 | else |
628 | return Value(FirstParameter()); |
629 | } |
630 | |
631 | //======================================================================= |
632 | //function : Weight |
633 | //purpose : |
634 | //======================================================================= |
635 | |
636 | Standard_Real Geom2d_BSplineCurve::Weight |
637 | (const Standard_Integer Index) const |
638 | { |
639 | Standard_OutOfRange_Raise_if (Index < 1 || Index > poles->Length(), |
640 | "Geom2d_BSplineCurve::Weight"); |
641 | if (IsRational()) |
642 | return weights->Value (Index); |
643 | else |
644 | return 1.; |
645 | } |
646 | |
647 | //======================================================================= |
648 | //function : Weights |
649 | //purpose : |
650 | //======================================================================= |
651 | |
652 | void Geom2d_BSplineCurve::Weights |
653 | (TColStd_Array1OfReal& W) const |
654 | { |
655 | Standard_DimensionError_Raise_if (W.Length() != poles->Length(), |
656 | "Geom2d_BSplineCurve::Weights"); |
657 | if (IsRational()) |
658 | W = weights->Array1(); |
659 | else { |
660 | Standard_Integer i; |
661 | for (i = W.Lower(); i <= W.Upper(); i++) |
662 | W(i) = 1.; |
663 | } |
664 | } |
665 | |
666 | //======================================================================= |
667 | //function : IsRational |
668 | //purpose : |
669 | //======================================================================= |
670 | |
671 | Standard_Boolean Geom2d_BSplineCurve::IsRational () const |
672 | { |
673 | return !weights.IsNull(); |
674 | } |
675 | |
676 | //======================================================================= |
677 | //function : Transform |
678 | //purpose : |
679 | //======================================================================= |
680 | |
681 | void Geom2d_BSplineCurve::Transform |
682 | (const gp_Trsf2d& T) |
683 | { |
684 | TColgp_Array1OfPnt2d & CPoles = poles->ChangeArray1(); |
685 | for (Standard_Integer I = 1; I <= CPoles.Length(); I++) |
686 | CPoles (I).Transform (T); |
687 | |
688 | InvalidateCache(); |
689 | // maxderivinvok = 0; |
690 | } |
691 | |
692 | //======================================================================= |
693 | //function : LocateU |
694 | //purpose : |
695 | //======================================================================= |
696 | |
697 | void Geom2d_BSplineCurve::LocateU |
698 | (const Standard_Real U, |
699 | const Standard_Real ParametricTolerance, |
700 | Standard_Integer& I1, |
701 | Standard_Integer& I2, |
702 | const Standard_Boolean WithKnotRepetition) const |
703 | { |
704 | Standard_Real NewU = U; |
705 | Handle(TColStd_HArray1OfReal) TheKnots; |
706 | if (WithKnotRepetition) TheKnots = flatknots; |
707 | else TheKnots = knots; |
708 | |
709 | const TColStd_Array1OfReal & CKnots = TheKnots->Array1(); |
710 | |
711 | PeriodicNormalization(NewU); //Attention a la periode |
712 | Standard_Real UFirst = CKnots (1); |
713 | Standard_Real ULast = CKnots (CKnots.Length()); |
41c52af3 |
714 | Standard_Real PParametricTolerance = Abs(ParametricTolerance); |
715 | if (Abs (NewU - UFirst) <= PParametricTolerance) { I1 = I2 = 1; } |
716 | else if (Abs (NewU - ULast) <= PParametricTolerance) { |
7fd59977 |
717 | I1 = I2 = CKnots.Length(); |
718 | } |
41c52af3 |
719 | else if (NewU < UFirst) { |
7fd59977 |
720 | I2 = 1; |
721 | I1 = 0; |
722 | } |
41c52af3 |
723 | else if (NewU > ULast) { |
7fd59977 |
724 | I1 = CKnots.Length(); |
725 | I2 = I1 + 1; |
726 | } |
727 | else { |
728 | I1 = 1; |
729 | BSplCLib::Hunt (CKnots, NewU, I1); |
41c52af3 |
730 | while ( Abs( CKnots(I1+1) - NewU) <= PParametricTolerance) I1++; |
731 | if ( Abs( CKnots(I1) - NewU) <= PParametricTolerance) { |
7fd59977 |
732 | I2 = I1; |
733 | } |
734 | else { |
735 | I2 = I1 + 1; |
736 | } |
737 | } |
738 | } |
739 | |
740 | //======================================================================= |
741 | //function : Resolution |
742 | //purpose : |
743 | //======================================================================= |
744 | |
745 | void Geom2d_BSplineCurve::Resolution(const Standard_Real ToleranceUV, |
746 | Standard_Real & UTolerance) |
747 | { |
748 | Standard_Integer ii ; |
749 | if(!maxderivinvok){ |
750 | if ( periodic) { |
751 | Standard_Integer NbKnots, NbPoles; |
752 | BSplCLib::PrepareUnperiodize( deg, |
753 | mults->Array1(), |
754 | NbKnots, |
755 | NbPoles); |
756 | TColgp_Array1OfPnt2d new_poles(1,NbPoles) ; |
757 | TColStd_Array1OfReal new_weights(1,NbPoles) ; |
758 | for(ii = 1 ; ii <= NbPoles ; ii++) { |
759 | new_poles(ii) = poles->Array1()(((ii-1) % poles->Length()) + 1) ; |
760 | } |
761 | if (rational) { |
762 | for(ii = 1 ; ii <= NbPoles ; ii++) { |
763 | new_weights(ii) = weights->Array1()(((ii-1) % poles->Length()) + 1) ; |
764 | } |
765 | BSplCLib::Resolution(new_poles, |
766 | new_weights, |
767 | new_poles.Length(), |
768 | flatknots->Array1(), |
769 | deg, |
770 | 1., |
771 | maxderivinv) ; |
772 | } |
773 | else { |
774 | BSplCLib::Resolution(new_poles, |
775 | *((TColStd_Array1OfReal*) NULL), |
776 | new_poles.Length(), |
777 | flatknots->Array1(), |
778 | deg, |
779 | 1., |
780 | maxderivinv) ; |
781 | } |
782 | } |
783 | else { |
784 | if (rational) { |
785 | BSplCLib::Resolution(poles->Array1(), |
786 | weights->Array1(), |
787 | poles->Length(), |
788 | flatknots->Array1(), |
789 | deg, |
790 | 1., |
791 | maxderivinv) ; |
792 | } |
793 | else { |
794 | BSplCLib::Resolution(poles->Array1(), |
795 | *((TColStd_Array1OfReal*) NULL), |
796 | poles->Length(), |
797 | flatknots->Array1(), |
798 | deg, |
799 | 1., |
800 | maxderivinv) ; |
801 | } |
802 | } |
803 | maxderivinvok = 1; |
804 | } |
805 | UTolerance = ToleranceUV * maxderivinv; |
806 | } |
807 | |