0023906: Performance of the projection algorithm in some cases became lower after...
authoremv <emv@opencascade.com>
Thu, 16 May 2013 13:55:09 +0000 (17:55 +0400)
committeremv <emv@opencascade.com>
Thu, 16 May 2013 13:55:09 +0000 (17:55 +0400)
New search algorithm Extrema_ExtAlgo_Tree used in projection algorithm in Boolean Operations.
Extrema is set to search only min distance.
Add test case for this fix
Draw command projponf has been modified to provide possibility to change the default parameters of Extrema_ExtPS algorithm:
projponf f pnt [extrema flag: -min/-max/-minmax] [extrema algo: -g(grad)/-t(tree)]
-min - Extrema_ExtFlag_MIN;
-max - Extrema_ExtFlag_MAX;
-minmax - Extrema_ExtFlag_MINMAX (default);
-g - Extrema_ExtAlgo_Grad (default);
-t - Extrema_ExtAlgo_Tree;
Examples:
projponf f pnt -min  - the parameters are Extrema_ExtFlag_MIN and Extrema_ExtAlgo_Grad;
projponf f pnt -t  - the parameters are Extrema_ExtFlag_MINMAX and Extrema_ExtAlgo_Tree;
projponf f pnt -min -t  - the parameters are Extrema_ExtFlag_MIN and Extrema_ExtAlgo_Tree;

src/BOPInt/BOPInt_Context.cxx
src/TestTopOpe/TestTopOpe_CORCommands.cxx
src/TopOpeBRepTool/TopOpeBRepTool_PROJECT.cxx
src/TopOpeBRepTool/TopOpeBRepTool_PROJECT.hxx
tests/bugs/modalg_5/bug23906 [new file with mode: 0755]

index 1db3905..109ad6b 100644 (file)
     //
     pProjPS=(GeomAPI_ProjectPointOnSurf*)myAllocator->Allocate(sizeof(GeomAPI_ProjectPointOnSurf));
     new (pProjPS) GeomAPI_ProjectPointOnSurf();
-    pProjPS->Init(aS ,Umin, Usup, Vmin, Vsup, anEpsT);
+    pProjPS->Init(aS ,Umin, Usup, Vmin, Vsup, anEpsT, Extrema_ExtAlgo_Tree);
+    Extrema_ExtPS& anExtAlgo = const_cast<Extrema_ExtPS&>(pProjPS->Extrema());
+    anExtAlgo.SetFlag(Extrema_ExtFlag_MIN);
     //
     anAdr=(Standard_Address)pProjPS;
     myProjPSMap.Bind(aF, anAdr);
index 8f02967..694ea03 100755 (executable)
@@ -73,6 +73,9 @@
 #include <Draw_Color.hxx>
 #include <DBRep.hxx>
 
+#include <Extrema_ExtFlag.hxx>
+#include <Extrema_ExtAlgo.hxx>
+
 #ifdef DRAW
 #include <TopOpeBRepTool_DRAW.hxx>
 #endif
