1 // File: Geom2d_BezierCurve.cxx
2 // Created: Thu Mar 25 10:24:39 1993
5 // Copyright: Matra Datavision 1993
7 // File Geom2d_BezierCurve.cxx Septembre 1990
8 // Passage en classe persistante - 23/01/91
9 // Modif suite a la deuxieme revue de projet toolkit Geometry -23/01/91
11 // Actuellement pour les champs de la courbe le tableau des poles est
12 // declare de 1 a NbPoles et le tableau des poids est declare de 1 a NbPoles
15 // Revised RLE Aug 19 1993
16 // Suppressed Swaps, added Init, removed typedefs
18 #define No_Standard_OutOfRange
19 #define No_Standard_DimensionError
21 #include <Geom2d_BezierCurve.ixx>
23 #include <BSplCLib.hxx>
26 #include <Standard_ConstructionError.hxx>
27 #include <Standard_DimensionError.hxx>
28 #include <Standard_OutOfRange.hxx>
29 #include <Standard_RangeError.hxx>
30 #include <TColStd_Array1OfReal.hxx>
31 #include <TColStd_Array1OfInteger.hxx>
33 //=======================================================================
35 //purpose : check rationality of an array of weights
36 //=======================================================================
38 static Standard_Boolean Rational(const TColStd_Array1OfReal& W)
40 Standard_Integer i, n = W.Length();
41 Standard_Boolean rat = Standard_False;
42 for (i = 1; i < n; i++) {
43 rat = Abs(W(i) - W(i+1)) > gp::Resolution();
50 //=======================================================================
51 //function : Geom2d_BezierCurve
53 //=======================================================================
55 Geom2d_BezierCurve::Geom2d_BezierCurve
56 (const TColgp_Array1OfPnt2d& Poles):
57 validcache(0), parametercache(0.), spanlenghtcache(1.)
61 Handle(TColgp_HArray1OfPnt2d) npoles =
62 new TColgp_HArray1OfPnt2d(1,Poles.Length());
64 npoles->ChangeArray1() = Poles;
68 Handle(TColStd_HArray1OfReal)());
72 //=======================================================================
73 //function : Geom2d_BezierCurve
75 //=======================================================================
77 Geom2d_BezierCurve::Geom2d_BezierCurve
78 (const TColgp_Array1OfPnt2d& Poles,
79 const TColStd_Array1OfReal& Weights):
80 validcache(0), parametercache(0.), spanlenghtcache(1.)
85 Handle(TColgp_HArray1OfPnt2d) npoles =
86 new TColgp_HArray1OfPnt2d(1,Poles.Length());
88 npoles->ChangeArray1() = Poles;
93 Standard_Integer nbpoles = Poles.Length();
95 if (Weights.Length() != nbpoles)
96 Standard_ConstructionError::Raise();
99 for (i = 1; i <= nbpoles; i++) {
100 if (Weights(i) <= gp::Resolution()) {
101 Standard_ConstructionError::Raise();
105 // check really rational
106 Standard_Boolean rat = Rational(Weights);
109 Handle(TColStd_HArray1OfReal) nweights;
111 nweights = new TColStd_HArray1OfReal(1,nbpoles);
112 nweights->ChangeArray1() = Weights;
116 Init(npoles,nweights);
120 //=======================================================================
121 //function : Increase
122 //purpose : increase degree
123 //=======================================================================
125 void Geom2d_BezierCurve::Increase (const Standard_Integer Deg)
127 if (Deg == Degree()) return;
129 Standard_ConstructionError_Raise_if
131 Deg > Geom2d_BezierCurve::MaxDegree(), "Geom2d_BezierCurve::Increase");
133 Handle(TColgp_HArray1OfPnt2d) npoles =
134 new TColgp_HArray1OfPnt2d(1,Deg+1);
136 Handle(TColStd_HArray1OfReal) nweights;
138 TColStd_Array1OfReal bidknots(1,2); bidknots(1) = 0.; bidknots(2) = 1.;
139 TColStd_Array1OfInteger bidmults(1,2); bidmults.Init(Degree() + 1);
142 nweights = new TColStd_HArray1OfReal(1,Deg+1);
143 BSplCLib::IncreaseDegree(Degree(), Deg, 0,
144 poles->Array1(),weights->Array1(),
146 npoles->ChangeArray1(),nweights->ChangeArray1(),
150 BSplCLib::IncreaseDegree(Degree(), Deg, 0,
152 *((TColStd_Array1OfReal*) NULL),
154 npoles->ChangeArray1(),
155 *((TColStd_Array1OfReal*) NULL),
159 Init(npoles,nweights);
163 //=======================================================================
164 //function : MaxDegree
166 //=======================================================================
168 Standard_Integer Geom2d_BezierCurve::MaxDegree ()
170 return BSplCLib::MaxDegree();
174 //=======================================================================
175 //function : InsertPoleAfter
177 //=======================================================================
179 void Geom2d_BezierCurve::InsertPoleAfter
180 (const Standard_Integer Index,
182 const Standard_Real Weight)
184 Standard_Integer nbpoles = NbPoles();
186 Standard_ConstructionError_Raise_if
187 (nbpoles >= Geom2d_BezierCurve::MaxDegree() ||
188 Weight <= gp::Resolution(),
189 "Geom2d_BezierCurve::InsertPoleAfter" );
191 Standard_OutOfRange_Raise_if
192 (Index < 0 || Index > nbpoles,
193 "Geom2d_BezierCurve::InsertPoleAfter");
198 Handle(TColgp_HArray1OfPnt2d) npoles =
199 new TColgp_HArray1OfPnt2d(1,nbpoles+1);
201 TColgp_Array1OfPnt2d& newpoles = npoles->ChangeArray1();
202 const TColgp_Array1OfPnt2d& oldpoles = poles->Array1();
204 for (i = 1; i <= Index; i++)
205 newpoles(i) = oldpoles(i);
207 newpoles(Index+1) = P;
209 for (i = Index+1; i <= nbpoles; i++)
210 newpoles(i+1) = oldpoles(i);
214 Handle(TColStd_HArray1OfReal) nweights;
215 Standard_Boolean rat = IsRational() || Abs(Weight-1.) > gp::Resolution();
218 nweights = new TColStd_HArray1OfReal(1,nbpoles+1);
219 TColStd_Array1OfReal& newweights = nweights->ChangeArray1();
221 for (i = 1; i <= Index; i++)
223 newweights(i) = weights->Value(i);
227 newweights(Index+1) = Weight;
229 for (i = Index+1; i <= nbpoles; i++)
231 newweights(i+1) = weights->Value(i);
233 newweights(i+1) = 1.;
237 Init(npoles,nweights);
241 //=======================================================================
242 //function : InsertPoleBefore
244 //=======================================================================
246 void Geom2d_BezierCurve::InsertPoleBefore
247 (const Standard_Integer Index,
249 const Standard_Real Weight)
251 InsertPoleAfter(Index-1,P,Weight);
255 //=======================================================================
256 //function : RemovePole
258 //=======================================================================
260 void Geom2d_BezierCurve::RemovePole
261 (const Standard_Integer Index)
263 Standard_Integer nbpoles = NbPoles();
265 Standard_ConstructionError_Raise_if
266 (nbpoles <= 2 , "Geom2d_BezierCurve::RemovePole" );
268 Standard_OutOfRange_Raise_if
269 (Index < 1 || Index > nbpoles,
270 "Geom2d_BezierCurve::RemovePole");
275 Handle(TColgp_HArray1OfPnt2d) npoles =
276 new TColgp_HArray1OfPnt2d(1,nbpoles-1);
278 TColgp_Array1OfPnt2d& newpoles = npoles->ChangeArray1();
279 const TColgp_Array1OfPnt2d& oldpoles = poles->Array1();
281 for (i = 1; i < Index; i++)
282 newpoles(i) = oldpoles(i);
284 for (i = Index+1; i <= nbpoles; i++)
285 newpoles(i-1) = oldpoles(i);
289 Handle(TColStd_HArray1OfReal) nweights;
292 nweights = new TColStd_HArray1OfReal(1,nbpoles-1);
293 TColStd_Array1OfReal& newweights = nweights->ChangeArray1();
294 const TColStd_Array1OfReal& oldweights = weights->Array1();
296 for (i = 1; i < Index; i++)
297 newweights(i) = oldweights(i);
299 for (i = Index+1; i <= nbpoles; i++)
300 newweights(i-1) = oldweights(i);
303 Init(npoles,nweights);
307 //=======================================================================
310 //=======================================================================
312 void Geom2d_BezierCurve::Reverse ()
315 Standard_Integer i, nbpoles = NbPoles();
316 TColgp_Array1OfPnt2d & cpoles = poles->ChangeArray1();
319 for (i = 1; i <= nbpoles / 2; i++) {
321 cpoles(i) = cpoles(nbpoles-i+1);
322 cpoles(nbpoles-i+1) = P;
327 TColStd_Array1OfReal & cweights = weights->ChangeArray1();
329 for (i = 1; i <= nbpoles / 2; i++) {
331 cweights(i) = cweights(nbpoles-i+1);
332 cweights(nbpoles-i+1) = w;
336 UpdateCoefficients();
340 //=======================================================================
341 //function : ReversedParameter
343 //=======================================================================
345 Standard_Real Geom2d_BezierCurve::ReversedParameter
346 ( const Standard_Real U) const
352 //=======================================================================
355 //=======================================================================
357 void Geom2d_BezierCurve::Segment
358 (const Standard_Real U1, const Standard_Real U2)
360 closed = (Abs(Value(U1).Distance (Value(U2))) <= gp::Resolution());
362 // WARNING : when calling trimming be carefull that the cache
363 // is computed regarding 0.0e0 and not 1.0e0
367 PLib::Trimming(U1,U2,coeffs->ChangeArray1(),wcoeffs->ChangeArray1());
368 PLib::CoefficientsPoles(coeffs->Array1(),wcoeffs->Array1(),
369 poles->ChangeArray1(),weights->ChangeArray1());
372 PLib::Trimming(U1,U2,coeffs->ChangeArray1(),
373 *((TColStd_Array1OfReal*) NULL));
374 PLib::CoefficientsPoles(coeffs->Array1(),
375 *((TColStd_Array1OfReal*) NULL),
376 poles->ChangeArray1(),
377 *((TColStd_Array1OfReal*) NULL));
379 UpdateCoefficients();
383 //=======================================================================
386 //=======================================================================
388 void Geom2d_BezierCurve::SetPole
389 (const Standard_Integer Index,
392 Standard_OutOfRange_Raise_if (Index < 1 || Index > NbPoles(),
393 "Geom2d_BezierCurve::SetPole");
395 TColgp_Array1OfPnt2d& cpoles = poles->ChangeArray1();
398 if (Index == 1 || Index == cpoles.Length()) {
399 closed = (cpoles(1).Distance(cpoles(NbPoles())) <= gp::Resolution());
402 UpdateCoefficients();
406 //=======================================================================
409 //=======================================================================
411 void Geom2d_BezierCurve::SetPole
412 (const Standard_Integer Index,
414 const Standard_Real Weight)
417 SetWeight(Index,Weight);
421 //=======================================================================
422 //function : SetWeight
424 //=======================================================================
426 void Geom2d_BezierCurve::SetWeight
427 (const Standard_Integer Index,
428 const Standard_Real Weight)
430 Standard_Integer nbpoles = NbPoles();
432 Standard_OutOfRange_Raise_if
433 (Index < 1 || Index > nbpoles,
434 "Geom2d_BezierCurve::SetWeight");
435 Standard_ConstructionError_Raise_if
436 (Weight <= gp::Resolution (),
437 "Geom2d_BezierCurve::SetWeight");
440 // compute new rationality
441 Standard_Boolean wasrat = IsRational();
443 // a weight of 1. does not turn to rational
444 if (Abs(Weight - 1.) <= gp::Resolution()) return;
447 weights = new TColStd_HArray1OfReal(1,nbpoles);
448 wcoeffs = new TColStd_HArray1OfReal(1,nbpoles);
452 TColStd_Array1OfReal & cweights = weights->ChangeArray1();
453 cweights(Index) = Weight;
455 // is it turning into non rational
457 if (!Rational(cweights)) {
463 UpdateCoefficients();
467 //=======================================================================
468 //function : IsClosed
470 //=======================================================================
472 Standard_Boolean Geom2d_BezierCurve::IsClosed () const
478 //=======================================================================
481 //=======================================================================
483 Standard_Boolean Geom2d_BezierCurve::IsCN (const Standard_Integer ) const
485 return Standard_True;
489 //=======================================================================
490 //function : IsPeriodic
492 //=======================================================================
494 Standard_Boolean Geom2d_BezierCurve::IsPeriodic () const
496 return Standard_False;
500 //=======================================================================
501 //function : IsRational
503 //=======================================================================
505 Standard_Boolean Geom2d_BezierCurve::IsRational () const
507 return !weights.IsNull();
511 //=======================================================================
512 //function : Continuity
514 //=======================================================================
516 GeomAbs_Shape Geom2d_BezierCurve::Continuity () const
522 //=======================================================================
525 //=======================================================================
527 Standard_Integer Geom2d_BezierCurve::Degree () const
529 return poles->Length()-1;
533 //=======================================================================
536 //=======================================================================
538 void Geom2d_BezierCurve::D0 (const Standard_Real U, gp_Pnt2d& P ) const
540 // Idee lumineuse sacrifiee sur l autel des performances.
542 // if(!CoefficientsOK(U))
543 // ((Geom2d_BezierCurve*)(void*)this)->UpdateCoefficients(U);
545 BSplCLib::CacheD0(U,Degree(),parametercache,spanlenghtcache,
546 coeffs->Array1(),wcoeffs->Array1(),P);
548 BSplCLib::CacheD0(U,Degree(),parametercache,spanlenghtcache,
550 *((TColStd_Array1OfReal*) NULL),
554 //=======================================================================
557 //=======================================================================
559 void Geom2d_BezierCurve::D1(const Standard_Real U,
563 // Idee lumineuse sacrifiee sur l autel des performances.
565 // if(!CoefficientsOK(U))
566 // ((Geom2d_BezierCurve*)(void*)this)->UpdateCoefficients(U);
568 BSplCLib::CacheD1(U,Degree(),parametercache,spanlenghtcache,
569 coeffs->Array1(),wcoeffs->Array1(),P,V1);
571 BSplCLib::CacheD1(U,Degree(),parametercache,spanlenghtcache,
573 *((TColStd_Array1OfReal*) NULL),
577 //=======================================================================
580 //=======================================================================
582 void Geom2d_BezierCurve::D2 (const Standard_Real U,
587 // Idee lumineuse sacrifiee sur l autel des performances.
589 // if(!CoefficientsOK(U))
590 // ((Geom2d_BezierCurve*)(void*)this)->UpdateCoefficients(U);
592 BSplCLib::CacheD2(U,Degree(),parametercache,spanlenghtcache,
593 coeffs->Array1(),wcoeffs->Array1(),P,V1,V2);
595 BSplCLib::CacheD2(U,Degree(),parametercache,spanlenghtcache,
597 *((TColStd_Array1OfReal*) NULL),
601 //=======================================================================
604 //=======================================================================
606 void Geom2d_BezierCurve::D3 (const Standard_Real U,
612 // Idee lumineuse sacrifiee sur l autel des performances.
614 // if(!CoefficientsOK(U))
615 // ((Geom2d_BezierCurve*)(void*)this)->UpdateCoefficients(U);
617 BSplCLib::CacheD3(U,Degree(),parametercache,spanlenghtcache,
618 coeffs->Array1(),wcoeffs->Array1(),P,V1,V2,V3);
620 BSplCLib::CacheD3(U,Degree(),parametercache,spanlenghtcache,
622 *((TColStd_Array1OfReal*) NULL),
626 //=======================================================================
629 //=======================================================================
631 gp_Vec2d Geom2d_BezierCurve::DN (const Standard_Real U,
632 const Standard_Integer N) const
634 Standard_RangeError_Raise_if (N < 1, "Geom2d_BezierCurve::DN");
637 TColStd_Array1OfReal bidknots(1,2); bidknots(1) = 0.; bidknots(2) = 1.;
638 TColStd_Array1OfInteger bidmults(1,2); bidmults.Init(Degree() + 1);
641 BSplCLib::DN(U,N,0,Degree(),Standard_False,
642 poles->Array1(),weights->Array1(),
643 bidknots,bidmults,V);
645 BSplCLib::DN(U,N,0,Degree(),Standard_False,
647 *((TColStd_Array1OfReal*) NULL),
648 bidknots,bidmults,V);
652 //=======================================================================
653 //function : EndPoint
655 //=======================================================================
657 gp_Pnt2d Geom2d_BezierCurve::EndPoint () const
659 return poles->Value (poles->Upper());
663 //=======================================================================
664 //function : FirstParameter
666 //=======================================================================
668 Standard_Real Geom2d_BezierCurve::FirstParameter () const
674 //=======================================================================
675 //function : LastParameter
677 //=======================================================================
679 Standard_Real Geom2d_BezierCurve::LastParameter () const
685 //=======================================================================
688 //=======================================================================
690 Standard_Integer Geom2d_BezierCurve::NbPoles () const
692 return poles->Length();
696 //=======================================================================
699 //=======================================================================
701 gp_Pnt2d Geom2d_BezierCurve::Pole (const Standard_Integer Index) const
703 Standard_OutOfRange_Raise_if (Index < 1 || Index > poles->Length(),
704 "Geom2d_BezierCurve::Pole");
705 return poles->Value(Index);
709 //=======================================================================
712 //=======================================================================
714 void Geom2d_BezierCurve::Poles (TColgp_Array1OfPnt2d& P) const
716 Standard_DimensionError_Raise_if (P.Length() != poles->Length(),
717 "Geom2d_BezierCurve::Poles");
722 //=======================================================================
723 //function : StartPoint
725 //=======================================================================
727 gp_Pnt2d Geom2d_BezierCurve::StartPoint () const
729 return poles->Value(1);
733 //=======================================================================
736 //=======================================================================
738 Standard_Real Geom2d_BezierCurve::Weight
739 (const Standard_Integer Index) const
741 Standard_OutOfRange_Raise_if (Index < 1 || Index > weights->Length(),
742 "Geom2d_BezierCurve::Weight");
744 return weights->Value(Index);
750 //=======================================================================
753 //=======================================================================
755 void Geom2d_BezierCurve::Weights
756 (TColStd_Array1OfReal& W) const
759 Standard_Integer nbpoles = NbPoles();
760 Standard_DimensionError_Raise_if (W.Length() != nbpoles,
761 "Geom2d_BezierCurve::Weights");
763 W = weights->Array1();
766 for (i = 1; i <= nbpoles; i++)
772 //=======================================================================
773 //function : Transform
775 //=======================================================================
777 void Geom2d_BezierCurve::Transform (const gp_Trsf2d& T)
779 Standard_Integer nbpoles = NbPoles();
780 TColgp_Array1OfPnt2d & cpoles = poles->ChangeArray1();
782 for (Standard_Integer i = 1; i <= nbpoles; i++)
783 cpoles (i).Transform(T);
785 UpdateCoefficients();
789 //=======================================================================
790 //function : Resolution
792 //=======================================================================
794 void Geom2d_BezierCurve::Resolution(const Standard_Real ToleranceUV,
795 Standard_Real & UTolerance)
798 TColStd_Array1OfReal bidflatknots(1, 2*(Degree()+1));
799 for(Standard_Integer i = 1; i <= Degree()+1; i++){
800 bidflatknots(i) = 0.;
801 bidflatknots(i + Degree() +1) = 1.;
805 BSplCLib::Resolution(poles->Array1(),
814 BSplCLib::Resolution(poles->Array1(),
815 *((TColStd_Array1OfReal*) NULL),
824 UTolerance = ToleranceUV * maxderivinv;
828 //=======================================================================
831 //=======================================================================
833 Handle(Geom2d_Geometry) Geom2d_BezierCurve::Copy() const {
835 Handle(Geom2d_BezierCurve) C;
837 C = new Geom2d_BezierCurve (poles->Array1(),weights->Array1());
839 C = new Geom2d_BezierCurve (poles->Array1());
844 //=======================================================================
847 //=======================================================================
849 void Geom2d_BezierCurve::Init
850 (const Handle(TColgp_HArray1OfPnt2d)& Poles,
851 const Handle(TColStd_HArray1OfReal)& Weights)
853 Standard_Integer nbpoles = Poles->Length();
855 const TColgp_Array1OfPnt2d& cpoles = Poles->Array1();
856 closed = cpoles(1).Distance(cpoles(nbpoles)) <= gp::Resolution();
859 rational = !Weights.IsNull();
863 coeffs = new TColgp_HArray1OfPnt2d (1,nbpoles);
867 wcoeffs = new TColStd_HArray1OfReal (1, nbpoles, 0.0);
874 UpdateCoefficients();
878 //=======================================================================
879 //function : CoefficientsOK
881 //=======================================================================
883 //Standard_Boolean Geom2d_BezierCurve::CoefficientsOK(const Standard_Real U)const
884 Standard_Boolean Geom2d_BezierCurve::CoefficientsOK(const Standard_Real )const
886 return (validcache) ;
891 //=======================================================================
892 //function : UpdateCoefficients
894 //=======================================================================
896 //void Geom2d_BezierCurve::UpdateCoefficients(const Standard_Real U)
897 void Geom2d_BezierCurve::UpdateCoefficients(const Standard_Real )
902 // Idee lumineuse sacrifiee sur l autel des performances.
903 // if (U >= 1.) parametercache = 1.;
904 TColStd_Array1OfReal bidflatknots(BSplCLib::FlatBezierKnots(Degree()),
907 BSplCLib::BuildCache(parametercache,spanlenghtcache,0,Degree(),
908 bidflatknots,poles->Array1(),weights->Array1(),
909 coeffs->ChangeArray1(),wcoeffs->ChangeArray1());
911 BSplCLib::BuildCache(parametercache,spanlenghtcache,0,Degree(),
912 bidflatknots,poles->Array1(),
913 *((TColStd_Array1OfReal*) NULL),
914 coeffs->ChangeArray1(),
915 *((TColStd_Array1OfReal*) NULL));