1 // Created on: 1993-04-29
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 : RBV -> traitement des offset curves
21 #define No_Standard_RangeError
22 #define No_Standard_OutOfRange
24 #include <GeomAdaptor_Curve.hxx>
26 #include <Adaptor3d_Curve.hxx>
27 #include <BSplCLib.hxx>
28 #include <BSplCLib_Cache.hxx>
29 #include <Geom_BezierCurve.hxx>
30 #include <Geom_BSplineCurve.hxx>
31 #include <Geom_Circle.hxx>
32 #include <Geom_Curve.hxx>
33 #include <Geom_Ellipse.hxx>
34 #include <Geom_Hyperbola.hxx>
35 #include <Geom_Line.hxx>
36 #include <Geom_OffsetCurve.hxx>
37 #include <Geom_Parabola.hxx>
38 #include <Geom_TrimmedCurve.hxx>
39 #include <GeomAbs_Shape.hxx>
40 #include <GeomEvaluator_OffsetCurve.hxx>
41 #include <gp_Circ.hxx>
42 #include <gp_Elips.hxx>
43 #include <gp_Hypr.hxx>
45 #include <gp_Parab.hxx>
48 #include <Precision.hxx>
49 #include <Standard_DomainError.hxx>
50 #include <Standard_NoSuchObject.hxx>
51 #include <Standard_NotImplemented.hxx>
52 #include <TColgp_Array1OfPnt.hxx>
53 #include <TColStd_Array1OfInteger.hxx>
54 #include <TColStd_Array1OfReal.hxx>
56 //#include <GeomConvert_BSplineCurveKnotSplitting.hxx>
57 static const Standard_Real PosTol = Precision::PConfusion() / 2;
59 IMPLEMENT_STANDARD_RTTIEXT(GeomAdaptor_Curve, Adaptor3d_Curve)
61 //=======================================================================
62 //function : ShallowCopy
64 //=======================================================================
66 Handle(Adaptor3d_Curve) GeomAdaptor_Curve::ShallowCopy() const
68 Handle(GeomAdaptor_Curve) aCopy = new GeomAdaptor_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 GeomAdaptor_Curve::LocalContinuity(const Standard_Real U1,
93 const Standard_Real U2)
96 Standard_NoSuchObject_Raise_if(myTypeCurve!=GeomAbs_BSplineCurve," ");
97 Standard_Integer Nb = myBSplineCurve->NbKnots();
98 Standard_Integer Index1 = 0;
99 Standard_Integer Index2 = 0;
100 Standard_Real newFirst, newLast;
101 const TColStd_Array1OfReal& TK = myBSplineCurve->Knots();
102 const TColStd_Array1OfInteger& TM = myBSplineCurve->Multiplicities();
103 BSplCLib::LocateParameter(myBSplineCurve->Degree(),TK,TM,U1,myBSplineCurve->IsPeriodic(),
104 1,Nb,Index1,newFirst);
105 BSplCLib::LocateParameter(myBSplineCurve->Degree(),TK,TM,U2,myBSplineCurve->IsPeriodic(),
106 1,Nb,Index2,newLast);
107 if ( Abs(newFirst-TK(Index1+1))<Precision::PConfusion()) {
108 if (Index1 < Nb) Index1++;
110 if ( Abs(newLast-TK(Index2))<Precision::PConfusion())
112 Standard_Integer MultMax;
113 // attention aux courbes peridiques.
114 if ( (myBSplineCurve->IsPeriodic()) && (Index1 == Nb) )
117 if ((Index2 - Index1 <= 0) && (!myBSplineCurve->IsPeriodic())) {
118 MultMax = 100; // CN entre 2 Noeuds consecutifs
121 MultMax = TM(Index1+1);
122 for(Standard_Integer i = Index1+1;i<=Index2;i++) {
123 if ( TM(i)>MultMax) MultMax=TM(i);
125 MultMax = myBSplineCurve->Degree() - MultMax;
130 else if ( MultMax == 1) {
133 else if ( MultMax == 2) {
136 else if ( MultMax == 3) {
144 //=======================================================================
147 //=======================================================================
148 void GeomAdaptor_Curve::Reset()
150 myTypeCurve = GeomAbs_OtherCurve;
152 myNestedEvaluator.Nullify();
153 myBSplineCurve.Nullify();
154 myCurveCache.Nullify();
155 myFirst = myLast = 0.0;
158 //=======================================================================
161 //=======================================================================
163 void GeomAdaptor_Curve::load(const Handle(Geom_Curve)& C,
164 const Standard_Real UFirst,
165 const Standard_Real ULast)
169 myCurveCache.Nullify();
173 myNestedEvaluator.Nullify();
174 myBSplineCurve.Nullify();
176 const Handle(Standard_Type)& TheType = C->DynamicType();
177 if ( TheType == STANDARD_TYPE(Geom_TrimmedCurve)) {
178 Load(Handle(Geom_TrimmedCurve)::DownCast (C)->BasisCurve(),UFirst,ULast);
180 else if ( TheType == STANDARD_TYPE(Geom_Circle)) {
181 myTypeCurve = GeomAbs_Circle;
183 else if ( TheType ==STANDARD_TYPE(Geom_Line)) {
184 myTypeCurve = GeomAbs_Line;
186 else if ( TheType == STANDARD_TYPE(Geom_Ellipse)) {
187 myTypeCurve = GeomAbs_Ellipse;
189 else if ( TheType == STANDARD_TYPE(Geom_Parabola)) {
190 myTypeCurve = GeomAbs_Parabola;
192 else if ( TheType == STANDARD_TYPE(Geom_Hyperbola)) {
193 myTypeCurve = GeomAbs_Hyperbola;
195 else if ( TheType == STANDARD_TYPE(Geom_BezierCurve)) {
196 myTypeCurve = GeomAbs_BezierCurve;
198 else if ( TheType == STANDARD_TYPE(Geom_BSplineCurve)) {
199 myTypeCurve = GeomAbs_BSplineCurve;
200 myBSplineCurve = Handle(Geom_BSplineCurve)::DownCast(myCurve);
202 else if ( TheType == STANDARD_TYPE(Geom_OffsetCurve)) {
203 myTypeCurve = GeomAbs_OffsetCurve;
204 Handle(Geom_OffsetCurve) anOffsetCurve = Handle(Geom_OffsetCurve)::DownCast(myCurve);
205 // Create nested adaptor for base curve
206 Handle(Geom_Curve) aBaseCurve = anOffsetCurve->BasisCurve();
207 Handle(GeomAdaptor_Curve) aBaseAdaptor = new GeomAdaptor_Curve(aBaseCurve);
208 myNestedEvaluator = new GeomEvaluator_OffsetCurve(
209 aBaseAdaptor, anOffsetCurve->Offset(), anOffsetCurve->Direction());
212 myTypeCurve = GeomAbs_OtherCurve;
218 // -- Global methods - Apply to the whole curve.
221 //=======================================================================
222 //function : Continuity
224 //=======================================================================
226 GeomAbs_Shape GeomAdaptor_Curve::Continuity() const
228 if (myTypeCurve == GeomAbs_BSplineCurve)
229 return LocalContinuity(myFirst, myLast);
231 if (myTypeCurve == GeomAbs_OffsetCurve)
233 const GeomAbs_Shape S =
234 Handle(Geom_OffsetCurve)::DownCast (myCurve)->GetBasisCurveContinuity();
237 case GeomAbs_CN: return GeomAbs_CN;
238 case GeomAbs_C3: return GeomAbs_C2;
239 case GeomAbs_C2: return GeomAbs_C1;
240 case GeomAbs_C1: return GeomAbs_C0;
241 case GeomAbs_G1: return GeomAbs_G1;
242 case GeomAbs_G2: return GeomAbs_G2;
244 throw Standard_NoSuchObject("GeomAdaptor_Curve::Continuity");
247 else if (myTypeCurve == GeomAbs_OtherCurve) {
248 throw Standard_NoSuchObject("GeomAdaptor_Curve::Contunuity");
254 //=======================================================================
255 //function : NbIntervals
257 //=======================================================================
259 Standard_Integer GeomAdaptor_Curve::NbIntervals(const GeomAbs_Shape S) const
261 if (myTypeCurve == GeomAbs_BSplineCurve)
263 if ((!myBSplineCurve->IsPeriodic() && S <= Continuity()) || S == GeomAbs_C0)
268 Standard_Integer aDegree = myBSplineCurve->Degree();
269 Standard_Integer aCont;
286 throw Standard_DomainError ("GeomAdaptor_Curve::NbIntervals()");
289 Standard_Real anEps = Min(Resolution(Precision::Confusion()), Precision::PConfusion());
291 return BSplCLib::Intervals(myBSplineCurve->Knots(),
292 myBSplineCurve->Multiplicities(),
294 myBSplineCurve->IsPeriodic(),
302 else if (myTypeCurve == GeomAbs_OffsetCurve) {
303 Standard_Integer myNbIntervals = 1;
304 GeomAbs_Shape BaseS=GeomAbs_C0;
308 throw Standard_DomainError("GeomAdaptor_Curve::NbIntervals");
310 case GeomAbs_C0: BaseS = GeomAbs_C1; break;
311 case GeomAbs_C1: BaseS = GeomAbs_C2; break;
312 case GeomAbs_C2: BaseS = GeomAbs_C3; break;
313 default: BaseS = GeomAbs_CN;
315 GeomAdaptor_Curve C (Handle(Geom_OffsetCurve)::DownCast (myCurve)->BasisCurve(), myFirst, myLast);
316 // akm 05/04/02 (OCC278) If our curve is trimmed we must recalculate
317 // the number of intervals obtained from the basis to
318 // vvv reflect parameter bounds
319 Standard_Integer iNbBasisInt = C.NbIntervals(BaseS), iInt;
322 TColStd_Array1OfReal rdfInter(1,1+iNbBasisInt);
323 C.Intervals(rdfInter,BaseS);
324 for (iInt=1; iInt<=iNbBasisInt; iInt++)
325 if (rdfInter(iInt)>myFirst && rdfInter(iInt)<myLast)
329 return myNbIntervals;
338 //=======================================================================
339 //function : Intervals
341 //=======================================================================
343 void GeomAdaptor_Curve::Intervals (TColStd_Array1OfReal& T, const GeomAbs_Shape S) const
345 if (myTypeCurve == GeomAbs_BSplineCurve)
347 if ((!myBSplineCurve->IsPeriodic() && S <= Continuity()) || S == GeomAbs_C0)
349 T( T.Lower() ) = myFirst;
350 T( T.Lower() + 1 ) = myLast;
354 Standard_Integer aDegree = myBSplineCurve->Degree();
355 Standard_Integer aCont;
372 throw Standard_DomainError ("GeomAdaptor_Curve::Intervals()");
375 Standard_Real anEps = Min(Resolution(Precision::Confusion()), Precision::PConfusion());
377 BSplCLib::Intervals(myBSplineCurve->Knots(),
378 myBSplineCurve->Multiplicities(),
380 myBSplineCurve->IsPeriodic(),
388 else if (myTypeCurve == GeomAbs_OffsetCurve){
389 Standard_Integer myNbIntervals = 1;
390 GeomAbs_Shape BaseS=GeomAbs_C0;
394 throw Standard_DomainError("GeomAdaptor_Curve::NbIntervals");
396 case GeomAbs_C0: BaseS = GeomAbs_C1; break;
397 case GeomAbs_C1: BaseS = GeomAbs_C2; break;
398 case GeomAbs_C2: BaseS = GeomAbs_C3; break;
399 default: BaseS = GeomAbs_CN;
401 GeomAdaptor_Curve C (Handle(Geom_OffsetCurve)::DownCast (myCurve)->BasisCurve(), myFirst, myLast);
402 // akm 05/04/02 (OCC278) If our curve is trimmed we must recalculate
403 // the array of intervals obtained from the basis to
404 // vvv reflect parameter bounds
405 Standard_Integer iNbBasisInt = C.NbIntervals(BaseS), iInt;
408 TColStd_Array1OfReal rdfInter(1,1+iNbBasisInt);
409 C.Intervals(rdfInter,BaseS);
410 for (iInt=1; iInt<=iNbBasisInt; iInt++)
411 if (rdfInter(iInt)>myFirst && rdfInter(iInt)<myLast)
412 T(++myNbIntervals)=rdfInter(iInt);
414 // old - myNbIntervals = C.NbIntervals(BaseS);
415 // old - C.Intervals(T, BaseS);
417 T( T.Lower() ) = myFirst;
418 T( T.Lower() + myNbIntervals ) = myLast;
423 T( T.Lower() ) = myFirst;
424 T( T.Lower() + 1 ) = myLast;
428 //=======================================================================
431 //=======================================================================
433 Handle(Adaptor3d_Curve) GeomAdaptor_Curve::Trim(const Standard_Real First,
434 const Standard_Real Last,
435 const Standard_Real /*Tol*/) const
437 return Handle(GeomAdaptor_Curve)(new GeomAdaptor_Curve(myCurve,First,Last));
441 //=======================================================================
442 //function : IsClosed
444 //=======================================================================
446 Standard_Boolean GeomAdaptor_Curve::IsClosed() const
448 if (!Precision::IsPositiveInfinite(myLast) &&
449 !Precision::IsNegativeInfinite(myFirst))
451 const gp_Pnt Pd = Value(myFirst);
452 const gp_Pnt Pf = Value(myLast);
453 return (Pd.Distance(Pf) <= Precision::Confusion());
455 return Standard_False;
458 //=======================================================================
459 //function : IsPeriodic
461 //=======================================================================
463 Standard_Boolean GeomAdaptor_Curve::IsPeriodic() const
465 return myCurve->IsPeriodic();
468 //=======================================================================
471 //=======================================================================
473 Standard_Real GeomAdaptor_Curve::Period() const
475 return myCurve->LastParameter() - myCurve->FirstParameter();
478 //=======================================================================
479 //function : RebuildCache
481 //=======================================================================
482 void GeomAdaptor_Curve::RebuildCache(const Standard_Real theParameter) const
484 if (myTypeCurve == GeomAbs_BezierCurve)
486 // Create cache for Bezier
487 Handle(Geom_BezierCurve) aBezier = Handle(Geom_BezierCurve)::DownCast(myCurve);
488 Standard_Integer aDeg = aBezier->Degree();
489 TColStd_Array1OfReal aFlatKnots(BSplCLib::FlatBezierKnots(aDeg), 1, 2 * (aDeg + 1));
490 if (myCurveCache.IsNull())
491 myCurveCache = new BSplCLib_Cache(aDeg, aBezier->IsPeriodic(), aFlatKnots,
492 aBezier->Poles(), aBezier->Weights());
493 myCurveCache->BuildCache (theParameter, aFlatKnots, aBezier->Poles(), aBezier->Weights());
495 else if (myTypeCurve == GeomAbs_BSplineCurve)
497 // Create cache for B-spline
498 if (myCurveCache.IsNull())
499 myCurveCache = new BSplCLib_Cache(myBSplineCurve->Degree(), myBSplineCurve->IsPeriodic(),
500 myBSplineCurve->KnotSequence(), myBSplineCurve->Poles(), myBSplineCurve->Weights());
501 myCurveCache->BuildCache (theParameter, myBSplineCurve->KnotSequence(),
502 myBSplineCurve->Poles(), myBSplineCurve->Weights());
506 //=======================================================================
507 //function : IsBoundary
509 //=======================================================================
510 Standard_Boolean GeomAdaptor_Curve::IsBoundary(const Standard_Real theU,
511 Standard_Integer& theSpanStart,
512 Standard_Integer& theSpanFinish) const
514 if (!myBSplineCurve.IsNull() && (theU == myFirst || theU == myLast))
518 myBSplineCurve->LocateU(myFirst, PosTol, theSpanStart, theSpanFinish);
519 if (theSpanStart < 1)
521 if (theSpanStart >= theSpanFinish)
522 theSpanFinish = theSpanStart + 1;
524 else if (theU == myLast)
526 myBSplineCurve->LocateU(myLast, PosTol, theSpanStart, theSpanFinish);
527 if (theSpanFinish > myBSplineCurve->NbKnots())
528 theSpanFinish = myBSplineCurve->NbKnots();
529 if (theSpanStart >= theSpanFinish)
530 theSpanStart = theSpanFinish - 1;
532 return Standard_True;
534 return Standard_False;
537 //=======================================================================
540 //=======================================================================
542 gp_Pnt GeomAdaptor_Curve::Value(const Standard_Real U) const
549 //=======================================================================
552 //=======================================================================
554 void GeomAdaptor_Curve::D0(const Standard_Real U, gp_Pnt& P) const
558 case GeomAbs_BezierCurve:
559 case GeomAbs_BSplineCurve:
561 Standard_Integer aStart = 0, aFinish = 0;
562 if (IsBoundary(U, aStart, aFinish))
564 myBSplineCurve->LocalD0(U, aStart, aFinish, P);
569 if (myCurveCache.IsNull() || !myCurveCache->IsCacheValid(U))
571 myCurveCache->D0(U, P);
576 case GeomAbs_OffsetCurve:
577 myNestedEvaluator->D0(U, P);
585 //=======================================================================
588 //=======================================================================
590 void GeomAdaptor_Curve::D1(const Standard_Real U, gp_Pnt& P, gp_Vec& V) const
594 case GeomAbs_BezierCurve:
595 case GeomAbs_BSplineCurve:
597 Standard_Integer aStart = 0, aFinish = 0;
598 if (IsBoundary(U, aStart, aFinish))
600 myBSplineCurve->LocalD1(U, aStart, aFinish, P, V);
605 if (myCurveCache.IsNull() || !myCurveCache->IsCacheValid(U))
607 myCurveCache->D1(U, P, V);
612 case GeomAbs_OffsetCurve:
613 myNestedEvaluator->D1(U, P, V);
617 myCurve->D1(U, P, V);
621 //=======================================================================
624 //=======================================================================
626 void GeomAdaptor_Curve::D2(const Standard_Real U,
627 gp_Pnt& P, gp_Vec& V1, gp_Vec& V2) const
631 case GeomAbs_BezierCurve:
632 case GeomAbs_BSplineCurve:
634 Standard_Integer aStart = 0, aFinish = 0;
635 if (IsBoundary(U, aStart, aFinish))
637 myBSplineCurve->LocalD2(U, aStart, aFinish, P, V1, V2);
642 if (myCurveCache.IsNull() || !myCurveCache->IsCacheValid(U))
644 myCurveCache->D2(U, P, V1, V2);
649 case GeomAbs_OffsetCurve:
650 myNestedEvaluator->D2(U, P, V1, V2);
654 myCurve->D2(U, P, V1, V2);
658 //=======================================================================
661 //=======================================================================
663 void GeomAdaptor_Curve::D3(const Standard_Real U,
664 gp_Pnt& P, gp_Vec& V1,
665 gp_Vec& V2, gp_Vec& V3) const
669 case GeomAbs_BezierCurve:
670 case GeomAbs_BSplineCurve:
672 Standard_Integer aStart = 0, aFinish = 0;
673 if (IsBoundary(U, aStart, aFinish))
675 myBSplineCurve->LocalD3(U, aStart, aFinish, P, V1, V2, V3);
680 if (myCurveCache.IsNull() || !myCurveCache->IsCacheValid(U))
682 myCurveCache->D3(U, P, V1, V2, V3);
687 case GeomAbs_OffsetCurve:
688 myNestedEvaluator->D3(U, P, V1, V2, V3);
692 myCurve->D3(U, P, V1, V2, V3);
696 //=======================================================================
699 //=======================================================================
701 gp_Vec GeomAdaptor_Curve::DN(const Standard_Real U,
702 const Standard_Integer N) const
706 case GeomAbs_BezierCurve:
707 case GeomAbs_BSplineCurve:
709 Standard_Integer aStart = 0, aFinish = 0;
710 if (IsBoundary(U, aStart, aFinish))
712 return myBSplineCurve->LocalDN(U, aStart, aFinish, N);
715 return myCurve->DN (U, N);
718 case GeomAbs_OffsetCurve:
719 return myNestedEvaluator->DN(U, N);
722 default: // to eliminate gcc warning
725 return myCurve->DN(U, N);
728 //=======================================================================
729 //function : Resolution
731 //=======================================================================
733 Standard_Real GeomAdaptor_Curve::Resolution(const Standard_Real R3D) const
735 switch ( myTypeCurve) {
738 case GeomAbs_Circle: {
739 Standard_Real R = Handle(Geom_Circle)::DownCast (myCurve)->Circ().Radius();
741 return 2*ASin(R3D/(2*R));
745 case GeomAbs_Ellipse: {
746 return R3D / Handle(Geom_Ellipse)::DownCast (myCurve)->MajorRadius();
748 case GeomAbs_BezierCurve: {
750 Handle(Geom_BezierCurve)::DownCast (myCurve)->Resolution(R3D,res);
753 case GeomAbs_BSplineCurve: {
755 myBSplineCurve->Resolution(R3D,res);
759 return Precision::Parametric(R3D);
765 // -- The following methods must be called when GetType returned
766 // -- the corresponding type.
769 //=======================================================================
772 //=======================================================================
774 gp_Lin GeomAdaptor_Curve::Line() const
776 Standard_NoSuchObject_Raise_if (myTypeCurve != GeomAbs_Line,
777 "GeomAdaptor_Curve::Line() - curve is not a Line");
778 return Handle(Geom_Line)::DownCast (myCurve)->Lin();
781 //=======================================================================
784 //=======================================================================
786 gp_Circ GeomAdaptor_Curve::Circle() const
788 Standard_NoSuchObject_Raise_if (myTypeCurve != GeomAbs_Circle,
789 "GeomAdaptor_Curve::Circle() - curve is not a Circle");
790 return Handle(Geom_Circle)::DownCast (myCurve)->Circ();
793 //=======================================================================
796 //=======================================================================
798 gp_Elips GeomAdaptor_Curve::Ellipse() const
800 Standard_NoSuchObject_Raise_if (myTypeCurve != GeomAbs_Ellipse,
801 "GeomAdaptor_Curve::Ellipse() - curve is not an Ellipse");
802 return Handle(Geom_Ellipse)::DownCast (myCurve)->Elips();
805 //=======================================================================
806 //function : Hyperbola
808 //=======================================================================
810 gp_Hypr GeomAdaptor_Curve::Hyperbola() const
812 Standard_NoSuchObject_Raise_if (myTypeCurve != GeomAbs_Hyperbola,
813 "GeomAdaptor_Curve::Hyperbola() - curve is not a Hyperbola");
814 return Handle(Geom_Hyperbola)::DownCast (myCurve)->Hypr();
817 //=======================================================================
818 //function : Parabola
820 //=======================================================================
822 gp_Parab GeomAdaptor_Curve::Parabola() const
824 Standard_NoSuchObject_Raise_if (myTypeCurve != GeomAbs_Parabola,
825 "GeomAdaptor_Curve::Parabola() - curve is not a Parabola");
826 return Handle(Geom_Parabola)::DownCast (myCurve)->Parab();
829 //=======================================================================
832 //=======================================================================
834 Standard_Integer GeomAdaptor_Curve::Degree() const
836 if (myTypeCurve == GeomAbs_BezierCurve)
837 return Handle(Geom_BezierCurve)::DownCast (myCurve)->Degree();
838 else if (myTypeCurve == GeomAbs_BSplineCurve)
839 return myBSplineCurve->Degree();
841 throw Standard_NoSuchObject();
844 //=======================================================================
845 //function : IsRational
847 //=======================================================================
849 Standard_Boolean GeomAdaptor_Curve::IsRational() const {
850 switch( myTypeCurve) {
851 case GeomAbs_BSplineCurve:
852 return myBSplineCurve->IsRational();
853 case GeomAbs_BezierCurve:
854 return Handle(Geom_BezierCurve)::DownCast (myCurve)->IsRational();
856 return Standard_False;
860 //=======================================================================
863 //=======================================================================
865 Standard_Integer GeomAdaptor_Curve::NbPoles() const
867 if (myTypeCurve == GeomAbs_BezierCurve)
868 return Handle(Geom_BezierCurve)::DownCast (myCurve)->NbPoles();
869 else if (myTypeCurve == GeomAbs_BSplineCurve)
870 return myBSplineCurve->NbPoles();
872 throw Standard_NoSuchObject();
875 //=======================================================================
878 //=======================================================================
880 Standard_Integer GeomAdaptor_Curve::NbKnots() const
882 if ( myTypeCurve != GeomAbs_BSplineCurve)
883 throw Standard_NoSuchObject("GeomAdaptor_Curve::NbKnots");
884 return myBSplineCurve->NbKnots();
887 //=======================================================================
890 //=======================================================================
892 Handle(Geom_BezierCurve) GeomAdaptor_Curve::Bezier() const
894 if ( myTypeCurve != GeomAbs_BezierCurve)
895 throw Standard_NoSuchObject("GeomAdaptor_Curve::Bezier");
896 return Handle(Geom_BezierCurve)::DownCast (myCurve);
899 //=======================================================================
902 //=======================================================================
904 Handle(Geom_BSplineCurve) GeomAdaptor_Curve::BSpline() const
906 if ( myTypeCurve != GeomAbs_BSplineCurve)
907 throw Standard_NoSuchObject("GeomAdaptor_Curve::BSpline");
909 return myBSplineCurve;
912 //=======================================================================
913 //function : BasisCurve
915 //=======================================================================
917 Handle(Geom_OffsetCurve) GeomAdaptor_Curve::OffsetCurve() const
919 if ( myTypeCurve != GeomAbs_OffsetCurve)
920 throw Standard_NoSuchObject("GeomAdaptor_Curve::OffsetCurve");
921 return Handle(Geom_OffsetCurve)::DownCast(myCurve);