0030437: Visualization, TKV3d - add Draw command to print rendering statistics IR-2019-01-11
authorosa <osa@opencascade.com>
Thu, 10 Jan 2019 14:25:48 +0000 (17:25 +0300)
committerbugmaster <bugmaster@opencascade.com>
Fri, 11 Jan 2019 15:57:53 +0000 (18:57 +0300)
Add new command "vstatprofiler" to manage rendering parameters and print them.
If there are some input parameters - print corresponding statistic counters values,
else - print all performance counters set previously.

src/Graphic3d/Graphic3d_CView.hxx
src/Graphic3d/Graphic3d_FrameStats.cxx
src/Graphic3d/Graphic3d_FrameStats.hxx
src/OpenGl/OpenGl_View.cxx
src/OpenGl/OpenGl_View.hxx
src/V3d/V3d_View.cxx
src/V3d/V3d_View.hxx
src/ViewerTest/ViewerTest_ViewerCommands.cxx
tests/bugs/vis/bug30437 [new file with mode: 0644]
tests/bugs/vis/bug30437_1 [new file with mode: 0644]

index 1a2eda6..761e791 100644 (file)
@@ -415,6 +415,12 @@ public:
   virtual void DiagnosticInformation (TColStd_IndexedDataMapOfStringString& theDict,
                                       Graphic3d_DiagnosticInfo theFlags) const = 0;
 
+  //! Returns string with statistic performance info.
+  virtual TCollection_AsciiString StatisticInformation() const = 0;
+
+  //! Fills in the dictionary with statistic performance info.
+  virtual void StatisticInformation (TColStd_IndexedDataMapOfStringString& theDict) const = 0;
+
 private:
 
   //! Adds the structure to display lists of the view.
index 59045e1..eabb962 100644 (file)
@@ -149,6 +149,71 @@ namespace
     }
     return theStream;
   }
+
+  //! Add key-value pair to the dictionary.
+  static void addInfo (TColStd_IndexedDataMapOfStringString& theDict,
+                       const TCollection_AsciiString&        theKey,
+                       const char*                           theValue)
+  {
+    TCollection_AsciiString aValue (theValue != NULL ? theValue : "");
+    theDict.ChangeFromIndex (theDict.Add (theKey, aValue)) = aValue;
+  }
+
+  //! Add key-value pair to the dictionary.
+  static void addInfo (TColStd_IndexedDataMapOfStringString& theDict,
+                       const TCollection_AsciiString&        theKey,
+                       const Standard_Real                   theValue)
+  {
+    char aTmp[50];
+    Sprintf (aTmp, "%.1g", theValue);
+    addInfo (theDict, theKey, aTmp);
+  }
+
+  //! Add key-value pair to the dictionary.
+  static void addInfo (TColStd_IndexedDataMapOfStringString& theDict,
+                       const TCollection_AsciiString&        theKey,
+                       const Standard_Size                   theValue)
+  {
+    char aTmp[50];
+    Sprintf (aTmp, "%zu", theValue);
+    addInfo (theDict, theKey, aTmp);
+  }
+
+  //! Format time.
+  static void addTimeInfo (TColStd_IndexedDataMapOfStringString& theDict,
+                           const TCollection_AsciiString&        theKey,
+                           Standard_Real                         theSeconds)
+  {
+    Standard_Real aSecIn = theSeconds;
+    unsigned int aHours   = (unsigned int )(aSecIn * THE_SECOND_IN_HOUR);
+    aSecIn -= Standard_Real(aHours) * THE_SECONDS_IN_HOUR;
+    unsigned int aMinutes = (unsigned int )(aSecIn * THE_SECOND_IN_MINUTE);
+    aSecIn -= Standard_Real(aMinutes) * THE_SECONDS_IN_MINUTE;
+    unsigned int aSeconds = (unsigned int )aSecIn;
+    aSecIn -= Standard_Real(aSeconds);
+    Standard_Real aMilliSeconds = 1000.0 * aSecIn;
+
+    char aBuffer[64];
+    if (aHours > 0)
+    {
+      Sprintf (aBuffer, "%02u:%02u:%02u", aHours, aMinutes, aSeconds);
+    }
+    else if (aMinutes > 0)
+    {
+      Sprintf (aBuffer, "%02u:%02u", aMinutes, aSeconds);
+    }
+    else if (aSeconds > 0)
+    {
+      Sprintf (aBuffer, "%2u", aSeconds);
+    }
+    else
+    {
+      addInfo (theDict, theKey, aMilliSeconds);
+      return;
+    }
+    
+    addInfo (theDict, theKey, aBuffer);
+  }
 }
 
 // =======================================================================
