1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-14 13:30:48 +03:00

0025487: Extrema_GenExtPS needs to be optimized

Better caching and cashe usage in Extrema_GenExtPS.

Test-cases for issue #25487

Update of test-cases
This commit is contained in:
aml
2014-11-28 13:19:30 +03:00
committed by bugmaster
parent 4a913f2102
commit 150e93a7f2
6 changed files with 315 additions and 126 deletions

View File

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

View File

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

View File

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

View File

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

View File

@@ -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!"
}
}
}

View File

@@ -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!"
}
}
}