1 // Created on: 1993-03-25
3 // Copyright (c) 1993-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 // Passage en classe persistante - 23/01/91
18 // Modif suite a la deuxieme revue de projet toolkit Geometry -23/01/91
20 // Actuellement pour les champs de la courbe le tableau des poles est
21 // declare de 1 a NbPoles et le tableau des poids est declare de 1 a NbPoles
24 // Revised RLE Aug 19 1993
25 // Suppressed Swaps, added Init, removed typedefs
27 #define No_Standard_OutOfRange
28 #define No_Standard_DimensionError
31 #include <BSplCLib.hxx>
32 #include <Geom2d_BezierCurve.hxx>
33 #include <Geom2d_Geometry.hxx>
35 #include <gp_Pnt2d.hxx>
36 #include <gp_Trsf2d.hxx>
37 #include <gp_Vec2d.hxx>
40 #include <Standard_ConstructionError.hxx>
41 #include <Standard_DimensionError.hxx>
42 #include <Standard_OutOfRange.hxx>
43 #include <Standard_RangeError.hxx>
44 #include <Standard_Type.hxx>
45 #include <TColStd_Array1OfInteger.hxx>
46 #include <TColStd_Array1OfReal.hxx>
48 //=======================================================================
50 //purpose : check rationality of an array of weights
51 //=======================================================================
52 static Standard_Boolean Rational(const TColStd_Array1OfReal& W)
54 Standard_Integer i, n = W.Length();
55 Standard_Boolean rat = Standard_False;
56 for (i = 1; i < n; i++) {
57 rat = Abs(W(i) - W(i+1)) > gp::Resolution();
64 //=======================================================================
65 //function : Geom2d_BezierCurve
67 //=======================================================================
69 Geom2d_BezierCurve::Geom2d_BezierCurve
70 (const TColgp_Array1OfPnt2d& Poles):
71 validcache(0), parametercache(0.), spanlenghtcache(1.)
75 Handle(TColgp_HArray1OfPnt2d) npoles =
76 new TColgp_HArray1OfPnt2d(1,Poles.Length());
78 npoles->ChangeArray1() = Poles;
82 Handle(TColStd_HArray1OfReal)());
86 //=======================================================================
87 //function : Geom2d_BezierCurve
89 //=======================================================================
91 Geom2d_BezierCurve::Geom2d_BezierCurve
92 (const TColgp_Array1OfPnt2d& Poles,
93 const TColStd_Array1OfReal& Weights):
94 validcache(0), parametercache(0.), spanlenghtcache(1.)
99 Handle(TColgp_HArray1OfPnt2d) npoles =
100 new TColgp_HArray1OfPnt2d(1,Poles.Length());
102 npoles->ChangeArray1() = Poles;
107 Standard_Integer nbpoles = Poles.Length();
109 if (Weights.Length() != nbpoles)
110 Standard_ConstructionError::Raise();
113 for (i = 1; i <= nbpoles; i++) {
114 if (Weights(i) <= gp::Resolution()) {
115 Standard_ConstructionError::Raise();
119 // check really rational
120 Standard_Boolean rat = Rational(Weights);
123 Handle(TColStd_HArray1OfReal) nweights;
125 nweights = new TColStd_HArray1OfReal(1,nbpoles);
126 nweights->ChangeArray1() = Weights;
130 Init(npoles,nweights);
134 //=======================================================================
135 //function : Increase
136 //purpose : increase degree
137 //=======================================================================
139 void Geom2d_BezierCurve::Increase (const Standard_Integer Deg)
141 if (Deg == Degree()) return;
143 Standard_ConstructionError_Raise_if
145 Deg > Geom2d_BezierCurve::MaxDegree(), "Geom2d_BezierCurve::Increase");
147 Handle(TColgp_HArray1OfPnt2d) npoles =
148 new TColgp_HArray1OfPnt2d(1,Deg+1);
150 Handle(TColStd_HArray1OfReal) nweights;
152 TColStd_Array1OfReal bidknots(1,2); bidknots(1) = 0.; bidknots(2) = 1.;
153 TColStd_Array1OfInteger bidmults(1,2); bidmults.Init(Degree() + 1);
156 nweights = new TColStd_HArray1OfReal(1,Deg+1);
157 BSplCLib::IncreaseDegree(Degree(), Deg, 0,
158 poles->Array1(),weights->Array1(),
160 npoles->ChangeArray1(),nweights->ChangeArray1(),
164 BSplCLib::IncreaseDegree(Degree(), Deg, 0,
166 *((TColStd_Array1OfReal*) NULL),
168 npoles->ChangeArray1(),
169 *((TColStd_Array1OfReal*) NULL),
173 Init(npoles,nweights);
177 //=======================================================================
178 //function : MaxDegree
180 //=======================================================================
182 Standard_Integer Geom2d_BezierCurve::MaxDegree ()
184 return BSplCLib::MaxDegree();
188 //=======================================================================
189 //function : InsertPoleAfter
191 //=======================================================================
193 void Geom2d_BezierCurve::InsertPoleAfter
194 (const Standard_Integer Index,
196 const Standard_Real Weight)
198 Standard_Integer nbpoles = NbPoles();
200 Standard_ConstructionError_Raise_if
201 (nbpoles >= Geom2d_BezierCurve::MaxDegree() ||
202 Weight <= gp::Resolution(),
203 "Geom2d_BezierCurve::InsertPoleAfter" );
205 Standard_OutOfRange_Raise_if
206 (Index < 0 || Index > nbpoles,
207 "Geom2d_BezierCurve::InsertPoleAfter");
212 Handle(TColgp_HArray1OfPnt2d) npoles =
213 new TColgp_HArray1OfPnt2d(1,nbpoles+1);
215 TColgp_Array1OfPnt2d& newpoles = npoles->ChangeArray1();
216 const TColgp_Array1OfPnt2d& oldpoles = poles->Array1();
218 for (i = 1; i <= Index; i++)
219 newpoles(i) = oldpoles(i);
221 newpoles(Index+1) = P;
223 for (i = Index+1; i <= nbpoles; i++)
224 newpoles(i+1) = oldpoles(i);
228 Handle(TColStd_HArray1OfReal) nweights;
229 Standard_Boolean rat = IsRational() || Abs(Weight-1.) > gp::Resolution();
232 nweights = new TColStd_HArray1OfReal(1,nbpoles+1);
233 TColStd_Array1OfReal& newweights = nweights->ChangeArray1();
235 for (i = 1; i <= Index; i++)
237 newweights(i) = weights->Value(i);
241 newweights(Index+1) = Weight;
243 for (i = Index+1; i <= nbpoles; i++)
245 newweights(i+1) = weights->Value(i);
247 newweights(i+1) = 1.;
251 Init(npoles,nweights);
255 //=======================================================================
256 //function : InsertPoleBefore
258 //=======================================================================
260 void Geom2d_BezierCurve::InsertPoleBefore
261 (const Standard_Integer Index,
263 const Standard_Real Weight)
265 InsertPoleAfter(Index-1,P,Weight);
269 //=======================================================================
270 //function : RemovePole
272 //=======================================================================
274 void Geom2d_BezierCurve::RemovePole
275 (const Standard_Integer Index)
277 Standard_Integer nbpoles = NbPoles();
279 Standard_ConstructionError_Raise_if
280 (nbpoles <= 2 , "Geom2d_BezierCurve::RemovePole" );
282 Standard_OutOfRange_Raise_if
283 (Index < 1 || Index > nbpoles,
284 "Geom2d_BezierCurve::RemovePole");
289 Handle(TColgp_HArray1OfPnt2d) npoles =
290 new TColgp_HArray1OfPnt2d(1,nbpoles-1);
292 TColgp_Array1OfPnt2d& newpoles = npoles->ChangeArray1();
293 const TColgp_Array1OfPnt2d& oldpoles = poles->Array1();
295 for (i = 1; i < Index; i++)
296 newpoles(i) = oldpoles(i);
298 for (i = Index+1; i <= nbpoles; i++)
299 newpoles(i-1) = oldpoles(i);
303 Handle(TColStd_HArray1OfReal) nweights;
306 nweights = new TColStd_HArray1OfReal(1,nbpoles-1);
307 TColStd_Array1OfReal& newweights = nweights->ChangeArray1();
308 const TColStd_Array1OfReal& oldweights = weights->Array1();
310 for (i = 1; i < Index; i++)
311 newweights(i) = oldweights(i);
313 for (i = Index+1; i <= nbpoles; i++)
314 newweights(i-1) = oldweights(i);
317 Init(npoles,nweights);
321 //=======================================================================
324 //=======================================================================
326 void Geom2d_BezierCurve::Reverse ()
329 Standard_Integer i, nbpoles = NbPoles();
330 TColgp_Array1OfPnt2d & cpoles = poles->ChangeArray1();
333 for (i = 1; i <= nbpoles / 2; i++) {
335 cpoles(i) = cpoles(nbpoles-i+1);
336 cpoles(nbpoles-i+1) = P;
341 TColStd_Array1OfReal & cweights = weights->ChangeArray1();
343 for (i = 1; i <= nbpoles / 2; i++) {
345 cweights(i) = cweights(nbpoles-i+1);
346 cweights(nbpoles-i+1) = w;
350 UpdateCoefficients();
354 //=======================================================================
355 //function : ReversedParameter
357 //=======================================================================
359 Standard_Real Geom2d_BezierCurve::ReversedParameter
360 ( const Standard_Real U) const
366 //=======================================================================
369 //=======================================================================
371 void Geom2d_BezierCurve::Segment
372 (const Standard_Real U1, const Standard_Real U2)
374 closed = (Abs(Value(U1).Distance (Value(U2))) <= gp::Resolution());
376 // WARNING : when calling trimming be carefull that the cache
377 // is computed regarding 0.0e0 and not 1.0e0
381 PLib::Trimming(U1,U2,coeffs->ChangeArray1(),wcoeffs->ChangeArray1());
382 PLib::CoefficientsPoles(coeffs->Array1(),wcoeffs->Array1(),
383 poles->ChangeArray1(),weights->ChangeArray1());
386 PLib::Trimming(U1,U2,coeffs->ChangeArray1(),
387 *((TColStd_Array1OfReal*) NULL));
388 PLib::CoefficientsPoles(coeffs->Array1(),
389 *((TColStd_Array1OfReal*) NULL),
390 poles->ChangeArray1(),
391 *((TColStd_Array1OfReal*) NULL));
393 UpdateCoefficients();
397 //=======================================================================
400 //=======================================================================
402 void Geom2d_BezierCurve::SetPole
403 (const Standard_Integer Index,
406 Standard_OutOfRange_Raise_if (Index < 1 || Index > NbPoles(),
407 "Geom2d_BezierCurve::SetPole");
409 TColgp_Array1OfPnt2d& cpoles = poles->ChangeArray1();
412 if (Index == 1 || Index == cpoles.Length()) {
413 closed = (cpoles(1).Distance(cpoles(NbPoles())) <= gp::Resolution());
416 UpdateCoefficients();
420 //=======================================================================
423 //=======================================================================
425 void Geom2d_BezierCurve::SetPole
426 (const Standard_Integer Index,
428 const Standard_Real Weight)
431 SetWeight(Index,Weight);
435 //=======================================================================
436 //function : SetWeight
438 //=======================================================================
440 void Geom2d_BezierCurve::SetWeight
441 (const Standard_Integer Index,
442 const Standard_Real Weight)
444 Standard_Integer nbpoles = NbPoles();
446 Standard_OutOfRange_Raise_if
447 (Index < 1 || Index > nbpoles,
448 "Geom2d_BezierCurve::SetWeight");
449 Standard_ConstructionError_Raise_if
450 (Weight <= gp::Resolution (),
451 "Geom2d_BezierCurve::SetWeight");
454 // compute new rationality
455 Standard_Boolean wasrat = IsRational();
457 // a weight of 1. does not turn to rational
458 if (Abs(Weight - 1.) <= gp::Resolution()) return;
461 weights = new TColStd_HArray1OfReal(1,nbpoles);
462 wcoeffs = new TColStd_HArray1OfReal(1,nbpoles);
466 TColStd_Array1OfReal & cweights = weights->ChangeArray1();
467 cweights(Index) = Weight;
469 // is it turning into non rational
471 if (!Rational(cweights)) {
477 UpdateCoefficients();
481 //=======================================================================
482 //function : IsClosed
484 //=======================================================================
486 Standard_Boolean Geom2d_BezierCurve::IsClosed () const
492 //=======================================================================
495 //=======================================================================
497 Standard_Boolean Geom2d_BezierCurve::IsCN (const Standard_Integer ) const
499 return Standard_True;
503 //=======================================================================
504 //function : IsPeriodic
506 //=======================================================================
508 Standard_Boolean Geom2d_BezierCurve::IsPeriodic () const
510 return Standard_False;
514 //=======================================================================
515 //function : IsRational
517 //=======================================================================
519 Standard_Boolean Geom2d_BezierCurve::IsRational () const
521 return !weights.IsNull();
525 //=======================================================================
526 //function : Continuity
528 //=======================================================================
530 GeomAbs_Shape Geom2d_BezierCurve::Continuity () const
536 //=======================================================================
539 //=======================================================================
541 Standard_Integer Geom2d_BezierCurve::Degree () const
543 return poles->Length()-1;
547 //=======================================================================
550 //=======================================================================
552 void Geom2d_BezierCurve::D0 (const Standard_Real U, gp_Pnt2d& P ) const
554 // Idee lumineuse sacrifiee sur l autel des performances.
556 // if(!CoefficientsOK(U))
557 // ((Geom2d_BezierCurve*)(void*)this)->UpdateCoefficients(U);
559 BSplCLib::CacheD0(U,Degree(),parametercache,spanlenghtcache,
560 coeffs->Array1(),wcoeffs->Array1(),P);
562 BSplCLib::CacheD0(U,Degree(),parametercache,spanlenghtcache,
564 *((TColStd_Array1OfReal*) NULL),
568 //=======================================================================
571 //=======================================================================
573 void Geom2d_BezierCurve::D1(const Standard_Real U,
577 // Idee lumineuse sacrifiee sur l autel des performances.
579 // if(!CoefficientsOK(U))
580 // ((Geom2d_BezierCurve*)(void*)this)->UpdateCoefficients(U);
582 BSplCLib::CacheD1(U,Degree(),parametercache,spanlenghtcache,
583 coeffs->Array1(),wcoeffs->Array1(),P,V1);
585 BSplCLib::CacheD1(U,Degree(),parametercache,spanlenghtcache,
587 *((TColStd_Array1OfReal*) NULL),
591 //=======================================================================
594 //=======================================================================
596 void Geom2d_BezierCurve::D2 (const Standard_Real U,
601 // Idee lumineuse sacrifiee sur l autel des performances.
603 // if(!CoefficientsOK(U))
604 // ((Geom2d_BezierCurve*)(void*)this)->UpdateCoefficients(U);
606 BSplCLib::CacheD2(U,Degree(),parametercache,spanlenghtcache,
607 coeffs->Array1(),wcoeffs->Array1(),P,V1,V2);
609 BSplCLib::CacheD2(U,Degree(),parametercache,spanlenghtcache,
611 *((TColStd_Array1OfReal*) NULL),
615 //=======================================================================
618 //=======================================================================
620 void Geom2d_BezierCurve::D3 (const Standard_Real U,
626 // Idee lumineuse sacrifiee sur l autel des performances.
628 // if(!CoefficientsOK(U))
629 // ((Geom2d_BezierCurve*)(void*)this)->UpdateCoefficients(U);
631 BSplCLib::CacheD3(U,Degree(),parametercache,spanlenghtcache,
632 coeffs->Array1(),wcoeffs->Array1(),P,V1,V2,V3);
634 BSplCLib::CacheD3(U,Degree(),parametercache,spanlenghtcache,
636 *((TColStd_Array1OfReal*) NULL),
640 //=======================================================================
643 //=======================================================================
645 gp_Vec2d Geom2d_BezierCurve::DN (const Standard_Real U,
646 const Standard_Integer N) const
648 Standard_RangeError_Raise_if (N < 1, "Geom2d_BezierCurve::DN");
651 TColStd_Array1OfReal bidknots(1,2); bidknots(1) = 0.; bidknots(2) = 1.;
652 TColStd_Array1OfInteger bidmults(1,2); bidmults.Init(Degree() + 1);
655 BSplCLib::DN(U,N,0,Degree(),Standard_False,
656 poles->Array1(),weights->Array1(),
657 bidknots,bidmults,V);
659 BSplCLib::DN(U,N,0,Degree(),Standard_False,
661 *((TColStd_Array1OfReal*) NULL),
662 bidknots,bidmults,V);
666 //=======================================================================
667 //function : EndPoint
669 //=======================================================================
671 gp_Pnt2d Geom2d_BezierCurve::EndPoint () const
673 return poles->Value (poles->Upper());
677 //=======================================================================
678 //function : FirstParameter
680 //=======================================================================
682 Standard_Real Geom2d_BezierCurve::FirstParameter () const
688 //=======================================================================
689 //function : LastParameter
691 //=======================================================================
693 Standard_Real Geom2d_BezierCurve::LastParameter () const
699 //=======================================================================
702 //=======================================================================
704 Standard_Integer Geom2d_BezierCurve::NbPoles () const
706 return poles->Length();
710 //=======================================================================
713 //=======================================================================
715 gp_Pnt2d Geom2d_BezierCurve::Pole (const Standard_Integer Index) const
717 Standard_OutOfRange_Raise_if (Index < 1 || Index > poles->Length(),
718 "Geom2d_BezierCurve::Pole");
719 return poles->Value(Index);
723 //=======================================================================
726 //=======================================================================
728 void Geom2d_BezierCurve::Poles (TColgp_Array1OfPnt2d& P) const
730 Standard_DimensionError_Raise_if (P.Length() != poles->Length(),
731 "Geom2d_BezierCurve::Poles");
736 //=======================================================================
737 //function : StartPoint
739 //=======================================================================
741 gp_Pnt2d Geom2d_BezierCurve::StartPoint () const
743 return poles->Value(1);
747 //=======================================================================
750 //=======================================================================
752 Standard_Real Geom2d_BezierCurve::Weight
753 (const Standard_Integer Index) const
755 Standard_OutOfRange_Raise_if (Index < 1 || Index > weights->Length(),
756 "Geom2d_BezierCurve::Weight");
758 return weights->Value(Index);
764 //=======================================================================
767 //=======================================================================
769 void Geom2d_BezierCurve::Weights
770 (TColStd_Array1OfReal& W) const
773 Standard_Integer nbpoles = NbPoles();
774 Standard_DimensionError_Raise_if (W.Length() != nbpoles,
775 "Geom2d_BezierCurve::Weights");
777 W = weights->Array1();
780 for (i = 1; i <= nbpoles; i++)
786 //=======================================================================
787 //function : Transform
789 //=======================================================================
791 void Geom2d_BezierCurve::Transform (const gp_Trsf2d& T)
793 Standard_Integer nbpoles = NbPoles();
794 TColgp_Array1OfPnt2d & cpoles = poles->ChangeArray1();
796 for (Standard_Integer i = 1; i <= nbpoles; i++)
797 cpoles (i).Transform(T);
799 UpdateCoefficients();
803 //=======================================================================
804 //function : Resolution
806 //=======================================================================
808 void Geom2d_BezierCurve::Resolution(const Standard_Real ToleranceUV,
809 Standard_Real & UTolerance)
812 TColStd_Array1OfReal bidflatknots(1, 2*(Degree()+1));
813 for(Standard_Integer i = 1; i <= Degree()+1; i++){
814 bidflatknots(i) = 0.;
815 bidflatknots(i + Degree() +1) = 1.;
819 BSplCLib::Resolution(poles->Array1(),
828 BSplCLib::Resolution(poles->Array1(),
829 *((TColStd_Array1OfReal*) NULL),
838 UTolerance = ToleranceUV * maxderivinv;
842 //=======================================================================
845 //=======================================================================
847 Handle(Geom2d_Geometry) Geom2d_BezierCurve::Copy() const {
849 Handle(Geom2d_BezierCurve) C;
851 C = new Geom2d_BezierCurve (poles->Array1(),weights->Array1());
853 C = new Geom2d_BezierCurve (poles->Array1());
858 //=======================================================================
861 //=======================================================================
863 void Geom2d_BezierCurve::Init
864 (const Handle(TColgp_HArray1OfPnt2d)& Poles,
865 const Handle(TColStd_HArray1OfReal)& Weights)
867 Standard_Integer nbpoles = Poles->Length();
869 const TColgp_Array1OfPnt2d& cpoles = Poles->Array1();
870 closed = cpoles(1).Distance(cpoles(nbpoles)) <= gp::Resolution();
873 rational = !Weights.IsNull();
877 coeffs = new TColgp_HArray1OfPnt2d (1,nbpoles);
881 wcoeffs = new TColStd_HArray1OfReal (1, nbpoles, 0.0);
888 UpdateCoefficients();
892 //=======================================================================
893 //function : CoefficientsOK
895 //=======================================================================
897 //Standard_Boolean Geom2d_BezierCurve::CoefficientsOK(const Standard_Real U)const
898 Standard_Boolean Geom2d_BezierCurve::CoefficientsOK(const Standard_Real )const
900 return (validcache) ;
905 //=======================================================================
906 //function : UpdateCoefficients
908 //=======================================================================
910 //void Geom2d_BezierCurve::UpdateCoefficients(const Standard_Real U)
911 void Geom2d_BezierCurve::UpdateCoefficients(const Standard_Real )
916 // Idee lumineuse sacrifiee sur l autel des performances.
917 // if (U >= 1.) parametercache = 1.;
918 TColStd_Array1OfReal bidflatknots(BSplCLib::FlatBezierKnots(Degree()),
921 BSplCLib::BuildCache(parametercache,spanlenghtcache,0,Degree(),
922 bidflatknots,poles->Array1(),weights->Array1(),
923 coeffs->ChangeArray1(),wcoeffs->ChangeArray1());
925 BSplCLib::BuildCache(parametercache,spanlenghtcache,0,Degree(),
926 bidflatknots,poles->Array1(),
927 *((TColStd_Array1OfReal*) NULL),
928 coeffs->ChangeArray1(),
929 *((TColStd_Array1OfReal*) NULL));