@@ -325,6 +390,100 @@ TCollection_AsciiString Graphic3d_FrameStats::FormatStats (Graphic3d_RenderingPa
 }
 
 // =======================================================================
+// function : FormatStats
+// purpose  :
+// =======================================================================
+void Graphic3d_FrameStats::FormatStats (TColStd_IndexedDataMapOfStringString&   theDict,
+                                        Graphic3d_RenderingParams::PerfCounters theFlags) const
+{
+  const Graphic3d_FrameStatsData& aStats = LastDataFrame();
+  if ((theFlags & Graphic3d_RenderingParams::PerfCounters_FrameRate) != 0)
+  {
+    addInfo (theDict, "FPS", aStats.FrameRate());
+  }
+  if ((theFlags & Graphic3d_RenderingParams::PerfCounters_CPU) != 0)
+  {
+    addInfo (theDict, "CPU FPS", aStats.FrameRateCpu());
+  }
+  if ((theFlags & Graphic3d_RenderingParams::PerfCounters_Layers) != 0)
+  {
+    addInfo (theDict, "Layers", aStats[Graphic3d_FrameStatsCounter_NbLayers]);
+    if (HasCulledLayers())
+    {
+      addInfo (theDict, "Rendered layers", aStats[Graphic3d_FrameStatsCounter_NbLayersNotCulled]);
+    }
+  }
+  if ((theFlags & Graphic3d_RenderingParams::PerfCounters_Structures) != 0)
+  {
+    addInfo (theDict, "Structs", aStats[Graphic3d_FrameStatsCounter_NbStructs]);
+    if (HasCulledStructs())
+    {
+      addInfo (theDict, "Rendered structs", aStats[Graphic3d_FrameStatsCounter_NbStructsNotCulled]);
+    }
+  }
+  if ((theFlags & Graphic3d_RenderingParams::PerfCounters_Groups) != 0)
+  {
+    addInfo (theDict, "Rendered groups", aStats[Graphic3d_FrameStatsCounter_NbGroupsNotCulled]);
+  }
+  if ((theFlags & Graphic3d_RenderingParams::PerfCounters_GroupArrays) != 0)
+  {
+    addInfo (theDict, "Rendered arrays",         aStats[Graphic3d_FrameStatsCounter_NbElemsNotCulled]);
+    addInfo (theDict, "Rendered [fill] arrays",  aStats[Graphic3d_FrameStatsCounter_NbElemsFillNotCulled]);
+    addInfo (theDict, "Rendered [line] arrays",  aStats[Graphic3d_FrameStatsCounter_NbElemsLineNotCulled]);
+    addInfo (theDict, "Rendered [point] arrays", aStats[Graphic3d_FrameStatsCounter_NbElemsPointNotCulled]);
+    addInfo (theDict, "Rendered [text] arrays",  aStats[Graphic3d_FrameStatsCounter_NbElemsTextNotCulled]);
+  }
+  if ((theFlags & Graphic3d_RenderingParams::PerfCounters_Triangles) != 0)
+  {
+    addInfo (theDict, "Rendered triangles", aStats[Graphic3d_FrameStatsCounter_NbTrianglesNotCulled]);
+  }
+  if ((theFlags & Graphic3d_RenderingParams::PerfCounters_Points) != 0)
+  {
+    addInfo (theDict, "Rendered points", aStats[Graphic3d_FrameStatsCounter_NbPointsNotCulled]);
+  }
+  if ((theFlags & Graphic3d_RenderingParams::PerfCounters_EstimMem) != 0)
+  {
+    addInfo (theDict, "GPU Memory [geometry]", aStats[Graphic3d_FrameStatsCounter_EstimatedBytesGeom]);
+    addInfo (theDict, "GPU Memory [textures]", aStats[Graphic3d_FrameStatsCounter_EstimatedBytesTextures]);
+    addInfo (theDict, "GPU Memory [frames]",   aStats[Graphic3d_FrameStatsCounter_EstimatedBytesFbos]);
+  }
+
+  if ((theFlags & Graphic3d_RenderingParams::PerfCounters_FrameTime) != 0)
+  {
+    addTimeInfo (theDict, "Elapsed Frame (average)", aStats[Graphic3d_FrameStatsTimer_ElapsedFrame]);
+    addTimeInfo (theDict, "CPU Frame (average)",     aStats[Graphic3d_FrameStatsTimer_CpuFrame]);
+    if (myCountersMax[Graphic3d_FrameStatsTimer_CpuPicking] > 0.0)
+    {
+      addTimeInfo (theDict, "CPU Picking (average)", aStats[Graphic3d_FrameStatsTimer_CpuPicking]);
+    }
+    if (myCountersMax[Graphic3d_FrameStatsTimer_CpuCulling] > 0.0)
+    {
+      addTimeInfo (theDict, "CPU Culling (average)", aStats[Graphic3d_FrameStatsTimer_CpuCulling]);
+    }
+    if (myCountersMax[Graphic3d_FrameStatsTimer_CpuDynamics])
+    {
+      addTimeInfo (theDict, "CPU Dynamics (average)", aStats[Graphic3d_FrameStatsTimer_CpuDynamics]);
+    }
+    if ((theFlags & Graphic3d_RenderingParams::PerfCounters_FrameTimeMax) != 0)
+    {
+      addTimeInfo (theDict, "CPU Frame (max)", myCountersMax[Graphic3d_FrameStatsTimer_CpuFrame]);
+      if (myCountersMax[Graphic3d_FrameStatsTimer_CpuPicking] > 0.0)
+      {
+        addTimeInfo (theDict, "CPU Picking (max)", myCountersMax[Graphic3d_FrameStatsTimer_CpuPicking]);
+      }
+      if (myCountersMax[Graphic3d_FrameStatsTimer_CpuCulling] > 0.0)
+      {
+        addTimeInfo (theDict, "CPU Culling (max)", myCountersMax[Graphic3d_FrameStatsTimer_CpuCulling]);
+      }
+      if (myCountersMax[Graphic3d_FrameStatsTimer_CpuDynamics])
+      {
+        addTimeInfo (theDict, "CPU Dynamics (max)", myCountersMax[Graphic3d_FrameStatsTimer_CpuDynamics]);
+      }
+    }
+  }
+}
+
+// =======================================================================
 // function : FrameStart
 // purpose  :
 // =======================================================================
