From ac9acb4fb1f3e8711e9450bdceecd9cefcce3fe2 Mon Sep 17 00:00:00 2001 From: Pasukhin Dmitry Date: Thu, 13 Nov 2025 18:03:39 +0000 Subject: [PATCH] Foundation Classes - Migrate BSplCLib from deprecated gxx macros (#826) - Created BSplCLib_CurveComputation.pxx with template implementations for 2D/3D curve computation methods - Updated BSplCLib_1.cxx to use explicit template instantiation for 2D types (gp_Pnt2d, gp_Vec2d, TColgp_Array1OfPnt2d) - Updated BSplCLib_3.cxx to use explicit template instantiation for 3D types (gp_Pnt, gp_Vec, TColgp_Array1OfPnt) - Removed deprecated BSplCLib_CurveComputation.gxx file --- .../TKMath/BSplCLib/BSplCLib_1.cxx | 700 +++++- .../TKMath/BSplCLib/BSplCLib_2.cxx | 21 +- .../TKMath/BSplCLib/BSplCLib_3.cxx | 696 +++++- .../BSplCLib/BSplCLib_CurveComputation.gxx | 1483 ------------- .../BSplCLib/BSplCLib_CurveComputation.pxx | 1913 +++++++++++++++++ .../TKMath/BSplCLib/FILES.cmake | 2 +- 6 files changed, 3285 insertions(+), 1530 deletions(-) delete mode 100644 src/FoundationClasses/TKMath/BSplCLib/BSplCLib_CurveComputation.gxx create mode 100644 src/FoundationClasses/TKMath/BSplCLib/BSplCLib_CurveComputation.pxx diff --git a/src/FoundationClasses/TKMath/BSplCLib/BSplCLib_1.cxx b/src/FoundationClasses/TKMath/BSplCLib/BSplCLib_1.cxx index 925b4e607e..b03cb8eca3 100644 --- a/src/FoundationClasses/TKMath/BSplCLib/BSplCLib_1.cxx +++ b/src/FoundationClasses/TKMath/BSplCLib/BSplCLib_1.cxx @@ -13,29 +13,703 @@ // commercial license or contractual agreement. #include - +#include +#include #include + // BSpline Curve in 2d space // ************************** -#define Dimension_gen 2 +// Include the template implementation header +#include + +// Explicit template instantiations for 2D types +// This replaces the old macro-based approach with modern C++ templates + +//================================================================================================== + +void BSplCLib::Reverse(TColgp_Array1OfPnt2d& Poles, const Standard_Integer L) +{ + BSplCLib_Reverse(Poles, L); +} + +//================================================================================================== + +Standard_Boolean BSplCLib::RemoveKnot(const Standard_Integer Index, + const Standard_Integer Mult, + const Standard_Integer Degree, + const Standard_Boolean Periodic, + const TColgp_Array1OfPnt2d& Poles, + const TColStd_Array1OfReal* Weights, + const TColStd_Array1OfReal& Knots, + const TColStd_Array1OfInteger& Mults, + TColgp_Array1OfPnt2d& NewPoles, + TColStd_Array1OfReal* NewWeights, + TColStd_Array1OfReal& NewKnots, + TColStd_Array1OfInteger& NewMults, + const Standard_Real Tolerance) +{ + return BSplCLib_RemoveKnot(Index, + Mult, + Degree, + Periodic, + Poles, + Weights, + Knots, + Mults, + NewPoles, + NewWeights, + NewKnots, + NewMults, + Tolerance); +} + +//================================================================================================== + +void BSplCLib::InsertKnots(const Standard_Integer Degree, + const Standard_Boolean Periodic, + const TColgp_Array1OfPnt2d& Poles, + const TColStd_Array1OfReal* Weights, + const TColStd_Array1OfReal& Knots, + const TColStd_Array1OfInteger& Mults, + const TColStd_Array1OfReal& AddKnots, + const TColStd_Array1OfInteger* AddMults, + TColgp_Array1OfPnt2d& NewPoles, + TColStd_Array1OfReal* NewWeights, + TColStd_Array1OfReal& NewKnots, + TColStd_Array1OfInteger& NewMults, + const Standard_Real Epsilon, + const Standard_Boolean Add) +{ + BSplCLib_InsertKnots(Degree, + Periodic, + Poles, + Weights, + Knots, + Mults, + AddKnots, + AddMults, + NewPoles, + NewWeights, + NewKnots, + NewMults, + Epsilon, + Add); +} + +//================================================================================================== + +void BSplCLib::InsertKnot(const Standard_Integer, + const Standard_Real U, + const Standard_Integer UMult, + const Standard_Integer Degree, + const Standard_Boolean Periodic, + const TColgp_Array1OfPnt2d& Poles, + const TColStd_Array1OfReal* Weights, + const TColStd_Array1OfReal& Knots, + const TColStd_Array1OfInteger& Mults, + TColgp_Array1OfPnt2d& NewPoles, + TColStd_Array1OfReal* NewWeights) +{ + BSplCLib_InsertKnot(0, + U, + UMult, + Degree, + Periodic, + Poles, + Weights, + Knots, + Mults, + NewPoles, + NewWeights); +} + +//================================================================================================== + +void BSplCLib::RaiseMultiplicity(const Standard_Integer KnotIndex, + const Standard_Integer Mult, + const Standard_Integer Degree, + const Standard_Boolean Periodic, + const TColgp_Array1OfPnt2d& Poles, + const TColStd_Array1OfReal* Weights, + const TColStd_Array1OfReal& Knots, + const TColStd_Array1OfInteger& Mults, + TColgp_Array1OfPnt2d& NewPoles, + TColStd_Array1OfReal* NewWeights) +{ + BSplCLib_RaiseMultiplicity(KnotIndex, + Mult, + Degree, + Periodic, + Poles, + Weights, + Knots, + Mults, + NewPoles, + NewWeights); +} + +//================================================================================================== + +void BSplCLib::IncreaseDegree(const Standard_Integer Degree, + const Standard_Integer NewDegree, + const Standard_Boolean Periodic, + const TColgp_Array1OfPnt2d& Poles, + const TColStd_Array1OfReal* Weights, + const TColStd_Array1OfReal& Knots, + const TColStd_Array1OfInteger& Mults, + TColgp_Array1OfPnt2d& NewPoles, + TColStd_Array1OfReal* NewWeights, + TColStd_Array1OfReal& NewKnots, + TColStd_Array1OfInteger& NewMults) +{ + BSplCLib_IncreaseDegree(Degree, + NewDegree, + Periodic, + Poles, + Weights, + Knots, + Mults, + NewPoles, + NewWeights, + NewKnots, + NewMults); +} + +//================================================================================================== + +void BSplCLib::Unperiodize(const Standard_Integer Degree, + const TColStd_Array1OfInteger& Mults, + const TColStd_Array1OfReal& Knots, + const TColgp_Array1OfPnt2d& Poles, + const TColStd_Array1OfReal* Weights, + TColStd_Array1OfInteger& NewMults, + TColStd_Array1OfReal& NewKnots, + TColgp_Array1OfPnt2d& NewPoles, + TColStd_Array1OfReal* NewWeights) +{ + BSplCLib_Unperiodize(Degree, + Mults, + Knots, + Poles, + Weights, + NewMults, + NewKnots, + NewPoles, + NewWeights); +} + +//================================================================================================== + +void BSplCLib::Trimming(const Standard_Integer Degree, + const Standard_Boolean Periodic, + const TColStd_Array1OfReal& Knots, + const TColStd_Array1OfInteger& Mults, + const TColgp_Array1OfPnt2d& Poles, + const TColStd_Array1OfReal* Weights, + const Standard_Real U1, + const Standard_Real U2, + TColStd_Array1OfReal& NewKnots, + TColStd_Array1OfInteger& NewMults, + TColgp_Array1OfPnt2d& NewPoles, + TColStd_Array1OfReal* NewWeights) +{ + BSplCLib_Trimming(Degree, + Periodic, + Knots, + Mults, + Poles, + Weights, + U1, + U2, + NewKnots, + NewMults, + NewPoles, + NewWeights); +} + +//================================================================================================== + +void BSplCLib::BuildEval(const Standard_Integer Degree, + const Standard_Integer Index, + const TColgp_Array1OfPnt2d& Poles, + const TColStd_Array1OfReal* Weights, + Standard_Real& LP) +{ + BSplCLib_BuildEval(Degree, + Index, + Poles, + Weights, + LP); +} + +//================================================================================================== + +void BSplCLib::D0(const Standard_Real U, + const Standard_Integer Index, + const Standard_Integer Degree, + const Standard_Boolean Periodic, + const TColgp_Array1OfPnt2d& Poles, + const TColStd_Array1OfReal* Weights, + const TColStd_Array1OfReal& Knots, + const TColStd_Array1OfInteger* Mults, + gp_Pnt2d& P) +{ + BSplCLib_D0(U, + Index, + Degree, + Periodic, + Poles, + Weights, + Knots, + Mults, + P); +} + +//================================================================================================== + +void BSplCLib::D1(const Standard_Real U, + const Standard_Integer Index, + const Standard_Integer Degree, + const Standard_Boolean Periodic, + const TColgp_Array1OfPnt2d& Poles, + const TColStd_Array1OfReal* Weights, + const TColStd_Array1OfReal& Knots, + const TColStd_Array1OfInteger* Mults, + gp_Pnt2d& P, + gp_Vec2d& V) +{ + BSplCLib_D1(U, + Index, + Degree, + Periodic, + Poles, + Weights, + Knots, + Mults, + P, + V); +} + +//================================================================================================== + +void BSplCLib::D2(const Standard_Real U, + const Standard_Integer Index, + const Standard_Integer Degree, + const Standard_Boolean Periodic, + const TColgp_Array1OfPnt2d& Poles, + const TColStd_Array1OfReal* Weights, + const TColStd_Array1OfReal& Knots, + const TColStd_Array1OfInteger* Mults, + gp_Pnt2d& P, + gp_Vec2d& V1, + gp_Vec2d& V2) +{ + BSplCLib_D2(U, + Index, + Degree, + Periodic, + Poles, + Weights, + Knots, + Mults, + P, + V1, + V2); +} + +//================================================================================================== + +void BSplCLib::D3(const Standard_Real U, + const Standard_Integer Index, + const Standard_Integer Degree, + const Standard_Boolean Periodic, + const TColgp_Array1OfPnt2d& Poles, + const TColStd_Array1OfReal* Weights, + const TColStd_Array1OfReal& Knots, + const TColStd_Array1OfInteger* Mults, + gp_Pnt2d& P, + gp_Vec2d& V1, + gp_Vec2d& V2, + gp_Vec2d& V3) +{ + BSplCLib_D3(U, + Index, + Degree, + Periodic, + Poles, + Weights, + Knots, + Mults, + P, + V1, + V2, + V3); +} + +//================================================================================================== + +void BSplCLib::DN(const Standard_Real U, + const Standard_Integer N, + const Standard_Integer Index, + const Standard_Integer Degree, + const Standard_Boolean Periodic, + const TColgp_Array1OfPnt2d& Poles, + const TColStd_Array1OfReal* Weights, + const TColStd_Array1OfReal& Knots, + const TColStd_Array1OfInteger* Mults, + gp_Vec2d& VN) +{ + BSplCLib_DN(U, + N, + Index, + Degree, + Periodic, + Poles, + Weights, + Knots, + Mults, + VN); +} + +//================================================================================================== + +Standard_Integer BSplCLib::SolveBandedSystem(const math_Matrix& Matrix, + const Standard_Integer UpperBandWidth, + const Standard_Integer LowerBandWidth, + TColgp_Array1OfPnt2d& PolesArray) +{ + return BSplCLib_SolveBandedSystem(Matrix, + UpperBandWidth, + LowerBandWidth, + PolesArray); +} + +//================================================================================================== + +Standard_Integer BSplCLib::SolveBandedSystem(const math_Matrix& Matrix, + const Standard_Integer UpperBandWidth, + const Standard_Integer LowerBandWidth, + const Standard_Boolean HomogeneousFlag, + TColgp_Array1OfPnt2d& PolesArray, + TColStd_Array1OfReal& WeightsArray) +{ + return BSplCLib_SolveBandedSystem(Matrix, + UpperBandWidth, + LowerBandWidth, + HomogeneousFlag, + PolesArray, + WeightsArray); +} + +//================================================================================================== + +void BSplCLib::Eval(const Standard_Real Parameter, + const Standard_Boolean PeriodicFlag, + const Standard_Boolean HomogeneousFlag, + Standard_Integer& ExtrapMode, + const Standard_Integer Degree, + const TColStd_Array1OfReal& FlatKnots, + const TColgp_Array1OfPnt2d& PolesArray, + const TColStd_Array1OfReal& WeightsArray, + gp_Pnt2d& aPoint, + Standard_Real& aWeight) +{ + BSplCLib_Eval(Parameter, + PeriodicFlag, + HomogeneousFlag, + ExtrapMode, + Degree, + FlatKnots, + PolesArray, + WeightsArray, + aPoint, + aWeight); +} + +//================================================================================================== + +void BSplCLib::CacheD0(const Standard_Real Parameter, + const Standard_Integer Degree, + const Standard_Real CacheParameter, + const Standard_Real SpanLenght, + const TColgp_Array1OfPnt2d& PolesArray, + const TColStd_Array1OfReal* WeightsArray, + gp_Pnt2d& aPoint) +{ + BSplCLib_CacheD0(Parameter, + Degree, + CacheParameter, + SpanLenght, + PolesArray, + WeightsArray, + aPoint); +} + +//================================================================================================== + +void BSplCLib::CacheD1(const Standard_Real Parameter, + const Standard_Integer Degree, + const Standard_Real CacheParameter, + const Standard_Real SpanLenght, + const TColgp_Array1OfPnt2d& PolesArray, + const TColStd_Array1OfReal* WeightsArray, + gp_Pnt2d& aPoint, + gp_Vec2d& aVector) +{ + BSplCLib_CacheD1(Parameter, + Degree, + CacheParameter, + SpanLenght, + PolesArray, + WeightsArray, + aPoint, + aVector); +} + +//================================================================================================== + +void BSplCLib::CacheD2(const Standard_Real Parameter, + const Standard_Integer Degree, + const Standard_Real CacheParameter, + const Standard_Real SpanLenght, + const TColgp_Array1OfPnt2d& PolesArray, + const TColStd_Array1OfReal* WeightsArray, + gp_Pnt2d& aPoint, + gp_Vec2d& aVector1, + gp_Vec2d& aVector2) +{ + BSplCLib_CacheD2(Parameter, + Degree, + CacheParameter, + SpanLenght, + PolesArray, + WeightsArray, + aPoint, + aVector1, + aVector2); +} + +//================================================================================================== + +void BSplCLib::CacheD3(const Standard_Real Parameter, + const Standard_Integer Degree, + const Standard_Real CacheParameter, + const Standard_Real SpanLenght, + const TColgp_Array1OfPnt2d& PolesArray, + const TColStd_Array1OfReal* WeightsArray, + gp_Pnt2d& aPoint, + gp_Vec2d& aVector1, + gp_Vec2d& aVector2, + gp_Vec2d& aVector3) +{ + BSplCLib_CacheD3(Parameter, + Degree, + CacheParameter, + SpanLenght, + PolesArray, + WeightsArray, + aPoint, + aVector1, + aVector2, + aVector3); +} + +//================================================================================================== + +void BSplCLib::BuildCache(const Standard_Real U, + const Standard_Real SpanDomain, + const Standard_Boolean Periodic, + const Standard_Integer Degree, + const TColStd_Array1OfReal& FlatKnots, + const TColgp_Array1OfPnt2d& Poles, + const TColStd_Array1OfReal* Weights, + TColgp_Array1OfPnt2d& CachePoles, + TColStd_Array1OfReal* CacheWeights) +{ + BSplCLib_BuildCache(U, + SpanDomain, + Periodic, + Degree, + FlatKnots, + Poles, + Weights, + CachePoles, + CacheWeights); +} + +//================================================================================================== + +void BSplCLib::BuildCache(const Standard_Real theParameter, + const Standard_Real theSpanDomain, + const Standard_Boolean thePeriodicFlag, + const Standard_Integer theDegree, + const Standard_Integer theSpanIndex, + const TColStd_Array1OfReal& theFlatKnots, + const TColgp_Array1OfPnt2d& thePoles, + const TColStd_Array1OfReal* theWeights, + TColStd_Array2OfReal& theCacheArray) +{ + BSplCLib_BuildCache(theParameter, + theSpanDomain, + thePeriodicFlag, + theDegree, + theSpanIndex, + theFlatKnots, + thePoles, + theWeights, + theCacheArray); +} + +//================================================================================================== + +void BSplCLib::Interpolate(const Standard_Integer Degree, + const TColStd_Array1OfReal& FlatKnots, + const TColStd_Array1OfReal& Parameters, + const TColStd_Array1OfInteger& ContactOrderArray, + TColgp_Array1OfPnt2d& Poles, + Standard_Integer& InversionProblem) +{ + BSplCLib_Interpolate(Degree, + FlatKnots, + Parameters, + ContactOrderArray, + Poles, + InversionProblem); +} + +//================================================================================================== + +void BSplCLib::Interpolate(const Standard_Integer Degree, + const TColStd_Array1OfReal& FlatKnots, + const TColStd_Array1OfReal& Parameters, + const TColStd_Array1OfInteger& ContactOrderArray, + TColgp_Array1OfPnt2d& Poles, + TColStd_Array1OfReal& Weights, + Standard_Integer& InversionProblem) +{ + BSplCLib_Interpolate(Degree, + FlatKnots, + Parameters, + ContactOrderArray, + Poles, + Weights, + InversionProblem); +} + +//================================================================================================== -#define Array1OfPoints TColgp_Array1OfPnt2d -#define Point gp_Pnt2d -#define Vector gp_Vec2d +void BSplCLib::MovePoint(const Standard_Real U, + const gp_Vec2d& Displ, + const Standard_Integer Index1, + const Standard_Integer Index2, + const Standard_Integer Degree, + const TColgp_Array1OfPnt2d& Poles, + const TColStd_Array1OfReal* Weights, + const TColStd_Array1OfReal& FlatKnots, + Standard_Integer& FirstIndex, + Standard_Integer& LastIndex, + TColgp_Array1OfPnt2d& NewPoles) +{ + BSplCLib_MovePoint(U, + Displ, + Index1, + Index2, + Degree, + Poles, + Weights, + FlatKnots, + FirstIndex, + LastIndex, + NewPoles); +} -#define PointToCoords(carr, pnt, op) (carr)[0] = (pnt).X() op, (carr)[1] = (pnt).Y() op +//================================================================================================== -#define CoordsToPoint(pnt, carr, op) (pnt).SetX((carr)[0] op), (pnt).SetY((carr)[1] op) +void BSplCLib::MovePointAndTangent(const Standard_Real U, + const gp_Vec2d& Delta, + const gp_Vec2d& DeltaDerivatives, + const Standard_Real Tolerance, + const Standard_Integer Degree, + const Standard_Integer StartingCondition, + const Standard_Integer EndingCondition, + const TColgp_Array1OfPnt2d& Poles, + const TColStd_Array1OfReal* Weights, + const TColStd_Array1OfReal& FlatKnots, + TColgp_Array1OfPnt2d& NewPoles, + Standard_Integer& ErrorStatus) +{ + BSplCLib_MovePointAndTangent(U, + Delta, + DeltaDerivatives, + Tolerance, + Degree, + StartingCondition, + EndingCondition, + Poles, + Weights, + FlatKnots, + NewPoles, + ErrorStatus); +} -#define NullifyPoint(pnt) (pnt).SetCoord(0., 0.) +//================================================================================================== -#define NullifyCoords(carr) (carr)[0] = (carr)[1] = 0. +void BSplCLib::Resolution(const TColgp_Array1OfPnt2d& Poles, + const TColStd_Array1OfReal* Weights, + const Standard_Integer NumPoles, + const TColStd_Array1OfReal& FlatKnots, + const Standard_Integer Degree, + const Standard_Real Tolerance3D, + Standard_Real& UTolerance) +{ + BSplCLib_Resolution(Poles, + Weights, + NumPoles, + FlatKnots, + Degree, + Tolerance3D, + UTolerance); +} -#define ModifyCoords(carr, op) (carr)[0] op, (carr)[1] op +//================================================================================================== -#define CopyCoords(carr, carr2) (carr)[0] = (carr2)[0], (carr)[1] = (carr2)[1] +void BSplCLib::FunctionMultiply(const BSplCLib_EvaluatorFunction& FunctionPtr, + const Standard_Integer BSplineDegree, + const TColStd_Array1OfReal& BSplineFlatKnots, + const TColgp_Array1OfPnt2d& Poles, + const TColStd_Array1OfReal& FlatKnots, + const Standard_Integer NewDegree, + TColgp_Array1OfPnt2d& NewPoles, + Standard_Integer& theStatus) +{ + BSplCLib_FunctionMultiply(FunctionPtr, + BSplineDegree, + BSplineFlatKnots, + Poles, + FlatKnots, + NewDegree, + NewPoles, + theStatus); +} -#define BSplCLib_DataContainer BSplCLib_DataContainer_2d +//================================================================================================== -#include +void BSplCLib::FunctionReparameterise(const BSplCLib_EvaluatorFunction& FunctionPtr, + const Standard_Integer BSplineDegree, + const TColStd_Array1OfReal& BSplineFlatKnots, + const TColgp_Array1OfPnt2d& Poles, + const TColStd_Array1OfReal& FlatKnots, + const Standard_Integer NewDegree, + TColgp_Array1OfPnt2d& NewPoles, + Standard_Integer& theStatus) +{ + BSplCLib_FunctionReparameterise(FunctionPtr, + BSplineDegree, + BSplineFlatKnots, + Poles, + FlatKnots, + NewDegree, + NewPoles, + theStatus); +} diff --git a/src/FoundationClasses/TKMath/BSplCLib/BSplCLib_2.cxx b/src/FoundationClasses/TKMath/BSplCLib/BSplCLib_2.cxx index 4cb55cf1c0..417b275b62 100644 --- a/src/FoundationClasses/TKMath/BSplCLib/BSplCLib_2.cxx +++ b/src/FoundationClasses/TKMath/BSplCLib/BSplCLib_2.cxx @@ -31,25 +31,10 @@ #include -//======================================================================= -// struct : BSplCLib_DataContainer -// purpose: Auxiliary structure providing buffers for poles and knots used in -// evaluation of bspline (allocated in the stack) -//======================================================================= - -struct BSplCLib_DataContainer -{ - BSplCLib_DataContainer(Standard_Integer Degree) - { - (void)Degree; // avoid compiler warning - Standard_OutOfRange_Raise_if(Degree > BSplCLib::MaxDegree(), - "BSplCLib: bspline degree is greater than maximum supported"); - } +#include "BSplCLib_CurveComputation.pxx" - Standard_Real poles[2 * (25 + 1)]{}; - Standard_Real knots[2 * 25]{}; - Standard_Real ders[4]{}; -}; +// Use 1D specialization of the template data container +using BSplCLib_DataContainer = BSplCLib_DataContainer_T<1>; // methods for 1 dimensional BSplines diff --git a/src/FoundationClasses/TKMath/BSplCLib/BSplCLib_3.cxx b/src/FoundationClasses/TKMath/BSplCLib/BSplCLib_3.cxx index 5888bd4a32..2fbcd690a5 100644 --- a/src/FoundationClasses/TKMath/BSplCLib/BSplCLib_3.cxx +++ b/src/FoundationClasses/TKMath/BSplCLib/BSplCLib_3.cxx @@ -24,27 +24,693 @@ // BSpline Curve in 3d space // *************************** -#define Dimension_gen 3 -#define Array1OfPoints TColgp_Array1OfPnt -#define Point gp_Pnt -#define Vector gp_Vec +// Include the template implementation header +#include -#define PointToCoords(carr, pnt, op) \ - (carr)[0] = (pnt).X() op, (carr)[1] = (pnt).Y() op, (carr)[2] = (pnt).Z() op +// Explicit template instantiations for 3D types +// This replaces the old macro-based approach with modern C++ templates -#define CoordsToPoint(pnt, carr, op) \ - (pnt).SetX((carr)[0] op), (pnt).SetY((carr)[1] op), (pnt).SetZ((carr)[2] op) +//================================================================================================== -#define NullifyPoint(pnt) (pnt).SetCoord(0., 0., 0.) +void BSplCLib::Reverse(TColgp_Array1OfPnt& Poles, const Standard_Integer L) +{ + BSplCLib_Reverse(Poles, L); +} -#define NullifyCoords(carr) (carr)[0] = (carr)[1] = (carr)[2] = 0. +//================================================================================================== -#define ModifyCoords(carr, op) (carr)[0] op, (carr)[1] op, (carr)[2] op +Standard_Boolean BSplCLib::RemoveKnot(const Standard_Integer Index, + const Standard_Integer Mult, + const Standard_Integer Degree, + const Standard_Boolean Periodic, + const TColgp_Array1OfPnt& Poles, + const TColStd_Array1OfReal* Weights, + const TColStd_Array1OfReal& Knots, + const TColStd_Array1OfInteger& Mults, + TColgp_Array1OfPnt& NewPoles, + TColStd_Array1OfReal* NewWeights, + TColStd_Array1OfReal& NewKnots, + TColStd_Array1OfInteger& NewMults, + const Standard_Real Tolerance) +{ + return BSplCLib_RemoveKnot(Index, + Mult, + Degree, + Periodic, + Poles, + Weights, + Knots, + Mults, + NewPoles, + NewWeights, + NewKnots, + NewMults, + Tolerance); +} -#define CopyCoords(carr, carr2) \ - (carr)[0] = (carr2)[0], (carr)[1] = (carr2)[1], (carr)[2] = (carr2)[2] +//================================================================================================== -#define BSplCLib_DataContainer BSplCLib_DataContainer_3d +void BSplCLib::InsertKnots(const Standard_Integer Degree, + const Standard_Boolean Periodic, + const TColgp_Array1OfPnt& Poles, + const TColStd_Array1OfReal* Weights, + const TColStd_Array1OfReal& Knots, + const TColStd_Array1OfInteger& Mults, + const TColStd_Array1OfReal& AddKnots, + const TColStd_Array1OfInteger* AddMults, + TColgp_Array1OfPnt& NewPoles, + TColStd_Array1OfReal* NewWeights, + TColStd_Array1OfReal& NewKnots, + TColStd_Array1OfInteger& NewMults, + const Standard_Real Epsilon, + const Standard_Boolean Add) +{ + BSplCLib_InsertKnots(Degree, + Periodic, + Poles, + Weights, + Knots, + Mults, + AddKnots, + AddMults, + NewPoles, + NewWeights, + NewKnots, + NewMults, + Epsilon, + Add); +} -#include +//================================================================================================== + +void BSplCLib::InsertKnot(const Standard_Integer, + const Standard_Real U, + const Standard_Integer UMult, + const Standard_Integer Degree, + const Standard_Boolean Periodic, + const TColgp_Array1OfPnt& Poles, + const TColStd_Array1OfReal* Weights, + const TColStd_Array1OfReal& Knots, + const TColStd_Array1OfInteger& Mults, + TColgp_Array1OfPnt& NewPoles, + TColStd_Array1OfReal* NewWeights) +{ + BSplCLib_InsertKnot(0, + U, + UMult, + Degree, + Periodic, + Poles, + Weights, + Knots, + Mults, + NewPoles, + NewWeights); +} + +//================================================================================================== + +void BSplCLib::RaiseMultiplicity(const Standard_Integer KnotIndex, + const Standard_Integer Mult, + const Standard_Integer Degree, + const Standard_Boolean Periodic, + const TColgp_Array1OfPnt& Poles, + const TColStd_Array1OfReal* Weights, + const TColStd_Array1OfReal& Knots, + const TColStd_Array1OfInteger& Mults, + TColgp_Array1OfPnt& NewPoles, + TColStd_Array1OfReal* NewWeights) +{ + BSplCLib_RaiseMultiplicity(KnotIndex, + Mult, + Degree, + Periodic, + Poles, + Weights, + Knots, + Mults, + NewPoles, + NewWeights); +} + +//================================================================================================== + +void BSplCLib::IncreaseDegree(const Standard_Integer Degree, + const Standard_Integer NewDegree, + const Standard_Boolean Periodic, + const TColgp_Array1OfPnt& Poles, + const TColStd_Array1OfReal* Weights, + const TColStd_Array1OfReal& Knots, + const TColStd_Array1OfInteger& Mults, + TColgp_Array1OfPnt& NewPoles, + TColStd_Array1OfReal* NewWeights, + TColStd_Array1OfReal& NewKnots, + TColStd_Array1OfInteger& NewMults) +{ + BSplCLib_IncreaseDegree(Degree, + NewDegree, + Periodic, + Poles, + Weights, + Knots, + Mults, + NewPoles, + NewWeights, + NewKnots, + NewMults); +} + +//================================================================================================== + +void BSplCLib::Unperiodize(const Standard_Integer Degree, + const TColStd_Array1OfInteger& Mults, + const TColStd_Array1OfReal& Knots, + const TColgp_Array1OfPnt& Poles, + const TColStd_Array1OfReal* Weights, + TColStd_Array1OfInteger& NewMults, + TColStd_Array1OfReal& NewKnots, + TColgp_Array1OfPnt& NewPoles, + TColStd_Array1OfReal* NewWeights) +{ + BSplCLib_Unperiodize(Degree, + Mults, + Knots, + Poles, + Weights, + NewMults, + NewKnots, + NewPoles, + NewWeights); +} + +//================================================================================================== + +void BSplCLib::Trimming(const Standard_Integer Degree, + const Standard_Boolean Periodic, + const TColStd_Array1OfReal& Knots, + const TColStd_Array1OfInteger& Mults, + const TColgp_Array1OfPnt& Poles, + const TColStd_Array1OfReal* Weights, + const Standard_Real U1, + const Standard_Real U2, + TColStd_Array1OfReal& NewKnots, + TColStd_Array1OfInteger& NewMults, + TColgp_Array1OfPnt& NewPoles, + TColStd_Array1OfReal* NewWeights) +{ + BSplCLib_Trimming(Degree, + Periodic, + Knots, + Mults, + Poles, + Weights, + U1, + U2, + NewKnots, + NewMults, + NewPoles, + NewWeights); +} + +//================================================================================================== + +void BSplCLib::BuildEval(const Standard_Integer Degree, + const Standard_Integer Index, + const TColgp_Array1OfPnt& Poles, + const TColStd_Array1OfReal* Weights, + Standard_Real& LP) +{ + BSplCLib_BuildEval(Degree, Index, Poles, Weights, LP); +} + +//================================================================================================== + +void BSplCLib::D0(const Standard_Real U, + const Standard_Integer Index, + const Standard_Integer Degree, + const Standard_Boolean Periodic, + const TColgp_Array1OfPnt& Poles, + const TColStd_Array1OfReal* Weights, + const TColStd_Array1OfReal& Knots, + const TColStd_Array1OfInteger* Mults, + gp_Pnt& P) +{ + BSplCLib_D0(U, + Index, + Degree, + Periodic, + Poles, + Weights, + Knots, + Mults, + P); +} + +//================================================================================================== + +void BSplCLib::D1(const Standard_Real U, + const Standard_Integer Index, + const Standard_Integer Degree, + const Standard_Boolean Periodic, + const TColgp_Array1OfPnt& Poles, + const TColStd_Array1OfReal* Weights, + const TColStd_Array1OfReal& Knots, + const TColStd_Array1OfInteger* Mults, + gp_Pnt& P, + gp_Vec& V) +{ + BSplCLib_D1(U, + Index, + Degree, + Periodic, + Poles, + Weights, + Knots, + Mults, + P, + V); +} + +//================================================================================================== + +void BSplCLib::D2(const Standard_Real U, + const Standard_Integer Index, + const Standard_Integer Degree, + const Standard_Boolean Periodic, + const TColgp_Array1OfPnt& Poles, + const TColStd_Array1OfReal* Weights, + const TColStd_Array1OfReal& Knots, + const TColStd_Array1OfInteger* Mults, + gp_Pnt& P, + gp_Vec& V1, + gp_Vec& V2) +{ + BSplCLib_D2(U, + Index, + Degree, + Periodic, + Poles, + Weights, + Knots, + Mults, + P, + V1, + V2); +} + +//================================================================================================== + +void BSplCLib::D3(const Standard_Real U, + const Standard_Integer Index, + const Standard_Integer Degree, + const Standard_Boolean Periodic, + const TColgp_Array1OfPnt& Poles, + const TColStd_Array1OfReal* Weights, + const TColStd_Array1OfReal& Knots, + const TColStd_Array1OfInteger* Mults, + gp_Pnt& P, + gp_Vec& V1, + gp_Vec& V2, + gp_Vec& V3) +{ + BSplCLib_D3(U, + Index, + Degree, + Periodic, + Poles, + Weights, + Knots, + Mults, + P, + V1, + V2, + V3); +} + +//================================================================================================== + +void BSplCLib::DN(const Standard_Real U, + const Standard_Integer N, + const Standard_Integer Index, + const Standard_Integer Degree, + const Standard_Boolean Periodic, + const TColgp_Array1OfPnt& Poles, + const TColStd_Array1OfReal* Weights, + const TColStd_Array1OfReal& Knots, + const TColStd_Array1OfInteger* Mults, + gp_Vec& VN) +{ + BSplCLib_DN(U, + N, + Index, + Degree, + Periodic, + Poles, + Weights, + Knots, + Mults, + VN); +} + +//================================================================================================== + +Standard_Integer BSplCLib::SolveBandedSystem(const math_Matrix& Matrix, + const Standard_Integer UpperBandWidth, + const Standard_Integer LowerBandWidth, + TColgp_Array1OfPnt& PolesArray) +{ + return BSplCLib_SolveBandedSystem(Matrix, + UpperBandWidth, + LowerBandWidth, + PolesArray); +} + +//================================================================================================== + +Standard_Integer BSplCLib::SolveBandedSystem(const math_Matrix& Matrix, + const Standard_Integer UpperBandWidth, + const Standard_Integer LowerBandWidth, + const Standard_Boolean HomogeneousFlag, + TColgp_Array1OfPnt& PolesArray, + TColStd_Array1OfReal& WeightsArray) +{ + return BSplCLib_SolveBandedSystem(Matrix, + UpperBandWidth, + LowerBandWidth, + HomogeneousFlag, + PolesArray, + WeightsArray); +} + +//================================================================================================== + +void BSplCLib::Eval(const Standard_Real Parameter, + const Standard_Boolean PeriodicFlag, + const Standard_Boolean HomogeneousFlag, + Standard_Integer& ExtrapMode, + const Standard_Integer Degree, + const TColStd_Array1OfReal& FlatKnots, + const TColgp_Array1OfPnt& PolesArray, + const TColStd_Array1OfReal& WeightsArray, + gp_Pnt& aPoint, + Standard_Real& aWeight) +{ + BSplCLib_Eval(Parameter, + PeriodicFlag, + HomogeneousFlag, + ExtrapMode, + Degree, + FlatKnots, + PolesArray, + WeightsArray, + aPoint, + aWeight); +} + +//================================================================================================== + +void BSplCLib::CacheD0(const Standard_Real Parameter, + const Standard_Integer Degree, + const Standard_Real CacheParameter, + const Standard_Real SpanLenght, + const TColgp_Array1OfPnt& PolesArray, + const TColStd_Array1OfReal* WeightsArray, + gp_Pnt& aPoint) +{ + BSplCLib_CacheD0(Parameter, + Degree, + CacheParameter, + SpanLenght, + PolesArray, + WeightsArray, + aPoint); +} + +//================================================================================================== + +void BSplCLib::CacheD1(const Standard_Real Parameter, + const Standard_Integer Degree, + const Standard_Real CacheParameter, + const Standard_Real SpanLenght, + const TColgp_Array1OfPnt& PolesArray, + const TColStd_Array1OfReal* WeightsArray, + gp_Pnt& aPoint, + gp_Vec& aVector) +{ + BSplCLib_CacheD1(Parameter, + Degree, + CacheParameter, + SpanLenght, + PolesArray, + WeightsArray, + aPoint, + aVector); +} + +//================================================================================================== + +void BSplCLib::CacheD2(const Standard_Real Parameter, + const Standard_Integer Degree, + const Standard_Real CacheParameter, + const Standard_Real SpanLenght, + const TColgp_Array1OfPnt& PolesArray, + const TColStd_Array1OfReal* WeightsArray, + gp_Pnt& aPoint, + gp_Vec& aVector1, + gp_Vec& aVector2) +{ + BSplCLib_CacheD2(Parameter, + Degree, + CacheParameter, + SpanLenght, + PolesArray, + WeightsArray, + aPoint, + aVector1, + aVector2); +} + +//================================================================================================== + +void BSplCLib::CacheD3(const Standard_Real Parameter, + const Standard_Integer Degree, + const Standard_Real CacheParameter, + const Standard_Real SpanLenght, + const TColgp_Array1OfPnt& PolesArray, + const TColStd_Array1OfReal* WeightsArray, + gp_Pnt& aPoint, + gp_Vec& aVector1, + gp_Vec& aVector2, + gp_Vec& aVector3) +{ + BSplCLib_CacheD3(Parameter, + Degree, + CacheParameter, + SpanLenght, + PolesArray, + WeightsArray, + aPoint, + aVector1, + aVector2, + aVector3); +} + +//================================================================================================== + +void BSplCLib::BuildCache(const Standard_Real U, + const Standard_Real SpanDomain, + const Standard_Boolean Periodic, + const Standard_Integer Degree, + const TColStd_Array1OfReal& FlatKnots, + const TColgp_Array1OfPnt& Poles, + const TColStd_Array1OfReal* Weights, + TColgp_Array1OfPnt& CachePoles, + TColStd_Array1OfReal* CacheWeights) +{ + BSplCLib_BuildCache(U, + SpanDomain, + Periodic, + Degree, + FlatKnots, + Poles, + Weights, + CachePoles, + CacheWeights); +} + +//================================================================================================== + +void BSplCLib::BuildCache(const Standard_Real theParameter, + const Standard_Real theSpanDomain, + const Standard_Boolean thePeriodicFlag, + const Standard_Integer theDegree, + const Standard_Integer theSpanIndex, + const TColStd_Array1OfReal& theFlatKnots, + const TColgp_Array1OfPnt& thePoles, + const TColStd_Array1OfReal* theWeights, + TColStd_Array2OfReal& theCacheArray) +{ + BSplCLib_BuildCache(theParameter, + theSpanDomain, + thePeriodicFlag, + theDegree, + theSpanIndex, + theFlatKnots, + thePoles, + theWeights, + theCacheArray); +} + +//================================================================================================== + +void BSplCLib::Interpolate(const Standard_Integer Degree, + const TColStd_Array1OfReal& FlatKnots, + const TColStd_Array1OfReal& Parameters, + const TColStd_Array1OfInteger& ContactOrderArray, + TColgp_Array1OfPnt& Poles, + Standard_Integer& InversionProblem) +{ + BSplCLib_Interpolate(Degree, + FlatKnots, + Parameters, + ContactOrderArray, + Poles, + InversionProblem); +} + +//================================================================================================== + +void BSplCLib::Interpolate(const Standard_Integer Degree, + const TColStd_Array1OfReal& FlatKnots, + const TColStd_Array1OfReal& Parameters, + const TColStd_Array1OfInteger& ContactOrderArray, + TColgp_Array1OfPnt& Poles, + TColStd_Array1OfReal& Weights, + Standard_Integer& InversionProblem) +{ + BSplCLib_Interpolate(Degree, + FlatKnots, + Parameters, + ContactOrderArray, + Poles, + Weights, + InversionProblem); +} + +//================================================================================================== + +void BSplCLib::MovePoint(const Standard_Real U, + const gp_Vec& Displ, + const Standard_Integer Index1, + const Standard_Integer Index2, + const Standard_Integer Degree, + const TColgp_Array1OfPnt& Poles, + const TColStd_Array1OfReal* Weights, + const TColStd_Array1OfReal& FlatKnots, + Standard_Integer& FirstIndex, + Standard_Integer& LastIndex, + TColgp_Array1OfPnt& NewPoles) +{ + BSplCLib_MovePoint(U, + Displ, + Index1, + Index2, + Degree, + Poles, + Weights, + FlatKnots, + FirstIndex, + LastIndex, + NewPoles); +} + +//================================================================================================== + +void BSplCLib::MovePointAndTangent(const Standard_Real U, + const gp_Vec& Delta, + const gp_Vec& DeltaDerivatives, + const Standard_Real Tolerance, + const Standard_Integer Degree, + const Standard_Integer StartingCondition, + const Standard_Integer EndingCondition, + const TColgp_Array1OfPnt& Poles, + const TColStd_Array1OfReal* Weights, + const TColStd_Array1OfReal& FlatKnots, + TColgp_Array1OfPnt& NewPoles, + Standard_Integer& ErrorStatus) +{ + BSplCLib_MovePointAndTangent(U, + Delta, + DeltaDerivatives, + Tolerance, + Degree, + StartingCondition, + EndingCondition, + Poles, + Weights, + FlatKnots, + NewPoles, + ErrorStatus); +} + +//================================================================================================== + +void BSplCLib::Resolution(const TColgp_Array1OfPnt& Poles, + const TColStd_Array1OfReal* Weights, + const Standard_Integer NumPoles, + const TColStd_Array1OfReal& FlatKnots, + const Standard_Integer Degree, + const Standard_Real Tolerance3D, + Standard_Real& UTolerance) +{ + BSplCLib_Resolution(Poles, + Weights, + NumPoles, + FlatKnots, + Degree, + Tolerance3D, + UTolerance); +} + +//================================================================================================== + +void BSplCLib::FunctionMultiply(const BSplCLib_EvaluatorFunction& FunctionPtr, + const Standard_Integer BSplineDegree, + const TColStd_Array1OfReal& BSplineFlatKnots, + const TColgp_Array1OfPnt& Poles, + const TColStd_Array1OfReal& FlatKnots, + const Standard_Integer NewDegree, + TColgp_Array1OfPnt& NewPoles, + Standard_Integer& theStatus) +{ + BSplCLib_FunctionMultiply(FunctionPtr, + BSplineDegree, + BSplineFlatKnots, + Poles, + FlatKnots, + NewDegree, + NewPoles, + theStatus); +} + +//================================================================================================== + +void BSplCLib::FunctionReparameterise(const BSplCLib_EvaluatorFunction& FunctionPtr, + const Standard_Integer BSplineDegree, + const TColStd_Array1OfReal& BSplineFlatKnots, + const TColgp_Array1OfPnt& Poles, + const TColStd_Array1OfReal& FlatKnots, + const Standard_Integer NewDegree, + TColgp_Array1OfPnt& NewPoles, + Standard_Integer& theStatus) +{ + BSplCLib_FunctionReparameterise(FunctionPtr, + BSplineDegree, + BSplineFlatKnots, + Poles, + FlatKnots, + NewDegree, + NewPoles, + theStatus); +} diff --git a/src/FoundationClasses/TKMath/BSplCLib/BSplCLib_CurveComputation.gxx b/src/FoundationClasses/TKMath/BSplCLib/BSplCLib_CurveComputation.gxx deleted file mode 100644 index 874b17461f..0000000000 --- a/src/FoundationClasses/TKMath/BSplCLib/BSplCLib_CurveComputation.gxx +++ /dev/null @@ -1,1483 +0,0 @@ -// Copyright (c) 1995-1999 Matra Datavision -// Copyright (c) 1999-2014 OPEN CASCADE SAS -// -// This file is part of Open CASCADE Technology software library. -// -// 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. -// -// Alternatively, this file may be used under the terms of Open CASCADE -// commercial license or contractual agreement. - -// xab : modified 15-Mar-94 added EvalBSplineMatrix, FactorBandedMatrix, SolveBandedSystem -// Eval, BuildCache, cacheD0, cacheD1, cacheD2, cacheD3, LocalMatrix, -// EvalPolynomial, RationalDerivatives. -// xab : 22-Mar-94 : fixed rational problem in BuildCache -// xab : 12-Mar-96 : added MovePointAndTangent -#include -#include -#include -#include -#include -#include -#include - -//======================================================================= -// struct : BSplCLib_DataContainer -// purpose: Auxiliary structure providing buffers for poles and knots used in -// evaluation of bspline (allocated in the stack) -//======================================================================= - -struct BSplCLib_DataContainer -{ - BSplCLib_DataContainer(Standard_Integer Degree) - { - (void)Degree; // avoid compiler warning - Standard_OutOfRange_Raise_if(Degree > BSplCLib::MaxDegree() || BSplCLib::MaxDegree() > 25, - "BSplCLib: bspline degree is greater than maximum supported"); - } - - Standard_Real poles[(25 + 1) * (Dimension_gen + 1)]; - Standard_Real knots[2 * 25]; - Standard_Real ders[Dimension_gen * 4]; -}; - -//================================================================================================= - -void BSplCLib::Reverse(Array1OfPoints& Poles, const Standard_Integer L) -{ - Standard_Integer i, l = L; - l = Poles.Lower() + (l - Poles.Lower()) % (Poles.Upper() - Poles.Lower() + 1); - - Array1OfPoints temp(0, Poles.Length() - 1); - - for (i = Poles.Lower(); i <= l; i++) - temp(l - i) = Poles(i); - - for (i = l + 1; i <= Poles.Upper(); i++) - temp(l - Poles.Lower() + Poles.Upper() - i + 1) = Poles(i); - - for (i = Poles.Lower(); i <= Poles.Upper(); i++) - Poles(i) = temp(i - Poles.Lower()); -} - -// -// CURVES MODIFICATIONS -// - -//================================================================================================= - -Standard_Boolean BSplCLib::RemoveKnot(const Standard_Integer Index, - const Standard_Integer Mult, - const Standard_Integer Degree, - const Standard_Boolean Periodic, - const Array1OfPoints& Poles, - const TColStd_Array1OfReal* Weights, - const TColStd_Array1OfReal& Knots, - const TColStd_Array1OfInteger& Mults, - Array1OfPoints& NewPoles, - TColStd_Array1OfReal* NewWeights, - TColStd_Array1OfReal& NewKnots, - TColStd_Array1OfInteger& NewMults, - const Standard_Real Tolerance) -{ - Standard_Boolean rational = Weights != NULL; - Standard_Integer dim; - dim = Dimension_gen; - if (rational) - dim++; - - TColStd_Array1OfReal poles(1, dim * Poles.Length()); - TColStd_Array1OfReal newpoles(1, dim * NewPoles.Length()); - - if (rational) - PLib::SetPoles(Poles, *Weights, poles); - else - PLib::SetPoles(Poles, poles); - - if (!RemoveKnot(Index, - Mult, - Degree, - Periodic, - dim, - poles, - Knots, - Mults, - newpoles, - NewKnots, - NewMults, - Tolerance)) - return Standard_False; - - if (rational) - PLib::GetPoles(newpoles, NewPoles, *NewWeights); - else - PLib::GetPoles(newpoles, NewPoles); - return Standard_True; -} - -//======================================================================= -// function : InsertKnots -// purpose : insert an array of knots and multiplicities -//======================================================================= - -void BSplCLib::InsertKnots(const Standard_Integer Degree, - const Standard_Boolean Periodic, - const Array1OfPoints& Poles, - const TColStd_Array1OfReal* Weights, - const TColStd_Array1OfReal& Knots, - const TColStd_Array1OfInteger& Mults, - const TColStd_Array1OfReal& AddKnots, - const TColStd_Array1OfInteger* AddMults, - Array1OfPoints& NewPoles, - TColStd_Array1OfReal* NewWeights, - TColStd_Array1OfReal& NewKnots, - TColStd_Array1OfInteger& NewMults, - const Standard_Real Epsilon, - const Standard_Boolean Add) -{ - Standard_Boolean rational = Weights != NULL; - Standard_Integer dim; - dim = Dimension_gen; - if (rational) - dim++; - - TColStd_Array1OfReal poles(1, dim * Poles.Length()); - TColStd_Array1OfReal newpoles(1, dim * NewPoles.Length()); - - if (rational) - PLib::SetPoles(Poles, *Weights, poles); - else - PLib::SetPoles(Poles, poles); - - InsertKnots(Degree, - Periodic, - dim, - poles, - Knots, - Mults, - AddKnots, - AddMults, - newpoles, - NewKnots, - NewMults, - Epsilon, - Add); - - if (rational) - PLib::GetPoles(newpoles, NewPoles, *NewWeights); - else - PLib::GetPoles(newpoles, NewPoles); -} - -//================================================================================================= - -void BSplCLib::InsertKnot(const Standard_Integer, - const Standard_Real U, - const Standard_Integer UMult, - const Standard_Integer Degree, - const Standard_Boolean Periodic, - const Array1OfPoints& Poles, - const TColStd_Array1OfReal* Weights, - const TColStd_Array1OfReal& Knots, - const TColStd_Array1OfInteger& Mults, - Array1OfPoints& NewPoles, - TColStd_Array1OfReal* NewWeights) -{ - TColStd_Array1OfReal k(1, 1); - k(1) = U; - TColStd_Array1OfInteger m(1, 1); - m(1) = UMult; - TColStd_Array1OfReal nk(1, Knots.Length() + 1); - TColStd_Array1OfInteger nm(1, Knots.Length() + 1); - InsertKnots(Degree, - Periodic, - Poles, - Weights, - Knots, - Mults, - k, - &m, - NewPoles, - NewWeights, - nk, - nm, - Epsilon(U)); -} - -//================================================================================================= - -void BSplCLib::RaiseMultiplicity(const Standard_Integer KnotIndex, - const Standard_Integer Mult, - const Standard_Integer Degree, - const Standard_Boolean Periodic, - const Array1OfPoints& Poles, - const TColStd_Array1OfReal* Weights, - const TColStd_Array1OfReal& Knots, - const TColStd_Array1OfInteger& Mults, - Array1OfPoints& NewPoles, - TColStd_Array1OfReal* NewWeights) -{ - TColStd_Array1OfReal k(1, 1); - k(1) = Knots(KnotIndex); - TColStd_Array1OfInteger m(1, 1); - m(1) = Mult - Mults(KnotIndex); - TColStd_Array1OfReal nk(1, Knots.Length()); - TColStd_Array1OfInteger nm(1, Knots.Length()); - InsertKnots(Degree, - Periodic, - Poles, - Weights, - Knots, - Mults, - k, - &m, - NewPoles, - NewWeights, - nk, - nm, - Epsilon(k(1))); -} - -//================================================================================================= - -void BSplCLib::IncreaseDegree(const Standard_Integer Degree, - const Standard_Integer NewDegree, - const Standard_Boolean Periodic, - const Array1OfPoints& Poles, - const TColStd_Array1OfReal* Weights, - const TColStd_Array1OfReal& Knots, - const TColStd_Array1OfInteger& Mults, - Array1OfPoints& NewPoles, - TColStd_Array1OfReal* NewWeights, - TColStd_Array1OfReal& NewKnots, - TColStd_Array1OfInteger& NewMults) -{ - Standard_Boolean rational = Weights != NULL; - Standard_Integer dim; - dim = Dimension_gen; - if (rational) - dim++; - - TColStd_Array1OfReal poles(1, dim * Poles.Length()); - TColStd_Array1OfReal newpoles(1, dim * NewPoles.Length()); - - if (rational) - PLib::SetPoles(Poles, *Weights, poles); - else - PLib::SetPoles(Poles, poles); - - IncreaseDegree(Degree, - NewDegree, - Periodic, - dim, - poles, - Knots, - Mults, - newpoles, - NewKnots, - NewMults); - - if (rational) - PLib::GetPoles(newpoles, NewPoles, *NewWeights); - else - PLib::GetPoles(newpoles, NewPoles); -} - -//================================================================================================= - -void BSplCLib::Unperiodize(const Standard_Integer Degree, - const TColStd_Array1OfInteger& Mults, - const TColStd_Array1OfReal& Knots, - const Array1OfPoints& Poles, - const TColStd_Array1OfReal* Weights, - TColStd_Array1OfInteger& NewMults, - TColStd_Array1OfReal& NewKnots, - Array1OfPoints& NewPoles, - TColStd_Array1OfReal* NewWeights) -{ - Standard_Boolean rational = Weights != NULL; - Standard_Integer dim; - dim = Dimension_gen; - if (rational) - dim++; - - TColStd_Array1OfReal poles(1, dim * Poles.Length()); - TColStd_Array1OfReal newpoles(1, dim * NewPoles.Length()); - - if (rational) - PLib::SetPoles(Poles, *Weights, poles); - else - PLib::SetPoles(Poles, poles); - - Unperiodize(Degree, dim, Mults, Knots, poles, NewMults, NewKnots, newpoles); - - if (rational) - PLib::GetPoles(newpoles, NewPoles, *NewWeights); - else - PLib::GetPoles(newpoles, NewPoles); -} - -//================================================================================================= - -void BSplCLib::Trimming(const Standard_Integer Degree, - const Standard_Boolean Periodic, - const TColStd_Array1OfReal& Knots, - const TColStd_Array1OfInteger& Mults, - const Array1OfPoints& Poles, - const TColStd_Array1OfReal* Weights, - const Standard_Real U1, - const Standard_Real U2, - TColStd_Array1OfReal& NewKnots, - TColStd_Array1OfInteger& NewMults, - Array1OfPoints& NewPoles, - TColStd_Array1OfReal* NewWeights) -{ - Standard_Boolean rational = Weights != NULL; - Standard_Integer dim; - dim = Dimension_gen; - if (rational) - dim++; - - TColStd_Array1OfReal poles(1, dim * Poles.Length()); - TColStd_Array1OfReal newpoles(1, dim * NewPoles.Length()); - - if (rational) - PLib::SetPoles(Poles, *Weights, poles); - else - PLib::SetPoles(Poles, poles); - - Trimming(Degree, Periodic, dim, Knots, Mults, poles, U1, U2, NewKnots, NewMults, newpoles); - - if (rational) - PLib::GetPoles(newpoles, NewPoles, *NewWeights); - else - PLib::GetPoles(newpoles, NewPoles); -} - -//================================================================================================= - -// -// All the following methods are methods of low level used in BSplCLib -// but also in BSplSLib (but not in Geom) -// At the creation time of this package there is no possibility -// to declare private methods of package and to declare friend -// methods of package. It could interesting to declare that BSplSLib -// is a package friend to BSplCLib because it uses all the basis methods -// of BSplCLib. -//-------------------------------------------------------------------------- - -//======================================================================= -// function : BuildEval -// purpose : builds the local array for evaluation -//======================================================================= - -void BSplCLib::BuildEval(const Standard_Integer Degree, - const Standard_Integer Index, - const Array1OfPoints& Poles, - const TColStd_Array1OfReal* Weights, - Standard_Real& LP) -{ - Standard_Real w, *pole = &LP; - Standard_Integer PLower = Poles.Lower(); - Standard_Integer PUpper = Poles.Upper(); - Standard_Integer i; - Standard_Integer ip = PLower + Index - 1; - if (Weights == NULL) - { - for (i = 0; i <= Degree; i++) - { - ip++; - if (ip > PUpper) - ip = PLower; - const Point& P = Poles(ip); - PointToCoords(pole, P, +0); - pole += Dimension_gen; - } - } - else - { - for (i = 0; i <= Degree; i++) - { - ip++; - if (ip > PUpper) - ip = PLower; - const Point& P = Poles(ip); - pole[Dimension_gen] = w = (*Weights)(ip); - PointToCoords(pole, P, *w); - pole += Dimension_gen + 1; - } - } -} - -//======================================================================= -// function : PrepareEval -// purpose : stores data for Eval in the local arrays -// dc.poles and dc.knots -//======================================================================= - -static void PrepareEval(Standard_Real& u, - Standard_Integer& index, - Standard_Integer& dim, - Standard_Boolean& rational, - const Standard_Integer Degree, - const Standard_Boolean Periodic, - const Array1OfPoints& Poles, - const TColStd_Array1OfReal* Weights, - const TColStd_Array1OfReal& Knots, - const TColStd_Array1OfInteger* Mults, - BSplCLib_DataContainer& dc) -{ - // Set the Index - BSplCLib::LocateParameter(Degree, Knots, Mults, u, Periodic, index, u); - - // make the knots - BSplCLib::BuildKnots(Degree, index, Periodic, Knots, Mults, *dc.knots); - if (Mults == NULL) - index -= Knots.Lower() + Degree; - else - index = BSplCLib::PoleIndex(Degree, index, Periodic, *Mults); - - // check truly rational - rational = (Weights != NULL); - if (rational) - { - Standard_Integer WLower = Weights->Lower() + index; - rational = BSplCLib::IsRational(*Weights, WLower, WLower + Degree); - } - - // make the poles - if (rational) - { - dim = Dimension_gen + 1; - BSplCLib::BuildEval(Degree, index, Poles, Weights, *dc.poles); - } - else - { - dim = Dimension_gen; - BSplCLib::BuildEval(Degree, index, Poles, BSplCLib::NoWeights(), *dc.poles); - } -} - -//================================================================================================= - -void BSplCLib::D0(const Standard_Real U, - const Standard_Integer Index, - const Standard_Integer Degree, - const Standard_Boolean Periodic, - const Array1OfPoints& Poles, - const TColStd_Array1OfReal* Weights, - const TColStd_Array1OfReal& Knots, - const TColStd_Array1OfInteger* Mults, - Point& P) -{ - // Standard_Integer k,dim,index = Index; - Standard_Integer dim, index = Index; - Standard_Real u = U; - Standard_Boolean rational; - BSplCLib_DataContainer dc(Degree); - PrepareEval(u, index, dim, rational, Degree, Periodic, Poles, Weights, Knots, Mults, dc); - BSplCLib::Eval(u, Degree, *dc.knots, dim, *dc.poles); - - if (rational) - { - Standard_Real w = dc.poles[Dimension_gen]; - CoordsToPoint(P, dc.poles, / w); - } - else - CoordsToPoint(P, dc.poles, ); -} - -//================================================================================================= - -void BSplCLib::D1(const Standard_Real U, - const Standard_Integer Index, - const Standard_Integer Degree, - const Standard_Boolean Periodic, - const Array1OfPoints& Poles, - const TColStd_Array1OfReal* Weights, - const TColStd_Array1OfReal& Knots, - const TColStd_Array1OfInteger* Mults, - Point& P, - Vector& V) -{ - Standard_Integer dim, index = Index; - Standard_Real u = U; - Standard_Boolean rational; - BSplCLib_DataContainer dc(Degree); - PrepareEval(u, index, dim, rational, Degree, Periodic, Poles, Weights, Knots, Mults, dc); - BSplCLib::Bohm(u, Degree, 1, *dc.knots, dim, *dc.poles); - Standard_Real* result = dc.poles; - if (rational) - { - PLib::RationalDerivative(Degree, 1, Dimension_gen, *dc.poles, *dc.ders); - result = dc.ders; - } - - CoordsToPoint(P, result, ); - CoordsToPoint(V, result + Dimension_gen, ); -} - -//================================================================================================= - -void BSplCLib::D2(const Standard_Real U, - const Standard_Integer Index, - const Standard_Integer Degree, - const Standard_Boolean Periodic, - const Array1OfPoints& Poles, - const TColStd_Array1OfReal* Weights, - const TColStd_Array1OfReal& Knots, - const TColStd_Array1OfInteger* Mults, - Point& P, - Vector& V1, - Vector& V2) -{ - Standard_Integer dim, index = Index; - Standard_Real u = U; - Standard_Boolean rational; - BSplCLib_DataContainer dc(Degree); - PrepareEval(u, index, dim, rational, Degree, Periodic, Poles, Weights, Knots, Mults, dc); - BSplCLib::Bohm(u, Degree, 2, *dc.knots, dim, *dc.poles); - Standard_Real* result = dc.poles; - if (rational) - { - PLib::RationalDerivative(Degree, 2, Dimension_gen, *dc.poles, *dc.ders); - result = dc.ders; - } - - CoordsToPoint(P, result, ); - CoordsToPoint(V1, result + Dimension_gen, ); - if (!rational && (Degree < 2)) - NullifyPoint(V2); - else - CoordsToPoint(V2, result + 2 * Dimension_gen, ); -} - -//================================================================================================= - -void BSplCLib::D3(const Standard_Real U, - const Standard_Integer Index, - const Standard_Integer Degree, - const Standard_Boolean Periodic, - const Array1OfPoints& Poles, - const TColStd_Array1OfReal* Weights, - const TColStd_Array1OfReal& Knots, - const TColStd_Array1OfInteger* Mults, - Point& P, - Vector& V1, - Vector& V2, - Vector& V3) -{ - Standard_Integer dim, index = Index; - Standard_Real u = U; - Standard_Boolean rational; - BSplCLib_DataContainer dc(Degree); - PrepareEval(u, index, dim, rational, Degree, Periodic, Poles, Weights, Knots, Mults, dc); - BSplCLib::Bohm(u, Degree, 3, *dc.knots, dim, *dc.poles); - Standard_Real* result = dc.poles; - if (rational) - { - PLib::RationalDerivative(Degree, 3, Dimension_gen, *dc.poles, *dc.ders); - result = dc.ders; - } - - CoordsToPoint(P, result, ); - CoordsToPoint(V1, result + Dimension_gen, ); - if (!rational && (Degree < 2)) - NullifyPoint(V2); - else - CoordsToPoint(V2, result + 2 * Dimension_gen, ); - if (!rational && (Degree < 3)) - NullifyPoint(V3); - else - CoordsToPoint(V3, result + 3 * Dimension_gen, ); -} - -//================================================================================================= - -void BSplCLib::DN(const Standard_Real U, - const Standard_Integer N, - const Standard_Integer Index, - const Standard_Integer Degree, - const Standard_Boolean Periodic, - const Array1OfPoints& Poles, - const TColStd_Array1OfReal* Weights, - const TColStd_Array1OfReal& Knots, - const TColStd_Array1OfInteger* Mults, - Vector& VN) -{ - Standard_Integer dim, index = Index; - Standard_Real u = U; - Standard_Boolean rational; - BSplCLib_DataContainer dc(Degree); - PrepareEval(u, index, dim, rational, Degree, Periodic, Poles, Weights, Knots, Mults, dc); - BSplCLib::Bohm(u, Degree, N, *dc.knots, dim, *dc.poles); - - if (rational) - { - Standard_Real v[Dimension_gen]; - PLib::RationalDerivative(Degree, N, Dimension_gen, *dc.poles, v[0], Standard_False); - CoordsToPoint(VN, v, ); - } - else - { - if (N > Degree) - NullifyPoint(VN); - else - { - Standard_Real* DN = dc.poles + N * Dimension_gen; - CoordsToPoint(VN, DN, ); - } - } -} - -//================================================================================================= - -Standard_Integer BSplCLib::SolveBandedSystem(const math_Matrix& Matrix, - const Standard_Integer UpperBandWidth, - const Standard_Integer LowerBandWidth, - Array1OfPoints& PolesArray) -{ - Standard_Real* PArray; - PArray = (Standard_Real*)&PolesArray(PolesArray.Lower()); - - return BSplCLib::SolveBandedSystem(Matrix, - UpperBandWidth, - LowerBandWidth, - Dimension_gen, - PArray[0]); -} - -//======================================================================= -// function : Solves a LU factored Matrix -// purpose : if HomogeneousFlag is 1 then the input and the output -// will be homogeneous that is no division or multiplication -// by weights will happen. On the contrary if HomogeneousFlag -// is 0 then the poles will be multiplied first by the weights -// and after interpolation they will be divided by the weights -//======================================================================= - -Standard_Integer BSplCLib::SolveBandedSystem(const math_Matrix& Matrix, - const Standard_Integer UpperBandWidth, - const Standard_Integer LowerBandWidth, - const Standard_Boolean HomogeneousFlag, - Array1OfPoints& PolesArray, - TColStd_Array1OfReal& WeightsArray) -{ - Standard_Real *PArray, *WArray; - PArray = (Standard_Real*)&PolesArray(PolesArray.Lower()); - WArray = (Standard_Real*)&WeightsArray(WeightsArray.Lower()); - return BSplCLib::SolveBandedSystem(Matrix, - UpperBandWidth, - LowerBandWidth, - HomogeneousFlag, - Dimension_gen, - PArray[0], - WArray[0]); -} - -//======================================================================= -// function : Evaluates a Bspline function : uses the ExtrapMode -// purpose : the function is extrapolated using the Taylor expansion -// of degree ExtrapMode[0] to the left and the Taylor -// expansion of degree ExtrapMode[1] to the right -// if the HomogeneousFlag == True than the Poles are supposed -// to be stored homogeneously and the result will also be homogeneous -// Valid only if Weights -//======================================================================= -void BSplCLib::Eval(const Standard_Real Parameter, - const Standard_Boolean PeriodicFlag, - const Standard_Boolean HomogeneousFlag, - Standard_Integer& ExtrapMode, - const Standard_Integer Degree, - const TColStd_Array1OfReal& FlatKnots, - const Array1OfPoints& PolesArray, - const TColStd_Array1OfReal& WeightsArray, - Point& aPoint, - Standard_Real& aWeight) -{ - Standard_Real Inverse, P[Dimension_gen], *PArray, *WArray; - Standard_Integer kk; - PArray = (Standard_Real*)&PolesArray(PolesArray.Lower()); - WArray = (Standard_Real*)&WeightsArray(WeightsArray.Lower()); - if (HomogeneousFlag) - { - BSplCLib::Eval(Parameter, - PeriodicFlag, - 0, - ExtrapMode, - Degree, - FlatKnots, - Dimension_gen, - PArray[0], - P[0]); - BSplCLib::Eval(Parameter, - PeriodicFlag, - 0, - ExtrapMode, - Degree, - FlatKnots, - 1, - WArray[0], - aWeight); - } - else - { - BSplCLib::Eval(Parameter, - PeriodicFlag, - 0, - ExtrapMode, - Degree, - FlatKnots, - Dimension_gen, - PArray[0], - WArray[0], - P[0], - aWeight); - Inverse = 1.0e0 / aWeight; - - for (kk = 0; kk < Dimension_gen; kk++) - { - P[kk] *= Inverse; - } - } - - for (kk = 0; kk < Dimension_gen; kk++) - aPoint.SetCoord(kk + 1, P[kk]); -} - -//======================================================================= -// function : CacheD0 -// purpose : Evaluates the polynomial cache of the Bspline Curve -// -//======================================================================= -void BSplCLib::CacheD0(const Standard_Real Parameter, - const Standard_Integer Degree, - const Standard_Real CacheParameter, - const Standard_Real SpanLenght, - const Array1OfPoints& PolesArray, - const TColStd_Array1OfReal* WeightsArray, - Point& aPoint) -{ - // - // the CacheParameter is where the cache polynomial was evaluated in homogeneous - // form - // the SpanLenght is the normalizing factor so that the polynomial is between - // 0 and 1 - Standard_Real NewParameter, Inverse; - Standard_Real* PArray = (Standard_Real*)&(PolesArray(PolesArray.Lower())); - Standard_Real* myPoint = (Standard_Real*)&aPoint; - NewParameter = (Parameter - CacheParameter) / SpanLenght; - PLib::NoDerivativeEvalPolynomial(NewParameter, - Degree, - Dimension_gen, - Degree * Dimension_gen, - PArray[0], - myPoint[0]); - if (WeightsArray != NULL) - { - const TColStd_Array1OfReal& refWeights = *WeightsArray; - Standard_Real* WArray = (Standard_Real*)&refWeights(refWeights.Lower()); - PLib::NoDerivativeEvalPolynomial(NewParameter, Degree, 1, Degree, WArray[0], Inverse); - - Inverse = 1.0e0 / Inverse; - ModifyCoords(myPoint, *= Inverse); - } -} - -//======================================================================= -// function : CacheD1 -// purpose : Evaluates the polynomial cache of the Bspline Curve -// -//======================================================================= -void BSplCLib::CacheD1(const Standard_Real Parameter, - const Standard_Integer Degree, - const Standard_Real CacheParameter, - const Standard_Real SpanLenght, - const Array1OfPoints& PolesArray, - const TColStd_Array1OfReal* WeightsArray, - Point& aPoint, - Vector& aVector) -{ - // - // the CacheParameter is where the cache polynomial was evaluated in homogeneous - // form - // the SpanLenght is the normalizing factor so that the polynomial is between - // 0 and 1 - Standard_Real LocalPDerivatives[Dimension_gen << 1]; - // Standard_Real LocalWDerivatives[2], NewParameter, Inverse ; - Standard_Real LocalWDerivatives[2], NewParameter; - - Standard_Real* PArray = (Standard_Real*)&(PolesArray(PolesArray.Lower())); - Standard_Real* myPoint = (Standard_Real*)&aPoint; - Standard_Real* myVector = (Standard_Real*)&aVector; - NewParameter = (Parameter - CacheParameter) / SpanLenght; - PLib::EvalPolynomial(NewParameter, 1, Degree, Dimension_gen, PArray[0], LocalPDerivatives[0]); - // - // unormalize derivatives since those are computed normalized - // - - ModifyCoords(LocalPDerivatives + Dimension_gen, /= SpanLenght); - - if (WeightsArray != NULL) - { - const TColStd_Array1OfReal& refWeights = *WeightsArray; - Standard_Real* WArray = (Standard_Real*)&refWeights(refWeights.Lower()); - PLib::EvalPolynomial(NewParameter, 1, Degree, 1, WArray[0], LocalWDerivatives[0]); - // - // unormalize the result since the polynomial stored in the cache - // is normalized between 0 and 1 - // - LocalWDerivatives[1] /= SpanLenght; - - PLib::RationalDerivatives(1, - Dimension_gen, - LocalPDerivatives[0], - LocalWDerivatives[0], - LocalPDerivatives[0]); - } - - CopyCoords(myPoint, LocalPDerivatives); - CopyCoords(myVector, LocalPDerivatives + Dimension_gen); -} - -//======================================================================= -// function : CacheD2 -// purpose : Evaluates the polynomial cache of the Bspline Curve -// -//======================================================================= -void BSplCLib::CacheD2(const Standard_Real Parameter, - const Standard_Integer Degree, - const Standard_Real CacheParameter, - const Standard_Real SpanLenght, - const Array1OfPoints& PolesArray, - const TColStd_Array1OfReal* WeightsArray, - Point& aPoint, - Vector& aVector1, - Vector& aVector2) -{ - // - // the CacheParameter is where the cache polynomial was evaluated in homogeneous - // form - // the SpanLenght is the normalizing factor so that the polynomial is between - // 0 and 1 - Standard_Integer ii, Index, EndIndex; - Standard_Real LocalPDerivatives[(Dimension_gen << 1) + Dimension_gen]; - // Standard_Real LocalWDerivatives[3], NewParameter, Factor, Inverse ; - Standard_Real LocalWDerivatives[3], NewParameter, Factor; - Standard_Real* PArray = (Standard_Real*)&(PolesArray(PolesArray.Lower())); - Standard_Real* myPoint = (Standard_Real*)&aPoint; - Standard_Real* myVector1 = (Standard_Real*)&aVector1; - Standard_Real* myVector2 = (Standard_Real*)&aVector2; - NewParameter = (Parameter - CacheParameter) / SpanLenght; - PLib::EvalPolynomial(NewParameter, 2, Degree, Dimension_gen, PArray[0], LocalPDerivatives[0]); - // - // unormalize derivatives since those are computed normalized - // - Factor = 1.0e0 / SpanLenght; - Index = Dimension_gen; - EndIndex = Min(2, Degree); - - for (ii = 1; ii <= EndIndex; ii++) - { - ModifyCoords(LocalPDerivatives + Index, *= Factor); - Factor /= SpanLenght; - Index += Dimension_gen; - } - - Index = (Degree + 1) * Dimension_gen; - for (ii = Degree; ii < 2; ii++) - { - NullifyCoords(LocalPDerivatives + Index); - Index += Dimension_gen; - } - - if (WeightsArray != NULL) - { - const TColStd_Array1OfReal& refWeights = *WeightsArray; - Standard_Real* WArray = (Standard_Real*)&refWeights(refWeights.Lower()); - - PLib::EvalPolynomial(NewParameter, 2, Degree, 1, WArray[0], LocalWDerivatives[0]); - - for (ii = Degree + 1; ii <= 2; ii++) - { - LocalWDerivatives[ii] = 0.0e0; - } - // - // unormalize the result since the polynomial stored in the cache - // is normalized between 0 and 1 - // - Factor = 1.0e0 / SpanLenght; - - for (ii = 1; ii <= EndIndex; ii++) - { - LocalWDerivatives[ii] *= Factor; - Factor /= SpanLenght; - } - PLib::RationalDerivatives(2, - Dimension_gen, - LocalPDerivatives[0], - LocalWDerivatives[0], - LocalPDerivatives[0]); - } - - CopyCoords(myPoint, LocalPDerivatives); - CopyCoords(myVector1, LocalPDerivatives + Dimension_gen); - CopyCoords(myVector2, LocalPDerivatives + Dimension_gen * 2); -} - -//======================================================================= -// function : CacheD3 -// purpose : Evaluates the polynomial cache of the Bspline Curve -// -//======================================================================= -void BSplCLib::CacheD3(const Standard_Real Parameter, - const Standard_Integer Degree, - const Standard_Real CacheParameter, - const Standard_Real SpanLenght, - const Array1OfPoints& PolesArray, - const TColStd_Array1OfReal* WeightsArray, - Point& aPoint, - Vector& aVector1, - Vector& aVector2, - Vector& aVector3) -{ - // - // the CacheParameter is where the cache polynomial was evaluated in homogeneous - // form - // the SpanLenght is the normalizing factor so that the polynomial is between - // 0 and 1 - Standard_Integer ii, Index, EndIndex; - Standard_Real LocalPDerivatives[Dimension_gen << 2]; - // Standard_Real LocalWDerivatives[4], Factor, NewParameter, Inverse ; - Standard_Real LocalWDerivatives[4], Factor, NewParameter; - Standard_Real* PArray = (Standard_Real*)&(PolesArray(PolesArray.Lower())); - Standard_Real* myPoint = (Standard_Real*)&aPoint; - Standard_Real* myVector1 = (Standard_Real*)&aVector1; - Standard_Real* myVector2 = (Standard_Real*)&aVector2; - Standard_Real* myVector3 = (Standard_Real*)&aVector3; - NewParameter = (Parameter - CacheParameter) / SpanLenght; - PLib::EvalPolynomial(NewParameter, 3, Degree, Dimension_gen, PArray[0], LocalPDerivatives[0]); - - Index = (Degree + 1) * Dimension_gen; - for (ii = Degree; ii < 3; ii++) - { - NullifyCoords(LocalPDerivatives + Index); - Index += Dimension_gen; - } - - // - // unormalize derivatives since those are computed normalized - // - Factor = 1.0e0 / SpanLenght; - Index = Dimension_gen; - EndIndex = Min(3, Degree); - - for (ii = 1; ii <= EndIndex; ii++) - { - ModifyCoords(LocalPDerivatives + Index, *= Factor); - Factor /= SpanLenght; - Index += Dimension_gen; - } - - if (WeightsArray != NULL) - { - const TColStd_Array1OfReal& refWeights = *WeightsArray; - Standard_Real* WArray = (Standard_Real*)&refWeights(refWeights.Lower()); - - PLib::EvalPolynomial(NewParameter, 3, Degree, 1, WArray[0], LocalWDerivatives[0]); - // - // unormalize the result since the polynomial stored in the cache - // is normalized between 0 and 1 - // - Factor = 1.0e0 / SpanLenght; - - for (ii = 1; ii <= EndIndex; ii++) - { - LocalWDerivatives[ii] *= Factor; - Factor /= SpanLenght; - } - - for (ii = (Degree + 1); ii <= 3; ii++) - { - LocalWDerivatives[ii] = 0.0e0; - } - PLib::RationalDerivatives(3, - Dimension_gen, - LocalPDerivatives[0], - LocalWDerivatives[0], - LocalPDerivatives[0]); - } - - CopyCoords(myPoint, LocalPDerivatives); - CopyCoords(myVector1, LocalPDerivatives + Dimension_gen); - CopyCoords(myVector2, LocalPDerivatives + Dimension_gen * 2); - CopyCoords(myVector3, LocalPDerivatives + Dimension_gen * 3); -} - -//======================================================================= -// function : BuildCache -// purpose : Stores theTaylor expansion normalized between 0,1 in the -// Cache : in case of a rational function the Poles are -// stored in homogeneous form -//======================================================================= - -void BSplCLib::BuildCache(const Standard_Real U, - const Standard_Real SpanDomain, - const Standard_Boolean Periodic, - const Standard_Integer Degree, - const TColStd_Array1OfReal& FlatKnots, - const Array1OfPoints& Poles, - const TColStd_Array1OfReal* Weights, - Array1OfPoints& CachePoles, - TColStd_Array1OfReal* CacheWeights) -{ - Standard_Integer ii, Dimension, LocalIndex, index = 0; - Standard_Real u = U, LocalValue; - Standard_Boolean rational; - - BSplCLib_DataContainer dc(Degree); - PrepareEval(u, - index, - Dimension, - rational, - Degree, - Periodic, - Poles, - Weights, - FlatKnots, - (BSplCLib::NoMults()), - dc); - // - // Watch out : PrepareEval checks if locally the Bspline is polynomial - // therefore rational flag could be set to False even if there are - // Weights. The Dimension is set accordingly. - // - - BSplCLib::Bohm(u, Degree, Degree, *dc.knots, Dimension, *dc.poles); - - LocalValue = 1.0e0; - LocalIndex = 0; - - if (rational) - { - - for (ii = 1; ii <= Degree + 1; ii++) - { - CoordsToPoint(CachePoles(ii), dc.poles + LocalIndex, *LocalValue); - LocalIndex += Dimension_gen + 1; - LocalValue *= SpanDomain / (Standard_Real)ii; - } - - LocalIndex = Dimension_gen; - LocalValue = 1.0e0; - for (ii = 1; ii <= Degree + 1; ii++) - { - (*CacheWeights)(ii) = dc.poles[LocalIndex] * LocalValue; - LocalIndex += Dimension_gen + 1; - LocalValue *= SpanDomain / (Standard_Real)ii; - } - } - else - { - - for (ii = 1; ii <= Degree + 1; ii++) - { - CoordsToPoint(CachePoles(ii), dc.poles + LocalIndex, *LocalValue); - LocalIndex += Dimension_gen; - LocalValue *= SpanDomain / (Standard_Real)ii; - } - - if (Weights != NULL) - { - for (ii = 1; ii <= Degree + 1; ii++) - (*CacheWeights)(ii) = 0.0e0; - (*CacheWeights)(1) = 1.0e0; - } - } -} - -void BSplCLib::BuildCache(const Standard_Real theParameter, - const Standard_Real theSpanDomain, - const Standard_Boolean thePeriodicFlag, - const Standard_Integer theDegree, - const Standard_Integer theSpanIndex, - const TColStd_Array1OfReal& theFlatKnots, - const Array1OfPoints& thePoles, - const TColStd_Array1OfReal* theWeights, - TColStd_Array2OfReal& theCacheArray) -{ - Standard_Real aParam = theParameter; - Standard_Integer anIndex = theSpanIndex; - Standard_Integer aDimension; - Standard_Boolean isRational; - - BSplCLib_DataContainer dc(theDegree); - PrepareEval(aParam, - anIndex, - aDimension, - isRational, - theDegree, - thePeriodicFlag, - thePoles, - theWeights, - theFlatKnots, - (BSplCLib::NoMults()), - dc); - // - // Watch out : PrepareEval checks if locally the Bspline is polynomial - // therefore rational flag could be set to False even if there are - // Weights. The Dimension is set accordingly. - // - - Standard_Integer aCacheShift = // helps to store weights when PrepareEval did not found that the - // curve is locally polynomial - (theWeights != NULL && !isRational) ? aDimension + 1 : aDimension; - - BSplCLib::Bohm(aParam, theDegree, theDegree, *dc.knots, aDimension, *dc.poles); - - Standard_Real aCoeff = 1.0; - Standard_Real* aCache = - (Standard_Real*)&(theCacheArray(theCacheArray.LowerRow(), theCacheArray.LowerCol())); - Standard_Real* aPolyCoeffs = dc.poles; - - for (Standard_Integer i = 0; i <= theDegree; i++) - { - for (Standard_Integer j = 0; j < aDimension; j++) - aCache[j] = aPolyCoeffs[j] * aCoeff; - aCoeff *= theSpanDomain / (i + 1); - aPolyCoeffs += aDimension; - aCache += aDimension; - if (aCacheShift > aDimension) - { - aCache[0] = 0.0; - aCache++; - } - } - - if (aCacheShift > aDimension) - theCacheArray.SetValue(theCacheArray.LowerRow(), - theCacheArray.LowerCol() + aCacheShift - 1, - 1.0); -} - -//================================================================================================= - -void BSplCLib::Interpolate(const Standard_Integer Degree, - const TColStd_Array1OfReal& FlatKnots, - const TColStd_Array1OfReal& Parameters, - const TColStd_Array1OfInteger& ContactOrderArray, - Array1OfPoints& Poles, - Standard_Integer& InversionProblem) - -{ - Standard_Real* PArray; - - PArray = (Standard_Real*)&Poles(Poles.Lower()); - - BSplCLib::Interpolate(Degree, - FlatKnots, - Parameters, - ContactOrderArray, - Dimension_gen, - PArray[0], - InversionProblem); -} - -//================================================================================================= - -void BSplCLib::Interpolate(const Standard_Integer Degree, - const TColStd_Array1OfReal& FlatKnots, - const TColStd_Array1OfReal& Parameters, - const TColStd_Array1OfInteger& ContactOrderArray, - Array1OfPoints& Poles, - TColStd_Array1OfReal& Weights, - Standard_Integer& InversionProblem) -{ - Standard_Real *PArray, *WArray; - PArray = (Standard_Real*)&Poles(Poles.Lower()); - WArray = (Standard_Real*)&Weights(Weights.Lower()); - BSplCLib::Interpolate(Degree, - FlatKnots, - Parameters, - ContactOrderArray, - Dimension_gen, - PArray[0], - WArray[0], - InversionProblem); -} - -//======================================================================= -// function : MovePoint -// purpose : Find the new poles which allows an old point (with a -// given u as parameter) to reach a new position -//======================================================================= - -void BSplCLib::MovePoint(const Standard_Real U, - const Vector& Displ, - const Standard_Integer Index1, - const Standard_Integer Index2, - const Standard_Integer Degree, - const Array1OfPoints& Poles, - const TColStd_Array1OfReal* Weights, - const TColStd_Array1OfReal& FlatKnots, - Standard_Integer& FirstIndex, - Standard_Integer& LastIndex, - Array1OfPoints& NewPoles) -{ - // calculate the BSplineBasis in the parameter U - Standard_Integer FirstNonZeroBsplineIndex; - math_Matrix BSplineBasis(1, 1, 1, Degree + 1); - Standard_Integer ErrorCode = - BSplCLib::EvalBsplineBasis(0, Degree + 1, FlatKnots, U, FirstNonZeroBsplineIndex, BSplineBasis); - if (ErrorCode != 0) - { - FirstIndex = 0; - LastIndex = 0; - - for (Standard_Integer i = Poles.Lower(); i <= Poles.Upper(); i++) - { - NewPoles(i) = Poles(i); - } - return; - } - - // find the span which is predominant for parameter U - FirstIndex = FirstNonZeroBsplineIndex; - LastIndex = FirstNonZeroBsplineIndex + Degree; - if (FirstIndex < Index1) - FirstIndex = Index1; - if (LastIndex > Index2) - LastIndex = Index2; - - Standard_Real maxValue = 0.0; - Standard_Integer i, kk1 = 0, kk2, ii; - - for (i = FirstIndex - FirstNonZeroBsplineIndex + 1; i <= LastIndex - FirstNonZeroBsplineIndex + 1; - i++) - { - if (BSplineBasis(1, i) > maxValue) - { - kk1 = i + FirstNonZeroBsplineIndex - 1; - maxValue = BSplineBasis(1, i); - } - } - - // find a kk2 if symmetry - kk2 = kk1; - i = kk1 - FirstNonZeroBsplineIndex + 2; - if ((kk1 + 1) <= LastIndex) - { - if (Abs(BSplineBasis(1, kk1 - FirstNonZeroBsplineIndex + 2) - maxValue) < 1.e-10) - { - kk2 = kk1 + 1; - } - } - - // compute the vector of displacement - Standard_Real D1 = 0.0; - Standard_Real D2 = 0.0; - Standard_Real hN, Coef, Dval; - - for (i = 1; i <= Degree + 1; i++) - { - ii = i + FirstNonZeroBsplineIndex - 1; - if (Weights != NULL) - { - hN = Weights->Value(ii) * BSplineBasis(1, i); - D2 += hN; - } - else - { - hN = BSplineBasis(1, i); - } - if (ii >= FirstIndex && ii <= LastIndex) - { - if (ii < kk1) - { - Dval = kk1 - ii; - } - else if (ii > kk2) - { - Dval = ii - kk2; - } - else - { - Dval = 0.0; - } - D1 += 1. / (Dval + 1.) * hN; - } - } - - if (Weights != NULL) - { - Coef = D2 / D1; - } - else - { - Coef = 1. / D1; - } - - // compute the new poles - - for (i = Poles.Lower(); i <= Poles.Upper(); i++) - { - if (i >= FirstIndex && i <= LastIndex) - { - if (i < kk1) - { - Dval = kk1 - i; - } - else if (i > kk2) - { - Dval = i - kk2; - } - else - { - Dval = 0.0; - } - NewPoles(i) = Poles(i).Translated((Coef / (Dval + 1.)) * Displ); - } - else - { - NewPoles(i) = Poles(i); - } - } -} - -//======================================================================= -// function : MovePoint -// purpose : Find the new poles which allows an old point (with a -// given u as parameter) to reach a new position -//======================================================================= - -//================================================================================================= - -void BSplCLib::MovePointAndTangent(const Standard_Real U, - const Vector& Delta, - const Vector& DeltaDerivatives, - const Standard_Real Tolerance, - const Standard_Integer Degree, - const Standard_Integer StartingCondition, - const Standard_Integer EndingCondition, - const Array1OfPoints& Poles, - const TColStd_Array1OfReal* Weights, - const TColStd_Array1OfReal& FlatKnots, - Array1OfPoints& NewPoles, - Standard_Integer& ErrorStatus) -{ - Standard_Real *delta_array, *delta_derivative_array, *poles_array, *new_poles_array; - - Standard_Integer num_poles; - num_poles = Poles.Length(); - - if (NewPoles.Length() != num_poles) - { - throw Standard_ConstructionError(); - } - delta_array = (Standard_Real*)Δ - delta_derivative_array = (Standard_Real*)&DeltaDerivatives; - poles_array = (Standard_Real*)&Poles(Poles.Lower()); - - new_poles_array = (Standard_Real*)&NewPoles(NewPoles.Lower()); - MovePointAndTangent(U, - Dimension_gen, - delta_array[0], - delta_derivative_array[0], - Tolerance, - Degree, - StartingCondition, - EndingCondition, - poles_array[0], - Weights, - FlatKnots, - new_poles_array[0], - ErrorStatus); -} - -//================================================================================================= - -void BSplCLib::Resolution(const Array1OfPoints& Poles, - const TColStd_Array1OfReal* Weights, - const Standard_Integer NumPoles, - const TColStd_Array1OfReal& FlatKnots, - const Standard_Integer Degree, - const Standard_Real Tolerance3D, - Standard_Real& UTolerance) -{ - Standard_Real* PolesArray; - PolesArray = (Standard_Real*)&Poles(Poles.Lower()); - BSplCLib::Resolution(PolesArray[0], - Dimension_gen, - NumPoles, - Weights, - FlatKnots, - Degree, - Tolerance3D, - UTolerance); -} - -//================================================================================================= - -void BSplCLib::FunctionMultiply(const BSplCLib_EvaluatorFunction& FunctionPtr, - const Standard_Integer BSplineDegree, - const TColStd_Array1OfReal& BSplineFlatKnots, - const Array1OfPoints& Poles, - const TColStd_Array1OfReal& FlatKnots, - const Standard_Integer NewDegree, - Array1OfPoints& NewPoles, - Standard_Integer& theStatus) -{ - Standard_Integer num_bspline_poles = BSplineFlatKnots.Length() - BSplineDegree - 1; - Standard_Integer num_new_poles = FlatKnots.Length() - NewDegree - 1; - - if (Poles.Length() != num_bspline_poles || NewPoles.Length() != num_new_poles) - { - throw Standard_ConstructionError(); - } - Standard_Real* array_of_poles = (Standard_Real*)&Poles(Poles.Lower()); - Standard_Real* array_of_new_poles = (Standard_Real*)&NewPoles(NewPoles.Lower()); - BSplCLib::FunctionMultiply(FunctionPtr, - BSplineDegree, - BSplineFlatKnots, - Dimension_gen, - array_of_poles[0], - FlatKnots, - NewDegree, - array_of_new_poles[0], - theStatus); -} - -//================================================================================================= - -void BSplCLib::FunctionReparameterise(const BSplCLib_EvaluatorFunction& FunctionPtr, - const Standard_Integer BSplineDegree, - const TColStd_Array1OfReal& BSplineFlatKnots, - const Array1OfPoints& Poles, - const TColStd_Array1OfReal& FlatKnots, - const Standard_Integer NewDegree, - Array1OfPoints& NewPoles, - Standard_Integer& theStatus) -{ - Standard_Integer num_bspline_poles = BSplineFlatKnots.Length() - BSplineDegree - 1; - Standard_Integer num_new_poles = FlatKnots.Length() - NewDegree - 1; - - if (Poles.Length() != num_bspline_poles || NewPoles.Length() != num_new_poles) - { - throw Standard_ConstructionError(); - } - Standard_Real* array_of_poles = (Standard_Real*)&Poles(Poles.Lower()); - Standard_Real* array_of_new_poles = (Standard_Real*)&NewPoles(NewPoles.Lower()); - BSplCLib::FunctionReparameterise(FunctionPtr, - BSplineDegree, - BSplineFlatKnots, - Dimension_gen, - array_of_poles[0], - FlatKnots, - NewDegree, - array_of_new_poles[0], - theStatus); -} diff --git a/src/FoundationClasses/TKMath/BSplCLib/BSplCLib_CurveComputation.pxx b/src/FoundationClasses/TKMath/BSplCLib/BSplCLib_CurveComputation.pxx new file mode 100644 index 0000000000..5104fd7f41 --- /dev/null +++ b/src/FoundationClasses/TKMath/BSplCLib/BSplCLib_CurveComputation.pxx @@ -0,0 +1,1913 @@ +// Copyright (c) 1995-1999 Matra Datavision +// Copyright (c) 1999-2014 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// 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. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +// This is a private header file with template implementations for BSplCLib +// It replaces the deprecated .gxx macro-based approach with modern C++ templates + +#ifndef _BSplCLib_CurveComputation_pxx_HeaderFile +#define _BSplCLib_CurveComputation_pxx_HeaderFile + +#include +#include +#include +#include +#include +#include +#include + +// Template traits for 2D/3D point and vector operations +template +struct BSplCLib_CurveTraits +{ + // Coordinate operations + static void PointToCoords(Standard_Real* carr, const Point& pnt, Standard_Real op) + { + if constexpr (Dimension == 2) + { + carr[0] = pnt.X() + op; + carr[1] = pnt.Y() + op; + } + else if constexpr (Dimension == 3) + { + carr[0] = pnt.X() + op; + carr[1] = pnt.Y() + op; + carr[2] = pnt.Z() + op; + } + } + + static void PointToCoordsScaled(Standard_Real* carr, const Point& pnt, Standard_Real scale) + { + if constexpr (Dimension == 2) + { + carr[0] = pnt.X() * scale; + carr[1] = pnt.Y() * scale; + } + else if constexpr (Dimension == 3) + { + carr[0] = pnt.X() * scale; + carr[1] = pnt.Y() * scale; + carr[2] = pnt.Z() * scale; + } + } + + static void CoordsToPointMultiplied(Point& pnt, const Standard_Real* carr, Standard_Real factor) + { + if constexpr (Dimension == 2) + { + pnt.SetX(carr[0] * factor); + pnt.SetY(carr[1] * factor); + } + else if constexpr (Dimension == 3) + { + pnt.SetX(carr[0] * factor); + pnt.SetY(carr[1] * factor); + pnt.SetZ(carr[2] * factor); + } + } + + static void CoordsToPointScaled(Point& pnt, const Standard_Real* carr, Standard_Real scale) + { + if constexpr (Dimension == 2) + { + pnt.SetX(carr[0] / scale); + pnt.SetY(carr[1] / scale); + } + else if constexpr (Dimension == 3) + { + pnt.SetX(carr[0] / scale); + pnt.SetY(carr[1] / scale); + pnt.SetZ(carr[2] / scale); + } + } + + static void CoordsToPointDirect(Point& pnt, const Standard_Real* carr) + { + if constexpr (Dimension == 2) + { + pnt.SetX(carr[0]); + pnt.SetY(carr[1]); + } + else if constexpr (Dimension == 3) + { + pnt.SetX(carr[0]); + pnt.SetY(carr[1]); + pnt.SetZ(carr[2]); + } + } + + static void CoordsToVectorDirect(Vector& vec, const Standard_Real* carr) + { + if constexpr (Dimension == 2) + { + vec.SetX(carr[0]); + vec.SetY(carr[1]); + } + else if constexpr (Dimension == 3) + { + vec.SetX(carr[0]); + vec.SetY(carr[1]); + vec.SetZ(carr[2]); + } + } + + static void NullifyPoint(Point& pnt) + { + if constexpr (Dimension == 2) + { + pnt.SetCoord(0., 0.); + } + else if constexpr (Dimension == 3) + { + pnt.SetCoord(0., 0., 0.); + } + } + + static void NullifyVector(Vector& vec) + { + if constexpr (Dimension == 2) + { + vec.SetCoord(0., 0.); + } + else if constexpr (Dimension == 3) + { + vec.SetCoord(0., 0., 0.); + } + } + + static void NullifyCoords(Standard_Real* carr) + { + if constexpr (Dimension == 2) + { + carr[0] = carr[1] = 0.; + } + else if constexpr (Dimension == 3) + { + carr[0] = carr[1] = carr[2] = 0.; + } + } + + static void CopyCoords(Standard_Real* carr, const Standard_Real* carr2) + { + if constexpr (Dimension == 2) + { + carr[0] = carr2[0]; + carr[1] = carr2[1]; + } + else if constexpr (Dimension == 3) + { + carr[0] = carr2[0]; + carr[1] = carr2[1]; + carr[2] = carr2[2]; + } + } + + static void ModifyCoordsScale(Standard_Real* carr, Standard_Real scale) + { + if constexpr (Dimension == 2) + { + carr[0] *= scale; + carr[1] *= scale; + } + else if constexpr (Dimension == 3) + { + carr[0] *= scale; + carr[1] *= scale; + carr[2] *= scale; + } + } + + static void ModifyCoordsDivide(Standard_Real* carr, Standard_Real divisor) + { + if constexpr (Dimension == 2) + { + carr[0] /= divisor; + carr[1] /= divisor; + } + else if constexpr (Dimension == 3) + { + carr[0] /= divisor; + carr[1] /= divisor; + carr[2] /= divisor; + } + } +}; + +// Auxiliary structure providing buffers for poles and knots used in evaluation of bspline +// (allocated in the stack) +template +struct BSplCLib_DataContainer_T +{ + BSplCLib_DataContainer_T(Standard_Integer Degree) + { + (void)Degree; // avoid compiler warning + Standard_OutOfRange_Raise_if(Degree > BSplCLib::MaxDegree() || BSplCLib::MaxDegree() > 25, + "BSplCLib: bspline degree is greater than maximum supported"); + } + + Standard_Real poles[(25 + 1) * (Dimension + 1)]; + Standard_Real knots[2 * 25]; + Standard_Real ders[Dimension * 4]; +}; + +// Reverses the order of poles in the array +// @param[in,out] Poles - array of poles to be reversed +// @param[in] L - length parameter for reversal +template +void BSplCLib_Reverse(Array1OfPoints& Poles, const Standard_Integer L) +{ + Standard_Integer i, l = L; + l = Poles.Lower() + (l - Poles.Lower()) % (Poles.Upper() - Poles.Lower() + 1); + + Array1OfPoints temp(0, Poles.Length() - 1); + + for (i = Poles.Lower(); i <= l; i++) + temp(l - i) = Poles(i); + + for (i = l + 1; i <= Poles.Upper(); i++) + temp(l - Poles.Lower() + Poles.Upper() - i + 1) = Poles(i); + + for (i = Poles.Lower(); i <= Poles.Upper(); i++) + Poles(i) = temp(i - Poles.Lower()); +} + +// Removes a knot from the B-spline curve +// @param[in] Index - index of the knot to remove +// @param[in] Mult - multiplicity of the knot +// @param[in] Degree - degree of the B-spline +// @param[in] Periodic - whether the curve is periodic +// @param[in] Poles - original poles +// @param[in] Weights - optional weights for rational curves +// @param[in] Knots - knot sequence +// @param[in] Mults - multiplicities +// @param[out] NewPoles - resulting poles after knot removal +// @param[out] NewWeights - resulting weights +// @param[out] NewKnots - resulting knot sequence +// @param[out] NewMults - resulting multiplicities +// @param[in] Tolerance - tolerance for knot removal +// @returns true if knot removal was successful +template +Standard_Boolean BSplCLib_RemoveKnot(const Standard_Integer Index, + const Standard_Integer Mult, + const Standard_Integer Degree, + const Standard_Boolean Periodic, + const Array1OfPoints& Poles, + const TColStd_Array1OfReal* Weights, + const TColStd_Array1OfReal& Knots, + const TColStd_Array1OfInteger& Mults, + Array1OfPoints& NewPoles, + TColStd_Array1OfReal* NewWeights, + TColStd_Array1OfReal& NewKnots, + TColStd_Array1OfInteger& NewMults, + const Standard_Real Tolerance) +{ + Standard_Boolean rational = Weights != NULL; + Standard_Integer dim; + dim = Dimension; + if (rational) + dim++; + + TColStd_Array1OfReal poles(1, dim * Poles.Length()); + TColStd_Array1OfReal newpoles(1, dim * NewPoles.Length()); + + if (rational) + PLib::SetPoles(Poles, *Weights, poles); + else + PLib::SetPoles(Poles, poles); + + if (!BSplCLib::RemoveKnot(Index, + Mult, + Degree, + Periodic, + dim, + poles, + Knots, + Mults, + newpoles, + NewKnots, + NewMults, + Tolerance)) + return Standard_False; + + if (rational) + PLib::GetPoles(newpoles, NewPoles, *NewWeights); + else + PLib::GetPoles(newpoles, NewPoles); + return Standard_True; +} + +// Inserts an array of knots and multiplicities into the B-spline curve +// @param[in] Degree - degree of the B-spline +// @param[in] Periodic - whether the curve is periodic +// @param[in] Poles - original poles +// @param[in] Weights - optional weights for rational curves +// @param[in] Knots - original knot sequence +// @param[in] Mults - original multiplicities +// @param[in] AddKnots - knots to be inserted +// @param[in] AddMults - multiplicities of knots to be inserted +// @param[out] NewPoles - resulting poles +// @param[out] NewWeights - resulting weights +// @param[out] NewKnots - resulting knot sequence +// @param[out] NewMults - resulting multiplicities +// @param[in] Epsilon - tolerance for knot comparison +// @param[in] Add - whether to add or replace knots +template +void BSplCLib_InsertKnots(const Standard_Integer Degree, + const Standard_Boolean Periodic, + const Array1OfPoints& Poles, + const TColStd_Array1OfReal* Weights, + const TColStd_Array1OfReal& Knots, + const TColStd_Array1OfInteger& Mults, + const TColStd_Array1OfReal& AddKnots, + const TColStd_Array1OfInteger* AddMults, + Array1OfPoints& NewPoles, + TColStd_Array1OfReal* NewWeights, + TColStd_Array1OfReal& NewKnots, + TColStd_Array1OfInteger& NewMults, + const Standard_Real Epsilon, + const Standard_Boolean Add) +{ + Standard_Boolean rational = Weights != NULL; + Standard_Integer dim; + dim = Dimension; + if (rational) + dim++; + + TColStd_Array1OfReal poles(1, dim * Poles.Length()); + TColStd_Array1OfReal newpoles(1, dim * NewPoles.Length()); + + if (rational) + PLib::SetPoles(Poles, *Weights, poles); + else + PLib::SetPoles(Poles, poles); + + BSplCLib::InsertKnots(Degree, + Periodic, + dim, + poles, + Knots, + Mults, + AddKnots, + AddMults, + newpoles, + NewKnots, + NewMults, + Epsilon, + Add); + + if (rational) + PLib::GetPoles(newpoles, NewPoles, *NewWeights); + else + PLib::GetPoles(newpoles, NewPoles); +} + +// Inserts a single knot into the B-spline curve +// @param[in] U - parameter value of the knot to insert +// @param[in] UMult - multiplicity of the knot +// @param[in] Degree - degree of the B-spline +// @param[in] Periodic - whether the curve is periodic +// @param[in] Poles - original poles +// @param[in] Weights - optional weights for rational curves +// @param[in] Knots - original knot sequence +// @param[in] Mults - original multiplicities +// @param[out] NewPoles - resulting poles +// @param[out] NewWeights - resulting weights +template +void BSplCLib_InsertKnot(const Standard_Integer, + const Standard_Real U, + const Standard_Integer UMult, + const Standard_Integer Degree, + const Standard_Boolean Periodic, + const Array1OfPoints& Poles, + const TColStd_Array1OfReal* Weights, + const TColStd_Array1OfReal& Knots, + const TColStd_Array1OfInteger& Mults, + Array1OfPoints& NewPoles, + TColStd_Array1OfReal* NewWeights) +{ + TColStd_Array1OfReal k(1, 1); + k(1) = U; + TColStd_Array1OfInteger m(1, 1); + m(1) = UMult; + TColStd_Array1OfReal nk(1, Knots.Length() + 1); + TColStd_Array1OfInteger nm(1, Knots.Length() + 1); + BSplCLib_InsertKnots(Degree, + Periodic, + Poles, + Weights, + Knots, + Mults, + k, + &m, + NewPoles, + NewWeights, + nk, + nm, + Epsilon(U), + Standard_True); +} + +// Raises the multiplicity of a knot in the B-spline curve +// @param[in] KnotIndex - index of the knot +// @param[in] Mult - target multiplicity +// @param[in] Degree - degree of the B-spline +// @param[in] Periodic - whether the curve is periodic +// @param[in] Poles - original poles +// @param[in] Weights - optional weights for rational curves +// @param[in] Knots - knot sequence +// @param[in] Mults - original multiplicities +// @param[out] NewPoles - resulting poles +// @param[out] NewWeights - resulting weights +template +void BSplCLib_RaiseMultiplicity(const Standard_Integer KnotIndex, + const Standard_Integer Mult, + const Standard_Integer Degree, + const Standard_Boolean Periodic, + const Array1OfPoints& Poles, + const TColStd_Array1OfReal* Weights, + const TColStd_Array1OfReal& Knots, + const TColStd_Array1OfInteger& Mults, + Array1OfPoints& NewPoles, + TColStd_Array1OfReal* NewWeights) +{ + TColStd_Array1OfReal k(1, 1); + k(1) = Knots(KnotIndex); + TColStd_Array1OfInteger m(1, 1); + m(1) = Mult - Mults(KnotIndex); + TColStd_Array1OfReal nk(1, Knots.Length()); + TColStd_Array1OfInteger nm(1, Knots.Length()); + BSplCLib_InsertKnots(Degree, + Periodic, + Poles, + Weights, + Knots, + Mults, + k, + &m, + NewPoles, + NewWeights, + nk, + nm, + Epsilon(k(1)), + Standard_True); +} + +// Increases the degree of the B-spline curve +// @param[in] Degree - current degree +// @param[in] NewDegree - target degree +// @param[in] Periodic - whether the curve is periodic +// @param[in] Poles - original poles +// @param[in] Weights - optional weights for rational curves +// @param[in] Knots - original knot sequence +// @param[in] Mults - original multiplicities +// @param[out] NewPoles - resulting poles +// @param[out] NewWeights - resulting weights +// @param[out] NewKnots - resulting knot sequence +// @param[out] NewMults - resulting multiplicities +template +void BSplCLib_IncreaseDegree(const Standard_Integer Degree, + const Standard_Integer NewDegree, + const Standard_Boolean Periodic, + const Array1OfPoints& Poles, + const TColStd_Array1OfReal* Weights, + const TColStd_Array1OfReal& Knots, + const TColStd_Array1OfInteger& Mults, + Array1OfPoints& NewPoles, + TColStd_Array1OfReal* NewWeights, + TColStd_Array1OfReal& NewKnots, + TColStd_Array1OfInteger& NewMults) +{ + Standard_Boolean rational = Weights != NULL; + Standard_Integer dim; + dim = Dimension; + if (rational) + dim++; + + TColStd_Array1OfReal poles(1, dim * Poles.Length()); + TColStd_Array1OfReal newpoles(1, dim * NewPoles.Length()); + + if (rational) + PLib::SetPoles(Poles, *Weights, poles); + else + PLib::SetPoles(Poles, poles); + + BSplCLib::IncreaseDegree(Degree, + NewDegree, + Periodic, + dim, + poles, + Knots, + Mults, + newpoles, + NewKnots, + NewMults); + + if (rational) + PLib::GetPoles(newpoles, NewPoles, *NewWeights); + else + PLib::GetPoles(newpoles, NewPoles); +} + +// Converts a periodic B-spline curve to non-periodic +// @param[in] Degree - degree of the B-spline +// @param[in] Mults - original multiplicities +// @param[in] Knots - original knot sequence +// @param[in] Poles - original poles +// @param[in] Weights - optional weights for rational curves +// @param[out] NewMults - resulting multiplicities +// @param[out] NewKnots - resulting knot sequence +// @param[out] NewPoles - resulting poles +// @param[out] NewWeights - resulting weights +template +void BSplCLib_Unperiodize(const Standard_Integer Degree, + const TColStd_Array1OfInteger& Mults, + const TColStd_Array1OfReal& Knots, + const Array1OfPoints& Poles, + const TColStd_Array1OfReal* Weights, + TColStd_Array1OfInteger& NewMults, + TColStd_Array1OfReal& NewKnots, + Array1OfPoints& NewPoles, + TColStd_Array1OfReal* NewWeights) +{ + Standard_Boolean rational = Weights != NULL; + Standard_Integer dim; + dim = Dimension; + if (rational) + dim++; + + TColStd_Array1OfReal poles(1, dim * Poles.Length()); + TColStd_Array1OfReal newpoles(1, dim * NewPoles.Length()); + + if (rational) + PLib::SetPoles(Poles, *Weights, poles); + else + PLib::SetPoles(Poles, poles); + + BSplCLib::Unperiodize(Degree, dim, Mults, Knots, poles, NewMults, NewKnots, newpoles); + + if (rational) + PLib::GetPoles(newpoles, NewPoles, *NewWeights); + else + PLib::GetPoles(newpoles, NewPoles); +} + +// Trims the B-spline curve to a parameter range +// @param[in] Degree - degree of the B-spline +// @param[in] Periodic - whether the curve is periodic +// @param[in] Knots - original knot sequence +// @param[in] Mults - original multiplicities +// @param[in] Poles - original poles +// @param[in] Weights - optional weights for rational curves +// @param[in] U1 - start parameter for trimming +// @param[in] U2 - end parameter for trimming +// @param[out] NewKnots - resulting knot sequence +// @param[out] NewMults - resulting multiplicities +// @param[out] NewPoles - resulting poles +// @param[out] NewWeights - resulting weights +template +void BSplCLib_Trimming(const Standard_Integer Degree, + const Standard_Boolean Periodic, + const TColStd_Array1OfReal& Knots, + const TColStd_Array1OfInteger& Mults, + const Array1OfPoints& Poles, + const TColStd_Array1OfReal* Weights, + const Standard_Real U1, + const Standard_Real U2, + TColStd_Array1OfReal& NewKnots, + TColStd_Array1OfInteger& NewMults, + Array1OfPoints& NewPoles, + TColStd_Array1OfReal* NewWeights) +{ + Standard_Boolean rational = Weights != NULL; + Standard_Integer dim; + dim = Dimension; + if (rational) + dim++; + + TColStd_Array1OfReal poles(1, dim * Poles.Length()); + TColStd_Array1OfReal newpoles(1, dim * NewPoles.Length()); + + if (rational) + PLib::SetPoles(Poles, *Weights, poles); + else + PLib::SetPoles(Poles, poles); + + BSplCLib::Trimming(Degree, + Periodic, + dim, + Knots, + Mults, + poles, + U1, + U2, + NewKnots, + NewMults, + newpoles); + + if (rational) + PLib::GetPoles(newpoles, NewPoles, *NewWeights); + else + PLib::GetPoles(newpoles, NewPoles); +} + +// Builds the local array for B-spline evaluation +// @param[in] Degree - degree of the B-spline +// @param[in] Index - starting index in poles array +// @param[in] Poles - poles array +// @param[in] Weights - optional weights for rational curves +// @param[out] LP - local poles array for evaluation +template +void BSplCLib_BuildEval(const Standard_Integer Degree, + const Standard_Integer Index, + const Array1OfPoints& Poles, + const TColStd_Array1OfReal* Weights, + Standard_Real& LP) +{ + using Traits = BSplCLib_CurveTraits; + + Standard_Real w, *pole = &LP; + Standard_Integer PLower = Poles.Lower(); + Standard_Integer PUpper = Poles.Upper(); + Standard_Integer i; + Standard_Integer ip = PLower + Index - 1; + if (Weights == NULL) + { + for (i = 0; i <= Degree; i++) + { + ip++; + if (ip > PUpper) + ip = PLower; + const Point& P = Poles(ip); + Traits::PointToCoords(pole, P, 0); + pole += Dimension; + } + } + else + { + for (i = 0; i <= Degree; i++) + { + ip++; + if (ip > PUpper) + ip = PLower; + const Point& P = Poles(ip); + pole[Dimension] = w = (*Weights)(ip); + Traits::PointToCoordsScaled(pole, P, w); + pole += Dimension + 1; + } + } +} + +// Prepares data for B-spline evaluation by storing poles and knots in local arrays +// @param[in,out] u - parameter value +// @param[in,out] index - knot span index +// @param[out] dim - dimension of the curve +// @param[out] rational - whether the curve is rational +// @param[in] Degree - degree of the B-spline +// @param[in] Periodic - whether the curve is periodic +// @param[in] Poles - poles array +// @param[in] Weights - optional weights for rational curves +// @param[in] Knots - knot sequence +// @param[in] Mults - multiplicities +// @param[out] dc - data container for evaluation +template +static void PrepareEval_T(Standard_Real& u, + Standard_Integer& index, + Standard_Integer& dim, + Standard_Boolean& rational, + const Standard_Integer Degree, + const Standard_Boolean Periodic, + const Array1OfPoints& Poles, + const TColStd_Array1OfReal* Weights, + const TColStd_Array1OfReal& Knots, + const TColStd_Array1OfInteger* Mults, + BSplCLib_DataContainer_T& dc) +{ + // Set the Index + BSplCLib::LocateParameter(Degree, Knots, Mults, u, Periodic, index, u); + + // make the knots + BSplCLib::BuildKnots(Degree, index, Periodic, Knots, Mults, *dc.knots); + if (Mults == NULL) + index -= Knots.Lower() + Degree; + else + index = BSplCLib::PoleIndex(Degree, index, Periodic, *Mults); + + // check truly rational + rational = (Weights != NULL); + if (rational) + { + Standard_Integer WLower = Weights->Lower() + index; + rational = BSplCLib::IsRational(*Weights, WLower, WLower + Degree); + } + + // make the poles + if (rational) + { + dim = Dimension + 1; + BSplCLib_BuildEval(Degree, + index, + Poles, + Weights, + *dc.poles); + } + else + { + dim = Dimension; + BSplCLib_BuildEval(Degree, + index, + Poles, + BSplCLib::NoWeights(), + *dc.poles); + } +} + +// Evaluates the point on the B-spline curve at parameter U +// @param[in] U - parameter value +// @param[in] Index - knot span index +// @param[in] Degree - degree of the B-spline +// @param[in] Periodic - whether the curve is periodic +// @param[in] Poles - poles array +// @param[in] Weights - optional weights for rational curves +// @param[in] Knots - knot sequence +// @param[in] Mults - multiplicities +// @param[out] P - resulting point +template +void BSplCLib_D0(const Standard_Real U, + const Standard_Integer Index, + const Standard_Integer Degree, + const Standard_Boolean Periodic, + const Array1OfPoints& Poles, + const TColStd_Array1OfReal* Weights, + const TColStd_Array1OfReal& Knots, + const TColStd_Array1OfInteger* Mults, + Point& P) +{ + using Traits = BSplCLib_CurveTraits; + + Standard_Integer dim, index = Index; + Standard_Real u = U; + Standard_Boolean rational; + BSplCLib_DataContainer_T dc(Degree); + PrepareEval_T(u, + index, + dim, + rational, + Degree, + Periodic, + Poles, + Weights, + Knots, + Mults, + dc); + BSplCLib::Eval(u, Degree, *dc.knots, dim, *dc.poles); + + if (rational) + { + Standard_Real w = dc.poles[Dimension]; + Traits::CoordsToPointScaled(P, dc.poles, w); + } + else + Traits::CoordsToPointDirect(P, dc.poles); +} + +// Evaluates the point and first derivative on the B-spline curve at parameter U +// @param[in] U - parameter value +// @param[in] Index - knot span index +// @param[in] Degree - degree of the B-spline +// @param[in] Periodic - whether the curve is periodic +// @param[in] Poles - poles array +// @param[in] Weights - optional weights for rational curves +// @param[in] Knots - knot sequence +// @param[in] Mults - multiplicities +// @param[out] P - resulting point +// @param[out] V - first derivative vector +template +void BSplCLib_D1(const Standard_Real U, + const Standard_Integer Index, + const Standard_Integer Degree, + const Standard_Boolean Periodic, + const Array1OfPoints& Poles, + const TColStd_Array1OfReal* Weights, + const TColStd_Array1OfReal& Knots, + const TColStd_Array1OfInteger* Mults, + Point& P, + Vector& V) +{ + using Traits = BSplCLib_CurveTraits; + + Standard_Integer dim, index = Index; + Standard_Real u = U; + Standard_Boolean rational; + BSplCLib_DataContainer_T dc(Degree); + PrepareEval_T(u, + index, + dim, + rational, + Degree, + Periodic, + Poles, + Weights, + Knots, + Mults, + dc); + BSplCLib::Bohm(u, Degree, 1, *dc.knots, dim, *dc.poles); + Standard_Real* result = dc.poles; + if (rational) + { + PLib::RationalDerivative(Degree, 1, Dimension, *dc.poles, *dc.ders); + result = dc.ders; + } + + Traits::CoordsToPointDirect(P, result); + Traits::CoordsToVectorDirect(V, result + Dimension); +} + +// Evaluates the point and first two derivatives on the B-spline curve at parameter U +// @param[in] U - parameter value +// @param[in] Index - knot span index +// @param[in] Degree - degree of the B-spline +// @param[in] Periodic - whether the curve is periodic +// @param[in] Poles - poles array +// @param[in] Weights - optional weights for rational curves +// @param[in] Knots - knot sequence +// @param[in] Mults - multiplicities +// @param[out] P - resulting point +// @param[out] V1 - first derivative vector +// @param[out] V2 - second derivative vector +template +void BSplCLib_D2(const Standard_Real U, + const Standard_Integer Index, + const Standard_Integer Degree, + const Standard_Boolean Periodic, + const Array1OfPoints& Poles, + const TColStd_Array1OfReal* Weights, + const TColStd_Array1OfReal& Knots, + const TColStd_Array1OfInteger* Mults, + Point& P, + Vector& V1, + Vector& V2) +{ + using Traits = BSplCLib_CurveTraits; + + Standard_Integer dim, index = Index; + Standard_Real u = U; + Standard_Boolean rational; + BSplCLib_DataContainer_T dc(Degree); + PrepareEval_T(u, + index, + dim, + rational, + Degree, + Periodic, + Poles, + Weights, + Knots, + Mults, + dc); + BSplCLib::Bohm(u, Degree, 2, *dc.knots, dim, *dc.poles); + Standard_Real* result = dc.poles; + if (rational) + { + PLib::RationalDerivative(Degree, 2, Dimension, *dc.poles, *dc.ders); + result = dc.ders; + } + + Traits::CoordsToPointDirect(P, result); + Traits::CoordsToVectorDirect(V1, result + Dimension); + if (!rational && (Degree < 2)) + Traits::NullifyVector(V2); + else + Traits::CoordsToVectorDirect(V2, result + 2 * Dimension); +} + +// Evaluates the point and first three derivatives on the B-spline curve at parameter U +// @param[in] U - parameter value +// @param[in] Index - knot span index +// @param[in] Degree - degree of the B-spline +// @param[in] Periodic - whether the curve is periodic +// @param[in] Poles - poles array +// @param[in] Weights - optional weights for rational curves +// @param[in] Knots - knot sequence +// @param[in] Mults - multiplicities +// @param[out] P - resulting point +// @param[out] V1 - first derivative vector +// @param[out] V2 - second derivative vector +// @param[out] V3 - third derivative vector +template +void BSplCLib_D3(const Standard_Real U, + const Standard_Integer Index, + const Standard_Integer Degree, + const Standard_Boolean Periodic, + const Array1OfPoints& Poles, + const TColStd_Array1OfReal* Weights, + const TColStd_Array1OfReal& Knots, + const TColStd_Array1OfInteger* Mults, + Point& P, + Vector& V1, + Vector& V2, + Vector& V3) +{ + using Traits = BSplCLib_CurveTraits; + + Standard_Integer dim, index = Index; + Standard_Real u = U; + Standard_Boolean rational; + BSplCLib_DataContainer_T dc(Degree); + PrepareEval_T(u, + index, + dim, + rational, + Degree, + Periodic, + Poles, + Weights, + Knots, + Mults, + dc); + BSplCLib::Bohm(u, Degree, 3, *dc.knots, dim, *dc.poles); + Standard_Real* result = dc.poles; + if (rational) + { + PLib::RationalDerivative(Degree, 3, Dimension, *dc.poles, *dc.ders); + result = dc.ders; + } + + Traits::CoordsToPointDirect(P, result); + Traits::CoordsToVectorDirect(V1, result + Dimension); + if (!rational && (Degree < 2)) + Traits::NullifyVector(V2); + else + Traits::CoordsToVectorDirect(V2, result + 2 * Dimension); + if (!rational && (Degree < 3)) + Traits::NullifyVector(V3); + else + Traits::CoordsToVectorDirect(V3, result + 3 * Dimension); +} + +// Evaluates the Nth derivative on the B-spline curve at parameter U +// @param[in] U - parameter value +// @param[in] N - order of derivative +// @param[in] Index - knot span index +// @param[in] Degree - degree of the B-spline +// @param[in] Periodic - whether the curve is periodic +// @param[in] Poles - poles array +// @param[in] Weights - optional weights for rational curves +// @param[in] Knots - knot sequence +// @param[in] Mults - multiplicities +// @param[out] VN - Nth derivative vector +template +void BSplCLib_DN(const Standard_Real U, + const Standard_Integer N, + const Standard_Integer Index, + const Standard_Integer Degree, + const Standard_Boolean Periodic, + const Array1OfPoints& Poles, + const TColStd_Array1OfReal* Weights, + const TColStd_Array1OfReal& Knots, + const TColStd_Array1OfInteger* Mults, + Vector& VN) +{ + using Traits = BSplCLib_CurveTraits; + + Standard_Integer dim, index = Index; + Standard_Real u = U; + Standard_Boolean rational; + BSplCLib_DataContainer_T dc(Degree); + PrepareEval_T(u, + index, + dim, + rational, + Degree, + Periodic, + Poles, + Weights, + Knots, + Mults, + dc); + BSplCLib::Bohm(u, Degree, N, *dc.knots, dim, *dc.poles); + + if (rational) + { + Standard_Real v[Dimension]; + PLib::RationalDerivative(Degree, N, Dimension, *dc.poles, v[0], Standard_False); + Traits::CoordsToVectorDirect(VN, v); + } + else + { + if (N > Degree) + Traits::NullifyVector(VN); + else + { + Standard_Real* DN = dc.poles + N * Dimension; + Traits::CoordsToVectorDirect(VN, DN); + } + } +} + +// Solves a banded system of equations for B-spline poles +// @param[in] Matrix - coefficient matrix +// @param[in] UpperBandWidth - upper bandwidth of the matrix +// @param[in] LowerBandWidth - lower bandwidth of the matrix +// @param[in,out] PolesArray - poles array containing right-hand side and receiving solution +// @returns error status +template +Standard_Integer BSplCLib_SolveBandedSystem(const math_Matrix& Matrix, + const Standard_Integer UpperBandWidth, + const Standard_Integer LowerBandWidth, + Array1OfPoints& PolesArray) +{ + Standard_Real* PArray; + PArray = (Standard_Real*)&PolesArray(PolesArray.Lower()); + + return BSplCLib::SolveBandedSystem(Matrix, UpperBandWidth, LowerBandWidth, Dimension, PArray[0]); +} + +// Solves a banded system of equations for rational B-spline poles with weights +// @param[in] Matrix - coefficient matrix +// @param[in] UpperBandWidth - upper bandwidth of the matrix +// @param[in] LowerBandWidth - lower bandwidth of the matrix +// @param[in] HomogeneousFlag - whether to use homogeneous coordinates +// @param[in,out] PolesArray - poles array containing right-hand side and receiving solution +// @param[in,out] WeightsArray - weights array +// @returns error status +template +Standard_Integer BSplCLib_SolveBandedSystem(const math_Matrix& Matrix, + const Standard_Integer UpperBandWidth, + const Standard_Integer LowerBandWidth, + const Standard_Boolean HomogeneousFlag, + Array1OfPoints& PolesArray, + TColStd_Array1OfReal& WeightsArray) +{ + Standard_Real *PArray, *WArray; + PArray = (Standard_Real*)&PolesArray(PolesArray.Lower()); + WArray = (Standard_Real*)&WeightsArray(WeightsArray.Lower()); + return BSplCLib::SolveBandedSystem(Matrix, + UpperBandWidth, + LowerBandWidth, + HomogeneousFlag, + Dimension, + PArray[0], + WArray[0]); +} + +// Evaluates the B-spline curve at a given parameter +// @param[in] Parameter - parameter value +// @param[in] PeriodicFlag - whether the curve is periodic +// @param[in] HomogeneousFlag - whether to use homogeneous coordinates +// @param[in,out] ExtrapMode - extrapolation mode +// @param[in] Degree - degree of the B-spline +// @param[in] FlatKnots - flat knot sequence +// @param[in] PolesArray - poles array +// @param[in] WeightsArray - weights array +// @param[out] aPoint - resulting point +// @param[out] aWeight - resulting weight +template +void BSplCLib_Eval(const Standard_Real Parameter, + const Standard_Boolean PeriodicFlag, + const Standard_Boolean HomogeneousFlag, + Standard_Integer& ExtrapMode, + const Standard_Integer Degree, + const TColStd_Array1OfReal& FlatKnots, + const Array1OfPoints& PolesArray, + const TColStd_Array1OfReal& WeightsArray, + Point& aPoint, + Standard_Real& aWeight) +{ + Standard_Real Inverse, P[Dimension], *PArray, *WArray; + Standard_Integer kk; + PArray = (Standard_Real*)&PolesArray(PolesArray.Lower()); + WArray = (Standard_Real*)&WeightsArray(WeightsArray.Lower()); + if (HomogeneousFlag) + { + BSplCLib::Eval(Parameter, + PeriodicFlag, + 0, + ExtrapMode, + Degree, + FlatKnots, + Dimension, + PArray[0], + P[0]); + BSplCLib::Eval(Parameter, + PeriodicFlag, + 0, + ExtrapMode, + Degree, + FlatKnots, + 1, + WArray[0], + aWeight); + } + else + { + BSplCLib::Eval(Parameter, + PeriodicFlag, + 0, + ExtrapMode, + Degree, + FlatKnots, + Dimension, + PArray[0], + WArray[0], + P[0], + aWeight); + Inverse = 1.0e0 / aWeight; + + for (kk = 0; kk < Dimension; kk++) + { + P[kk] *= Inverse; + } + } + + for (kk = 0; kk < Dimension; kk++) + aPoint.SetCoord(kk + 1, P[kk]); +} + +// Evaluates the point on cached B-spline curve at parameter +// @param[in] Parameter - parameter value +// @param[in] Degree - degree of the polynomial +// @param[in] CacheParameter - cache parameter offset +// @param[in] SpanLenght - span length +// @param[in] PolesArray - cached poles array +// @param[in] WeightsArray - optional cached weights +// @param[out] aPoint - resulting point +template +void BSplCLib_CacheD0(const Standard_Real Parameter, + const Standard_Integer Degree, + const Standard_Real CacheParameter, + const Standard_Real SpanLenght, + const Array1OfPoints& PolesArray, + const TColStd_Array1OfReal* WeightsArray, + Point& aPoint) +{ + using Traits = BSplCLib_CurveTraits; + + Standard_Real NewParameter, Inverse; + Standard_Real* PArray = (Standard_Real*)&(PolesArray(PolesArray.Lower())); + Standard_Real* myPoint = (Standard_Real*)&aPoint; + NewParameter = (Parameter - CacheParameter) / SpanLenght; + PLib::NoDerivativeEvalPolynomial(NewParameter, + Degree, + Dimension, + Degree * Dimension, + PArray[0], + myPoint[0]); + if (WeightsArray != NULL) + { + const TColStd_Array1OfReal& refWeights = *WeightsArray; + Standard_Real* WArray = (Standard_Real*)&refWeights(refWeights.Lower()); + PLib::NoDerivativeEvalPolynomial(NewParameter, Degree, 1, Degree, WArray[0], Inverse); + + Inverse = 1.0e0 / Inverse; + Traits::ModifyCoordsScale(myPoint, Inverse); + } +} + +// Evaluates the point and first derivative on cached B-spline curve at parameter +// @param[in] Parameter - parameter value +// @param[in] Degree - degree of the polynomial +// @param[in] CacheParameter - cache parameter offset +// @param[in] SpanLenght - span length +// @param[in] PolesArray - cached poles array +// @param[in] WeightsArray - optional cached weights +// @param[out] aPoint - resulting point +// @param[out] aVector - first derivative vector +template +void BSplCLib_CacheD1(const Standard_Real Parameter, + const Standard_Integer Degree, + const Standard_Real CacheParameter, + const Standard_Real SpanLenght, + const Array1OfPoints& PolesArray, + const TColStd_Array1OfReal* WeightsArray, + Point& aPoint, + Vector& aVector) +{ + using Traits = BSplCLib_CurveTraits; + + Standard_Real LocalPDerivatives[Dimension << 1]; + Standard_Real LocalWDerivatives[2], NewParameter; + + Standard_Real* PArray = (Standard_Real*)&(PolesArray(PolesArray.Lower())); + Standard_Real* myPoint = (Standard_Real*)&aPoint; + Standard_Real* myVector = (Standard_Real*)&aVector; + NewParameter = (Parameter - CacheParameter) / SpanLenght; + PLib::EvalPolynomial(NewParameter, 1, Degree, Dimension, PArray[0], LocalPDerivatives[0]); + + Traits::ModifyCoordsDivide(LocalPDerivatives + Dimension, SpanLenght); + + if (WeightsArray != NULL) + { + const TColStd_Array1OfReal& refWeights = *WeightsArray; + Standard_Real* WArray = (Standard_Real*)&refWeights(refWeights.Lower()); + PLib::EvalPolynomial(NewParameter, 1, Degree, 1, WArray[0], LocalWDerivatives[0]); + + LocalWDerivatives[1] /= SpanLenght; + + PLib::RationalDerivatives(1, + Dimension, + LocalPDerivatives[0], + LocalWDerivatives[0], + LocalPDerivatives[0]); + } + + Traits::CopyCoords(myPoint, LocalPDerivatives); + Traits::CopyCoords(myVector, LocalPDerivatives + Dimension); +} + +// Evaluates the point and first two derivatives on cached B-spline curve at parameter +// @param[in] Parameter - parameter value +// @param[in] Degree - degree of the polynomial +// @param[in] CacheParameter - cache parameter offset +// @param[in] SpanLenght - span length +// @param[in] PolesArray - cached poles array +// @param[in] WeightsArray - optional cached weights +// @param[out] aPoint - resulting point +// @param[out] aVector1 - first derivative vector +// @param[out] aVector2 - second derivative vector +template +void BSplCLib_CacheD2(const Standard_Real Parameter, + const Standard_Integer Degree, + const Standard_Real CacheParameter, + const Standard_Real SpanLenght, + const Array1OfPoints& PolesArray, + const TColStd_Array1OfReal* WeightsArray, + Point& aPoint, + Vector& aVector1, + Vector& aVector2) +{ + using Traits = BSplCLib_CurveTraits; + + Standard_Integer ii, Index, EndIndex; + Standard_Real LocalPDerivatives[(Dimension << 1) + Dimension]; + Standard_Real LocalWDerivatives[3], NewParameter, Factor; + Standard_Real* PArray = (Standard_Real*)&(PolesArray(PolesArray.Lower())); + Standard_Real* myPoint = (Standard_Real*)&aPoint; + Standard_Real* myVector1 = (Standard_Real*)&aVector1; + Standard_Real* myVector2 = (Standard_Real*)&aVector2; + NewParameter = (Parameter - CacheParameter) / SpanLenght; + PLib::EvalPolynomial(NewParameter, 2, Degree, Dimension, PArray[0], LocalPDerivatives[0]); + + Factor = 1.0e0 / SpanLenght; + Index = Dimension; + EndIndex = Min(2, Degree); + + for (ii = 1; ii <= EndIndex; ii++) + { + Traits::ModifyCoordsScale(LocalPDerivatives + Index, Factor); + Factor /= SpanLenght; + Index += Dimension; + } + + Index = (Degree + 1) * Dimension; + for (ii = Degree; ii < 2; ii++) + { + Traits::NullifyCoords(LocalPDerivatives + Index); + Index += Dimension; + } + + if (WeightsArray != NULL) + { + const TColStd_Array1OfReal& refWeights = *WeightsArray; + Standard_Real* WArray = (Standard_Real*)&refWeights(refWeights.Lower()); + + PLib::EvalPolynomial(NewParameter, 2, Degree, 1, WArray[0], LocalWDerivatives[0]); + + for (ii = Degree + 1; ii <= 2; ii++) + { + LocalWDerivatives[ii] = 0.0e0; + } + + Factor = 1.0e0 / SpanLenght; + + for (ii = 1; ii <= EndIndex; ii++) + { + LocalWDerivatives[ii] *= Factor; + Factor /= SpanLenght; + } + PLib::RationalDerivatives(2, + Dimension, + LocalPDerivatives[0], + LocalWDerivatives[0], + LocalPDerivatives[0]); + } + + Traits::CopyCoords(myPoint, LocalPDerivatives); + Traits::CopyCoords(myVector1, LocalPDerivatives + Dimension); + Traits::CopyCoords(myVector2, LocalPDerivatives + Dimension * 2); +} + +// Evaluates the point and first three derivatives on cached B-spline curve at parameter +// @param[in] Parameter - parameter value +// @param[in] Degree - degree of the polynomial +// @param[in] CacheParameter - cache parameter offset +// @param[in] SpanLenght - span length +// @param[in] PolesArray - cached poles array +// @param[in] WeightsArray - optional cached weights +// @param[out] aPoint - resulting point +// @param[out] aVector1 - first derivative vector +// @param[out] aVector2 - second derivative vector +// @param[out] aVector3 - third derivative vector +template +void BSplCLib_CacheD3(const Standard_Real Parameter, + const Standard_Integer Degree, + const Standard_Real CacheParameter, + const Standard_Real SpanLenght, + const Array1OfPoints& PolesArray, + const TColStd_Array1OfReal* WeightsArray, + Point& aPoint, + Vector& aVector1, + Vector& aVector2, + Vector& aVector3) +{ + using Traits = BSplCLib_CurveTraits; + + Standard_Integer ii, Index, EndIndex; + Standard_Real LocalPDerivatives[Dimension << 2]; + Standard_Real LocalWDerivatives[4], Factor, NewParameter; + Standard_Real* PArray = (Standard_Real*)&(PolesArray(PolesArray.Lower())); + Standard_Real* myPoint = (Standard_Real*)&aPoint; + Standard_Real* myVector1 = (Standard_Real*)&aVector1; + Standard_Real* myVector2 = (Standard_Real*)&aVector2; + Standard_Real* myVector3 = (Standard_Real*)&aVector3; + NewParameter = (Parameter - CacheParameter) / SpanLenght; + PLib::EvalPolynomial(NewParameter, 3, Degree, Dimension, PArray[0], LocalPDerivatives[0]); + + Index = (Degree + 1) * Dimension; + for (ii = Degree; ii < 3; ii++) + { + Traits::NullifyCoords(LocalPDerivatives + Index); + Index += Dimension; + } + + Factor = 1.0e0 / SpanLenght; + Index = Dimension; + EndIndex = Min(3, Degree); + + for (ii = 1; ii <= EndIndex; ii++) + { + Traits::ModifyCoordsScale(LocalPDerivatives + Index, Factor); + Factor /= SpanLenght; + Index += Dimension; + } + + if (WeightsArray != NULL) + { + const TColStd_Array1OfReal& refWeights = *WeightsArray; + Standard_Real* WArray = (Standard_Real*)&refWeights(refWeights.Lower()); + + PLib::EvalPolynomial(NewParameter, 3, Degree, 1, WArray[0], LocalWDerivatives[0]); + + Factor = 1.0e0 / SpanLenght; + + for (ii = 1; ii <= EndIndex; ii++) + { + LocalWDerivatives[ii] *= Factor; + Factor /= SpanLenght; + } + + for (ii = (Degree + 1); ii <= 3; ii++) + { + LocalWDerivatives[ii] = 0.0e0; + } + PLib::RationalDerivatives(3, + Dimension, + LocalPDerivatives[0], + LocalWDerivatives[0], + LocalPDerivatives[0]); + } + + Traits::CopyCoords(myPoint, LocalPDerivatives); + Traits::CopyCoords(myVector1, LocalPDerivatives + Dimension); + Traits::CopyCoords(myVector2, LocalPDerivatives + Dimension * 2); + Traits::CopyCoords(myVector3, LocalPDerivatives + Dimension * 3); +} + +// Builds cache for efficient B-spline evaluation (Point version) +// @param[in] U - parameter value +// @param[in] SpanDomain - span domain +// @param[in] Periodic - whether the curve is periodic +// @param[in] Degree - degree of the B-spline +// @param[in] FlatKnots - flat knot sequence +// @param[in] Poles - poles array +// @param[in] Weights - optional weights for rational curves +// @param[out] CachePoles - cached poles array +// @param[out] CacheWeights - cached weights array +template +void BSplCLib_BuildCache(const Standard_Real U, + const Standard_Real SpanDomain, + const Standard_Boolean Periodic, + const Standard_Integer Degree, + const TColStd_Array1OfReal& FlatKnots, + const Array1OfPoints& Poles, + const TColStd_Array1OfReal* Weights, + Array1OfPoints& CachePoles, + TColStd_Array1OfReal* CacheWeights) +{ + using Traits = BSplCLib_CurveTraits; + + Standard_Integer ii, LocalDimension, LocalIndex, index = 0; + Standard_Real u = U, LocalValue; + Standard_Boolean rational; + + BSplCLib_DataContainer_T dc(Degree); + PrepareEval_T(u, + index, + LocalDimension, + rational, + Degree, + Periodic, + Poles, + Weights, + FlatKnots, + (BSplCLib::NoMults()), + dc); + + BSplCLib::Bohm(u, Degree, Degree, *dc.knots, LocalDimension, *dc.poles); + + LocalValue = 1.0e0; + LocalIndex = 0; + + if (rational) + { + + for (ii = 1; ii <= Degree + 1; ii++) + { + Traits::CoordsToPointMultiplied(CachePoles(ii), dc.poles + LocalIndex, LocalValue); + LocalIndex += Dimension + 1; + LocalValue *= SpanDomain / (Standard_Real)ii; + } + + LocalIndex = Dimension; + LocalValue = 1.0e0; + for (ii = 1; ii <= Degree + 1; ii++) + { + (*CacheWeights)(ii) = dc.poles[LocalIndex] * LocalValue; + LocalIndex += Dimension + 1; + LocalValue *= SpanDomain / (Standard_Real)ii; + } + } + else + { + + for (ii = 1; ii <= Degree + 1; ii++) + { + Traits::CoordsToPointMultiplied(CachePoles(ii), dc.poles + LocalIndex, LocalValue); + LocalIndex += Dimension; + LocalValue *= SpanDomain / (Standard_Real)ii; + } + + if (Weights != NULL) + { + for (ii = 1; ii <= Degree + 1; ii++) + (*CacheWeights)(ii) = 0.0e0; + (*CacheWeights)(1) = 1.0e0; + } + } +} + +// Builds cache for efficient B-spline evaluation (Array2 version) +// @param[in] theParameter - parameter value +// @param[in] theSpanDomain - span domain +// @param[in] thePeriodicFlag - whether the curve is periodic +// @param[in] theDegree - degree of the B-spline +// @param[in] theSpanIndex - span index +// @param[in] theFlatKnots - flat knot sequence +// @param[in] thePoles - poles array +// @param[in] theWeights - optional weights for rational curves +// @param[out] theCacheArray - 2D cache array +template +void BSplCLib_BuildCache(const Standard_Real theParameter, + const Standard_Real theSpanDomain, + const Standard_Boolean thePeriodicFlag, + const Standard_Integer theDegree, + const Standard_Integer theSpanIndex, + const TColStd_Array1OfReal& theFlatKnots, + const Array1OfPoints& thePoles, + const TColStd_Array1OfReal* theWeights, + TColStd_Array2OfReal& theCacheArray) +{ + Standard_Real aParam = theParameter; + Standard_Integer anIndex = theSpanIndex; + Standard_Integer aDimension; + Standard_Boolean isRational; + + BSplCLib_DataContainer_T dc(theDegree); + PrepareEval_T(aParam, + anIndex, + aDimension, + isRational, + theDegree, + thePeriodicFlag, + thePoles, + theWeights, + theFlatKnots, + (BSplCLib::NoMults()), + dc); + + Standard_Integer aCacheShift = (theWeights != NULL && !isRational) ? aDimension + 1 : aDimension; + + BSplCLib::Bohm(aParam, theDegree, theDegree, *dc.knots, aDimension, *dc.poles); + + Standard_Real aCoeff = 1.0; + Standard_Real* aCache = + (Standard_Real*)&(theCacheArray(theCacheArray.LowerRow(), theCacheArray.LowerCol())); + Standard_Real* aPolyCoeffs = dc.poles; + + for (Standard_Integer i = 0; i <= theDegree; i++) + { + for (Standard_Integer j = 0; j < aDimension; j++) + aCache[j] = aPolyCoeffs[j] * aCoeff; + aCoeff *= theSpanDomain / (i + 1); + aPolyCoeffs += aDimension; + aCache += aDimension; + if (aCacheShift > aDimension) + { + aCache[0] = 0.0; + aCache++; + } + } + + if (aCacheShift > aDimension) + theCacheArray.SetValue(theCacheArray.LowerRow(), + theCacheArray.LowerCol() + aCacheShift - 1, + 1.0); +} + +// Interpolates points to create a B-spline curve +// @param[in] Degree - degree of the B-spline +// @param[in] FlatKnots - flat knot sequence +// @param[in] Parameters - parameter values at points +// @param[in] ContactOrderArray - contact order at each point +// @param[in,out] Poles - poles array to be computed +// @param[out] InversionProblem - status of matrix inversion +template +void BSplCLib_Interpolate(const Standard_Integer Degree, + const TColStd_Array1OfReal& FlatKnots, + const TColStd_Array1OfReal& Parameters, + const TColStd_Array1OfInteger& ContactOrderArray, + Array1OfPoints& Poles, + Standard_Integer& InversionProblem) + +{ + Standard_Real* PArray; + + PArray = (Standard_Real*)&Poles(Poles.Lower()); + + BSplCLib::Interpolate(Degree, + FlatKnots, + Parameters, + ContactOrderArray, + Dimension, + PArray[0], + InversionProblem); +} + +// Interpolates weighted points to create a rational B-spline curve +// @param[in] Degree - degree of the B-spline +// @param[in] FlatKnots - flat knot sequence +// @param[in] Parameters - parameter values at points +// @param[in] ContactOrderArray - contact order at each point +// @param[in,out] Poles - poles array to be computed +// @param[in,out] Weights - weights array +// @param[out] InversionProblem - status of matrix inversion +template +void BSplCLib_Interpolate(const Standard_Integer Degree, + const TColStd_Array1OfReal& FlatKnots, + const TColStd_Array1OfReal& Parameters, + const TColStd_Array1OfInteger& ContactOrderArray, + Array1OfPoints& Poles, + TColStd_Array1OfReal& Weights, + Standard_Integer& InversionProblem) +{ + Standard_Real *PArray, *WArray; + PArray = (Standard_Real*)&Poles(Poles.Lower()); + WArray = (Standard_Real*)&Weights(Weights.Lower()); + BSplCLib::Interpolate(Degree, + FlatKnots, + Parameters, + ContactOrderArray, + Dimension, + PArray[0], + WArray[0], + InversionProblem); +} + +// Moves a point on the B-spline curve by modifying poles +// @param[in] U - parameter value where point is moved +// @param[in] Displ - displacement vector +// @param[in] Index1 - first pole index to modify +// @param[in] Index2 - last pole index to modify +// @param[in] Degree - degree of the B-spline +// @param[in] Poles - original poles +// @param[in] Weights - optional weights for rational curves +// @param[in] FlatKnots - flat knot sequence +// @param[out] FirstIndex - first modified pole index +// @param[out] LastIndex - last modified pole index +// @param[out] NewPoles - resulting poles +template +void BSplCLib_MovePoint(const Standard_Real U, + const Vector& Displ, + const Standard_Integer Index1, + const Standard_Integer Index2, + const Standard_Integer Degree, + const Array1OfPoints& Poles, + const TColStd_Array1OfReal* Weights, + const TColStd_Array1OfReal& FlatKnots, + Standard_Integer& FirstIndex, + Standard_Integer& LastIndex, + Array1OfPoints& NewPoles) +{ + // calculate the BSplineBasis in the parameter U + Standard_Integer FirstNonZeroBsplineIndex; + math_Matrix BSplineBasis(1, 1, 1, Degree + 1); + Standard_Integer ErrorCode = + BSplCLib::EvalBsplineBasis(0, Degree + 1, FlatKnots, U, FirstNonZeroBsplineIndex, BSplineBasis); + if (ErrorCode != 0) + { + FirstIndex = 0; + LastIndex = 0; + + for (Standard_Integer i = Poles.Lower(); i <= Poles.Upper(); i++) + { + NewPoles(i) = Poles(i); + } + return; + } + + // find the span which is predominant for parameter U + FirstIndex = FirstNonZeroBsplineIndex; + LastIndex = FirstNonZeroBsplineIndex + Degree; + if (FirstIndex < Index1) + FirstIndex = Index1; + if (LastIndex > Index2) + LastIndex = Index2; + + Standard_Real maxValue = 0.0; + Standard_Integer i, kk1 = 0, kk2, ii; + + for (i = FirstIndex - FirstNonZeroBsplineIndex + 1; i <= LastIndex - FirstNonZeroBsplineIndex + 1; + i++) + { + if (BSplineBasis(1, i) > maxValue) + { + kk1 = i + FirstNonZeroBsplineIndex - 1; + maxValue = BSplineBasis(1, i); + } + } + + // find a kk2 if symmetry + kk2 = kk1; + i = kk1 - FirstNonZeroBsplineIndex + 2; + if ((kk1 + 1) <= LastIndex) + { + if (Abs(BSplineBasis(1, kk1 - FirstNonZeroBsplineIndex + 2) - maxValue) < 1.e-10) + { + kk2 = kk1 + 1; + } + } + + // compute the vector of displacement + Standard_Real D1 = 0.0; + Standard_Real D2 = 0.0; + Standard_Real hN, Coef, Dval; + + for (i = 1; i <= Degree + 1; i++) + { + ii = i + FirstNonZeroBsplineIndex - 1; + if (Weights != NULL) + { + hN = Weights->Value(ii) * BSplineBasis(1, i); + D2 += hN; + } + else + { + hN = BSplineBasis(1, i); + } + if (ii >= FirstIndex && ii <= LastIndex) + { + if (ii < kk1) + { + Dval = kk1 - ii; + } + else if (ii > kk2) + { + Dval = ii - kk2; + } + else + { + Dval = 0.0; + } + D1 += 1. / (Dval + 1.) * hN; + } + } + + if (Weights != NULL) + { + Coef = D2 / D1; + } + else + { + Coef = 1. / D1; + } + + // compute the new poles + + for (i = Poles.Lower(); i <= Poles.Upper(); i++) + { + if (i >= FirstIndex && i <= LastIndex) + { + if (i < kk1) + { + Dval = kk1 - i; + } + else if (i > kk2) + { + Dval = i - kk2; + } + else + { + Dval = 0.0; + } + NewPoles(i) = Poles(i).Translated((Coef / (Dval + 1.)) * Displ); + } + else + { + NewPoles(i) = Poles(i); + } + } +} + +// Moves a point and tangent on the B-spline curve by modifying poles +// @param[in] U - parameter value where point and tangent are moved +// @param[in] Delta - displacement vector for point +// @param[in] DeltaDerivatives - displacement vector for tangent +// @param[in] Tolerance - tolerance for computation +// @param[in] Degree - degree of the B-spline +// @param[in] StartingCondition - starting boundary condition +// @param[in] EndingCondition - ending boundary condition +// @param[in] Poles - original poles +// @param[in] Weights - optional weights for rational curves +// @param[in] FlatKnots - flat knot sequence +// @param[out] NewPoles - resulting poles +// @param[out] ErrorStatus - error status of the operation +template +void BSplCLib_MovePointAndTangent(const Standard_Real U, + const Vector& Delta, + const Vector& DeltaDerivatives, + const Standard_Real Tolerance, + const Standard_Integer Degree, + const Standard_Integer StartingCondition, + const Standard_Integer EndingCondition, + const Array1OfPoints& Poles, + const TColStd_Array1OfReal* Weights, + const TColStd_Array1OfReal& FlatKnots, + Array1OfPoints& NewPoles, + Standard_Integer& ErrorStatus) +{ + Standard_Real *delta_array, *delta_derivative_array, *poles_array, *new_poles_array; + + Standard_Integer num_poles; + num_poles = Poles.Length(); + + if (NewPoles.Length() != num_poles) + { + throw Standard_ConstructionError(); + } + delta_array = (Standard_Real*)Δ + delta_derivative_array = (Standard_Real*)&DeltaDerivatives; + poles_array = (Standard_Real*)&Poles(Poles.Lower()); + + new_poles_array = (Standard_Real*)&NewPoles(NewPoles.Lower()); + BSplCLib::MovePointAndTangent(U, + Dimension, + delta_array[0], + delta_derivative_array[0], + Tolerance, + Degree, + StartingCondition, + EndingCondition, + poles_array[0], + Weights, + FlatKnots, + new_poles_array[0], + ErrorStatus); +} + +// Computes the parametric tolerance corresponding to a 3D tolerance +// @param[in] Poles - poles array +// @param[in] Weights - optional weights for rational curves +// @param[in] NumPoles - number of poles +// @param[in] FlatKnots - flat knot sequence +// @param[in] Degree - degree of the B-spline +// @param[in] Tolerance3D - 3D tolerance +// @param[out] UTolerance - computed parametric tolerance +template +void BSplCLib_Resolution(const Array1OfPoints& Poles, + const TColStd_Array1OfReal* Weights, + const Standard_Integer NumPoles, + const TColStd_Array1OfReal& FlatKnots, + const Standard_Integer Degree, + const Standard_Real Tolerance3D, + Standard_Real& UTolerance) +{ + Standard_Real* PolesArray; + PolesArray = (Standard_Real*)&Poles(Poles.Lower()); + BSplCLib::Resolution(PolesArray[0], + Dimension, + NumPoles, + Weights, + FlatKnots, + Degree, + Tolerance3D, + UTolerance); +} + +// Multiplies the B-spline curve by a function +// @param[in] FunctionPtr - evaluator function to multiply with +// @param[in] BSplineDegree - degree of the B-spline +// @param[in] BSplineFlatKnots - flat knot sequence of the B-spline +// @param[in] Poles - original poles +// @param[in] FlatKnots - flat knot sequence for result +// @param[in] NewDegree - degree of result +// @param[out] NewPoles - resulting poles +// @param[out] theStatus - status of the operation +template +void BSplCLib_FunctionMultiply(const BSplCLib_EvaluatorFunction& FunctionPtr, + const Standard_Integer BSplineDegree, + const TColStd_Array1OfReal& BSplineFlatKnots, + const Array1OfPoints& Poles, + const TColStd_Array1OfReal& FlatKnots, + const Standard_Integer NewDegree, + Array1OfPoints& NewPoles, + Standard_Integer& theStatus) +{ + Standard_Integer num_bspline_poles = BSplineFlatKnots.Length() - BSplineDegree - 1; + Standard_Integer num_new_poles = FlatKnots.Length() - NewDegree - 1; + + if (Poles.Length() != num_bspline_poles || NewPoles.Length() != num_new_poles) + { + throw Standard_ConstructionError(); + } + Standard_Real* array_of_poles = (Standard_Real*)&Poles(Poles.Lower()); + Standard_Real* array_of_new_poles = (Standard_Real*)&NewPoles(NewPoles.Lower()); + BSplCLib::FunctionMultiply(FunctionPtr, + BSplineDegree, + BSplineFlatKnots, + Dimension, + array_of_poles[0], + FlatKnots, + NewDegree, + array_of_new_poles[0], + theStatus); +} + +// Reparameterizes the B-spline curve using a function +// @param[in] FunctionPtr - evaluator function for reparameterization +// @param[in] BSplineDegree - degree of the B-spline +// @param[in] BSplineFlatKnots - flat knot sequence of the B-spline +// @param[in] Poles - original poles +// @param[in] FlatKnots - flat knot sequence for result +// @param[in] NewDegree - degree of result +// @param[out] NewPoles - resulting poles +// @param[out] theStatus - status of the operation +template +void BSplCLib_FunctionReparameterise(const BSplCLib_EvaluatorFunction& FunctionPtr, + const Standard_Integer BSplineDegree, + const TColStd_Array1OfReal& BSplineFlatKnots, + const Array1OfPoints& Poles, + const TColStd_Array1OfReal& FlatKnots, + const Standard_Integer NewDegree, + Array1OfPoints& NewPoles, + Standard_Integer& theStatus) +{ + Standard_Integer num_bspline_poles = BSplineFlatKnots.Length() - BSplineDegree - 1; + Standard_Integer num_new_poles = FlatKnots.Length() - NewDegree - 1; + + if (Poles.Length() != num_bspline_poles || NewPoles.Length() != num_new_poles) + { + throw Standard_ConstructionError(); + } + Standard_Real* array_of_poles = (Standard_Real*)&Poles(Poles.Lower()); + Standard_Real* array_of_new_poles = (Standard_Real*)&NewPoles(NewPoles.Lower()); + BSplCLib::FunctionReparameterise(FunctionPtr, + BSplineDegree, + BSplineFlatKnots, + Dimension, + array_of_poles[0], + FlatKnots, + NewDegree, + array_of_new_poles[0], + theStatus); +} + +#endif // _BSplCLib_CurveComputation_pxx_HeaderFile diff --git a/src/FoundationClasses/TKMath/BSplCLib/FILES.cmake b/src/FoundationClasses/TKMath/BSplCLib/FILES.cmake index 7fac5f8d8f..aa1ec7f839 100644 --- a/src/FoundationClasses/TKMath/BSplCLib/FILES.cmake +++ b/src/FoundationClasses/TKMath/BSplCLib/FILES.cmake @@ -12,7 +12,7 @@ set(OCCT_BSplCLib_FILES BSplCLib_Cache.cxx BSplCLib_Cache.hxx BSplCLib_CacheParams.hxx - BSplCLib_CurveComputation.gxx + BSplCLib_CurveComputation.pxx BSplCLib_EvaluatorFunction.hxx BSplCLib_KnotDistribution.hxx BSplCLib_MultDistribution.hxx -- 2.39.5