1
0
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:
azv
2016-01-21 11:35:24 +03:00
committed by bugmaster
parent 4f5ad41656
commit f3a1c0cb60
10 changed files with 111 additions and 4 deletions

View File

@@ -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

View File

@@ -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)

View File

@@ -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

View File

@@ -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

View File

@@ -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);
}
// --

View File

@@ -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.

View File

@@ -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);
}
// --

View File

@@ -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;
}