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