1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-03 17:56:21 +03:00

0026064: distmini of two edges locks up

Method Extrema_GenExtCC::Perform() refactored to avoid very inefficient (O(N^2)) algorithm of removal of duplicate points at the end. Instead, duplications are checked when new points are added.

Fields are initialized in constructors of the class Extrema_GenExtCC; unused instances of generic classes (duplications) ELCC and ELCC2d removed.

Test case bugs/modalg_6/bug26064 added.
This commit is contained in:
abv 2015-04-15 22:40:58 +03:00 committed by bugmaster
parent 0a66e59dad
commit 6ca1fa7070
4 changed files with 59 additions and 75 deletions

View File

@ -138,16 +138,6 @@ is
class LocateExtCC;
class ELCC instantiates GenExtCC from Extrema
(Curve from Adaptor3d,
CurveTool from Extrema,
Curve from Adaptor3d,
CurveTool from Extrema,
HArray1OfPnt from TColgp,
POnCurv from Extrema,
Pnt from gp,
Vec from gp);
class LocECC instantiates GenLocateExtCC from Extrema
(Curve from Adaptor3d,
CurveTool from Extrema,
@ -172,17 +162,6 @@ is
class LocateExtCC2d;
class ELCC2d instantiates GenExtCC from Extrema
(Curve2d from Adaptor2d,
Curve2dTool from Extrema,
Curve2d from Adaptor2d,
Curve2dTool from Extrema,
HArray1OfPnt2d from TColgp,
POnCurv2d from Extrema,
Pnt2d from gp,
Vec2d from gp);
class LocECC2d instantiates GenLocateExtCC from Extrema
(Curve2d from Adaptor2d,
Curve2dTool from Extrema,

View File

@ -99,7 +99,6 @@ fields
myCurveMinTol : Real from Standard;
myLowBorder : Vector from math;
myUppBorder : Vector from math;
mySolCount : Integer from Standard;
myPoints1 : SequenceOfReal from TColStd;
myPoints2 : SequenceOfReal from TColStd;
myC : Address from Standard [2];

View File

@ -27,10 +27,12 @@
//purpose :
//=======================================================================
Extrema_GenExtCC::Extrema_GenExtCC()
: myLowBorder(1,2),
: myCurveMinTol(Precision::PConfusion()),
myLowBorder(1,2),
myUppBorder(1,2),
myDone(Standard_False)
{
myC[0] = myC[1] = 0;
}
//=======================================================================
@ -39,7 +41,8 @@ Extrema_GenExtCC::Extrema_GenExtCC()
//=======================================================================
Extrema_GenExtCC::Extrema_GenExtCC(const Curve1& C1,
const Curve2& C2)
: myLowBorder(1,2),
: myCurveMinTol(Precision::PConfusion()),
myLowBorder(1,2),
myUppBorder(1,2),
myDone(Standard_False)
{
@ -49,7 +52,6 @@ Extrema_GenExtCC::Extrema_GenExtCC(const Curve1& C1,
myLowBorder(2) = C2.FirstParameter();
myUppBorder(1) = C1.LastParameter();
myUppBorder(2) = C2.LastParameter();
myCurveMinTol = 1.0e-9;
}
//=======================================================================
@ -62,7 +64,8 @@ Extrema_GenExtCC::Extrema_GenExtCC(const Curve1& C1,
const Standard_Real Usup,
const Standard_Real Vinf,
const Standard_Real Vsup)
: myLowBorder(1,2),
: myCurveMinTol(Precision::PConfusion()),
myLowBorder(1,2),
myUppBorder(1,2),
myDone(Standard_False)
{
@ -72,7 +75,6 @@ Extrema_GenExtCC::Extrema_GenExtCC(const Curve1& C1,
myLowBorder(2) = Vinf;
myUppBorder(1) = Usup;
myUppBorder(2) = Vsup;
myCurveMinTol = 1.0e-9;
}
//=======================================================================
@ -122,13 +124,16 @@ void Extrema_GenExtCC::Perform()
C1.Intervals(anIntervals1, GeomAbs_C2);
C2.Intervals(anIntervals2, GeomAbs_C2);
math_MultipleVarFunction *aFunc = new Extrema_GlobOptFuncCCC2(C1, C2);
math_GlobOptMin aFinder(aFunc, myLowBorder, myUppBorder);
Extrema_GlobOptFuncCCC2 aFunc (C1, C2);
math_GlobOptMin aFinder(&aFunc, myLowBorder, myUppBorder);
Standard_Real aDiscTol = 1.0e-2;
Standard_Real aValueTol = 1.0e-2;
Standard_Real aSameTol = myCurveMinTol / (aDiscTol);
aFinder.SetTol(aDiscTol, aSameTol);
Standard_Real anEps1 = (myUppBorder(1) - myLowBorder(1)) * Precision::Confusion();
Standard_Real anEps2 = (myUppBorder(2) - myLowBorder(2)) * Precision::Confusion();
Standard_Integer i,j,k;
math_Vector aFirstBorderInterval(1,2);
math_Vector aSecondBorderInterval(1,2);
@ -146,60 +151,49 @@ void Extrema_GenExtCC::Perform()
aFinder.SetLocalParams(aFirstBorderInterval, aSecondBorderInterval);
aFinder.Perform();
// check that solution found on current interval is not worse than previous
aCurrF = aFinder.GetF();
if (aCurrF < aF + aSameTol * aValueTol)
if (aCurrF >= aF + aSameTol * aValueTol)
{
if (aCurrF > aF - aSameTol * aValueTol)
{
if (aCurrF < aF)
aF = aCurrF;
continue;
}
math_Vector sol(1,2);
Standard_Integer myTmpSolCount = aFinder.NbExtrema();
for(k = 1; k <= myTmpSolCount; k++)
{
aFinder.Points(k, sol);
myPoints1.Append(sol(1));
myPoints2.Append(sol(2));
}
mySolCount += myTmpSolCount;
} // if (aCurrF > aF - aSameTol * aValueTol)
else
{
// clean previously computed solution if current one is better
if (aCurrF > aF - aSameTol * aValueTol)
{
if (aCurrF < aF)
aF = aCurrF;
mySolCount = aFinder.NbExtrema();
myPoints1.Clear();
myPoints2.Clear();
math_Vector sol(1,2);
for(k = 1; k <= mySolCount; k++)
{
aFinder.Points(k, sol);
myPoints1.Append(sol(1));
myPoints2.Append(sol(2));
}
} // else
} //if (aCurrF < aF + aSameTol * aValueTol)
}
}
// Clear solutions clusters if it is necessary.
for(i = 1; i <= mySolCount - 1; i++)
{
for(j = i + 1; j <= mySolCount; j++)
{
if (Abs(myPoints1(i) - myPoints1(j)) < (myUppBorder(1) - myLowBorder(1)) * Precision::Confusion() &&
Abs(myPoints2(i) - myPoints2(j)) < (myUppBorder(2) - myLowBorder(2)) * Precision::Confusion())
}
else
{
// Points with indexes i and j is in same cluster, delete j point from extrema array.
myPoints1.Remove(j);
myPoints2.Remove(j);
j--;
mySolCount--;
aF = aCurrF;
myPoints1.Clear();
myPoints2.Clear();
}
// save found solutions avoiding repetitions
math_Vector sol(1,2);
for(k = 1; k <= aFinder.NbExtrema(); k++)
{
aFinder.Points(k, sol);
// avoid duplicated points
Standard_Boolean isNew = Standard_True;
for (Standard_Integer iSol = 1; isNew && iSol <= myPoints1.Length(); iSol++)
{
if (Abs(myPoints1(iSol) - sol(1)) < anEps1 &&
Abs(myPoints2(iSol) - sol(2)) < anEps2)
isNew = Standard_False;
}
if (isNew)
{
myPoints1.Append(sol(1));
myPoints2.Append(sol(2));
}
}
}
}
delete aFunc;
myDone = Standard_True;
}
@ -220,7 +214,7 @@ Standard_Integer Extrema_GenExtCC::NbExt() const
{
StdFail_NotDone_Raise_if (!myDone, "Extrema_GenExtCC::NbExt()")
return mySolCount;
return myPoints1.Length();
}
//=======================================================================

View File

@ -0,0 +1,12 @@
puts "========"
puts "OCC26064"
puts "========"
puts ""
###########################################################
# distmini of two edges locks up
###########################################################
pload MODELING
restore [locate_data_file dist1-s1.brep] s1
restore [locate_data_file dist1-s2.brep] s2
distmini d s1 s2