mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-08-09 13:22:24 +03:00
0024682: Move out B-spline cache from curves and surfaces to dedicated classes BSplCLib_Cache and BSplSLib_Cache
1. B-spline cache was moved into separated classes: BSplCLib_Cache for 2D and 3D curves and BSplSLib_Cache for surfaces. 2. The cache is used now in corresponding adaptor classes (Geom2dAdaptor_Curve, GeomAdaptor_Curve and GeomAdaptor_Surface) when the curve or surface is a B-spline. 3. Algorithms were changed to use adaptors for B-spline calculations instead of curves or surfaces. 4. Precised calculation of derivatives of surface of revolution is implemented for the points of surface placed on the axis of revolution (Geom_SurfaceOfRevolution.cxx) 5. Small modifications are made to adjust algorithms to new behavior of B-spline calculation. 6. Test cases were modified according to the modern behavior. 7. Changes in BOPAlgo_WireSplitter, BOPTools_AlgoTools, BRepLib_CheckCurveOnSurface and ShapeAnalysis_Wire to use adaptors instead of geometric entities 8. Allow Geom2dAdaptor and GeomAdaptor in case of offset curve to use corresponding adaptor for basis curve Modification of test-cases according to the new behavior.
This commit is contained in:
@@ -104,6 +104,8 @@ uses TColStd, gp, TColgp, math, GeomAbs
|
||||
|
||||
|
||||
is
|
||||
|
||||
imported transient class Cache;
|
||||
|
||||
imported EvaluatorFunction ;
|
||||
|
||||
@@ -2063,6 +2065,30 @@ is
|
||||
-- If rational computes the homogeneous Taylor expension
|
||||
-- for the numerator and stores it in CachePoles
|
||||
|
||||
BuildCache(theParameter : Real;
|
||||
theSpanDomain : Real;
|
||||
thePeriodicFlag : Boolean ;
|
||||
theDegree : Integer;
|
||||
theFlatKnots : Array1OfReal from TColStd ;
|
||||
thePoles : Array1OfPnt from TColgp;
|
||||
theWeights : Array1OfReal from TColStd ;
|
||||
theCacheArray : in out Array2OfReal from TColStd) ;
|
||||
---Purpose: Perform the evaluation of the Taylor expansion
|
||||
-- of the Bspline normalized between 0 and 1.
|
||||
-- Structure of result optimized for BSplCLib_Cache.
|
||||
|
||||
BuildCache(theParameter : Real;
|
||||
theSpanDomain : Real;
|
||||
thePeriodicFlag : Boolean ;
|
||||
theDegree : Integer;
|
||||
theFlatKnots : Array1OfReal from TColStd ;
|
||||
thePoles : Array1OfPnt2d from TColgp;
|
||||
theWeights : Array1OfReal from TColStd ;
|
||||
theCacheArray : in out Array2OfReal from TColStd) ;
|
||||
---Purpose: Perform the evaluation of the Taylor expansion
|
||||
-- of the Bspline normalized between 0 and 1.
|
||||
-- Structure of result optimized for BSplCLib_Cache.
|
||||
|
||||
PolesCoefficients(Poles : Array1OfPnt2d from TColgp;
|
||||
CachePoles : in out Array1OfPnt2d from TColgp);
|
||||
---Warning: To be used for Beziercurves ONLY!!!
|
||||
@@ -2454,6 +2480,7 @@ is
|
||||
-- all u1 and u0 in the domain of the curve f(u)
|
||||
-- | u1 - u0 | < UTolerance and
|
||||
-- we have |f (u1) - f (u0)| < Tolerance3D
|
||||
|
||||
|
||||
end BSplCLib;
|
||||
|
||||
|
@@ -73,6 +73,7 @@ void BSplCLib::Hunt (const Array1OfReal& XX,
|
||||
{
|
||||
// replaced by simple dichotomy (RLE)
|
||||
Ilc = XX.Lower();
|
||||
if (XX.Length() <= 1) return;
|
||||
const Standard_Real *px = &XX(Ilc);
|
||||
px -= Ilc;
|
||||
|
||||
|
362
src/BSplCLib/BSplCLib_Cache.cxx
Normal file
362
src/BSplCLib/BSplCLib_Cache.cxx
Normal file
@@ -0,0 +1,362 @@
|
||||
// Copyright (c) 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.
|
||||
|
||||
#include <BSplCLib_Cache.hxx>
|
||||
#include <BSplCLib.hxx>
|
||||
|
||||
#include <NCollection_LocalArray.hxx>
|
||||
|
||||
#include <TColgp_HArray1OfPnt.hxx>
|
||||
#include <TColgp_HArray1OfPnt2d.hxx>
|
||||
#include <TColStd_HArray1OfReal.hxx>
|
||||
#include <TColStd_HArray2OfReal.hxx>
|
||||
|
||||
IMPLEMENT_STANDARD_HANDLE(BSplCLib_Cache, Standard_Transient)
|
||||
IMPLEMENT_STANDARD_RTTIEXT(BSplCLib_Cache, Standard_Transient)
|
||||
|
||||
//! Converts handle of array of Standard_Real into the pointer to Standard_Real
|
||||
static Standard_Real* ConvertArray(const Handle_TColStd_HArray2OfReal& theHArray)
|
||||
{
|
||||
const TColStd_Array2OfReal& anArray = theHArray->Array2();
|
||||
return (Standard_Real*) &(anArray(anArray.LowerRow(), anArray.LowerCol()));
|
||||
}
|
||||
|
||||
|
||||
BSplCLib_Cache::BSplCLib_Cache()
|
||||
{
|
||||
myPolesWeights.Nullify();
|
||||
myIsRational = Standard_False;
|
||||
mySpanStart = 0.0;
|
||||
mySpanLength = 0.0;
|
||||
mySpanIndex = 0;
|
||||
myDegree = 0;
|
||||
myFlatKnots.Nullify();
|
||||
}
|
||||
|
||||
BSplCLib_Cache::BSplCLib_Cache(const Standard_Integer& theDegree,
|
||||
const Standard_Boolean& thePeriodic,
|
||||
const TColStd_Array1OfReal& theFlatKnots,
|
||||
const TColgp_Array1OfPnt2d& thePoles2d,
|
||||
const TColStd_Array1OfReal& theWeights)
|
||||
{
|
||||
Standard_Real aCacheParam = theFlatKnots.Value(theFlatKnots.Lower() + theDegree);
|
||||
BuildCache(aCacheParam, theDegree, thePeriodic,
|
||||
theFlatKnots, thePoles2d, theWeights);
|
||||
}
|
||||
|
||||
BSplCLib_Cache::BSplCLib_Cache(const Standard_Integer& theDegree,
|
||||
const Standard_Boolean& thePeriodic,
|
||||
const TColStd_Array1OfReal& theFlatKnots,
|
||||
const TColgp_Array1OfPnt& thePoles,
|
||||
const TColStd_Array1OfReal& theWeights)
|
||||
{
|
||||
Standard_Real aCacheParam = theFlatKnots.Value(theFlatKnots.Lower() + theDegree);
|
||||
BuildCache(aCacheParam, theDegree, thePeriodic,
|
||||
theFlatKnots, thePoles, theWeights);
|
||||
}
|
||||
|
||||
|
||||
Standard_Boolean BSplCLib_Cache::IsCacheValid(Standard_Real theParameter) const
|
||||
{
|
||||
Standard_Real aNewParam = theParameter;
|
||||
if (!myFlatKnots.IsNull())
|
||||
PeriodicNormalization(myFlatKnots->Array1(), aNewParam);
|
||||
|
||||
Standard_Real aDelta = aNewParam - mySpanStart;
|
||||
return (aDelta >= 0.0 && (aDelta < mySpanLength || mySpanIndex == mySpanIndexMax));
|
||||
}
|
||||
|
||||
void BSplCLib_Cache::PeriodicNormalization(const TColStd_Array1OfReal& theFlatKnots,
|
||||
Standard_Real& theParameter) const
|
||||
{
|
||||
Standard_Real aPeriod = theFlatKnots.Value(theFlatKnots.Upper() - myDegree) -
|
||||
theFlatKnots.Value(myDegree + 1) ;
|
||||
if (theParameter < theFlatKnots.Value(myDegree + 1))
|
||||
{
|
||||
Standard_Real aScale = IntegerPart(
|
||||
(theFlatKnots.Value(myDegree + 1) - theParameter) / aPeriod);
|
||||
theParameter += aPeriod * (aScale + 1.0);
|
||||
}
|
||||
if (theParameter > theFlatKnots.Value(theFlatKnots.Upper() - myDegree))
|
||||
{
|
||||
Standard_Real aScale = IntegerPart(
|
||||
(theParameter - theFlatKnots.Value(theFlatKnots.Upper() - myDegree)) / aPeriod);
|
||||
theParameter -= aPeriod * (aScale + 1.0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void BSplCLib_Cache::BuildCache(const Standard_Real& theParameter,
|
||||
const Standard_Integer& theDegree,
|
||||
const Standard_Boolean& thePeriodic,
|
||||
const TColStd_Array1OfReal& theFlatKnots,
|
||||
const TColgp_Array1OfPnt2d& thePoles2d,
|
||||
const TColStd_Array1OfReal& theWeights)
|
||||
{
|
||||
// Normalize theParameter for periodical B-splines
|
||||
Standard_Real aNewParam = theParameter;
|
||||
if (thePeriodic)
|
||||
{
|
||||
PeriodicNormalization(theFlatKnots, aNewParam);
|
||||
myFlatKnots = new TColStd_HArray1OfReal(1, theFlatKnots.Length());
|
||||
myFlatKnots->ChangeArray1() = theFlatKnots;
|
||||
}
|
||||
else if (!myFlatKnots.IsNull()) // Periodical curve became non-periodical
|
||||
myFlatKnots.Nullify();
|
||||
|
||||
// Change the size of cached data if needed
|
||||
myIsRational = (&theWeights != NULL);
|
||||
Standard_Integer aPWColNumber = myIsRational ? 3 : 2;
|
||||
if (theDegree > myDegree)
|
||||
myPolesWeights = new TColStd_HArray2OfReal(1, theDegree + 1, 1, aPWColNumber);
|
||||
|
||||
myDegree = theDegree;
|
||||
mySpanIndex = 0;
|
||||
BSplCLib::LocateParameter(theDegree, theFlatKnots, BSplCLib::NoMults(),
|
||||
aNewParam, thePeriodic, mySpanIndex, aNewParam);
|
||||
mySpanStart = theFlatKnots.Value(mySpanIndex);
|
||||
mySpanLength = theFlatKnots.Value(mySpanIndex + 1) - mySpanStart;
|
||||
mySpanIndexMax = theFlatKnots.Length() - 1 - theDegree;
|
||||
|
||||
// Calculate new cache data
|
||||
BSplCLib::BuildCache(mySpanStart, mySpanLength, thePeriodic, theDegree,
|
||||
theFlatKnots, thePoles2d, theWeights,
|
||||
myPolesWeights->ChangeArray2());
|
||||
}
|
||||
|
||||
void BSplCLib_Cache::BuildCache(const Standard_Real& theParameter,
|
||||
const Standard_Integer& theDegree,
|
||||
const Standard_Boolean& thePeriodic,
|
||||
const TColStd_Array1OfReal& theFlatKnots,
|
||||
const TColgp_Array1OfPnt& thePoles,
|
||||
const TColStd_Array1OfReal& theWeights)
|
||||
{
|
||||
// Create list of knots with repetitions and normalize theParameter for periodical B-splines
|
||||
Standard_Real aNewParam = theParameter;
|
||||
if (thePeriodic)
|
||||
{
|
||||
PeriodicNormalization(theFlatKnots, aNewParam);
|
||||
myFlatKnots = new TColStd_HArray1OfReal(1, theFlatKnots.Length());
|
||||
myFlatKnots->ChangeArray1() = theFlatKnots;
|
||||
}
|
||||
else if (!myFlatKnots.IsNull()) // Periodical curve became non-periodical
|
||||
myFlatKnots.Nullify();
|
||||
|
||||
// Change the size of cached data if needed
|
||||
myIsRational = (&theWeights != NULL);
|
||||
Standard_Integer aPWColNumber = myIsRational ? 4 : 3;
|
||||
if (theDegree > myDegree)
|
||||
myPolesWeights = new TColStd_HArray2OfReal(1, theDegree + 1, 1, aPWColNumber);
|
||||
|
||||
myDegree = theDegree;
|
||||
mySpanIndex = 0;
|
||||
BSplCLib::LocateParameter(theDegree, theFlatKnots, BSplCLib::NoMults(),
|
||||
aNewParam, thePeriodic, mySpanIndex, aNewParam);
|
||||
mySpanStart = theFlatKnots.Value(mySpanIndex);
|
||||
mySpanLength = theFlatKnots.Value(mySpanIndex + 1) - mySpanStart;
|
||||
mySpanIndexMax = theFlatKnots.Length() - 1 - theDegree;
|
||||
|
||||
// Calculate new cache data
|
||||
BSplCLib::BuildCache(mySpanStart, mySpanLength, thePeriodic, theDegree,
|
||||
theFlatKnots, thePoles, theWeights,
|
||||
myPolesWeights->ChangeArray2());
|
||||
}
|
||||
|
||||
|
||||
void BSplCLib_Cache::CalculateDerivative(const Standard_Real& theParameter,
|
||||
const Standard_Integer& theDerivative,
|
||||
Standard_Real& theDerivArray) const
|
||||
{
|
||||
Standard_Real aNewParameter = theParameter;
|
||||
if (!myFlatKnots.IsNull()) // B-spline is periodical
|
||||
PeriodicNormalization(myFlatKnots->Array1(), aNewParameter);
|
||||
aNewParameter = (aNewParameter - mySpanStart) / mySpanLength;
|
||||
|
||||
Standard_Real* aPolesArray = ConvertArray(myPolesWeights);
|
||||
Standard_Integer aDimension = myPolesWeights->RowLength(); // number of columns
|
||||
|
||||
// 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 degree of curve is lesser than the requested derivative,
|
||||
// nullify array cells corresponding to greater derivatives
|
||||
Standard_Integer aDerivative = theDerivative;
|
||||
if (myDegree < theDerivative)
|
||||
{
|
||||
aDerivative = myDegree;
|
||||
for (Standard_Integer ind = myDegree * aDimension; ind < (theDerivative + 1) * aDimension; ind++)
|
||||
{
|
||||
aPntDeriv[ind] = 0.0;
|
||||
(&theDerivArray)[ind] = 0.0; // should be cleared separately, because aPntDeriv may look to another memory area
|
||||
}
|
||||
}
|
||||
|
||||
PLib::EvalPolynomial(aNewParameter, aDerivative, myDegree, aDimension,
|
||||
aPolesArray[0], aPntDeriv[0]);
|
||||
// Unnormalize derivatives since those are computed normalized
|
||||
Standard_Real aFactor = 1.0;
|
||||
for (Standard_Integer deriv = 1; deriv <= aDerivative; deriv++)
|
||||
{
|
||||
aFactor /= mySpanLength;
|
||||
for (Standard_Integer 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);
|
||||
}
|
||||
|
||||
|
||||
void BSplCLib_Cache::D0(const Standard_Real& theParameter, gp_Pnt2d& thePoint) const
|
||||
{
|
||||
Standard_Real aNewParameter = theParameter;
|
||||
if (!myFlatKnots.IsNull()) // B-spline is periodical
|
||||
PeriodicNormalization(myFlatKnots->Array1(), aNewParameter);
|
||||
aNewParameter = (aNewParameter - mySpanStart) / mySpanLength;
|
||||
|
||||
Standard_Real* aPolesArray = ConvertArray(myPolesWeights);
|
||||
Standard_Real aPoint[4];
|
||||
Standard_Integer aDimension = myPolesWeights->RowLength(); // number of columns
|
||||
|
||||
PLib::NoDerivativeEvalPolynomial(aNewParameter, myDegree,
|
||||
aDimension, myDegree * aDimension,
|
||||
aPolesArray[0], aPoint[0]);
|
||||
|
||||
thePoint.SetCoord(aPoint[0], aPoint[1]);
|
||||
if (myIsRational)
|
||||
thePoint.ChangeCoord().Divide(aPoint[2]);
|
||||
}
|
||||
|
||||
void BSplCLib_Cache::D0(const Standard_Real& theParameter, gp_Pnt& thePoint) const
|
||||
{
|
||||
Standard_Real aNewParameter = theParameter;
|
||||
if (!myFlatKnots.IsNull()) // B-spline is periodical
|
||||
PeriodicNormalization(myFlatKnots->Array1(), aNewParameter);
|
||||
aNewParameter = (aNewParameter - mySpanStart) / mySpanLength;
|
||||
|
||||
Standard_Real* aPolesArray = ConvertArray(myPolesWeights);
|
||||
Standard_Real aPoint[4];
|
||||
Standard_Integer aDimension = myPolesWeights->RowLength(); // number of columns
|
||||
|
||||
PLib::NoDerivativeEvalPolynomial(aNewParameter, myDegree,
|
||||
aDimension, myDegree * aDimension,
|
||||
aPolesArray[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, gp_Pnt2d& thePoint, gp_Vec2d& theTangent) const
|
||||
{
|
||||
Standard_Integer aDimension = myPolesWeights->RowLength(); // number of columns
|
||||
Standard_Real aPntDeriv[8]; // result storage (point and derivative coordinates)
|
||||
|
||||
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]);
|
||||
theTangent.SetCoord(aPntDeriv[aDimension], aPntDeriv[aDimension + 1]);
|
||||
}
|
||||
|
||||
void BSplCLib_Cache::D1(const Standard_Real& theParameter, gp_Pnt& thePoint, gp_Vec& theTangent) const
|
||||
{
|
||||
Standard_Integer aDimension = myPolesWeights->RowLength(); // number of columns
|
||||
Standard_Real aPntDeriv[8]; // result storage (point and derivative coordinates)
|
||||
|
||||
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::D2(const Standard_Real& theParameter, gp_Pnt2d& thePoint, gp_Vec2d& theTangent, gp_Vec2d& theCurvature) const
|
||||
{
|
||||
Standard_Integer aDimension = myPolesWeights->RowLength(); // number of columns
|
||||
Standard_Real aPntDeriv[12]; // result storage (point and derivatives coordinates)
|
||||
|
||||
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]);
|
||||
theTangent.SetCoord(aPntDeriv[aDimension], aPntDeriv[aDimension + 1]);
|
||||
theCurvature.SetCoord(aPntDeriv[aDimension<<1], aPntDeriv[(aDimension<<1) + 1]);
|
||||
}
|
||||
|
||||
void BSplCLib_Cache::D2(const Standard_Real& theParameter, gp_Pnt& thePoint, gp_Vec& theTangent, gp_Vec& theCurvature) const
|
||||
{
|
||||
Standard_Integer aDimension = myPolesWeights->RowLength(); // number of columns
|
||||
Standard_Real aPntDeriv[12]; // result storage (point and derivatives coordinates)
|
||||
|
||||
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::D3(const Standard_Real& theParameter,
|
||||
gp_Pnt2d& thePoint,
|
||||
gp_Vec2d& theTangent,
|
||||
gp_Vec2d& theCurvature,
|
||||
gp_Vec2d& theTorsion) const
|
||||
{
|
||||
Standard_Integer aDimension = myPolesWeights->RowLength(); // number of columns
|
||||
Standard_Real aPntDeriv[16]; // result storage (point and derivatives coordinates)
|
||||
|
||||
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]);
|
||||
theTangent.SetCoord(aPntDeriv[aDimension], aPntDeriv[aDimension + 1]);
|
||||
Standard_Integer aShift = aDimension << 1;
|
||||
theCurvature.SetCoord(aPntDeriv[aShift], aPntDeriv[aShift + 1]);
|
||||
aShift += aDimension;
|
||||
theTorsion.SetCoord(aPntDeriv[aShift], aPntDeriv[aShift + 1]);
|
||||
}
|
||||
|
||||
void BSplCLib_Cache::D3(const Standard_Real& theParameter,
|
||||
gp_Pnt& thePoint,
|
||||
gp_Vec& theTangent,
|
||||
gp_Vec& theCurvature,
|
||||
gp_Vec& theTorsion) const
|
||||
{
|
||||
Standard_Integer aDimension = myPolesWeights->RowLength(); // number of columns
|
||||
Standard_Real aPntDeriv[16]; // result storage (point and derivatives coordinates)
|
||||
|
||||
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]);
|
||||
}
|
||||
|
182
src/BSplCLib/BSplCLib_Cache.hxx
Normal file
182
src/BSplCLib/BSplCLib_Cache.hxx
Normal file
@@ -0,0 +1,182 @@
|
||||
// Copyright (c) 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.
|
||||
|
||||
#ifndef _BSplCLib_Cache_Headerfile
|
||||
#define _BSplCLib_Cache_Headerfile
|
||||
|
||||
#include <Standard.hxx>
|
||||
#include <Standard_Macro.hxx>
|
||||
#include <Standard_DefineHandle.hxx>
|
||||
#include <Standard_Transient.hxx>
|
||||
|
||||
#include <Handle_TColStd_HArray1OfReal.hxx>
|
||||
#include <Handle_TColStd_HArray2OfReal.hxx>
|
||||
|
||||
#include <gp_Pnt2d.hxx>
|
||||
#include <gp_Pnt.hxx>
|
||||
#include <gp_Vec2d.hxx>
|
||||
#include <gp_Vec.hxx>
|
||||
|
||||
class Handle(BSplCLib_Cache);
|
||||
class TColStd_Array1OfReal;
|
||||
class TColgp_Array1OfPnt;
|
||||
class TColgp_Array1OfPnt2d;
|
||||
|
||||
#ifndef NOWEIGHTS_CURVE
|
||||
#define NOWEIGHTS_CURVE (*((TColStd_Array1OfReal*) NULL))
|
||||
#endif
|
||||
|
||||
//! \brief A cache class for B-spline curves.
|
||||
//!
|
||||
//! Defines all data, that can be cached on a span of B-spline curve.
|
||||
//! The data should be recalculated in going from span to span.
|
||||
class BSplCLib_Cache : public Standard_Transient
|
||||
{
|
||||
public:
|
||||
//! Default constructor
|
||||
Standard_EXPORT BSplCLib_Cache();
|
||||
//! Constructor for caching of 2D curves
|
||||
//! \param theDegree degree of the B-spline
|
||||
//! \param thePeriodic identify the B-spline is periodic
|
||||
//! \param theFlatKnots knots of B-spline curve (with repetitions)
|
||||
//! \param thePoles2d array of poles of 2D B-spline
|
||||
//! \param theWeights array of weights of corresponding poles
|
||||
Standard_EXPORT BSplCLib_Cache(const Standard_Integer& theDegree,
|
||||
const Standard_Boolean& thePeriodic,
|
||||
const TColStd_Array1OfReal& theFlatKnots,
|
||||
const TColgp_Array1OfPnt2d& thePoles2d,
|
||||
const TColStd_Array1OfReal& theWeights = NOWEIGHTS_CURVE);
|
||||
//! Constructor for caching of 3D curves
|
||||
//! \param theDegree degree of the B-spline
|
||||
//! \param thePeriodic identify the B-spline is periodic
|
||||
//! \param theFlatKnots knots of B-spline curve (with repetitions)
|
||||
//! \param thePoles array of poles of 3D B-spline
|
||||
//! \param theWeights array of weights of corresponding poles
|
||||
Standard_EXPORT BSplCLib_Cache(const Standard_Integer& theDegree,
|
||||
const Standard_Boolean& thePeriodic,
|
||||
const TColStd_Array1OfReal& theFlatKnots,
|
||||
const TColgp_Array1OfPnt& thePoles,
|
||||
const TColStd_Array1OfReal& theWeights = NOWEIGHTS_CURVE);
|
||||
|
||||
//! Verifies validity of the cache using flat parameter of the point
|
||||
//! \param theParameter parameter of the point placed in the span
|
||||
Standard_EXPORT Standard_Boolean IsCacheValid(Standard_Real theParameter) const;
|
||||
|
||||
//! Recomputes the cache data for 2D curves. Does not verify validity of the cache
|
||||
//! \param theParameter the value on the knot's axis to identify the span
|
||||
//! \param theDegree degree of the B-spline
|
||||
//! \param thePeriodic identify the B-spline is periodic
|
||||
//! \param theFlatKnots knots of B-spline curve (with repetitions)
|
||||
//! \param thePoles2d array of poles of 2D B-spline
|
||||
//! \param theWeights array of weights of corresponding poles
|
||||
Standard_EXPORT void BuildCache(const Standard_Real& theParameter,
|
||||
const Standard_Integer& theDegree,
|
||||
const Standard_Boolean& thePeriodic,
|
||||
const TColStd_Array1OfReal& theFlatKnots,
|
||||
const TColgp_Array1OfPnt2d& thePoles2d,
|
||||
const TColStd_Array1OfReal& theWeights = NOWEIGHTS_CURVE);
|
||||
//! Recomputes the cache data for 3D curves. Does not verify validity of the cache
|
||||
//! \param theParameter the value on the knot's axis to identify the span
|
||||
//! \param theDegree degree of the B-spline
|
||||
//! \param thePeriodic identify the B-spline is periodic
|
||||
//! \param theFlatKnots knots of B-spline curve (with repetitions)
|
||||
//! \param thePoles array of poles of 3D B-spline
|
||||
//! \param theWeights array of weights of corresponding poles
|
||||
Standard_EXPORT void BuildCache(const Standard_Real& theParameter,
|
||||
const Standard_Integer& theDegree,
|
||||
const Standard_Boolean& thePeriodic,
|
||||
const TColStd_Array1OfReal& theFlatKnots,
|
||||
const TColgp_Array1OfPnt& thePoles,
|
||||
const TColStd_Array1OfReal& theWeights = NOWEIGHTS_CURVE);
|
||||
|
||||
//! Calculates the point on B-spline in the selected point
|
||||
//! \param[in] theParameter parameter of calculation of the value
|
||||
//! \param[out] thePoint the result of calculation (the point on B-spline)
|
||||
Standard_EXPORT void D0(const Standard_Real& theParameter, gp_Pnt2d& thePoint) const;
|
||||
Standard_EXPORT void D0(const Standard_Real& theParameter, gp_Pnt& thePoint) const;
|
||||
|
||||
//! Calculates the point on B-spline and its first derivative in the selected point
|
||||
//! \param[in] theParameter parameter of calculation of the value
|
||||
//! \param[out] thePoint the result of calculation (the point on B-spline)
|
||||
//! \param[out] theTangent tangent vector (first derivatives) for B-spline in the calculated point
|
||||
Standard_EXPORT void D1(const Standard_Real& theParameter, gp_Pnt2d& thePoint, gp_Vec2d& theTangent) const;
|
||||
Standard_EXPORT void D1(const Standard_Real& theParameter, gp_Pnt& thePoint, gp_Vec& theTangent) const;
|
||||
|
||||
//! Calculates the point on B-spline and two derivatives in the selected point
|
||||
//! \param[in] theParameter parameter of calculation of the value
|
||||
//! \param[out] thePoint the result of calculation (the point on B-spline)
|
||||
//! \param[out] theTangent tangent vector (1st derivatives) for B-spline in the calculated point
|
||||
//! \param[out] theCurvature curvature vector (2nd derivatives) for B-spline in the calculated point
|
||||
Standard_EXPORT void D2(const Standard_Real& theParameter,
|
||||
gp_Pnt2d& thePoint,
|
||||
gp_Vec2d& theTangent,
|
||||
gp_Vec2d& theCurvature) const;
|
||||
Standard_EXPORT void D2(const Standard_Real& theParameter,
|
||||
gp_Pnt& thePoint,
|
||||
gp_Vec& theTangent,
|
||||
gp_Vec& theCurvature) const;
|
||||
|
||||
//! Calculates the point on B-spline and three derivatives in the selected point
|
||||
//! \param[in] theParameter parameter of calculation of the value
|
||||
//! \param[out] thePoint the result of calculation (the point on B-spline)
|
||||
//! \param[out] theTangent tangent vector (1st derivatives) for B-spline in the calculated point
|
||||
//! \param[out] theCurvature curvature vector (2nd derivatives) for B-spline in the calculated point
|
||||
//! \param[out] theTorsion second curvature vector (3rd derivatives) for B-spline in the calculated point
|
||||
Standard_EXPORT void D3(const Standard_Real& theParameter,
|
||||
gp_Pnt2d& thePoint,
|
||||
gp_Vec2d& theTangent,
|
||||
gp_Vec2d& theCurvature,
|
||||
gp_Vec2d& theTorsion) const;
|
||||
Standard_EXPORT void D3(const Standard_Real& theParameter,
|
||||
gp_Pnt& thePoint,
|
||||
gp_Vec& theTangent,
|
||||
gp_Vec& theCurvature,
|
||||
gp_Vec& theTorsion) const;
|
||||
|
||||
|
||||
DEFINE_STANDARD_RTTI(BSplCLib_Cache)
|
||||
|
||||
protected:
|
||||
//! Normalizes the parameter for periodical B-splines
|
||||
//! \param theFlatKnots knots with repetitions
|
||||
//! \param theParameter the value to be normalized into the knots array
|
||||
void PeriodicNormalization(const TColStd_Array1OfReal& theFlatKnots, Standard_Real& theParameter) const;
|
||||
|
||||
//! Fills array of derivatives in the selected point of the B-spline
|
||||
//! \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 B-spline curve)
|
||||
void CalculateDerivative(const Standard_Real& theParameter,
|
||||
const Standard_Integer& theDerivative,
|
||||
Standard_Real& theDerivArray) const;
|
||||
|
||||
private:
|
||||
Handle(TColStd_HArray2OfReal) myPolesWeights; ///< array of poles and weights of calculated cache
|
||||
// the array has following structure:
|
||||
// x1 y1 [z1] [w1]
|
||||
// x2 y2 [z2] [w2] etc
|
||||
// for 2D-curves there is no z conponent, for non-rational curves there is no weight
|
||||
|
||||
Standard_Boolean myIsRational; ///< identifies the rationality of B-spline
|
||||
Standard_Real mySpanStart; ///< parameter for the first point of the span
|
||||
Standard_Real mySpanLength; ///< length of the span
|
||||
Standard_Integer mySpanIndex; ///< index of the span on B-spline curve
|
||||
Standard_Integer mySpanIndexMax; ///< maximal number of spans on B-spline curve
|
||||
Standard_Integer myDegree; ///< degree of B-spline
|
||||
Handle(TColStd_HArray1OfReal) myFlatKnots; ///< knots of B-spline (used for periodic normalization of parameters, exists only for periodical splines)
|
||||
};
|
||||
|
||||
DEFINE_STANDARD_HANDLE(BSplCLib_Cache, Standard_Transient)
|
||||
|
||||
#endif
|
@@ -19,6 +19,7 @@
|
||||
// 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>
|
||||
@@ -1089,6 +1090,65 @@ void BSplCLib::BuildCache
|
||||
}
|
||||
}
|
||||
|
||||
void BSplCLib::BuildCache(const Standard_Real theParameter,
|
||||
const Standard_Real theSpanDomain,
|
||||
const Standard_Boolean thePeriodicFlag,
|
||||
const Standard_Integer theDegree,
|
||||
const TColStd_Array1OfReal& theFlatKnots,
|
||||
const Array1OfPoints& thePoles,
|
||||
const TColStd_Array1OfReal& theWeights,
|
||||
TColStd_Array2OfReal& theCacheArray)
|
||||
{
|
||||
Standard_Real aParam = theParameter;
|
||||
Standard_Integer anIndex = 0;
|
||||
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);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Interpolate
|
||||
//purpose :
|
||||
|
@@ -4,4 +4,5 @@ BSplCLib_3.cxx
|
||||
BSplCLib_BzSyntaxes.cxx
|
||||
BSplCLib_CurveComputation.gxx
|
||||
BSplCLib_EvaluatorFunction.hxx
|
||||
|
||||
BSplCLib_Cache.hxx
|
||||
BSplCLib_Cache.cxx
|
||||
|
Reference in New Issue
Block a user