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 Handle(Geom_BSplineCurve) aBspl = Handle(Geom_BSplineCurve)::DownCast(myCurve);
81 Standard_Integer Nb = aBspl->NbKnots();
82 Standard_Integer Index1 = 0;
83 Standard_Integer Index2 = 0;
84 Standard_Real newFirst, newLast;
85 TColStd_Array1OfReal TK(1,Nb);
86 TColStd_Array1OfInteger TM(1,Nb);
88 aBspl->Multiplicities(TM);
89 BSplCLib::LocateParameter(aBspl->Degree(),TK,TM,U1,aBspl->IsPeriodic(),
90 1,Nb,Index1,newFirst);
91 BSplCLib::LocateParameter(aBspl->Degree(),TK,TM,U2,aBspl->IsPeriodic(),
93 if ( Abs(newFirst-TK(Index1+1))<Precision::PConfusion()) {
94 if (Index1 < Nb) Index1++;
96 if ( Abs(newLast-TK(Index2))<Precision::PConfusion())
98 Standard_Integer MultMax;
99 // attention aux courbes peridiques.
100 if ( (aBspl->IsPeriodic()) && (Index1 == Nb) )
103 if ( Index2 - Index1 <= 0) {
104 MultMax = 100; // CN entre 2 Noeuds consecutifs
107 MultMax = TM(Index1+1);
108 for(Standard_Integer i = Index1+1;i<=Index2;i++) {
109 if ( TM(i)>MultMax) MultMax=TM(i);
111 MultMax = aBspl->Degree() - MultMax;
116 else if ( MultMax == 1) {
119 else if ( MultMax == 2) {
122 else if ( MultMax == 3) {
131 //=======================================================================
134 //=======================================================================
136 void GeomAdaptor_Curve::load(const Handle(Geom_Curve)& C,
137 const Standard_Real UFirst,
138 const Standard_Real ULast)
145 myCurveCache = Handle(BSplCLib_Cache)();
146 myNestedEvaluator = Handle(GeomEvaluator_Curve)();
148 const Handle(Standard_Type)& TheType = C->DynamicType();
149 if ( TheType == STANDARD_TYPE(Geom_TrimmedCurve)) {
150 Load(Handle(Geom_TrimmedCurve)::DownCast (C)->BasisCurve(),UFirst,ULast);
152 else if ( TheType == STANDARD_TYPE(Geom_Circle)) {
153 myTypeCurve = GeomAbs_Circle;
155 else if ( TheType ==STANDARD_TYPE(Geom_Line)) {
156 myTypeCurve = GeomAbs_Line;
158 else if ( TheType == STANDARD_TYPE(Geom_Ellipse)) {
159 myTypeCurve = GeomAbs_Ellipse;
161 else if ( TheType == STANDARD_TYPE(Geom_Parabola)) {
162 myTypeCurve = GeomAbs_Parabola;
164 else if ( TheType == STANDARD_TYPE(Geom_Hyperbola)) {
165 myTypeCurve = GeomAbs_Hyperbola;
167 else if ( TheType == STANDARD_TYPE(Geom_BezierCurve)) {
168 myTypeCurve = GeomAbs_BezierCurve;
169 // Create cache for Bezier
170 Handle(Geom_BezierCurve) aBezier = Handle(Geom_BezierCurve)::DownCast(myCurve);
171 Standard_Integer aDeg = aBezier->Degree();
172 TColStd_Array1OfReal aFlatKnots(BSplCLib::FlatBezierKnots(aDeg), 1, 2 * (aDeg + 1));
173 myCurveCache = new BSplCLib_Cache(aDeg, aBezier->IsPeriodic(), aFlatKnots,
174 aBezier->Poles(), aBezier->Weights());
176 else if ( TheType == STANDARD_TYPE(Geom_BSplineCurve)) {
177 myTypeCurve = GeomAbs_BSplineCurve;
178 // Create cache for B-spline
179 Handle(Geom_BSplineCurve) aBspl = Handle(Geom_BSplineCurve)::DownCast(myCurve);
180 myCurveCache = new BSplCLib_Cache(aBspl->Degree(), aBspl->IsPeriodic(),
181 aBspl->KnotSequence(), aBspl->Poles(), aBspl->Weights());
183 else if ( TheType == STANDARD_TYPE(Geom_OffsetCurve)) {
184 myTypeCurve = GeomAbs_OffsetCurve;
185 Handle(Geom_OffsetCurve) anOffsetCurve = Handle(Geom_OffsetCurve)::DownCast(myCurve);
186 // Create nested adaptor for base curve
187 Handle(Geom_Curve) aBaseCurve = anOffsetCurve->BasisCurve();
188 Handle(GeomAdaptor_HCurve) aBaseAdaptor = new GeomAdaptor_HCurve(aBaseCurve);
189 myNestedEvaluator = new GeomEvaluator_OffsetCurve(
190 aBaseAdaptor, anOffsetCurve->Offset(), anOffsetCurve->Direction());
193 myTypeCurve = GeomAbs_OtherCurve;
199 // -- Global methods - Apply to the whole curve.
202 //=======================================================================
203 //function : Continuity
205 //=======================================================================
207 GeomAbs_Shape GeomAdaptor_Curve::Continuity() const
209 if (myTypeCurve == GeomAbs_BSplineCurve)
210 return LocalContinuity(myFirst, myLast);
212 if (myTypeCurve == GeomAbs_OffsetCurve)
214 const GeomAbs_Shape S =
215 Handle(Geom_OffsetCurve)::DownCast (myCurve)->GetBasisCurveContinuity();
218 case GeomAbs_CN: return GeomAbs_CN;
219 case GeomAbs_C3: return GeomAbs_C2;
220 case GeomAbs_C2: return GeomAbs_C1;
221 case GeomAbs_C1: return GeomAbs_C0;
222 case GeomAbs_G1: return GeomAbs_G1;
223 case GeomAbs_G2: return GeomAbs_G2;
225 Standard_NoSuchObject::Raise("GeomAdaptor_Curve::Continuity");
228 else if (myTypeCurve == GeomAbs_OtherCurve) {
229 Standard_NoSuchObject::Raise("GeomAdaptor_Curve::Contunuity");
235 //=======================================================================
236 //function : NbIntervals
238 //=======================================================================
240 Standard_Integer GeomAdaptor_Curve::NbIntervals(const GeomAbs_Shape S) const
242 Standard_Integer myNbIntervals = 1;
243 Standard_Integer NbSplit;
244 if (myTypeCurve == GeomAbs_BSplineCurve) {
245 Handle(Geom_BSplineCurve) aBspl = Handle(Geom_BSplineCurve)::DownCast(myCurve);
246 Standard_Integer FirstIndex = aBspl->FirstUKnotIndex();
247 Standard_Integer LastIndex = aBspl->LastUKnotIndex();
248 TColStd_Array1OfInteger Inter (1, LastIndex-FirstIndex+1);
249 if ( S > Continuity()) {
250 Standard_Integer Cont;
254 Standard_DomainError::Raise("GeomAdaptor_Curve::NbIntervals");
264 if ( S == GeomAbs_C1) Cont = 1;
265 else if ( S == GeomAbs_C2) Cont = 2;
266 else if ( S == GeomAbs_C3) Cont = 3;
267 else Cont = aBspl->Degree();
268 Standard_Integer Degree = aBspl->Degree();
269 Standard_Integer NbKnots = aBspl->NbKnots();
270 TColStd_Array1OfInteger Mults (1, NbKnots);
271 aBspl->Multiplicities (Mults);
273 Standard_Integer Index = FirstIndex;
274 Inter (NbSplit) = Index;
277 while (Index < LastIndex)
279 if (Degree - Mults (Index) < Cont)
281 Inter (NbSplit) = Index;
286 Inter (NbSplit) = Index;
288 Standard_Integer NbInt = NbSplit-1;
290 Standard_Integer Nb = aBspl->NbKnots();
291 Standard_Integer Index1 = 0;
292 Standard_Integer Index2 = 0;
293 Standard_Real newFirst, newLast;
294 TColStd_Array1OfReal TK(1,Nb);
295 TColStd_Array1OfInteger TM(1,Nb);
297 aBspl->Multiplicities(TM);
298 BSplCLib::LocateParameter(aBspl->Degree(),TK,TM,myFirst,
300 1,Nb,Index1,newFirst);
301 BSplCLib::LocateParameter(aBspl->Degree(),TK,TM,myLast,
303 1,Nb,Index2,newLast);
305 // On decale eventuellement les indices
306 // On utilise une "petite" tolerance, la resolution ne doit
307 // servir que pour les tres longue courbes....(PRO9248)
308 Standard_Real Eps = Min(Resolution(Precision::Confusion()),
309 Precision::PConfusion());
310 if ( Abs(newFirst-TK(Index1+1))< Eps) Index1++;
311 if ( newLast-TK(Index2)> Eps) Index2++;
314 for ( Standard_Integer i=1; i<=NbInt; i++)
315 if (Inter(i)>Index1 && Inter(i)<Index2) myNbIntervals++;
322 else if (myTypeCurve == GeomAbs_OffsetCurve) {
323 GeomAbs_Shape BaseS=GeomAbs_C0;
327 Standard_DomainError::Raise("GeomAdaptor_Curve::NbIntervals");
329 case GeomAbs_C0: BaseS = GeomAbs_C1; break;
330 case GeomAbs_C1: BaseS = GeomAbs_C2; break;
331 case GeomAbs_C2: BaseS = GeomAbs_C3; break;
332 default: BaseS = GeomAbs_CN;
335 (Handle(Geom_OffsetCurve)::DownCast (myCurve)->BasisCurve());
336 // akm 05/04/02 (OCC278) If our curve is trimmed we must recalculate
337 // the number of intervals obtained from the basis to
338 // vvv reflect parameter bounds
339 Standard_Integer iNbBasisInt = C.NbIntervals(BaseS), iInt;
342 TColStd_Array1OfReal rdfInter(1,1+iNbBasisInt);
343 C.Intervals(rdfInter,BaseS);
344 for (iInt=1; iInt<=iNbBasisInt; iInt++)
345 if (rdfInter(iInt)>myFirst && rdfInter(iInt)<myLast)
350 return myNbIntervals;
353 //=======================================================================
354 //function : Intervals
356 //=======================================================================
358 void GeomAdaptor_Curve::Intervals(TColStd_Array1OfReal& T,
359 const GeomAbs_Shape S ) const
361 Standard_Integer myNbIntervals = 1;
362 Standard_Integer NbSplit;
363 Standard_Real FirstParam = myFirst, LastParam = myLast;
365 if (myTypeCurve == GeomAbs_BSplineCurve)
367 Handle(Geom_BSplineCurve) aBspl = Handle(Geom_BSplineCurve)::DownCast(myCurve);
368 Standard_Integer FirstIndex = aBspl->FirstUKnotIndex();
369 Standard_Integer LastIndex = aBspl->LastUKnotIndex();
370 TColStd_Array1OfInteger Inter (1, LastIndex-FirstIndex+1);
372 if ( S > Continuity()) {
373 Standard_Integer Cont;
377 Standard_DomainError::Raise("Geom2dAdaptor_Curve::NbIntervals");
387 if ( S == GeomAbs_C1) Cont = 1;
388 else if ( S == GeomAbs_C2) Cont = 2;
389 else if ( S == GeomAbs_C3) Cont = 3;
390 else Cont = aBspl->Degree();
391 Standard_Integer Degree = aBspl->Degree();
392 Standard_Integer NbKnots = aBspl->NbKnots();
393 TColStd_Array1OfInteger Mults (1, NbKnots);
394 aBspl->Multiplicities (Mults);
396 Standard_Integer Index = FirstIndex;
397 Inter (NbSplit) = Index;
400 while (Index < LastIndex)
402 if (Degree - Mults (Index) < Cont)
404 Inter (NbSplit) = Index;
409 Inter (NbSplit) = Index;
410 Standard_Integer NbInt = NbSplit-1;
411 // GeomConvert_BSplineCurveKnotSplitting Convector(myBspl, Cont);
412 // Standard_Integer NbInt = Convector.NbSplits()-1;
413 // TColStd_Array1OfInteger Inter(1,NbInt+1);
414 // Convector.Splitting( Inter);
416 Standard_Integer Nb = aBspl->NbKnots();
417 Standard_Integer Index1 = 0;
418 Standard_Integer Index2 = 0;
419 Standard_Real newFirst, newLast;
420 TColStd_Array1OfReal TK(1,Nb);
421 TColStd_Array1OfInteger TM(1,Nb);
423 aBspl->Multiplicities(TM);
424 BSplCLib::LocateParameter(aBspl->Degree(),TK,TM,myFirst,
426 1,Nb,Index1,newFirst);
427 BSplCLib::LocateParameter(aBspl->Degree(),TK,TM,myLast,
429 1,Nb,Index2,newLast);
430 FirstParam = newFirst;
432 // On decale eventuellement les indices
433 // On utilise une "petite" tolerance, la resolution ne doit
434 // servir que pour les tres longue courbes....(PRO9248)
435 Standard_Real Eps = Min(Resolution(Precision::Confusion()),
436 Precision::PConfusion());
437 if ( Abs(newFirst-TK(Index1+1))< Eps) Index1++;
438 if ( newLast-TK(Index2)> Eps) Index2++;
442 for ( Standard_Integer i=1; i<=NbInt; i++) {
443 if (Inter(i) > Index1 && Inter(i)<Index2 ) {
445 Inter(myNbIntervals) = Inter(i);
448 Inter(myNbIntervals+1) = Index2;
450 for (Standard_Integer I=1;I<=myNbIntervals+1;I++) {
459 else if (myTypeCurve == GeomAbs_OffsetCurve){
460 GeomAbs_Shape BaseS=GeomAbs_C0;
464 Standard_DomainError::Raise("GeomAdaptor_Curve::NbIntervals");
466 case GeomAbs_C0: BaseS = GeomAbs_C1; break;
467 case GeomAbs_C1: BaseS = GeomAbs_C2; break;
468 case GeomAbs_C2: BaseS = GeomAbs_C3; break;
469 default: BaseS = GeomAbs_CN;
472 (Handle(Geom_OffsetCurve)::DownCast (myCurve)->BasisCurve());
473 // akm 05/04/02 (OCC278) If our curve is trimmed we must recalculate
474 // the array of intervals obtained from the basis to
475 // vvv reflect parameter bounds
476 Standard_Integer iNbBasisInt = C.NbIntervals(BaseS), iInt;
479 TColStd_Array1OfReal rdfInter(1,1+iNbBasisInt);
480 C.Intervals(rdfInter,BaseS);
481 for (iInt=1; iInt<=iNbBasisInt; iInt++)
482 if (rdfInter(iInt)>myFirst && rdfInter(iInt)<myLast)
483 T(++myNbIntervals)=rdfInter(iInt);
485 // old - myNbIntervals = C.NbIntervals(BaseS);
486 // old - C.Intervals(T, BaseS);
490 T( T.Lower() ) = FirstParam;
491 T( T.Lower() + myNbIntervals ) = LastParam;
494 //=======================================================================
497 //=======================================================================
499 Handle(Adaptor3d_HCurve) GeomAdaptor_Curve::Trim(const Standard_Real First,
500 const Standard_Real Last,
501 const Standard_Real /*Tol*/) const
503 return Handle(GeomAdaptor_HCurve)(new GeomAdaptor_HCurve(myCurve,First,Last));
507 //=======================================================================
508 //function : IsClosed
510 //=======================================================================
512 Standard_Boolean GeomAdaptor_Curve::IsClosed() const
514 if (!Precision::IsPositiveInfinite(myLast) &&
515 !Precision::IsNegativeInfinite(myFirst))
517 const gp_Pnt Pd = Value(myFirst);
518 const gp_Pnt Pf = Value(myLast);
519 return (Pd.Distance(Pf) <= Precision::Confusion());
521 return Standard_False;
524 //=======================================================================
525 //function : IsPeriodic
527 //=======================================================================
529 Standard_Boolean GeomAdaptor_Curve::IsPeriodic() const
531 return (myCurve->IsPeriodic()? IsClosed() : Standard_False);
534 //=======================================================================
537 //=======================================================================
539 Standard_Real GeomAdaptor_Curve::Period() const
541 return myCurve->LastParameter() - myCurve->FirstParameter();
544 //=======================================================================
545 //function : RebuildCache
547 //=======================================================================
548 void GeomAdaptor_Curve::RebuildCache(const Standard_Real theParameter) const
550 if (myTypeCurve == GeomAbs_BezierCurve)
552 Handle(Geom_BezierCurve) aBezier = Handle(Geom_BezierCurve)::DownCast(myCurve);
553 Standard_Integer aDeg = aBezier->Degree();
554 TColStd_Array1OfReal aFlatKnots(BSplCLib::FlatBezierKnots(aDeg), 1, 2 * (aDeg + 1));
555 myCurveCache->BuildCache(theParameter, aDeg, aBezier->IsPeriodic(), aFlatKnots,
556 aBezier->Poles(), aBezier->Weights());
558 else if (myTypeCurve == GeomAbs_BSplineCurve)
560 Handle(Geom_BSplineCurve) aBspl = Handle(Geom_BSplineCurve)::DownCast(myCurve);
561 myCurveCache->BuildCache(theParameter, aBspl->Degree(),
562 aBspl->IsPeriodic(), aBspl->KnotSequence(),
563 aBspl->Poles(), aBspl->Weights());
567 //=======================================================================
568 //function : IsBoundary
570 //=======================================================================
571 Standard_Boolean GeomAdaptor_Curve::IsBoundary(const Standard_Real theU,
572 Standard_Integer& theSpanStart,
573 Standard_Integer& theSpanFinish) const
575 Handle(Geom_BSplineCurve) aBspl = Handle(Geom_BSplineCurve)::DownCast(myCurve);
576 if (!aBspl.IsNull() && (theU == myFirst || theU == myLast))
580 aBspl->LocateU(myFirst, PosTol, theSpanStart, theSpanFinish);
581 if (theSpanStart < 1)
583 if (theSpanStart >= theSpanFinish)
584 theSpanFinish = theSpanStart + 1;
586 else if (theU == myLast)
588 aBspl->LocateU(myLast, PosTol, theSpanStart, theSpanFinish);
589 if (theSpanFinish > aBspl->NbKnots())
590 theSpanFinish = aBspl->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 Handle(Geom_BSplineCurve) aBspl = Handle(Geom_BSplineCurve)::DownCast(myCurve);
627 aBspl->LocalD0(U, aStart, aFinish, P);
629 else if (!myCurveCache.IsNull()) // use cached data
631 if (!myCurveCache->IsCacheValid(U))
633 myCurveCache->D0(U, P);
640 case GeomAbs_OffsetCurve:
641 myNestedEvaluator->D0(U, P);
649 //=======================================================================
652 //=======================================================================
654 void GeomAdaptor_Curve::D1(const Standard_Real U, gp_Pnt& P, gp_Vec& V) const
658 case GeomAbs_BezierCurve:
659 case GeomAbs_BSplineCurve:
661 Standard_Integer aStart = 0, aFinish = 0;
662 if (IsBoundary(U, aStart, aFinish))
664 Handle(Geom_BSplineCurve) aBspl = Handle(Geom_BSplineCurve)::DownCast(myCurve);
665 aBspl->LocalD1(U, aStart, aFinish, P, V);
667 else if (!myCurveCache.IsNull()) // use cached data
669 if (!myCurveCache->IsCacheValid(U))
671 myCurveCache->D1(U, P, V);
674 myCurve->D1(U, P, V);
678 case GeomAbs_OffsetCurve:
679 myNestedEvaluator->D1(U, P, V);
683 myCurve->D1(U, P, V);
687 //=======================================================================
690 //=======================================================================
692 void GeomAdaptor_Curve::D2(const Standard_Real U,
693 gp_Pnt& P, gp_Vec& V1, gp_Vec& V2) const
697 case GeomAbs_BezierCurve:
698 case GeomAbs_BSplineCurve:
700 Standard_Integer aStart = 0, aFinish = 0;
701 if (IsBoundary(U, aStart, aFinish))
703 Handle(Geom_BSplineCurve) aBspl = Handle(Geom_BSplineCurve)::DownCast(myCurve);
704 aBspl->LocalD2(U, aStart, aFinish, P, V1, V2);
706 else if (!myCurveCache.IsNull()) // use cached data
708 if (!myCurveCache->IsCacheValid(U))
710 myCurveCache->D2(U, P, V1, V2);
713 myCurve->D2(U, P, V1, V2);
717 case GeomAbs_OffsetCurve:
718 myNestedEvaluator->D2(U, P, V1, V2);
722 myCurve->D2(U, P, V1, V2);
726 //=======================================================================
729 //=======================================================================
731 void GeomAdaptor_Curve::D3(const Standard_Real U,
732 gp_Pnt& P, gp_Vec& V1,
733 gp_Vec& V2, gp_Vec& V3) const
737 case GeomAbs_BezierCurve:
738 case GeomAbs_BSplineCurve:
740 Standard_Integer aStart = 0, aFinish = 0;
741 if (IsBoundary(U, aStart, aFinish))
743 Handle(Geom_BSplineCurve) aBspl = Handle(Geom_BSplineCurve)::DownCast(myCurve);
744 aBspl->LocalD3(U, aStart, aFinish, P, V1, V2, V3);
746 else if (!myCurveCache.IsNull()) // use cached data
748 if (!myCurveCache->IsCacheValid(U))
750 myCurveCache->D3(U, P, V1, V2, V3);
753 myCurve->D3(U, P, V1, V2, V3);
757 case GeomAbs_OffsetCurve:
758 myNestedEvaluator->D3(U, P, V1, V2, V3);
762 myCurve->D3(U, P, V1, V2, V3);
766 //=======================================================================
769 //=======================================================================
771 gp_Vec GeomAdaptor_Curve::DN(const Standard_Real U,
772 const Standard_Integer N) const
776 case GeomAbs_BezierCurve:
777 case GeomAbs_BSplineCurve:
779 Standard_Integer aStart = 0, aFinish = 0;
780 if (IsBoundary(U, aStart, aFinish))
782 Handle(Geom_BSplineCurve) aBspl = Handle(Geom_BSplineCurve)::DownCast(myCurve);
783 return aBspl->LocalDN(U, aStart, aFinish, N);
786 return myCurve->DN(U, N);
790 case GeomAbs_OffsetCurve:
791 return myNestedEvaluator->DN(U, N);
794 default: // to eliminate gcc warning
797 return myCurve->DN(U, N);
800 //=======================================================================
801 //function : Resolution
803 //=======================================================================
805 Standard_Real GeomAdaptor_Curve::Resolution(const Standard_Real R3D) const
807 switch ( myTypeCurve) {
810 case GeomAbs_Circle: {
811 Standard_Real R = Handle(Geom_Circle)::DownCast (myCurve)->Circ().Radius();
813 return 2*ASin(R3D/(2*R));
817 case GeomAbs_Ellipse: {
818 return R3D / Handle(Geom_Ellipse)::DownCast (myCurve)->MajorRadius();
820 case GeomAbs_BezierCurve: {
822 Handle(Geom_BezierCurve)::DownCast (myCurve)->Resolution(R3D,res);
825 case GeomAbs_BSplineCurve: {
827 Handle(Geom_BSplineCurve)::DownCast (myCurve)->Resolution(R3D,res);
831 return Precision::Parametric(R3D);
837 // -- The following methods must be called when GetType returned
838 // -- the corresponding type.
841 //=======================================================================
844 //=======================================================================
846 gp_Lin GeomAdaptor_Curve::Line() const
848 Standard_NoSuchObject_Raise_if(myTypeCurve != GeomAbs_Line, "");
849 return Handle(Geom_Line)::DownCast (myCurve)->Lin();
852 //=======================================================================
855 //=======================================================================
857 gp_Circ GeomAdaptor_Curve::Circle() const
859 Standard_NoSuchObject_Raise_if(myTypeCurve != GeomAbs_Circle, "");
860 return Handle(Geom_Circle)::DownCast (myCurve)->Circ();
863 //=======================================================================
866 //=======================================================================
868 gp_Elips GeomAdaptor_Curve::Ellipse() const
870 Standard_NoSuchObject_Raise_if(myTypeCurve != GeomAbs_Ellipse, "");
871 return Handle(Geom_Ellipse)::DownCast (myCurve)->Elips();
874 //=======================================================================
875 //function : Hyperbola
877 //=======================================================================
879 gp_Hypr GeomAdaptor_Curve::Hyperbola() const
881 Standard_NoSuchObject_Raise_if(myTypeCurve != GeomAbs_Hyperbola, "");
882 return Handle(Geom_Hyperbola)::DownCast (myCurve)->Hypr();
885 //=======================================================================
886 //function : Parabola
888 //=======================================================================
890 gp_Parab GeomAdaptor_Curve::Parabola() const
892 Standard_NoSuchObject_Raise_if(myTypeCurve != GeomAbs_Parabola, "");
893 return Handle(Geom_Parabola)::DownCast (myCurve)->Parab();
896 //=======================================================================
899 //=======================================================================
901 Standard_Integer GeomAdaptor_Curve::Degree() const
903 if (myTypeCurve == GeomAbs_BezierCurve)
904 return Handle(Geom_BezierCurve)::DownCast (myCurve)->Degree();
905 else if (myTypeCurve == GeomAbs_BSplineCurve)
906 return Handle(Geom_BSplineCurve)::DownCast (myCurve)->Degree();
908 Standard_NoSuchObject::Raise();
913 //=======================================================================
914 //function : IsRational
916 //=======================================================================
918 Standard_Boolean GeomAdaptor_Curve::IsRational() const {
919 switch( myTypeCurve) {
920 case GeomAbs_BSplineCurve:
921 return Handle(Geom_BSplineCurve)::DownCast (myCurve)->IsRational();
922 case GeomAbs_BezierCurve:
923 return Handle(Geom_BezierCurve)::DownCast (myCurve)->IsRational();
925 return Standard_False;
929 //=======================================================================
932 //=======================================================================
934 Standard_Integer GeomAdaptor_Curve::NbPoles() const
936 if (myTypeCurve == GeomAbs_BezierCurve)
937 return Handle(Geom_BezierCurve)::DownCast (myCurve)->NbPoles();
938 else if (myTypeCurve == GeomAbs_BSplineCurve)
939 return Handle(Geom_BSplineCurve)::DownCast (myCurve)->NbPoles();
941 Standard_NoSuchObject::Raise();
946 //=======================================================================
949 //=======================================================================
951 Standard_Integer GeomAdaptor_Curve::NbKnots() const
953 if ( myTypeCurve != GeomAbs_BSplineCurve)
954 Standard_NoSuchObject::Raise("GeomAdaptor_Curve::NbKnots");
955 return Handle(Geom_BSplineCurve)::DownCast (myCurve)->NbKnots();
958 //=======================================================================
961 //=======================================================================
963 Handle(Geom_BezierCurve) GeomAdaptor_Curve::Bezier() const
965 if ( myTypeCurve != GeomAbs_BezierCurve)
966 Standard_NoSuchObject::Raise("GeomAdaptor_Curve::Bezier");
967 return Handle(Geom_BezierCurve)::DownCast (myCurve);
970 //=======================================================================
973 //=======================================================================
975 Handle(Geom_BSplineCurve) GeomAdaptor_Curve::BSpline() const
977 if ( myTypeCurve != GeomAbs_BSplineCurve)
978 Standard_NoSuchObject::Raise("GeomAdaptor_Curve::BSpline");
980 return Handle(Geom_BSplineCurve)::DownCast (myCurve);