0025413: Line-Shape intersection algorithm became 400 times slower
authorazv <azv@opencascade.com>
Wed, 5 Nov 2014 14:02:23 +0000 (17:02 +0300)
committerbugmaster <bugmaster@opencascade.com>
Wed, 5 Nov 2014 14:02:58 +0000 (17:02 +0300)
Changed the procedure of creating initial samples

Test-case for issue #25413

src/IntCurvesFace/IntCurvesFace_Intersector.cxx
src/QABugs/QABugs_19.cxx
tests/bugs/modalg_5/bug25413 [new file with mode: 0644]

index 0f93db9..383c23f 100644 (file)
@@ -91,47 +91,35 @@ IntCurvesFace_Intersector::IntCurvesFace_Intersector(const TopoDS_Face& Face,
     U1 = Hsurface->LastUParameter();
     V0 = Hsurface->FirstVParameter();
     V1 = Hsurface->LastVParameter();
-    //modified by NIZNHY-PKV Fri Apr 06 07:30:47 2012f
-    Standard_Boolean bFlag;
-    //
+
+    Standard_Real aURes = Hsurface->UResolution(1.0);
+    Standard_Real aVRes = Hsurface->VResolution(1.0);
+
+    // Checking correlation between number of samples and length of the face along each axis
+    const Standard_Real aTresh = 100.0;
+    const Standard_Integer aMinSamples = 10;
+    const Standard_Integer aMaxSamples = 40;
+    const Standard_Integer aMaxSamples2 = aMaxSamples * aMaxSamples;
+    Standard_Real dU = (U1 - U0) / aURes;
+    Standard_Real dV = (V1 - V0) / aVRes;
+    nbsu = myTopolTool->NbSamplesU();
+    nbsv = myTopolTool->NbSamplesV();
+    if (nbsu > aMaxSamples) nbsu = aMaxSamples;
+    if (nbsv > aMaxSamples) nbsv = aMaxSamples;
+
+    if (Max(dU, dV) > Min(dU, dV) * aTresh)
     {
-      Standard_Real dU, dV, dA, dB, aTresh; 
-      bFlag=Standard_True;
-      //
-      aTresh=100.;
-      dU=U1-U0;
-      dV=V1-V0;
-      dA=dU;
-      dB=dV;
-      if (dV>dU) {
-       dA=dV;
-       dB=dU;
+      nbsu = (Standard_Integer)(Sqrt(dU / dV) * aMaxSamples);
+      if (nbsu < aMinSamples) nbsu = aMinSamples;
+      nbsv = aMaxSamples2 / nbsu;
+      if (nbsv < aMinSamples)
+      {
+        nbsv = aMinSamples;
+        nbsu = aMaxSamples2 / aMinSamples;
       }
-      //
-      if (dB < Precision::PConfusion() || dA > dB * aTresh) {
-       bFlag=!bFlag;
-      }
-    }
-    //
-    if (bFlag) {
-      nbsu = myTopolTool->NbSamplesU();
-      nbsv = myTopolTool->NbSamplesV();
-      if(nbsu>40) nbsu = 40;
-      if(nbsv>40) nbsv = 40;
-      PtrOnPolyhedron = (IntCurveSurface_ThePolyhedronOfHInter *) 
-       new IntCurveSurface_ThePolyhedronOfHInter(Hsurface,nbsu,nbsv,U0,V0,U1,V1);
     }
-    //
-    /*
-    nbsu = myTopolTool->NbSamplesU();
-    nbsv = myTopolTool->NbSamplesV();
-    if(nbsu>40) nbsu = 40;
-    if(nbsv>40) nbsv = 40;
-    PtrOnPolyhedron = (IntCurveSurface_ThePolyhedronOfHInter *) 
-      new IntCurveSurface_ThePolyhedronOfHInter(Hsurface,nbsu,nbsv,U0,V0,U1,V1);
-      */
-    
-    //modified by NIZNHY-PKV Fri Apr 06 07:30:49 2012t
+    PtrOnPolyhedron = (IntCurveSurface_ThePolyhedronOfHInter *)
+        new IntCurveSurface_ThePolyhedronOfHInter(Hsurface,nbsu,nbsv,U0,V0,U1,V1);
   }
 }
 //=======================================================================
index 1f6de33..c57f4cd 100755 (executable)
@@ -2961,6 +2961,44 @@ static Standard_Integer OCC25348 (Draw_Interpretor& theDI,
   return 0;
 }
 
