]> OCCT Git - occt.git/commitdiff
Foundation Classes - Migrate BSplCLib from deprecated gxx macros (#826)
authorPasukhin Dmitry <dpasukhi@opencascade.com>
Thu, 13 Nov 2025 18:03:39 +0000 (18:03 +0000)
committerGitHub <noreply@github.com>
Thu, 13 Nov 2025 18:03:39 +0000 (18:03 +0000)
- 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

src/FoundationClasses/TKMath/BSplCLib/BSplCLib_1.cxx
src/FoundationClasses/TKMath/BSplCLib/BSplCLib_2.cxx
src/FoundationClasses/TKMath/BSplCLib/BSplCLib_3.cxx
src/FoundationClasses/TKMath/BSplCLib/BSplCLib_CurveComputation.gxx [deleted file]
src/FoundationClasses/TKMath/BSplCLib/BSplCLib_CurveComputation.pxx [new file with mode: 0644]
src/FoundationClasses/TKMath/BSplCLib/FILES.cmake

index 925b4e607e574e62c0e03ddcb3b457d8bb6ef6d3..b03cb8eca3c5df73787afde6304e6995a0ee9434 100644 (file)
 // commercial license or contractual agreement.
 
 #include <BSplCLib.hxx>
-
+#include <gp_Pnt2d.hxx>
+#include <gp_Vec2d.hxx>
 #include <Standard_NotImplemented.hxx>
+
 // BSpline Curve in 2d space
 // **************************
 
-#define Dimension_gen 2
+// Include the template implementation header
+#include <BSplCLib_CurveComputation.pxx>
+
+// 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<gp_Pnt2d, gp_Vec2d, TColgp_Array1OfPnt2d, 2>(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<gp_Pnt2d, gp_Vec2d, TColgp_Array1OfPnt2d, 2>(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<gp_Pnt2d, gp_Vec2d, TColgp_Array1OfPnt2d, 2>(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<gp_Pnt2d, gp_Vec2d, TColgp_Array1OfPnt2d, 2>(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<gp_Pnt2d, gp_Vec2d, TColgp_Array1OfPnt2d, 2>(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<gp_Pnt2d, gp_Vec2d, TColgp_Array1OfPnt2d, 2>(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<gp_Pnt2d, gp_Vec2d, TColgp_Array1OfPnt2d, 2>(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<gp_Pnt2d, gp_Vec2d, TColgp_Array1OfPnt2d, 2>(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<gp_Pnt2d, gp_Vec2d, TColgp_Array1OfPnt2d, 2>(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<gp_Pnt2d, gp_Vec2d, TColgp_Array1OfPnt2d, 2>(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<gp_Pnt2d, gp_Vec2d, TColgp_Array1OfPnt2d, 2>(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<gp_Pnt2d, gp_Vec2d, TColgp_Array1OfPnt2d, 2>(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<gp_Pnt2d, gp_Vec2d, TColgp_Array1OfPnt2d, 2>(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<gp_Pnt2d, gp_Vec2d, TColgp_Array1OfPnt2d, 2>(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<gp_Pnt2d, gp_Vec2d, TColgp_Array1OfPnt2d, 2>(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<gp_Pnt2d, gp_Vec2d, TColgp_Array1OfPnt2d, 2>(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<gp_Pnt2d, gp_Vec2d, TColgp_Array1OfPnt2d, 2>(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<gp_Pnt2d, gp_Vec2d, TColgp_Array1OfPnt2d, 2>(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<gp_Pnt2d, gp_Vec2d, TColgp_Array1OfPnt2d, 2>(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<gp_Pnt2d, gp_Vec2d, TColgp_Array1OfPnt2d, 2>(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<gp_Pnt2d, gp_Vec2d, TColgp_Array1OfPnt2d, 2>(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<gp_Pnt2d, gp_Vec2d, TColgp_Array1OfPnt2d, 2>(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<gp_Pnt2d, gp_Vec2d, TColgp_Array1OfPnt2d, 2>(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<gp_Pnt2d, gp_Vec2d, TColgp_Array1OfPnt2d, 2>(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<gp_Pnt2d, gp_Vec2d, TColgp_Array1OfPnt2d, 2>(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<gp_Pnt2d, gp_Vec2d, TColgp_Array1OfPnt2d, 2>(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<gp_Pnt2d, gp_Vec2d, TColgp_Array1OfPnt2d, 2>(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<gp_Pnt2d, gp_Vec2d, TColgp_Array1OfPnt2d, 2>(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<gp_Pnt2d, gp_Vec2d, TColgp_Array1OfPnt2d, 2>(FunctionPtr,
+                                                                         BSplineDegree,
+                                                                         BSplineFlatKnots,
+                                                                         Poles,
+                                                                         FlatKnots,
+                                                                         NewDegree,
+                                                                         NewPoles,
+                                                                         theStatus);
+}
 
