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) {
127 //=======================================================================
130 //=======================================================================
131 void GeomAdaptor_Curve::Reset()
133 myTypeCurve = GeomAbs_OtherCurve;
135 myNestedEvaluator.Nullify();
136 myBSplineCurve.Nullify();
137 myCurveCache.Nullify();
138 myFirst = myLast = 0.0;
141 //=======================================================================
144 //=======================================================================
146 void GeomAdaptor_Curve::load(const Handle(Geom_Curve)& C,
147 const Standard_Real UFirst,
148 const Standard_Real ULast)
152 myCurveCache.Nullify();
156 myNestedEvaluator.Nullify();
157 myBSplineCurve.Nullify();
159 const Handle(Standard_Type)& TheType = C->DynamicType();
160 if ( TheType == STANDARD_TYPE(Geom_TrimmedCurve)) {
161 Load(Handle(Geom_TrimmedCurve)::DownCast (C)->BasisCurve(),UFirst,ULast);
163 else if ( TheType == STANDARD_TYPE(Geom_Circle)) {
164 myTypeCurve = GeomAbs_Circle;
166 else if ( TheType ==STANDARD_TYPE(Geom_Line)) {
167 myTypeCurve = GeomAbs_Line;
169 else if ( TheType == STANDARD_TYPE(Geom_Ellipse)) {
170 myTypeCurve = GeomAbs_Ellipse;
172 else if ( TheType == STANDARD_TYPE(Geom_Parabola)) {
173 myTypeCurve = GeomAbs_Parabola;
175 else if ( TheType == STANDARD_TYPE(Geom_Hyperbola)) {
176 myTypeCurve = GeomAbs_Hyperbola;
178 else if ( TheType == STANDARD_TYPE(Geom_BezierCurve)) {
179 myTypeCurve = GeomAbs_BezierCurve;
181 else if ( TheType == STANDARD_TYPE(Geom_BSplineCurve)) {
182 myTypeCurve = GeomAbs_BSplineCurve;
183 myBSplineCurve = Handle(Geom_BSplineCurve)::DownCast(myCurve);
185 else if ( TheType == STANDARD_TYPE(Geom_OffsetCurve)) {
186 myTypeCurve = GeomAbs_OffsetCurve;
187 Handle(Geom_OffsetCurve) anOffsetCurve = Handle(Geom_OffsetCurve)::DownCast(myCurve);
188 // Create nested adaptor for base curve
189 Handle(Geom_Curve) aBaseCurve = anOffsetCurve->BasisCurve();
190 Handle(GeomAdaptor_HCurve) aBaseAdaptor = new GeomAdaptor_HCurve(aBaseCurve);
191 myNestedEvaluator = new GeomEvaluator_OffsetCurve(
192 aBaseAdaptor, anOffsetCurve->Offset(), anOffsetCurve->Direction());
195 myTypeCurve = GeomAbs_OtherCurve;
201 // -- Global methods - Apply to the whole curve.
204 //=======================================================================
205 //function : Continuity
207 //=======================================================================
209 GeomAbs_Shape GeomAdaptor_Curve::Continuity() const
211 if (myTypeCurve == GeomAbs_BSplineCurve)
212 return LocalContinuity(myFirst, myLast);
214 if (myTypeCurve == GeomAbs_OffsetCurve)
216 const GeomAbs_Shape S =
217 Handle(Geom_OffsetCurve)::DownCast (myCurve)->GetBasisCurveContinuity();
220 case GeomAbs_CN: return GeomAbs_CN;
221 case GeomAbs_C3: return GeomAbs_C2;
222 case GeomAbs_C2: return GeomAbs_C1;
223 case GeomAbs_C1: return GeomAbs_C0;
224 case GeomAbs_G1: return GeomAbs_G1;
225 case GeomAbs_G2: return GeomAbs_G2;
227 throw Standard_NoSuchObject("GeomAdaptor_Curve::Continuity");
230 else if (myTypeCurve == GeomAbs_OtherCurve) {
231 throw Standard_NoSuchObject("GeomAdaptor_Curve::Contunuity");
237 //=======================================================================
238 //function : NbIntervals
240 //=======================================================================
242 Standard_Integer GeomAdaptor_Curve::NbIntervals(const GeomAbs_Shape S) const
244 Standard_Integer myNbIntervals = 1;
245 Standard_Integer NbSplit;
246 if (myTypeCurve == GeomAbs_BSplineCurve) {
247 Standard_Integer FirstIndex = myBSplineCurve->FirstUKnotIndex();
248 Standard_Integer LastIndex = myBSplineCurve->LastUKnotIndex();
249 TColStd_Array1OfInteger Inter (1, LastIndex-FirstIndex+1);
250 if ( S > Continuity()) {
251 Standard_Integer Cont;
255 throw Standard_DomainError("GeomAdaptor_Curve::NbIntervals");
265 if ( S == GeomAbs_C1) Cont = 1;
266 else if ( S == GeomAbs_C2) Cont = 2;
267 else if ( S == GeomAbs_C3) Cont = 3;
268 else Cont = myBSplineCurve->Degree();
269 Standard_Integer Degree = myBSplineCurve->Degree();
270 Standard_Integer NbKnots = myBSplineCurve->NbKnots();
271 TColStd_Array1OfInteger Mults (1, NbKnots);
272 myBSplineCurve->Multiplicities (Mults);
274 Standard_Integer Index = FirstIndex;
275 Inter (NbSplit) = Index;
278 while (Index < LastIndex)
280 if (Degree - Mults (Index) < Cont)
282 Inter (NbSplit) = Index;
287 Inter (NbSplit) = Index;
289 Standard_Integer NbInt = NbSplit-1;
291 Standard_Integer Nb = myBSplineCurve->NbKnots();
292 Standard_Integer Index1 = 0;
293 Standard_Integer Index2 = 0;
294 Standard_Real newFirst, newLast;
295 const TColStd_Array1OfReal& TK = myBSplineCurve->Knots();
296 const TColStd_Array1OfInteger& TM = myBSplineCurve->Multiplicities();
297 BSplCLib::LocateParameter(myBSplineCurve->Degree(),TK,TM,myFirst,
298 myBSplineCurve->IsPeriodic(),
299 1,Nb,Index1,newFirst);
300 BSplCLib::LocateParameter(myBSplineCurve->Degree(),TK,TM,myLast,
301 myBSplineCurve->IsPeriodic(),
302 1,Nb,Index2,newLast);
304 // On decale eventuellement les indices
305 // On utilise une "petite" tolerance, la resolution ne doit
306 // servir que pour les tres longue courbes....(PRO9248)
307 Standard_Real Eps = Min(Resolution(Precision::Confusion()),
308 Precision::PConfusion());
309 if ( Abs(newFirst-TK(Index1+1))< Eps) Index1++;
310 if ( newLast-TK(Index2)> Eps) Index2++;
313 for ( Standard_Integer i=1; i<=NbInt; i++)
314 if (Inter(i)>Index1 && Inter(i)<Index2) myNbIntervals++;
321 else if (myTypeCurve == GeomAbs_OffsetCurve) {
322 GeomAbs_Shape BaseS=GeomAbs_C0;
326 throw Standard_DomainError("GeomAdaptor_Curve::NbIntervals");
328 case GeomAbs_C0: BaseS = GeomAbs_C1; break;
329 case GeomAbs_C1: BaseS = GeomAbs_C2; break;
330 case GeomAbs_C2: BaseS = GeomAbs_C3; break;
331 default: BaseS = GeomAbs_CN;
334 (Handle(Geom_OffsetCurve)::DownCast (myCurve)->BasisCurve());
335 // akm 05/04/02 (OCC278) If our curve is trimmed we must recalculate
336 // the number of intervals obtained from the basis to
337 // vvv reflect parameter bounds
338 Standard_Integer iNbBasisInt = C.NbIntervals(BaseS), iInt;
341 TColStd_Array1OfReal rdfInter(1,1+iNbBasisInt);
342 C.Intervals(rdfInter,BaseS);
343 for (iInt=1; iInt<=iNbBasisInt; iInt++)
344 if (rdfInter(iInt)>myFirst && rdfInter(iInt)<myLast)
349 return myNbIntervals;
352 //=======================================================================
353 //function : Intervals
355 //=======================================================================
357 void GeomAdaptor_Curve::Intervals(TColStd_Array1OfReal& T,
358 const GeomAbs_Shape S ) const
360 Standard_Integer myNbIntervals = 1;
361 Standard_Integer NbSplit;
362 Standard_Real FirstParam = myFirst, LastParam = myLast;
364 if (myTypeCurve == GeomAbs_BSplineCurve)
366 Standard_Integer FirstIndex = myBSplineCurve->FirstUKnotIndex();
367 Standard_Integer LastIndex = myBSplineCurve->LastUKnotIndex();
368 TColStd_Array1OfInteger Inter (1, LastIndex-FirstIndex+1);
370 if ( S > Continuity()) {
371 Standard_Integer Cont;
375 throw Standard_DomainError("Geom2dAdaptor_Curve::NbIntervals");
385 if ( S == GeomAbs_C1) Cont = 1;
386 else if ( S == GeomAbs_C2) Cont = 2;
387 else if ( S == GeomAbs_C3) Cont = 3;
388 else Cont = myBSplineCurve->Degree();
389 Standard_Integer Degree = myBSplineCurve->Degree();
390 Standard_Integer NbKnots = myBSplineCurve->NbKnots();
391 TColStd_Array1OfInteger Mults (1, NbKnots);
392 myBSplineCurve->Multiplicities (Mults);
394 Standard_Integer Index = FirstIndex;
395 Inter (NbSplit) = Index;
398 while (Index < LastIndex)
400 if (Degree - Mults (Index) < Cont)
402 Inter (NbSplit) = Index;
407 Inter (NbSplit) = Index;
408 Standard_Integer NbInt = NbSplit-1;
409 // GeomConvert_BSplineCurveKnotSplitting Convector(myBspl, Cont);
410 // Standard_Integer NbInt = Convector.NbSplits()-1;
411 // TColStd_Array1OfInteger Inter(1,NbInt+1);
412 // Convector.Splitting( Inter);
414 Standard_Integer Nb = myBSplineCurve->NbKnots();
415 Standard_Integer Index1 = 0;
416 Standard_Integer Index2 = 0;
417 Standard_Real newFirst, newLast;
418 const TColStd_Array1OfReal& TK = myBSplineCurve->Knots();
419 const TColStd_Array1OfInteger& TM = myBSplineCurve->Multiplicities();
420 BSplCLib::LocateParameter(myBSplineCurve->Degree(),TK,TM,myFirst,
421 myBSplineCurve->IsPeriodic(),
422 1,Nb,Index1,newFirst);
423 BSplCLib::LocateParameter(myBSplineCurve->Degree(),TK,TM,myLast,
424 myBSplineCurve->IsPeriodic(),
425 1,Nb,Index2,newLast);
426 FirstParam = newFirst;
428 // On decale eventuellement les indices
429 // On utilise une "petite" tolerance, la resolution ne doit
430 // servir que pour les tres longue courbes....(PRO9248)
431 Standard_Real Eps = Min(Resolution(Precision::Confusion()),
432 Precision::PConfusion());
433 if ( Abs(newFirst-TK(Index1+1))< Eps) Index1++;
434 if ( newLast-TK(Index2)> Eps) Index2++;
438 for ( Standard_Integer i=1; i<=NbInt; i++) {
439 if (Inter(i) > Index1 && Inter(i)<Index2 ) {
441 Inter(myNbIntervals) = Inter(i);
444 Inter(myNbIntervals+1) = Index2;
446 for (Standard_Integer I=1;I<=myNbIntervals+1;I++) {
455 else if (myTypeCurve == GeomAbs_OffsetCurve){
456 GeomAbs_Shape BaseS=GeomAbs_C0;
460 throw Standard_DomainError("GeomAdaptor_Curve::NbIntervals");
462 case GeomAbs_C0: BaseS = GeomAbs_C1; break;
463 case GeomAbs_C1: BaseS = GeomAbs_C2; break;
464 case GeomAbs_C2: BaseS = GeomAbs_C3; break;
465 default: BaseS = GeomAbs_CN;
468 (Handle(Geom_OffsetCurve)::DownCast (myCurve)->BasisCurve());
469 // akm 05/04/02 (OCC278) If our curve is trimmed we must recalculate
470 // the array of intervals obtained from the basis to
471 // vvv reflect parameter bounds
472 Standard_Integer iNbBasisInt = C.NbIntervals(BaseS), iInt;
475 TColStd_Array1OfReal rdfInter(1,1+iNbBasisInt);
476 C.Intervals(rdfInter,BaseS);
477 for (iInt=1; iInt<=iNbBasisInt; iInt++)
478 if (rdfInter(iInt)>myFirst && rdfInter(iInt)<myLast)
479 T(++myNbIntervals)=rdfInter(iInt);
481 // old - myNbIntervals = C.NbIntervals(BaseS);
482 // old - C.Intervals(T, BaseS);
486 T( T.Lower() ) = FirstParam;
487 T( T.Lower() + myNbIntervals ) = LastParam;
490 //=======================================================================
493 //=======================================================================
495 Handle(Adaptor3d_HCurve) GeomAdaptor_Curve::Trim(const Standard_Real First,
496 const Standard_Real Last,
497 const Standard_Real /*Tol*/) const
499 return Handle(GeomAdaptor_HCurve)(new GeomAdaptor_HCurve(myCurve,First,Last));
503 //=======================================================================
504 //function : IsClosed
506 //=======================================================================
508 Standard_Boolean GeomAdaptor_Curve::IsClosed() const
510 if (!Precision::IsPositiveInfinite(myLast) &&
511 !Precision::IsNegativeInfinite(myFirst))
513 const gp_Pnt Pd = Value(myFirst);
514 const gp_Pnt Pf = Value(myLast);
515 return (Pd.Distance(Pf) <= Precision::Confusion());
517 return Standard_False;
520 //=======================================================================
521 //function : IsPeriodic
523 //=======================================================================
525 Standard_Boolean GeomAdaptor_Curve::IsPeriodic() const
527 return myCurve->IsPeriodic();
530 //=======================================================================
533 //=======================================================================
535 Standard_Real GeomAdaptor_Curve::Period() const
537 return myCurve->LastParameter() - myCurve->FirstParameter();
540 //=======================================================================
541 //function : RebuildCache
543 //=======================================================================
544 void GeomAdaptor_Curve::RebuildCache(const Standard_Real theParameter) const
546 if (myTypeCurve == GeomAbs_BezierCurve)
548 // Create cache for Bezier
549 Handle(Geom_BezierCurve) aBezier = Handle(Geom_BezierCurve)::DownCast(myCurve);
550 Standard_Integer aDeg = aBezier->Degree();
551 TColStd_Array1OfReal aFlatKnots(BSplCLib::FlatBezierKnots(aDeg), 1, 2 * (aDeg + 1));
552 if (myCurveCache.IsNull())
553 myCurveCache = new BSplCLib_Cache(aDeg, aBezier->IsPeriodic(), aFlatKnots,
554 aBezier->Poles(), aBezier->Weights());
555 myCurveCache->BuildCache (theParameter, aFlatKnots, aBezier->Poles(), aBezier->Weights());
557 else if (myTypeCurve == GeomAbs_BSplineCurve)
559 // Create cache for B-spline
560 if (myCurveCache.IsNull())
561 myCurveCache = new BSplCLib_Cache(myBSplineCurve->Degree(), myBSplineCurve->IsPeriodic(),
562 myBSplineCurve->KnotSequence(), myBSplineCurve->Poles(), myBSplineCurve->Weights());
563 myCurveCache->BuildCache (theParameter, myBSplineCurve->KnotSequence(),
564 myBSplineCurve->Poles(), myBSplineCurve->Weights());
568 //=======================================================================
569 //function : IsBoundary
571 //=======================================================================
572 Standard_Boolean GeomAdaptor_Curve::IsBoundary(const Standard_Real theU,
573 Standard_Integer& theSpanStart,
574 Standard_Integer& theSpanFinish) const
576 if (!myBSplineCurve.IsNull() && (theU == myFirst || theU == myLast))
580 myBSplineCurve->LocateU(myFirst, PosTol, theSpanStart, theSpanFinish);
581 if (theSpanStart < 1)
583 if (theSpanStart >= theSpanFinish)
584 theSpanFinish = theSpanStart + 1;
586 else if (theU == myLast)
588 myBSplineCurve->LocateU(myLast, PosTol, theSpanStart, theSpanFinish);
589 if (theSpanFinish > myBSplineCurve->NbKnots())
590 theSpanFinish = myBSplineCurve->NbKnots();
591 if (theSpanStart >= theSpanFinish)
592 theSpanStart = theSpanFinish - 1;
594 return Standard_True;
596 return Standard_False;
599 //=======================================================================
602 //=======================================================================
604 gp_Pnt GeomAdaptor_Curve::Value(const Standard_Real U) const
611 //=======================================================================
614 //=======================================================================
616 void GeomAdaptor_Curve::D0(const Standard_Real U, gp_Pnt& P) const
620 case GeomAbs_BezierCurve:
621 case GeomAbs_BSplineCurve:
623 Standard_Integer aStart = 0, aFinish = 0;
624 if (IsBoundary(U, aStart, aFinish))
626 myBSplineCurve->LocalD0(U, aStart, aFinish, P);
631 if (myCurveCache.IsNull() || !myCurveCache->IsCacheValid(U))
633 myCurveCache->D0(U, P);
638 case GeomAbs_OffsetCurve:
639 myNestedEvaluator->D0(U, P);
647 //=======================================================================
650 //=======================================================================
652 void GeomAdaptor_Curve::D1(const Standard_Real U, gp_Pnt& P, gp_Vec& V) const
656 case GeomAbs_BezierCurve:
657 case GeomAbs_BSplineCurve:
659 Standard_Integer aStart = 0, aFinish = 0;
660 if (IsBoundary(U, aStart, aFinish))
662 myBSplineCurve->LocalD1(U, aStart, aFinish, P, V);
667 if (myCurveCache.IsNull() || !myCurveCache->IsCacheValid(U))
669 myCurveCache->D1(U, P, V);
674 case GeomAbs_OffsetCurve:
675 myNestedEvaluator->D1(U, P, V);
679 myCurve->D1(U, P, V);
683 //=======================================================================
686 //=======================================================================
688 void GeomAdaptor_Curve::D2(const Standard_Real U,
689 gp_Pnt& P, gp_Vec& V1, gp_Vec& V2) const
693 case GeomAbs_BezierCurve:
694 case GeomAbs_BSplineCurve:
696 Standard_Integer aStart = 0, aFinish = 0;
697 if (IsBoundary(U, aStart, aFinish))
699 myBSplineCurve->LocalD2(U, aStart, aFinish, P, V1, V2);
704 if (myCurveCache.IsNull() || !myCurveCache->IsCacheValid(U))
706 myCurveCache->D2(U, P, V1, V2);
711 case GeomAbs_OffsetCurve:
712 myNestedEvaluator->D2(U, P, V1, V2);
716 myCurve->D2(U, P, V1, V2);
720 //=======================================================================
723 //=======================================================================
725 void GeomAdaptor_Curve::D3(const Standard_Real U,
726 gp_Pnt& P, gp_Vec& V1,
727 gp_Vec& V2, gp_Vec& V3) const
731 case GeomAbs_BezierCurve:
732 case GeomAbs_BSplineCurve:
734 Standard_Integer aStart = 0, aFinish = 0;
735 if (IsBoundary(U, aStart, aFinish))
737 myBSplineCurve->LocalD3(U, aStart, aFinish, P, V1, V2, V3);
742 if (myCurveCache.IsNull() || !myCurveCache->IsCacheValid(U))
744 myCurveCache->D3(U, P, V1, V2, V3);
749 case GeomAbs_OffsetCurve:
750 myNestedEvaluator->D3(U, P, V1, V2, V3);
754 myCurve->D3(U, P, V1, V2, V3);
758 //=======================================================================
761 //=======================================================================
763 gp_Vec GeomAdaptor_Curve::DN(const Standard_Real U,
764 const Standard_Integer N) const
768 case GeomAbs_BezierCurve:
769 case GeomAbs_BSplineCurve:
771 Standard_Integer aStart = 0, aFinish = 0;
772 if (IsBoundary(U, aStart, aFinish))
774 return myBSplineCurve->LocalDN(U, aStart, aFinish, N);
777 return myCurve->DN (U, N);
780 case GeomAbs_OffsetCurve:
781 return myNestedEvaluator->DN(U, N);
784 default: // to eliminate gcc warning
787 return myCurve->DN(U, N);
790 //=======================================================================
791 //function : Resolution
793 //=======================================================================
795 Standard_Real GeomAdaptor_Curve::Resolution(const Standard_Real R3D) const
797 switch ( myTypeCurve) {
800 case GeomAbs_Circle: {
801 Standard_Real R = Handle(Geom_Circle)::DownCast (myCurve)->Circ().Radius();
803 return 2*ASin(R3D/(2*R));
807 case GeomAbs_Ellipse: {
808 return R3D / Handle(Geom_Ellipse)::DownCast (myCurve)->MajorRadius();
810 case GeomAbs_BezierCurve: {
812 Handle(Geom_BezierCurve)::DownCast (myCurve)->Resolution(R3D,res);
815 case GeomAbs_BSplineCurve: {
817 myBSplineCurve->Resolution(R3D,res);
821 return Precision::Parametric(R3D);
827 // -- The following methods must be called when GetType returned
828 // -- the corresponding type.
831 //=======================================================================
834 //=======================================================================
836 gp_Lin GeomAdaptor_Curve::Line() const
838 Standard_NoSuchObject_Raise_if (myTypeCurve != GeomAbs_Line,
839 "GeomAdaptor_Curve::Line() - curve is not a Line");
840 return Handle(Geom_Line)::DownCast (myCurve)->Lin();
843 //=======================================================================
846 //=======================================================================
848 gp_Circ GeomAdaptor_Curve::Circle() const
850 Standard_NoSuchObject_Raise_if (myTypeCurve != GeomAbs_Circle,
851 "GeomAdaptor_Curve::Circle() - curve is not a Circle");
852 return Handle(Geom_Circle)::DownCast (myCurve)->Circ();
855 //=======================================================================
858 //=======================================================================
860 gp_Elips GeomAdaptor_Curve::Ellipse() const
862 Standard_NoSuchObject_Raise_if (myTypeCurve != GeomAbs_Ellipse,
863 "GeomAdaptor_Curve::Ellipse() - curve is not an Ellipse");
864 return Handle(Geom_Ellipse)::DownCast (myCurve)->Elips();
867 //=======================================================================
868 //function : Hyperbola
870 //=======================================================================
872 gp_Hypr GeomAdaptor_Curve::Hyperbola() const
874 Standard_NoSuchObject_Raise_if (myTypeCurve != GeomAbs_Hyperbola,
875 "GeomAdaptor_Curve::Hyperbola() - curve is not a Hyperbola");
876 return Handle(Geom_Hyperbola)::DownCast (myCurve)->Hypr();
879 //=======================================================================
880 //function : Parabola
882 //=======================================================================
884 gp_Parab GeomAdaptor_Curve::Parabola() const
886 Standard_NoSuchObject_Raise_if (myTypeCurve != GeomAbs_Parabola,
887 "GeomAdaptor_Curve::Parabola() - curve is not a Parabola");
888 return Handle(Geom_Parabola)::DownCast (myCurve)->Parab();
891 //=======================================================================
894 //=======================================================================
896 Standard_Integer GeomAdaptor_Curve::Degree() const
898 if (myTypeCurve == GeomAbs_BezierCurve)
899 return Handle(Geom_BezierCurve)::DownCast (myCurve)->Degree();
900 else if (myTypeCurve == GeomAbs_BSplineCurve)
901 return myBSplineCurve->Degree();
903 throw Standard_NoSuchObject();
906 //=======================================================================
907 //function : IsRational
909 //=======================================================================
911 Standard_Boolean GeomAdaptor_Curve::IsRational() const {
912 switch( myTypeCurve) {
913 case GeomAbs_BSplineCurve:
914 return myBSplineCurve->IsRational();
915 case GeomAbs_BezierCurve:
916 return Handle(Geom_BezierCurve)::DownCast (myCurve)->IsRational();
918 return Standard_False;
922 //=======================================================================
925 //=======================================================================
927 Standard_Integer GeomAdaptor_Curve::NbPoles() const
929 if (myTypeCurve == GeomAbs_BezierCurve)
930 return Handle(Geom_BezierCurve)::DownCast (myCurve)->NbPoles();
931 else if (myTypeCurve == GeomAbs_BSplineCurve)
932 return myBSplineCurve->NbPoles();
934 throw Standard_NoSuchObject();
937 //=======================================================================
940 //=======================================================================
942 Standard_Integer GeomAdaptor_Curve::NbKnots() const
944 if ( myTypeCurve != GeomAbs_BSplineCurve)
945 throw Standard_NoSuchObject("GeomAdaptor_Curve::NbKnots");
946 return myBSplineCurve->NbKnots();
949 //=======================================================================
952 //=======================================================================
954 Handle(Geom_BezierCurve) GeomAdaptor_Curve::Bezier() const
956 if ( myTypeCurve != GeomAbs_BezierCurve)
957 throw Standard_NoSuchObject("GeomAdaptor_Curve::Bezier");
958 return Handle(Geom_BezierCurve)::DownCast (myCurve);
961 //=======================================================================
964 //=======================================================================
966 Handle(Geom_BSplineCurve) GeomAdaptor_Curve::BSpline() const
968 if ( myTypeCurve != GeomAbs_BSplineCurve)
969 throw Standard_NoSuchObject("GeomAdaptor_Curve::BSpline");
971 return myBSplineCurve;
974 //=======================================================================
975 //function : BasisCurve
977 //=======================================================================
979 Handle(Geom_OffsetCurve) GeomAdaptor_Curve::OffsetCurve() const
981 if ( myTypeCurve != GeomAbs_OffsetCurve)
982 throw Standard_NoSuchObject("GeomAdaptor_Curve::OffsetCurve");
983 return Handle(Geom_OffsetCurve)::DownCast(myCurve);