mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-08-19 13:40:49 +03:00
0027048: BSpline cache is always wrong outside of surface
1. Disable recalculation of B-spline cache when the parameter is out of surface boundary but near the cached span. 2. Rebuild cache each time a curve/surface is loaded into adaptor (B-spline knots may be re-parametrized outside adaptor without changing base curve) 3. Test cases.
This commit is contained in:
@@ -73,7 +73,8 @@ Standard_Boolean BSplCLib_Cache::IsCacheValid(Standard_Real theParameter) const
|
||||
PeriodicNormalization(myFlatKnots->Array1(), aNewParam);
|
||||
|
||||
Standard_Real aDelta = aNewParam - mySpanStart;
|
||||
return (aDelta >= 0.0 && (aDelta < mySpanLength || mySpanIndex == mySpanIndexMax));
|
||||
return ((aDelta >= 0.0 || mySpanIndex == mySpanIndexMin) &&
|
||||
(aDelta < mySpanLength || mySpanIndex == mySpanIndexMax));
|
||||
}
|
||||
|
||||
void BSplCLib_Cache::PeriodicNormalization(const TColStd_Array1OfReal& theFlatKnots,
|
||||
@@ -126,6 +127,7 @@ void BSplCLib_Cache::BuildCache(const Standard_Real& theParameter,
|
||||
aNewParam, thePeriodic, mySpanIndex, aNewParam);
|
||||
mySpanStart = theFlatKnots.Value(mySpanIndex);
|
||||
mySpanLength = theFlatKnots.Value(mySpanIndex + 1) - mySpanStart;
|
||||
mySpanIndexMin = thePeriodic ? 0 : myDegree + 1;
|
||||
mySpanIndexMax = theFlatKnots.Length() - 1 - theDegree;
|
||||
|
||||
// Calculate new cache data
|
||||
@@ -164,6 +166,7 @@ void BSplCLib_Cache::BuildCache(const Standard_Real& theParameter,
|
||||
aNewParam, thePeriodic, mySpanIndex, aNewParam);
|
||||
mySpanStart = theFlatKnots.Value(mySpanIndex);
|
||||
mySpanLength = theFlatKnots.Value(mySpanIndex + 1) - mySpanStart;
|
||||
mySpanIndexMin = thePeriodic ? 0 : myDegree + 1;
|
||||
mySpanIndexMax = theFlatKnots.Length() - 1 - theDegree;
|
||||
|
||||
// Calculate new cache data
|
||||
|
@@ -167,6 +167,7 @@ private:
|
||||
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 Bezier/B-spline curve
|
||||
Standard_Integer mySpanIndexMin; ///< minimal index of span on Bezier/B-spline curve
|
||||
Standard_Integer mySpanIndexMax; ///< maximal number of spans on Bezier/B-spline curve
|
||||
Standard_Integer myDegree; ///< degree of Bezier/B-spline
|
||||
Handle(TColStd_HArray1OfReal) myFlatKnots; ///< knots of Bezier/B-spline (used for periodic normalization of parameters, exists only for periodical splines)
|
||||
|
@@ -75,8 +75,10 @@ Standard_Boolean BSplSLib_Cache::IsCacheValid(Standard_Real theParameterU,
|
||||
|
||||
Standard_Real aDelta0 = aNewU - mySpanStart[0];
|
||||
Standard_Real aDelta1 = aNewV - mySpanStart[1];
|
||||
return (aDelta0 >= -mySpanLength[0] && (aDelta0 < mySpanLength[0] || mySpanIndex[0] == mySpanIndexMax[0]) &&
|
||||
aDelta1 >= -mySpanLength[1] && (aDelta1 < mySpanLength[1] || mySpanIndex[1] == mySpanIndexMax[1]));
|
||||
return ((aDelta0 >= -mySpanLength[0] || mySpanIndex[0] == mySpanIndexMin[0]) &&
|
||||
(aDelta0 < mySpanLength[0] || mySpanIndex[0] == mySpanIndexMax[0]) &&
|
||||
(aDelta1 >= -mySpanLength[1] || mySpanIndex[1] == mySpanIndexMin[1]) &&
|
||||
(aDelta1 < mySpanLength[1] || mySpanIndex[1] == mySpanIndexMax[1]));
|
||||
}
|
||||
|
||||
void BSplSLib_Cache::PeriodicNormalization(const Standard_Integer& theDegree,
|
||||
@@ -164,7 +166,9 @@ void BSplSLib_Cache::BuildCache(const Standard_Real& theParameterU,
|
||||
|
||||
mySpanLength[1] = (theFlatKnotsV.Value(mySpanIndex[1] + 1) - theFlatKnotsV.Value(mySpanIndex[1])) * 0.5;
|
||||
mySpanStart[1] = theFlatKnotsV.Value(mySpanIndex[1]) + mySpanLength[1];
|
||||
mySpanIndexMin[0] = thePeriodicU ? 0 : theDegreeU + 1;
|
||||
mySpanIndexMax[0] = theFlatKnotsU.Length() - 1 - theDegreeU;
|
||||
mySpanIndexMin[1] = thePeriodicV ? 0 : theDegreeV + 1;
|
||||
mySpanIndexMax[1] = theFlatKnotsV.Length() - 1 - theDegreeV;
|
||||
|
||||
// Calculate new cache data
|
||||
|
@@ -144,6 +144,7 @@ private:
|
||||
Standard_Real mySpanStart[2]; ///< parameters (u, v) for the frst point of the span
|
||||
Standard_Real mySpanLength[2]; ///< lengths of the span along corresponding parameter
|
||||
Standard_Integer mySpanIndex[2]; ///< indexes of the span on Bezier/B-spline surface
|
||||
Standard_Integer mySpanIndexMin[2]; ///< minimal indexes of span
|
||||
Standard_Integer mySpanIndexMax[2]; ///< maximal indexes of span
|
||||
Standard_Integer myDegree[2]; ///< degrees of Bezier/B-spline for each parameter
|
||||
Handle(TColStd_HArray1OfReal) myFlatKnots[2]; ///< arrays of knots of Bezier/B-spline
|
||||
|
@@ -237,6 +237,8 @@ void Geom2dAdaptor_Curve::load(const Handle(Geom2d_Curve)& C,
|
||||
myTypeCurve = GeomAbs_OtherCurve;
|
||||
}
|
||||
}
|
||||
else // rebuild cache of Bezier and B-spline curve even if the loaded curve is same
|
||||
RebuildCache(myFirst);
|
||||
}
|
||||
|
||||
// --
|
||||
|
@@ -194,7 +194,9 @@ void GeomAdaptor_Curve::load(const Handle(Geom_Curve)& C,
|
||||
myTypeCurve = GeomAbs_OtherCurve;
|
||||
}
|
||||
}
|
||||
}
|
||||
else // rebuild cache of Bezier and B-spline curve even if the loaded curve is same
|
||||
RebuildCache(myFirst);
|
||||
}
|
||||
|
||||
// --
|
||||
// -- Global methods - Apply to the whole curve.
|
||||
|
@@ -217,6 +217,8 @@ void GeomAdaptor_Surface::load(const Handle(Geom_Surface)& S,
|
||||
else
|
||||
mySurfaceType = GeomAbs_OtherSurface;
|
||||
}
|
||||
else // rebuild cache of Bezier and B-spline surface even if the loaded surface is same
|
||||
RebuildCache(myUFirst, myVFirst);
|
||||
}
|
||||
|
||||
// --
|
||||
|
@@ -5027,6 +5027,32 @@ static Standard_Integer OCC26945_close (Draw_Interpretor& theDI, Standard_Intege
|
||||
return 0;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : OCC27048
|
||||
//purpose : Calculate value of B-spline surface N times
|
||||
//=======================================================================
|
||||
static Standard_Integer OCC27048(Draw_Interpretor& theDI, Standard_Integer theArgc, const char** theArgv)
|
||||
{
|
||||
if (theArgc != 5)
|
||||
{
|
||||
std::cout << "Incorrect number of arguments. See usage:" << std::endl;
|
||||
theDI.PrintHelp(theArgv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
Handle(Geom_Surface) aSurf = DrawTrSurf::GetSurface(theArgv[1]);
|
||||
GeomAdaptor_Surface anAdaptor(aSurf);
|
||||
|
||||
Standard_Real aU = Draw::Atof(theArgv[2]);
|
||||
Standard_Real aV = Draw::Atof(theArgv[3]);
|
||||
Standard_Integer aN = Draw::Atoi(theArgv[4]);
|
||||
|
||||
for (; aN > 0; --aN)
|
||||
anAdaptor.Value(aU, aV);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void QABugs::Commands_19(Draw_Interpretor& theCommands) {
|
||||
const char *group = "QABugs";
|
||||
|
||||
@@ -5132,6 +5158,10 @@ void QABugs::Commands_19(Draw_Interpretor& theCommands) {
|
||||
"OCC26945 localCtxToClose"
|
||||
"\n\t\t: Closes local context with the ID localCtxToClose",
|
||||
__FILE__, OCC26945_close, group);
|
||||
|
||||
theCommands.Add ("OCC27048",
|
||||
"OCC27048 surf U V N\nCalculate value of surface N times in the point (U, V)",
|
||||
__FILE__, OCC27048, group);
|
||||
|
||||
return;
|
||||
}
|
||||
|
Reference in New Issue
Block a user