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 <Geom2d_BezierCurve.hxx>
32 #include <Geom2d_Geometry.hxx>
34 #include <gp_Pnt2d.hxx>
35 #include <gp_Trsf2d.hxx>
36 #include <gp_Vec2d.hxx>
39 #include <Standard_ConstructionError.hxx>
40 #include <Standard_DimensionError.hxx>
41 #include <Standard_OutOfRange.hxx>
42 #include <Standard_RangeError.hxx>
43 #include <Standard_Type.hxx>
44 #include <TColStd_Array1OfInteger.hxx>
45 #include <TColStd_Array1OfReal.hxx>
47 //=======================================================================
49 //purpose : check rationality of an array of weights
50 //=======================================================================
51 static Standard_Boolean Rational(const TColStd_Array1OfReal& W)
53 Standard_Integer i, n = W.Length();
54 Standard_Boolean rat = Standard_False;
55 for (i = 1; i < n; i++) {
56 rat = Abs(W(i) - W(i+1)) > gp::Resolution();
63 //=======================================================================
64 //function : Geom2d_BezierCurve
66 //=======================================================================
68 Geom2d_BezierCurve::Geom2d_BezierCurve
69 (const TColgp_Array1OfPnt2d& Poles)
73 Handle(TColgp_HArray1OfPnt2d) npoles =
74 new TColgp_HArray1OfPnt2d(1,Poles.Length());
76 npoles->ChangeArray1() = Poles;
80 Handle(TColStd_HArray1OfReal)());
84 //=======================================================================
85 //function : Geom2d_BezierCurve
87 //=======================================================================
89 Geom2d_BezierCurve::Geom2d_BezierCurve
90 (const TColgp_Array1OfPnt2d& Poles,
91 const TColStd_Array1OfReal& Weights)
96 Handle(TColgp_HArray1OfPnt2d) npoles =
97 new TColgp_HArray1OfPnt2d(1,Poles.Length());
99 npoles->ChangeArray1() = Poles;
104 Standard_Integer nbpoles = Poles.Length();
106 if (Weights.Length() != nbpoles)
107 Standard_ConstructionError::Raise();
110 for (i = 1; i <= nbpoles; i++) {
111 if (Weights(i) <= gp::Resolution()) {
112 Standard_ConstructionError::Raise();
116 // check really rational
117 Standard_Boolean rat = Rational(Weights);
120 Handle(TColStd_HArray1OfReal) nweights;
122 nweights = new TColStd_HArray1OfReal(1,nbpoles);
123 nweights->ChangeArray1() = Weights;
127 Init(npoles,nweights);
131 //=======================================================================
132 //function : Increase
133 //purpose : increase degree
134 //=======================================================================
136 void Geom2d_BezierCurve::Increase (const Standard_Integer Deg)
138 if (Deg == Degree()) return;
140 Standard_ConstructionError_Raise_if
142 Deg > Geom2d_BezierCurve::MaxDegree(), "Geom2d_BezierCurve::Increase");
144 Handle(TColgp_HArray1OfPnt2d) npoles =
145 new TColgp_HArray1OfPnt2d(1,Deg+1);
147 Handle(TColStd_HArray1OfReal) nweights;
149 TColStd_Array1OfReal bidknots(1,2); bidknots(1) = 0.; bidknots(2) = 1.;
150 TColStd_Array1OfInteger bidmults(1,2); bidmults.Init(Degree() + 1);
153 nweights = new TColStd_HArray1OfReal(1,Deg+1);
154 BSplCLib::IncreaseDegree(Degree(), Deg, 0,
155 poles->Array1(),&weights->Array1(),
157 npoles->ChangeArray1(),&nweights->ChangeArray1(),
161 BSplCLib::IncreaseDegree(Degree(), Deg, 0,
163 BSplCLib::NoWeights(),
165 npoles->ChangeArray1(),
166 BSplCLib::NoWeights(),
170 Init(npoles,nweights);
174 //=======================================================================
175 //function : MaxDegree
177 //=======================================================================
179 Standard_Integer Geom2d_BezierCurve::MaxDegree ()
181 return BSplCLib::MaxDegree();
185 //=======================================================================
186 //function : InsertPoleAfter
188 //=======================================================================
190 void Geom2d_BezierCurve::InsertPoleAfter
191 (const Standard_Integer Index,
193 const Standard_Real Weight)
195 Standard_Integer nbpoles = NbPoles();
197 Standard_ConstructionError_Raise_if
198 (nbpoles >= Geom2d_BezierCurve::MaxDegree() ||
199 Weight <= gp::Resolution(),
200 "Geom2d_BezierCurve::InsertPoleAfter" );
202 Standard_OutOfRange_Raise_if
203 (Index < 0 || Index > nbpoles,
204 "Geom2d_BezierCurve::InsertPoleAfter");
209 Handle(TColgp_HArray1OfPnt2d) npoles =
210 new TColgp_HArray1OfPnt2d(1,nbpoles+1);
212 TColgp_Array1OfPnt2d& newpoles = npoles->ChangeArray1();
213 const TColgp_Array1OfPnt2d& oldpoles = poles->Array1();
215 for (i = 1; i <= Index; i++)
216 newpoles(i) = oldpoles(i);
218 newpoles(Index+1) = P;
220 for (i = Index+1; i <= nbpoles; i++)
221 newpoles(i+1) = oldpoles(i);
225 Handle(TColStd_HArray1OfReal) nweights;
226 Standard_Boolean rat = IsRational() || Abs(Weight-1.) > gp::Resolution();
229 nweights = new TColStd_HArray1OfReal(1,nbpoles+1);
230 TColStd_Array1OfReal& newweights = nweights->ChangeArray1();
232 for (i = 1; i <= Index; i++)
234 newweights(i) = weights->Value(i);
238 newweights(Index+1) = Weight;
240 for (i = Index+1; i <= nbpoles; i++)
242 newweights(i+1) = weights->Value(i);
244 newweights(i+1) = 1.;
248 Init(npoles,nweights);
252 //=======================================================================
253 //function : InsertPoleBefore
255 //=======================================================================
257 void Geom2d_BezierCurve::InsertPoleBefore
258 (const Standard_Integer Index,
260 const Standard_Real Weight)
262 InsertPoleAfter(Index-1,P,Weight);
266 //=======================================================================
267 //function : RemovePole
269 //=======================================================================
271 void Geom2d_BezierCurve::RemovePole
272 (const Standard_Integer Index)
274 Standard_Integer nbpoles = NbPoles();
276 Standard_ConstructionError_Raise_if
277 (nbpoles <= 2 , "Geom2d_BezierCurve::RemovePole" );
279 Standard_OutOfRange_Raise_if
280 (Index < 1 || Index > nbpoles,
281 "Geom2d_BezierCurve::RemovePole");
286 Handle(TColgp_HArray1OfPnt2d) npoles =
287 new TColgp_HArray1OfPnt2d(1,nbpoles-1);
289 TColgp_Array1OfPnt2d& newpoles = npoles->ChangeArray1();
290 const TColgp_Array1OfPnt2d& oldpoles = poles->Array1();
292 for (i = 1; i < Index; i++)
293 newpoles(i) = oldpoles(i);
295 for (i = Index+1; i <= nbpoles; i++)
296 newpoles(i-1) = oldpoles(i);
300 Handle(TColStd_HArray1OfReal) nweights;
303 nweights = new TColStd_HArray1OfReal(1,nbpoles-1);
304 TColStd_Array1OfReal& newweights = nweights->ChangeArray1();
305 const TColStd_Array1OfReal& oldweights = weights->Array1();
307 for (i = 1; i < Index; i++)
308 newweights(i) = oldweights(i);
310 for (i = Index+1; i <= nbpoles; i++)
311 newweights(i-1) = oldweights(i);
314 Init(npoles,nweights);
318 //=======================================================================
321 //=======================================================================
323 void Geom2d_BezierCurve::Reverse ()
326 Standard_Integer i, nbpoles = NbPoles();
327 TColgp_Array1OfPnt2d & cpoles = poles->ChangeArray1();
330 for (i = 1; i <= nbpoles / 2; i++) {
332 cpoles(i) = cpoles(nbpoles-i+1);
333 cpoles(nbpoles-i+1) = P;
338 TColStd_Array1OfReal & cweights = weights->ChangeArray1();
340 for (i = 1; i <= nbpoles / 2; i++) {
342 cweights(i) = cweights(nbpoles-i+1);
343 cweights(nbpoles-i+1) = w;
349 //=======================================================================
350 //function : ReversedParameter
352 //=======================================================================
354 Standard_Real Geom2d_BezierCurve::ReversedParameter
355 ( const Standard_Real U) const
361 //=======================================================================
364 //=======================================================================
366 void Geom2d_BezierCurve::Segment
367 (const Standard_Real U1, const Standard_Real U2)
369 closed = (Abs(Value(U1).Distance (Value(U2))) <= gp::Resolution());
371 // WARNING : when calling trimming be carefull that the cache
372 // is computed regarding 0.0e0 and not 1.0e0
374 TColStd_Array1OfReal bidflatknots(BSplCLib::FlatBezierKnots(Degree()), 1, 2 * (Degree() + 1));
375 TColgp_Array1OfPnt2d coeffs(1, poles->Size());
377 TColStd_Array1OfReal wcoeffs(1, poles->Size());
378 BSplCLib::BuildCache(0.0, 1.0, 0, Degree(), bidflatknots,
379 poles->Array1(), &weights->Array1(), coeffs, &wcoeffs);
380 PLib::Trimming(U1, U2, coeffs, &wcoeffs);
381 PLib::CoefficientsPoles(coeffs, &wcoeffs, poles->ChangeArray1(), &weights->ChangeArray1());
384 BSplCLib::BuildCache(0.0, 1.0, 0, Degree(), bidflatknots,
385 poles->Array1(), BSplCLib::NoWeights(), coeffs, BSplCLib::NoWeights());
386 PLib::Trimming(U1, U2, coeffs, PLib::NoWeights());
387 PLib::CoefficientsPoles(coeffs, PLib::NoWeights(), poles->ChangeArray1(), PLib::NoWeights());
392 //=======================================================================
395 //=======================================================================
397 void Geom2d_BezierCurve::SetPole
398 (const Standard_Integer Index,
401 Standard_OutOfRange_Raise_if (Index < 1 || Index > NbPoles(),
402 "Geom2d_BezierCurve::SetPole");
404 TColgp_Array1OfPnt2d& cpoles = poles->ChangeArray1();
407 if (Index == 1 || Index == cpoles.Length()) {
408 closed = (cpoles(1).Distance(cpoles(NbPoles())) <= gp::Resolution());
413 //=======================================================================
416 //=======================================================================
418 void Geom2d_BezierCurve::SetPole
419 (const Standard_Integer Index,
421 const Standard_Real Weight)
424 SetWeight(Index,Weight);
428 //=======================================================================
429 //function : SetWeight
431 //=======================================================================
433 void Geom2d_BezierCurve::SetWeight
434 (const Standard_Integer Index,
435 const Standard_Real Weight)
437 Standard_Integer nbpoles = NbPoles();
439 Standard_OutOfRange_Raise_if
440 (Index < 1 || Index > nbpoles,
441 "Geom2d_BezierCurve::SetWeight");
442 Standard_ConstructionError_Raise_if
443 (Weight <= gp::Resolution (),
444 "Geom2d_BezierCurve::SetWeight");
447 // compute new rationality
448 Standard_Boolean wasrat = IsRational();
450 // a weight of 1. does not turn to rational
451 if (Abs(Weight - 1.) <= gp::Resolution()) return;
454 weights = new TColStd_HArray1OfReal(1,nbpoles);
458 TColStd_Array1OfReal & cweights = weights->ChangeArray1();
459 cweights(Index) = Weight;
461 // is it turning into non rational
462 if (wasrat && !Rational(cweights))
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 BSplCLib::D0(U, Poles(), Weights(), P);
543 //=======================================================================
546 //=======================================================================
548 void Geom2d_BezierCurve::D1(const Standard_Real U,
552 BSplCLib::D1(U, Poles(), Weights(), P, V1);
555 //=======================================================================
558 //=======================================================================
560 void Geom2d_BezierCurve::D2 (const Standard_Real U,
565 BSplCLib::D2(U, Poles(), Weights(), P, V1, V2);
568 //=======================================================================
571 //=======================================================================
573 void Geom2d_BezierCurve::D3 (const Standard_Real U,
579 BSplCLib::D3(U, Poles(), Weights(), P, V1, V2, V3);
582 //=======================================================================
585 //=======================================================================
587 gp_Vec2d Geom2d_BezierCurve::DN (const Standard_Real U,
588 const Standard_Integer N) const
590 Standard_RangeError_Raise_if (N < 1, "Geom2d_BezierCurve::DN");
593 TColStd_Array1OfReal bidknots(1,2); bidknots(1) = 0.; bidknots(2) = 1.;
594 TColStd_Array1OfInteger bidmults(1,2); bidmults.Init(Degree() + 1);
597 BSplCLib::DN(U,N,0,Degree(),Standard_False,
598 poles->Array1(),&weights->Array1(),
599 bidknots,&bidmults,V);
601 BSplCLib::DN(U,N,0,Degree(),Standard_False,
603 BSplCLib::NoWeights(),
604 bidknots,&bidmults,V);
608 //=======================================================================
609 //function : EndPoint
611 //=======================================================================
613 gp_Pnt2d Geom2d_BezierCurve::EndPoint () const
615 return poles->Value (poles->Upper());
619 //=======================================================================
620 //function : FirstParameter
622 //=======================================================================
624 Standard_Real Geom2d_BezierCurve::FirstParameter () const
630 //=======================================================================
631 //function : LastParameter
633 //=======================================================================
635 Standard_Real Geom2d_BezierCurve::LastParameter () const
641 //=======================================================================
644 //=======================================================================
646 Standard_Integer Geom2d_BezierCurve::NbPoles () const
648 return poles->Length();
652 //=======================================================================
655 //=======================================================================
657 gp_Pnt2d Geom2d_BezierCurve::Pole (const Standard_Integer Index) const
659 Standard_OutOfRange_Raise_if (Index < 1 || Index > poles->Length(),
660 "Geom2d_BezierCurve::Pole");
661 return poles->Value(Index);
665 //=======================================================================
668 //=======================================================================
670 void Geom2d_BezierCurve::Poles (TColgp_Array1OfPnt2d& P) const
672 Standard_DimensionError_Raise_if (P.Length() != poles->Length(),
673 "Geom2d_BezierCurve::Poles");
678 //=======================================================================
679 //function : StartPoint
681 //=======================================================================
683 gp_Pnt2d Geom2d_BezierCurve::StartPoint () const
685 return poles->Value(1);
689 //=======================================================================
692 //=======================================================================
694 Standard_Real Geom2d_BezierCurve::Weight
695 (const Standard_Integer Index) const
697 Standard_OutOfRange_Raise_if (Index < 1 || Index > weights->Length(),
698 "Geom2d_BezierCurve::Weight");
700 return weights->Value(Index);
706 //=======================================================================
709 //=======================================================================
711 void Geom2d_BezierCurve::Weights
712 (TColStd_Array1OfReal& W) const
715 Standard_Integer nbpoles = NbPoles();
716 Standard_DimensionError_Raise_if (W.Length() != nbpoles,
717 "Geom2d_BezierCurve::Weights");
719 W = weights->Array1();
722 for (i = 1; i <= nbpoles; i++)
728 //=======================================================================
729 //function : Transform
731 //=======================================================================
733 void Geom2d_BezierCurve::Transform (const gp_Trsf2d& T)
735 Standard_Integer nbpoles = NbPoles();
736 TColgp_Array1OfPnt2d & cpoles = poles->ChangeArray1();
738 for (Standard_Integer i = 1; i <= nbpoles; i++)
739 cpoles (i).Transform(T);
743 //=======================================================================
744 //function : Resolution
746 //=======================================================================
748 void Geom2d_BezierCurve::Resolution(const Standard_Real ToleranceUV,
749 Standard_Real & UTolerance)
752 TColStd_Array1OfReal bidflatknots(1, 2*(Degree()+1));
753 for(Standard_Integer i = 1; i <= Degree()+1; i++){
754 bidflatknots(i) = 0.;
755 bidflatknots(i + Degree() +1) = 1.;
759 BSplCLib::Resolution(poles->Array1(),
768 BSplCLib::Resolution(poles->Array1(),
769 BSplCLib::NoWeights(),
778 UTolerance = ToleranceUV * maxderivinv;
782 //=======================================================================
785 //=======================================================================
787 Handle(Geom2d_Geometry) Geom2d_BezierCurve::Copy() const {
789 Handle(Geom2d_BezierCurve) C;
791 C = new Geom2d_BezierCurve (poles->Array1(),weights->Array1());
793 C = new Geom2d_BezierCurve (poles->Array1());
798 //=======================================================================
801 //=======================================================================
803 void Geom2d_BezierCurve::Init
804 (const Handle(TColgp_HArray1OfPnt2d)& Poles,
805 const Handle(TColStd_HArray1OfReal)& Weights)
807 Standard_Integer nbpoles = Poles->Length();
809 const TColgp_Array1OfPnt2d& cpoles = Poles->Array1();
810 closed = cpoles(1).Distance(cpoles(nbpoles)) <= gp::Resolution();
813 rational = !Weights.IsNull();