@@ -671,16 +674,57 @@ static Standard_Integer pntonc2d(Draw_Interpretor& di, Standard_Integer n, const
 
 static Standard_Integer projponf(Draw_Interpretor& di, Standard_Integer n, const char** a)
 {
-  if (n < 3) return 1;
+  if (n < 3) {
+    di << "projponf f pnt [extrema flag: -min/-max/-minmax] [extrema algo: -g(grad)/-t(tree)]\n";
+    return 1;
+  }
+  //
   TopoDS_Shape aLocalShape = DBRep::Get(a[1]);
   TopoDS_Face f = TopoDS::Face(aLocalShape);
-//  TopoDS_Face f = TopoDS::Face(DBRep::Get(a[1]));
-  if (f.IsNull()) {di<<"null shape"<<"\n";return 1;}
-  gp_Pnt p; DrawTrSurf::GetPoint(a[2], p);
-  Standard_Real dist=0.; gp_Pnt2d uv; Standard_Boolean ok = FUN_tool_projPonF(p,f,uv,dist);
-  if (!ok) {di<<"projection failed"<<"\n"; return 1;}
-  gp_Pnt pproj; ok = FUN_tool_value(uv,f,pproj);
-  if (!ok) {di<<"projection failed"<<"\n"; return 1;}
+  //
+  if (f.IsNull()) {
+    di<<"null shape"<<"\n";
+    return 1;
+  }
+  //
+  Standard_Real dist=0.;
+  Standard_Boolean ok;
+  gp_Pnt2d uv;
+  gp_Pnt p, pproj; 
+  Extrema_ExtAlgo aExtAlgo = Extrema_ExtAlgo_Grad;
+  Extrema_ExtFlag aExtFlag = Extrema_ExtFlag_MINMAX;
+  //
+  DrawTrSurf::GetPoint(a[2], p);
+  //
+  if (n > 3) {
+    const char* key1 = a[3];
+    const char* key2 = (n > 4) ? a[4] : NULL;
+    if (key1) {
+      if (!strcasecmp(key1,"-min")) {
+        aExtFlag = Extrema_ExtFlag_MIN;
+      } else if (!strcasecmp(key1,"-max")) {
+        aExtFlag = Extrema_ExtFlag_MAX;
+      } else {
+        aExtAlgo = (!strcasecmp(key1,"-t")) ? Extrema_ExtAlgo_Tree : aExtAlgo;
+      }
+    }
+    if (key2) {
+      aExtAlgo = (!strcasecmp(key2,"-t")) ? Extrema_ExtAlgo_Tree : aExtAlgo;
+    }
+  }
+  ok = FUN_tool_projPonF(p, f, uv, dist, aExtFlag, aExtAlgo);
+  //
+  if (!ok) {
+    di<<"projection failed"<<"\n"; 
+    return 1;
+  }
+  //
+  ok = FUN_tool_value(uv,f,pproj);
+  if (!ok) {
+    di<<"projection failed"<<"\n"; 
+    return 1;
+  }
+  //
   di<<"proj dist = "<<dist<<" uvproj = ("<<uv.X()<<" "<<uv.Y();
   di<<"); pproj = ("<<pproj.X()<<" "<<pproj.Y()<<" "<<pproj.Z()<<")"<<"\n";
   return 0;
@@ -878,7 +922,9 @@ void TestTopOpe::CORCommands(Draw_Interpretor& theCommands)
   theCommands.Add("classibnd2d","classibnd2d W1 W2 F i",    __FILE__, classifBnd2d, g);
   theCommands.Add("pntonc",     "pntonc par C3d",           __FILE__, pntonc, g);
   theCommands.Add("pntonc2d",   "pntonc2d par C2d S",       __FILE__, pntonc2d, g);
-  theCommands.Add("projponf",   "projponf f pnt",           __FILE__, projponf, g);
+  theCommands.Add("projponf",   
+                  "projponf f pnt [extrema flag: -min/-max/-minmax] [extrema algo: -g(grad)/-t(tree)]",
+                                                            __FILE__, projponf, g);
   theCommands.Add("tolmax",     "tolmax s",                 __FILE__, tolmax, g);
   theCommands.Add("normal",     "normal f p3d length",      __FILE__, normal, g);
   theCommands.Add("curvature",  "curvature f x y z",        __FILE__, curvature , g);
index c4c748f..b55e9ba 100755 (executable)
@@ -201,10 +201,21 @@ Standard_EXPORT Standard_Boolean FUN_tool_projPonC2D(const gp_Pnt& P,
 
 // ----------------------------------------------------------------------
 Standard_EXPORT Standard_Boolean FUN_tool_projPonS(const gp_Pnt& P,
-                                     const Handle(Geom_Surface)& S,
-                                     gp_Pnt2d& UV,Standard_Real& dist)
-{  
-  GeomAPI_ProjectPointOnSurf PonS(P,S);
+                                                   const Handle(Geom_Surface)& S,
+                                                   gp_Pnt2d& UV,Standard_Real& dist,
+                                                   const Extrema_ExtFlag aExtFlag,
+                                                   const Extrema_ExtAlgo aExtAlgo)
+{ 
+  Standard_Real UMin, UMax, VMin, VMax;
+  GeomAPI_ProjectPointOnSurf PonS;
+  //
+  S->Bounds(UMin, UMax, VMin, VMax);
+  PonS.Init(S, UMin, UMax, VMin, VMax, aExtAlgo);
+  Extrema_ExtPS& anExtAlgo = const_cast<Extrema_ExtPS&>(PonS.Extrema());
+  anExtAlgo.SetFlag(aExtFlag);
+  //
+  PonS.Perform(P);
+  //
   if (!PonS.Extrema().IsDone()) return Standard_False;
   if (PonS.NbPoints() == 0) return Standard_False;
   dist = PonS.LowerDistance();
@@ -272,10 +283,12 @@ Standard_EXPORT Standard_Boolean FUN_tool_projPonboundedF(const gp_Pnt& P,const
 
 // ----------------------------------------------------------------------
 Standard_EXPORT Standard_Boolean FUN_tool_projPonF(const gp_Pnt& P,const TopoDS_Face& F,
-                                     gp_Pnt2d& UV,Standard_Real& dist)
+                                                   gp_Pnt2d& UV,Standard_Real& dist,
+                                                   const Extrema_ExtFlag aExtFlag,
+                                                   const Extrema_ExtAlgo aExtAlgo)
 {
   dist = 1.;
   Handle(Geom_Surface) S = BRep_Tool::Surface(F);
-  Standard_Boolean ok = FUN_tool_projPonS(P,S,UV,dist);
+  Standard_Boolean ok = FUN_tool_projPonS(P,S,UV,dist, aExtFlag, aExtAlgo);
   return ok;
 }
index 04d62b9..daa63e9 100755 (executable)
@@ -31,6 +31,8 @@
 #include <BRepAdaptor_Curve2d.hxx>
 #include <Extrema_ExtPC.hxx>
 #include <Extrema_ExtPC2d.hxx>
+#include <Extrema_ExtFlag.hxx>
+#include <Extrema_ExtAlgo.hxx>
 
 // ----------------------------------------------------------------------
 //  project point <P> on geometries (curve <C>,surface <S>)
@@ -44,7 +46,9 @@ Standard_EXPORT Standard_Boolean FUN_tool_projPonC(const gp_Pnt& P,const BRepAda
 Standard_EXPORT Standard_Boolean FUN_tool_projPonC2D(const gp_Pnt& P,const Standard_Real tole,const BRepAdaptor_Curve2d& BAC2D,const Standard_Real pmin,const Standard_Real pmax,Standard_Real& param,Standard_Real& dist);
 Standard_EXPORT Standard_Boolean FUN_tool_projPonC2D(const gp_Pnt& P,const BRepAdaptor_Curve2d& BAC2D,const Standard_Real pmin,const Standard_Real pmax,Standard_Real& param,Standard_Real& dist);
 Standard_EXPORT Standard_Boolean FUN_tool_projPonC2D(const gp_Pnt& P,const BRepAdaptor_Curve2d& BAC2D,Standard_Real& param,Standard_Real& dist);
-Standard_EXPORT Standard_Boolean FUN_tool_projPonS(const gp_Pnt& P,const Handle(Geom_Surface)& S,gp_Pnt2d& UV,Standard_Real& dist);
+Standard_EXPORT Standard_Boolean FUN_tool_projPonS(const gp_Pnt& P,const Handle(Geom_Surface)& S,gp_Pnt2d& UV,Standard_Real& dist,
+                                                   const Extrema_ExtFlag aExtFlag=Extrema_ExtFlag_MINMAX,
+                                                   const Extrema_ExtAlgo aExtAlgo=Extrema_ExtAlgo_Grad);
 
 // ----------------------------------------------------------------------
 //  project point <P> on topologies (edge <E>,face <F>)
@@ -52,6 +56,8 @@ Standard_EXPORT Standard_Boolean FUN_tool_projPonS(const gp_Pnt& P,const Handle(
 Standard_EXPORT Standard_Boolean FUN_tool_projPonE(const gp_Pnt& P,const Standard_Real tole,const TopoDS_Edge& E,Standard_Real& param,Standard_Real& dist);
 Standard_EXPORT Standard_Boolean FUN_tool_projPonE(const gp_Pnt& P,const TopoDS_Edge& E,Standard_Real& param,Standard_Real& dist);
 Standard_EXPORT Standard_Boolean FUN_tool_projPonboundedF(const gp_Pnt& P,const TopoDS_Face& F,gp_Pnt2d& UV,Standard_Real& dist);
-Standard_EXPORT Standard_Boolean FUN_tool_projPonF(const gp_Pnt& P,const TopoDS_Face& F,gp_Pnt2d& UV,Standard_Real& dist);
+Standard_EXPORT Standard_Boolean FUN_tool_projPonF(const gp_Pnt& P,const TopoDS_Face& F,gp_Pnt2d& UV,Standard_Real& dist,
+                                                   const Extrema_ExtFlag aExtFlag=Extrema_ExtFlag_MINMAX,
+                                                   const Extrema_ExtAlgo aExtAlgo=Extrema_ExtAlgo_Grad);
 
 #endif
diff --git a/tests/bugs/modalg_5/bug23906 b/tests/bugs/modalg_5/bug23906
new file mode 100755 (executable)
index 0000000..2e6c980
--- /dev/null
@@ -0,0 +1,34 @@
+puts "============"
+puts "OCC23906"
+puts "============"
+puts ""
+###############################
+## Performance of the projection algorithm in some cases became lower after integration of the fix for the bug 0022610
+###############################
+
+restore [locate_data_file bug23906_f.brep] f
+
+point p 3.5527136788005e-015 100 100
+
+dchrono h reset
+dchrono h start
+
+projponf f p -min -t
+
+dchrono h stop
+set q2 [dchrono h show]
+
+regexp {CPU user time: ([-0-9.+eE]+) seconds} $q2 full z
+puts "$z"
+if { [string compare $tcl_platform(platform) "windows"] == 0 }  {
+   puts "OS = Windows NT"
+   set max_time 0.2
+} else {
+   puts "OS = Linux"
+   set max_time 0.1
+}
+if { $z > ${max_time} } {                                         
+    puts "Elapsed time is more then ${max_time} seconds - Faulty"
+} else {
+    puts "Elapsed time is less then ${max_time} seconds - OK"
+}