0022627: Change OCCT memory management defaults
[occt.git] / src / Geom2d / Geom2d_BSplineCurve.cxx
CommitLineData
7fd59977 1// File: Geom2d_BSplineCurve.cxx
2// Created: Thu Mar 25 11:25:16 1993
3// Author: JCV
4// <fid@sdsun2>
5// Copyright: Matra Datavision 1993
6
7//File Geom2d_BSplineCurve.cxx jcv - Avril 1991
8//Avril 1991 : constructeurs + methodes de lecture.
9//Mai 1991 : revue des specifs + debut de realisation des classes tool =>
10// implementation des methodes Set et calcul du point courant.
11//Juillet 1991 : voir egalement File Geom2d_BSplineCurve_1.cxx
12//Juin 1992 : mise a plat des valeurs nodales - amelioration des
13// performances sur calcul du point courant
14
15//RLE Aug 1993 Remove Swaps, Init methods, Remove typedefs
16// 14-Mar-96 : xab implemented MovePointAndTangent
17
18//SAMTECH Jan 2002 : add text to Raise()
19
20#define No_Standard_OutOfRange
21
22#include <Geom2d_BSplineCurve.ixx>
23#include <gp.hxx>
24#include <BSplCLib.hxx>
25#include <BSplCLib_KnotDistribution.hxx>
26#include <BSplCLib_MultDistribution.hxx>
27#include <Standard_NotImplemented.hxx>
28#include <Standard_ConstructionError.hxx>
29#include <Standard_OutOfRange.hxx>
30
31//=======================================================================
32//function : CheckCurveData
33//purpose : Internal use only
34//=======================================================================
35
36static void CheckCurveData
37(const TColgp_Array1OfPnt2d& CPoles,
38 const TColStd_Array1OfReal& CKnots,
39 const TColStd_Array1OfInteger& CMults,
40 const Standard_Integer Degree,
41 const Standard_Boolean Periodic)
42{
43 if (Degree < 1 || Degree > Geom2d_BSplineCurve::MaxDegree()) {
44 Standard_ConstructionError::Raise("BSpline curve : invalid degree");
45 }
46
47 if (CPoles.Length() < 2) Standard_ConstructionError::Raise("BSpline curve : at least 2 poles required");
48 if (CKnots.Length() != CMults.Length()) Standard_ConstructionError::Raise("BSpline curve : Knot and Mult array size mismatch");
49
50 for (Standard_Integer I = CKnots.Lower(); I < CKnots.Upper(); I++) {
51 if (CKnots (I+1) - CKnots (I) <= Epsilon (Abs(CKnots (I)))) {
52 Standard_ConstructionError::Raise("BSpline curve : Knots interval values too close");
53 }
54 }
55
56 if (CPoles.Length() != BSplCLib::NbPoles(Degree,Periodic,CMults))
57 Standard_ConstructionError::Raise("BSpline curve : # Poles and degree mismatch");
58}
59
60//=======================================================================
61//function : KnotAnalysis
62//purpose : Internal use only
63//=======================================================================
64
65static void KnotAnalysis
66(const Standard_Integer Degree,
67 const Standard_Boolean Periodic,
68 const TColStd_Array1OfReal& CKnots,
69 const TColStd_Array1OfInteger& CMults,
70 GeomAbs_BSplKnotDistribution& KnotForm,
71 Standard_Integer& MaxKnotMult)
72{
73 KnotForm = GeomAbs_NonUniform;
74
75 BSplCLib_KnotDistribution KSet =
76 BSplCLib::KnotForm (CKnots, 1, CKnots.Length());
77
78
79 if (KSet == BSplCLib_Uniform) {
80 BSplCLib_MultDistribution MSet =
81 BSplCLib::MultForm (CMults, 1, CMults.Length());
82 switch (MSet) {
83 case BSplCLib_NonConstant :
84 break;
85 case BSplCLib_Constant :
86 if (CKnots.Length() == 2) {
87 KnotForm = GeomAbs_PiecewiseBezier;
88 }
89 else {
90 if (CMults (1) == 1) KnotForm = GeomAbs_Uniform;
91 }
92 break;
93 case BSplCLib_QuasiConstant :
94 if (CMults (1) == Degree + 1) {
95 Standard_Real M = CMults (2);
96 if (M == Degree ) KnotForm = GeomAbs_PiecewiseBezier;
97 else if (M == 1) KnotForm = GeomAbs_QuasiUniform;
98 }
99 break;
100 }
101 }
102
103 Standard_Integer FirstKM =
104 Periodic ? CKnots.Lower() : BSplCLib::FirstUKnotIndex (Degree,CMults);
105 Standard_Integer LastKM =
106 Periodic ? CKnots.Upper() : BSplCLib::LastUKnotIndex (Degree,CMults);
107 MaxKnotMult = 0;
108 if (LastKM - FirstKM != 1) {
109 Standard_Integer Multi;
110 for (Standard_Integer i = FirstKM + 1; i < LastKM; i++) {
111 Multi = CMults (i);
112 MaxKnotMult = Max (MaxKnotMult, Multi);
113 }
114 }
115}
116
117//=======================================================================
118//function : Rational
119//purpose : check rationality of an array of weights
120//=======================================================================
121
122static Standard_Boolean Rational(const TColStd_Array1OfReal& W)
123{
124 Standard_Integer i, n = W.Length();
125 Standard_Boolean rat = Standard_False;
126 for (i = 1; i < n; i++) {
127 rat = Abs(W(i) - W(i+1)) > gp::Resolution();
128 if (rat) break;
129 }
130 return rat;
131}
132
133//=======================================================================
134//function : Copy
135//purpose :
136//=======================================================================
137
138Handle(Geom2d_Geometry) Geom2d_BSplineCurve::Copy() const
139{
140 Handle(Geom2d_BSplineCurve) C;
141 if (IsRational())
142 C = new Geom2d_BSplineCurve(poles->Array1(),
143 weights->Array1(),
144 knots->Array1(),
145 mults->Array1(),
146 deg,periodic);
147 else
148 C = new Geom2d_BSplineCurve(poles->Array1(),
149 knots->Array1(),
150 mults->Array1(),
151 deg,periodic);
152 return C;
153}
154
155//=======================================================================
156//function : Geom2d_BSplineCurve
157//purpose :
158//=======================================================================
159
160Geom2d_BSplineCurve::Geom2d_BSplineCurve
161(const TColgp_Array1OfPnt2d& Poles,
162 const TColStd_Array1OfReal& Knots,
163 const TColStd_Array1OfInteger& Mults,
164 const Standard_Integer Degree,
165 const Standard_Boolean Periodic) :
166 rational(Standard_False),
167 periodic(Periodic),
168 deg(Degree),
169 maxderivinvok(Standard_False)
170{
171 // check
172
173 CheckCurveData (Poles,
174 Knots,
175 Mults,
176 Degree,
177 Periodic);
178
179
180 // copy arrays
181
182 poles = new TColgp_HArray1OfPnt2d(1,Poles.Length());
183 poles->ChangeArray1() = Poles;
184
185 knots = new TColStd_HArray1OfReal(1,Knots.Length());
186 knots->ChangeArray1() = Knots;
187
188 mults = new TColStd_HArray1OfInteger(1,Mults.Length());
189 mults->ChangeArray1() = Mults;
190
191 UpdateKnots();
192 cachepoles = new TColgp_HArray1OfPnt2d(1,Degree + 1);
193 parametercache = 0.0e0 ;
194 spanlenghtcache = 0.0e0 ;
195 spanindexcache = 0 ;
196}
197
198//=======================================================================
199//function : Geom2d_BSplineCurve
200//purpose :
201//=======================================================================
202
203Geom2d_BSplineCurve::Geom2d_BSplineCurve
204(const TColgp_Array1OfPnt2d& Poles,
205 const TColStd_Array1OfReal& Weights,
206 const TColStd_Array1OfReal& Knots,
207 const TColStd_Array1OfInteger& Mults,
208 const Standard_Integer Degree,
209 const Standard_Boolean Periodic) :
210 rational(Standard_True),
211 periodic(Periodic),
212 deg(Degree),
213 maxderivinvok(Standard_False)
214
215{
216
217 // check
218
219 CheckCurveData (Poles,
220 Knots,
221 Mults,
222 Degree,
223 Periodic);
224
225 if (Weights.Length() != Poles.Length())
226 Standard_ConstructionError::Raise("Geom2d_BSplineCurve :Weights and Poles array size mismatch");
227
228 Standard_Integer i;
229 for (i = Weights.Lower(); i <= Weights.Upper(); i++) {
230 if (Weights(i) <= gp::Resolution()) {
231 Standard_ConstructionError::Raise("Geom2d_BSplineCurve: Weights values too small");
232 }
233 }
234
235 // check really rational
236 rational = Rational(Weights);
237
238 // copy arrays
239
240 poles = new TColgp_HArray1OfPnt2d(1,Poles.Length());
241 poles->ChangeArray1() = Poles;
242 cachepoles = new TColgp_HArray1OfPnt2d(1,Degree + 1);
243 if (rational) {
244 weights = new TColStd_HArray1OfReal(1,Weights.Length());
245 weights->ChangeArray1() = Weights;
246 cacheweights = new TColStd_HArray1OfReal(1,Degree + 1);
247 }
248
249 knots = new TColStd_HArray1OfReal(1,Knots.Length());
250 knots->ChangeArray1() = Knots;
251
252 mults = new TColStd_HArray1OfInteger(1,Mults.Length());
253 mults->ChangeArray1() = Mults;
254
255 UpdateKnots();
256
257 parametercache = 0.0e0 ;
258 spanlenghtcache = 0.0e0 ;
259 spanindexcache = 0 ;
260}
261
262//=======================================================================
263//function : MaxDegree
264//purpose :
265//=======================================================================
266
267Standard_Integer Geom2d_BSplineCurve::MaxDegree ()
268{
269 return BSplCLib::MaxDegree();
270}
271
272//=======================================================================
273//function : IncreaseDegree
274//purpose :
275//=======================================================================
276
277void Geom2d_BSplineCurve::IncreaseDegree
278(const Standard_Integer Degree)
279{
280 if (Degree == deg) return;
281
282 if (Degree < deg || Degree > Geom2d_BSplineCurve::MaxDegree()) {
283 Standard_ConstructionError::Raise("BSpline curve : IncreaseDegree : bad degree value");
284 }
285
286 Standard_Integer FromK1 = FirstUKnotIndex ();
287 Standard_Integer ToK2 = LastUKnotIndex ();
288
289 Standard_Integer Step = Degree - deg;
290
291 Handle(TColgp_HArray1OfPnt2d) npoles = new
292 TColgp_HArray1OfPnt2d(1,poles->Length() + Step * (ToK2-FromK1));
293
294 Standard_Integer nbknots = BSplCLib::IncreaseDegreeCountKnots
295 (deg,Degree,periodic,mults->Array1());
296
297 Handle(TColStd_HArray1OfReal) nknots =
298 new TColStd_HArray1OfReal(1,nbknots);
299
300 Handle(TColStd_HArray1OfInteger) nmults =
301 new TColStd_HArray1OfInteger(1,nbknots);
302
303 Handle(TColStd_HArray1OfReal) nweights;
304
305 if (IsRational()) {
306
307 nweights = new TColStd_HArray1OfReal(1,npoles->Upper());
308
309 BSplCLib::IncreaseDegree
310 (deg,Degree, periodic,
311 poles->Array1(),weights->Array1(),
312 knots->Array1(),mults->Array1(),
313 npoles->ChangeArray1(),nweights->ChangeArray1(),
314 nknots->ChangeArray1(),nmults->ChangeArray1());
315 }
316 else {
317
318 BSplCLib::IncreaseDegree
319 (deg,Degree, periodic,
320 poles->Array1(),
321 *((TColStd_Array1OfReal*) NULL),
322 knots->Array1(),mults->Array1(),
323 npoles->ChangeArray1(),
324 *((TColStd_Array1OfReal*) NULL),
325 nknots->ChangeArray1(),nmults->ChangeArray1());
326 }
327
328 deg = Degree;
329 poles = npoles;
330 weights = nweights;
331 knots = nknots;
332 mults = nmults;
333 UpdateKnots();
334}
335
336//=======================================================================
337//function : IncreaseMultiplicity
338//purpose :
339//=======================================================================
340
341void Geom2d_BSplineCurve::IncreaseMultiplicity
342(const Standard_Integer Index,
343 const Standard_Integer M)
344{
345 TColStd_Array1OfReal k(1,1);
346 k(1) = knots->Value(Index);
347 TColStd_Array1OfInteger m(1,1);
348 m(1) = M - mults->Value(Index);
349 InsertKnots(k,m,Epsilon(1.),Standard_True);
350}
351
352//=======================================================================
353//function : IncreaseMultiplicity
354//purpose :
355//=======================================================================
356
357void Geom2d_BSplineCurve::IncreaseMultiplicity
358(const Standard_Integer I1,
359 const Standard_Integer I2,
360 const Standard_Integer M)
361{
362 Handle(TColStd_HArray1OfReal) tk = knots;
363 TColStd_Array1OfReal k((knots->Array1())(I1),I1,I2);
364 TColStd_Array1OfInteger m(I1,I2);
365 Standard_Integer i;
366 for (i = I1; i <= I2; i++)
367 m(i) = M - mults->Value(i);
368 InsertKnots(k,m,Epsilon(1.),Standard_True);
369}
370
371//=======================================================================
372//function : IncrementMultiplicity
373//purpose :
374//=======================================================================
375
376void Geom2d_BSplineCurve::IncrementMultiplicity
377(const Standard_Integer I1,
378 const Standard_Integer I2,
379 const Standard_Integer Step)
380{
381 Handle(TColStd_HArray1OfReal) tk = knots;
382 TColStd_Array1OfReal k((knots->Array1())(I1),I1,I2);
383 TColStd_Array1OfInteger m(I1,I2);
384 m.Init(Step);
385 InsertKnots(k,m,Epsilon(1.),Standard_True);
386}
387
388//=======================================================================
389//function : InsertKnot
390//purpose :
391//=======================================================================
392
393void Geom2d_BSplineCurve::InsertKnot
394(const Standard_Real U,
395 const Standard_Integer M,
396 const Standard_Real ParametricTolerance)
397{
398 TColStd_Array1OfReal k(1,1);
399 k(1) = U;
400 TColStd_Array1OfInteger m(1,1);
401 m(1) = M;
402 InsertKnots(k,m,ParametricTolerance);
403}
404
405//=======================================================================
406//function : InsertKnots
407//purpose :
408//=======================================================================
409void Geom2d_BSplineCurve::InsertKnots(const TColStd_Array1OfReal& Knots,
410 const TColStd_Array1OfInteger& Mults,
411 const Standard_Real Epsilon,
412 const Standard_Boolean Add)
413{
414 // Check and compute new sizes
415 Standard_Integer nbpoles,nbknots;
416
417 if (!BSplCLib::PrepareInsertKnots(deg,periodic,
418 knots->Array1(),mults->Array1(),
419 Knots,Mults,nbpoles,nbknots,Epsilon,Add))
420 Standard_ConstructionError::Raise("Geom2d_BSplineCurve::InsertKnots");
421
422 if (nbpoles == poles->Length()) return;
423
424 Handle(TColgp_HArray1OfPnt2d) npoles = new TColgp_HArray1OfPnt2d(1,nbpoles);
425 Handle(TColStd_HArray1OfReal) nknots = knots;
426 Handle(TColStd_HArray1OfInteger) nmults = mults;
427
428 if (nbknots != knots->Length()) {
429 nknots = new TColStd_HArray1OfReal(1,nbknots);
430 nmults = new TColStd_HArray1OfInteger(1,nbknots);
431 }
432
433 if (rational) {
434 Handle(TColStd_HArray1OfReal) nweights =
435 new TColStd_HArray1OfReal(1,nbpoles);
436 BSplCLib::InsertKnots(deg,periodic,
437 poles->Array1(), weights->Array1(),
438 knots->Array1(), mults->Array1(),
439 Knots, Mults,
440 npoles->ChangeArray1(), nweights->ChangeArray1(),
441 nknots->ChangeArray1(), nmults->ChangeArray1(),
442 Epsilon,Add);
443 weights = nweights;
444 }
445 else {
446 BSplCLib::InsertKnots(deg,periodic,
447 poles->Array1(),
448 *((TColStd_Array1OfReal*) NULL),
449 knots->Array1(), mults->Array1(),
450 Knots, Mults,
451 npoles->ChangeArray1(),
452 *((TColStd_Array1OfReal*) NULL),
453 nknots->ChangeArray1(), nmults->ChangeArray1(),
454 Epsilon,Add);
455 }
456
457 poles = npoles;
458 knots = nknots;
459 mults = nmults;
460 UpdateKnots();
461
462}
463
464//=======================================================================
465//function : RemoveKnot
466//purpose :
467//=======================================================================
468
469Standard_Boolean Geom2d_BSplineCurve::RemoveKnot
470(const Standard_Integer Index,
471 const Standard_Integer M,
472 const Standard_Real Tolerance)
473{
474 if (M < 0) return Standard_True;
475
476 Standard_Integer I1 = FirstUKnotIndex ();
477 Standard_Integer I2 = LastUKnotIndex ();
478
479 if (Index < I1 || Index > I2) {
480 Standard_OutOfRange::Raise("BSpline curve : RemoveKnot : index out of range");
481 }
482
483 const TColgp_Array1OfPnt2d & oldpoles = poles->Array1();
484
485 Standard_Integer step = mults->Value(Index) - M;
486 if (step <= 0) return Standard_True;
487
488 Handle(TColgp_HArray1OfPnt2d) npoles =
489 new TColgp_HArray1OfPnt2d(1,oldpoles.Length()-step);
490
491 Handle(TColStd_HArray1OfReal) nknots = knots;
492 Handle(TColStd_HArray1OfInteger) nmults = mults;
493
494 if (M == 0) {
495 nknots = new TColStd_HArray1OfReal(1,knots->Length()-1);
496 nmults = new TColStd_HArray1OfInteger(1,knots->Length()-1);
497 }
498
499 if (IsRational()) {
500 Handle(TColStd_HArray1OfReal) nweights =
501 new TColStd_HArray1OfReal(1,npoles->Length());
502 if (!BSplCLib::RemoveKnot
503 (Index, M, deg, periodic,
504 poles->Array1(),weights->Array1(),
505 knots->Array1(),mults->Array1(),
506 npoles->ChangeArray1(), nweights->ChangeArray1(),
507 nknots->ChangeArray1(),nmults->ChangeArray1(),
508 Tolerance))
509 return Standard_False;
510 weights = nweights;
511 }
512 else {
513 if (!BSplCLib::RemoveKnot
514 (Index, M, deg, periodic,
515 poles->Array1(),
516 *((TColStd_Array1OfReal*) NULL),
517 knots->Array1(),mults->Array1(),
518 npoles->ChangeArray1(),
519 *((TColStd_Array1OfReal*) NULL),
520 nknots->ChangeArray1(),nmults->ChangeArray1(),
521 Tolerance))
522 return Standard_False;
523 }
524
525 poles = npoles;
526 knots = nknots;
527 mults = nmults;
528
529 UpdateKnots();
530 maxderivinvok = 0;
531 return Standard_True;
532}
533
534//=======================================================================
535//function : InsertPoleAfter
536//purpose :
537//=======================================================================
538
539void Geom2d_BSplineCurve::InsertPoleAfter
540(const Standard_Integer Index,
541 const gp_Pnt2d& P,
542 const Standard_Real Weight)
543{
544 if (Index < 0 || Index > poles->Length()) Standard_OutOfRange::Raise("BSpline curve : InsertPoleAfter: Index and #pole mismatch");
545
546 if (Weight <= gp::Resolution()) Standard_ConstructionError::Raise("BSpline curve : InsertPoleAfter: Weight too small");
547
548 if (knotSet == GeomAbs_NonUniform || knotSet == GeomAbs_PiecewiseBezier) {
549 Standard_ConstructionError::Raise("BSpline curve : InsertPoleAfter : bad knotSet type");
550 }
551
552 const TColStd_Array1OfReal& cknots = knots->Array1();
553 Standard_Integer nbknots = cknots.Length();
554
555 Handle(TColStd_HArray1OfReal) nknots =
556 new TColStd_HArray1OfReal(1,nbknots+1);
557
558 TColStd_Array1OfReal& newknots = nknots->ChangeArray1();
559
560 Standard_Integer i;
561 for (i = 1; i < nbknots; i++) {
562 newknots (i) = cknots(i);
563 }
564
565 newknots (nbknots+1) = 2 * newknots (nbknots) - newknots(nbknots-1);
566
567 Handle(TColStd_HArray1OfInteger) nmults =
568 new TColStd_HArray1OfInteger(1,nbknots+1);
569
570 TColStd_Array1OfInteger& newmults = nmults->ChangeArray1();
571 const TColStd_Array1OfInteger& cmults = mults->Array1();
572
573 for (i = 2; i <= nbknots; i++) newmults (i) = 1;
574 newmults (1) = cmults(1);
575 newmults (nbknots+1) = cmults(nbknots+1);
576
577 const TColgp_Array1OfPnt2d& cpoles = poles->Array1();
578 Standard_Integer nbpoles = cpoles.Length();
579 Handle(TColgp_HArray1OfPnt2d) npoles =
580 new TColgp_HArray1OfPnt2d(1, nbpoles+1);
581 TColgp_Array1OfPnt2d& newpoles = npoles->ChangeArray1();
582
583 // insert the pole
584
585 for (i = 1; i <= Index; i++)
586 newpoles(i) = cpoles(i);
587
588 newpoles(Index+1) = P;
589
590 for (i = Index+1; i <= nbpoles; i++)
591 newpoles(i+1) = cpoles(i);
592
593 // Insert the weight
594
595 Handle(TColStd_HArray1OfReal) nweights;
596 Standard_Boolean rat = IsRational() || Abs(Weight-1.) > gp::Resolution();
597
598 if (rat) {
599 nweights = new TColStd_HArray1OfReal(1,nbpoles+1);
600 TColStd_Array1OfReal& newweights = nweights->ChangeArray1();
601
602 for (i = 1; i <= Index; i++)
603 if (IsRational())
604 newweights(i) = weights->Value(i);
605 else
606 newweights(i) = 1.;
607
608 newweights(Index+1) = Weight;
609
610 for (i = Index+1; i <= nbpoles; i++)
611 if (IsRational())
612 newweights(i+1) = weights->Value(i);
613 else
614 newweights(i+1) = 1.;
615 }
616
617 poles = npoles;
618 weights = nweights;
619 knots = nknots;
620 mults = nmults;
621 maxderivinvok = 0;
622 UpdateKnots();
623}
624
625//=======================================================================
626//function : InsertPoleBefore
627//purpose :
628//=======================================================================
629
630void Geom2d_BSplineCurve::InsertPoleBefore
631(const Standard_Integer Index,
632 const gp_Pnt2d& P,
633 const Standard_Real Weight)
634{
635 InsertPoleAfter(Index-1,P,Weight);
636}
637
638//=======================================================================
639//function : RemovePole
640//purpose :
641//=======================================================================
642
643void Geom2d_BSplineCurve::RemovePole
644(const Standard_Integer Index)
645{
646 if (Index < 1 || Index > poles->Length()) Standard_OutOfRange::Raise("BSpline curve :RemovePole : Index and #pole mismatch");
647
648 if (poles->Length() <= 2) Standard_ConstructionError::Raise("BSpline curve : RemovePole : #pole is already minimum");
649
650 if (knotSet == GeomAbs_NonUniform || knotSet == GeomAbs_PiecewiseBezier)
651 Standard_ConstructionError::Raise("BSpline curve : RemovePole: bad knotSet type");
652
653 Standard_Integer i;
654 Handle(TColStd_HArray1OfReal) nknots =
655 new TColStd_HArray1OfReal(1,knots->Length()-1);
656 TColStd_Array1OfReal& newknots = nknots->ChangeArray1();
657
658 Handle(TColStd_HArray1OfInteger) nmults =
659 new TColStd_HArray1OfInteger(1,mults->Length()-1);
660 TColStd_Array1OfInteger& newmults = nmults->ChangeArray1();
661
662 for (i = 1; i < newknots.Length(); i++) {
663 newknots (i) = knots->Value (i);
664 newmults (i) = 1;
665 }
666 newmults(1) = mults->Value(1);
667 newknots(newknots.Upper()) = knots->Value (knots->Upper());
668 newmults(newmults.Upper()) = mults->Value (mults->Upper());
669
670
671 Handle(TColgp_HArray1OfPnt2d) npoles =
672 new TColgp_HArray1OfPnt2d(1, poles->Upper()-1);
673 TColgp_Array1OfPnt2d& newpoles = npoles->ChangeArray1();
674
675 for (i = 1; i < Index; i++)
676 newpoles(i) = poles->Value(i);
677 for (i = Index; i < newpoles.Length(); i++)
678 newpoles(i) = poles->Value(i+1);
679
680 Handle(TColStd_HArray1OfReal) nweights;
681 if (IsRational()) {
682 nweights = new TColStd_HArray1OfReal(1,newpoles.Length());
683 TColStd_Array1OfReal& newweights = nweights->ChangeArray1();
684 for (i = 1; i < Index; i++)
685 newweights(i) = weights->Value(i);
686 for (i = Index; i < newweights.Length(); i++)
687 newweights(i) = weights->Value(i+1);
688 }
689
690 poles = npoles;
691 weights = nweights;
692 knots = nknots;
693 mults = nmults;
694 UpdateKnots();
695}
696
697//=======================================================================
698//function : Reverse
699//purpose :
700//=======================================================================
701
702void Geom2d_BSplineCurve::Reverse ()
703{
704 BSplCLib::Reverse(knots->ChangeArray1());
705 BSplCLib::Reverse(mults->ChangeArray1());
706 Standard_Integer last;
707 if (periodic)
708 last = flatknots->Upper() - deg - 1;
709 else
710 last = poles->Upper();
711 BSplCLib::Reverse(poles->ChangeArray1(),last);
712 if (rational)
713 BSplCLib::Reverse(weights->ChangeArray1(),last);
714 UpdateKnots();
715}
716
717//=======================================================================
718//function : ReversedParameter
719//purpose :
720//=======================================================================
721
722Standard_Real Geom2d_BSplineCurve::ReversedParameter( const Standard_Real U) const
723{
724 return (FirstParameter() + LastParameter() - U);
725}
726
727//=======================================================================
728//function : Segment
729//purpose :
730//=======================================================================
731void Geom2d_BSplineCurve::Segment(const Standard_Real aU1,
732 const Standard_Real aU2)
733{
734 Standard_DomainError_Raise_if ( aU2 < aU1, "Geom2d_BSplineCurve::Segment");
735 //
736 Standard_Real AbsUMax = Max(Abs(FirstParameter()),Abs(LastParameter()));
737 Standard_Real Eps = Epsilon(AbsUMax);
738 Standard_Real NewU1, NewU2;
739 Standard_Real U, DU=0;
740 Standard_Integer i, k, index;
741 //
742 //f
743 // Checking the input bounds aUj (j=1,2).
744 // For the case when aUj==knot(i),
745 // in order to prevent the insertion of a new knot that will be too closed
746 // to the existing knot,
747 // we assign Uj=knot(i)
748 Standard_Integer n1, n2;
749 Standard_Real U1, U2;
750 //
751 U1=aU1;
752 U2=aU2;
753 n1=knots->Lower();
754 n2=knots->Upper();
755 for (i=n1; i<=n2; ++i) {
756 U=knots->Value(i);
757 if (Abs(U-aU1)<=Eps) {
758 U1=U;
759 }
760 else if (Abs(U-aU2)<=Eps) {
761 U2=U;
762 }
763 }
764 // Henceforward we use U1, U2 as bounds of the segment
765 //t
766 //
767 TColStd_Array1OfReal Knots(1,2);
768 TColStd_Array1OfInteger Mults(1,2);
769 //
770 // define param ditance to keep (eap, Apr 18 2002, occ311)
771 if (periodic) {
772 Standard_Real Period = LastParameter() - FirstParameter();
773 DU = U2 - U1;
774 while (DU > Period) {
775 DU -= Period;
776 }
777 if (DU <= Epsilon(Period)) {
778 DU = Period;
779 }
780 }
781 //
782 index = 0;
783 BSplCLib::LocateParameter(deg,knots->Array1(),mults->Array1(),
784 U1,periodic,knots->Lower(),knots->Upper(),
785 index,NewU1);
786 index = 0;
787 BSplCLib::LocateParameter(deg,knots->Array1(),mults->Array1(),
788 U2,periodic,knots->Lower(),knots->Upper(),
789 index,NewU2);
790 Knots(1) = Min( NewU1, NewU2);
791 Knots(2) = Max( NewU1, NewU2);
792 Mults(1) = Mults( 2) = deg;
793 InsertKnots(Knots, Mults, Eps);
794
795 if (periodic) { // set the origine at NewU1
796 index = 0;
797 BSplCLib::LocateParameter(deg,knots->Array1(),mults->Array1(),
798 U1,periodic,knots->Lower(),knots->Upper(),
799 index,U);
800 // Eps = Epsilon(knots->Value(index+1));
801 if ( Abs(knots->Value(index+1)-U) <= Eps) {
802 index++;
803 }
804 SetOrigin(index);
805 SetNotPeriodic();
806 NewU2 = NewU1 + DU;
807 }
808
809 // compute index1 and index2 to set the new knots and mults
810 Standard_Integer index1 = 0, index2 = 0;
811 Standard_Integer FromU1 = knots->Lower();
812 Standard_Integer ToU2 = knots->Upper();
813 BSplCLib::LocateParameter(deg,knots->Array1(),mults->Array1(),
814 NewU1,periodic,FromU1,ToU2,index1,U);
815 BSplCLib::LocateParameter(deg,knots->Array1(),mults->Array1(),
816 NewU2,periodic,FromU1,ToU2,index2,U);
817 // Eps = Epsilon(knots->Value(index2+1));
818 if ( Abs(knots->Value(index2+1)-U) <= Eps){
819 index2++;
820 }
821
822 Standard_Integer nbknots = index2 - index1 + 1;
823
824 Handle(TColStd_HArray1OfReal)
825 nknots = new TColStd_HArray1OfReal(1,nbknots);
826 Handle(TColStd_HArray1OfInteger)
827 nmults = new TColStd_HArray1OfInteger(1,nbknots);
828
829 // to restore changed U1
830 if (DU > 0) {// if was periodic
831 DU = NewU1 - U1;
832 }
833 //
834 k = 1;
835 //
836 for ( i = index1; i<= index2; i++) {
837 nknots->SetValue(k, knots->Value(i) - DU);
838 nmults->SetValue(k, mults->Value(i));
839 k++;
840 }
841 nmults->SetValue( 1, deg + 1);
842 nmults->SetValue(nbknots, deg + 1);
843
844
845 // compute index1 and index2 to set the new poles and weights
846 Standard_Integer pindex1
847 = BSplCLib::PoleIndex(deg,index1,periodic,mults->Array1());
848 Standard_Integer pindex2
849 = BSplCLib::PoleIndex(deg,index2,periodic,mults->Array1());
850
851 pindex1++;
852 pindex2 = Min( pindex2+1, poles->Length());
853
854 Standard_Integer nbpoles = pindex2 - pindex1 + 1;
855
856 Handle(TColStd_HArray1OfReal)
857 nweights = new TColStd_HArray1OfReal(1,nbpoles);
858 Handle(TColgp_HArray1OfPnt2d)
859 npoles = new TColgp_HArray1OfPnt2d(1,nbpoles);
860
861 k = 1;
862 if ( rational) {
863 nweights = new TColStd_HArray1OfReal( 1, nbpoles);
864 for ( i = pindex1; i <= pindex2; i++) {
865 npoles->SetValue(k, poles->Value(i));
866 nweights->SetValue(k, weights->Value(i));
867 k++;
868 }
869 }
870 else {
871 for ( i = pindex1; i <= pindex2; i++) {
872 npoles->SetValue(k, poles->Value(i));
873 k++;
874 }
875 }
876
877 knots = nknots;
878 mults = nmults;
879 poles = npoles;
880 if (rational){
881 weights = nweights;
882 }
883 UpdateKnots();
884}
885
886//=======================================================================
887//function : SetKnot
888//purpose :
889//=======================================================================
890
891void Geom2d_BSplineCurve::SetKnot
892(const Standard_Integer Index,
893 const Standard_Real K)
894{
895 if (Index < 1 || Index > knots->Length()) Standard_OutOfRange::Raise("BSpline curve : SetKnot: Index and #pole mismatch");
896 Standard_Real DK = Abs(Epsilon (K));
897 if (Index == 1) {
898 if (K >= knots->Value(2) - DK) Standard_ConstructionError::Raise("BSpline curve :SetKnot :K out of range");
899 }
900 else if (Index == knots->Length()) {
901 if (K <= knots->Value (knots->Length()-1) + DK) {
902 Standard_ConstructionError::Raise("BSpline curve : SetKnot : K out of range");
903 }
904 }
905 else {
906 if (K <= knots->Value(Index-1) + DK ||
907 K >= knots->Value(Index+1) - DK ) {
908 Standard_ConstructionError::Raise("BSpline curve : SetKnot: K out of range");
909 }
910 }
911 if (K != knots->Value (Index)) {
912 knots->SetValue (Index, K);
913 maxderivinvok = 0;
914 UpdateKnots();
915 }
916}
917
918//=======================================================================
919//function : SetKnots
920//purpose :
921//=======================================================================
922
923void Geom2d_BSplineCurve::SetKnots
924(const TColStd_Array1OfReal& K)
925{
926 CheckCurveData(poles->Array1(),K,mults->Array1(),deg,periodic);
927 knots->ChangeArray1() = K;
928 maxderivinvok = 0;
929 UpdateKnots();
930}
931
932//=======================================================================
933//function : SetKnot
934//purpose :
935//=======================================================================
936
937void Geom2d_BSplineCurve::SetKnot
938(const Standard_Integer Index,
939 const Standard_Real K,
940 const Standard_Integer M)
941{
942 IncreaseMultiplicity (Index, M);
943 SetKnot (Index, K);
944}
945
946//=======================================================================
947//function : SetPeriodic
948//purpose :
949//=======================================================================
950
951void Geom2d_BSplineCurve::SetPeriodic ()
952{
953 Standard_Integer first = FirstUKnotIndex();
954 Standard_Integer last = LastUKnotIndex();
955
956 Handle(TColStd_HArray1OfReal) tk = knots;
957 TColStd_Array1OfReal cknots((knots->Array1())(first),first,last);
958 knots = new TColStd_HArray1OfReal(1,cknots.Length());
959 knots->ChangeArray1() = cknots;
960
961 Handle(TColStd_HArray1OfInteger) tm = mults;
962 TColStd_Array1OfInteger cmults((mults->Array1())(first),first,last);
963 cmults(first) = cmults(last) = Min(deg, Max( cmults(first), cmults(last)));
964 mults = new TColStd_HArray1OfInteger(1,cmults.Length());
965 mults->ChangeArray1() = cmults;
966
967 // compute new number of poles;
968 Standard_Integer nbp = BSplCLib::NbPoles(deg,Standard_True,cmults);
969
970 Handle(TColgp_HArray1OfPnt2d) tp = poles;
971 TColgp_Array1OfPnt2d cpoles((poles->Array1())(1),1,nbp);
972 poles = new TColgp_HArray1OfPnt2d(1,nbp);
973 poles->ChangeArray1() = cpoles;
974
975 if (rational) {
976 Handle(TColStd_HArray1OfReal) tw = weights;
977 TColStd_Array1OfReal cweights((weights->Array1())(1),1,nbp);
978 weights = new TColStd_HArray1OfReal(1,nbp);
979 weights->ChangeArray1() = cweights;
980 }
981
982 periodic = Standard_True;
983
984 maxderivinvok = 0;
985 UpdateKnots();
986}
987
988//=======================================================================
989//function : SetOrigin
990//purpose :
991//=======================================================================
992
993void Geom2d_BSplineCurve::SetOrigin(const Standard_Integer Index)
994{
995 Standard_NoSuchObject_Raise_if( !periodic,
996 "Geom2d_BSplineCurve::SetOrigin");
997 Standard_Integer i,k;
998 Standard_Integer first = FirstUKnotIndex();
999 Standard_Integer last = LastUKnotIndex();
1000
1001 Standard_DomainError_Raise_if( (Index < first) || (Index > last),
1002 "Geom2d_BSplineCurve::SetOrigine");
1003
1004 Standard_Integer nbknots = knots->Length();
1005 Standard_Integer nbpoles = poles->Length();
1006
1007 Handle(TColStd_HArray1OfReal) nknots =
1008 new TColStd_HArray1OfReal(1,nbknots);
1009 TColStd_Array1OfReal& newknots = nknots->ChangeArray1();
1010
1011 Handle(TColStd_HArray1OfInteger) nmults =
1012 new TColStd_HArray1OfInteger(1,nbknots);
1013 TColStd_Array1OfInteger& newmults = nmults->ChangeArray1();
1014
1015 // set the knots and mults
1016 Standard_Real period = knots->Value(last) - knots->Value(first);
1017 k = 1;
1018 for ( i = Index; i <= last ; i++) {
1019 newknots(k) = knots->Value(i);
1020 newmults(k) = mults->Value(i);
1021 k++;
1022 }
1023 for ( i = first+1; i <= Index; i++) {
1024 newknots(k) = knots->Value(i) + period;
1025 newmults(k) = mults->Value(i);
1026 k++;
1027 }
1028
1029 Standard_Integer index = 1;
1030 for (i = first+1; i <= Index; i++)
1031 index += mults->Value(i);
1032
1033 // set the poles and weights
1034 Handle(TColgp_HArray1OfPnt2d) npoles =
1035 new TColgp_HArray1OfPnt2d(1,nbpoles);
1036 Handle(TColStd_HArray1OfReal) nweights =
1037 new TColStd_HArray1OfReal(1,nbpoles);
1038 TColgp_Array1OfPnt2d & newpoles = npoles->ChangeArray1();
1039 TColStd_Array1OfReal & newweights = nweights->ChangeArray1();
1040 first = poles->Lower();
1041 last = poles->Upper();
1042 if ( rational) {
1043 k = 1;
1044 for ( i = index; i <= last; i++) {
1045 newpoles(k) = poles->Value(i);
1046 newweights(k) = weights->Value(i);
1047 k++;
1048 }
1049 for ( i = first; i < index; i++) {
1050 newpoles(k) = poles->Value(i);
1051 newweights(k) = weights->Value(i);
1052 k++;
1053 }
1054 }
1055 else {
1056 k = 1;
1057 for ( i = index; i <= last; i++) {
1058 newpoles(k) = poles->Value(i);
1059 k++;
1060 }
1061 for ( i = first; i < index; i++) {
1062 newpoles(k) = poles->Value(i);
1063 k++;
1064 }
1065 }
1066
1067 poles = npoles;
1068 knots = nknots;
1069 mults = nmults;
1070 if (rational)
1071 weights = nweights;
1072 maxderivinvok = 0;
1073 UpdateKnots();
1074}
1075
1076//=======================================================================
1077//function : SetNotPeriodic
1078//purpose :
1079//=======================================================================
1080
1081void Geom2d_BSplineCurve::SetNotPeriodic ()
1082{
1083 if (periodic) {
1084 Standard_Integer NbKnots, NbPoles;
1085 BSplCLib::PrepareUnperiodize( deg, mults->Array1(),NbKnots,NbPoles);
1086
1087 Handle(TColgp_HArray1OfPnt2d) npoles
1088 = new TColgp_HArray1OfPnt2d(1,NbPoles);
1089
1090 Handle(TColStd_HArray1OfReal) nknots
1091 = new TColStd_HArray1OfReal(1,NbKnots);
1092
1093 Handle(TColStd_HArray1OfInteger) nmults
1094 = new TColStd_HArray1OfInteger(1,NbKnots);
1095
1096 Handle(TColStd_HArray1OfReal) nweights;
1097
1098 if (IsRational()) {
1099
1100 nweights = new TColStd_HArray1OfReal(1,NbPoles);
1101
1102 BSplCLib::Unperiodize
1103 (deg,mults->Array1(),knots->Array1(),poles->Array1(),
1104 weights->Array1(),nmults->ChangeArray1(),
1105 nknots->ChangeArray1(),npoles->ChangeArray1(),
1106 nweights->ChangeArray1());
1107
1108 }
1109 else {
1110
1111 BSplCLib::Unperiodize
1112 (deg,mults->Array1(),knots->Array1(),poles->Array1(),
1113 *((TColStd_Array1OfReal*) NULL),nmults->ChangeArray1(),
1114 nknots->ChangeArray1(),npoles->ChangeArray1(),
1115 *((TColStd_Array1OfReal*) NULL));
1116
1117 }
1118 poles = npoles;
1119 weights = nweights;
1120 mults = nmults;
1121 knots = nknots;
1122 periodic = Standard_False;
1123 maxderivinvok = 0;
1124 UpdateKnots();
1125 }
1126}
1127
1128//=======================================================================
1129//function : SetPole
1130//purpose :
1131//=======================================================================
1132
1133void Geom2d_BSplineCurve::SetPole
1134(const Standard_Integer Index,
1135 const gp_Pnt2d& P)
1136{
1137 if (Index < 1 || Index > poles->Length()) Standard_OutOfRange::Raise("BSpline curve : SetPole : index and #pole mismatch");
1138 poles->SetValue (Index, P);
1139 maxderivinvok = 0;
1140 InvalidateCache();
1141}
1142
1143//=======================================================================
1144//function : SetPole
1145//purpose :
1146//=======================================================================
1147
1148void Geom2d_BSplineCurve::SetPole
1149(const Standard_Integer Index,
1150 const gp_Pnt2d& P,
1151 const Standard_Real W)
1152{
1153 SetPole(Index,P);
1154 SetWeight(Index,W);
1155}
1156
1157//=======================================================================
1158//function : SetWeight
1159//purpose :
1160//=======================================================================
1161
1162void Geom2d_BSplineCurve::SetWeight
1163(const Standard_Integer Index,
1164 const Standard_Real W)
1165{
1166 if (Index < 1 || Index > poles->Length()) Standard_OutOfRange::Raise("BSpline curve : SetWeight: Index and #pole mismatch");
1167
1168 if (W <= gp::Resolution ()) Standard_ConstructionError::Raise("BSpline curve : SetWeight: Weight too small");
1169
1170
1171 Standard_Boolean rat = IsRational() || (Abs(W - 1.) > gp::Resolution());
1172
1173 if ( rat) {
1174 if (rat && !IsRational()) {
1175 weights = new TColStd_HArray1OfReal(1,poles->Length());
1176 weights->Init(1.);
1177 }
1178
1179 weights->SetValue (Index, W);
1180
1181 if (IsRational()) {
1182 rat = Rational(weights->Array1());
1183 if (!rat) weights.Nullify();
1184 }
1185
1186 rational = !weights.IsNull();
1187 }
1188
1189 maxderivinvok = 0;
1190 InvalidateCache() ;
1191}
1192
1193//=======================================================================
1194//function : MovePoint
1195//purpose :
1196//=======================================================================
1197
1198void Geom2d_BSplineCurve::MovePoint(const Standard_Real U,
1199 const gp_Pnt2d& P,
1200 const Standard_Integer Index1,
1201 const Standard_Integer Index2,
1202 Standard_Integer& FirstModifiedPole,
1203 Standard_Integer& LastmodifiedPole)
1204{
1205 if (Index1 < 1 || Index1 > poles->Length() ||
1206 Index2 < 1 || Index2 > poles->Length() || Index1 > Index2) {
1207 Standard_OutOfRange::Raise("BSpline curve : MovePoint: Index and #pole mismatch");
1208 }
1209 TColgp_Array1OfPnt2d npoles(1, poles->Length());
1210 gp_Pnt2d P0;
1211 D0(U, P0);
1212 gp_Vec2d Displ(P0, P);
1213 BSplCLib::MovePoint(U, Displ, Index1, Index2, deg, rational, poles->Array1(),
1214 weights->Array1(), flatknots->Array1(),
1215 FirstModifiedPole, LastmodifiedPole, npoles);
1216 if (FirstModifiedPole) {
1217 poles->ChangeArray1() = npoles;
1218 maxderivinvok = 0;
1219 InvalidateCache() ;
1220 }
1221}
1222
1223//=======================================================================
1224//function : MovePointAndTangent
1225//purpose :
1226//=======================================================================
1227
1228void Geom2d_BSplineCurve::
1229MovePointAndTangent(const Standard_Real U,
1230 const gp_Pnt2d& P,
1231 const gp_Vec2d& Tangent,
1232 const Standard_Real Tolerance,
1233 const Standard_Integer StartingCondition,
1234 const Standard_Integer EndingCondition,
1235 Standard_Integer& ErrorStatus)
1236{
1237 Standard_Integer ii ;
1238 if (IsPeriodic()) {
1239 //
1240 // for the time being do not deal with periodic curves
1241 //
1242 SetNotPeriodic() ;
1243 }
1244 TColgp_Array1OfPnt2d new_poles(1, poles->Length());
1245 gp_Pnt2d P0;
1246
1247
1248 gp_Vec2d delta_derivative;
1249 D1(U, P0,
1250 delta_derivative) ;
1251 gp_Vec2d delta(P0, P);
1252 for (ii = 1 ; ii <= 2 ; ii++) {
1253 delta_derivative.SetCoord(ii,
1254 Tangent.Coord(ii)- delta_derivative.Coord(ii)) ;
1255 }
1256 BSplCLib::MovePointAndTangent(U,
1257 delta,
1258 delta_derivative,
1259 Tolerance,
1260 deg,
1261 rational,
1262 StartingCondition,
1263 EndingCondition,
1264 poles->Array1(),
1265 weights->Array1(),
1266 flatknots->Array1(),
1267 new_poles,
1268 ErrorStatus) ;
1269 if (!ErrorStatus) {
1270 poles->ChangeArray1() = new_poles;
1271 maxderivinvok = 0;
1272 InvalidateCache() ;
1273 }
1274}
1275
1276//=======================================================================
1277//function : UpdateKnots
1278//purpose :
1279//=======================================================================
1280
1281void Geom2d_BSplineCurve::UpdateKnots()
1282{
1283
1284 rational = !weights.IsNull();
1285
1286 Standard_Integer MaxKnotMult = 0;
1287 KnotAnalysis (deg,
1288 periodic,
1289 knots->Array1(),
1290 mults->Array1(),
1291 knotSet, MaxKnotMult);
1292
1293 if (knotSet == GeomAbs_Uniform && !periodic) {
1294 flatknots = knots;
1295 }
1296 else {
1297 flatknots = new TColStd_HArray1OfReal
1298 (1, BSplCLib::KnotSequenceLength(mults->Array1(),deg,periodic));
1299
1300 BSplCLib::KnotSequence (knots->Array1(),
1301 mults->Array1(),
1302 deg,periodic,
1303 flatknots->ChangeArray1());
1304 }
1305
1306 if (MaxKnotMult == 0) smooth = GeomAbs_CN;
1307 else {
1308 switch (deg - MaxKnotMult) {
1309 case 0 : smooth = GeomAbs_C0; break;
1310 case 1 : smooth = GeomAbs_C1; break;
1311 case 2 : smooth = GeomAbs_C2; break;
1312 case 3 : smooth = GeomAbs_C3; break;
1313 default : smooth = GeomAbs_C3; break;
1314 }
1315 }
1316 InvalidateCache() ;
1317}
1318
1319//=======================================================================
1320//function : Invalidate the Cache
1321//purpose : as the name says
1322//=======================================================================
1323
1324void Geom2d_BSplineCurve::InvalidateCache()
1325{
1326 validcache = 0 ;
1327}
1328
1329//=======================================================================
1330//function : check if the Cache is valid
1331//purpose : as the name says
1332//=======================================================================
1333
1334Standard_Boolean Geom2d_BSplineCurve::IsCacheValid
1335(const Standard_Real U) const
1336{
1337 //Roman Lygin 26.12.08, see comments in Geom_BSplineCurve::IsCacheValid()
1338 Standard_Real aDelta = U - parametercache;
1339
1340 return ( validcache &&
1341 (aDelta >= 0.0e0) &&
1342 ((aDelta < spanlenghtcache) || (spanindexcache == flatknots->Upper() - deg)) );
1343}
1344
1345//=======================================================================
1346//function : Normalizes the parameters if the curve is periodic
1347//purpose : that is compute the cache so that it is valid
1348//=======================================================================
1349
1350void Geom2d_BSplineCurve::PeriodicNormalization(Standard_Real& Parameter) const
1351{
1352 Standard_Real Period ;
1353
1354 if (periodic) {
1355 Period = flatknots->Value(flatknots->Upper() - deg) - flatknots->Value (deg + 1) ;
1356 while (Parameter > flatknots->Value(flatknots->Upper()-deg)) {
1357 Parameter -= Period ;
1358 }
1359 while (Parameter < flatknots->Value((deg + 1))) {
1360 Parameter += Period ;
1361 }
1362 }
1363}
1364
1365//=======================================================================
1366//function : Validate the Cache
1367//purpose : that is compute the cache so that it is valid
1368//=======================================================================
1369
1370void Geom2d_BSplineCurve::ValidateCache(const Standard_Real Parameter)
1371{
1372 Standard_Real NewParameter ;
1373 Standard_Integer LocalIndex = 0 ;
1374 //
1375 // check if the degree did not change
1376 //
1377 if (cachepoles->Upper() < deg + 1) {
1378 cachepoles = new TColgp_HArray1OfPnt2d(1,deg + 1);
1379 if (rational) {
1380 cacheweights = new TColStd_HArray1OfReal(1,deg + 1);
1381 }
1382 }
1383
1384 BSplCLib::LocateParameter(deg,
1385 (flatknots->Array1()),
1386 (BSplCLib::NoMults()),
1387 Parameter,
1388 periodic,
1389 LocalIndex,
1390 NewParameter);
1391 spanindexcache = LocalIndex ;
1392 if (Parameter == flatknots->Value(LocalIndex + 1)) {
1393
1394 LocalIndex += 1 ;
1395 parametercache = flatknots->Value(LocalIndex) ;
1396 if (LocalIndex == flatknots->Upper() - deg) {
1397 //
1398 // for the last span if the parameter is outside of
1399 // the domain of the curve than use the last knot
1400 // and normalize with the last span Still set the
1401 // spanindexcache to flatknots->Upper() - deg so that
1402 // the IsCacheValid will know for sure we are extending
1403 // the Bspline
1404 //
1405
1406 spanlenghtcache = flatknots->Value(LocalIndex - 1) - parametercache ;
1407 }
1408 else {
1409 spanlenghtcache = flatknots->Value(LocalIndex + 1) - parametercache ;
1410 }
1411 }
1412 else {
1413 parametercache = flatknots->Value(LocalIndex) ;
1414 spanlenghtcache = flatknots->Value(LocalIndex + 1) - parametercache ;
1415 }
1416
1417 if (rational) {
1418 BSplCLib::BuildCache(parametercache,
1419 spanlenghtcache,
1420 periodic,
1421 deg,
1422 (flatknots->Array1()),
1423 poles->Array1(),
1424 weights->Array1(),
1425 cachepoles->ChangeArray1(),
1426 cacheweights->ChangeArray1()) ;
1427 }
1428 else {
1429 BSplCLib::BuildCache(parametercache,
1430 spanlenghtcache,
1431 periodic,
1432 deg,
1433 (flatknots->Array1()),
1434 poles->Array1(),
1435 *((TColStd_Array1OfReal*) NULL),
1436 cachepoles->ChangeArray1(),
1437 *((TColStd_Array1OfReal*) NULL)) ;
1438 }
1439 validcache = 1 ;
1440}
1441