index 56cc1ba..8fde94f 100644 (file)
@@ -18,6 +18,7 @@
 #include <Graphic3d_RenderingParams.hxx>
 #include <Standard_Type.hxx>
 #include <Standard_Transient.hxx>
+#include <TColStd_IndexedDataMapOfStringString.hxx>
 
 class Graphic3d_CView;
 
@@ -58,6 +59,10 @@ public:
   //! Returns formatted string.
   Standard_EXPORT virtual TCollection_AsciiString FormatStats (Graphic3d_RenderingParams::PerfCounters theFlags) const;
 
+  //! Fill in the dictionary with formatted statistic info.
+  Standard_EXPORT virtual void FormatStats (TColStd_IndexedDataMapOfStringString&   theDict,
+                                            Graphic3d_RenderingParams::PerfCounters theFlags) const;
+
   //! Returns duration of the last frame in seconds.
   Standard_Real FrameDuration() const { return myFrameDuration; }
 
index 4e9a35d..789961e 100644 (file)
@@ -805,3 +805,32 @@ void OpenGl_View::DiagnosticInformation (TColStd_IndexedDataMapOfStringString& t
     theDict.ChangeFromIndex (theDict.Add ("ResolutionRatio", aResRatio)) = aResRatio;
   }
 }
+
+//=======================================================================
+//function : StatisticInformation
+//purpose  :
+//=======================================================================
+void OpenGl_View::StatisticInformation (TColStd_IndexedDataMapOfStringString& theDict) const
+{
+  if (const Handle(OpenGl_Context)& aCtx = myWorkspace->GetGlContext())
+  {
+    const Handle(OpenGl_FrameStats)& aStats = aCtx->FrameStats();
+    const Graphic3d_RenderingParams& aRendParams = myWorkspace->View()->RenderingParams();
+    aStats->FormatStats (theDict, aRendParams.CollectedStats);
+  }
+}
+
+//=======================================================================
+//function : StatisticInformation
+//purpose  :
+//=======================================================================
+TCollection_AsciiString OpenGl_View::StatisticInformation() const
+{
+  if (const Handle(OpenGl_Context)& aCtx = myWorkspace->GetGlContext())
+  {
+    const Handle(OpenGl_FrameStats)& aStats = aCtx->FrameStats();
+    const Graphic3d_RenderingParams& aRendParams = myWorkspace->View()->RenderingParams();
+    return aStats->FormatStats (aRendParams.CollectedStats);
+  }
+  return TCollection_AsciiString();
+}
index 29a7418..b318974 100644 (file)
@@ -285,6 +285,12 @@ public:
   Standard_EXPORT virtual void DiagnosticInformation (TColStd_IndexedDataMapOfStringString& theDict,
                                                       Graphic3d_DiagnosticInfo theFlags) const Standard_OVERRIDE;
 
