1 // Created on: 1993-06-04
2 // Created by: Bruno DUMORTIER
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 // 20/02/97 : PMN -> Positionement local sur BSpline (PRO6902)
18 // 10/07/97 : PMN -> Pas de calcul de resolution dans Nb(Intervals) (PRO9248)
19 // 20/10/97 : JPI -> traitement des offset curves
21 #define No_Standard_RangeError
22 #define No_Standard_OutOfRange
24 #include <Geom2dAdaptor_Curve.hxx>
26 #include <Adaptor2d_Curve2d.hxx>
27 #include <BSplCLib.hxx>
28 #include <BSplCLib_Cache.hxx>
29 #include <Geom2d_BezierCurve.hxx>
30 #include <Geom2d_BSplineCurve.hxx>
31 #include <Geom2d_Circle.hxx>
32 #include <Geom2d_Curve.hxx>
33 #include <Geom2d_Ellipse.hxx>
34 #include <Geom2d_Hyperbola.hxx>
35 #include <Geom2d_Line.hxx>
36 #include <Geom2d_OffsetCurve.hxx>
37 #include <Geom2d_Parabola.hxx>
38 #include <Geom2d_TrimmedCurve.hxx>
39 #include <Geom2d_UndefinedDerivative.hxx>
40 #include <Geom2dEvaluator_OffsetCurve.hxx>
41 #include <GeomAbs_Shape.hxx>
42 #include <gp_Circ2d.hxx>
43 #include <gp_Elips2d.hxx>
44 #include <gp_Hypr2d.hxx>
45 #include <gp_Lin2d.hxx>
46 #include <gp_Parab2d.hxx>
47 #include <gp_Pnt2d.hxx>
48 #include <gp_Vec2d.hxx>
49 #include <Precision.hxx>
50 #include <Standard_DomainError.hxx>
51 #include <Standard_NoSuchObject.hxx>
52 #include <Standard_NotImplemented.hxx>
53 #include <TColStd_Array1OfInteger.hxx>
54 #include <TColStd_Array1OfReal.hxx>
56 //#include <Geom2dConvert_BSplineCurveKnotSplitting.hxx>
57 static const Standard_Real PosTol = Precision::PConfusion() / 2;
59 IMPLEMENT_STANDARD_RTTIEXT(Geom2dAdaptor_Curve, Adaptor2d_Curve2d)
61 //=======================================================================
62 //function : ShallowCopy
64 //=======================================================================
66 Handle(Adaptor2d_Curve2d) Geom2dAdaptor_Curve::ShallowCopy() const
68 Handle(Geom2dAdaptor_Curve) aCopy = new Geom2dAdaptor_Curve();
70 aCopy->myCurve = myCurve;
71 aCopy->myTypeCurve = myTypeCurve;
72 aCopy->myFirst = myFirst;
73 aCopy->myLast = myLast;
74 aCopy->myBSplineCurve = myBSplineCurve;
75 if(!myNestedEvaluator.IsNull())
77 aCopy->myNestedEvaluator = myNestedEvaluator->ShallowCopy();
83 //=======================================================================
84 //function : LocalContinuity
85 //purpose : Computes the Continuity of a BSplineCurve
86 // between the parameters U1 and U2
87 // The continuity is C(d-m)
89 // m = max multiplicity of the Knots between U1 and U2
90 //=======================================================================
92 GeomAbs_Shape Geom2dAdaptor_Curve::LocalContinuity(const Standard_Real U1,
93 const Standard_Real U2) const
95 Standard_NoSuchObject_Raise_if(myTypeCurve!=GeomAbs_BSplineCurve," ");
96 Standard_Integer Nb = myBSplineCurve->NbKnots();
97 Standard_Integer Index1 = 0;
98 Standard_Integer Index2 = 0;
99 Standard_Real newFirst, newLast;
100 TColStd_Array1OfReal TK(1,Nb);
101 TColStd_Array1OfInteger TM(1,Nb);
102 myBSplineCurve->Knots(TK);
103 myBSplineCurve->Multiplicities(TM);
104 BSplCLib::LocateParameter(myBSplineCurve->Degree(),TK,TM,U1,myBSplineCurve->IsPeriodic(),
105 1,Nb,Index1,newFirst);
106 BSplCLib::LocateParameter(myBSplineCurve->Degree(),TK,TM,U2,myBSplineCurve->IsPeriodic(),
107 1,Nb,Index2,newLast);
108 if ( Abs(newFirst-TK(Index1+1))<Precision::PConfusion()) {
109 if (Index1 < Nb)Index1++;
111 if ( Abs(newLast-TK(Index2))<Precision::PConfusion())
113 Standard_Integer MultMax;
114 // attention aux courbes peridiques.
115 if ( myBSplineCurve->IsPeriodic() && Index1 == Nb )
118 if ((Index2 - Index1 <= 0) && (!myBSplineCurve->IsPeriodic())) {
119 MultMax = 100; // CN entre 2 Noeuds consecutifs
122 MultMax = TM(Index1+1);
123 for(Standard_Integer i = Index1+1;i<=Index2;i++) {
124 if ( TM(i)>MultMax) MultMax=TM(i);
126 MultMax = myBSplineCurve->Degree() - MultMax;
131 else if ( MultMax == 1) {
134 else if ( MultMax == 2) {
137 else if ( MultMax == 3) {
146 //=======================================================================
147 //function : Geom2dAdaptor_Curve
149 //=======================================================================
151 Geom2dAdaptor_Curve::Geom2dAdaptor_Curve()
152 : myTypeCurve(GeomAbs_OtherCurve),
158 //=======================================================================
159 //function : Geom2dAdaptor_Curve
161 //=======================================================================
163 Geom2dAdaptor_Curve::Geom2dAdaptor_Curve(const Handle(Geom2d_Curve)& theCrv)
164 : myTypeCurve(GeomAbs_OtherCurve),
171 //=======================================================================
172 //function : Geom2dAdaptor_Curve
174 //=======================================================================
176 Geom2dAdaptor_Curve::Geom2dAdaptor_Curve(const Handle(Geom2d_Curve)& theCrv,
177 const Standard_Real theUFirst,
178 const Standard_Real theULast)
179 : myTypeCurve(GeomAbs_OtherCurve),
183 Load(theCrv, theUFirst, theULast);
186 //=======================================================================
189 //=======================================================================
190 void Geom2dAdaptor_Curve::Reset()
192 myTypeCurve = GeomAbs_OtherCurve;
194 myCurveCache.Nullify();
195 myNestedEvaluator.Nullify();
196 myBSplineCurve.Nullify();
197 myFirst = myLast = 0.0;
200 //=======================================================================
203 //=======================================================================
205 void Geom2dAdaptor_Curve::load(const Handle(Geom2d_Curve)& C,
206 const Standard_Real UFirst,
207 const Standard_Real ULast)
211 myCurveCache.Nullify();
215 myNestedEvaluator.Nullify();
216 myBSplineCurve.Nullify();
218 Handle(Standard_Type) TheType = C->DynamicType();
219 if ( TheType == STANDARD_TYPE(Geom2d_TrimmedCurve)) {
220 Load(Handle(Geom2d_TrimmedCurve)::DownCast (C)->BasisCurve(),
223 else if ( TheType == STANDARD_TYPE(Geom2d_Circle)) {
224 myTypeCurve = GeomAbs_Circle;
226 else if ( TheType ==STANDARD_TYPE(Geom2d_Line)) {
227 myTypeCurve = GeomAbs_Line;
229 else if ( TheType == STANDARD_TYPE(Geom2d_Ellipse)) {
230 myTypeCurve = GeomAbs_Ellipse;
232 else if ( TheType == STANDARD_TYPE(Geom2d_Parabola)) {
233 myTypeCurve = GeomAbs_Parabola;
235 else if ( TheType == STANDARD_TYPE(Geom2d_Hyperbola)) {
236 myTypeCurve = GeomAbs_Hyperbola;
238 else if ( TheType == STANDARD_TYPE(Geom2d_BezierCurve)) {
239 myTypeCurve = GeomAbs_BezierCurve;
241 else if ( TheType == STANDARD_TYPE(Geom2d_BSplineCurve)) {
242 myTypeCurve = GeomAbs_BSplineCurve;
243 myBSplineCurve = Handle(Geom2d_BSplineCurve)::DownCast(myCurve);
245 else if ( TheType == STANDARD_TYPE(Geom2d_OffsetCurve))
247 myTypeCurve = GeomAbs_OffsetCurve;
248 Handle(Geom2d_OffsetCurve) anOffsetCurve = Handle(Geom2d_OffsetCurve)::DownCast(myCurve);
249 // Create nested adaptor for base curve
250 Handle(Geom2d_Curve) aBaseCurve = anOffsetCurve->BasisCurve();
251 Handle(Geom2dAdaptor_Curve) aBaseAdaptor = new Geom2dAdaptor_Curve(aBaseCurve);
252 myNestedEvaluator = new Geom2dEvaluator_OffsetCurve(aBaseAdaptor, anOffsetCurve->Offset());
255 myTypeCurve = GeomAbs_OtherCurve;
261 // -- Global methods - Apply to the whole curve.
264 //=======================================================================
265 //function : Continuity
267 //=======================================================================
269 GeomAbs_Shape Geom2dAdaptor_Curve::Continuity() const
271 if (myTypeCurve == GeomAbs_BSplineCurve) {
272 return LocalContinuity(myFirst, myLast);
274 else if (myTypeCurve == GeomAbs_OffsetCurve){
276 Handle(Geom2d_OffsetCurve)::DownCast (myCurve)->GetBasisCurveContinuity();
278 case GeomAbs_CN: return GeomAbs_CN;
279 case GeomAbs_C3: return GeomAbs_C2;
280 case GeomAbs_C2: return GeomAbs_C1;
281 case GeomAbs_C1: return GeomAbs_C0;
282 case GeomAbs_G1: return GeomAbs_G1;
283 case GeomAbs_G2: return GeomAbs_G2;
286 throw Standard_NoSuchObject("Geom2dAdaptor_Curve::Continuity");
290 else if (myTypeCurve == GeomAbs_OtherCurve) {
291 throw Standard_NoSuchObject("Geom2dAdaptor_Curve::Continuity");
298 //=======================================================================
299 //function : NbIntervals
301 //=======================================================================
303 Standard_Integer Geom2dAdaptor_Curve::NbIntervals(const GeomAbs_Shape S) const
305 if (myTypeCurve == GeomAbs_BSplineCurve)
307 if ((!myBSplineCurve->IsPeriodic() && S <= Continuity()) || S == GeomAbs_C0)
312 Standard_Integer aDegree = myBSplineCurve->Degree();
313 Standard_Integer aCont;
330 throw Standard_DomainError ("Geom2dAdaptor_Curve::NbIntervals()");
333 Standard_Real anEps = Min(Resolution(Precision::Confusion()), Precision::PConfusion());
335 return BSplCLib::Intervals(myBSplineCurve->Knots(),
336 myBSplineCurve->Multiplicities(),
338 myBSplineCurve->IsPeriodic(),
346 else if (myTypeCurve == GeomAbs_OffsetCurve){
347 Standard_Integer myNbIntervals = 1;
348 GeomAbs_Shape BaseS=GeomAbs_C0;
352 throw Standard_DomainError("GeomAdaptor_Curve::NbIntervals");
354 case GeomAbs_C0: BaseS = GeomAbs_C1; break;
355 case GeomAbs_C1: BaseS = GeomAbs_C2; break;
356 case GeomAbs_C2: BaseS = GeomAbs_C3; break;
357 default: BaseS = GeomAbs_CN;
359 Geom2dAdaptor_Curve anAdaptor (Handle(Geom2d_OffsetCurve)::DownCast(myCurve)->BasisCurve(), myFirst, myLast);
360 myNbIntervals = anAdaptor.NbIntervals(BaseS);
361 return myNbIntervals;
370 //=======================================================================
371 //function : Intervals
373 //=======================================================================
375 void Geom2dAdaptor_Curve::Intervals (TColStd_Array1OfReal& T, const GeomAbs_Shape S) const
377 if (myTypeCurve == GeomAbs_BSplineCurve)
379 if ((!myBSplineCurve->IsPeriodic() && S <= Continuity()) || S == GeomAbs_C0)
381 T( T.Lower() ) = myFirst;
382 T( T.Lower() + 1 ) = myLast;
386 Standard_Integer aDegree = myBSplineCurve->Degree();
387 Standard_Integer aCont;
404 throw Standard_DomainError ("Geom2dAdaptor_Curve::Intervals()");
407 Standard_Real anEps = Min(Resolution(Precision::Confusion()), Precision::PConfusion());
409 BSplCLib::Intervals(myBSplineCurve->Knots(),
410 myBSplineCurve->Multiplicities(),
412 myBSplineCurve->IsPeriodic(),
420 else if (myTypeCurve == GeomAbs_OffsetCurve){
421 Standard_Integer myNbIntervals = 1;
422 GeomAbs_Shape BaseS=GeomAbs_C0;
426 throw Standard_DomainError("GeomAdaptor_Curve::NbIntervals");
428 case GeomAbs_C0: BaseS = GeomAbs_C1; break;
429 case GeomAbs_C1: BaseS = GeomAbs_C2; break;
430 case GeomAbs_C2: BaseS = GeomAbs_C3; break;
431 default: BaseS = GeomAbs_CN;
434 Geom2dAdaptor_Curve anAdaptor (Handle(Geom2d_OffsetCurve)::DownCast(myCurve)->BasisCurve(), myFirst, myLast);
435 myNbIntervals = anAdaptor.NbIntervals(BaseS);
436 anAdaptor.Intervals(T, BaseS);
437 T( T.Lower() ) = myFirst;
438 T( T.Lower() + myNbIntervals ) = myLast;
443 T( T.Lower() ) = myFirst;
444 T( T.Lower() + 1 ) = myLast;
448 //=======================================================================
451 //=======================================================================
453 Handle(Adaptor2d_Curve2d) Geom2dAdaptor_Curve::Trim
454 (const Standard_Real First,
455 const Standard_Real Last,
456 // const Standard_Real Tol) const
457 const Standard_Real ) const
459 Handle(Geom2dAdaptor_Curve) HE = new Geom2dAdaptor_Curve(myCurve,First,Last);
464 //=======================================================================
465 //function : IsClosed
467 //=======================================================================
469 Standard_Boolean Geom2dAdaptor_Curve::IsClosed() const
471 if (!Precision::IsPositiveInfinite(myLast) &&
472 !Precision::IsNegativeInfinite(myFirst)) {
473 gp_Pnt2d Pd = Value(myFirst);
474 gp_Pnt2d Pf = Value(myLast);
475 return ( Pd.Distance(Pf) <= Precision::Confusion());
478 return Standard_False;
481 //=======================================================================
482 //function : IsPeriodic
484 //=======================================================================
486 Standard_Boolean Geom2dAdaptor_Curve::IsPeriodic() const
488 return myCurve->IsPeriodic();
491 //=======================================================================
494 //=======================================================================
496 Standard_Real Geom2dAdaptor_Curve::Period() const
498 return myCurve->LastParameter() - myCurve->FirstParameter();
501 //=======================================================================
502 //function : RebuildCache
504 //=======================================================================
505 void Geom2dAdaptor_Curve::RebuildCache(const Standard_Real theParameter) const
507 if (myTypeCurve == GeomAbs_BezierCurve)
509 // Create cache for Bezier
510 Handle(Geom2d_BezierCurve) aBezier = Handle(Geom2d_BezierCurve)::DownCast(myCurve);
511 Standard_Integer aDeg = aBezier->Degree();
512 TColStd_Array1OfReal aFlatKnots(BSplCLib::FlatBezierKnots(aDeg), 1, 2 * (aDeg + 1));
513 if (myCurveCache.IsNull())
514 myCurveCache = new BSplCLib_Cache (aDeg, aBezier->IsPeriodic(), aFlatKnots,
515 aBezier->Poles(), aBezier->Weights());
516 myCurveCache->BuildCache (theParameter, aFlatKnots, aBezier->Poles(), aBezier->Weights());
518 else if (myTypeCurve == GeomAbs_BSplineCurve)
520 // Create cache for B-spline
521 if (myCurveCache.IsNull())
522 myCurveCache = new BSplCLib_Cache (myBSplineCurve->Degree(), myBSplineCurve->IsPeriodic(),
523 myBSplineCurve->KnotSequence(), myBSplineCurve->Poles(), myBSplineCurve->Weights());
524 myCurveCache->BuildCache (theParameter, myBSplineCurve->KnotSequence(),
525 myBSplineCurve->Poles(), myBSplineCurve->Weights());
529 //=======================================================================
530 //function : IsBoundary
532 //=======================================================================
533 Standard_Boolean Geom2dAdaptor_Curve::IsBoundary(const Standard_Real theU,
534 Standard_Integer& theSpanStart,
535 Standard_Integer& theSpanFinish) const
537 if (!myBSplineCurve.IsNull() && (theU == myFirst || theU == myLast))
541 myBSplineCurve->LocateU(myFirst, PosTol, theSpanStart, theSpanFinish);
542 if (theSpanStart < 1)
544 if (theSpanStart >= theSpanFinish)
545 theSpanFinish = theSpanStart + 1;
547 else if (theU == myLast)
549 myBSplineCurve->LocateU(myLast, PosTol, theSpanStart, theSpanFinish);
550 if (theSpanFinish > myBSplineCurve->NbKnots())
551 theSpanFinish = myBSplineCurve->NbKnots();
552 if (theSpanStart >= theSpanFinish)
553 theSpanStart = theSpanFinish - 1;
555 return Standard_True;
557 return Standard_False;
560 //=======================================================================
563 //=======================================================================
565 gp_Pnt2d Geom2dAdaptor_Curve::Value(const Standard_Real U) const
572 //=======================================================================
575 //=======================================================================
577 void Geom2dAdaptor_Curve::D0(const Standard_Real U, gp_Pnt2d& P) const
581 case GeomAbs_BezierCurve:
582 case GeomAbs_BSplineCurve:
584 Standard_Integer aStart = 0, aFinish = 0;
585 if (IsBoundary(U, aStart, aFinish))
587 myBSplineCurve->LocalD0(U, aStart, aFinish, P);
592 if (myCurveCache.IsNull() || !myCurveCache->IsCacheValid(U))
594 myCurveCache->D0(U, P);
599 case GeomAbs_OffsetCurve:
600 myNestedEvaluator->D0(U, P);
608 //=======================================================================
611 //=======================================================================
613 void Geom2dAdaptor_Curve::D1(const Standard_Real U,
614 gp_Pnt2d& P, gp_Vec2d& V) const
618 case GeomAbs_BezierCurve:
619 case GeomAbs_BSplineCurve:
621 Standard_Integer aStart = 0, aFinish = 0;
622 if (IsBoundary(U, aStart, aFinish))
624 myBSplineCurve->LocalD1(U, aStart, aFinish, P, V);
629 if (myCurveCache.IsNull() || !myCurveCache->IsCacheValid(U))
631 myCurveCache->D1(U, P, V);
636 case GeomAbs_OffsetCurve:
637 myNestedEvaluator->D1(U, P, V);
641 myCurve->D1(U, P, V);
645 //=======================================================================
648 //=======================================================================
650 void Geom2dAdaptor_Curve::D2(const Standard_Real U,
651 gp_Pnt2d& P, gp_Vec2d& V1, gp_Vec2d& V2) const
655 case GeomAbs_BezierCurve:
656 case GeomAbs_BSplineCurve:
658 Standard_Integer aStart = 0, aFinish = 0;
659 if (IsBoundary(U, aStart, aFinish))
661 myBSplineCurve->LocalD2(U, aStart, aFinish, P, V1, V2);
666 if (myCurveCache.IsNull() || !myCurveCache->IsCacheValid(U))
668 myCurveCache->D2(U, P, V1, V2);
673 case GeomAbs_OffsetCurve:
674 myNestedEvaluator->D2(U, P, V1, V2);
678 myCurve->D2(U, P, V1, V2);
682 //=======================================================================
685 //=======================================================================
687 void Geom2dAdaptor_Curve::D3(const Standard_Real U,
688 gp_Pnt2d& P, gp_Vec2d& V1,
689 gp_Vec2d& V2, gp_Vec2d& V3) const
693 case GeomAbs_BezierCurve:
694 case GeomAbs_BSplineCurve:
696 Standard_Integer aStart = 0, aFinish = 0;
697 if (IsBoundary(U, aStart, aFinish))
699 myBSplineCurve->LocalD3(U, aStart, aFinish, P, V1, V2, V3);
704 if (myCurveCache.IsNull() || !myCurveCache->IsCacheValid(U))
706 myCurveCache->D3(U, P, V1, V2, V3);
711 case GeomAbs_OffsetCurve:
712 myNestedEvaluator->D3(U, P, V1, V2, V3);
716 myCurve->D3(U, P, V1, V2, V3);
720 //=======================================================================
723 //=======================================================================
725 gp_Vec2d Geom2dAdaptor_Curve::DN(const Standard_Real U,
726 const Standard_Integer N) const
730 case GeomAbs_BezierCurve:
731 case GeomAbs_BSplineCurve:
733 Standard_Integer aStart = 0, aFinish = 0;
734 if (IsBoundary(U, aStart, aFinish))
736 myBSplineCurve->LocalDN(U, aStart, aFinish, N);
739 return myCurve->DN(U, N);
743 case GeomAbs_OffsetCurve:
744 return myNestedEvaluator->DN(U, N);
747 default: // to eliminate gcc warning
750 return myCurve->DN(U, N);
753 //=======================================================================
754 //function : Resolution
756 //=======================================================================
758 Standard_Real Geom2dAdaptor_Curve::Resolution(const Standard_Real Ruv) const {
759 switch ( myTypeCurve) {
762 case GeomAbs_Circle: {
763 Standard_Real R = Handle(Geom2d_Circle)::DownCast (myCurve)->Circ2d().Radius();
765 return 2*ASin(Ruv/(2*R));
769 case GeomAbs_Ellipse: {
770 return Ruv / Handle(Geom2d_Ellipse)::DownCast (myCurve)->MajorRadius();
772 case GeomAbs_BezierCurve: {
774 Handle(Geom2d_BezierCurve)::DownCast (myCurve)->Resolution(Ruv,res);
777 case GeomAbs_BSplineCurve: {
779 Handle(Geom2d_BSplineCurve)::DownCast (myCurve)->Resolution(Ruv,res);
783 return Precision::Parametric(Ruv);
789 // -- The following methods must be called when GetType returned
790 // -- the corresponding type.
793 //=======================================================================
796 //=======================================================================
798 gp_Lin2d Geom2dAdaptor_Curve::Line() const
800 Standard_NoSuchObject_Raise_if (myTypeCurve != GeomAbs_Line,
801 "Geom2dAdaptor_Curve::Line() - curve is not a Line");
802 return Handle(Geom2d_Line)::DownCast (myCurve)->Lin2d();
805 //=======================================================================
808 //=======================================================================
810 gp_Circ2d Geom2dAdaptor_Curve::Circle() const
812 Standard_NoSuchObject_Raise_if (myTypeCurve != GeomAbs_Circle,
813 "Geom2dAdaptor_Curve::Circle() - curve is not a Circle");
814 return Handle(Geom2d_Circle)::DownCast (myCurve)->Circ2d();
817 //=======================================================================
820 //=======================================================================
822 gp_Elips2d Geom2dAdaptor_Curve::Ellipse() const
824 Standard_NoSuchObject_Raise_if (myTypeCurve != GeomAbs_Ellipse,
825 "Geom2dAdaptor_Curve::Ellipse() - curve is not an Ellipse");
826 return Handle(Geom2d_Ellipse)::DownCast (myCurve)->Elips2d();
829 //=======================================================================
830 //function : Hyperbola
832 //=======================================================================
834 gp_Hypr2d Geom2dAdaptor_Curve::Hyperbola() const
836 Standard_NoSuchObject_Raise_if (myTypeCurve != GeomAbs_Hyperbola,
837 "Geom2dAdaptor_Curve::Hyperbola() - curve is not a Hyperbola");
838 return Handle(Geom2d_Hyperbola)::DownCast (myCurve)->Hypr2d();
841 //=======================================================================
842 //function : Parabola
844 //=======================================================================
846 gp_Parab2d Geom2dAdaptor_Curve::Parabola() const
848 Standard_NoSuchObject_Raise_if (myTypeCurve != GeomAbs_Parabola,
849 "Geom2dAdaptor_Curve::Parabola() - curve is not a Parabola");
850 return Handle(Geom2d_Parabola)::DownCast (myCurve)->Parab2d();
853 //=======================================================================
856 //=======================================================================
858 Standard_Integer Geom2dAdaptor_Curve::Degree() const
860 if (myTypeCurve == GeomAbs_BezierCurve)
861 return Handle(Geom2d_BezierCurve)::DownCast (myCurve)->Degree();
862 else if (myTypeCurve == GeomAbs_BSplineCurve)
863 return myBSplineCurve->Degree();
865 throw Standard_NoSuchObject();
868 //=======================================================================
869 //function : IsRational
871 //=======================================================================
873 Standard_Boolean Geom2dAdaptor_Curve::IsRational() const {
874 switch( myTypeCurve) {
875 case GeomAbs_BSplineCurve:
876 return myBSplineCurve->IsRational();
877 case GeomAbs_BezierCurve:
878 return Handle(Geom2d_BezierCurve)::DownCast (myCurve)->IsRational();
880 return Standard_False;
884 //=======================================================================
887 //=======================================================================
889 Standard_Integer Geom2dAdaptor_Curve::NbPoles() const
891 if (myTypeCurve == GeomAbs_BezierCurve)
892 return Handle(Geom2d_BezierCurve)::DownCast (myCurve)->NbPoles();
893 else if (myTypeCurve == GeomAbs_BSplineCurve)
894 return myBSplineCurve->NbPoles();
896 throw Standard_NoSuchObject();
899 //=======================================================================
902 //=======================================================================
904 Standard_Integer Geom2dAdaptor_Curve::NbKnots() const
906 if ( myTypeCurve != GeomAbs_BSplineCurve)
907 throw Standard_NoSuchObject("Geom2dAdaptor_Curve::NbKnots");
908 return myBSplineCurve->NbKnots();
911 //=======================================================================
914 //=======================================================================
916 Handle(Geom2d_BezierCurve) Geom2dAdaptor_Curve::Bezier() const
918 return Handle(Geom2d_BezierCurve)::DownCast (myCurve);
921 //=======================================================================
924 //=======================================================================
926 Handle(Geom2d_BSplineCurve) Geom2dAdaptor_Curve::BSpline() const
928 return myBSplineCurve;
931 static Standard_Integer nbPoints(const Handle(Geom2d_Curve)& theCurve)
934 Standard_Integer nbs = 20;
936 if(theCurve->IsKind(STANDARD_TYPE( Geom2d_Line)) )
938 else if(theCurve->IsKind(STANDARD_TYPE( Geom2d_BezierCurve)))
940 nbs = 3 + Handle(Geom2d_BezierCurve)::DownCast (theCurve)->NbPoles();
942 else if(theCurve->IsKind(STANDARD_TYPE( Geom2d_BSplineCurve))) {
943 nbs = Handle(Geom2d_BSplineCurve)::DownCast (theCurve)->NbKnots();
944 nbs*= Handle(Geom2d_BSplineCurve)::DownCast (theCurve)->Degree();
947 else if (theCurve->IsKind(STANDARD_TYPE(Geom2d_OffsetCurve)))
949 Handle(Geom2d_Curve) aCurve = Handle(Geom2d_OffsetCurve)::DownCast (theCurve)->BasisCurve();
950 return Max(nbs, nbPoints(aCurve));
953 else if (theCurve->IsKind(STANDARD_TYPE(Geom2d_TrimmedCurve)))
955 Handle(Geom2d_Curve) aCurve = Handle(Geom2d_TrimmedCurve)::DownCast (theCurve)->BasisCurve();
956 return Max(nbs, nbPoints(aCurve));
964 Standard_Integer Geom2dAdaptor_Curve::NbSamples() const
966 return nbPoints(myCurve);