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>
38 #include <Standard_ConstructionError.hxx>
39 #include <Standard_DimensionError.hxx>
40 #include <Standard_OutOfRange.hxx>
41 #include <Standard_RangeError.hxx>
42 #include <Standard_Type.hxx>
43 #include <TColStd_Array1OfInteger.hxx>
44 #include <TColStd_Array1OfReal.hxx>
46 IMPLEMENT_STANDARD_RTTIEXT(Geom2d_BezierCurve,Geom2d_BoundedCurve)
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)
74 Handle(TColgp_HArray1OfPnt2d) npoles =
75 new TColgp_HArray1OfPnt2d(1,Poles.Length());
77 npoles->ChangeArray1() = Poles;
81 Handle(TColStd_HArray1OfReal)());
85 //=======================================================================
86 //function : Geom2d_BezierCurve
88 //=======================================================================
90 Geom2d_BezierCurve::Geom2d_BezierCurve
91 (const TColgp_Array1OfPnt2d& Poles,
92 const TColStd_Array1OfReal& Weights)
97 Handle(TColgp_HArray1OfPnt2d) npoles =
98 new TColgp_HArray1OfPnt2d(1,Poles.Length());
100 npoles->ChangeArray1() = Poles;
105 Standard_Integer nbpoles = Poles.Length();
107 if (Weights.Length() != nbpoles)
108 throw Standard_ConstructionError();
111 for (i = 1; i <= nbpoles; i++) {
112 if (Weights(i) <= gp::Resolution()) {
113 throw Standard_ConstructionError();
117 // check really rational
118 Standard_Boolean rat = Rational(Weights);
121 Handle(TColStd_HArray1OfReal) nweights;
123 nweights = new TColStd_HArray1OfReal(1,nbpoles);
124 nweights->ChangeArray1() = Weights;
128 Init(npoles,nweights);
132 //=======================================================================
133 //function : Increase
134 //purpose : increase degree
135 //=======================================================================
137 void Geom2d_BezierCurve::Increase (const Standard_Integer Deg)
139 if (Deg == Degree()) return;
141 Standard_ConstructionError_Raise_if
143 Deg > Geom2d_BezierCurve::MaxDegree(), "Geom2d_BezierCurve::Increase");
145 Handle(TColgp_HArray1OfPnt2d) npoles =
146 new TColgp_HArray1OfPnt2d(1,Deg+1);
148 Handle(TColStd_HArray1OfReal) nweights;
150 TColStd_Array1OfReal bidknots(1,2); bidknots(1) = 0.; bidknots(2) = 1.;
151 TColStd_Array1OfInteger bidmults(1,2); bidmults.Init(Degree() + 1);
154 nweights = new TColStd_HArray1OfReal(1,Deg+1);
155 BSplCLib::IncreaseDegree(Degree(), Deg, 0,
156 poles->Array1(),&weights->Array1(),
158 npoles->ChangeArray1(),&nweights->ChangeArray1(),
162 BSplCLib::IncreaseDegree(Degree(), Deg, 0,
164 BSplCLib::NoWeights(),
166 npoles->ChangeArray1(),
167 BSplCLib::NoWeights(),
171 Init(npoles,nweights);
175 //=======================================================================
176 //function : MaxDegree
178 //=======================================================================
180 Standard_Integer Geom2d_BezierCurve::MaxDegree ()
182 return BSplCLib::MaxDegree();
186 //=======================================================================
187 //function : InsertPoleAfter
189 //=======================================================================
191 void Geom2d_BezierCurve::InsertPoleAfter
192 (const Standard_Integer Index,
194 const Standard_Real Weight)
196 Standard_Integer nbpoles = NbPoles();
198 Standard_ConstructionError_Raise_if
199 (nbpoles >= Geom2d_BezierCurve::MaxDegree() ||
200 Weight <= gp::Resolution(),
201 "Geom2d_BezierCurve::InsertPoleAfter" );
203 Standard_OutOfRange_Raise_if
204 (Index < 0 || Index > nbpoles,
205 "Geom2d_BezierCurve::InsertPoleAfter");
210 Handle(TColgp_HArray1OfPnt2d) npoles =
211 new TColgp_HArray1OfPnt2d(1,nbpoles+1);
213 TColgp_Array1OfPnt2d& newpoles = npoles->ChangeArray1();
214 const TColgp_Array1OfPnt2d& oldpoles = poles->Array1();
216 for (i = 1; i <= Index; i++)
217 newpoles(i) = oldpoles(i);
219 newpoles(Index+1) = P;
221 for (i = Index+1; i <= nbpoles; i++)
222 newpoles(i+1) = oldpoles(i);
226 Handle(TColStd_HArray1OfReal) nweights;
227 Standard_Boolean rat = IsRational() || Abs(Weight-1.) > gp::Resolution();
230 nweights = new TColStd_HArray1OfReal(1,nbpoles+1);
231 TColStd_Array1OfReal& newweights = nweights->ChangeArray1();
233 for (i = 1; i <= Index; i++)
235 newweights(i) = weights->Value(i);
239 newweights(Index+1) = Weight;
241 for (i = Index+1; i <= nbpoles; i++)
243 newweights(i+1) = weights->Value(i);
245 newweights(i+1) = 1.;
249 Init(npoles,nweights);
253 //=======================================================================
254 //function : InsertPoleBefore
256 //=======================================================================
258 void Geom2d_BezierCurve::InsertPoleBefore
259 (const Standard_Integer Index,
261 const Standard_Real Weight)
263 InsertPoleAfter(Index-1,P,Weight);
267 //=======================================================================
268 //function : RemovePole
270 //=======================================================================
272 void Geom2d_BezierCurve::RemovePole
273 (const Standard_Integer Index)
275 Standard_Integer nbpoles = NbPoles();
277 Standard_ConstructionError_Raise_if
278 (nbpoles <= 2 , "Geom2d_BezierCurve::RemovePole" );
280 Standard_OutOfRange_Raise_if
281 (Index < 1 || Index > nbpoles,
282 "Geom2d_BezierCurve::RemovePole");
287 Handle(TColgp_HArray1OfPnt2d) npoles =
288 new TColgp_HArray1OfPnt2d(1,nbpoles-1);
290 TColgp_Array1OfPnt2d& newpoles = npoles->ChangeArray1();
291 const TColgp_Array1OfPnt2d& oldpoles = poles->Array1();
293 for (i = 1; i < Index; i++)
294 newpoles(i) = oldpoles(i);
296 for (i = Index+1; i <= nbpoles; i++)
297 newpoles(i-1) = oldpoles(i);
301 Handle(TColStd_HArray1OfReal) nweights;
304 nweights = new TColStd_HArray1OfReal(1,nbpoles-1);
305 TColStd_Array1OfReal& newweights = nweights->ChangeArray1();
306 const TColStd_Array1OfReal& oldweights = weights->Array1();
308 for (i = 1; i < Index; i++)
309 newweights(i) = oldweights(i);
311 for (i = Index+1; i <= nbpoles; i++)
312 newweights(i-1) = oldweights(i);
315 Init(npoles,nweights);
319 //=======================================================================
322 //=======================================================================
324 void Geom2d_BezierCurve::Reverse ()
327 Standard_Integer i, nbpoles = NbPoles();
328 TColgp_Array1OfPnt2d & cpoles = poles->ChangeArray1();
331 for (i = 1; i <= nbpoles / 2; i++) {
333 cpoles(i) = cpoles(nbpoles-i+1);
334 cpoles(nbpoles-i+1) = P;
339 TColStd_Array1OfReal & cweights = weights->ChangeArray1();
341 for (i = 1; i <= nbpoles / 2; i++) {
343 cweights(i) = cweights(nbpoles-i+1);
344 cweights(nbpoles-i+1) = w;
350 //=======================================================================
351 //function : ReversedParameter
353 //=======================================================================
355 Standard_Real Geom2d_BezierCurve::ReversedParameter
356 ( const Standard_Real U) const
362 //=======================================================================
365 //=======================================================================
367 void Geom2d_BezierCurve::Segment
368 (const Standard_Real U1, const Standard_Real U2)
370 closed = (Abs(Value(U1).Distance (Value(U2))) <= gp::Resolution());
372 // WARNING : when calling trimming be careful that the cache
373 // is computed regarding 0.0e0 and not 1.0e0
375 TColStd_Array1OfReal bidflatknots(BSplCLib::FlatBezierKnots(Degree()), 1, 2 * (Degree() + 1));
376 TColgp_Array1OfPnt2d coeffs(1, poles->Size());
378 TColStd_Array1OfReal wcoeffs(1, poles->Size());
379 BSplCLib::BuildCache(0.0, 1.0, 0, Degree(), bidflatknots,
380 poles->Array1(), &weights->Array1(), coeffs, &wcoeffs);
381 PLib::Trimming(U1, U2, coeffs, &wcoeffs);
382 PLib::CoefficientsPoles(coeffs, &wcoeffs, poles->ChangeArray1(), &weights->ChangeArray1());
385 BSplCLib::BuildCache(0.0, 1.0, 0, Degree(), bidflatknots,
386 poles->Array1(), BSplCLib::NoWeights(), coeffs, BSplCLib::NoWeights());
387 PLib::Trimming(U1, U2, coeffs, PLib::NoWeights());
388 PLib::CoefficientsPoles(coeffs, PLib::NoWeights(), poles->ChangeArray1(), PLib::NoWeights());
393 //=======================================================================
396 //=======================================================================
398 void Geom2d_BezierCurve::SetPole
399 (const Standard_Integer Index,
402 Standard_OutOfRange_Raise_if (Index < 1 || Index > NbPoles(),
403 "Geom2d_BezierCurve::SetPole");
405 TColgp_Array1OfPnt2d& cpoles = poles->ChangeArray1();
408 if (Index == 1 || Index == cpoles.Length()) {
409 closed = (cpoles(1).Distance(cpoles(NbPoles())) <= gp::Resolution());
414 //=======================================================================
417 //=======================================================================
419 void Geom2d_BezierCurve::SetPole
420 (const Standard_Integer Index,
422 const Standard_Real Weight)
425 SetWeight(Index,Weight);
429 //=======================================================================
430 //function : SetWeight
432 //=======================================================================
434 void Geom2d_BezierCurve::SetWeight
435 (const Standard_Integer Index,
436 const Standard_Real Weight)
438 Standard_Integer nbpoles = NbPoles();
440 Standard_OutOfRange_Raise_if
441 (Index < 1 || Index > nbpoles,
442 "Geom2d_BezierCurve::SetWeight");
443 Standard_ConstructionError_Raise_if
444 (Weight <= gp::Resolution (),
445 "Geom2d_BezierCurve::SetWeight");
448 // compute new rationality
449 Standard_Boolean wasrat = IsRational();
451 // a weight of 1. does not turn to rational
452 if (Abs(Weight - 1.) <= gp::Resolution()) return;
455 weights = new TColStd_HArray1OfReal(1,nbpoles);
459 TColStd_Array1OfReal & cweights = weights->ChangeArray1();
460 cweights(Index) = Weight;
462 // is it turning into non rational
463 if (wasrat && !Rational(cweights))
468 //=======================================================================
469 //function : IsClosed
471 //=======================================================================
473 Standard_Boolean Geom2d_BezierCurve::IsClosed () const
479 //=======================================================================
482 //=======================================================================
484 Standard_Boolean Geom2d_BezierCurve::IsCN (const Standard_Integer ) const
486 return Standard_True;
490 //=======================================================================
491 //function : IsPeriodic
493 //=======================================================================
495 Standard_Boolean Geom2d_BezierCurve::IsPeriodic () const
497 return Standard_False;
501 //=======================================================================
502 //function : IsRational
504 //=======================================================================
506 Standard_Boolean Geom2d_BezierCurve::IsRational () const
508 return !weights.IsNull();
512 //=======================================================================
513 //function : Continuity
515 //=======================================================================
517 GeomAbs_Shape Geom2d_BezierCurve::Continuity () const
523 //=======================================================================
526 //=======================================================================
528 Standard_Integer Geom2d_BezierCurve::Degree () const
530 return poles->Length()-1;
534 //=======================================================================
537 //=======================================================================
539 void Geom2d_BezierCurve::D0 (const Standard_Real U, gp_Pnt2d& P ) const
541 BSplCLib::D0(U, Poles(), Weights(), P);
544 //=======================================================================
547 //=======================================================================
549 void Geom2d_BezierCurve::D1(const Standard_Real U,
553 BSplCLib::D1(U, Poles(), Weights(), P, V1);
556 //=======================================================================
559 //=======================================================================
561 void Geom2d_BezierCurve::D2 (const Standard_Real U,
566 BSplCLib::D2(U, Poles(), Weights(), P, V1, V2);
569 //=======================================================================
572 //=======================================================================
574 void Geom2d_BezierCurve::D3 (const Standard_Real U,
580 BSplCLib::D3(U, Poles(), Weights(), P, V1, V2, V3);
583 //=======================================================================
586 //=======================================================================
588 gp_Vec2d Geom2d_BezierCurve::DN (const Standard_Real U,
589 const Standard_Integer N) const
591 Standard_RangeError_Raise_if (N < 1, "Geom2d_BezierCurve::DN");
594 TColStd_Array1OfReal bidknots(1,2); bidknots(1) = 0.; bidknots(2) = 1.;
595 TColStd_Array1OfInteger bidmults(1,2); bidmults.Init(Degree() + 1);
598 BSplCLib::DN(U,N,0,Degree(),Standard_False,
599 poles->Array1(),&weights->Array1(),
600 bidknots,&bidmults,V);
602 BSplCLib::DN(U,N,0,Degree(),Standard_False,
604 BSplCLib::NoWeights(),
605 bidknots,&bidmults,V);
609 //=======================================================================
610 //function : EndPoint
612 //=======================================================================
614 gp_Pnt2d Geom2d_BezierCurve::EndPoint () const
616 return poles->Value (poles->Upper());
620 //=======================================================================
621 //function : FirstParameter
623 //=======================================================================
625 Standard_Real Geom2d_BezierCurve::FirstParameter () const
631 //=======================================================================
632 //function : LastParameter
634 //=======================================================================
636 Standard_Real Geom2d_BezierCurve::LastParameter () const
642 //=======================================================================
645 //=======================================================================
647 Standard_Integer Geom2d_BezierCurve::NbPoles () const
649 return poles->Length();
653 //=======================================================================
656 //=======================================================================
658 const gp_Pnt2d& Geom2d_BezierCurve::Pole (const Standard_Integer Index) const
660 Standard_OutOfRange_Raise_if (Index < 1 || Index > poles->Length(),
661 "Geom2d_BezierCurve::Pole");
662 return poles->Value(Index);
666 //=======================================================================
669 //=======================================================================
671 void Geom2d_BezierCurve::Poles (TColgp_Array1OfPnt2d& P) const
673 Standard_DimensionError_Raise_if (P.Length() != poles->Length(),
674 "Geom2d_BezierCurve::Poles");
679 //=======================================================================
680 //function : StartPoint
682 //=======================================================================
684 gp_Pnt2d Geom2d_BezierCurve::StartPoint () const
686 return poles->Value(1);
690 //=======================================================================
693 //=======================================================================
695 Standard_Real Geom2d_BezierCurve::Weight
696 (const Standard_Integer Index) const
698 Standard_OutOfRange_Raise_if (Index < 1 || Index > weights->Length(),
699 "Geom2d_BezierCurve::Weight");
701 return weights->Value(Index);
707 //=======================================================================
710 //=======================================================================
712 void Geom2d_BezierCurve::Weights
713 (TColStd_Array1OfReal& W) const
716 Standard_Integer nbpoles = NbPoles();
717 Standard_DimensionError_Raise_if (W.Length() != nbpoles,
718 "Geom2d_BezierCurve::Weights");
720 W = weights->Array1();
723 for (i = 1; i <= nbpoles; i++)
729 //=======================================================================
730 //function : Transform
732 //=======================================================================
734 void Geom2d_BezierCurve::Transform (const gp_Trsf2d& T)
736 Standard_Integer nbpoles = NbPoles();
737 TColgp_Array1OfPnt2d & cpoles = poles->ChangeArray1();
739 for (Standard_Integer i = 1; i <= nbpoles; i++)
740 cpoles (i).Transform(T);
744 //=======================================================================
745 //function : Resolution
747 //=======================================================================
749 void Geom2d_BezierCurve::Resolution(const Standard_Real ToleranceUV,
750 Standard_Real & UTolerance)
753 TColStd_Array1OfReal bidflatknots(1, 2*(Degree()+1));
754 for(Standard_Integer i = 1; i <= Degree()+1; i++){
755 bidflatknots(i) = 0.;
756 bidflatknots(i + Degree() +1) = 1.;
760 BSplCLib::Resolution(poles->Array1(),
769 BSplCLib::Resolution(poles->Array1(),
770 BSplCLib::NoWeights(),
779 UTolerance = ToleranceUV * maxderivinv;
783 //=======================================================================
786 //=======================================================================
788 Handle(Geom2d_Geometry) Geom2d_BezierCurve::Copy() const {
790 Handle(Geom2d_BezierCurve) C;
792 C = new Geom2d_BezierCurve (poles->Array1(),weights->Array1());
794 C = new Geom2d_BezierCurve (poles->Array1());
799 //=======================================================================
802 //=======================================================================
804 void Geom2d_BezierCurve::Init
805 (const Handle(TColgp_HArray1OfPnt2d)& Poles,
806 const Handle(TColStd_HArray1OfReal)& Weights)
808 Standard_Integer nbpoles = Poles->Length();
810 const TColgp_Array1OfPnt2d& cpoles = Poles->Array1();
811 closed = cpoles(1).Distance(cpoles(nbpoles)) <= gp::Resolution();
814 rational = !Weights.IsNull();
824 //=======================================================================
825 //function : DumpJson
827 //=======================================================================
828 void Geom2d_BezierCurve::DumpJson (Standard_OStream& theOStream, Standard_Integer theDepth) const
830 OCCT_DUMP_TRANSIENT_CLASS_BEGIN (theOStream)
832 OCCT_DUMP_BASE_CLASS (theOStream, theDepth, Geom2d_BoundedCurve)
834 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, rational)
835 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, closed)
837 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, poles->Size())
838 if (!weights.IsNull())
839 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, weights->Size())
841 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, maxderivinv)
842 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, maxderivinvok)