+  //! Returns string with statistic performance info.
+  Standard_EXPORT virtual TCollection_AsciiString StatisticInformation() const Standard_OVERRIDE;
+
+  //! Fills in the dictionary with statistic performance info.
+  Standard_EXPORT virtual void StatisticInformation (TColStd_IndexedDataMapOfStringString& theDict) const Standard_OVERRIDE;
+
 public:
 
   //! Returns background color.
index 0874f5e..067c91c 100644 (file)
@@ -3183,6 +3183,24 @@ void V3d_View::DiagnosticInformation (TColStd_IndexedDataMapOfStringString& theD
   myView->DiagnosticInformation (theDict, theFlags);
 }
 
+//=======================================================================
+//function : StatisticInformation
+//purpose  :
+//=======================================================================
+void V3d_View::StatisticInformation (TColStd_IndexedDataMapOfStringString& theDict) const
+{
+  myView->StatisticInformation (theDict);
+}
+
+// =======================================================================
+// function : StatisticInformation
+// purpose  :
+// =======================================================================
+TCollection_AsciiString V3d_View::StatisticInformation() const
+{
+  return myView->StatisticInformation();
+}
+
 //=============================================================================
 //function : RenderingParams
 //purpose  :
index 85701bc..0ecafb3 100644 (file)
@@ -928,6 +928,12 @@ public:
   Standard_EXPORT void DiagnosticInformation (TColStd_IndexedDataMapOfStringString& theDict,
                                               Graphic3d_DiagnosticInfo theFlags) const;
 
+  //! Returns string with statistic performance info.
+  Standard_EXPORT TCollection_AsciiString StatisticInformation() const;
+
+  //! Fills in the dictionary with statistic performance info.
+  Standard_EXPORT void StatisticInformation (TColStd_IndexedDataMapOfStringString& theDict) const;
+
   DEFINE_STANDARD_RTTIEXT(V3d_View,Standard_Transient)
 
 protected:
index a2c3ce8..f5c09e3 100644 (file)
@@ -11150,6 +11150,231 @@ static Standard_Integer VRenderParams (Draw_Interpretor& theDI,
 }
 
 //=======================================================================
