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