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
25 #include <Adaptor3d_HCurve.hxx>
26 #include <BSplCLib.hxx>
27 #include <BSplCLib_Cache.hxx>
28 #include <Geom_BezierCurve.hxx>
29 #include <Geom_BSplineCurve.hxx>
30 #include <Geom_Circle.hxx>
31 #include <Geom_Curve.hxx>
32 #include <Geom_Ellipse.hxx>
33 #include <Geom_Hyperbola.hxx>
34 #include <Geom_Line.hxx>
35 #include <Geom_OffsetCurve.hxx>
36 #include <Geom_Parabola.hxx>
37 #include <Geom_TrimmedCurve.hxx>
38 #include <GeomAbs_Shape.hxx>
39 #include <GeomAdaptor_Curve.hxx>
40 #include <GeomAdaptor_HCurve.hxx>
41 #include <GeomAdaptor_Surface.hxx>
42 #include <GeomEvaluator_OffsetCurve.hxx>
43 #include <gp_Circ.hxx>
44 #include <gp_Elips.hxx>
45 #include <gp_Hypr.hxx>
47 #include <gp_Parab.hxx>
50 #include <Precision.hxx>
51 #include <Standard_ConstructionError.hxx>
52 #include <Standard_DomainError.hxx>
53 #include <Standard_NoSuchObject.hxx>
54 #include <Standard_NotImplemented.hxx>
55 #include <Standard_NullObject.hxx>
56 #include <Standard_OutOfRange.hxx>
57 #include <TColgp_Array1OfPnt.hxx>
58 #include <TColStd_Array1OfInteger.hxx>
59 #include <TColStd_Array1OfReal.hxx>
60 #include <TColStd_HArray1OfInteger.hxx>
62 //#include <GeomConvert_BSplineCurveKnotSplitting.hxx>
63 static const Standard_Real PosTol = Precision::PConfusion() / 2;
66 //=======================================================================
67 //function : LocalContinuity
68 //purpose : Computes the Continuity of a BSplineCurve
69 // between the parameters U1 and U2
70 // The continuity is C(d-m)
72 // m = max multiplicity of the Knots between U1 and U2
73 //=======================================================================
75 GeomAbs_Shape GeomAdaptor_Curve::LocalContinuity(const Standard_Real U1,
76 const Standard_Real U2)
79 Standard_NoSuchObject_Raise_if(myTypeCurve!=GeomAbs_BSplineCurve," ");
80 Standard_Integer Nb = myBSplineCurve->NbKnots();
81 Standard_Integer Index1 = 0;
82 Standard_Integer Index2 = 0;
83 Standard_Real newFirst, newLast;
84 const TColStd_Array1OfReal& TK = myBSplineCurve->Knots();
85 const TColStd_Array1OfInteger& TM = myBSplineCurve->Multiplicities();
86 BSplCLib::LocateParameter(myBSplineCurve->Degree(),TK,TM,U1,myBSplineCurve->IsPeriodic(),
87 1,Nb,Index1,newFirst);
88 BSplCLib::LocateParameter(myBSplineCurve->Degree(),TK,TM,U2,myBSplineCurve->IsPeriodic(),
90 if ( Abs(newFirst-TK(Index1+1))<Precision::PConfusion()) {
91 if (Index1 < Nb) Index1++;
93 if ( Abs(newLast-TK(Index2))<Precision::PConfusion())
95 Standard_Integer MultMax;
96 // attention aux courbes peridiques.
97 if ( (myBSplineCurve->IsPeriodic()) && (Index1 == Nb) )
100 if ( Index2 - Index1 <= 0) {
101 MultMax = 100; // CN entre 2 Noeuds consecutifs
104 MultMax = TM(Index1+1);
105 for(Standard_Integer i = Index1+1;i<=Index2;i++) {
106 if ( TM(i)>MultMax) MultMax=TM(i);
108 MultMax = myBSplineCurve->Degree() - MultMax;
113 else if ( MultMax == 1) {
116 else if ( MultMax == 2) {
119 else if ( MultMax == 3) {
128 //=======================================================================
131 //=======================================================================
133 void GeomAdaptor_Curve::load(const Handle(Geom_Curve)& C,
134 const Standard_Real UFirst,
135 const Standard_Real ULast)
139 myCurveCache.Nullify();
143 myNestedEvaluator.Nullify();
144 myBSplineCurve.Nullify();
146 const Handle(Standard_Type)& TheType = C->DynamicType();
147 if ( TheType == STANDARD_TYPE(Geom_TrimmedCurve)) {
148 Load(Handle(Geom_TrimmedCurve)::DownCast (C)->BasisCurve(),UFirst,ULast);
150 else if ( TheType == STANDARD_TYPE(Geom_Circle)) {
151 myTypeCurve = GeomAbs_Circle;
153 else if ( TheType ==STANDARD_TYPE(Geom_Line)) {
154 myTypeCurve = GeomAbs_Line;
156 else if ( TheType == STANDARD_TYPE(Geom_Ellipse)) {
157 myTypeCurve = GeomAbs_Ellipse;
159 else if ( TheType == STANDARD_TYPE(Geom_Parabola)) {
160 myTypeCurve = GeomAbs_Parabola;
162 else if ( TheType == STANDARD_TYPE(Geom_Hyperbola)) {
163 myTypeCurve = GeomAbs_Hyperbola;
165 else if ( TheType == STANDARD_TYPE(Geom_BezierCurve)) {
166 myTypeCurve = GeomAbs_BezierCurve;
168 else if ( TheType == STANDARD_TYPE(Geom_BSplineCurve)) {
169 myTypeCurve = GeomAbs_BSplineCurve;
170 myBSplineCurve = Handle(Geom_BSplineCurve)::DownCast(myCurve);
172 else if ( TheType == STANDARD_TYPE(Geom_OffsetCurve)) {
173 myTypeCurve = GeomAbs_OffsetCurve;
174 Handle(Geom_OffsetCurve) anOffsetCurve = Handle(Geom_OffsetCurve)::DownCast(myCurve);
175 // Create nested adaptor for base curve
176 Handle(Geom_Curve) aBaseCurve = anOffsetCurve->BasisCurve();
177 Handle(GeomAdaptor_HCurve) aBaseAdaptor = new GeomAdaptor_HCurve(aBaseCurve);
178 myNestedEvaluator = new GeomEvaluator_OffsetCurve(
179 aBaseAdaptor, anOffsetCurve->Offset(), anOffsetCurve->Direction());
182 myTypeCurve = GeomAbs_OtherCurve;
188 // -- Global methods - Apply to the whole curve.
191 //=======================================================================
192 //function : Continuity
194 //=======================================================================
196 GeomAbs_Shape GeomAdaptor_Curve::Continuity() const
198 if (myTypeCurve == GeomAbs_BSplineCurve)
199 return LocalContinuity(myFirst, myLast);
201 if (myTypeCurve == GeomAbs_OffsetCurve)
203 const GeomAbs_Shape S =
204 Handle(Geom_OffsetCurve)::DownCast (myCurve)->GetBasisCurveContinuity();
207 case GeomAbs_CN: return GeomAbs_CN;
208 case GeomAbs_C3: return GeomAbs_C2;
209 case GeomAbs_C2: return GeomAbs_C1;
210 case GeomAbs_C1: return GeomAbs_C0;
211 case GeomAbs_G1: return GeomAbs_G1;
212 case GeomAbs_G2: return GeomAbs_G2;
214 Standard_NoSuchObject::Raise("GeomAdaptor_Curve::Continuity");
217 else if (myTypeCurve == GeomAbs_OtherCurve) {
218 Standard_NoSuchObject::Raise("GeomAdaptor_Curve::Contunuity");
224 //=======================================================================
225 //function : NbIntervals
227 //=======================================================================
229 Standard_Integer GeomAdaptor_Curve::NbIntervals(const GeomAbs_Shape S) const
231 Standard_Integer myNbIntervals = 1;
232 Standard_Integer NbSplit;
233 if (myTypeCurve == GeomAbs_BSplineCurve) {
234 Standard_Integer FirstIndex = myBSplineCurve->FirstUKnotIndex();
235 Standard_Integer LastIndex = myBSplineCurve->LastUKnotIndex();
236 TColStd_Array1OfInteger Inter (1, LastIndex-FirstIndex+1);
237 if ( S > Continuity()) {
238 Standard_Integer Cont;
242 Standard_DomainError::Raise("GeomAdaptor_Curve::NbIntervals");
252 if ( S == GeomAbs_C1) Cont = 1;
253 else if ( S == GeomAbs_C2) Cont = 2;
254 else if ( S == GeomAbs_C3) Cont = 3;
255 else Cont = myBSplineCurve->Degree();
256 Standard_Integer Degree = myBSplineCurve->Degree();
257 Standard_Integer NbKnots = myBSplineCurve->NbKnots();
258 TColStd_Array1OfInteger Mults (1, NbKnots);
259 myBSplineCurve->Multiplicities (Mults);
261 Standard_Integer Index = FirstIndex;
262 Inter (NbSplit) = Index;
265 while (Index < LastIndex)
267 if (Degree - Mults (Index) < Cont)
269 Inter (NbSplit) = Index;
274 Inter (NbSplit) = Index;
276 Standard_Integer NbInt = NbSplit-1;
278 Standard_Integer Nb = myBSplineCurve->NbKnots();
279 Standard_Integer Index1 = 0;
280 Standard_Integer Index2 = 0;
281 Standard_Real newFirst, newLast;
282 const TColStd_Array1OfReal& TK = myBSplineCurve->Knots();
283 const TColStd_Array1OfInteger& TM = myBSplineCurve->Multiplicities();
284 BSplCLib::LocateParameter(myBSplineCurve->Degree(),TK,TM,myFirst,
285 myBSplineCurve->IsPeriodic(),
286 1,Nb,Index1,newFirst);
287 BSplCLib::LocateParameter(myBSplineCurve->Degree(),TK,TM,myLast,
288 myBSplineCurve->IsPeriodic(),
289 1,Nb,Index2,newLast);
291 // On decale eventuellement les indices
292 // On utilise une "petite" tolerance, la resolution ne doit
293 // servir que pour les tres longue courbes....(PRO9248)
294 Standard_Real Eps = Min(Resolution(Precision::Confusion()),
295 Precision::PConfusion());
296 if ( Abs(newFirst-TK(Index1+1))< Eps) Index1++;
297 if ( newLast-TK(Index2)> Eps) Index2++;
300 for ( Standard_Integer i=1; i<=NbInt; i++)
301 if (Inter(i)>Index1 && Inter(i)<Index2) myNbIntervals++;
308 else if (myTypeCurve == GeomAbs_OffsetCurve) {
309 GeomAbs_Shape BaseS=GeomAbs_C0;
313 Standard_DomainError::Raise("GeomAdaptor_Curve::NbIntervals");
315 case GeomAbs_C0: BaseS = GeomAbs_C1; break;
316 case GeomAbs_C1: BaseS = GeomAbs_C2; break;
317 case GeomAbs_C2: BaseS = GeomAbs_C3; break;
318 default: BaseS = GeomAbs_CN;
321 (Handle(Geom_OffsetCurve)::DownCast (myCurve)->BasisCurve());
322 // akm 05/04/02 (OCC278) If our curve is trimmed we must recalculate
323 // the number of intervals obtained from the basis to
324 // vvv reflect parameter bounds
325 Standard_Integer iNbBasisInt = C.NbIntervals(BaseS), iInt;
328 TColStd_Array1OfReal rdfInter(1,1+iNbBasisInt);
329 C.Intervals(rdfInter,BaseS);
330 for (iInt=1; iInt<=iNbBasisInt; iInt++)
331 if (rdfInter(iInt)>myFirst && rdfInter(iInt)<myLast)
336 return myNbIntervals;
339 //=======================================================================
340 //function : Intervals
342 //=======================================================================
344 void GeomAdaptor_Curve::Intervals(TColStd_Array1OfReal& T,
345 const GeomAbs_Shape S ) const
347 Standard_Integer myNbIntervals = 1;
348 Standard_Integer NbSplit;
349 Standard_Real FirstParam = myFirst, LastParam = myLast;
351 if (myTypeCurve == GeomAbs_BSplineCurve)
353 Standard_Integer FirstIndex = myBSplineCurve->FirstUKnotIndex();
354 Standard_Integer LastIndex = myBSplineCurve->LastUKnotIndex();
355 TColStd_Array1OfInteger Inter (1, LastIndex-FirstIndex+1);
357 if ( S > Continuity()) {
358 Standard_Integer Cont;
362 Standard_DomainError::Raise("Geom2dAdaptor_Curve::NbIntervals");
372 if ( S == GeomAbs_C1) Cont = 1;
373 else if ( S == GeomAbs_C2) Cont = 2;
374 else if ( S == GeomAbs_C3) Cont = 3;
375 else Cont = myBSplineCurve->Degree();
376 Standard_Integer Degree = myBSplineCurve->Degree();
377 Standard_Integer NbKnots = myBSplineCurve->NbKnots();
378 TColStd_Array1OfInteger Mults (1, NbKnots);
379 myBSplineCurve->Multiplicities (Mults);
381 Standard_Integer Index = FirstIndex;
382 Inter (NbSplit) = Index;
385 while (Index < LastIndex)
387 if (Degree - Mults (Index) < Cont)
389 Inter (NbSplit) = Index;
394 Inter (NbSplit) = Index;
395 Standard_Integer NbInt = NbSplit-1;
396 // GeomConvert_BSplineCurveKnotSplitting Convector(myBspl, Cont);
397 // Standard_Integer NbInt = Convector.NbSplits()-1;
398 // TColStd_Array1OfInteger Inter(1,NbInt+1);
399 // Convector.Splitting( Inter);
401 Standard_Integer Nb = myBSplineCurve->NbKnots();
402 Standard_Integer Index1 = 0;
403 Standard_Integer Index2 = 0;
404 Standard_Real newFirst, newLast;
405 const TColStd_Array1OfReal& TK = myBSplineCurve->Knots();
406 const TColStd_Array1OfInteger& TM = myBSplineCurve->Multiplicities();
407 BSplCLib::LocateParameter(myBSplineCurve->Degree(),TK,TM,myFirst,
408 myBSplineCurve->IsPeriodic(),
409 1,Nb,Index1,newFirst);
410 BSplCLib::LocateParameter(myBSplineCurve->Degree(),TK,TM,myLast,
411 myBSplineCurve->IsPeriodic(),
412 1,Nb,Index2,newLast);
413 FirstParam = newFirst;
415 // On decale eventuellement les indices
416 // On utilise une "petite" tolerance, la resolution ne doit
417 // servir que pour les tres longue courbes....(PRO9248)
418 Standard_Real Eps = Min(Resolution(Precision::Confusion()),
419 Precision::PConfusion());
420 if ( Abs(newFirst-TK(Index1+1))< Eps) Index1++;
421 if ( newLast-TK(Index2)> Eps) Index2++;
425 for ( Standard_Integer i=1; i<=NbInt; i++) {
426 if (Inter(i) > Index1 && Inter(i)<Index2 ) {
428 Inter(myNbIntervals) = Inter(i);
431 Inter(myNbIntervals+1) = Index2;
433 for (Standard_Integer I=1;I<=myNbIntervals+1;I++) {
442 else if (myTypeCurve == GeomAbs_OffsetCurve){
443 GeomAbs_Shape BaseS=GeomAbs_C0;
447 Standard_DomainError::Raise("GeomAdaptor_Curve::NbIntervals");
449 case GeomAbs_C0: BaseS = GeomAbs_C1; break;
450 case GeomAbs_C1: BaseS = GeomAbs_C2; break;
451 case GeomAbs_C2: BaseS = GeomAbs_C3; break;
452 default: BaseS = GeomAbs_CN;
455 (Handle(Geom_OffsetCurve)::DownCast (myCurve)->BasisCurve());
456 // akm 05/04/02 (OCC278) If our curve is trimmed we must recalculate
457 // the array of intervals obtained from the basis to
458 // vvv reflect parameter bounds
459 Standard_Integer iNbBasisInt = C.NbIntervals(BaseS), iInt;
462 TColStd_Array1OfReal rdfInter(1,1+iNbBasisInt);
463 C.Intervals(rdfInter,BaseS);
464 for (iInt=1; iInt<=iNbBasisInt; iInt++)
465 if (rdfInter(iInt)>myFirst && rdfInter(iInt)<myLast)
466 T(++myNbIntervals)=rdfInter(iInt);
468 // old - myNbIntervals = C.NbIntervals(BaseS);
469 // old - C.Intervals(T, BaseS);
473 T( T.Lower() ) = FirstParam;
474 T( T.Lower() + myNbIntervals ) = LastParam;
477 //=======================================================================
480 //=======================================================================
482 Handle(Adaptor3d_HCurve) GeomAdaptor_Curve::Trim(const Standard_Real First,
483 const Standard_Real Last,
484 const Standard_Real /*Tol*/) const
486 return Handle(GeomAdaptor_HCurve)(new GeomAdaptor_HCurve(myCurve,First,Last));
490 //=======================================================================
491 //function : IsClosed
493 //=======================================================================
495 Standard_Boolean GeomAdaptor_Curve::IsClosed() const
497 if (!Precision::IsPositiveInfinite(myLast) &&
498 !Precision::IsNegativeInfinite(myFirst))
500 const gp_Pnt Pd = Value(myFirst);
501 const gp_Pnt Pf = Value(myLast);
502 return (Pd.Distance(Pf) <= Precision::Confusion());
504 return Standard_False;
507 //=======================================================================
508 //function : IsPeriodic
510 //=======================================================================
512 Standard_Boolean GeomAdaptor_Curve::IsPeriodic() const
514 return (myCurve->IsPeriodic()? IsClosed() : Standard_False);
517 //=======================================================================
520 //=======================================================================
522 Standard_Real GeomAdaptor_Curve::Period() const
524 return myCurve->LastParameter() - myCurve->FirstParameter();
527 //=======================================================================
528 //function : RebuildCache
530 //=======================================================================
531 void GeomAdaptor_Curve::RebuildCache(const Standard_Real theParameter) const
533 if (myTypeCurve == GeomAbs_BezierCurve)
535 // Create cache for Bezier
536 Handle(Geom_BezierCurve) aBezier = Handle(Geom_BezierCurve)::DownCast(myCurve);
537 Standard_Integer aDeg = aBezier->Degree();
538 TColStd_Array1OfReal aFlatKnots(BSplCLib::FlatBezierKnots(aDeg), 1, 2 * (aDeg + 1));
539 if (myCurveCache.IsNull())
540 myCurveCache = new BSplCLib_Cache(aDeg, aBezier->IsPeriodic(), aFlatKnots,
541 aBezier->Poles(), aBezier->Weights());
542 myCurveCache->BuildCache(theParameter, aDeg, aBezier->IsPeriodic(), aFlatKnots,
543 aBezier->Poles(), aBezier->Weights());
545 else if (myTypeCurve == GeomAbs_BSplineCurve)
547 // Create cache for B-spline
548 if (myCurveCache.IsNull())
549 myCurveCache = new BSplCLib_Cache(myBSplineCurve->Degree(), myBSplineCurve->IsPeriodic(),
550 myBSplineCurve->KnotSequence(), myBSplineCurve->Poles(), myBSplineCurve->Weights());
551 myCurveCache->BuildCache(theParameter, myBSplineCurve->Degree(),
552 myBSplineCurve->IsPeriodic(), myBSplineCurve->KnotSequence(),
553 myBSplineCurve->Poles(), myBSplineCurve->Weights());
557 //=======================================================================
558 //function : IsBoundary
560 //=======================================================================
561 Standard_Boolean GeomAdaptor_Curve::IsBoundary(const Standard_Real theU,
562 Standard_Integer& theSpanStart,
563 Standard_Integer& theSpanFinish) const
565 if (!myBSplineCurve.IsNull() && (theU == myFirst || theU == myLast))
569 myBSplineCurve->LocateU(myFirst, PosTol, theSpanStart, theSpanFinish);
570 if (theSpanStart < 1)
572 if (theSpanStart >= theSpanFinish)
573 theSpanFinish = theSpanStart + 1;
575 else if (theU == myLast)
577 myBSplineCurve->LocateU(myLast, PosTol, theSpanStart, theSpanFinish);
578 if (theSpanFinish > myBSplineCurve->NbKnots())
579 theSpanFinish = myBSplineCurve->NbKnots();
580 if (theSpanStart >= theSpanFinish)
581 theSpanStart = theSpanFinish - 1;
583 return Standard_True;
585 return Standard_False;
588 //=======================================================================
591 //=======================================================================
593 gp_Pnt GeomAdaptor_Curve::Value(const Standard_Real U) const
600 //=======================================================================
603 //=======================================================================
605 void GeomAdaptor_Curve::D0(const Standard_Real U, gp_Pnt& P) const
609 case GeomAbs_BezierCurve:
610 case GeomAbs_BSplineCurve:
612 Standard_Integer aStart = 0, aFinish = 0;
613 if (IsBoundary(U, aStart, aFinish))
615 myBSplineCurve->LocalD0(U, aStart, aFinish, P);
620 if (myCurveCache.IsNull() || !myCurveCache->IsCacheValid(U))
622 myCurveCache->D0(U, P);
627 case GeomAbs_OffsetCurve:
628 myNestedEvaluator->D0(U, P);
636 //=======================================================================
639 //=======================================================================
641 void GeomAdaptor_Curve::D1(const Standard_Real U, gp_Pnt& P, gp_Vec& V) const
645 case GeomAbs_BezierCurve:
646 case GeomAbs_BSplineCurve:
648 Standard_Integer aStart = 0, aFinish = 0;
649 if (IsBoundary(U, aStart, aFinish))
651 myBSplineCurve->LocalD1(U, aStart, aFinish, P, V);
656 if (myCurveCache.IsNull() || !myCurveCache->IsCacheValid(U))
658 myCurveCache->D1(U, P, V);
663 case GeomAbs_OffsetCurve:
664 myNestedEvaluator->D1(U, P, V);
668 myCurve->D1(U, P, V);
672 //=======================================================================
675 //=======================================================================
677 void GeomAdaptor_Curve::D2(const Standard_Real U,
678 gp_Pnt& P, gp_Vec& V1, gp_Vec& V2) const
682 case GeomAbs_BezierCurve:
683 case GeomAbs_BSplineCurve:
685 Standard_Integer aStart = 0, aFinish = 0;
686 if (IsBoundary(U, aStart, aFinish))
688 myBSplineCurve->LocalD2(U, aStart, aFinish, P, V1, V2);
693 if (myCurveCache.IsNull() || !myCurveCache->IsCacheValid(U))
695 myCurveCache->D2(U, P, V1, V2);
700 case GeomAbs_OffsetCurve:
701 myNestedEvaluator->D2(U, P, V1, V2);
705 myCurve->D2(U, P, V1, V2);
709 //=======================================================================
712 //=======================================================================
714 void GeomAdaptor_Curve::D3(const Standard_Real U,
715 gp_Pnt& P, gp_Vec& V1,
716 gp_Vec& V2, gp_Vec& V3) const
720 case GeomAbs_BezierCurve:
721 case GeomAbs_BSplineCurve:
723 Standard_Integer aStart = 0, aFinish = 0;
724 if (IsBoundary(U, aStart, aFinish))
726 myBSplineCurve->LocalD3(U, aStart, aFinish, P, V1, V2, V3);
731 if (myCurveCache.IsNull() || !myCurveCache->IsCacheValid(U))
733 myCurveCache->D3(U, P, V1, V2, V3);
738 case GeomAbs_OffsetCurve:
739 myNestedEvaluator->D3(U, P, V1, V2, V3);
743 myCurve->D3(U, P, V1, V2, V3);
747 //=======================================================================
750 //=======================================================================
752 gp_Vec GeomAdaptor_Curve::DN(const Standard_Real U,
753 const Standard_Integer N) const
757 case GeomAbs_BezierCurve:
758 case GeomAbs_BSplineCurve:
760 Standard_Integer aStart = 0, aFinish = 0;
761 if (IsBoundary(U, aStart, aFinish))
763 return myBSplineCurve->LocalDN(U, aStart, aFinish, N);
766 return myCurve->DN( U, N);
770 case GeomAbs_OffsetCurve:
771 return myNestedEvaluator->DN(U, N);
774 default: // to eliminate gcc warning
777 return myCurve->DN(U, N);
780 //=======================================================================
781 //function : Resolution
783 //=======================================================================
785 Standard_Real GeomAdaptor_Curve::Resolution(const Standard_Real R3D) const
787 switch ( myTypeCurve) {
790 case GeomAbs_Circle: {
791 Standard_Real R = Handle(Geom_Circle)::DownCast (myCurve)->Circ().Radius();
793 return 2*ASin(R3D/(2*R));
797 case GeomAbs_Ellipse: {
798 return R3D / Handle(Geom_Ellipse)::DownCast (myCurve)->MajorRadius();
800 case GeomAbs_BezierCurve: {
802 Handle(Geom_BezierCurve)::DownCast (myCurve)->Resolution(R3D,res);
805 case GeomAbs_BSplineCurve: {
807 myBSplineCurve->Resolution(R3D,res);
811 return Precision::Parametric(R3D);
817 // -- The following methods must be called when GetType returned
818 // -- the corresponding type.
821 //=======================================================================
824 //=======================================================================
826 gp_Lin GeomAdaptor_Curve::Line() const
828 Standard_NoSuchObject_Raise_if(myTypeCurve != GeomAbs_Line, "");
829 return Handle(Geom_Line)::DownCast (myCurve)->Lin();
832 //=======================================================================
835 //=======================================================================
837 gp_Circ GeomAdaptor_Curve::Circle() const
839 Standard_NoSuchObject_Raise_if(myTypeCurve != GeomAbs_Circle, "");
840 return Handle(Geom_Circle)::DownCast (myCurve)->Circ();
843 //=======================================================================
846 //=======================================================================
848 gp_Elips GeomAdaptor_Curve::Ellipse() const
850 Standard_NoSuchObject_Raise_if(myTypeCurve != GeomAbs_Ellipse, "");
851 return Handle(Geom_Ellipse)::DownCast (myCurve)->Elips();
854 //=======================================================================
855 //function : Hyperbola
857 //=======================================================================
859 gp_Hypr GeomAdaptor_Curve::Hyperbola() const
861 Standard_NoSuchObject_Raise_if(myTypeCurve != GeomAbs_Hyperbola, "");
862 return Handle(Geom_Hyperbola)::DownCast (myCurve)->Hypr();
865 //=======================================================================
866 //function : Parabola
868 //=======================================================================
870 gp_Parab GeomAdaptor_Curve::Parabola() const
872 Standard_NoSuchObject_Raise_if(myTypeCurve != GeomAbs_Parabola, "");
873 return Handle(Geom_Parabola)::DownCast (myCurve)->Parab();
876 //=======================================================================
879 //=======================================================================
881 Standard_Integer GeomAdaptor_Curve::Degree() const
883 if (myTypeCurve == GeomAbs_BezierCurve)
884 return Handle(Geom_BezierCurve)::DownCast (myCurve)->Degree();
885 else if (myTypeCurve == GeomAbs_BSplineCurve)
886 return myBSplineCurve->Degree();
888 Standard_NoSuchObject::Raise();
893 //=======================================================================
894 //function : IsRational
896 //=======================================================================
898 Standard_Boolean GeomAdaptor_Curve::IsRational() const {
899 switch( myTypeCurve) {
900 case GeomAbs_BSplineCurve:
901 return myBSplineCurve->IsRational();
902 case GeomAbs_BezierCurve:
903 return Handle(Geom_BezierCurve)::DownCast (myCurve)->IsRational();
905 return Standard_False;
909 //=======================================================================
912 //=======================================================================
914 Standard_Integer GeomAdaptor_Curve::NbPoles() const
916 if (myTypeCurve == GeomAbs_BezierCurve)
917 return Handle(Geom_BezierCurve)::DownCast (myCurve)->NbPoles();
918 else if (myTypeCurve == GeomAbs_BSplineCurve)
919 return myBSplineCurve->NbPoles();
921 Standard_NoSuchObject::Raise();
926 //=======================================================================
929 //=======================================================================
931 Standard_Integer GeomAdaptor_Curve::NbKnots() const
933 if ( myTypeCurve != GeomAbs_BSplineCurve)
934 Standard_NoSuchObject::Raise("GeomAdaptor_Curve::NbKnots");
935 return myBSplineCurve->NbKnots();
938 //=======================================================================
941 //=======================================================================
943 Handle(Geom_BezierCurve) GeomAdaptor_Curve::Bezier() const
945 if ( myTypeCurve != GeomAbs_BezierCurve)
946 Standard_NoSuchObject::Raise("GeomAdaptor_Curve::Bezier");
947 return Handle(Geom_BezierCurve)::DownCast (myCurve);
950 //=======================================================================
953 //=======================================================================
955 Handle(Geom_BSplineCurve) GeomAdaptor_Curve::BSpline() const
957 if ( myTypeCurve != GeomAbs_BSplineCurve)
958 Standard_NoSuchObject::Raise("GeomAdaptor_Curve::BSpline");
960 return myBSplineCurve;
963 //=======================================================================
964 //function : BasisCurve
966 //=======================================================================
968 Handle(Geom_OffsetCurve) GeomAdaptor_Curve::OffsetCurve() const
970 if ( myTypeCurve != GeomAbs_OffsetCurve)
971 Standard_NoSuchObject::Raise("GeomAdaptor_Curve::OffsetCurve");
972 return Handle(Geom_OffsetCurve)::DownCast(myCurve);