+//function : searchInfo
+//purpose  :
+//=======================================================================
+inline TCollection_AsciiString searchInfo (const TColStd_IndexedDataMapOfStringString& theDict,
+                                           const TCollection_AsciiString&              theKey)
+{
+  for (TColStd_IndexedDataMapOfStringString::Iterator anIter (theDict); anIter.More(); anIter.Next())
+  {
+    if (TCollection_AsciiString::IsSameString (anIter.Key(), theKey, Standard_False))
+    {
+      return anIter.Value();
+    }
+  }
+  return TCollection_AsciiString();
+}
+
+//=======================================================================
+//function : VStatProfiler
+//purpose  :
+//=======================================================================
+static Standard_Integer VStatProfiler (Draw_Interpretor& theDI,
+                                       Standard_Integer  theArgNb,
+                                       const char**      theArgVec)
+{
+  Handle(V3d_View) aView = ViewerTest::CurrentView();
+  if (aView.IsNull())
+  {
+    std::cerr << "Error: no active viewer!\n";
+    return 1;
+  }
+
+  Standard_Boolean toRedraw = Standard_True;
+  Graphic3d_RenderingParams::PerfCounters aPrevCounters = aView->ChangeRenderingParams().CollectedStats;
+  Standard_ShortReal aPrevUpdInterval = aView->ChangeRenderingParams().StatsUpdateInterval;
+  Graphic3d_RenderingParams::PerfCounters aRenderParams = Graphic3d_RenderingParams::PerfCounters_NONE;
+  for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
+  {
+    Standard_CString        anArg (theArgVec[anArgIter]);
+    TCollection_AsciiString aFlag (anArg);
+    aFlag.LowerCase();
+    if (aFlag == "-noredraw")
+    {
+      toRedraw = Standard_False;
+    }
+    else
+    {
+      Graphic3d_RenderingParams::PerfCounters aParam = Graphic3d_RenderingParams::PerfCounters_NONE;
+      if      (aFlag == "fps")        aParam = Graphic3d_RenderingParams::PerfCounters_FrameRate;
+      else if (aFlag == "cpu")        aParam = Graphic3d_RenderingParams::PerfCounters_CPU;
+      else if (aFlag == "alllayers"
+            || aFlag == "layers")     aParam = Graphic3d_RenderingParams::PerfCounters_Layers;
+      else if (aFlag == "allstructs"
+            || aFlag == "structs")    aParam = Graphic3d_RenderingParams::PerfCounters_Structures;
+      else if (aFlag == "groups")     aParam = Graphic3d_RenderingParams::PerfCounters_Groups;
+      else if (aFlag == "allarrays"
+            || aFlag == "fillarrays"
+            || aFlag == "linearrays"
+            || aFlag == "pointarrays"
+            || aFlag == "textarrays") aParam = Graphic3d_RenderingParams::PerfCounters_GroupArrays;
+      else if (aFlag == "triangles")  aParam = Graphic3d_RenderingParams::PerfCounters_Triangles;
+      else if (aFlag == "points")     aParam = Graphic3d_RenderingParams::PerfCounters_Points;
+      else if (aFlag == "geommem"
+            || aFlag == "texturemem"
+            || aFlag == "framemem")   aParam = Graphic3d_RenderingParams::PerfCounters_EstimMem;
+      else if (aFlag == "elapsedframe"
+            || aFlag == "cpuframeaverage"
+            || aFlag == "cpupickingaverage"
+            || aFlag == "cpucullingaverage"
+            || aFlag == "cpudynaverage"
+            || aFlag == "cpuframemax"
+            || aFlag == "cpupickingmax"
+            || aFlag == "cpucullingmax"
+            || aFlag == "cpudynmax")  aParam = Graphic3d_RenderingParams::PerfCounters_FrameTime;
+      else
+      {
+        std::cerr << "Unknown argument '" << theArgVec[anArgIter] << "'!\n";
+        continue;
+      }
+
+      aRenderParams = Graphic3d_RenderingParams::PerfCounters (aRenderParams | aParam);
+    }
+  }
+
+  if (aRenderParams != Graphic3d_RenderingParams::PerfCounters_NONE)
+  {
+    aView->ChangeRenderingParams().CollectedStats =
+      Graphic3d_RenderingParams::PerfCounters (aView->RenderingParams().CollectedStats | aRenderParams);
+
+    if (toRedraw)
+    {
+      aView->ChangeRenderingParams().StatsUpdateInterval = -1;
+      aView->Redraw();
+      aView->ChangeRenderingParams().StatsUpdateInterval = aPrevUpdInterval;
+    }
+
+    TColStd_IndexedDataMapOfStringString aDict;
+    aView->StatisticInformation (aDict);
+
+    aView->ChangeRenderingParams().CollectedStats = aPrevCounters;
+
+    for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
+    {
+      Standard_CString        anArg(theArgVec[anArgIter]);
+      TCollection_AsciiString aFlag(anArg);
+      aFlag.LowerCase();
+      if (aFlag == "fps")
+      {
+        theDI << searchInfo (aDict, "FPS") << " ";
+      }
+      else if (aFlag == "cpu")
+      {
+        theDI << searchInfo (aDict, "CPU FPS") << " ";
+      }
+      else if (aFlag == "alllayers")
+      {
+        theDI << searchInfo (aDict, "Layers") << " ";
+      }
+      else if (aFlag == "layers")
+      {
+        theDI << searchInfo (aDict, "Rendered layers") << " ";
+      }
+      else if (aFlag == "allstructs")
+      {
+        theDI << searchInfo (aDict, "Structs") << " ";
+      }
+      else if (aFlag == "structs")
+      {
+        theDI << searchInfo (aDict, "Rendered structs") << " ";
+      }
+      else if (aFlag == "groups")
+      {
+        theDI << searchInfo (aDict, "Rendered groups") << " ";
+      }
+      else if (aFlag == "allarrays")
+      {
+        theDI << searchInfo (aDict, "Rendered arrays") << " ";
+      }
+      else if (aFlag == "fillarrays")
+      {
+        theDI << searchInfo (aDict, "Rendered [fill] arrays") << " ";
+      }
+      else if (aFlag == "linearrays")
+      {
+        theDI << searchInfo (aDict, "Rendered [line] arrays") << " ";
+      }
+      else if (aFlag == "pointarrays")
+      {
+        theDI << searchInfo (aDict, "Rendered [point] arrays") << " ";
+      }
+      else if (aFlag == "textarrays")
+      {
+        theDI << searchInfo (aDict, "Rendered [text] arrays") << " ";
+      }
+      else if (aFlag == "triangles")
+      {
+        theDI << searchInfo (aDict, "Rendered triangles") << " ";
+      }
+      else if (aFlag == "points")
+      {
+        theDI << searchInfo (aDict, "Rendered points") << " ";
+      }
+      else if (aFlag == "geommem")
+      {
+        theDI << searchInfo (aDict, "GPU Memory [geometry]") << " ";
+      }
+      else if (aFlag == "texturemem")
+      {
+        theDI << searchInfo (aDict, "GPU Memory [textures]") << " ";
+      }
+      else if (aFlag == "framemem")
+      {
+        theDI << searchInfo (aDict, "GPU Memory [frames]") << " ";
+      }
+      else if (aFlag == "elapsedframe")
+      {
+        theDI << searchInfo (aDict, "Elapsed Frame (average)") << " ";
+      }
+      else if (aFlag == "cpuframe_average")
+      {
+        theDI << searchInfo (aDict, "CPU Frame (average)") << " ";
+      }
+      else if (aFlag == "cpupicking_average")
+      {
+        theDI << searchInfo (aDict, "CPU Picking (average)") << " ";
+      }
+      else if (aFlag == "cpuculling_average")
+      {
+        theDI << searchInfo (aDict, "CPU Culling (average)") << " ";
+      }
+      else if (aFlag == "cpudyn_average")
+      {
+        theDI << searchInfo (aDict, "CPU Dynamics (average)") << " ";
+      }
+      else if (aFlag == "cpuframe_max")
+      {
+        theDI << searchInfo (aDict, "CPU Frame (max)") << " ";
+      }
+      else if (aFlag == "cpupicking_max")
+      {
+        theDI << searchInfo (aDict, "CPU Picking (max)") << " ";
+      }
+      else if (aFlag == "cpuculling_max")
+      {
+        theDI << searchInfo (aDict, "CPU Culling (max)") << " ";
+      }
+      else if (aFlag == "cpudyn_max")
+      {
+        theDI << searchInfo (aDict, "CPU Dynamics (max)") << " ";
+      }
+    }
+  }
+  else
+  {
+    if (toRedraw)
+    {
+      aView->ChangeRenderingParams().StatsUpdateInterval = -1;
+      aView->Redraw();
+      aView->ChangeRenderingParams().StatsUpdateInterval = aPrevUpdInterval;
+    }
+    theDI << "Statistic info:\n" << aView->StatisticInformation();
+  }
+  return 0;
+}
+
+//=======================================================================
 //function : VProgressiveMode
 //purpose  :
 //=======================================================================
