1 // Created on: 1995-10-20
2 // Created by: Laurent BOURESCHE
3 // Copyright (c) 1995-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
6 // This file is part of Open CASCADE Technology software library.
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
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.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
17 // Cut and past sauvage depuis Geom!?!?
18 // 14-Mar-96 : xab implemented MovePointAndTangent
19 // 03-02-97 : pmn ->LocateU sur Periodic (PRO6963),
20 // bon appel a LocateParameter (PRO6973) et mise en conformite avec
21 // le cdl de LocateU, lorsque U est un noeud (PRO6988)
23 #include <BSplCLib.hxx>
24 #include <BSplCLib_KnotDistribution.hxx>
25 #include <BSplCLib_MultDistribution.hxx>
27 #include <Law_BSpline.hxx>
28 #include <Standard_ConstructionError.hxx>
29 #include <Standard_DimensionError.hxx>
30 #include <Standard_DomainError.hxx>
31 #include <Standard_NoSuchObject.hxx>
32 #include <Standard_NotImplemented.hxx>
33 #include <Standard_OutOfRange.hxx>
34 #include <Standard_RangeError.hxx>
35 #include <Standard_Type.hxx>
37 IMPLEMENT_STANDARD_RTTIEXT(Law_BSpline,Standard_Transient)
39 #define POLES (poles->Array1())
40 #define KNOTS (knots->Array1())
41 #define FKNOTS (flatknots->Array1())
42 #define FMULTS (BSplCLib::NoMults())
44 //=======================================================================
47 //=======================================================================
49 static void SetPoles(const TColStd_Array1OfReal& Poles,
50 const TColStd_Array1OfReal& Weights,
51 TColStd_Array1OfReal& FP)
53 Standard_Integer i,j = FP.Lower();
54 for (i = Poles.Lower(); i <= Poles.Upper(); i++) {
55 Standard_Real w = Weights(i);
64 //=======================================================================
67 //=======================================================================
69 static void GetPoles(const TColStd_Array1OfReal& FP,
70 TColStd_Array1OfReal& Poles,
71 TColStd_Array1OfReal& Weights)
74 Standard_Integer i,j = FP.Lower();
75 for (i = Poles.Lower(); i <= Poles.Upper(); i++) {
76 Standard_Real w = FP(j+1);
84 //=======================================================================
85 //function : CheckCurveData
86 //purpose : Internal use only
87 //=======================================================================
89 static void CheckCurveData
90 (const TColStd_Array1OfReal& CPoles,
91 const TColStd_Array1OfReal& CKnots,
92 const TColStd_Array1OfInteger& CMults,
93 const Standard_Integer Degree,
94 const Standard_Boolean Periodic)
96 if (Degree < 1 || Degree > Law_BSpline::MaxDegree()) {
97 throw Standard_ConstructionError();
100 if (CPoles.Length() < 2) throw Standard_ConstructionError();
101 if (CKnots.Length() != CMults.Length()) throw Standard_ConstructionError();
103 for (Standard_Integer I = CKnots.Lower(); I < CKnots.Upper(); I++) {
104 if (CKnots (I+1) - CKnots (I) <= Epsilon (Abs(CKnots (I)))) {
105 throw Standard_ConstructionError();
109 if (CPoles.Length() != BSplCLib::NbPoles(Degree,Periodic,CMults))
110 throw Standard_ConstructionError();
114 //=======================================================================
115 //function : KnotAnalysis
116 //purpose : Internal use only
117 //=======================================================================
119 static void KnotAnalysis
120 (const Standard_Integer Degree,
121 const Standard_Boolean Periodic,
122 const TColStd_Array1OfReal& CKnots,
123 const TColStd_Array1OfInteger& CMults,
124 GeomAbs_BSplKnotDistribution& KnotForm,
125 Standard_Integer& MaxKnotMult)
127 KnotForm = GeomAbs_NonUniform;
129 BSplCLib_KnotDistribution KSet =
130 BSplCLib::KnotForm (CKnots, 1, CKnots.Length());
133 if (KSet == BSplCLib_Uniform) {
134 BSplCLib_MultDistribution MSet =
135 BSplCLib::MultForm (CMults, 1, CMults.Length());
137 case BSplCLib_NonConstant :
139 case BSplCLib_Constant :
140 if (CKnots.Length() == 2) {
141 KnotForm = GeomAbs_PiecewiseBezier;
144 if (CMults (1) == 1) KnotForm = GeomAbs_Uniform;
147 case BSplCLib_QuasiConstant :
148 if (CMults (1) == Degree + 1) {
149 Standard_Real M = CMults (2);
150 if (M == Degree ) KnotForm = GeomAbs_PiecewiseBezier;
151 else if (M == 1) KnotForm = GeomAbs_QuasiUniform;
157 Standard_Integer FirstKM =
158 Periodic ? CKnots.Lower() : BSplCLib::FirstUKnotIndex (Degree,CMults);
159 Standard_Integer LastKM =
160 Periodic ? CKnots.Upper() : BSplCLib::LastUKnotIndex (Degree,CMults);
162 if (LastKM - FirstKM != 1) {
163 Standard_Integer Multi;
164 for (Standard_Integer i = FirstKM + 1; i < LastKM; i++) {
166 MaxKnotMult = Max (MaxKnotMult, Multi);
172 //=======================================================================
173 //function : Rational
174 //purpose : check rationality of an array of weights
175 //=======================================================================
177 static Standard_Boolean Rational(const TColStd_Array1OfReal& W)
179 Standard_Integer i, n = W.Length();
180 Standard_Boolean rat = Standard_False;
181 for (i = 1; i < n; i++) {
182 rat = Abs(W(i) - W(i+1)) > gp::Resolution();
188 //=======================================================================
191 //=======================================================================
193 Handle(Law_BSpline) Law_BSpline::Copy() const
195 Handle(Law_BSpline) C;
197 C = new Law_BSpline(poles->Array1(),
203 C = new Law_BSpline(poles->Array1(),
212 //=======================================================================
213 //function : Law_BSpline
215 //=======================================================================
217 Law_BSpline::Law_BSpline
218 (const TColStd_Array1OfReal& Poles,
219 const TColStd_Array1OfReal& Knots,
220 const TColStd_Array1OfInteger& Mults,
221 const Standard_Integer Degree,
222 const Standard_Boolean Periodic) :
223 rational(Standard_False),periodic(Periodic), deg(Degree)
227 CheckCurveData (Poles,
236 poles = new TColStd_HArray1OfReal(1,Poles.Length());
237 poles->ChangeArray1() = Poles;
240 knots = new TColStd_HArray1OfReal(1,Knots.Length());
241 knots->ChangeArray1() = Knots;
243 mults = new TColStd_HArray1OfInteger(1,Mults.Length());
244 mults->ChangeArray1() = Mults;
251 //=======================================================================
252 //function : Law_BSpline
254 //=======================================================================
256 Law_BSpline::Law_BSpline
257 (const TColStd_Array1OfReal& Poles,
258 const TColStd_Array1OfReal& Weights,
259 const TColStd_Array1OfReal& Knots,
260 const TColStd_Array1OfInteger& Mults,
261 const Standard_Integer Degree,
262 const Standard_Boolean Periodic) :
263 rational(Standard_True), periodic(Periodic), deg(Degree)
269 CheckCurveData (Poles,
275 if (Weights.Length() != Poles.Length())
276 throw Standard_ConstructionError("Law_BSpline");
279 for (i = Weights.Lower(); i <= Weights.Upper(); i++) {
280 if (Weights(i) <= gp::Resolution())
281 throw Standard_ConstructionError("Law_BSpline");
284 // check really rational
285 rational = Rational(Weights);
289 poles = new TColStd_HArray1OfReal(1,Poles.Length());
290 poles->ChangeArray1() = Poles;
292 weights = new TColStd_HArray1OfReal(1,Weights.Length());
293 weights->ChangeArray1() = Weights;
296 knots = new TColStd_HArray1OfReal(1,Knots.Length());
297 knots->ChangeArray1() = Knots;
299 mults = new TColStd_HArray1OfInteger(1,Mults.Length());
300 mults->ChangeArray1() = Mults;
306 //=======================================================================
307 //function : MaxDegree
309 //=======================================================================
311 Standard_Integer Law_BSpline::MaxDegree ()
313 return BSplCLib::MaxDegree();
317 //=======================================================================
318 //function : IncreaseDegree
320 //=======================================================================
322 void Law_BSpline::IncreaseDegree (const Standard_Integer Degree)
324 if (Degree == deg) return;
326 if (Degree < deg || Degree > Law_BSpline::MaxDegree()) {
327 throw Standard_ConstructionError();
330 Standard_Integer FromK1 = FirstUKnotIndex ();
331 Standard_Integer ToK2 = LastUKnotIndex ();
333 Standard_Integer Step = Degree - deg;
335 Handle(TColStd_HArray1OfReal) npoles = new
336 TColStd_HArray1OfReal(1,poles->Length() + Step * (ToK2-FromK1));
338 Standard_Integer nbknots = BSplCLib::IncreaseDegreeCountKnots
339 (deg,Degree,periodic,mults->Array1());
341 Handle(TColStd_HArray1OfReal) nknots =
342 new TColStd_HArray1OfReal(1,nbknots);
344 Handle(TColStd_HArray1OfInteger) nmults =
345 new TColStd_HArray1OfInteger(1,nbknots);
347 Handle(TColStd_HArray1OfReal) nweights;
350 nweights = new TColStd_HArray1OfReal(1,npoles->Upper());
351 TColStd_Array1OfReal adimpol(1,2*poles->Upper());
352 SetPoles(poles->Array1(),weights->Array1(),adimpol);
353 TColStd_Array1OfReal adimnpol(1,2*npoles->Upper());
354 BSplCLib::IncreaseDegree
355 (deg,Degree, periodic,2,adimpol,
356 knots->Array1(),mults->Array1(),adimnpol,
357 nknots->ChangeArray1(),nmults->ChangeArray1());
358 GetPoles(adimnpol,npoles->ChangeArray1(),nweights->ChangeArray1());
361 BSplCLib::IncreaseDegree
362 (deg,Degree, periodic,1,poles->Array1(),
363 knots->Array1(),mults->Array1(),npoles->ChangeArray1(),
364 nknots->ChangeArray1(),nmults->ChangeArray1());
377 //=======================================================================
378 //function : IncreaseMultiplicity
380 //=======================================================================
382 void Law_BSpline::IncreaseMultiplicity (const Standard_Integer Index,
383 const Standard_Integer M)
385 TColStd_Array1OfReal k(1,1);
386 k(1) = knots->Value(Index);
387 TColStd_Array1OfInteger m(1,1);
388 m(1) = M - mults->Value(Index);
389 InsertKnots(k,m,Epsilon(1.));
393 //=======================================================================
394 //function : IncreaseMultiplicity
396 //=======================================================================
398 void Law_BSpline::IncreaseMultiplicity (const Standard_Integer I1,
399 const Standard_Integer I2,
400 const Standard_Integer M)
402 Handle(TColStd_HArray1OfReal) tk = knots;
403 TColStd_Array1OfReal k((knots->Array1())(I1),I1,I2);
404 TColStd_Array1OfInteger m(I1,I2);
406 for (i = I1; i <= I2; i++)
407 m(i) = M - mults->Value(i);
408 InsertKnots(k,m,Epsilon(1.));
411 //=======================================================================
412 //function : IncrementMultiplicity
414 //=======================================================================
416 void Law_BSpline::IncrementMultiplicity
417 (const Standard_Integer I1,
418 const Standard_Integer I2,
419 const Standard_Integer Step)
421 Handle(TColStd_HArray1OfReal) tk = knots;
422 TColStd_Array1OfReal k((knots->Array1())(I1),I1,I2);
423 TColStd_Array1OfInteger m(I1,I2) ;
425 InsertKnots(k,m,Epsilon(1.));
429 //=======================================================================
430 //function : InsertKnot
432 //=======================================================================
434 void Law_BSpline::InsertKnot
435 (const Standard_Real U,
436 const Standard_Integer M,
437 const Standard_Real ParametricTolerance,
438 const Standard_Boolean Add)
440 TColStd_Array1OfReal k(1,1);
442 TColStd_Array1OfInteger m(1,1);
444 InsertKnots(k,m,ParametricTolerance,Add);
447 //=======================================================================
448 //function : InsertKnots
450 //=======================================================================
452 void Law_BSpline::InsertKnots(const TColStd_Array1OfReal& Knots,
453 const TColStd_Array1OfInteger& Mults,
454 const Standard_Real Epsilon,
455 const Standard_Boolean Add)
457 // Check and compute new sizes
458 Standard_Integer nbpoles,nbknots;
460 if (!BSplCLib::PrepareInsertKnots(deg,periodic,
461 knots->Array1(),mults->Array1(),
462 Knots,&Mults,nbpoles,nbknots,Epsilon,Add))
463 throw Standard_ConstructionError("Law_BSpline::InsertKnots");
465 if (nbpoles == poles->Length()) return;
467 Handle(TColStd_HArray1OfReal) npoles = new TColStd_HArray1OfReal(1,nbpoles);
468 Handle(TColStd_HArray1OfReal) nknots = knots;
469 Handle(TColStd_HArray1OfInteger) nmults = mults;
471 if (nbknots != knots->Length()) {
472 nknots = new TColStd_HArray1OfReal(1,nbknots);
473 nmults = new TColStd_HArray1OfInteger(1,nbknots);
477 Handle(TColStd_HArray1OfReal) nweights =
478 new TColStd_HArray1OfReal(1,nbpoles);
479 TColStd_Array1OfReal adimpol(1,2*poles->Upper());
480 SetPoles(poles->Array1(),weights->Array1(),adimpol);
481 TColStd_Array1OfReal adimnpol(1,2*npoles->Upper());
482 BSplCLib::InsertKnots(deg,periodic,2,adimpol,
483 knots->Array1(), mults->Array1(),
484 Knots, &Mults,adimnpol,
485 nknots->ChangeArray1(), nmults->ChangeArray1(),
487 GetPoles(adimnpol,npoles->ChangeArray1(),nweights->ChangeArray1());
491 BSplCLib::InsertKnots(deg,periodic,1,poles->Array1(),
492 knots->Array1(), mults->Array1(),
494 npoles->ChangeArray1(),
495 nknots->ChangeArray1(), nmults->ChangeArray1(),
506 //=======================================================================
507 //function : RemoveKnot
509 //=======================================================================
511 Standard_Boolean Law_BSpline::RemoveKnot(const Standard_Integer Index,
512 const Standard_Integer M,
513 const Standard_Real Tolerance)
515 if (M < 0) return Standard_True;
517 Standard_Integer I1 = FirstUKnotIndex ();
518 Standard_Integer I2 = LastUKnotIndex ();
520 if ( !periodic && (Index <= I1 || Index >= I2) ) {
521 throw Standard_OutOfRange();
523 else if ( periodic && (Index < I1 || Index > I2)) {
524 throw Standard_OutOfRange();
527 const TColStd_Array1OfReal & oldpoles = poles->Array1();
528 Standard_Integer step = mults->Value(Index) - M;
529 if (step <= 0) return Standard_True;
531 Handle(TColStd_HArray1OfReal) npoles =
532 new TColStd_HArray1OfReal(1,oldpoles.Length()-step);
534 Handle(TColStd_HArray1OfReal) nknots = knots;
535 Handle(TColStd_HArray1OfInteger) nmults = mults;
538 nknots = new TColStd_HArray1OfReal(1,knots->Length()-1);
539 nmults = new TColStd_HArray1OfInteger(1,knots->Length()-1);
543 Handle(TColStd_HArray1OfReal) nweights =
544 new TColStd_HArray1OfReal(1,npoles->Length());
545 TColStd_Array1OfReal adimpol(1,2*poles->Upper());
546 SetPoles(poles->Array1(),weights->Array1(),adimpol);
547 TColStd_Array1OfReal adimnpol(1,2*npoles->Upper());
548 if (!BSplCLib::RemoveKnot(Index, M, deg, periodic,2,adimpol,
549 knots->Array1(),mults->Array1(),adimnpol,
550 nknots->ChangeArray1(),
551 nmults->ChangeArray1(),Tolerance))
552 return Standard_False;
553 GetPoles(adimnpol,npoles->ChangeArray1(),nweights->ChangeArray1());
557 if (!BSplCLib::RemoveKnot(Index, M, deg, periodic,1,poles->Array1(),
558 knots->Array1(),mults->Array1(),
559 npoles->ChangeArray1(), nknots->ChangeArray1(),
560 nmults->ChangeArray1(),Tolerance))
561 return Standard_False;
569 return Standard_True;
572 //----------------------------------------------------------------------
573 //----------------------------------------------------------------------
577 --- methodes otees du CDL -> spec trop vagues : on ne sait pas ou rajouter
580 //=======================================================================
581 //function : InsertPoleAfter
583 //=======================================================================
585 void Law_BSpline::InsertPoleAfter
586 (const Standard_Integer Index,
587 const Standard_Real& P)
589 InsertPoleAfter(Index,P,1.);
594 //=======================================================================
595 //function : InsertPoleAfter
597 //=======================================================================
599 void Law_BSpline::InsertPoleAfter
600 (const Standard_Integer Index,
601 const Standard_Real& P,
602 const Standard_Real Weight)
604 if (Index < 0 || Index > poles->Length()) throw Standard_OutOfRange();
606 if (Weight <= gp::Resolution()) throw Standard_ConstructionError();
609 // find the spans which are modified with the inserting pole
610 // --> evaluate NewKnot & KnotIndex : Value of the new knot to insert.
611 Standard_Integer KnotIndex, k, sigma;
612 Standard_Real NewKnot;
617 while ( sigma < Index) {
618 sigma += mults->Value(k);
622 NewKnot = ( knots->Value(KnotIndex) + knots->Value(KnotIndex+1)) / 2.;
627 while ( sigma < Index) {
628 sigma += mults->Value(k);
631 Standard_Integer first = k - 1;
633 while ( sigma < (deg+1)) {
634 sigma += mults->Value(k);
637 Standard_Integer last = k - 1;
639 KnotIndex = first + (( last - first) / 2);
640 NewKnot = ( knots->Value(KnotIndex) + knots->Value(KnotIndex+1)) / 2.;
643 Standard_Integer nbknots = knots->Length();
644 Handle(TColStd_HArray1OfReal) nknots =
645 new TColStd_HArray1OfReal(1,nbknots+1);
646 TColStd_Array1OfReal& newknots = nknots->ChangeArray1();
647 Handle(TColStd_HArray1OfInteger) nmults =
648 new TColStd_HArray1OfInteger(1,nbknots+1);
649 TColStd_Array1OfInteger& newmults = nmults->ChangeArray1();
654 for ( i = 1; i<= KnotIndex; i++) {
655 newknots(i) = knots->Value(i);
656 newmults(i) = mults->Value(i);
658 newknots(KnotIndex+1) = NewKnot;
659 newmults(KnotIndex+1) = 1;
660 for ( i = KnotIndex+1; i <= nbknots; i++) {
661 newknots(i+1) = knots->Value(i);
662 newmults(i+1) = mults->Value(i);
665 Standard_Integer nbpoles = poles->Length();
666 Handle(TColStd_HArray1OfReal) npoles =
667 new TColStd_HArray1OfReal(1,nbpoles+1);
668 TColStd_Array1OfReal& newpoles = npoles->ChangeArray1();
672 for (i = 1; i <= Index; i++)
673 newpoles(i) = poles->Value(i);
675 newpoles(Index+1) = P;
677 for (i = Index+1; i <= nbpoles; i++)
678 newpoles(i+1) = poles->Value(i);
682 Handle(TColStd_HArray1OfReal) nweights;
683 Standard_Boolean rat = IsRational() || Abs(Weight-1.) > gp::Resolution();
686 nweights = new TColStd_HArray1OfReal(1,nbpoles+1);
687 TColStd_Array1OfReal& newweights = nweights->ChangeArray1();
689 for (i = 1; i <= Index; i++)
691 newweights(i) = weights->Value(i);
695 newweights(Index+1) = Weight;
697 for (i = Index+1; i <= nbpoles; i++)
699 newweights(i+1) = weights->Value(i);
701 newweights(i+1) = 1.;
712 //=======================================================================
713 //function : InsertPoleBefore
715 //=======================================================================
717 void Law_BSpline::InsertPoleBefore
718 (const Standard_Integer Index,
719 const Standard_Real& P )
721 InsertPoleAfter(Index-1,P,1.);
726 //=======================================================================
727 //function : InsertPoleBefore
729 //=======================================================================
731 void Law_BSpline::InsertPoleBefore
732 (const Standard_Integer Index,
733 const Standard_Real& P,
734 const Standard_Real Weight)
736 InsertPoleAfter(Index-1,P,Weight);
739 //=======================================================================
740 //function : RemovePole
742 //=======================================================================
744 void Law_BSpline::RemovePole
745 (const Standard_Integer Index)
747 if (Index < 1 || Index > poles->Length()) throw Standard_OutOfRange();
749 if (poles->Length() <= 2) throw Standard_ConstructionError();
751 if (knotSet == GeomAbs_NonUniform || knotSet == GeomAbs_PiecewiseBezier)
752 throw Standard_ConstructionError();
755 Handle(TColStd_HArray1OfReal) nknots =
756 new TColStd_HArray1OfReal(1,knots->Length()-1);
757 TColStd_Array1OfReal& newknots = nknots->ChangeArray1();
759 Handle(TColStd_HArray1OfInteger) nmults =
760 new TColStd_HArray1OfInteger(1,mults->Length()-1);
761 TColStd_Array1OfInteger& newmults = nmults->ChangeArray1();
763 for (i = 1; i < newknots.Length(); i++) {
764 newknots (i) = knots->Value (i);
767 newmults(1) = mults->Value(1);
768 newknots(newknots.Upper()) = knots->Value (knots->Upper());
769 newmults(newmults.Upper()) = mults->Value (mults->Upper());
772 Handle(TColStd_HArray1OfReal) npoles =
773 new TColStd_HArray1OfReal(1, poles->Upper()-1);
774 TColStd_Array1OfReal& newpoles = npoles->ChangeArray1();
776 for (i = 1; i < Index; i++)
777 newpoles(i) = poles->Value(i);
778 for (i = Index; i < newpoles.Length(); i++)
779 newpoles(i) = poles->Value(i+1);
781 Handle(TColStd_HArray1OfReal) nweights;
783 nweights = new TColStd_HArray1OfReal(1,newpoles.Length());
784 TColStd_Array1OfReal& newweights = nweights->ChangeArray1();
785 for (i = 1; i < Index; i++)
786 newweights(i) = weights->Value(i);
787 for (i = Index; i < newweights.Length(); i++)
788 newweights(i) = weights->Value(i+1);
804 //=======================================================================
807 //=======================================================================
809 void Law_BSpline::Reverse ()
811 BSplCLib::Reverse(knots->ChangeArray1());
812 BSplCLib::Reverse(mults->ChangeArray1());
813 Standard_Integer last;
815 last = flatknots->Upper() - deg - 1;
817 last = poles->Upper();
818 BSplCLib::Reverse(poles->ChangeArray1(),last);
820 BSplCLib::Reverse(weights->ChangeArray1(),last);
825 //=======================================================================
826 //function : ReversedParameter
828 //=======================================================================
830 Standard_Real Law_BSpline::ReversedParameter
831 (const Standard_Real U) const
833 return (FirstParameter() + LastParameter() - U);
837 //=======================================================================
840 //=======================================================================
842 void Law_BSpline::Segment(const Standard_Real U1,
843 const Standard_Real U2)
845 Standard_DomainError_Raise_if ( U2 < U1,
846 "Law_BSpline::Segment");
847 Standard_Real Eps = Epsilon(Max(Abs(U1),Abs(U2)));
848 Standard_Real delta = U2 - U1;
850 Standard_Real NewU1, NewU2;
852 Standard_Integer index;
854 TColStd_Array1OfReal Knots(1,2);
855 TColStd_Array1OfInteger Mults(1,2);
858 BSplCLib::LocateParameter(deg,knots->Array1(),mults->Array1(),
859 U1,periodic,knots->Lower(),knots->Upper(),
862 BSplCLib::LocateParameter(deg,knots->Array1(),mults->Array1(),
863 U2,periodic,knots->Lower(),knots->Upper(),
865 Knots( 1) = Min( NewU1, NewU2);
866 Knots( 2) = Max( NewU1, NewU2);
867 Mults( 1) = Mults( 2) = deg;
868 InsertKnots( Knots, Mults, Eps);
870 if (periodic) { // set the origine at NewU1
871 Standard_Integer index0 = 0;
872 BSplCLib::LocateParameter(deg,knots->Array1(),mults->Array1(),
873 U1,periodic,knots->Lower(),knots->Upper(),
875 if ( Abs(knots->Value(index0+1)-U) < Eps)
881 // compute index1 and index2 to set the new knots and mults
882 Standard_Integer index1 = 0, index2 = 0;
883 Standard_Integer FromU1 = knots->Lower();
884 Standard_Integer ToU2 = knots->Upper();
885 BSplCLib::LocateParameter(deg,knots->Array1(),mults->Array1(),
886 NewU1,periodic,FromU1,ToU2,index1,U);
887 BSplCLib::LocateParameter(deg,knots->Array1(),mults->Array1(),
888 NewU1 + delta,periodic,FromU1,ToU2,index2,U);
889 if ( Abs(knots->Value(index2+1)-U) < Eps)
892 Standard_Integer nbknots = index2 - index1 + 1;
894 Handle(TColStd_HArray1OfReal)
895 nknots = new TColStd_HArray1OfReal(1,nbknots);
896 Handle(TColStd_HArray1OfInteger)
897 nmults = new TColStd_HArray1OfInteger(1,nbknots);
899 Standard_Integer i , k = 1;
900 for ( i = index1; i<= index2; i++) {
901 nknots->SetValue(k, knots->Value(i));
902 nmults->SetValue(k, mults->Value(i));
905 nmults->SetValue( 1, deg + 1);
906 nmults->SetValue(nbknots, deg + 1);
909 // compute index1 and index2 to set the new poles and weights
910 Standard_Integer pindex1
911 = BSplCLib::PoleIndex(deg,index1,periodic,mults->Array1());
912 Standard_Integer pindex2
913 = BSplCLib::PoleIndex(deg,index2,periodic,mults->Array1());
916 pindex2 = Min( pindex2+1, poles->Length());
918 Standard_Integer nbpoles = pindex2 - pindex1 + 1;
920 Handle(TColStd_HArray1OfReal)
921 nweights = new TColStd_HArray1OfReal(1,nbpoles);
922 Handle(TColStd_HArray1OfReal)
923 npoles = new TColStd_HArray1OfReal(1,nbpoles);
927 nweights = new TColStd_HArray1OfReal( 1, nbpoles);
928 for ( i = pindex1; i <= pindex2; i++) {
929 npoles->SetValue(k, poles->Value(i));
930 nweights->SetValue(k, weights->Value(i));
935 for ( i = pindex1; i <= pindex2; i++) {
936 npoles->SetValue(k, poles->Value(i));
951 //=======================================================================
954 //=======================================================================
956 void Law_BSpline::SetKnot
957 (const Standard_Integer Index,
958 const Standard_Real K)
960 if (Index < 1 || Index > knots->Length()) throw Standard_OutOfRange();
961 Standard_Real DK = Abs(Epsilon (K));
963 if (K >= knots->Value(2) - DK) throw Standard_ConstructionError();
965 else if (Index == knots->Length()) {
966 if (K <= knots->Value (knots->Length()-1) + DK) {
967 throw Standard_ConstructionError();
971 if (K <= knots->Value(Index-1) + DK ||
972 K >= knots->Value(Index+1) - DK ) {
973 throw Standard_ConstructionError();
976 if (K != knots->Value (Index)) {
977 knots->SetValue (Index, K);
983 //=======================================================================
984 //function : SetKnots
986 //=======================================================================
988 void Law_BSpline::SetKnots
989 (const TColStd_Array1OfReal& K)
991 CheckCurveData(poles->Array1(),K,mults->Array1(),deg,periodic);
992 knots->ChangeArray1() = K;
997 //=======================================================================
1000 //=======================================================================
1002 void Law_BSpline::SetKnot
1003 (const Standard_Integer Index,
1004 const Standard_Real K,
1005 const Standard_Integer M)
1007 IncreaseMultiplicity (Index, M);
1012 //=======================================================================
1013 //function : SetPeriodic
1015 //=======================================================================
1017 void Law_BSpline::SetPeriodic ()
1019 Standard_Integer first = FirstUKnotIndex();
1020 Standard_Integer last = LastUKnotIndex();
1022 Handle(TColStd_HArray1OfReal) tk = knots;
1023 TColStd_Array1OfReal cknots((knots->Array1())(first),first,last);
1024 knots = new TColStd_HArray1OfReal(1,cknots.Length());
1025 knots->ChangeArray1() = cknots;
1027 Handle(TColStd_HArray1OfInteger) tm = mults;
1028 TColStd_Array1OfInteger cmults((mults->Array1())(first),first,last);
1029 cmults(first) = cmults(last) = Max( cmults(first), cmults(last));
1030 mults = new TColStd_HArray1OfInteger(1,cmults.Length());
1031 mults->ChangeArray1() = cmults;
1033 // compute new number of poles;
1034 Standard_Integer nbp = BSplCLib::NbPoles(deg,Standard_True,cmults);
1036 Handle(TColStd_HArray1OfReal) tp = poles;
1037 TColStd_Array1OfReal cpoles((poles->Array1())(1),1,nbp);
1038 poles = new TColStd_HArray1OfReal(1,nbp);
1039 poles->ChangeArray1() = cpoles;
1042 Handle(TColStd_HArray1OfReal) tw = weights;
1043 TColStd_Array1OfReal cweights((weights->Array1())(1),1,nbp);
1044 weights = new TColStd_HArray1OfReal(1,nbp);
1045 weights->ChangeArray1() = cweights;
1048 periodic = Standard_True;
1054 //=======================================================================
1055 //function : SetOrigin
1057 //=======================================================================
1059 void Law_BSpline::SetOrigin(const Standard_Integer Index)
1061 Standard_NoSuchObject_Raise_if( !periodic,
1062 "Law_BSpline::SetOrigin");
1063 Standard_Integer i,k;
1064 Standard_Integer first = FirstUKnotIndex();
1065 Standard_Integer last = LastUKnotIndex();
1067 Standard_DomainError_Raise_if( (Index < first) || (Index > last),
1068 "Law_BSpline::SetOrigine");
1070 Standard_Integer nbknots = knots->Length();
1071 Standard_Integer nbpoles = poles->Length();
1073 Handle(TColStd_HArray1OfReal) nknots =
1074 new TColStd_HArray1OfReal(1,nbknots);
1075 TColStd_Array1OfReal& newknots = nknots->ChangeArray1();
1077 Handle(TColStd_HArray1OfInteger) nmults =
1078 new TColStd_HArray1OfInteger(1,nbknots);
1079 TColStd_Array1OfInteger& newmults = nmults->ChangeArray1();
1081 // set the knots and mults
1082 Standard_Real period = knots->Value(last) - knots->Value(first);
1084 for ( i = Index; i <= last ; i++) {
1085 newknots(k) = knots->Value(i);
1086 newmults(k) = mults->Value(i);
1089 for ( i = first+1; i <= Index; i++) {
1090 newknots(k) = knots->Value(i) + period;
1091 newmults(k) = mults->Value(i);
1095 Standard_Integer index = 1;
1096 for (i = first+1; i <= Index; i++)
1097 index += mults->Value(i);
1099 // set the poles and weights
1100 Handle(TColStd_HArray1OfReal) npoles =
1101 new TColStd_HArray1OfReal(1,nbpoles);
1102 Handle(TColStd_HArray1OfReal) nweights =
1103 new TColStd_HArray1OfReal(1,nbpoles);
1104 TColStd_Array1OfReal & newpoles = npoles->ChangeArray1();
1105 TColStd_Array1OfReal & newweights = nweights->ChangeArray1();
1106 first = poles->Lower();
1107 last = poles->Upper();
1110 for ( i = index; i <= last; i++) {
1111 newpoles(k) = poles->Value(i);
1112 newweights(k) = weights->Value(i);
1115 for ( i = first; i < index; i++) {
1116 newpoles(k) = poles->Value(i);
1117 newweights(k) = weights->Value(i);
1123 for ( i = index; i <= last; i++) {
1124 newpoles(k) = poles->Value(i);
1127 for ( i = first; i < index; i++) {
1128 newpoles(k) = poles->Value(i);
1143 //=======================================================================
1144 //function : SetNotPeriodic
1146 //=======================================================================
1148 void Law_BSpline::SetNotPeriodic ()
1151 Standard_Integer NbKnots, NbPoles;
1152 BSplCLib::PrepareUnperiodize( deg, mults->Array1(),NbKnots,NbPoles);
1154 Handle(TColStd_HArray1OfReal) npoles
1155 = new TColStd_HArray1OfReal(1,NbPoles);
1157 Handle(TColStd_HArray1OfReal) nknots
1158 = new TColStd_HArray1OfReal(1,NbKnots);
1160 Handle(TColStd_HArray1OfInteger) nmults
1161 = new TColStd_HArray1OfInteger(1,NbKnots);
1163 Handle(TColStd_HArray1OfReal) nweights;
1167 nweights = new TColStd_HArray1OfReal(1,NbPoles);
1169 TColStd_Array1OfReal adimpol(1,2*poles->Upper());
1170 SetPoles(poles->Array1(),weights->Array1(),adimpol);
1171 TColStd_Array1OfReal adimnpol(1,2*npoles->Upper());
1172 BSplCLib::Unperiodize
1173 (deg,1,mults->Array1(),knots->Array1(),adimpol,
1174 nmults->ChangeArray1(),nknots->ChangeArray1(),
1176 GetPoles(adimnpol,npoles->ChangeArray1(),nweights->ChangeArray1());
1180 BSplCLib::Unperiodize(deg,1,mults->Array1(),knots->Array1(),
1181 poles->Array1(),nmults->ChangeArray1(),
1182 nknots->ChangeArray1(),npoles->ChangeArray1());
1189 periodic = Standard_False;
1196 //=======================================================================
1197 //function : SetPole
1199 //=======================================================================
1201 void Law_BSpline::SetPole
1202 (const Standard_Integer Index,
1203 const Standard_Real P)
1205 if (Index < 1 || Index > poles->Length()) throw Standard_OutOfRange();
1206 poles->SetValue (Index, P);
1210 //=======================================================================
1211 //function : SetPole
1213 //=======================================================================
1215 void Law_BSpline::SetPole
1216 (const Standard_Integer Index,
1217 const Standard_Real P,
1218 const Standard_Real W)
1224 //=======================================================================
1225 //function : SetWeight
1227 //=======================================================================
1229 void Law_BSpline::SetWeight
1230 (const Standard_Integer Index,
1231 const Standard_Real W)
1233 if (Index < 1 || Index > poles->Length()) throw Standard_OutOfRange();
1235 if (W <= gp::Resolution ()) throw Standard_ConstructionError();
1238 Standard_Boolean rat = IsRational() || (Abs(W - 1.) > gp::Resolution());
1241 if (rat && !IsRational())
1242 weights = new TColStd_HArray1OfReal(1,poles->Length(),1.);
1244 weights->SetValue (Index, W);
1247 rat = Rational(weights->Array1());
1248 if (!rat) weights.Nullify();
1251 rational = !weights.IsNull();
1256 //=======================================================================
1257 //function : UpdateKnots
1259 //=======================================================================
1262 void Law_BSpline::UpdateKnots()
1265 rational = !weights.IsNull();
1267 Standard_Integer MaxKnotMult = 0;
1272 knotSet, MaxKnotMult);
1274 if (knotSet == GeomAbs_Uniform && !periodic) {
1278 flatknots = new TColStd_HArray1OfReal
1279 (1, BSplCLib::KnotSequenceLength(mults->Array1(),deg,periodic));
1281 BSplCLib::KnotSequence (knots->Array1(),
1284 flatknots->ChangeArray1());
1287 if (MaxKnotMult == 0) smooth = GeomAbs_CN;
1289 switch (deg - MaxKnotMult) {
1290 case 0: smooth = GeomAbs_C0; break;
1291 case 1: smooth = GeomAbs_C1; break;
1292 case 2: smooth = GeomAbs_C2; break;
1293 case 3: smooth = GeomAbs_C3; break;
1294 default: smooth = GeomAbs_C3; break;
1300 //=======================================================================
1301 //function : Normalizes the parameters if the curve is periodic
1302 //purpose : that is compute the cache so that it is valid
1303 //=======================================================================
1305 void Law_BSpline::PeriodicNormalization(Standard_Real& Parameter) const
1307 Standard_Real Period ;
1310 Period = flatknots->Value(flatknots->Upper() - deg) -
1311 flatknots->Value (deg + 1) ;
1312 while (Parameter > flatknots->Value(flatknots->Upper()-deg)){
1313 Parameter -= Period ;
1315 while (Parameter < flatknots->Value((deg + 1))){
1316 Parameter += Period ;
1322 //=======================================================================
1325 //=======================================================================
1327 Standard_Boolean Law_BSpline::IsCN ( const Standard_Integer N) const
1329 Standard_RangeError_Raise_if
1330 (N < 0, "Law_BSpline::IsCN");
1333 case GeomAbs_CN : return Standard_True;
1334 case GeomAbs_C0 : return N <= 0;
1335 case GeomAbs_G1 : return N <= 0;
1336 case GeomAbs_C1 : return N <= 1;
1337 case GeomAbs_G2 : return N <= 1;
1338 case GeomAbs_C2 : return N <= 2;
1340 return N <= 3 ? Standard_True :
1341 N <= deg - BSplCLib::MaxKnotMult (mults->Array1(), mults->Lower() + 1, mults->Upper() - 1);
1343 return Standard_False;
1349 //=======================================================================
1350 //function : IsClosed
1352 //=======================================================================
1354 Standard_Boolean Law_BSpline::IsClosed () const
1355 { return (Abs(StartPoint()-EndPoint())) <= gp::Resolution (); }
1359 //=======================================================================
1360 //function : IsPeriodic
1362 //=======================================================================
1364 Standard_Boolean Law_BSpline::IsPeriodic () const
1365 { return periodic; }
1367 //=======================================================================
1368 //function : Continuity
1370 //=======================================================================
1372 GeomAbs_Shape Law_BSpline::Continuity () const
1375 //=======================================================================
1378 //=======================================================================
1380 Standard_Integer Law_BSpline::Degree () const
1384 //=======================================================================
1387 //=======================================================================
1389 Standard_Real Law_BSpline::Value(const Standard_Real U)const
1397 //=======================================================================
1400 //=======================================================================
1402 void Law_BSpline::D0 (const Standard_Real U,
1403 Standard_Real& P) const
1405 Standard_Real NewU = U ;
1406 PeriodicNormalization(NewU) ;
1408 BSplCLib::D0(NewU,0,deg,periodic,POLES, &weights->Array1(),FKNOTS,FMULTS,P);
1411 BSplCLib::D0(NewU,0,deg,periodic,POLES,BSplCLib::NoWeights(),FKNOTS,FMULTS,P);
1418 //=======================================================================
1421 //=======================================================================
1423 void Law_BSpline::D1 (const Standard_Real U,
1425 Standard_Real& V1) const
1427 Standard_Real NewU = U ;
1428 PeriodicNormalization(NewU) ;
1430 BSplCLib::D1(NewU,0,deg,periodic,POLES, &weights->Array1(),FKNOTS,FMULTS,
1434 BSplCLib::D1(NewU,0,deg,periodic,POLES,BSplCLib::NoWeights(),FKNOTS,FMULTS,
1441 //=======================================================================
1444 //=======================================================================
1446 void Law_BSpline::D2(const Standard_Real U ,
1449 Standard_Real& V2 ) const
1451 Standard_Real NewU = U ;
1452 PeriodicNormalization(NewU) ;
1454 BSplCLib::D2(NewU,0,deg,periodic,POLES,&weights->Array1(),FKNOTS,FMULTS,
1458 BSplCLib::D2(NewU,0,deg,periodic,POLES,BSplCLib::NoWeights(),FKNOTS,FMULTS,
1465 //=======================================================================
1468 //=======================================================================
1470 void Law_BSpline::D3(const Standard_Real U ,
1474 Standard_Real& V3 ) const
1476 Standard_Real NewU = U ;
1477 PeriodicNormalization(NewU) ;
1479 BSplCLib::D3(NewU,0,deg,periodic,POLES,&weights->Array1(),FKNOTS,FMULTS,
1483 BSplCLib::D3(NewU,0,deg,periodic,POLES,BSplCLib::NoWeights(),FKNOTS,FMULTS,
1490 //=======================================================================
1493 //=======================================================================
1495 Standard_Real Law_BSpline::DN(const Standard_Real U,
1496 const Standard_Integer N ) const
1500 BSplCLib::DN(U,N,0,deg,periodic,POLES,&weights->Array1(),FKNOTS,FMULTS,V);
1503 BSplCLib::DN(U,N,0,deg,periodic,POLES,BSplCLib::NoWeights(),FKNOTS,FMULTS,V);
1510 //=======================================================================
1511 //function : EndPoint
1513 //=======================================================================
1515 Standard_Real Law_BSpline::EndPoint () const
1517 if (mults->Value (knots->Upper ()) == deg + 1)
1518 return poles->Value (poles->Upper());
1520 return Value(LastParameter());
1524 //=======================================================================
1525 //function : FirstUKnotIndex
1527 //=======================================================================
1529 Standard_Integer Law_BSpline::FirstUKnotIndex () const
1531 if (periodic) return 1;
1532 else return BSplCLib::FirstUKnotIndex (deg, mults->Array1());
1536 //=======================================================================
1537 //function : FirstParameter
1539 //=======================================================================
1541 Standard_Real Law_BSpline::FirstParameter () const
1543 return flatknots->Value (deg+1);
1547 //=======================================================================
1550 //=======================================================================
1552 Standard_Real Law_BSpline::Knot (const Standard_Integer Index) const
1554 Standard_OutOfRange_Raise_if
1555 (Index < 1 || Index > knots->Length(), "Law_BSpline::Knot");
1556 return knots->Value (Index);
1561 //=======================================================================
1562 //function : KnotDistribution
1564 //=======================================================================
1566 GeomAbs_BSplKnotDistribution Law_BSpline::KnotDistribution () const
1572 //=======================================================================
1575 //=======================================================================
1577 void Law_BSpline::Knots (TColStd_Array1OfReal& K) const
1579 Standard_DimensionError_Raise_if
1580 (K.Length() != knots->Length(), "Law_BSpline::Knots");
1581 K = knots->Array1();
1585 //=======================================================================
1586 //function : KnotSequence
1588 //=======================================================================
1590 void Law_BSpline::KnotSequence (TColStd_Array1OfReal& K) const
1592 Standard_DimensionError_Raise_if
1593 (K.Length() != flatknots->Length(), "Law_BSpline::KnotSequence");
1594 K = flatknots->Array1();
1599 //=======================================================================
1600 //function : LastUKnotIndex
1602 //=======================================================================
1604 Standard_Integer Law_BSpline::LastUKnotIndex() const
1606 if (periodic) return knots->Length();
1607 else return BSplCLib::LastUKnotIndex (deg, mults->Array1());
1611 //=======================================================================
1612 //function : LastParameter
1614 //=======================================================================
1616 Standard_Real Law_BSpline::LastParameter () const
1618 return flatknots->Value (flatknots->Upper()-deg);
1622 //=======================================================================
1623 //function : LocalValue
1625 //=======================================================================
1627 Standard_Real Law_BSpline::LocalValue
1628 (const Standard_Real U,
1629 const Standard_Integer FromK1,
1630 const Standard_Integer ToK2) const
1633 LocalD0(U,FromK1,ToK2,P);
1637 //=======================================================================
1638 //function : LocalD0
1640 //=======================================================================
1642 void Law_BSpline::LocalD0
1643 (const Standard_Real U,
1644 const Standard_Integer FromK1,
1645 const Standard_Integer ToK2,
1646 Standard_Real& P) const
1648 Standard_DomainError_Raise_if (FromK1 == ToK2,
1649 "Law_BSpline::LocalValue");
1650 Standard_Real u = U;
1651 Standard_Integer index = 0;
1652 BSplCLib::LocateParameter(deg, FKNOTS, U, periodic,FromK1,ToK2, index,u);
1653 index = BSplCLib::FlatIndex(deg,index,mults->Array1(),periodic);
1655 BSplCLib::D0(u,index,deg,periodic,POLES,&weights->Array1(),FKNOTS,FMULTS,P);
1658 BSplCLib::D0(u,index,deg,periodic,POLES,BSplCLib::NoWeights(),FKNOTS,FMULTS,P);
1662 //=======================================================================
1663 //function : LocalD1
1665 //=======================================================================
1667 void Law_BSpline::LocalD1 (const Standard_Real U,
1668 const Standard_Integer FromK1,
1669 const Standard_Integer ToK2,
1671 Standard_Real& V1) const
1673 Standard_DomainError_Raise_if (FromK1 == ToK2,
1674 "Law_BSpline::LocalD1");
1675 Standard_Real u = U;
1676 Standard_Integer index = 0;
1677 BSplCLib::LocateParameter(deg, FKNOTS, U, periodic, FromK1,ToK2, index, u);
1678 index = BSplCLib::FlatIndex(deg,index,mults->Array1(),periodic);
1680 BSplCLib::D1(u,index,deg,periodic,POLES,&weights->Array1(),FKNOTS,FMULTS,P,V1);
1683 BSplCLib::D1(u,index,deg,periodic,POLES,BSplCLib::NoWeights(),FKNOTS,FMULTS,P,V1);
1688 //=======================================================================
1689 //function : LocalD2
1691 //=======================================================================
1693 void Law_BSpline::LocalD2
1694 (const Standard_Real U,
1695 const Standard_Integer FromK1,
1696 const Standard_Integer ToK2,
1699 Standard_Real& V2) const
1701 Standard_DomainError_Raise_if (FromK1 == ToK2,
1702 "Law_BSpline::LocalD2");
1703 Standard_Real u = U;
1704 Standard_Integer index = 0;
1705 BSplCLib::LocateParameter(deg, FKNOTS, U, periodic, FromK1,ToK2, index, u);
1706 index = BSplCLib::FlatIndex(deg,index,mults->Array1(),periodic);
1708 BSplCLib::D2(u,index,deg,periodic,POLES, &weights->Array1(),FKNOTS,FMULTS,P,V1,V2);
1711 BSplCLib::D2(u,index,deg,periodic,POLES,BSplCLib::NoWeights(),FKNOTS,FMULTS,P,V1,V2);
1716 //=======================================================================
1717 //function : LocalD3
1719 //=======================================================================
1721 void Law_BSpline::LocalD3
1722 (const Standard_Real U,
1723 const Standard_Integer FromK1,
1724 const Standard_Integer ToK2,
1728 Standard_Real& V3) const
1730 Standard_DomainError_Raise_if (FromK1 == ToK2,
1731 "Law_BSpline::LocalD3");
1732 Standard_Real u = U;
1733 Standard_Integer index = 0;
1734 BSplCLib::LocateParameter(deg, FKNOTS, U, periodic, FromK1,ToK2, index, u);
1735 index = BSplCLib::FlatIndex(deg,index,mults->Array1(),periodic);
1737 BSplCLib::D3(u,index,deg,periodic,POLES,&weights->Array1(),FKNOTS,FMULTS,P,V1,V2,V3);
1740 BSplCLib::D3(u,index,deg,periodic,POLES,BSplCLib::NoWeights(),FKNOTS,FMULTS,P,V1,V2,V3);
1746 //=======================================================================
1747 //function : LocalDN
1749 //=======================================================================
1751 Standard_Real Law_BSpline::LocalDN
1752 (const Standard_Real U,
1753 const Standard_Integer FromK1,
1754 const Standard_Integer ToK2,
1755 const Standard_Integer N ) const
1757 Standard_DomainError_Raise_if (FromK1 == ToK2,
1758 "Law_BSpline::LocalD3");
1759 Standard_Real u = U;
1760 Standard_Integer index = 0;
1761 BSplCLib::LocateParameter(deg, FKNOTS, U, periodic, FromK1,ToK2, index, u);
1762 index = BSplCLib::FlatIndex(deg,index,mults->Array1(),periodic);
1766 BSplCLib::DN(u,N,index,deg,periodic,POLES,&weights->Array1(),FKNOTS,FMULTS,V);
1769 BSplCLib::DN(u,N,index,deg,periodic,POLES,BSplCLib::NoWeights(),FKNOTS,FMULTS,V);
1776 //=======================================================================
1777 //function : Multiplicity
1779 //=======================================================================
1781 Standard_Integer Law_BSpline::Multiplicity
1782 (const Standard_Integer Index) const
1784 Standard_OutOfRange_Raise_if (Index < 1 || Index > mults->Length(),
1785 "Law_BSpline::Multiplicity");
1786 return mults->Value (Index);
1790 //=======================================================================
1791 //function : Multiplicities
1793 //=======================================================================
1795 void Law_BSpline::Multiplicities (TColStd_Array1OfInteger& M) const
1797 Standard_DimensionError_Raise_if (M.Length() != mults->Length(),
1798 "Law_BSpline::Multiplicities");
1799 M = mults->Array1();
1803 //=======================================================================
1804 //function : NbKnots
1806 //=======================================================================
1808 Standard_Integer Law_BSpline::NbKnots () const
1809 { return knots->Length(); }
1811 //=======================================================================
1812 //function : NbPoles
1814 //=======================================================================
1816 Standard_Integer Law_BSpline::NbPoles () const
1817 { return poles->Length(); }
1820 //=======================================================================
1823 //=======================================================================
1825 Standard_Real Law_BSpline::Pole (const Standard_Integer Index) const
1827 Standard_OutOfRange_Raise_if (Index < 1 || Index > poles->Length(),
1828 "Law_BSpline::Pole");
1829 return poles->Value (Index);
1833 //=======================================================================
1836 //=======================================================================
1838 void Law_BSpline::Poles (TColStd_Array1OfReal& P) const
1840 Standard_DimensionError_Raise_if (P.Length() != poles->Length(),
1841 "Law_BSpline::Poles");
1842 P = poles->Array1();
1846 //=======================================================================
1847 //function : StartPoint
1849 //=======================================================================
1851 Standard_Real Law_BSpline::StartPoint () const
1853 if (mults->Value (1) == deg + 1)
1854 return poles->Value (1);
1856 return Value(FirstParameter());
1859 //=======================================================================
1862 //=======================================================================
1864 Standard_Real Law_BSpline::Weight
1865 (const Standard_Integer Index) const
1867 Standard_OutOfRange_Raise_if (Index < 1 || Index > poles->Length(),
1868 "Law_BSpline::Weight");
1870 return weights->Value (Index);
1877 //=======================================================================
1878 //function : Weights
1880 //=======================================================================
1882 void Law_BSpline::Weights
1883 (TColStd_Array1OfReal& W) const
1885 Standard_DimensionError_Raise_if (W.Length() != poles->Length(),
1886 "Law_BSpline::Weights");
1888 W = weights->Array1();
1891 for (i = W.Lower(); i <= W.Upper(); i++)
1898 //=======================================================================
1899 //function : IsRational
1901 //=======================================================================
1903 Standard_Boolean Law_BSpline::IsRational () const
1905 return !weights.IsNull();
1909 //=======================================================================
1910 //function : LocateU
1912 //=======================================================================
1914 void Law_BSpline::LocateU
1915 (const Standard_Real U,
1916 const Standard_Real ParametricTolerance,
1917 Standard_Integer& I1,
1918 Standard_Integer& I2,
1919 const Standard_Boolean WithKnotRepetition) const
1921 Standard_Real NewU = U;
1922 Handle(TColStd_HArray1OfReal) TheKnots;
1923 if (WithKnotRepetition) TheKnots = flatknots;
1924 else TheKnots = knots;
1926 PeriodicNormalization(NewU); //Attention a la periode
1928 const TColStd_Array1OfReal & CKnots = TheKnots->Array1();
1929 Standard_Real UFirst = CKnots (1);
1930 Standard_Real ULast = CKnots (CKnots.Length());
1931 if (Abs (U - UFirst) <= Abs(ParametricTolerance)) { I1 = I2 = 1; }
1932 else if (Abs (U - ULast) <= Abs(ParametricTolerance)) {
1933 I1 = I2 = CKnots.Length();
1935 else if (NewU < UFirst - Abs(ParametricTolerance)) {
1939 else if (NewU > ULast + Abs(ParametricTolerance)) {
1940 I1 = CKnots.Length();
1945 BSplCLib::Hunt (CKnots, NewU, I1);
1946 I1 = Max (Min (I1, CKnots.Upper()), CKnots.Lower());
1947 while (I1 + 1 <= CKnots.Upper()
1948 && Abs (CKnots (I1 + 1) - NewU) <= Abs(ParametricTolerance))
1952 if ( Abs( CKnots(I1) - NewU) <= Abs(ParametricTolerance)) {
1960 //=======================================================================
1961 //function : MovePointAndTangent
1963 //=======================================================================
1966 MovePointAndTangent(const Standard_Real U,
1967 const Standard_Real P,
1968 const Standard_Real Tangent,
1969 const Standard_Real Tolerance,
1970 const Standard_Integer StartingCondition,
1971 const Standard_Integer EndingCondition,
1972 Standard_Integer& ErrorStatus)
1974 TColStd_Array1OfReal new_poles(1, poles->Length());
1975 Standard_Real delta,
1979 const Standard_Integer dimension = 1 ;
1985 delta_derivative = Tangent - delta_derivative ;
1986 poles_array = (Standard_Real *)
1987 &poles->Array1()(1) ;
1988 new_poles_array = (Standard_Real *)
1990 BSplCLib::MovePointAndTangent(U,
2001 flatknots->Array1(),
2005 poles->ChangeArray1() = new_poles;
2010 //=======================================================================
2011 //function : Resolution
2013 //=======================================================================
2015 void Law_BSpline::Resolution(const Standard_Real Tolerance3D,
2016 Standard_Real & UTolerance) const
2018 void* bid = (void*)(&(poles->Value(1)));
2019 Standard_Real* bidr = (Standard_Real*)bid;
2021 BSplCLib::Resolution(*bidr,1,poles->Length(),
2022 &weights->Array1(),FKNOTS,deg,
2028 BSplCLib::Resolution(*bidr,1,poles->Length(),
2029 BSplCLib::NoWeights(),FKNOTS,deg,