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 IMPLEMENT_STANDARD_RTTIEXT(Geom2d_BezierCurve,Geom2d_BoundedCurve)
49 //=======================================================================
51 //purpose : check rationality of an array of weights
52 //=======================================================================
53 static Standard_Boolean Rational(const TColStd_Array1OfReal& W)
55 Standard_Integer i, n = W.Length();
56 Standard_Boolean rat = Standard_False;
57 for (i = 1; i < n; i++) {
58 rat = Abs(W(i) - W(i+1)) > gp::Resolution();
65 //=======================================================================
66 //function : Geom2d_BezierCurve
68 //=======================================================================
70 Geom2d_BezierCurve::Geom2d_BezierCurve
71 (const TColgp_Array1OfPnt2d& Poles)
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)
98 Handle(TColgp_HArray1OfPnt2d) npoles =
99 new TColgp_HArray1OfPnt2d(1,Poles.Length());
101 npoles->ChangeArray1() = Poles;
106 Standard_Integer nbpoles = Poles.Length();
108 if (Weights.Length() != nbpoles)
109 throw Standard_ConstructionError();
112 for (i = 1; i <= nbpoles; i++) {
113 if (Weights(i) <= gp::Resolution()) {
114 throw Standard_ConstructionError();
118 // check really rational
119 Standard_Boolean rat = Rational(Weights);
122 Handle(TColStd_HArray1OfReal) nweights;
124 nweights = new TColStd_HArray1OfReal(1,nbpoles);
125 nweights->ChangeArray1() = Weights;
129 Init(npoles,nweights);
133 //=======================================================================
134 //function : Increase
135 //purpose : increase degree
136 //=======================================================================
138 void Geom2d_BezierCurve::Increase (const Standard_Integer Deg)
140 if (Deg == Degree()) return;
142 Standard_ConstructionError_Raise_if
144 Deg > Geom2d_BezierCurve::MaxDegree(), "Geom2d_BezierCurve::Increase");
146 Handle(TColgp_HArray1OfPnt2d) npoles =
147 new TColgp_HArray1OfPnt2d(1,Deg+1);
149 Handle(TColStd_HArray1OfReal) nweights;
151 TColStd_Array1OfReal bidknots(1,2); bidknots(1) = 0.; bidknots(2) = 1.;
152 TColStd_Array1OfInteger bidmults(1,2); bidmults.Init(Degree() + 1);
155 nweights = new TColStd_HArray1OfReal(1,Deg+1);
156 BSplCLib::IncreaseDegree(Degree(), Deg, 0,
157 poles->Array1(),&weights->Array1(),
159 npoles->ChangeArray1(),&nweights->ChangeArray1(),
163 BSplCLib::IncreaseDegree(Degree(), Deg, 0,
165 BSplCLib::NoWeights(),
167 npoles->ChangeArray1(),
168 BSplCLib::NoWeights(),
172 Init(npoles,nweights);
176 //=======================================================================
177 //function : MaxDegree
179 //=======================================================================
181 Standard_Integer Geom2d_BezierCurve::MaxDegree ()
183 return BSplCLib::MaxDegree();
187 //=======================================================================
188 //function : InsertPoleAfter
190 //=======================================================================
192 void Geom2d_BezierCurve::InsertPoleAfter
193 (const Standard_Integer Index,
195 const Standard_Real Weight)
197 Standard_Integer nbpoles = NbPoles();
199 Standard_ConstructionError_Raise_if
200 (nbpoles >= Geom2d_BezierCurve::MaxDegree() ||
201 Weight <= gp::Resolution(),
202 "Geom2d_BezierCurve::InsertPoleAfter" );
204 Standard_OutOfRange_Raise_if
205 (Index < 0 || Index > nbpoles,
206 "Geom2d_BezierCurve::InsertPoleAfter");
211 Handle(TColgp_HArray1OfPnt2d) npoles =
212 new TColgp_HArray1OfPnt2d(1,nbpoles+1);
214 TColgp_Array1OfPnt2d& newpoles = npoles->ChangeArray1();
215 const TColgp_Array1OfPnt2d& oldpoles = poles->Array1();
217 for (i = 1; i <= Index; i++)
218 newpoles(i) = oldpoles(i);
220 newpoles(Index+1) = P;
222 for (i = Index+1; i <= nbpoles; i++)
223 newpoles(i+1) = oldpoles(i);
227 Handle(TColStd_HArray1OfReal) nweights;
228 Standard_Boolean rat = IsRational() || Abs(Weight-1.) > gp::Resolution();
231 nweights = new TColStd_HArray1OfReal(1,nbpoles+1);
232 TColStd_Array1OfReal& newweights = nweights->ChangeArray1();
234 for (i = 1; i <= Index; i++)
236 newweights(i) = weights->Value(i);
240 newweights(Index+1) = Weight;
242 for (i = Index+1; i <= nbpoles; i++)
244 newweights(i+1) = weights->Value(i);
246 newweights(i+1) = 1.;
250 Init(npoles,nweights);
254 //=======================================================================
255 //function : InsertPoleBefore
257 //=======================================================================
259 void Geom2d_BezierCurve::InsertPoleBefore
260 (const Standard_Integer Index,
262 const Standard_Real Weight)
264 InsertPoleAfter(Index-1,P,Weight);
268 //=======================================================================
269 //function : RemovePole
271 //=======================================================================
273 void Geom2d_BezierCurve::RemovePole
274 (const Standard_Integer Index)
276 Standard_Integer nbpoles = NbPoles();
278 Standard_ConstructionError_Raise_if
279 (nbpoles <= 2 , "Geom2d_BezierCurve::RemovePole" );
281 Standard_OutOfRange_Raise_if
282 (Index < 1 || Index > nbpoles,
283 "Geom2d_BezierCurve::RemovePole");
288 Handle(TColgp_HArray1OfPnt2d) npoles =
289 new TColgp_HArray1OfPnt2d(1,nbpoles-1);
291 TColgp_Array1OfPnt2d& newpoles = npoles->ChangeArray1();
292 const TColgp_Array1OfPnt2d& oldpoles = poles->Array1();
294 for (i = 1; i < Index; i++)
295 newpoles(i) = oldpoles(i);
297 for (i = Index+1; i <= nbpoles; i++)
298 newpoles(i-1) = oldpoles(i);
302 Handle(TColStd_HArray1OfReal) nweights;
305 nweights = new TColStd_HArray1OfReal(1,nbpoles-1);
306 TColStd_Array1OfReal& newweights = nweights->ChangeArray1();
307 const TColStd_Array1OfReal& oldweights = weights->Array1();
309 for (i = 1; i < Index; i++)
310 newweights(i) = oldweights(i);
312 for (i = Index+1; i <= nbpoles; i++)
313 newweights(i-1) = oldweights(i);
316 Init(npoles,nweights);
320 //=======================================================================
323 //=======================================================================
325 void Geom2d_BezierCurve::Reverse ()
328 Standard_Integer i, nbpoles = NbPoles();
329 TColgp_Array1OfPnt2d & cpoles = poles->ChangeArray1();
332 for (i = 1; i <= nbpoles / 2; i++) {
334 cpoles(i) = cpoles(nbpoles-i+1);
335 cpoles(nbpoles-i+1) = P;
340 TColStd_Array1OfReal & cweights = weights->ChangeArray1();
342 for (i = 1; i <= nbpoles / 2; i++) {
344 cweights(i) = cweights(nbpoles-i+1);
345 cweights(nbpoles-i+1) = w;
351 //=======================================================================
352 //function : ReversedParameter
354 //=======================================================================
356 Standard_Real Geom2d_BezierCurve::ReversedParameter
357 ( const Standard_Real U) const
363 //=======================================================================
366 //=======================================================================
368 void Geom2d_BezierCurve::Segment
369 (const Standard_Real U1, const Standard_Real U2)
371 closed = (Abs(Value(U1).Distance (Value(U2))) <= gp::Resolution());
373 // WARNING : when calling trimming be carefull that the cache
374 // is computed regarding 0.0e0 and not 1.0e0
376 TColStd_Array1OfReal bidflatknots(BSplCLib::FlatBezierKnots(Degree()), 1, 2 * (Degree() + 1));
377 TColgp_Array1OfPnt2d coeffs(1, poles->Size());
379 TColStd_Array1OfReal wcoeffs(1, poles->Size());
380 BSplCLib::BuildCache(0.0, 1.0, 0, Degree(), bidflatknots,
381 poles->Array1(), &weights->Array1(), coeffs, &wcoeffs);
382 PLib::Trimming(U1, U2, coeffs, &wcoeffs);
383 PLib::CoefficientsPoles(coeffs, &wcoeffs, poles->ChangeArray1(), &weights->ChangeArray1());
386 BSplCLib::BuildCache(0.0, 1.0, 0, Degree(), bidflatknots,
387 poles->Array1(), BSplCLib::NoWeights(), coeffs, BSplCLib::NoWeights());
388 PLib::Trimming(U1, U2, coeffs, PLib::NoWeights());
389 PLib::CoefficientsPoles(coeffs, PLib::NoWeights(), poles->ChangeArray1(), PLib::NoWeights());
394 //=======================================================================
397 //=======================================================================
399 void Geom2d_BezierCurve::SetPole
400 (const Standard_Integer Index,
403 Standard_OutOfRange_Raise_if (Index < 1 || Index > NbPoles(),
404 "Geom2d_BezierCurve::SetPole");
406 TColgp_Array1OfPnt2d& cpoles = poles->ChangeArray1();
409 if (Index == 1 || Index == cpoles.Length()) {
410 closed = (cpoles(1).Distance(cpoles(NbPoles())) <= gp::Resolution());
415 //=======================================================================
418 //=======================================================================
420 void Geom2d_BezierCurve::SetPole
421 (const Standard_Integer Index,
423 const Standard_Real Weight)
426 SetWeight(Index,Weight);
430 //=======================================================================
431 //function : SetWeight
433 //=======================================================================
435 void Geom2d_BezierCurve::SetWeight
436 (const Standard_Integer Index,
437 const Standard_Real Weight)
439 Standard_Integer nbpoles = NbPoles();
441 Standard_OutOfRange_Raise_if
442 (Index < 1 || Index > nbpoles,
443 "Geom2d_BezierCurve::SetWeight");
444 Standard_ConstructionError_Raise_if
445 (Weight <= gp::Resolution (),
446 "Geom2d_BezierCurve::SetWeight");
449 // compute new rationality
450 Standard_Boolean wasrat = IsRational();
452 // a weight of 1. does not turn to rational
453 if (Abs(Weight - 1.) <= gp::Resolution()) return;
456 weights = new TColStd_HArray1OfReal(1,nbpoles);
460 TColStd_Array1OfReal & cweights = weights->ChangeArray1();
461 cweights(Index) = Weight;
463 // is it turning into non rational
464 if (wasrat && !Rational(cweights))
469 //=======================================================================
470 //function : IsClosed
472 //=======================================================================
474 Standard_Boolean Geom2d_BezierCurve::IsClosed () const
480 //=======================================================================
483 //=======================================================================
485 Standard_Boolean Geom2d_BezierCurve::IsCN (const Standard_Integer ) const
487 return Standard_True;
491 //=======================================================================
492 //function : IsPeriodic
494 //=======================================================================
496 Standard_Boolean Geom2d_BezierCurve::IsPeriodic () const
498 return Standard_False;
502 //=======================================================================
503 //function : IsRational
505 //=======================================================================
507 Standard_Boolean Geom2d_BezierCurve::IsRational () const
509 return !weights.IsNull();
513 //=======================================================================
514 //function : Continuity
516 //=======================================================================
518 GeomAbs_Shape Geom2d_BezierCurve::Continuity () const
524 //=======================================================================
527 //=======================================================================
529 Standard_Integer Geom2d_BezierCurve::Degree () const
531 return poles->Length()-1;
535 //=======================================================================
538 //=======================================================================
540 void Geom2d_BezierCurve::D0 (const Standard_Real U, gp_Pnt2d& P ) const
542 BSplCLib::D0(U, Poles(), Weights(), P);
545 //=======================================================================
548 //=======================================================================
550 void Geom2d_BezierCurve::D1(const Standard_Real U,
554 BSplCLib::D1(U, Poles(), Weights(), P, V1);
557 //=======================================================================
560 //=======================================================================
562 void Geom2d_BezierCurve::D2 (const Standard_Real U,
567 BSplCLib::D2(U, Poles(), Weights(), P, V1, V2);
570 //=======================================================================
573 //=======================================================================
575 void Geom2d_BezierCurve::D3 (const Standard_Real U,
581 BSplCLib::D3(U, Poles(), Weights(), P, V1, V2, V3);
584 //=======================================================================
587 //=======================================================================
589 gp_Vec2d Geom2d_BezierCurve::DN (const Standard_Real U,
590 const Standard_Integer N) const
592 Standard_RangeError_Raise_if (N < 1, "Geom2d_BezierCurve::DN");
595 TColStd_Array1OfReal bidknots(1,2); bidknots(1) = 0.; bidknots(2) = 1.;
596 TColStd_Array1OfInteger bidmults(1,2); bidmults.Init(Degree() + 1);
599 BSplCLib::DN(U,N,0,Degree(),Standard_False,
600 poles->Array1(),&weights->Array1(),
601 bidknots,&bidmults,V);
603 BSplCLib::DN(U,N,0,Degree(),Standard_False,
605 BSplCLib::NoWeights(),
606 bidknots,&bidmults,V);
610 //=======================================================================
611 //function : EndPoint
613 //=======================================================================
615 gp_Pnt2d Geom2d_BezierCurve::EndPoint () const
617 return poles->Value (poles->Upper());
621 //=======================================================================
622 //function : FirstParameter
624 //=======================================================================
626 Standard_Real Geom2d_BezierCurve::FirstParameter () const
632 //=======================================================================
633 //function : LastParameter
635 //=======================================================================
637 Standard_Real Geom2d_BezierCurve::LastParameter () const
643 //=======================================================================
646 //=======================================================================
648 Standard_Integer Geom2d_BezierCurve::NbPoles () const
650 return poles->Length();
654 //=======================================================================
657 //=======================================================================
659 const gp_Pnt2d& Geom2d_BezierCurve::Pole (const Standard_Integer Index) const
661 Standard_OutOfRange_Raise_if (Index < 1 || Index > poles->Length(),
662 "Geom2d_BezierCurve::Pole");
663 return poles->Value(Index);
667 //=======================================================================
670 //=======================================================================
672 void Geom2d_BezierCurve::Poles (TColgp_Array1OfPnt2d& P) const
674 Standard_DimensionError_Raise_if (P.Length() != poles->Length(),
675 "Geom2d_BezierCurve::Poles");
680 //=======================================================================
681 //function : StartPoint
683 //=======================================================================
685 gp_Pnt2d Geom2d_BezierCurve::StartPoint () const
687 return poles->Value(1);
691 //=======================================================================
694 //=======================================================================
696 Standard_Real Geom2d_BezierCurve::Weight
697 (const Standard_Integer Index) const
699 Standard_OutOfRange_Raise_if (Index < 1 || Index > weights->Length(),
700 "Geom2d_BezierCurve::Weight");
702 return weights->Value(Index);
708 //=======================================================================
711 //=======================================================================
713 void Geom2d_BezierCurve::Weights
714 (TColStd_Array1OfReal& W) const
717 Standard_Integer nbpoles = NbPoles();
718 Standard_DimensionError_Raise_if (W.Length() != nbpoles,
719 "Geom2d_BezierCurve::Weights");
721 W = weights->Array1();
724 for (i = 1; i <= nbpoles; i++)
730 //=======================================================================
731 //function : Transform
733 //=======================================================================
735 void Geom2d_BezierCurve::Transform (const gp_Trsf2d& T)
737 Standard_Integer nbpoles = NbPoles();
738 TColgp_Array1OfPnt2d & cpoles = poles->ChangeArray1();
740 for (Standard_Integer i = 1; i <= nbpoles; i++)
741 cpoles (i).Transform(T);
745 //=======================================================================
746 //function : Resolution
748 //=======================================================================
750 void Geom2d_BezierCurve::Resolution(const Standard_Real ToleranceUV,
751 Standard_Real & UTolerance)
754 TColStd_Array1OfReal bidflatknots(1, 2*(Degree()+1));
755 for(Standard_Integer i = 1; i <= Degree()+1; i++){
756 bidflatknots(i) = 0.;
757 bidflatknots(i + Degree() +1) = 1.;
761 BSplCLib::Resolution(poles->Array1(),
770 BSplCLib::Resolution(poles->Array1(),
771 BSplCLib::NoWeights(),
780 UTolerance = ToleranceUV * maxderivinv;
784 //=======================================================================
787 //=======================================================================
789 Handle(Geom2d_Geometry) Geom2d_BezierCurve::Copy() const {
791 Handle(Geom2d_BezierCurve) C;
793 C = new Geom2d_BezierCurve (poles->Array1(),weights->Array1());
795 C = new Geom2d_BezierCurve (poles->Array1());
800 //=======================================================================
803 //=======================================================================
805 void Geom2d_BezierCurve::Init
806 (const Handle(TColgp_HArray1OfPnt2d)& Poles,
807 const Handle(TColStd_HArray1OfReal)& Weights)
809 Standard_Integer nbpoles = Poles->Length();
811 const TColgp_Array1OfPnt2d& cpoles = Poles->Array1();
812 closed = cpoles(1).Distance(cpoles(nbpoles)) <= gp::Resolution();
815 rational = !Weights.IsNull();