From: aml Date: Fri, 28 Nov 2014 10:19:30 +0000 (+0300) Subject: 0025487: Extrema_GenExtPS needs to be optimized X-Git-Tag: V6_9_0_beta~266 X-Git-Url: http://git.dev.opencascade.org/gitweb/?a=commitdiff_plain;h=150e93a7f2c5328981001c116e999515fb714332;p=occt.git 0025487: Extrema_GenExtPS needs to be optimized Better caching and cashe usage in Extrema_GenExtPS. Test-cases for issue #25487 Update of test-cases --- diff --git a/src/Extrema/Extrema_GenExtPS.cdl b/src/Extrema/Extrema_GenExtPS.cdl index f2f8557b1c..ca3e1dd562 100644 --- a/src/Extrema/Extrema_GenExtPS.cdl +++ b/src/Extrema/Extrema_GenExtPS.cdl @@ -144,6 +144,17 @@ is BuildGrid(me: in out; thePoint: Pnt from gp) is private; ---Purpose: Creation of grid of parametric points + ComputeEdgeParameters(me: in out; + IsUEdge : Boolean; + theParam0 : POnSurfParams from Extrema; + theParam1 : POnSurfParams from Extrema; + thePoints : Pnt from gp; + theDiffTol : Real) returns POnSurfParams from Extrema + is private; + ---Purpose: Compute new edge parameters. + ---C++: return const & + + fields myDone : Boolean; myInit : Boolean; @@ -164,6 +175,9 @@ fields myAlgo : ExtAlgo from Extrema; myUParams : HArray1OfReal from TColStd; myVParams : HArray1OfReal from TColStd; - myFacePntParams : HArray2OfPOnSurfParams from Extrema; + myFacePntParams : HArray2OfPOnSurfParams from Extrema; + myUEdgePntParams : HArray2OfPOnSurfParams from Extrema; + myVEdgePntParams : HArray2OfPOnSurfParams from Extrema; + myGridParam : POnSurfParams from Extrema; end GenExtPS; diff --git a/src/Extrema/Extrema_GenExtPS.cxx b/src/Extrema/Extrema_GenExtPS.cxx index d8af103d38..dc281f3f3b 100644 --- a/src/Extrema/Extrema_GenExtPS.cxx +++ b/src/Extrema/Extrema_GenExtPS.cxx @@ -169,70 +169,6 @@ Standard_Boolean Bnd_SphereUBTreeSelectorMax::Accept(const Standard_Integer& the return Standard_False; } -/* - * This function computes the point on surface parameters on edge. - * if it coincides with theParam0 or theParam1, it is returned. - */ -static Extrema_POnSurfParams ComputeEdgeParameters - (const Standard_Boolean IsUEdge, - const Extrema_POnSurfParams &theParam0, - const Extrema_POnSurfParams &theParam1, - const Adaptor3d_SurfacePtr &theSurf, - const gp_Pnt &thePoint, - const Standard_Real theDiffTol) -{ - const Standard_Real aSqrDist01 = - theParam0.Value().SquareDistance(theParam1.Value()); - - if (aSqrDist01 <= theDiffTol) { - // The points are confused. Get the first point and change its type. - return theParam0; - } else { - const Standard_Real aDiffDist = - Abs(theParam0.GetSqrDistance() - theParam1.GetSqrDistance()); - - if (aDiffDist >= aSqrDist01 - theDiffTol) { - // The shortest distance is one of the nodes. - if (theParam0.GetSqrDistance() > theParam1.GetSqrDistance()) { - // The shortest distance is the point 1. - return theParam1; - } else { - // The shortest distance is the point 0. - return theParam0; - } - } else { - // The shortest distance is inside the edge. - gp_XYZ aPoP(thePoint.XYZ().Subtracted(theParam0.Value().XYZ())); - gp_XYZ aPoP1(theParam1.Value().XYZ().Subtracted(theParam0.Value().XYZ())); - Standard_Real aRatio = aPoP.Dot(aPoP1)/aSqrDist01; - Standard_Real aU[2]; - Standard_Real aV[2]; - - theParam0.Parameter(aU[0], aV[0]); - theParam1.Parameter(aU[1], aV[1]); - - Standard_Real aUPar = aU[0]; - Standard_Real aVPar = aV[0]; - - if (IsUEdge) { - aUPar += aRatio*(aU[1] - aU[0]); - } else { - aVPar += aRatio*(aV[1] - aV[0]); - } - - Extrema_POnSurfParams aParam(aUPar, aVPar, theSurf->Value(aUPar, aVPar)); - Standard_Integer anIndices[2]; - - theParam0.GetIndices(anIndices[0], anIndices[1]); - aParam.SetElementType(IsUEdge ? Extrema_UIsoEdge : Extrema_VIsoEdge); - aParam.SetSqrDistance(thePoint.SquareDistance(aParam.Value())); - aParam.SetIndices(anIndices[0], anIndices[1]); - - return aParam; - } - } -} - //============================================================================= /*----------------------------------------------------------------------------- @@ -288,32 +224,36 @@ Extrema_GenExtPS::Extrema_GenExtPS() Extrema_GenExtPS::Extrema_GenExtPS (const gp_Pnt& P, - const Adaptor3d_Surface& S, - const Standard_Integer NbU, - const Standard_Integer NbV, - const Standard_Real TolU, - const Standard_Real TolV, - const Extrema_ExtFlag F, - const Extrema_ExtAlgo A) - : myF (P,S), myFlag(F), myAlgo(A) + const Adaptor3d_Surface& S, + const Standard_Integer NbU, + const Standard_Integer NbV, + const Standard_Real TolU, + const Standard_Real TolV, + const Extrema_ExtFlag F, + const Extrema_ExtAlgo A) +: myF (P,S), + myFlag(F), + myAlgo(A) { Initialize(S, NbU, NbV, TolU, TolV); Perform(P); } Extrema_GenExtPS::Extrema_GenExtPS (const gp_Pnt& P, - const Adaptor3d_Surface& S, - const Standard_Integer NbU, - const Standard_Integer NbV, - const Standard_Real Umin, - const Standard_Real Usup, - const Standard_Real Vmin, - const Standard_Real Vsup, - const Standard_Real TolU, - const Standard_Real TolV, - const Extrema_ExtFlag F, - const Extrema_ExtAlgo A) - : myF (P,S), myFlag(F), myAlgo(A) + const Adaptor3d_Surface& S, + const Standard_Integer NbU, + const Standard_Integer NbV, + const Standard_Real Umin, + const Standard_Real Usup, + const Standard_Real Vmin, + const Standard_Real Vsup, + const Standard_Real TolU, + const Standard_Real TolV, + const Extrema_ExtFlag F, + const Extrema_ExtAlgo A) +: myF (P,S), + myFlag(F), + myAlgo(A) { Initialize(S, NbU, NbV, Umin, Usup, Vmin, Vsup, TolU, TolV); Perform(P); @@ -321,10 +261,10 @@ Extrema_GenExtPS::Extrema_GenExtPS (const gp_Pnt& P, void Extrema_GenExtPS::Initialize(const Adaptor3d_Surface& S, - const Standard_Integer NbU, - const Standard_Integer NbV, - const Standard_Real TolU, - const Standard_Real TolV) + const Standard_Integer NbU, + const Standard_Integer NbV, + const Standard_Real TolU, + const Standard_Real TolV) { myumin = S.FirstUParameter(); myusup = S.LastUParameter(); @@ -335,14 +275,14 @@ void Extrema_GenExtPS::Initialize(const Adaptor3d_Surface& S, void Extrema_GenExtPS::Initialize(const Adaptor3d_Surface& S, - const Standard_Integer NbU, - const Standard_Integer NbV, - const Standard_Real Umin, - const Standard_Real Usup, - const Standard_Real Vmin, - const Standard_Real Vsup, - const Standard_Real TolU, - const Standard_Real TolV) + const Standard_Integer NbU, + const Standard_Integer NbV, + const Standard_Real Umin, + const Standard_Real Usup, + const Standard_Real Vmin, + const Standard_Real Vsup, + const Standard_Real TolU, + const Standard_Real TolV) { myS = (Adaptor3d_SurfacePtr)&S; myusample = NbU; @@ -486,6 +426,80 @@ void Extrema_GenExtPS::GetGridPoints( const Adaptor3d_Surface& theSurf) } +/* + * This function computes the point on surface parameters on edge. + * if it coincides with theParam0 or theParam1, it is returned. + */ +const Extrema_POnSurfParams& Extrema_GenExtPS::ComputeEdgeParameters + (const Standard_Boolean IsUEdge, + const Extrema_POnSurfParams &theParam0, + const Extrema_POnSurfParams &theParam1, + const gp_Pnt &thePoint, + const Standard_Real theDiffTol) +{ + const Standard_Real aSqrDist01 = + theParam0.Value().SquareDistance(theParam1.Value()); + + if (aSqrDist01 <= theDiffTol) + { + // The points are confused. Get the first point and change its type. + return theParam0; + } + else + { + const Standard_Real aDiffDist = + Abs(theParam0.GetSqrDistance() - theParam1.GetSqrDistance()); + + if (aDiffDist >= aSqrDist01 - theDiffTol) + { + // The shortest distance is one of the nodes. + if (theParam0.GetSqrDistance() > theParam1.GetSqrDistance()) + { + // The shortest distance is the point 1. + return theParam1; + } + else + { + // The shortest distance is the point 0. + return theParam0; + } + } + else + { + // The shortest distance is inside the edge. + gp_XYZ aPoP(thePoint.XYZ().Subtracted(theParam0.Value().XYZ())); + gp_XYZ aPoP1(theParam1.Value().XYZ().Subtracted(theParam0.Value().XYZ())); + Standard_Real aRatio = aPoP.Dot(aPoP1)/aSqrDist01; + Standard_Real aU[2]; + Standard_Real aV[2]; + + theParam0.Parameter(aU[0], aV[0]); + theParam1.Parameter(aU[1], aV[1]); + + Standard_Real aUPar = aU[0]; + Standard_Real aVPar = aV[0]; + + if (IsUEdge) + { + aUPar += aRatio*(aU[1] - aU[0]); + } + else + { + aVPar += aRatio*(aV[1] - aV[0]); + } + + myGridParam.SetParameters(aUPar, aVPar, myS->Value(aUPar, aVPar)); + Standard_Integer anIndices[2]; + + theParam0.GetIndices(anIndices[0], anIndices[1]); + myGridParam.SetElementType(IsUEdge ? Extrema_UIsoEdge : Extrema_VIsoEdge); + myGridParam.SetSqrDistance(thePoint.SquareDistance(myGridParam.Value())); + myGridParam.SetIndices(anIndices[0], anIndices[1]); + return myGridParam; + } + } +} + void Extrema_GenExtPS::BuildGrid(const gp_Pnt &thePoint) { Standard_Integer NoU, NoV; @@ -541,6 +555,14 @@ void Extrema_GenExtPS::BuildGrid(const gp_Pnt &thePoint) } } + myFacePntParams = + new Extrema_HArray2OfPOnSurfParams(0, myusample, 0, myvsample); + + myUEdgePntParams = + new Extrema_HArray2OfPOnSurfParams(1, myusample - 1, 1, myvsample); + myVEdgePntParams = + new Extrema_HArray2OfPOnSurfParams(1, myusample, 1, myvsample - 1); + // Fill boundary with negative square distance. // It is used for computation of Maximum. for (NoV = 0; NoV <= myvsample + 1; NoV++) { @@ -576,31 +598,28 @@ void Extrema_GenExtPS::BuildGrid(const gp_Pnt &thePoint) // Step 2. Compute distances to edges. // Assume UEdge(i, j) = { Point(i, j); Point(i + 1, j ) } // Assume VEdge(i, j) = { Point(i, j); Point(i, j + 1) } - Handle(Extrema_HArray2OfPOnSurfParams) aUEdgePntParams = - new Extrema_HArray2OfPOnSurfParams(1, myusample - 1, 1, myvsample); - Handle(Extrema_HArray2OfPOnSurfParams) aVEdgePntParams = - new Extrema_HArray2OfPOnSurfParams(1, myusample, 1, myvsample - 1); - - for ( NoU = 1 ; NoU <= myusample; NoU++ ) { - for ( NoV = 1 ; NoV <= myvsample; NoV++) { + for ( NoU = 1 ; NoU <= myusample; NoU++ ) + { + for ( NoV = 1 ; NoV <= myvsample; NoV++) + { const Extrema_POnSurfParams &aParam0 = myPoints->Value(NoU, NoV); - if (NoU < myusample) { + if (NoU < myusample) + { // Compute parameters to UEdge. const Extrema_POnSurfParams &aParam1 = myPoints->Value(NoU + 1, NoV); - Extrema_POnSurfParams aUEdgeParam = ComputeEdgeParameters - (Standard_True, aParam0, aParam1, myS, thePoint, aDiffTol); + const Extrema_POnSurfParams &anEdgeParam = ComputeEdgeParameters(Standard_True, aParam0, aParam1, thePoint, aDiffTol); - aUEdgePntParams->SetValue(NoU, NoV, aUEdgeParam); + myUEdgePntParams->SetValue(NoU, NoV, anEdgeParam); } - if (NoV < myvsample) { + if (NoV < myvsample) + { // Compute parameters to VEdge. const Extrema_POnSurfParams &aParam1 = myPoints->Value(NoU, NoV + 1); - Extrema_POnSurfParams aVEdgeParam = ComputeEdgeParameters - (Standard_False, aParam0, aParam1, myS, thePoint, aDiffTol); + const Extrema_POnSurfParams &anEdgeParam = ComputeEdgeParameters(Standard_False, aParam0, aParam1, thePoint, aDiffTol); - aVEdgePntParams->SetValue(NoU, NoV, aVEdgeParam); + myVEdgePntParams->SetValue(NoU, NoV, anEdgeParam); } } } @@ -610,18 +629,16 @@ void Extrema_GenExtPS::BuildGrid(const gp_Pnt &thePoint) // { Point(i, j); Point(i + 1, j); Point(i + 1, j + 1); Point(i, j + 1) } // Or // { UEdge(i, j); VEdge(i + 1, j); UEdge(i, j + 1); VEdge(i, j) } - myFacePntParams = - new Extrema_HArray2OfPOnSurfParams(0, myusample, 0, myvsample); Standard_Real aSqrDist01; Standard_Real aDiffDist; Standard_Boolean isOut; for ( NoU = 1 ; NoU < myusample; NoU++ ) { for ( NoV = 1 ; NoV < myvsample; NoV++) { - const Extrema_POnSurfParams &aUE0 = aUEdgePntParams->Value(NoU, NoV); - const Extrema_POnSurfParams &aUE1 = aUEdgePntParams->Value(NoU, NoV+1); - const Extrema_POnSurfParams &aVE0 = aVEdgePntParams->Value(NoU, NoV); - const Extrema_POnSurfParams &aVE1 = aVEdgePntParams->Value(NoU+1, NoV); + const Extrema_POnSurfParams &aUE0 = myUEdgePntParams->Value(NoU, NoV); + const Extrema_POnSurfParams &aUE1 = myUEdgePntParams->Value(NoU, NoV+1); + const Extrema_POnSurfParams &aVE0 = myVEdgePntParams->Value(NoU, NoV); + const Extrema_POnSurfParams &aVE1 = myVEdgePntParams->Value(NoU+1, NoV); aSqrDist01 = aUE0.Value().SquareDistance(aUE1.Value()); aDiffDist = Abs(aUE0.GetSqrDistance() - aUE1.GetSqrDistance()); @@ -689,13 +706,7 @@ void Extrema_GenExtPS::BuildGrid(const gp_Pnt &thePoint) } } -/* -a- Constitution of the table of distances (TbDist(0,myusample+1,0,myvsample+1)): - --------------------------------------------------------------- -*/ - // Parameterisation of the sample - void Extrema_GenExtPS::BuildTree() { // if tree already exists, assume it is already correctly filled diff --git a/src/Extrema/Extrema_POnSurf.cdl b/src/Extrema/Extrema_POnSurf.cdl index 89d4819ee1..a1f68693de 100644 --- a/src/Extrema/Extrema_POnSurf.cdl +++ b/src/Extrema/Extrema_POnSurf.cdl @@ -35,6 +35,13 @@ is ---C++: inline is static; + SetParameters(me: in out; + theU, theV: Real from Standard; + thePnt: Pnt from gp); + ---Purpose: Sets the params of current POnSurf instance. + -- (e.g. to the point to be projected). + ---C++: inline + Parameter (me; U,V: out Real) ---Purpose: Returns the parameter values on the surface. ---C++: inline diff --git a/src/Extrema/Extrema_POnSurf.lxx b/src/Extrema/Extrema_POnSurf.lxx index 9215d53198..17c6e630cc 100644 --- a/src/Extrema/Extrema_POnSurf.lxx +++ b/src/Extrema/Extrema_POnSurf.lxx @@ -16,11 +16,22 @@ inline Extrema_POnSurf::Extrema_POnSurf () {} inline Extrema_POnSurf::Extrema_POnSurf (const Standard_Real U, const Standard_Real V, - const gp_Pnt& P) : - myU (U), myV (V), myP (P) + const gp_Pnt& P) +: myU (U), + myV (V), + myP (P) { } +inline void Extrema_POnSurf::SetParameters (const Standard_Real U, + const Standard_Real V, + const gp_Pnt& P) +{ + myU = U; + myV = V; + myP = P; +} + inline void Extrema_POnSurf::Parameter ( Standard_Real& U, Standard_Real& V) const { U = myU; diff --git a/tests/bugs/moddata_3/bug25487_1 b/tests/bugs/moddata_3/bug25487_1 new file mode 100644 index 0000000000..a6eb562725 --- /dev/null +++ b/tests/bugs/moddata_3/bug25487_1 @@ -0,0 +1,73 @@ +puts "========" +puts "OCC25487" +puts "========" +puts "" +########################################## +# Extrema_GenExtPS needs to be optimized +########################################## + +pload DATAEXCHANGEKERNEL + +# Restore testing shape and get timing characteristics for operation stepread +dchrono perf_h reset +dchrono perf_h start +stepread [locate_data_file OCC25487_LP1.stp] a * +dchrono perf_h stop + +# Get elapsed time for operation stepread +set chrono_info [dchrono perf_h show] +regexp {CPU user time: ([-0-9.+eE]+) seconds} $chrono_info full CPU_time +puts "Elapsed time is: $CPU_time" + +# Check current OS +set currentOS $tcl_platform(os) + +# Check prformance on Windows +if {[string compare $currentOS "Windows NT"] == 0} { + if {[regexp {Debug mode} [dversion]]} { + # DEBUG mode + # initial CPU_time for WINDOWS in DEBUG mode is 410 ((186+19)*2) sec + puts "Checking WINDOWS performance in debug mode..." + if {$CPU_time > 410.} { + puts "ERROR: OCC25487 is reproduced." + puts " Low performance: $CPU_time (but should be less than 410 sec)" + } else { + puts "Done!" + } + } else { + # OPTIMIZE mode + # initial CPU_time for WINDOWS in OPTIMIZE mode is 205 (186+19) sec + puts "Checking WINDOWS performance in optimize mode..." + if {$CPU_time > 205.} { + puts "ERROR: OCC25487 is reproduced." + puts " Low performance: $CPU_time (but should be less than 205 sec)" + } else { + puts "Done!" + } + } +} + +# Check performance on Linux +if {[string compare $currentOS "Linux"] == 0} { + if {[regexp {Debug mode} [dversion]]} { + # DEBUG mode + # initial CPU_time for LINUX in DEBUG mode is 292 ((132+14)*2) sec + puts "Checking LINUX performance in debug mode..." + if {$CPU_time > 292.} { + puts "ERROR: OCC25487 is reproduced." + puts " Low performance: $CPU_time (but should be less than 292 sec)" + } else { + puts "Done!" + } + } else { + # OPTIMIZE mode + # initial CPU_time for LINUX in OPTIMIZE mode is 146 (132+14) sec + puts "Checking LINUX performance in optimize mode..." + if {$CPU_time > 146.} { + puts "ERROR: OCC25487 is reproduced." + puts " Low performance: $CPU_time (but should be less than 146 sec)" + } else { + puts "Done!" + } + } +} diff --git a/tests/bugs/moddata_3/bug25487_2 b/tests/bugs/moddata_3/bug25487_2 new file mode 100644 index 0000000000..41f8cacd0c --- /dev/null +++ b/tests/bugs/moddata_3/bug25487_2 @@ -0,0 +1,73 @@ +puts "========" +puts "OCC25487" +puts "========" +puts "" +########################################## +# Extrema_GenExtPS needs to be optimized +########################################## + +pload DATAEXCHANGEKERNEL + +# Restore testing shape and get timing characteristics for operation stepread +dchrono perf_h reset +dchrono perf_h start +stepread [locate_data_file OCC25487_LP2.stp] a * +dchrono perf_h stop + +# Get elapsed time for operation stepread +set chrono_info [dchrono perf_h show] +regexp {CPU user time: ([-0-9.+eE]+) seconds} $chrono_info full CPU_time +puts "Elapsed time is: $CPU_time" + +# Check current OS +set currentOS $tcl_platform(os) + +# Check prformance on Windows +if {[string compare $currentOS "Windows NT"] == 0} { + if {[regexp {Debug mode} [dversion]]} { + # DEBUG mode + # initial CPU_time for WINDOWS in DEBUG mode is 1208 ((549+55)*2) sec + puts "Checking WINDOWS performance in debug mode..." + if {$CPU_time > 1208.} { + puts "ERROR: OCC25487 is reproduced." + puts " Low performance: $CPU_time (but should be less than 1208 sec)" + } else { + puts "Done!" + } + } else { + # OPTIMIZE mode + # initial CPU_time for WINDOWS in OPTIMIZE mode is 604 (549+55) sec + puts "Checking WINDOWS performance in optimize mode..." + if {$CPU_time > 604.} { + puts "ERROR: OCC25487 is reproduced." + puts " Low performance: $CPU_time (but should be less than 604 sec)" + } else { + puts "Done!" + } + } +} + +# Check performance on Linux +if {[string compare $currentOS "Linux"] == 0} { + if {[regexp {Debug mode} [dversion]]} { + # DEBUG mode + # initial CPU_time for LINUX in DEBUG mode is 902 ((410+41)*2) sec + puts "Checking LINUX performance in debug mode..." + if {$CPU_time > 902.} { + puts "ERROR: OCC25487 is reproduced." + puts " Low performance: $CPU_time (but should be less than 902 sec)" + } else { + puts "Done!" + } + } else { + # OPTIMIZE mode + # initial CPU_time for LINUX in OPTIMIZE mode is 451 (410+41) sec + puts "Checking LINUX performance in optimize mode..." + if {$CPU_time > 451.} { + puts "ERROR: OCC25487 is reproduced." + puts " Low performance: $CPU_time (but should be less than 451 sec)" + } else { + puts "Done!" + } + } +}