-#define BSplCLib_DataContainer BSplCLib_DataContainer_2d
+//==================================================================================================
 
-#include <BSplCLib_CurveComputation.gxx>
+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<gp_Pnt2d, gp_Vec2d, TColgp_Array1OfPnt2d, 2>(FunctionPtr,
+                                                                               BSplineDegree,
+                                                                               BSplineFlatKnots,
+                                                                               Poles,
+                                                                               FlatKnots,
+                                                                               NewDegree,
+                                                                               NewPoles,
+                                                                               theStatus);
+}
index 4cb55cf1c05b6afd2c2dc573132970cc3aba365a..417b275b62a5edcc3376fd418b1c75630b654538 100644 (file)
 
 #include <math_Matrix.hxx>
 
-//=======================================================================
-// 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
 
index 5888bd4a32078f30fdf4ffc860569007498f2f8b..2fbcd690a572a0ab807c5284c06034f920334302 100644 (file)
 
 // 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 <BSplCLib_CurveComputation.pxx>
 
-#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<gp_Pnt, gp_Vec, TColgp_Array1OfPnt, 3>(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<gp_Pnt, gp_Vec, TColgp_Array1OfPnt, 3>(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<gp_Pnt, gp_Vec, TColgp_Array1OfPnt, 3>(Degree,
+                                                              Periodic,
+                                                              Poles,
+                                                              Weights,
+                                                              Knots,
+                                                              Mults,
+                                                              AddKnots,
+                                                              AddMults,
+                                                              NewPoles,
+                                                              NewWeights,
+                                                              NewKnots,
+                                                              NewMults,
+                                                              Epsilon,
+                                                              Add);
+}
 
