// Created on: 1993-04-29
// Created by: Bruno DUMORTIER
// Copyright (c) 1993-1999 Matra Datavision
-// Copyright (c) 1999-2012 OPEN CASCADE SAS
+// Copyright (c) 1999-2014 OPEN CASCADE SAS
//
-// The content of this file is subject to the Open CASCADE Technology Public
-// License Version 6.5 (the "License"). You may not use the content of this file
-// except in compliance with the License. Please obtain a copy of the License
-// at http://www.opencascade.org and read it completely before using this file.
+// This file is part of Open CASCADE Technology software library.
//
-// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
-// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
//
-// The Original Code and all software distributed under the License is
-// distributed on an "AS IS" basis, without warranty of any kind, and the
-// Initial Developer hereby disclaims all such warranties, including without
-// limitation, any warranties of merchantability, fitness for a particular
-// purpose or non-infringement. Please see the License for the specific terms
-// and conditions governing the rights and limitations under the License.
-
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
// 20/02/97 : PMN -> Positionement local sur BSpline (PRO6902)
// 10/07/97 : PMN -> Pas de calcul de resolution dans Nb(Intervals)(PRO9248)
#define No_Standard_RangeError
#define No_Standard_OutOfRange
-#include <GeomAdaptor_Curve.ixx>
-#include <GeomAdaptor_HCurve.hxx>
#include <Adaptor3d_HCurve.hxx>
#include <BSplCLib.hxx>
-#include <GeomAbs_Shape.hxx>
-#include <TColgp_Array1OfPnt.hxx>
-#include <TColStd_Array1OfReal.hxx>
-#include <TColStd_Array1OfInteger.hxx>
-#include <TColStd_HArray1OfInteger.hxx>
-#include <Precision.hxx>
-#include <Geom_TrimmedCurve.hxx>
-#include <Geom_Circle.hxx>
-#include <Geom_Line.hxx>
-#include <Geom_TrimmedCurve.hxx>
+#include <BSplCLib_Cache.hxx>
#include <Geom_BezierCurve.hxx>
#include <Geom_BSplineCurve.hxx>
+#include <Geom_Circle.hxx>
+#include <Geom_Curve.hxx>
#include <Geom_Ellipse.hxx>
-#include <Geom_Parabola.hxx>
#include <Geom_Hyperbola.hxx>
-//#include <GeomConvert_BSplineCurveKnotSplitting.hxx>
-
-#include <Standard_OutOfRange.hxx>
+#include <Geom_Line.hxx>
+#include <Geom_OffsetCurve.hxx>
+#include <Geom_Parabola.hxx>
+#include <Geom_TrimmedCurve.hxx>
+#include <GeomAbs_Shape.hxx>
+#include <GeomAdaptor_Curve.hxx>
+#include <GeomAdaptor_HCurve.hxx>
+#include <GeomAdaptor_Surface.hxx>
+#include <GeomEvaluator_OffsetCurve.hxx>
+#include <gp_Circ.hxx>
+#include <gp_Elips.hxx>
+#include <gp_Hypr.hxx>
+#include <gp_Lin.hxx>
+#include <gp_Parab.hxx>
+#include <gp_Pnt.hxx>
+#include <gp_Vec.hxx>
+#include <Precision.hxx>
+#include <Standard_ConstructionError.hxx>
+#include <Standard_DomainError.hxx>
#include <Standard_NoSuchObject.hxx>
-#include <Standard_NullObject.hxx>
#include <Standard_NotImplemented.hxx>
-#include <Geom_OffsetCurve.hxx>
+#include <Standard_NullObject.hxx>
+#include <Standard_OutOfRange.hxx>
+#include <TColgp_Array1OfPnt.hxx>
+#include <TColStd_Array1OfInteger.hxx>
+#include <TColStd_Array1OfReal.hxx>
+#include <TColStd_HArray1OfInteger.hxx>
+
+//#include <GeomConvert_BSplineCurveKnotSplitting.hxx>
+static const Standard_Real PosTol = Precision::PConfusion() / 2;
-#define myBspl (*((Handle(Geom_BSplineCurve)*)&myCurve))
-#define PosTol Precision::PConfusion()/2
//=======================================================================
//function : LocalContinuity
const
{
Standard_NoSuchObject_Raise_if(myTypeCurve!=GeomAbs_BSplineCurve," ");
- Standard_Integer Nb = myBspl->NbKnots();
+ Standard_Integer Nb = myBSplineCurve->NbKnots();
Standard_Integer Index1 = 0;
Standard_Integer Index2 = 0;
Standard_Real newFirst, newLast;
- TColStd_Array1OfReal TK(1,Nb);
- TColStd_Array1OfInteger TM(1,Nb);
- myBspl->Knots(TK);
- myBspl->Multiplicities(TM);
- BSplCLib::LocateParameter(myBspl->Degree(),TK,TM,U1,myBspl->IsPeriodic(),
+ const TColStd_Array1OfReal& TK = myBSplineCurve->Knots();
+ const TColStd_Array1OfInteger& TM = myBSplineCurve->Multiplicities();
+ BSplCLib::LocateParameter(myBSplineCurve->Degree(),TK,TM,U1,myBSplineCurve->IsPeriodic(),
1,Nb,Index1,newFirst);
- BSplCLib::LocateParameter(myBspl->Degree(),TK,TM,U2,myBspl->IsPeriodic(),
+ BSplCLib::LocateParameter(myBSplineCurve->Degree(),TK,TM,U2,myBSplineCurve->IsPeriodic(),
1,Nb,Index2,newLast);
if ( Abs(newFirst-TK(Index1+1))<Precision::PConfusion()) {
if (Index1 < Nb) Index1++;
Index2--;
Standard_Integer MultMax;
// attention aux courbes peridiques.
- if ( (myBspl->IsPeriodic()) && (Index1 == Nb) )
+ if ( (myBSplineCurve->IsPeriodic()) && (Index1 == Nb) )
Index1 = 1;
if ( Index2 - Index1 <= 0) {
for(Standard_Integer i = Index1+1;i<=Index2;i++) {
if ( TM(i)>MultMax) MultMax=TM(i);
}
- MultMax = myBspl->Degree() - MultMax;
+ MultMax = myBSplineCurve->Degree() - MultMax;
}
if ( MultMax <= 0) {
return GeomAbs_C0;
{
myFirst = UFirst;
myLast = ULast;
+ myCurveCache.Nullify();
if ( myCurve != C) {
myCurve = C;
+ myNestedEvaluator.Nullify();
+ myBSplineCurve.Nullify();
const Handle(Standard_Type)& TheType = C->DynamicType();
if ( TheType == STANDARD_TYPE(Geom_TrimmedCurve)) {
- Load((*((Handle(Geom_TrimmedCurve)*)&C))->BasisCurve(),UFirst,ULast);
+ Load(Handle(Geom_TrimmedCurve)::DownCast (C)->BasisCurve(),UFirst,ULast);
}
else if ( TheType == STANDARD_TYPE(Geom_Circle)) {
myTypeCurve = GeomAbs_Circle;
}
else if ( TheType == STANDARD_TYPE(Geom_BSplineCurve)) {
myTypeCurve = GeomAbs_BSplineCurve;
+ myBSplineCurve = Handle(Geom_BSplineCurve)::DownCast(myCurve);
+ }
+ else if ( TheType == STANDARD_TYPE(Geom_OffsetCurve)) {
+ myTypeCurve = GeomAbs_OffsetCurve;
+ Handle(Geom_OffsetCurve) anOffsetCurve = Handle(Geom_OffsetCurve)::DownCast(myCurve);
+ // Create nested adaptor for base curve
+ Handle(Geom_Curve) aBaseCurve = anOffsetCurve->BasisCurve();
+ Handle(GeomAdaptor_HCurve) aBaseAdaptor = new GeomAdaptor_HCurve(aBaseCurve);
+ myNestedEvaluator = new GeomEvaluator_OffsetCurve(
+ aBaseAdaptor, anOffsetCurve->Offset(), anOffsetCurve->Direction());
}
else {
myTypeCurve = GeomAbs_OtherCurve;
}
}
-}
+}
// --
// -- Global methods - Apply to the whole curve.
if (myTypeCurve == GeomAbs_BSplineCurve)
return LocalContinuity(myFirst, myLast);
- if (myCurve->IsKind(STANDARD_TYPE(Geom_OffsetCurve)))
+ if (myTypeCurve == GeomAbs_OffsetCurve)
{
const GeomAbs_Shape S =
- (*((Handle(Geom_OffsetCurve)*)&myCurve))->BasisCurve()->Continuity();
+ Handle(Geom_OffsetCurve)::DownCast (myCurve)->GetBasisCurveContinuity();
switch(S)
{
case GeomAbs_CN: return GeomAbs_CN;
case GeomAbs_C3: return GeomAbs_C2;
case GeomAbs_C2: return GeomAbs_C1;
- case GeomAbs_C1: return GeomAbs_C0;
+ case GeomAbs_C1: return GeomAbs_C0;
+ case GeomAbs_G1: return GeomAbs_G1;
+ case GeomAbs_G2: return GeomAbs_G2;
default:
- Standard_NoSuchObject::Raise("GeomAdaptor_Curve::Continuity");
+ throw Standard_NoSuchObject("GeomAdaptor_Curve::Continuity");
}
}
else if (myTypeCurve == GeomAbs_OtherCurve) {
- Standard_NoSuchObject::Raise("GeomAdaptor_Curve::Contunuity");
+ throw Standard_NoSuchObject("GeomAdaptor_Curve::Contunuity");
}
return GeomAbs_CN;
//purpose :
//=======================================================================
-Standard_Integer GeomAdaptor_Curve::NbIntervals(const GeomAbs_Shape S)
+Standard_Integer GeomAdaptor_Curve::NbIntervals(const GeomAbs_Shape S) const
{
Standard_Integer myNbIntervals = 1;
Standard_Integer NbSplit;
if (myTypeCurve == GeomAbs_BSplineCurve) {
- Standard_Integer FirstIndex = myBspl->FirstUKnotIndex();
- Standard_Integer LastIndex = myBspl->LastUKnotIndex();
+ Standard_Integer FirstIndex = myBSplineCurve->FirstUKnotIndex();
+ Standard_Integer LastIndex = myBSplineCurve->LastUKnotIndex();
TColStd_Array1OfInteger Inter (1, LastIndex-FirstIndex+1);
if ( S > Continuity()) {
Standard_Integer Cont;
switch ( S) {
case GeomAbs_G1:
case GeomAbs_G2:
- Standard_DomainError::Raise("GeomAdaptor_Curve::NbIntervals");
+ throw Standard_DomainError("GeomAdaptor_Curve::NbIntervals");
break;
case GeomAbs_C0:
myNbIntervals = 1;
if ( S == GeomAbs_C1) Cont = 1;
else if ( S == GeomAbs_C2) Cont = 2;
else if ( S == GeomAbs_C3) Cont = 3;
- else Cont = myBspl->Degree();
- Standard_Integer FirstIndex = myBspl->FirstUKnotIndex();
- Standard_Integer LastIndex = myBspl->LastUKnotIndex();
- Standard_Integer Degree = myBspl->Degree();
- Standard_Integer NbKnots = myBspl->NbKnots();
+ else Cont = myBSplineCurve->Degree();
+ Standard_Integer Degree = myBSplineCurve->Degree();
+ Standard_Integer NbKnots = myBSplineCurve->NbKnots();
TColStd_Array1OfInteger Mults (1, NbKnots);
- myBspl->Multiplicities (Mults);
+ myBSplineCurve->Multiplicities (Mults);
NbSplit = 1;
Standard_Integer Index = FirstIndex;
Inter (NbSplit) = Index;
Standard_Integer NbInt = NbSplit-1;
- Standard_Integer Nb = myBspl->NbKnots();
+ Standard_Integer Nb = myBSplineCurve->NbKnots();
Standard_Integer Index1 = 0;
Standard_Integer Index2 = 0;
Standard_Real newFirst, newLast;
- TColStd_Array1OfReal TK(1,Nb);
- TColStd_Array1OfInteger TM(1,Nb);
- myBspl->Knots(TK);
- myBspl->Multiplicities(TM);
- BSplCLib::LocateParameter(myBspl->Degree(),TK,TM,myFirst,
- myBspl->IsPeriodic(),
+ const TColStd_Array1OfReal& TK = myBSplineCurve->Knots();
+ const TColStd_Array1OfInteger& TM = myBSplineCurve->Multiplicities();
+ BSplCLib::LocateParameter(myBSplineCurve->Degree(),TK,TM,myFirst,
+ myBSplineCurve->IsPeriodic(),
1,Nb,Index1,newFirst);
- BSplCLib::LocateParameter(myBspl->Degree(),TK,TM,myLast,
- myBspl->IsPeriodic(),
+ BSplCLib::LocateParameter(myBSplineCurve->Degree(),TK,TM,myLast,
+ myBSplineCurve->IsPeriodic(),
1,Nb,Index2,newLast);
// On decale eventuellement les indices
}
}
- else if (myCurve->IsKind(STANDARD_TYPE(Geom_OffsetCurve))){
+ else if (myTypeCurve == GeomAbs_OffsetCurve) {
GeomAbs_Shape BaseS=GeomAbs_C0;
switch(S){
case GeomAbs_G1:
case GeomAbs_G2:
- Standard_DomainError::Raise("GeomAdaptor_Curve::NbIntervals");
+ throw Standard_DomainError("GeomAdaptor_Curve::NbIntervals");
break;
case GeomAbs_C0: BaseS = GeomAbs_C1; break;
case GeomAbs_C1: BaseS = GeomAbs_C2; break;
default: BaseS = GeomAbs_CN;
}
GeomAdaptor_Curve C
- ((*((Handle(Geom_OffsetCurve)*)&myCurve))->BasisCurve());
+ (Handle(Geom_OffsetCurve)::DownCast (myCurve)->BasisCurve());
// akm 05/04/02 (OCC278) If our curve is trimmed we must recalculate
// the number of intervals obtained from the basis to
// vvv reflect parameter bounds
//=======================================================================
void GeomAdaptor_Curve::Intervals(TColStd_Array1OfReal& T,
- const GeomAbs_Shape S )
+ const GeomAbs_Shape S ) const
{
Standard_Integer myNbIntervals = 1;
Standard_Integer NbSplit;
if (myTypeCurve == GeomAbs_BSplineCurve)
{
- Standard_Integer FirstIndex = myBspl->FirstUKnotIndex();
- Standard_Integer LastIndex = myBspl->LastUKnotIndex();
+ Standard_Integer FirstIndex = myBSplineCurve->FirstUKnotIndex();
+ Standard_Integer LastIndex = myBSplineCurve->LastUKnotIndex();
TColStd_Array1OfInteger Inter (1, LastIndex-FirstIndex+1);
if ( S > Continuity()) {
switch ( S) {
case GeomAbs_G1:
case GeomAbs_G2:
- Standard_DomainError::Raise("Geom2dAdaptor_Curve::NbIntervals");
+ throw Standard_DomainError("Geom2dAdaptor_Curve::NbIntervals");
break;
case GeomAbs_C0:
myNbIntervals = 1;
if ( S == GeomAbs_C1) Cont = 1;
else if ( S == GeomAbs_C2) Cont = 2;
else if ( S == GeomAbs_C3) Cont = 3;
- else Cont = myBspl->Degree();
- Standard_Integer FirstIndex = myBspl->FirstUKnotIndex();
- Standard_Integer LastIndex = myBspl->LastUKnotIndex();
- Standard_Integer Degree = myBspl->Degree();
- Standard_Integer NbKnots = myBspl->NbKnots();
+ else Cont = myBSplineCurve->Degree();
+ Standard_Integer Degree = myBSplineCurve->Degree();
+ Standard_Integer NbKnots = myBSplineCurve->NbKnots();
TColStd_Array1OfInteger Mults (1, NbKnots);
- myBspl->Multiplicities (Mults);
+ myBSplineCurve->Multiplicities (Mults);
NbSplit = 1;
Standard_Integer Index = FirstIndex;
Inter (NbSplit) = Index;
// TColStd_Array1OfInteger Inter(1,NbInt+1);
// Convector.Splitting( Inter);
- Standard_Integer Nb = myBspl->NbKnots();
+ Standard_Integer Nb = myBSplineCurve->NbKnots();
Standard_Integer Index1 = 0;
Standard_Integer Index2 = 0;
Standard_Real newFirst, newLast;
- TColStd_Array1OfReal TK(1,Nb);
- TColStd_Array1OfInteger TM(1,Nb);
- myBspl->Knots(TK);
- myBspl->Multiplicities(TM);
- BSplCLib::LocateParameter(myBspl->Degree(),TK,TM,myFirst,
- myBspl->IsPeriodic(),
+ const TColStd_Array1OfReal& TK = myBSplineCurve->Knots();
+ const TColStd_Array1OfInteger& TM = myBSplineCurve->Multiplicities();
+ BSplCLib::LocateParameter(myBSplineCurve->Degree(),TK,TM,myFirst,
+ myBSplineCurve->IsPeriodic(),
1,Nb,Index1,newFirst);
- BSplCLib::LocateParameter(myBspl->Degree(),TK,TM,myLast,
- myBspl->IsPeriodic(),
+ BSplCLib::LocateParameter(myBSplineCurve->Degree(),TK,TM,myLast,
+ myBSplineCurve->IsPeriodic(),
1,Nb,Index2,newLast);
FirstParam = newFirst;
LastParam = newLast;
}
}
- else if (myCurve->IsKind(STANDARD_TYPE(Geom_OffsetCurve))){
+ else if (myTypeCurve == GeomAbs_OffsetCurve){
GeomAbs_Shape BaseS=GeomAbs_C0;
switch(S){
case GeomAbs_G1:
case GeomAbs_G2:
- Standard_DomainError::Raise("GeomAdaptor_Curve::NbIntervals");
+ throw Standard_DomainError("GeomAdaptor_Curve::NbIntervals");
break;
case GeomAbs_C0: BaseS = GeomAbs_C1; break;
case GeomAbs_C1: BaseS = GeomAbs_C2; break;
default: BaseS = GeomAbs_CN;
}
GeomAdaptor_Curve C
- ((*((Handle(Geom_OffsetCurve)*)&myCurve))->BasisCurve());
+ (Handle(Geom_OffsetCurve)::DownCast (myCurve)->BasisCurve());
// akm 05/04/02 (OCC278) If our curve is trimmed we must recalculate
// the array of intervals obtained from the basis to
// vvv reflect parameter bounds
Standard_Boolean GeomAdaptor_Curve::IsPeriodic() const
{
- return (myCurve->IsPeriodic()? IsClosed() : Standard_False);
+ return myCurve->IsPeriodic();
}
//=======================================================================
}
//=======================================================================
-//function : Value
+//function : RebuildCache
//purpose :
//=======================================================================
+void GeomAdaptor_Curve::RebuildCache(const Standard_Real theParameter) const
+{
+ if (myTypeCurve == GeomAbs_BezierCurve)
+ {
+ // Create cache for Bezier
+ Handle(Geom_BezierCurve) aBezier = Handle(Geom_BezierCurve)::DownCast(myCurve);
+ Standard_Integer aDeg = aBezier->Degree();
+ TColStd_Array1OfReal aFlatKnots(BSplCLib::FlatBezierKnots(aDeg), 1, 2 * (aDeg + 1));
+ if (myCurveCache.IsNull())
+ myCurveCache = new BSplCLib_Cache(aDeg, aBezier->IsPeriodic(), aFlatKnots,
+ aBezier->Poles(), aBezier->Weights());
+ myCurveCache->BuildCache(theParameter, aDeg, aBezier->IsPeriodic(), aFlatKnots,
+ aBezier->Poles(), aBezier->Weights());
+}
+ else if (myTypeCurve == GeomAbs_BSplineCurve)
+{
+ // Create cache for B-spline
+ if (myCurveCache.IsNull())
+ myCurveCache = new BSplCLib_Cache(myBSplineCurve->Degree(), myBSplineCurve->IsPeriodic(),
+ myBSplineCurve->KnotSequence(), myBSplineCurve->Poles(), myBSplineCurve->Weights());
+ myCurveCache->BuildCache(theParameter, myBSplineCurve->Degree(),
+ myBSplineCurve->IsPeriodic(), myBSplineCurve->KnotSequence(),
+ myBSplineCurve->Poles(), myBSplineCurve->Weights());
+}
+}
-gp_Pnt GeomAdaptor_Curve::Value(const Standard_Real U) const
+//=======================================================================
+//function : IsBoundary
+//purpose :
+//=======================================================================
+Standard_Boolean GeomAdaptor_Curve::IsBoundary(const Standard_Real theU,
+ Standard_Integer& theSpanStart,
+ Standard_Integer& theSpanFinish) const
{
- if ( (myTypeCurve == GeomAbs_BSplineCurve)&&
- (U==myFirst || U==myLast) ) {
- Standard_Integer Ideb, Ifin;
- if (U==myFirst) {
- myBspl->LocateU(myFirst, PosTol, Ideb, Ifin);
- if (Ideb<1) Ideb=1;
- if (Ideb>=Ifin) Ifin = Ideb+1;
+ if (!myBSplineCurve.IsNull() && (theU == myFirst || theU == myLast))
+ {
+ if (theU == myFirst)
+ {
+ myBSplineCurve->LocateU(myFirst, PosTol, theSpanStart, theSpanFinish);
+ if (theSpanStart < 1)
+ theSpanStart = 1;
+ if (theSpanStart >= theSpanFinish)
+ theSpanFinish = theSpanStart + 1;
}
- if (U==myLast) {
- myBspl->LocateU(myLast, PosTol, Ideb, Ifin);
- if (Ifin>myBspl->NbKnots()) Ifin = myBspl->NbKnots();
- if (Ideb>=Ifin) Ideb = Ifin-1;
+ else if (theU == myLast)
+ {
+ myBSplineCurve->LocateU(myLast, PosTol, theSpanStart, theSpanFinish);
+ if (theSpanFinish > myBSplineCurve->NbKnots())
+ theSpanFinish = myBSplineCurve->NbKnots();
+ if (theSpanStart >= theSpanFinish)
+ theSpanStart = theSpanFinish - 1;
}
- return myBspl->LocalValue(U, Ideb, Ifin);
+ return Standard_True;
+ }
+ return Standard_False;
}
- return myCurve->Value(U);
+
+//=======================================================================
+//function : Value
+//purpose :
+//=======================================================================
+
+gp_Pnt GeomAdaptor_Curve::Value(const Standard_Real U) const
+{
+ gp_Pnt aValue;
+ D0(U, aValue);
+ return aValue;
}
//=======================================================================
void GeomAdaptor_Curve::D0(const Standard_Real U, gp_Pnt& P) const
{
- if ( (myTypeCurve == GeomAbs_BSplineCurve)&&
- (U==myFirst || U==myLast) ) {
- Standard_Integer Ideb, Ifin;
- if (U==myFirst) {
- myBspl->LocateU(myFirst, PosTol, Ideb, Ifin);
- if (Ideb<1) Ideb=1;
- if (Ideb>=Ifin) Ifin = Ideb+1;
- }
- if (U==myLast) {
- myBspl->LocateU(myLast, PosTol, Ideb, Ifin);
- if (Ifin>myBspl->NbKnots()) Ifin = myBspl->NbKnots();
- if (Ideb>=Ifin) Ideb = Ifin-1;
+ switch (myTypeCurve)
+{
+ case GeomAbs_BezierCurve:
+ case GeomAbs_BSplineCurve:
+ {
+ Standard_Integer aStart = 0, aFinish = 0;
+ if (IsBoundary(U, aStart, aFinish))
+ {
+ myBSplineCurve->LocalD0(U, aStart, aFinish, P);
}
- myBspl->LocalD0( U, Ideb, Ifin, P);
+ else
+ {
+ // use cached data
+ if (myCurveCache.IsNull() || !myCurveCache->IsCacheValid(U))
+ RebuildCache(U);
+ myCurveCache->D0(U, P);
}
- else {
+ break;
+}
+
+ case GeomAbs_OffsetCurve:
+ myNestedEvaluator->D0(U, P);
+ break;
+
+ default:
myCurve->D0(U, P);
- }
+}
}
//=======================================================================
void GeomAdaptor_Curve::D1(const Standard_Real U, gp_Pnt& P, gp_Vec& V) const
{
- if ( (myTypeCurve == GeomAbs_BSplineCurve)&&
- (U==myFirst || U==myLast) ) {
- Standard_Integer Ideb, Ifin;
- if (U==myFirst) {
- myBspl->LocateU(myFirst, PosTol, Ideb, Ifin);
- if (Ideb<1) Ideb=1;
- if (Ideb>=Ifin) Ifin = Ideb+1;
- }
- if (U==myLast) {
- myBspl->LocateU(myLast, PosTol, Ideb, Ifin);
- if (Ifin>myBspl->NbKnots()) Ifin = myBspl->NbKnots();
- if (Ideb>=Ifin) Ideb = Ifin-1;
+ switch (myTypeCurve)
+{
+ case GeomAbs_BezierCurve:
+ case GeomAbs_BSplineCurve:
+ {
+ Standard_Integer aStart = 0, aFinish = 0;
+ if (IsBoundary(U, aStart, aFinish))
+ {
+ myBSplineCurve->LocalD1(U, aStart, aFinish, P, V);
}
- myBspl->LocalD1( U, Ideb, Ifin, P, V);
- }
- else {
- myCurve->D1( U, P, V);
+ else
+ {
+ // use cached data
+ if (myCurveCache.IsNull() || !myCurveCache->IsCacheValid(U))
+ RebuildCache(U);
+ myCurveCache->D1(U, P, V);
}
+ break;
+}
+
+ case GeomAbs_OffsetCurve:
+ myNestedEvaluator->D1(U, P, V);
+ break;
+
+ default:
+ myCurve->D1(U, P, V);
+}
}
//=======================================================================
//=======================================================================
void GeomAdaptor_Curve::D2(const Standard_Real U,
- gp_Pnt& P, gp_Vec& V1, gp_Vec& V2) const
-{
- if ( (myTypeCurve == GeomAbs_BSplineCurve)&&
- (U==myFirst || U==myLast) ) {
- Standard_Integer Ideb, Ifin;
- if (U==myFirst) {
- myBspl->LocateU(myFirst, PosTol, Ideb, Ifin);
- if (Ideb<1) Ideb=1;
- if (Ideb>=Ifin) Ifin = Ideb+1;
- }
- if (U==myLast) {
- myBspl->LocateU(myLast, PosTol, Ideb, Ifin);
- if (Ifin>myBspl->NbKnots()) Ifin = myBspl->NbKnots();
- if (Ideb>=Ifin) Ideb = Ifin-1;
+ gp_Pnt& P, gp_Vec& V1, gp_Vec& V2) const
+{
+ switch (myTypeCurve)
+{
+ case GeomAbs_BezierCurve:
+ case GeomAbs_BSplineCurve:
+ {
+ Standard_Integer aStart = 0, aFinish = 0;
+ if (IsBoundary(U, aStart, aFinish))
+ {
+ myBSplineCurve->LocalD2(U, aStart, aFinish, P, V1, V2);
}
- myBspl->LocalD2( U, Ideb, Ifin, P, V1, V2);
- }
- else {
- myCurve->D2( U, P, V1, V2);
+ else
+ {
+ // use cached data
+ if (myCurveCache.IsNull() || !myCurveCache->IsCacheValid(U))
+ RebuildCache(U);
+ myCurveCache->D2(U, P, V1, V2);
}
+ break;
+}
+
+ case GeomAbs_OffsetCurve:
+ myNestedEvaluator->D2(U, P, V1, V2);
+ break;
+
+ default:
+ myCurve->D2(U, P, V1, V2);
+}
}
//=======================================================================
//=======================================================================
void GeomAdaptor_Curve::D3(const Standard_Real U,
- gp_Pnt& P, gp_Vec& V1,
- gp_Vec& V2, gp_Vec& V3) const
-{
- if ( (myTypeCurve == GeomAbs_BSplineCurve) &&
- (U==myFirst || U==myLast) ) {
- Standard_Integer Ideb, Ifin;
- if (U==myFirst) {
- myBspl->LocateU(myFirst, PosTol, Ideb, Ifin);
- if (Ideb<1) Ideb=1;
- if (Ideb>=Ifin) Ifin = Ideb+1;
- }
- if (U==myLast) {
- myBspl->LocateU(myLast, PosTol, Ideb, Ifin);
- if (Ifin>myBspl->NbKnots()) Ifin = myBspl->NbKnots();
- if (Ideb>=Ifin) Ideb = Ifin-1;
+ gp_Pnt& P, gp_Vec& V1,
+ gp_Vec& V2, gp_Vec& V3) const
+{
+ switch (myTypeCurve)
+{
+ case GeomAbs_BezierCurve:
+ case GeomAbs_BSplineCurve:
+ {
+ Standard_Integer aStart = 0, aFinish = 0;
+ if (IsBoundary(U, aStart, aFinish))
+ {
+ myBSplineCurve->LocalD3(U, aStart, aFinish, P, V1, V2, V3);
}
- myBspl->LocalD3( U, Ideb, Ifin, P, V1, V2, V3);
- }
- else {
- myCurve->D3( U, P, V1, V2, V3);
+ else
+ {
+ // use cached data
+ if (myCurveCache.IsNull() || !myCurveCache->IsCacheValid(U))
+ RebuildCache(U);
+ myCurveCache->D3(U, P, V1, V2, V3);
}
+ break;
+}
+
+ case GeomAbs_OffsetCurve:
+ myNestedEvaluator->D3(U, P, V1, V2, V3);
+ break;
+
+ default:
+ myCurve->D3(U, P, V1, V2, V3);
+}
}
//=======================================================================
//=======================================================================
gp_Vec GeomAdaptor_Curve::DN(const Standard_Real U,
- const Standard_Integer N) const
-{
- if ( (myTypeCurve == GeomAbs_BSplineCurve) &&
- (U==myFirst || U==myLast) ) {
- Standard_Integer Ideb, Ifin;
- if (U==myFirst) {
- myBspl->LocateU(myFirst, PosTol, Ideb, Ifin);
- if (Ideb<1) Ideb=1;
- if (Ideb>=Ifin) Ifin = Ideb+1;
+ const Standard_Integer N) const
+{
+ switch (myTypeCurve)
+{
+ case GeomAbs_BezierCurve:
+ case GeomAbs_BSplineCurve:
+ {
+ Standard_Integer aStart = 0, aFinish = 0;
+ if (IsBoundary(U, aStart, aFinish))
+ {
+ return myBSplineCurve->LocalDN(U, aStart, aFinish, N);
}
- if (U==myLast) {
- myBspl->LocateU(myLast, PosTol, Ideb, Ifin);
- if (Ifin>myBspl->NbKnots()) Ifin = myBspl->NbKnots();
- if (Ideb>=Ifin) Ideb = Ifin-1;
- }
- return myBspl->LocalDN( U, Ideb, Ifin, N);
- }
- else {
- return myCurve->DN( U, N);
+ else
+ return myCurve->DN( U, N);
+ break;
+}
+
+ case GeomAbs_OffsetCurve:
+ return myNestedEvaluator->DN(U, N);
+ break;
+
+ default: // to eliminate gcc warning
+ break;
}
+ return myCurve->DN(U, N);
}
//=======================================================================
case GeomAbs_Line :
return R3D;
case GeomAbs_Circle: {
- Standard_Real R = (*((Handle(Geom_Circle)*)&myCurve))->Circ().Radius();
+ Standard_Real R = Handle(Geom_Circle)::DownCast (myCurve)->Circ().Radius();
if ( R > R3D/2. )
return 2*ASin(R3D/(2*R));
else
return 2*M_PI;
}
case GeomAbs_Ellipse: {
- return R3D / (*((Handle(Geom_Ellipse)*)&myCurve))->MajorRadius();
+ return R3D / Handle(Geom_Ellipse)::DownCast (myCurve)->MajorRadius();
}
case GeomAbs_BezierCurve: {
Standard_Real res;
- (*((Handle(Geom_BezierCurve)*)&myCurve))->Resolution(R3D,res);
+ Handle(Geom_BezierCurve)::DownCast (myCurve)->Resolution(R3D,res);
return res;
}
case GeomAbs_BSplineCurve: {
Standard_Real res;
- (*((Handle(Geom_BSplineCurve)*)&myCurve))->Resolution(R3D,res);
+ myBSplineCurve->Resolution(R3D,res);
return res;
}
default:
gp_Lin GeomAdaptor_Curve::Line() const
{
- Standard_NoSuchObject_Raise_if(myTypeCurve != GeomAbs_Line, "");
- return (*((Handle(Geom_Line)*)&myCurve))->Lin();
+ Standard_NoSuchObject_Raise_if (myTypeCurve != GeomAbs_Line,
+ "GeomAdaptor_Curve::Line() - curve is not a Line");
+ return Handle(Geom_Line)::DownCast (myCurve)->Lin();
}
//=======================================================================
gp_Circ GeomAdaptor_Curve::Circle() const
{
- Standard_NoSuchObject_Raise_if(myTypeCurve != GeomAbs_Circle, "");
- return (*((Handle(Geom_Circle)*)&myCurve))->Circ();
+ Standard_NoSuchObject_Raise_if (myTypeCurve != GeomAbs_Circle,
+ "GeomAdaptor_Curve::Circle() - curve is not a Circle");
+ return Handle(Geom_Circle)::DownCast (myCurve)->Circ();
}
//=======================================================================
gp_Elips GeomAdaptor_Curve::Ellipse() const
{
- Standard_NoSuchObject_Raise_if(myTypeCurve != GeomAbs_Ellipse, "");
- return (*((Handle(Geom_Ellipse)*)&myCurve))->Elips();
+ Standard_NoSuchObject_Raise_if (myTypeCurve != GeomAbs_Ellipse,
+ "GeomAdaptor_Curve::Ellipse() - curve is not an Ellipse");
+ return Handle(Geom_Ellipse)::DownCast (myCurve)->Elips();
}
//=======================================================================
gp_Hypr GeomAdaptor_Curve::Hyperbola() const
{
- Standard_NoSuchObject_Raise_if(myTypeCurve != GeomAbs_Hyperbola, "");
- return (*((Handle(Geom_Hyperbola)*)&myCurve))->Hypr();
+ Standard_NoSuchObject_Raise_if (myTypeCurve != GeomAbs_Hyperbola,
+ "GeomAdaptor_Curve::Hyperbola() - curve is not a Hyperbola");
+ return Handle(Geom_Hyperbola)::DownCast (myCurve)->Hypr();
}
//=======================================================================
gp_Parab GeomAdaptor_Curve::Parabola() const
{
- Standard_NoSuchObject_Raise_if(myTypeCurve != GeomAbs_Parabola, "");
- return (*((Handle(Geom_Parabola)*)&myCurve))->Parab();
+ Standard_NoSuchObject_Raise_if (myTypeCurve != GeomAbs_Parabola,
+ "GeomAdaptor_Curve::Parabola() - curve is not a Parabola");
+ return Handle(Geom_Parabola)::DownCast (myCurve)->Parab();
}
//=======================================================================
Standard_Integer GeomAdaptor_Curve::Degree() const
{
if (myTypeCurve == GeomAbs_BezierCurve)
- return (*((Handle(Geom_BezierCurve)*)&myCurve))->Degree();
+ return Handle(Geom_BezierCurve)::DownCast (myCurve)->Degree();
else if (myTypeCurve == GeomAbs_BSplineCurve)
- return (*((Handle(Geom_BSplineCurve)*)&myCurve))->Degree();
+ return myBSplineCurve->Degree();
else
- Standard_NoSuchObject::Raise();
- // portage WNT
- return 0;
+ throw Standard_NoSuchObject();
}
//=======================================================================
Standard_Boolean GeomAdaptor_Curve::IsRational() const {
switch( myTypeCurve) {
case GeomAbs_BSplineCurve:
- return (*((Handle(Geom_BSplineCurve)*)&myCurve))->IsRational();
+ return myBSplineCurve->IsRational();
case GeomAbs_BezierCurve:
- return (*((Handle(Geom_BezierCurve)*)&myCurve))->IsRational();
+ return Handle(Geom_BezierCurve)::DownCast (myCurve)->IsRational();
default:
return Standard_False;
}
Standard_Integer GeomAdaptor_Curve::NbPoles() const
{
if (myTypeCurve == GeomAbs_BezierCurve)
- return (*((Handle(Geom_BezierCurve)*)&myCurve))->NbPoles();
+ return Handle(Geom_BezierCurve)::DownCast (myCurve)->NbPoles();
else if (myTypeCurve == GeomAbs_BSplineCurve)
- return (*((Handle(Geom_BSplineCurve)*)&myCurve))->NbPoles();
+ return myBSplineCurve->NbPoles();
else
- Standard_NoSuchObject::Raise();
- // portage WNT
- return 0;
+ throw Standard_NoSuchObject();
}
//=======================================================================
Standard_Integer GeomAdaptor_Curve::NbKnots() const
{
if ( myTypeCurve != GeomAbs_BSplineCurve)
- Standard_NoSuchObject::Raise("GeomAdaptor_Curve::NbKnots");
- return (*((Handle(Geom_BSplineCurve)*)&myCurve))->NbKnots();
+ throw Standard_NoSuchObject("GeomAdaptor_Curve::NbKnots");
+ return myBSplineCurve->NbKnots();
}
//=======================================================================
Handle(Geom_BezierCurve) GeomAdaptor_Curve::Bezier() const
{
if ( myTypeCurve != GeomAbs_BezierCurve)
- Standard_NoSuchObject::Raise("GeomAdaptor_Curve::Bezier");
- return *((Handle(Geom_BezierCurve)*)&myCurve);
+ throw Standard_NoSuchObject("GeomAdaptor_Curve::Bezier");
+ return Handle(Geom_BezierCurve)::DownCast (myCurve);
}
//=======================================================================
Handle(Geom_BSplineCurve) GeomAdaptor_Curve::BSpline() const
{
if ( myTypeCurve != GeomAbs_BSplineCurve)
- Standard_NoSuchObject::Raise("GeomAdaptor_Curve::BSpline");
+ throw Standard_NoSuchObject("GeomAdaptor_Curve::BSpline");
- return *((Handle(Geom_BSplineCurve)*)&myCurve);
+ return myBSplineCurve;
}
+//=======================================================================
+//function : BasisCurve
+//purpose :
+//=======================================================================
+
+Handle(Geom_OffsetCurve) GeomAdaptor_Curve::OffsetCurve() const
+{
+ if ( myTypeCurve != GeomAbs_OffsetCurve)
+ throw Standard_NoSuchObject("GeomAdaptor_Curve::OffsetCurve");
+ return Handle(Geom_OffsetCurve)::DownCast(myCurve);
+}