Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
e5888e6
Modeing - BSpline Cache Optimised calls for Local (#906)
dpasukhi Dec 12, 2025
275eb42
Refactor Geom2d and Geom3d Packages - Remove GeomEvaluator Classes an…
dpasukhi Dec 14, 2025
553e2b9
Add Geom_ExtrusionUtils and Geom_RevolutionUtils for surface evaluations
dpasukhi Dec 14, 2025
7ec1981
Update copyright year in Geom_ExtrusionUtils and Geom_RevolutionUtils…
dpasukhi Dec 14, 2025
9859909
Refactor GeomAdaptor_Surface to consolidate surface evaluation data s…
dpasukhi Dec 14, 2025
9cc6f9f
Refactor Geom2dAdaptor to unify offset curve data structures
dpasukhi Dec 14, 2025
a41fa0e
Refactor Geom2dAdaptor_Curve to enhance curve data handling
dpasukhi Dec 14, 2025
228f2eb
// formatting
dpasukhi Dec 14, 2025
c3998c1
Add gp_Ax1 include to ShapeUpgrade_SplitSurface for surface splitting…
dpasukhi Dec 14, 2025
e4be45d
Refactor Geom Offset Utilities for Enhanced Curve and Surface Calcula…
dpasukhi Dec 14, 2025
03e2fa9
Refactor Geom Extrusion and Revolution Utilities for Consistency and …
dpasukhi Dec 14, 2025
e7a0033
Enhance Offset Utilities for Curve and Surface Evaluations
dpasukhi Dec 14, 2025
12333e6
Implement ReplaceDerivative function in Geom_OffsetSurfaceUtils to ha…
dpasukhi Dec 14, 2025
0943d13
Refactor Geom_OffsetSurface for Improved Derivative Evaluations
dpasukhi Dec 14, 2025
f502785
Refactor GeomAdaptor_Surface for Improved Readability and Consistency
dpasukhi Dec 14, 2025
385eaf5
Refactor Geom_OffsetCurve for Enhanced Derivative Evaluations
dpasukhi Dec 14, 2025
62e5fa6
Enhance Error Handling in Geom_OffsetCurve and GeomAdaptor_Curve
dpasukhi Dec 14, 2025
b25156c
Refactor Geom2d_OffsetCurve and Geom2dAdaptor_Curve for Improved Offs…
dpasukhi Dec 14, 2025
622433b
Refactor Geom2d_OffsetCurve and Geom2dAdaptor_Curve for Enhanced Deri…
dpasukhi Dec 14, 2025
b66e3a7
Refactor Geom_OffsetCurve and GeomAdaptor_Curve for Improved Derivati…
dpasukhi Dec 14, 2025
15e1fe7
Refactor Derivative Calculations in Geom2d_OffsetUtils for Improved C…
dpasukhi Dec 14, 2025
c98e340
Enhance Derivative Evaluation in Geom_OffsetCurveUtils and Geom_Revol…
dpasukhi Dec 15, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
182 changes: 120 additions & 62 deletions src/FoundationClasses/TKMath/BSplCLib/BSplCLib_Cache.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@

IMPLEMENT_STANDARD_RTTIEXT(BSplCLib_Cache, Standard_Transient)

//==================================================================================================

BSplCLib_Cache::BSplCLib_Cache(
const Standard_Integer& theDegree,
const Standard_Boolean& thePeriodic,
Expand All @@ -33,6 +35,8 @@ BSplCLib_Cache::BSplCLib_Cache(
{
}

//==================================================================================================

BSplCLib_Cache::BSplCLib_Cache(
const Standard_Integer& theDegree,
const Standard_Boolean& thePeriodic,
Expand All @@ -45,11 +49,15 @@ BSplCLib_Cache::BSplCLib_Cache(
{
}

//==================================================================================================

Standard_Boolean BSplCLib_Cache::IsCacheValid(Standard_Real theParameter) const
{
return myParams.IsCacheValid(theParameter);
}

//==================================================================================================

void BSplCLib_Cache::BuildCache(const Standard_Real& theParameter,
const TColStd_Array1OfReal& theFlatKnots,
const TColgp_Array1OfPnt2d& thePoles2d,
Expand Down Expand Up @@ -106,60 +114,77 @@ void BSplCLib_Cache::BuildCache(const Standard_Real& theParameter,
aPolesWeights);
}

void BSplCLib_Cache::CalculateDerivative(const Standard_Real& theParameter,
const Standard_Integer& theDerivative,
Standard_Real& theDerivArray) const
//==================================================================================================

void BSplCLib_Cache::calculateDerivative(double theParameter,
int theDerivative,
Standard_Real* theDerivArray) const
{
Standard_Real aNewParameter = myParams.PeriodicNormalization(theParameter);
aNewParameter = (aNewParameter - myParams.SpanStart) / myParams.SpanLength;
double aLocalParam = myParams.PeriodicNormalization(theParameter);
aLocalParam = (aLocalParam - myParams.SpanStart) / myParams.SpanLength;
calculateDerivativeLocal(aLocalParam, theDerivative, theDerivArray);
}

Standard_Real* aPolesArray = const_cast<Standard_Real*>(myPolesWeightsBuffer);
const Standard_Integer aDimension = myRowLength;
//==================================================================================================

void BSplCLib_Cache::calculateDerivativeLocal(double theLocalParam,
int theDerivative,
Standard_Real* theDerivArray) const
{
const int aDimension = myRowLength;

// Temporary container. The maximal size of this container is defined by:
// 1) maximal derivative for cache evaluation, which is 3, plus one row for function values,
// 2) and maximal dimension of the point, which is 3, plus one column for weights.
Standard_Real aTmpContainer[16];

// When the PLib::RationaDerivative needs to be called, use temporary container
Standard_Real* aPntDeriv = myIsRational ? aTmpContainer : &theDerivArray;
// When the PLib::RationalDerivative needs to be called, use temporary container
Standard_Real* aPntDeriv = myIsRational ? aTmpContainer : theDerivArray;

// When the degree of curve is lesser than the requested derivative,
// nullify array cells corresponding to greater derivatives
Standard_Integer aDerivative = theDerivative;
int aDerivative = theDerivative;
if (!myIsRational && myParams.Degree < theDerivative)
{
aDerivative = myParams.Degree;
for (Standard_Integer ind = myParams.Degree * aDimension;
ind < (theDerivative + 1) * aDimension;
ind++)
for (int ind = myParams.Degree * aDimension; ind < (theDerivative + 1) * aDimension; ind++)
{
aPntDeriv[ind] = 0.0;
// clang-format off
(&theDerivArray)[ind] = 0.0; // should be cleared separately, because aPntDeriv may look to another memory area
// clang-format on
}
}

PLib::EvalPolynomial(aNewParameter,
PLib::EvalPolynomial(theLocalParam,
aDerivative,
myParams.Degree,
aDimension,
aPolesArray[0],
myPolesWeightsBuffer[0],
aPntDeriv[0]);

// Unnormalize derivatives since those are computed normalized
// Use division by SpanLength instead of multiplication by precomputed inverse
// for better numerical stability with very small span lengths
Standard_Real aFactor = 1.0;
for (Standard_Integer deriv = 1; deriv <= aDerivative; deriv++)
for (int deriv = 1; deriv <= aDerivative; deriv++)
{
aFactor /= myParams.SpanLength;
for (Standard_Integer ind = 0; ind < aDimension; ind++)
for (int ind = 0; ind < aDimension; ind++)
{
aPntDeriv[aDimension * deriv + ind] *= aFactor;
}
}

if (myIsRational) // calculate derivatives divided by weights derivatives
PLib::RationalDerivative(aDerivative, aDerivative, aDimension - 1, aPntDeriv[0], theDerivArray);
if (myIsRational)
{
PLib::RationalDerivative(aDerivative,
aDerivative,
aDimension - 1,
aPntDeriv[0],
theDerivArray[0]);
}
}

//==================================================================================================

void BSplCLib_Cache::D0(const Standard_Real& theParameter, gp_Pnt2d& thePoint) const
{
Standard_Real aNewParameter = myParams.PeriodicNormalization(theParameter);
Expand All @@ -181,25 +206,34 @@ void BSplCLib_Cache::D0(const Standard_Real& theParameter, gp_Pnt2d& thePoint) c
thePoint.ChangeCoord().Divide(aPoint[2]);
}

//==================================================================================================

void BSplCLib_Cache::D0(const Standard_Real& theParameter, gp_Pnt& thePoint) const
{
Standard_Real aNewParameter = myParams.PeriodicNormalization(theParameter);
aNewParameter = (aNewParameter - myParams.SpanStart) / myParams.SpanLength;
Standard_Real aLocalParam = myParams.PeriodicNormalization(theParameter);
aLocalParam = (aLocalParam - myParams.SpanStart) / myParams.SpanLength;
D0Local(aLocalParam, thePoint);
}

Standard_Real* aPolesArray = const_cast<Standard_Real*>(myPolesWeightsBuffer);
Standard_Real aPoint[4];
const Standard_Integer aDimension = myRowLength;
//==================================================================================================

PLib::NoDerivativeEvalPolynomial(aNewParameter,
void BSplCLib_Cache::D0Local(double theLocalParam, gp_Pnt& thePoint) const
{
// theLocalParam is already computed as (param - SpanStart) / SpanLength
Standard_Real aPoint[4];

PLib::NoDerivativeEvalPolynomial(theLocalParam,
myParams.Degree,
aDimension,
myParams.Degree * aDimension,
aPolesArray[0],
myRowLength,
myParams.Degree * myRowLength,
myPolesWeightsBuffer[0],
aPoint[0]);

thePoint.SetCoord(aPoint[0], aPoint[1], aPoint[2]);
if (myIsRational)
{
thePoint.ChangeCoord().Divide(aPoint[3]);
}
}

void BSplCLib_Cache::D1(const Standard_Real& theParameter,
Expand All @@ -209,7 +243,7 @@ void BSplCLib_Cache::D1(const Standard_Real& theParameter,
Standard_Integer aDimension = myRowLength;
Standard_Real aPntDeriv[8]; // result storage (point and derivative coordinates)

this->CalculateDerivative(theParameter, 1, aPntDeriv[0]);
calculateDerivative(theParameter, 1, aPntDeriv);
if (myIsRational) // the size of aPntDeriv was changed by PLib::RationalDerivative
aDimension -= 1;

Expand All @@ -221,15 +255,21 @@ void BSplCLib_Cache::D1(const Standard_Real& theParameter,
gp_Pnt& thePoint,
gp_Vec& theTangent) const
{
Standard_Integer aDimension = myRowLength;
Standard_Real aPntDeriv[8]; // result storage (point and derivative coordinates)
Standard_Real aLocalParam = myParams.PeriodicNormalization(theParameter);
aLocalParam = (aLocalParam - myParams.SpanStart) / myParams.SpanLength;
D1Local(aLocalParam, thePoint, theTangent);
}

this->CalculateDerivative(theParameter, 1, aPntDeriv[0]);
if (myIsRational) // the size of aPntDeriv was changed by PLib::RationalDerivative
aDimension -= 1;
//==================================================================================================

thePoint.SetCoord(aPntDeriv[0], aPntDeriv[1], aPntDeriv[2]);
theTangent.SetCoord(aPntDeriv[aDimension], aPntDeriv[aDimension + 1], aPntDeriv[aDimension + 2]);
void BSplCLib_Cache::D1Local(double theLocalParam, gp_Pnt& thePoint, gp_Vec& theTangent) const
{
Standard_Real aDerivArray[8];
calculateDerivativeLocal(theLocalParam, 1, aDerivArray);

const int aDim = myIsRational ? myRowLength - 1 : myRowLength;
thePoint.SetCoord(aDerivArray[0], aDerivArray[1], aDerivArray[2]);
theTangent.SetCoord(aDerivArray[aDim], aDerivArray[aDim + 1], aDerivArray[aDim + 2]);
}

void BSplCLib_Cache::D2(const Standard_Real& theParameter,
Expand All @@ -240,7 +280,7 @@ void BSplCLib_Cache::D2(const Standard_Real& theParameter,
Standard_Integer aDimension = myRowLength;
Standard_Real aPntDeriv[12]; // result storage (point and derivatives coordinates)

this->CalculateDerivative(theParameter, 2, aPntDeriv[0]);
calculateDerivative(theParameter, 2, aPntDeriv);
if (myIsRational) // the size of aPntDeriv was changed by PLib::RationalDerivative
aDimension -= 1;

Expand All @@ -254,18 +294,26 @@ void BSplCLib_Cache::D2(const Standard_Real& theParameter,
gp_Vec& theTangent,
gp_Vec& theCurvature) const
{
Standard_Integer aDimension = myRowLength;
Standard_Real aPntDeriv[12]; // result storage (point and derivatives coordinates)
Standard_Real aLocalParam = myParams.PeriodicNormalization(theParameter);
aLocalParam = (aLocalParam - myParams.SpanStart) / myParams.SpanLength;
D2Local(aLocalParam, thePoint, theTangent, theCurvature);
}

this->CalculateDerivative(theParameter, 2, aPntDeriv[0]);
if (myIsRational) // the size of aPntDeriv was changed by PLib::RationalDerivative
aDimension -= 1;
//==================================================================================================

thePoint.SetCoord(aPntDeriv[0], aPntDeriv[1], aPntDeriv[2]);
theTangent.SetCoord(aPntDeriv[aDimension], aPntDeriv[aDimension + 1], aPntDeriv[aDimension + 2]);
theCurvature.SetCoord(aPntDeriv[aDimension << 1],
aPntDeriv[(aDimension << 1) + 1],
aPntDeriv[(aDimension << 1) + 2]);
void BSplCLib_Cache::D2Local(double theLocalParam,
gp_Pnt& thePoint,
gp_Vec& theTangent,
gp_Vec& theCurvature) const
{
Standard_Real aDerivArray[12];
calculateDerivativeLocal(theLocalParam, 2, aDerivArray);

const int aDim = myIsRational ? myRowLength - 1 : myRowLength;
const int aShift = aDim << 1;
thePoint.SetCoord(aDerivArray[0], aDerivArray[1], aDerivArray[2]);
theTangent.SetCoord(aDerivArray[aDim], aDerivArray[aDim + 1], aDerivArray[aDim + 2]);
theCurvature.SetCoord(aDerivArray[aShift], aDerivArray[aShift + 1], aDerivArray[aShift + 2]);
}

void BSplCLib_Cache::D3(const Standard_Real& theParameter,
Expand All @@ -277,7 +325,7 @@ void BSplCLib_Cache::D3(const Standard_Real& theParameter,
Standard_Integer aDimension = myRowLength;
Standard_Real aPntDeriv[16]; // result storage (point and derivatives coordinates)

this->CalculateDerivative(theParameter, 3, aPntDeriv[0]);
calculateDerivative(theParameter, 3, aPntDeriv);
if (myIsRational) // the size of aPntDeriv was changed by PLib::RationalDerivative
aDimension -= 1;

Expand All @@ -295,17 +343,27 @@ void BSplCLib_Cache::D3(const Standard_Real& theParameter,
gp_Vec& theCurvature,
gp_Vec& theTorsion) const
{
Standard_Integer aDimension = myRowLength;
Standard_Real aPntDeriv[16]; // result storage (point and derivatives coordinates)
Standard_Real aLocalParam = myParams.PeriodicNormalization(theParameter);
aLocalParam = (aLocalParam - myParams.SpanStart) / myParams.SpanLength;
D3Local(aLocalParam, thePoint, theTangent, theCurvature, theTorsion);
}

this->CalculateDerivative(theParameter, 3, aPntDeriv[0]);
if (myIsRational) // the size of aPntDeriv was changed by PLib::RationalDerivative
aDimension -= 1;
//==================================================================================================

thePoint.SetCoord(aPntDeriv[0], aPntDeriv[1], aPntDeriv[2]);
theTangent.SetCoord(aPntDeriv[aDimension], aPntDeriv[aDimension + 1], aPntDeriv[aDimension + 2]);
Standard_Integer aShift = aDimension << 1;
theCurvature.SetCoord(aPntDeriv[aShift], aPntDeriv[aShift + 1], aPntDeriv[aShift + 2]);
aShift += aDimension;
theTorsion.SetCoord(aPntDeriv[aShift], aPntDeriv[aShift + 1], aPntDeriv[aShift + 2]);
void BSplCLib_Cache::D3Local(double theLocalParam,
gp_Pnt& thePoint,
gp_Vec& theTangent,
gp_Vec& theCurvature,
gp_Vec& theTorsion) const
{
Standard_Real aDerivArray[16];
calculateDerivativeLocal(theLocalParam, 3, aDerivArray);

const int aDim = myIsRational ? myRowLength - 1 : myRowLength;
const int aShift2 = aDim << 1;
const int aShift3 = aShift2 + aDim;
thePoint.SetCoord(aDerivArray[0], aDerivArray[1], aDerivArray[2]);
theTangent.SetCoord(aDerivArray[aDim], aDerivArray[aDim + 1], aDerivArray[aDim + 2]);
theCurvature.SetCoord(aDerivArray[aShift2], aDerivArray[aShift2 + 1], aDerivArray[aShift2 + 2]);
theTorsion.SetCoord(aDerivArray[aShift3], aDerivArray[aShift3 + 1], aDerivArray[aShift3 + 2]);
}
65 changes: 54 additions & 11 deletions src/FoundationClasses/TKMath/BSplCLib/BSplCLib_Cache.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -122,22 +122,65 @@ public:
gp_Vec& theCurvature,
gp_Vec& theTorsion) const;

//! Calculates the 3D point using pre-computed local parameter in [0, 1] range.
//! This bypasses periodic normalization and local parameter calculation.
//! @param[in] theLocalParam pre-computed local parameter: (Param - SpanStart) / SpanLength
//! @param[out] thePoint the result of calculation (the point on the curve)
Standard_EXPORT void D0Local(double theLocalParam, gp_Pnt& thePoint) const;

//! Calculates the 3D point and first derivative using pre-computed local parameter.
//! @param[in] theLocalParam pre-computed local parameter: (Param - SpanStart) / SpanLength
//! @param[out] thePoint the point on the curve
//! @param[out] theTangent first derivative (tangent vector)
Standard_EXPORT void D1Local(double theLocalParam, gp_Pnt& thePoint, gp_Vec& theTangent) const;

//! Calculates the 3D point, first and second derivatives using pre-computed local parameter.
//! @param[in] theLocalParam pre-computed local parameter: (Param - SpanStart) / SpanLength
//! @param[out] thePoint the point on the curve
//! @param[out] theTangent first derivative (tangent vector)
//! @param[out] theCurvature second derivative (curvature vector)
Standard_EXPORT void D2Local(double theLocalParam,
gp_Pnt& thePoint,
gp_Vec& theTangent,
gp_Vec& theCurvature) const;

//! Calculates the 3D point, first, second and third derivatives using pre-computed local
//! parameter.
//! @param[in] theLocalParam pre-computed local parameter: (Param - SpanStart) / SpanLength
//! @param[out] thePoint the point on the curve
//! @param[out] theTangent first derivative (tangent vector)
//! @param[out] theCurvature second derivative (curvature vector)
//! @param[out] theTorsion third derivative (torsion vector)
Standard_EXPORT void D3Local(double theLocalParam,
gp_Pnt& thePoint,
gp_Vec& theTangent,
gp_Vec& theCurvature,
gp_Vec& theTorsion) const;

DEFINE_STANDARD_RTTIEXT(BSplCLib_Cache, Standard_Transient)

protected:
//! Fills array of derivatives in the selected point of the curve
//! \param[in] theParameter parameter of the calculation
//! \param[in] theDerivative maximal derivative to be calculated (computes all derivatives lesser
//! than specified) \param[out] theDerivArray result array of derivatives (with size
//! (theDerivative+1)*(PntDim+1),
//! where PntDim = 2 or 3 is a dimension of the curve)
void CalculateDerivative(const Standard_Real& theParameter,
const Standard_Integer& theDerivative,
Standard_Real& theDerivArray) const;
//! Fills array of derivatives in the selected point of the curve.
//! @param[in] theParameter parameter of the calculation
//! @param[in] theDerivative maximal derivative to be calculated (computes all derivatives
//! lesser than specified)
//! @param[out] theDerivArray result array of derivatives with size (theDerivative+1)*(PntDim+1),
//! where PntDim = 2 or 3 is a dimension of the curve
void calculateDerivative(double theParameter,
int theDerivative,
Standard_Real* theDerivArray) const;

//! Fills array of derivatives using pre-computed local parameter.
//! @param[in] theLocalParam pre-computed local parameter: (Param - SpanStart) / SpanLength
//! @param[in] theDerivative maximal derivative to be calculated (1, 2, or 3)
//! @param[out] theDerivArray result array of derivatives
void calculateDerivativeLocal(double theLocalParam,
int theDerivative,
Standard_Real* theDerivArray) const;

// copying is prohibited
BSplCLib_Cache(const BSplCLib_Cache&);
void operator=(const BSplCLib_Cache&);
BSplCLib_Cache(const BSplCLib_Cache&) = delete;
void operator=(const BSplCLib_Cache&) = delete;

private:
// clang-format off
Expand Down
Loading
Loading