From: abv Date: Wed, 15 Apr 2015 19:40:58 +0000 (+0300) Subject: 0026064: distmini of two edges locks up X-Git-Tag: V6_9_0~53 X-Git-Url: http://git.dev.opencascade.org/gitweb/?p=occt.git;a=commitdiff_plain;h=6ca1fa707006770c63fe2a31272c8c0edc3de255 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. --- diff --git a/src/Extrema/Extrema.cdl b/src/Extrema/Extrema.cdl index b7b6942e90..41d873cfc4 100644 --- a/src/Extrema/Extrema.cdl +++ b/src/Extrema/Extrema.cdl @@ -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, diff --git a/src/Extrema/Extrema_GenExtCC.cdl b/src/Extrema/Extrema_GenExtCC.cdl index a3278b0490..a126b92ecf 100644 --- a/src/Extrema/Extrema_GenExtCC.cdl +++ b/src/Extrema/Extrema_GenExtCC.cdl @@ -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]; diff --git a/src/Extrema/Extrema_GenExtCC.gxx b/src/Extrema/Extrema_GenExtCC.gxx index a793d9c3dd..ba07b73781 100644 --- a/src/Extrema/Extrema_GenExtCC.gxx +++ b/src/Extrema/Extrema_GenExtCC.gxx @@ -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; - - 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 - { + continue; + } + + // 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) - } - } + } + else + { + aF = aCurrF; + myPoints1.Clear(); + myPoints2.Clear(); + } - // 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()) + // save found solutions avoiding repetitions + math_Vector sol(1,2); + for(k = 1; k <= aFinder.NbExtrema(); k++) { - // Points with indexes i and j is in same cluster, delete j point from extrema array. - myPoints1.Remove(j); - myPoints2.Remove(j); - j--; - mySolCount--; + 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(); } //======================================================================= diff --git a/tests/bugs/modalg_6/bug26064 b/tests/bugs/modalg_6/bug26064 new file mode 100644 index 0000000000..41a26054b6 --- /dev/null +++ b/tests/bugs/modalg_6/bug26064 @@ -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