X-Git-Url: http://git.dev.opencascade.org/gitweb/?p=occt.git;a=blobdiff_plain;f=src%2FBSplCLib%2FBSplCLib_Cache.cxx;h=2075211c4e7a60ef58433b58c6314b8b0fdb82db;hp=6a7041bb22ce7feeac291664c019f60ab3a4def6;hb=f732ea1ab553b92e04557e9a2252a8b36eb1af9f;hpb=35c0599a4255c0bf0a50327ec35627054978bda1 diff --git a/src/BSplCLib/BSplCLib_Cache.cxx b/src/BSplCLib/BSplCLib_Cache.cxx index 6a7041bb22..2075211c4e 100644 --- a/src/BSplCLib/BSplCLib_Cache.cxx +++ b/src/BSplCLib/BSplCLib_Cache.cxx @@ -22,6 +22,8 @@ #include +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) { @@ -29,156 +31,71 @@ static Standard_Real* ConvertArray(const Handle(TColStd_HArray2OfReal)& theHArra 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) + const TColgp_Array1OfPnt2d& /* only used to distinguish from 3d variant */, + const TColStd_Array1OfReal* theWeights) +: myIsRational(theWeights != NULL), + myParams (theDegree, thePeriodic, theFlatKnots) { - Standard_Real aCacheParam = theFlatKnots.Value(theFlatKnots.Lower() + theDegree); - BuildCache(aCacheParam, theDegree, thePeriodic, - theFlatKnots, thePoles2d, theWeights); + Standard_Integer aPWColNumber = (myIsRational ? 3 : 2); + myPolesWeights = new TColStd_HArray2OfReal (1, theDegree + 1, 1, aPWColNumber); } BSplCLib_Cache::BSplCLib_Cache(const Standard_Integer& theDegree, const Standard_Boolean& thePeriodic, const TColStd_Array1OfReal& theFlatKnots, - const TColgp_Array1OfPnt& thePoles, - const TColStd_Array1OfReal& theWeights) + const TColgp_Array1OfPnt& /* only used to distinguish from 2d variant */, + const TColStd_Array1OfReal* theWeights) +: myIsRational(theWeights != NULL), + myParams (theDegree, thePeriodic, theFlatKnots) { - Standard_Real aCacheParam = theFlatKnots.Value(theFlatKnots.Lower() + theDegree); - BuildCache(aCacheParam, theDegree, thePeriodic, - theFlatKnots, thePoles, theWeights); + Standard_Integer aPWColNumber = (myIsRational ? 4 : 3); + myPolesWeights = new TColStd_HArray2OfReal (1, theDegree + 1, 1, aPWColNumber); } - 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); - } + return myParams.IsCacheValid (theParameter); } - 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) + 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; + Standard_Real aNewParam = myParams.PeriodicNormalization (theParameter); + myParams.LocateParameter (aNewParam, theFlatKnots); // Calculate new cache data - BSplCLib::BuildCache(mySpanStart, mySpanLength, thePeriodic, theDegree, - theFlatKnots, thePoles2d, theWeights, - myPolesWeights->ChangeArray2()); + BSplCLib::BuildCache (myParams.SpanStart, myParams.SpanLength, myParams.IsPeriodic, + myParams.Degree, myParams.SpanIndex, 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) + 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; + Standard_Real aNewParam = myParams.PeriodicNormalization (theParameter); + myParams.LocateParameter (aNewParam, theFlatKnots); // Calculate new cache data - BSplCLib::BuildCache(mySpanStart, mySpanLength, thePeriodic, theDegree, - theFlatKnots, thePoles, theWeights, - myPolesWeights->ChangeArray2()); + BSplCLib::BuildCache (myParams.SpanStart, myParams.SpanLength, myParams.IsPeriodic, + myParams.Degree, myParams.SpanIndex, 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 aNewParameter = myParams.PeriodicNormalization (theParameter); + aNewParameter = (aNewParameter - myParams.SpanStart) / myParams.SpanLength; Standard_Real* aPolesArray = ConvertArray(myPolesWeights); Standard_Integer aDimension = myPolesWeights->RowLength(); // number of columns @@ -194,23 +111,23 @@ void BSplCLib_Cache::CalculateDerivative(const Standard_Real& theParameter, // 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) + if (!myIsRational && myParams.Degree < theDerivative) { - aDerivative = myDegree; - for (Standard_Integer ind = myDegree * aDimension; ind < (theDerivative + 1) * aDimension; ind++) + aDerivative = myParams.Degree; + for (Standard_Integer ind = myParams.Degree * 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, + PLib::EvalPolynomial(aNewParameter, aDerivative, myParams.Degree, 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; + aFactor /= myParams.SpanLength; for (Standard_Integer ind = 0; ind < aDimension; ind++) aPntDeriv[aDimension * deriv + ind] *= aFactor; } @@ -222,17 +139,15 @@ void BSplCLib_Cache::CalculateDerivative(const Standard_Real& theParameter, 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 aNewParameter = myParams.PeriodicNormalization (theParameter); + aNewParameter = (aNewParameter - myParams.SpanStart) / myParams.SpanLength; Standard_Real* aPolesArray = ConvertArray(myPolesWeights); Standard_Real aPoint[4]; Standard_Integer aDimension = myPolesWeights->RowLength(); // number of columns - PLib::NoDerivativeEvalPolynomial(aNewParameter, myDegree, - aDimension, myDegree * aDimension, + PLib::NoDerivativeEvalPolynomial(aNewParameter, myParams.Degree, + aDimension, myParams.Degree * aDimension, aPolesArray[0], aPoint[0]); thePoint.SetCoord(aPoint[0], aPoint[1]); @@ -242,17 +157,15 @@ void BSplCLib_Cache::D0(const Standard_Real& theParameter, gp_Pnt2d& thePoint) c 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 aNewParameter = myParams.PeriodicNormalization (theParameter); + aNewParameter = (aNewParameter - myParams.SpanStart) / myParams.SpanLength; Standard_Real* aPolesArray = ConvertArray(myPolesWeights); Standard_Real aPoint[4]; Standard_Integer aDimension = myPolesWeights->RowLength(); // number of columns - PLib::NoDerivativeEvalPolynomial(aNewParameter, myDegree, - aDimension, myDegree * aDimension, + PLib::NoDerivativeEvalPolynomial(aNewParameter, myParams.Degree, + aDimension, myParams.Degree * aDimension, aPolesArray[0], aPoint[0]); thePoint.SetCoord(aPoint[0], aPoint[1], aPoint[2]);