-#include <BSplCLib_CurveComputation.gxx>
+//==================================================================================================
+
+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<gp_Pnt, gp_Vec, TColgp_Array1OfPnt, 3>(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<gp_Pnt, gp_Vec, TColgp_Array1OfPnt, 3>(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<gp_Pnt, gp_Vec, TColgp_Array1OfPnt, 3>(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<gp_Pnt, gp_Vec, TColgp_Array1OfPnt, 3>(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<gp_Pnt, gp_Vec, TColgp_Array1OfPnt, 3>(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<gp_Pnt, gp_Vec, TColgp_Array1OfPnt, 3>(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<gp_Pnt, gp_Vec, TColgp_Array1OfPnt, 3>(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<gp_Pnt, gp_Vec, TColgp_Array1OfPnt, 3>(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<gp_Pnt, gp_Vec, TColgp_Array1OfPnt, 3>(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<gp_Pnt, gp_Vec, TColgp_Array1OfPnt, 3>(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<gp_Pnt, gp_Vec, TColgp_Array1OfPnt, 3>(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<gp_Pnt, gp_Vec, TColgp_Array1OfPnt, 3>(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<gp_Pnt, gp_Vec, TColgp_Array1OfPnt, 3>(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<gp_Pnt, gp_Vec, TColgp_Array1OfPnt, 3>(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<gp_Pnt, gp_Vec, TColgp_Array1OfPnt, 3>(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<gp_Pnt, gp_Vec, TColgp_Array1OfPnt, 3>(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<gp_Pnt, gp_Vec, TColgp_Array1OfPnt, 3>(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<gp_Pnt, gp_Vec, TColgp_Array1OfPnt, 3>(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<gp_Pnt, gp_Vec, TColgp_Array1OfPnt, 3>(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<gp_Pnt, gp_Vec, TColgp_Array1OfPnt, 3>(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<gp_Pnt, gp_Vec, TColgp_Array1OfPnt, 3>(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<gp_Pnt, gp_Vec, TColgp_Array1OfPnt, 3>(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<gp_Pnt, gp_Vec, TColgp_Array1OfPnt, 3>(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<gp_Pnt, gp_Vec, TColgp_Array1OfPnt, 3>(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<gp_Pnt, gp_Vec, TColgp_Array1OfPnt, 3>(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<gp_Pnt, gp_Vec, TColgp_Array1OfPnt, 3>(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<gp_Pnt, gp_Vec, TColgp_Array1OfPnt, 3>(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 (file)
index 874b174..0000000
+++ /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 <TColStd_Array1OfInteger.hxx>
-#include <TColStd_Array1OfReal.hxx>
-#include <TColStd_Array2OfReal.hxx>
-#include <gp_Vec2d.hxx>
-#include <Standard_ConstructionError.hxx>
-#include <PLib.hxx>
-#include <math_Matrix.hxx>
-
-//=======================================================================
-// 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;
-  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 (file)
index 0000000..5104fd7
--- /dev/null
@@ -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 <TColStd_Array1OfInteger.hxx>
+#include <TColStd_Array1OfReal.hxx>
+#include <TColStd_Array2OfReal.hxx>
+#include <gp_Vec2d.hxx>
+#include <Standard_ConstructionError.hxx>
+#include <PLib.hxx>
+#include <math_Matrix.hxx>
+
+// Template traits for 2D/3D point and vector operations
+template <typename Point, typename Vector, typename Array1OfPoints, Standard_Integer Dimension>
+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 <Standard_Integer Dimension>
+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 <typename Point, typename Vector, typename Array1OfPoints, Standard_Integer Dimension>
+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 <typename Point, typename Vector, typename Array1OfPoints, Standard_Integer Dimension>
+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 <typename Point, typename Vector, typename Array1OfPoints, Standard_Integer Dimension>
+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 <typename Point, typename Vector, typename Array1OfPoints, Standard_Integer Dimension>
+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<Point, Vector, Array1OfPoints, Dimension>(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 <typename Point, typename Vector, typename Array1OfPoints, Standard_Integer Dimension>
+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<Point, Vector, Array1OfPoints, Dimension>(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 <typename Point, typename Vector, typename Array1OfPoints, Standard_Integer Dimension>
+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 <typename Point, typename Vector, typename Array1OfPoints, Standard_Integer Dimension>
+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 <typename Point, typename Vector, typename Array1OfPoints, Standard_Integer Dimension>
+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 <typename Point, typename Vector, typename Array1OfPoints, Standard_Integer Dimension>
+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<Point, Vector, Array1OfPoints, Dimension>;
+
+  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 <typename Point, typename Vector, typename Array1OfPoints, Standard_Integer Dimension>
+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<Dimension>& 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<Point, Vector, Array1OfPoints, Dimension>(Degree,
+                                                                 index,
+                                                                 Poles,
+                                                                 Weights,
+                                                                 *dc.poles);
+  }
+  else
+  {
+    dim = Dimension;
+    BSplCLib_BuildEval<Point, Vector, Array1OfPoints, Dimension>(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 <typename Point, typename Vector, typename Array1OfPoints, Standard_Integer Dimension>
+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<Point, Vector, Array1OfPoints, Dimension>;
+
+  Standard_Integer                    dim, index = Index;
+  Standard_Real                       u = U;
+  Standard_Boolean                    rational;
+  BSplCLib_DataContainer_T<Dimension> dc(Degree);
+  PrepareEval_T<Point, Vector, Array1OfPoints, Dimension>(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 <typename Point, typename Vector, typename Array1OfPoints, Standard_Integer Dimension>
+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<Point, Vector, Array1OfPoints, Dimension>;
+
+  Standard_Integer                    dim, index = Index;
+  Standard_Real                       u = U;
+  Standard_Boolean                    rational;
+  BSplCLib_DataContainer_T<Dimension> dc(Degree);
+  PrepareEval_T<Point, Vector, Array1OfPoints, Dimension>(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 <typename Point, typename Vector, typename Array1OfPoints, Standard_Integer Dimension>
+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<Point, Vector, Array1OfPoints, Dimension>;
+
+  Standard_Integer                    dim, index = Index;
+  Standard_Real                       u = U;
+  Standard_Boolean                    rational;
+  BSplCLib_DataContainer_T<Dimension> dc(Degree);
+  PrepareEval_T<Point, Vector, Array1OfPoints, Dimension>(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 <typename Point, typename Vector, typename Array1OfPoints, Standard_Integer Dimension>
+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<Point, Vector, Array1OfPoints, Dimension>;
+
+  Standard_Integer                    dim, index = Index;
+  Standard_Real                       u = U;
+  Standard_Boolean                    rational;
+  BSplCLib_DataContainer_T<Dimension> dc(Degree);
+  PrepareEval_T<Point, Vector, Array1OfPoints, Dimension>(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 <typename Point, typename Vector, typename Array1OfPoints, Standard_Integer Dimension>
+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<Point, Vector, Array1OfPoints, Dimension>;
+
+  Standard_Integer                    dim, index = Index;
+  Standard_Real                       u = U;
+  Standard_Boolean                    rational;
+  BSplCLib_DataContainer_T<Dimension> dc(Degree);
+  PrepareEval_T<Point, Vector, Array1OfPoints, Dimension>(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 <typename Point, typename Vector, typename Array1OfPoints, Standard_Integer Dimension>
+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 <typename Point, typename Vector, typename Array1OfPoints, Standard_Integer Dimension>
+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 <typename Point, typename Vector, typename Array1OfPoints, Standard_Integer Dimension>
+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 <typename Point, typename Vector, typename Array1OfPoints, Standard_Integer Dimension>
+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<Point, Vector, Array1OfPoints, Dimension>;
+
+  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 <typename Point, typename Vector, typename Array1OfPoints, Standard_Integer Dimension>
+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<Point, Vector, Array1OfPoints, Dimension>;
+
+  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 <typename Point, typename Vector, typename Array1OfPoints, Standard_Integer Dimension>
+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<Point, Vector, Array1OfPoints, Dimension>;
+
+  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 <typename Point, typename Vector, typename Array1OfPoints, Standard_Integer Dimension>
+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<Point, Vector, Array1OfPoints, Dimension>;
+
+  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 <typename Point, typename Vector, typename Array1OfPoints, Standard_Integer Dimension>
+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<Point, Vector, Array1OfPoints, Dimension>;
+
+  Standard_Integer ii, LocalDimension, LocalIndex, index = 0;
+  Standard_Real    u = U, LocalValue;
+  Standard_Boolean rational;
+
+  BSplCLib_DataContainer_T<Dimension> dc(Degree);
+  PrepareEval_T<Point, Vector, Array1OfPoints, Dimension>(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 <typename Point, typename Vector, typename Array1OfPoints, Standard_Integer Dimension>
+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<Dimension> dc(theDegree);
+  PrepareEval_T<Point, Vector, Array1OfPoints, Dimension>(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 <typename Point, typename Vector, typename Array1OfPoints, Standard_Integer Dimension>
+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 <typename Point, typename Vector, typename Array1OfPoints, Standard_Integer Dimension>
+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 <typename Point, typename Vector, typename Array1OfPoints, Standard_Integer Dimension>
+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 <typename Point, typename Vector, typename Array1OfPoints, Standard_Integer Dimension>
+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;
+  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 <typename Point, typename Vector, typename Array1OfPoints, Standard_Integer Dimension>
+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 <typename Point, typename Vector, typename Array1OfPoints, Standard_Integer Dimension>
+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 <typename Point, typename Vector, typename Array1OfPoints, Standard_Integer Dimension>
+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
index 7fac5f8d8f48ff0a1bc09b869579a6e1b54b0556..aa1ec7f8390eaf5a54f5ee6686445ee298f70ef7 100644 (file)
@@ -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