mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-04-16 10:08:36 +03:00
0025407: Exception in extrema operation.
Special handling of curve / surface of extrusion case is deleted. Corresponding test case fixed. Test cases for issue CR25407
This commit is contained in:
parent
50d0e1cefd
commit
032d027214
@ -203,140 +203,94 @@ void Extrema_GenExtCS::Perform (const Adaptor3d_Curve& C,
|
|||||||
TUVsup(1) = mytsup;
|
TUVsup(1) = mytsup;
|
||||||
TUVsup(2) = trimusup;
|
TUVsup(2) = trimusup;
|
||||||
TUVsup(3) = trimvsup;
|
TUVsup(3) = trimvsup;
|
||||||
// 18/02/02 akm vvv : (OCC163) bad extremas - extrusion surface versus the line.
|
|
||||||
// Try to preset the initial solution as extrema between
|
// Number of particles used in PSO algorithm (particle swarm optimization).
|
||||||
// extrusion direction and the curve.
|
const Standard_Integer aNbParticles = 32;
|
||||||
if (myS->GetType() == GeomAbs_SurfaceOfExtrusion)
|
|
||||||
|
math_PSOParticlesPool aParticles(aNbParticles, 3);
|
||||||
|
|
||||||
|
math_Vector aMinTUV(1,3);
|
||||||
|
aMinTUV = TUVinf + (TUVsup - TUVinf) / aBorderDivisor;
|
||||||
|
|
||||||
|
math_Vector aMaxTUV(1,3);
|
||||||
|
aMaxTUV = TUVsup - (TUVsup - TUVinf) / aBorderDivisor;
|
||||||
|
|
||||||
|
Standard_Real aStepCU = (aMaxTUV(1) - aMinTUV(1)) / mytsample;
|
||||||
|
Standard_Real aStepSU = (aMaxTUV(2) - aMinTUV(2)) / myusample;
|
||||||
|
Standard_Real aStepSV = (aMaxTUV(3) - aMinTUV(3)) / myvsample;
|
||||||
|
|
||||||
|
// Correct number of curve samples in case of low resolution
|
||||||
|
Standard_Real aScaleFactor = 5.0;
|
||||||
|
Standard_Real aResolutionCU = aStepCU / C.Resolution (1.0);
|
||||||
|
|
||||||
|
Standard_Real aMinResolution = aScaleFactor * Min (aResolutionCU,
|
||||||
|
Min (aStepSU / myS->UResolution (1.0), aStepSV / myS->VResolution (1.0)));
|
||||||
|
|
||||||
|
if (aMinResolution > Epsilon (1.0))
|
||||||
{
|
{
|
||||||
gp_Dir aDir = myS->Direction();
|
if (aResolutionCU > aMinResolution)
|
||||||
Handle(Adaptor3d_HCurve) aCurve = myS->BasisCurve();
|
|
||||||
Standard_Real dfUFirst = aCurve->FirstParameter();
|
|
||||||
// Create iso line of U=U0
|
|
||||||
GeomAdaptor_Curve anAx(new Geom_Line(aCurve->Value(dfUFirst), aDir),
|
|
||||||
trimvmin, trimvsup);
|
|
||||||
Extrema_ExtCC aLocator(C, anAx);
|
|
||||||
if (aLocator.IsDone() && aLocator.NbExt()>0)
|
|
||||||
{
|
{
|
||||||
Standard_Integer iExt;
|
const Standard_Integer aMaxNbNodes = 50;
|
||||||
// Try to find all extremas
|
|
||||||
Extrema_POnCurv aP1, aP2;
|
|
||||||
for (iExt=1; iExt<=aLocator.NbExt(); iExt++)
|
|
||||||
{
|
|
||||||
aLocator.Points (iExt, aP1, aP2);
|
|
||||||
// Parameter on curve
|
|
||||||
TUV(1) = aP1.Parameter();
|
|
||||||
// To find parameters on surf, try ExtPS
|
|
||||||
Extrema_ExtPS aPreciser (aP1.Value(), *myS, mytol2, mytol2);
|
|
||||||
if (aPreciser.IsDone())
|
|
||||||
{
|
|
||||||
// Managed to find extremas between point and surface
|
|
||||||
Standard_Integer iPExt;
|
|
||||||
for (iPExt=1; iPExt<=aPreciser.NbExt(); iPExt++)
|
|
||||||
{
|
|
||||||
aPreciser.Point(iPExt).Parameter(TUV(2),TUV(3));
|
|
||||||
math_FunctionSetRoot S1 (myF,TUV,Tol,TUVinf,TUVsup);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Failed... try the point on iso line
|
|
||||||
TUV(2) = dfUFirst;
|
|
||||||
TUV(3) = aP2.Parameter();
|
|
||||||
math_FunctionSetRoot S1 (myF,TUV,Tol,TUVinf,TUVsup);
|
|
||||||
}
|
|
||||||
} // for (iExt=1; iExt<=aLocator.NbExt(); iExt++)
|
|
||||||
} // if (aLocator.IsDone() && aLocator.NbExt()>0)
|
|
||||||
} // if (myS.Type() == GeomAbs_ExtrusionSurface)
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Number of particles used in PSO algorithm (particle swarm optimization).
|
|
||||||
const Standard_Integer aNbParticles = 32;
|
|
||||||
|
|
||||||
math_PSOParticlesPool aParticles(aNbParticles, 3);
|
mytsample = Min(aMaxNbNodes,
|
||||||
|
RealToInt(mytsample * aResolutionCU / aMinResolution));
|
||||||
|
|
||||||
math_Vector aMinTUV(1,3);
|
aStepCU = (aMaxTUV(1) - aMinTUV(1)) / mytsample;
|
||||||
aMinTUV = TUVinf + (TUVsup - TUVinf) / aBorderDivisor;
|
|
||||||
|
|
||||||
math_Vector aMaxTUV(1,3);
|
|
||||||
aMaxTUV = TUVsup - (TUVsup - TUVinf) / aBorderDivisor;
|
|
||||||
|
|
||||||
Standard_Real aStepCU = (aMaxTUV(1) - aMinTUV(1)) / mytsample;
|
|
||||||
Standard_Real aStepSU = (aMaxTUV(2) - aMinTUV(2)) / myusample;
|
|
||||||
Standard_Real aStepSV = (aMaxTUV(3) - aMinTUV(3)) / myvsample;
|
|
||||||
|
|
||||||
// Correct number of curve samples in case of low resolution
|
|
||||||
Standard_Real aScaleFactor = 5.0;
|
|
||||||
Standard_Real aResolutionCU = aStepCU / C.Resolution (1.0);
|
|
||||||
|
|
||||||
Standard_Real aMinResolution = aScaleFactor * Min (aResolutionCU,
|
|
||||||
Min (aStepSU / myS->UResolution (1.0), aStepSV / myS->VResolution (1.0)));
|
|
||||||
|
|
||||||
if (aMinResolution > Epsilon (1.0))
|
|
||||||
{
|
|
||||||
if (aResolutionCU > aMinResolution)
|
|
||||||
{
|
|
||||||
const Standard_Integer aMaxNbNodes = 50;
|
|
||||||
|
|
||||||
mytsample = Min(aMaxNbNodes,
|
|
||||||
RealToInt(mytsample * aResolutionCU / aMinResolution));
|
|
||||||
|
|
||||||
aStepCU = (aMaxTUV(1) - aMinTUV(1)) / mytsample;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pre-compute curve sample points.
|
|
||||||
TColgp_HArray1OfPnt aCurvPnts (0, mytsample);
|
|
||||||
|
|
||||||
Standard_Real aCU = aMinTUV(1);
|
|
||||||
for (Standard_Integer aCUI = 0; aCUI <= mytsample; aCUI++, aCU += aStepCU)
|
|
||||||
aCurvPnts.SetValue (aCUI, C.Value (aCU));
|
|
||||||
|
|
||||||
PSO_Particle* aParticle = aParticles.GetWorstParticle();
|
|
||||||
// Select specified number of particles from pre-computed set of samples
|
|
||||||
Standard_Real aSU = aMinTUV(2);
|
|
||||||
for (Standard_Integer aSUI = 0; aSUI <= myusample; aSUI++, aSU += aStepSU)
|
|
||||||
{
|
|
||||||
Standard_Real aSV = aMinTUV(3);
|
|
||||||
for (Standard_Integer aSVI = 0; aSVI <= myvsample; aSVI++, aSV += aStepSV)
|
|
||||||
{
|
|
||||||
Standard_Real aCU = aMinTUV(1);
|
|
||||||
for (Standard_Integer aCUI = 0; aCUI <= mytsample; aCUI++, aCU += aStepCU)
|
|
||||||
{
|
|
||||||
Standard_Real aSqDist = mySurfPnts->Value(aSUI, aSVI).SquareDistance(aCurvPnts.Value(aCUI));
|
|
||||||
|
|
||||||
if (aSqDist < aParticle->Distance)
|
|
||||||
{
|
|
||||||
aParticle->Position[0] = aCU;
|
|
||||||
aParticle->Position[1] = aSU;
|
|
||||||
aParticle->Position[2] = aSV;
|
|
||||||
|
|
||||||
aParticle->BestPosition[0] = aCU;
|
|
||||||
aParticle->BestPosition[1] = aSU;
|
|
||||||
aParticle->BestPosition[2] = aSV;
|
|
||||||
|
|
||||||
aParticle->Distance = aSqDist;
|
|
||||||
aParticle->BestDistance = aSqDist;
|
|
||||||
|
|
||||||
aParticle = aParticles.GetWorstParticle();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
math_Vector aStep(1,3);
|
|
||||||
aStep(1) = aStepCU;
|
|
||||||
aStep(2) = aStepSU;
|
|
||||||
aStep(3) = aStepSV;
|
|
||||||
|
|
||||||
// Find min approximation
|
|
||||||
Standard_Real aValue;
|
|
||||||
Extrema_GlobOptFuncCS aFunc(&C, myS);
|
|
||||||
math_PSO aPSO(&aFunc, TUVinf, TUVsup, aStep);
|
|
||||||
aPSO.Perform(aParticles, aNbParticles, aValue, TUV);
|
|
||||||
|
|
||||||
math_FunctionSetRoot anA (myF, TUV, Tol, TUVinf, TUVsup, 100, Standard_False);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Pre-compute curve sample points.
|
||||||
|
TColgp_HArray1OfPnt aCurvPnts (0, mytsample);
|
||||||
|
|
||||||
|
Standard_Real aCU = aMinTUV(1);
|
||||||
|
for (Standard_Integer aCUI = 0; aCUI <= mytsample; aCUI++, aCU += aStepCU)
|
||||||
|
aCurvPnts.SetValue (aCUI, C.Value (aCU));
|
||||||
|
|
||||||
|
PSO_Particle* aParticle = aParticles.GetWorstParticle();
|
||||||
|
// Select specified number of particles from pre-computed set of samples
|
||||||
|
Standard_Real aSU = aMinTUV(2);
|
||||||
|
for (Standard_Integer aSUI = 0; aSUI <= myusample; aSUI++, aSU += aStepSU)
|
||||||
|
{
|
||||||
|
Standard_Real aSV = aMinTUV(3);
|
||||||
|
for (Standard_Integer aSVI = 0; aSVI <= myvsample; aSVI++, aSV += aStepSV)
|
||||||
|
{
|
||||||
|
Standard_Real aCU = aMinTUV(1);
|
||||||
|
for (Standard_Integer aCUI = 0; aCUI <= mytsample; aCUI++, aCU += aStepCU)
|
||||||
|
{
|
||||||
|
Standard_Real aSqDist = mySurfPnts->Value(aSUI, aSVI).SquareDistance(aCurvPnts.Value(aCUI));
|
||||||
|
|
||||||
|
if (aSqDist < aParticle->Distance)
|
||||||
|
{
|
||||||
|
aParticle->Position[0] = aCU;
|
||||||
|
aParticle->Position[1] = aSU;
|
||||||
|
aParticle->Position[2] = aSV;
|
||||||
|
|
||||||
|
aParticle->BestPosition[0] = aCU;
|
||||||
|
aParticle->BestPosition[1] = aSU;
|
||||||
|
aParticle->BestPosition[2] = aSV;
|
||||||
|
|
||||||
|
aParticle->Distance = aSqDist;
|
||||||
|
aParticle->BestDistance = aSqDist;
|
||||||
|
|
||||||
|
aParticle = aParticles.GetWorstParticle();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
math_Vector aStep(1,3);
|
||||||
|
aStep(1) = aStepCU;
|
||||||
|
aStep(2) = aStepSU;
|
||||||
|
aStep(3) = aStepSV;
|
||||||
|
|
||||||
|
// Find min approximation
|
||||||
|
Standard_Real aValue;
|
||||||
|
Extrema_GlobOptFuncCS aFunc(&C, myS);
|
||||||
|
math_PSO aPSO(&aFunc, TUVinf, TUVsup, aStep);
|
||||||
|
aPSO.Perform(aParticles, aNbParticles, aValue, TUV);
|
||||||
|
|
||||||
|
math_FunctionSetRoot anA (myF, TUV, Tol, TUVinf, TUVsup, 100, Standard_False);
|
||||||
|
|
||||||
myDone = Standard_True;
|
myDone = Standard_True;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@ puts "========"
|
|||||||
puts ""
|
puts ""
|
||||||
###########################################################
|
###########################################################
|
||||||
## The result of extrema command is not correct.
|
## The result of extrema command is not correct.
|
||||||
## We have only two "max" extrema, but we should have "min" and "max".
|
## Extrema command return max, but it acceptable because relative error near 1.0e-30.
|
||||||
###########################################################
|
###########################################################
|
||||||
|
|
||||||
restore [locate_data_file OCC130.brep] res
|
restore [locate_data_file OCC130.brep] res
|
||||||
@ -17,14 +17,31 @@ mksurface s res
|
|||||||
|
|
||||||
set che [extrema l s]
|
set che [extrema l s]
|
||||||
set err [llength $che]
|
set err [llength $che]
|
||||||
if { $err < 2} {
|
|
||||||
puts "Error OCC163 (amount): command extrema does NOT work properly"
|
# Amount Check
|
||||||
|
if { $err != 1} {
|
||||||
|
puts "Error: Invalid extrema number"
|
||||||
}
|
}
|
||||||
|
|
||||||
set dum1 [dump [lindex $che 0]]
|
set status 0
|
||||||
set dum2 [dump [lindex $che 1]]
|
set info [dump ext_1]
|
||||||
|
regexp "Parameters : 0 +(\[-0-9*\.+eE\]+)" $info full extLength
|
||||||
|
|
||||||
if { $dum1 == $dum2} {
|
# Test max
|
||||||
puts "Error OCC163 (dump): command extrema does NOT work properly"
|
if { $extLength > 35 && $extLength < 36} {
|
||||||
|
set good_dist 35.6687907545308
|
||||||
|
checkreal "Max distance:" ${extLength} ${good_dist} 0.01 0.01
|
||||||
|
set status 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Test min
|
||||||
|
if {$extLength > 0 && $extLength < 1} {
|
||||||
|
set good_dist 0.0
|
||||||
|
checkreal "Min distance:" ${extLength} ${good_dist} 0.01 0.01
|
||||||
|
set status 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# Not min or max
|
||||||
|
if {$status == 0} {
|
||||||
|
puts "Error: wrong extrema point"
|
||||||
|
}
|
||||||
|
24
tests/bugs/moddata_3/bug25407_1
Executable file
24
tests/bugs/moddata_3/bug25407_1
Executable file
@ -0,0 +1,24 @@
|
|||||||
|
puts "================"
|
||||||
|
puts "OCC25407"
|
||||||
|
puts "================"
|
||||||
|
puts ""
|
||||||
|
#######################################################################
|
||||||
|
# Exception in extrema operation.
|
||||||
|
#######################################################################
|
||||||
|
|
||||||
|
restore [locate_data_file bug25407_e2.brep] e
|
||||||
|
restore [locate_data_file bug25407_f2.brep] f
|
||||||
|
|
||||||
|
mkcurve c e
|
||||||
|
mksurface s f
|
||||||
|
|
||||||
|
extrema c s
|
||||||
|
|
||||||
|
if { [isdraw ext_1] } {
|
||||||
|
mkedge result ext_1
|
||||||
|
set length 1.88322e-11
|
||||||
|
} else {
|
||||||
|
puts "Error: invalid result"
|
||||||
|
}
|
||||||
|
|
||||||
|
set 2dviewer 1
|
27
tests/bugs/moddata_3/bug25407_2
Executable file
27
tests/bugs/moddata_3/bug25407_2
Executable file
@ -0,0 +1,27 @@
|
|||||||
|
puts "================"
|
||||||
|
puts "OCC25407"
|
||||||
|
puts "================"
|
||||||
|
puts ""
|
||||||
|
#######################################################################
|
||||||
|
# Exception in extrema operation.
|
||||||
|
#######################################################################
|
||||||
|
|
||||||
|
restore [locate_data_file bug25407_e2.brep] e
|
||||||
|
restore [locate_data_file bug25407_f2.brep] f
|
||||||
|
|
||||||
|
mkcurve c e
|
||||||
|
mksurface s f
|
||||||
|
|
||||||
|
trim st s -0.168011130695572 0. -16.5 0.
|
||||||
|
trim ct c 1.1167213545471877e-008 0.033333343614041021
|
||||||
|
|
||||||
|
extrema ct st
|
||||||
|
|
||||||
|
if { [isdraw ext_1] } {
|
||||||
|
mkedge result ext_1
|
||||||
|
set length 1.00005e-07
|
||||||
|
} else {
|
||||||
|
puts "Error: invalid result"
|
||||||
|
}
|
||||||
|
|
||||||
|
set 2dviewer 1
|
Loading…
x
Reference in New Issue
Block a user