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.
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,
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
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
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)
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,
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
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
myTypeCurve = GeomAbs_OtherCurve;
}
}
+ else // rebuild cache of Bezier and B-spline curve even if the loaded curve is same
+ RebuildCache(myFirst);
}
// --
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.
else
mySurfaceType = GeomAbs_OtherSurface;
}
+ else // rebuild cache of Bezier and B-spline surface even if the loaded surface is same
+ RebuildCache(myUFirst, myVFirst);
}
// --
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";
"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;
}
--- /dev/null
+puts "============"
+puts "OCC27048"
+puts "============"
+puts ""
+############################################################################
+# Recalculation of BSpline cache causes a performance problems
+############################################################################
+
+pload QAcommands
+
+bsplinesurf surf \
+3 4 0 4 1 1 2 1 3 4 \
+3 4 0 4 1 1 2 1 3 4 \
+0 0 0 1 2 0 0 1 3 0 15 1 5 0 15 1 7 0 0 1 10 0 0 1 \
+0 2 0 1 1 3 0 1 4 2 15 1 6 3 15 1 8 2 0 1 10 3 0 1 \
+0 4 0 1 3 4 0 1 4 3 15 1 5 3 15 1 7 4 0 1 10 5 0 1 \
+0 6 0 1 3 6 0 1 4 6 15 1 5 6 15 1 8 5 0 1 10 7 0 1 \
+0 8 0 1 2 8 0 1 4 8 15 1 6 8 15 1 7 7 0 1 10 8 0 1 \
+0 10 0 1 2 10 0 1 4 10 15 1 6 10 15 1 7 10 0 1 10 10 0 1
+
+dchrono t reset
+dchrono t start
+OCC27048 surf -0.1 -0.1 1000000
+dchrono t stop
+set elapsed [dchrono t show]
+
+regexp {CPU user time: ([-0-9.+eE]+) seconds} $elapsed full cpu_time
+set max_time 1
+
+if { $cpu_time > ${max_time} } {
+ puts "Error: calculating B-spline value takes too long time (greater than ${max_time} sec)"
+} else {
+ puts "OK: performance calculating B-spline is suitable"
+}
--- /dev/null
+puts "============"
+puts "OCC27048"
+puts "============"
+puts ""
+############################################################################
+# Recalculation of BSpline cache causes a performance problems
+############################################################################
+
+pload XSDRAW
+
+dchrono t reset
+dchrono t start
+testreadstep [locate_data_file bug27048.stp] result
+dchrono t stop
+set elapsed [dchrono t show]
+
+regexp {CPU user time: ([-0-9.+eE]+) seconds} $elapsed full cpu_time
+set max_time 40
+
+if { $cpu_time > ${max_time} } {
+ puts "Error: reading document Doc is too long (greater than ${max_time} sec)"
+} else {
+ puts "OK: performance reading document Doc is suitable"
+}
+
+smallview
+fit
+set only_screen_axo 1