0026064: distmini of two edges locks up
authorabv <abv@opencascade.com>
Wed, 15 Apr 2015 19:40:58 +0000 (22:40 +0300)
committerbugmaster <bugmaster@opencascade.com>
Thu, 30 Apr 2015 10:19:23 +0000 (13:19 +0300)
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.

src/Extrema/Extrema.cdl
src/Extrema/Extrema_GenExtCC.cdl
src/Extrema/Extrema_GenExtCC.gxx
tests/bugs/modalg_6/bug26064 [new file with mode: 0644]

index b7b6942e908a328112178f93a7c48393f1b334bf..41d873cfc41174b6d43dfdafe0dd0317c85ae567 100644 (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,
index a3278b0490a842913d28c48335f7f5f51181042d..a126b92ecf21bf9cee3892c24fde1c09b940278f 100644 (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];
index a793d9c3dda137ff5ebee4042610fec166fae1fc..ba07b737814ba4b5c6b0a427a8e7d716bfacf8f2 100644 (file)
 //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 (file)
index 0000000..41a2605
--- /dev/null
@@ -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