@@ -12623,6 +12848,18 @@ void ViewerTest::ViewerCommands(Draw_Interpretor& theCommands)
     "\n    Command is intended to control presentation quality depending on"
     "\n    hardware capabilities and performance.",
     __FILE__, VRenderParams, group);
+  theCommands.Add("vstatprofiler",
+    "\n vstatprofiler [fps|cpu|allLayers|layers|allstructures|structures|groups"
+    "\n                |allArrays|fillArrays|lineArrays|pointArrays|textArrays"
+    "\n                |triagles|points|geomMem|textureMem|frameMem"
+    "\n                |elapsedFrame|cpuFrameAverage|cpuPickingAverage|cpuCullingAverage|cpuDynAverage"
+    "\n                |cpuFrameMax|cpuPickingMax|cpuCullingMax|cpuDynMax]"
+    "\n                [-noredraw]"
+    "\n\t\t: Prints rendering statistics."
+    "\n\t\t:   If there are some parameters - print corresponding statistic counters values,"
+    "\n\t\t:   else - print all performance counters set previously."
+    "\n\t\t:   '-noredraw' Flag to avoid additional redraw call and use already collected values.\n",
+    __FILE__, VStatProfiler, group);
   theCommands.Add ("vplace",
             "vplace dx dy"
     "\n\t\t: Places the point (in pixels) at the center of the window",
diff --git a/tests/bugs/vis/bug30437 b/tests/bugs/vis/bug30437
new file mode 100644 (file)
index 0000000..1fcefbe
--- /dev/null
@@ -0,0 +1,26 @@
+puts "============="
+puts "0030437: Visualization, TKV3d - add Draw command to print rendering statistics"
+puts "============="
+
+pload MODELING VISUALIZATION
+vclear
+vinit View1 -width 800 -height 400
+vdrawparray g trianglestrips v -97.9819 -175.225 -7.6706 v -97.9819  194.163 -7.6706 v 271.406  -175.225 -7.6706 v 271.406   194.163 -7.6706
+
+vpoint pl1  -4 -17  0
+vpoint pl2  -4 -10 14
+vpoint pl3   0  -6 17
+vpoint pr1 179  17 39
+vpoint pr2 174  -2 12
+vpoint pr3 177   0 15
+vfit
+
+vcamera -persp
+vviewparams -scale 5 -proj -0 -1 -0 -up 0 0 1 -at -157 9.5 19
+vviewparams -scale 5 -proj -0 -1 -0 -up 0 0 1 -at -157 9.5 19
+
+set aPointsNb    [vstatprofiler points]
+set aTrianglesNb [vstatprofiler triangles]
+
+# check number of not culled points and triangles
+if [expr $aPointsNb != 3 || $aTrianglesNb != 2] { puts "Error: unexpected number of culled elements" }
diff --git a/tests/bugs/vis/bug30437_1 b/tests/bugs/vis/bug30437_1
new file mode 100644 (file)
index 0000000..7a56410
--- /dev/null
@@ -0,0 +1,31 @@
+puts "============="
+puts "0030437: Visualization, TKV3d - add Draw command to print rendering statistics"
+puts "============="
+
+pload MODELING VISUALIZATION
+vclear
+vinit View1
+
+set THE_NB_POINTS 10
+puts "Creating [expr $THE_NB_POINTS * $THE_NB_POINTS * $THE_NB_POINTS] points..."
+for {set i 0} {$i < $THE_NB_POINTS} {incr i} {
+  for {set j 0} {$j < $THE_NB_POINTS} {incr j} {
+    for {set k 0} {$k < $THE_NB_POINTS} {incr k} {
+      vpoint p$i$j$k 3.*$i 3.*$j 3.*$k
+    }
+  }
+}
+
+vcamera -ortho
+vfront
+vfit
+vzoom 2
+set aPointsNb_1 [vstatprofiler points]
+if [expr $aPointsNb_1 != 160] { puts "Error: unexpected number of not culled points 1" }
+
+vcamera -persp
+vaxo
+vfit
+vzoom 3
+set aPointsNb_2 [vstatprofiler points]
+if [expr $aPointsNb_2 != 307] { puts "Error: unexpected number of not culled points 2" }