+#include <IntCurvesFace_ShapeIntersector.hxx>
+#include <BRepBndLib.hxx>
+//=======================================================================
+//function : OCC25413
+//purpose  : 
+//=======================================================================
+static Standard_Integer OCC25413 (Draw_Interpretor& di, Standard_Integer narg , const char** a)
+{
+  if (narg != 2) {
+    di << "Usage: " << a[0] << " invalid number of arguments" << "\n";
+    return 1;
+  }
+  TopoDS_Shape aShape = DBRep::Get (a[1]);
+
+  IntCurvesFace_ShapeIntersector Inter;
+  Inter.Load(aShape, Precision::Confusion());
+
+  Bnd_Box aBndBox;
+  BRepBndLib::Add(aShape, aBndBox);
+
+  gp_Dir aDir(0., 1., 0.);
+  const int N = 250;
+  Standard_Real xMin = aBndBox.CornerMin().X();
+  Standard_Real zMin = aBndBox.CornerMin().Z();
+  Standard_Real xMax = aBndBox.CornerMax().X();
+  Standard_Real zMax = aBndBox.CornerMax().Z();
+  Standard_Real xStep = (xMax - xMin) / N;
+  Standard_Real zStep = (zMax - zMin) / N;
+
+  for (Standard_Real x = xMin; x <= xMax; x += xStep)
+    for (Standard_Real z = zMin; z <= zMax; z += zStep)
+    {
+      gp_Pnt aPoint(x, 0.0, z);
+      gp_Lin aLine(aPoint, aDir);
+      Inter.PerformNearest(aLine, -100., 100.);
+    }
+  return 0;
+}
 
 void QABugs::Commands_19(Draw_Interpretor& theCommands) {
   const char *group = "QABugs";
@@ -3021,5 +3059,6 @@ void QABugs::Commands_19(Draw_Interpretor& theCommands) {
   theCommands.Add ("OCC25100", "OCC25100 shape", __FILE__, OCC25100, group);
   theCommands.Add ("OCC25340", "OCC25340", __FILE__, OCC25340, group);
   theCommands.Add ("OCC25348", "OCC25348", __FILE__, OCC25348, group);
+  theCommands.Add ("OCC25413", "OCC25413 shape", __FILE__, OCC25413, group);
   return;
 }
diff --git a/tests/bugs/modalg_5/bug25413 b/tests/bugs/modalg_5/bug25413
new file mode 100644 (file)
index 0000000..afb3ba9
--- /dev/null
@@ -0,0 +1,65 @@
+puts "========"
+puts "OCC25413"
+puts "========"
+puts ""
+#############################################################
+# Line-Shape intersection algorithm became 400 times slower
+#############################################################
+
+pload QAcommands
+
+restore [locate_data_file bug25413.brep] w
+
+dchrono perf_h reset
+dchrono perf_h start
+OCC25413 w
+dchrono perf_h stop
+
+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"
+
+set currentOS $tcl_platform(os)
+if {[string compare $currentOS "Windows NT"] == 0} {
+  if {[regexp {Debug mode} [dversion]]} {
+    # initial CPU_time for WINDOWS in DEBUG mode is 90 sec
+    puts "Checking WINDOWS performance in debug mode..."
+    if {$CPU_time > 90.} {
+      puts "ERROR: OCC25413 is reproduced."
+      puts "       Low performance: $CPU_time (but should be less than 90 sec)"
+    } else {
+      puts "Done!"
+    }
+  } else {
+    puts "Checking WINDOWS performance in optimize mode..."
+    # initial CPU_time for WINDOWS in OPTIMIZE mode is 30 sec
+    if {$CPU_time > 30.} {
+      puts "ERROR: OCC25413 is reproduced."
+      puts "       Low performance: $CPU_time (but should be less than 30 sec)"
+    } else {
+      puts "Done!"
+    }
+  }
+}
+if {[string compare $currentOS "Linux"] == 0} {
+  if {[regexp {Debug mode} [dversion]]} {
+    # initial CPU_time for LINUX in DEBUG mode is 90 sec
+    puts "Checking LINUX performance in debug mode..."
+    if {$CPU_time > 90.} {
+      puts "ERROR: OCC25413 is reproduced."
+      puts "       Low performance: $CPU_time (but should be less than 90 sec)"
+    } else {
+      puts "Done!"
+    }
+  } else {
+    puts "Checking LINUX performance in optimize mode..."
+    # initial CPU_time for LINUX in OPTIMIZE mode is 30 sec
+    if {$CPU_time > 30.} {
+      puts "ERROR: OCC25413 is reproduced."
+      puts "       Low performance: $CPU_time (but should be less than 30 sec)"
+    } else {
+      puts "Done!"
+    }
+  }
+}