0026139: AIS_InteractiveContext::Display performance regression
authorvpa <vpa@opencascade.com>
Thu, 7 May 2015 15:39:36 +0000 (18:39 +0300)
committerabv <abv@opencascade.com>
Fri, 8 May 2015 05:56:33 +0000 (08:56 +0300)
NCollection_Sequence in SelectMgr_SensitiveEntitySet was replaced by indexed data map

src/QABugs/QABugs_19.cxx
src/SelectMgr/SelectMgr_SelectableObjectSet.cxx
src/SelectMgr/SelectMgr_SensitiveEntitySet.cxx
src/SelectMgr/SelectMgr_SensitiveEntitySet.hxx
tests/bugs/vis/bug26139 [new file with mode: 0644]

index f131aab89dbe506a73de809479d3c628314e2eee..208c9c66abc40b38f317e472e36ce20bc8add862 100755 (executable)
@@ -3390,6 +3390,92 @@ static Standard_Integer OCC25547(
   return 0;
 }
 
+static Standard_Integer OCC26139 (Draw_Interpretor& theDI,
+                                  Standard_Integer  argc,
+                                  const char **     argv)
+{
+
+  Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
+  if (aCtx.IsNull())
+  {
+    theDI << "Use 'vinit' command before " << argv[0] << "\n";
+    return 1;
+  }
+
+  Standard_Integer aBoxGridSize = 100;
+  Standard_Integer aCompGridSize = 3;
+  Standard_Real aBoxSize = 5.0;
+
+  if (argc > 1)
+  {
+    for (Standard_Integer anArgIdx = 1; anArgIdx < argc; ++anArgIdx)
+    {
+      TCollection_AsciiString anArg (argv[anArgIdx]);
+      anArg.LowerCase();
+      if (anArg == "-boxgrid")
+      {
+        aBoxGridSize = Draw::Atoi (argv[++anArgIdx]);
+      }
+      else if (anArg == "-compgrid")
+      {
+        aCompGridSize = Draw::Atoi (argv[++anArgIdx]);
+      }
+      else if (anArg == "-boxsize")
+      {
+        aBoxSize = Draw::Atof (argv[++anArgIdx]);
+      }
+    }
+  }
+
+  NCollection_List<Handle(AIS_Shape)> aCompounds;
+  for (Standard_Integer aCompGridX = 0; aCompGridX < aCompGridSize; ++aCompGridX)
+  {
+    for (Standard_Integer aCompGridY = 0; aCompGridY < aCompGridSize; ++aCompGridY)
+    {
+      BRep_Builder aBuilder;
+      TopoDS_Compound aComp;
+      aBuilder.MakeCompound (aComp);
+      for (Standard_Integer aBoxGridX = 0; aBoxGridX < aBoxGridSize; ++aBoxGridX)
+      {
+        for (Standard_Integer aBoxGridY = 0; aBoxGridY < aBoxGridSize; ++aBoxGridY)
+        {
+          BRepPrimAPI_MakeBox aBox (gp_Pnt (aBoxGridX * aBoxSize, aBoxGridY * aBoxSize, 0.0),
+                                    aBoxSize, aBoxSize, aBoxSize);
+          aBuilder.Add (aComp, aBox.Shape());
+        }
+      }
+      gp_Trsf aTrsf;
+      aTrsf.SetTranslation (gp_Vec (aBoxGridSize * aBoxSize * aCompGridX,
+                                    aBoxGridSize * aBoxSize * aCompGridY,
+                                    0.0));
+      TopLoc_Location aLoc (aTrsf);
+      aComp.Located (aLoc);
+      aCompounds.Append (new AIS_Shape (aComp));
+    }
+  }
+
+  OSD_Timer aTimer;
+  for (NCollection_List<Handle(AIS_Shape)>::Iterator aCompIter (aCompounds); aCompIter.More(); aCompIter.Next())
+  {
+    aTimer.Start();
+    aCtx->Display (aCompIter.Value(), Standard_False);
+    aTimer.Stop();
+    theDI << "Display time: " << aTimer.ElapsedTime() << "\n";
+    aTimer.Reset();
+  }
+
+  aTimer.Reset();
+  aTimer.Start();
+  for (NCollection_List<Handle(AIS_Shape)>::Iterator aCompIter (aCompounds); aCompIter.More(); aCompIter.Next())
+  {
+    aCtx->Remove (aCompIter.Value(), Standard_False);
+  }
+  aTimer.Stop();
+  theDI << "Remove time: " << aTimer.ElapsedTime() << "\n";
+
+  return 0;
+}
+
 #include <TColStd_DataMapIteratorOfDataMapOfIntegerInteger.hxx>
 #include <TColStd_DataMapOfIntegerInteger.hxx>
 #include <OSD.hxx>
@@ -3851,5 +3937,6 @@ void QABugs::Commands_19(Draw_Interpretor& theCommands) {
   theCommands.Add ("OCC26172", "OCC26172", __FILE__, OCC26172, group);
   theCommands.Add ("xprojponf", "xprojponf p f", __FILE__, xprojponf, group);
   theCommands.Add ("OCC24923", "OCC24923", __FILE__, OCC24923, group);
+  theCommands.Add ("OCC26139", "OCC26139 [-boxsize value] [-boxgrid value] [-compgrid value]", __FILE__, OCC26139, group);
   return;
 }
index ffd330b862c2b06898376bbc7aa40ce1b2885484..6e2b00e4c910c0a99ef040bbfc2392b97e5540e2 100644 (file)
@@ -51,7 +51,10 @@ void SelectMgr_SelectableObjectSet::Remove (const Handle(SelectMgr_SelectableObj
 
   if (anIndex != 0)
   {
-    Swap (anIndex - 1, Size() - 1);
+    if (anIndex != Size())
+    {
+      Swap (anIndex - 1, Size() - 1);
+    }
 
     myObjects.RemoveLast();
 
index c3c4d5d253225c3495f68ab62d426de726855fda..32326e0cbc39179e54aa661458ea4109954dd6de 100644 (file)
@@ -26,7 +26,7 @@
 //=======================================================================
 SelectMgr_SensitiveEntitySet::SelectMgr_SensitiveEntitySet()
 {
-  myBuilder = new BVH_BinnedBuilder<Standard_Real, 3, 32> (1, 32, Standard_True);
+  myBuilder = new BVH_BinnedBuilder<Standard_Real, 3, 4> (1, 32, Standard_True);
 }
 
 //=======================================================================
@@ -40,8 +40,7 @@ void SelectMgr_SensitiveEntitySet::Append (const Handle(SelectMgr_SensitiveEntit
     theEntity->ResetSelectionActiveStatus();
     return;
   }
-  myEntities.Append (theEntity);
-  myEntityIdxs.Append (myEntities.Size());
+  mySensitives.Add (theEntity);
   MarkDirty();
 }
 
@@ -59,34 +58,11 @@ void SelectMgr_SensitiveEntitySet::Append (const Handle(SelectMgr_Selection)& th
       theSelection->Sensitive()->ResetSelectionActiveStatus();
       continue;
     }
-    myEntities.Append (theSelection->Sensitive());
-    myEntityIdxs.Append (myEntities.Size());
+    mySensitives.Add (theSelection->Sensitive());
   }
   MarkDirty();
 }
 
-//=======================================================================
-// function : Remove
-// purpose  : Removes entity from the set and marks BVH tree for rebuild
-//=======================================================================
-void SelectMgr_SensitiveEntitySet::Remove (const Handle(SelectMgr_SensitiveEntity)& theEntity)
-{
-  for (Standard_Integer anEntityIdx = 1; anEntityIdx <= myEntities.Size(); ++anEntityIdx)
-  {
-    if (myEntities.Value (anEntityIdx) == theEntity)
-    {
-      myEntities.Remove (anEntityIdx);
-      myEntityIdxs.Clear();
-      for (Standard_Integer anEntityIndexesIter = 1; anEntityIndexesIter <= myEntities.Size(); ++anEntityIndexesIter)
-      {
-        myEntityIdxs.Append (anEntityIndexesIter);
-      }
-      MarkDirty();
-      break;
-    }
-  }
-}
-
 //=======================================================================
 // function : Remove
 // purpose  : Removes every entity of selection theSelection from the set
@@ -96,24 +72,19 @@ void SelectMgr_SensitiveEntitySet::Remove (const Handle(SelectMgr_Selection)& th
 {
   for (theSelection->Init(); theSelection->More(); theSelection->Next())
   {
-    for (Standard_Integer anEntityIdx = 1; anEntityIdx <= myEntities.Size(); ++anEntityIdx)
-    {
-      if (myEntities.Value (anEntityIdx) == theSelection->Sensitive())
-      {
-        myEntities.Remove (anEntityIdx);
-        MarkDirty();
-      }
-    }
-  }
+    Standard_Integer anEntIdx = mySensitives.FindIndex (theSelection->Sensitive());
+    if (!anEntIdx)
+      continue;
 
-  if (BVH_Object<Standard_Real, 3>::myIsDirty)
-  {
-    myEntityIdxs.Clear();
-    for (Standard_Integer anEntityIdxsIter = 1; anEntityIdxsIter <= myEntities.Size(); ++anEntityIdxsIter)
+    if (anEntIdx != mySensitives.Size())
     {
-      myEntityIdxs.Append (anEntityIdxsIter);
+      Swap (anEntIdx - 1, mySensitives.Size() - 1);
     }
+
+    mySensitives.RemoveLast();
   }
+
+  MarkDirty();
 }
 
 //=======================================================================
@@ -122,8 +93,7 @@ void SelectMgr_SensitiveEntitySet::Remove (const Handle(SelectMgr_Selection)& th
 //=======================================================================
 Select3D_BndBox3d SelectMgr_SensitiveEntitySet::Box (const Standard_Integer theIndex) const
 {
-  Standard_Integer anEntityIdx = myEntityIdxs.Value (theIndex + 1);
-  return myEntities.Value (anEntityIdx)->BaseSensitive()->BoundingBox();
+  return GetSensitiveById (theIndex)->BaseSensitive()->BoundingBox();
 }
 
 //=======================================================================
@@ -134,9 +104,8 @@ Select3D_BndBox3d SelectMgr_SensitiveEntitySet::Box (const Standard_Integer theI
 Standard_Real SelectMgr_SensitiveEntitySet::Center (const Standard_Integer theIndex,
                                                     const Standard_Integer theAxis) const
 {
-  Standard_Integer anEntityIdx = myEntityIdxs.Value (theIndex + 1);
   const Handle(SelectBasics_SensitiveEntity)& aBasicEntity =
-    myEntities.Value (anEntityIdx)->BaseSensitive();
+    GetSensitiveById (theIndex)->BaseSensitive();
   const Handle(Select3D_SensitiveEntity)& aSensitive =
     Handle(Select3D_SensitiveEntity)::DownCast (aBasicEntity);
   const gp_Pnt aCenter = aSensitive->CenterOfGeometry();
@@ -154,10 +123,12 @@ Standard_Real SelectMgr_SensitiveEntitySet::Center (const Standard_Integer theIn
 void SelectMgr_SensitiveEntitySet::Swap (const Standard_Integer theIndex1,
                                          const Standard_Integer theIndex2)
 {
-  Standard_Integer anEntityIdx1 = myEntityIdxs.Value (theIndex1 + 1);
-  Standard_Integer anEntityIdx2 = myEntityIdxs.Value (theIndex2 + 1);
-  myEntityIdxs.ChangeValue (theIndex1 + 1) = anEntityIdx2;
-  myEntityIdxs.ChangeValue (theIndex2 + 1) = anEntityIdx1;
+  const Handle(SelectMgr_SensitiveEntity) anEntity1 = GetSensitiveById (theIndex1);
+  const Handle(SelectMgr_SensitiveEntity) anEntity2 = GetSensitiveById (theIndex2);
+
+  mySensitives.Substitute (theIndex1 + 1, EMPTY_ENT);
+  mySensitives.Substitute (theIndex2 + 1, anEntity1);
+  mySensitives.Substitute (theIndex1 + 1, anEntity2);
 }
 
 //=======================================================================
@@ -166,7 +137,7 @@ void SelectMgr_SensitiveEntitySet::Swap (const Standard_Integer theIndex1,
 //=======================================================================
 Standard_Integer SelectMgr_SensitiveEntitySet::Size() const
 {
-  return myEntityIdxs.Size();
+  return mySensitives.Size();
 }
 
 //=======================================================================
@@ -176,6 +147,5 @@ Standard_Integer SelectMgr_SensitiveEntitySet::Size() const
 const Handle(SelectMgr_SensitiveEntity)& SelectMgr_SensitiveEntitySet::GetSensitiveById
   (const Standard_Integer theIndex) const
 {
-  Standard_Integer anIdx = myEntityIdxs.Value (theIndex + 1);
-  return myEntities.Value (anIdx);
+  return mySensitives.FindKey (theIndex + 1);
 }
index e51144025a536dfb95f12ef87a240ee875c74306..c3025d1b87952b6accc0fb5e90a7bac8c283390a 100644 (file)
@@ -18,7 +18,7 @@
 
 #include <BVH_PrimitiveSet.hxx>
 
-#include <NCollection_Sequence.hxx>
+#include <NCollection_IndexedMap.hxx>
 #include <NCollection_Handle.hxx>
 
 #include <Select3D_BndBox3d.hxx>
 #include <SelectMgr_SensitiveEntity.hxx>
 #include <SelectMgr_Selection.hxx>
 
+typedef NCollection_IndexedMap<Handle(SelectMgr_SensitiveEntity)> SelectMgr_IndexedMapOfHSensitive;
+
 //! This class is used to store all calculated sensitive entites of one selectable
 //! object. It provides an interface for building BVH tree which is used to speed-up
 //! the performance of searching for overlap among sensitives of one selectable object
 class SelectMgr_SensitiveEntitySet : public BVH_PrimitiveSet<Standard_Real, 3>
 {
+  Handle(SelectMgr_SensitiveEntity) EMPTY_ENT;
+
 public:
 
   SelectMgr_SensitiveEntitySet();
@@ -44,9 +48,6 @@ public:
   //! BVH tree for rebuild
   void Append (const Handle(SelectMgr_Selection)& theSelection);
 
-  //! Removes entity from the set and marks BVH tree for rebuild
-  void Remove (const Handle(SelectMgr_SensitiveEntity)& theEntity);
-
   //! Removes every entity of selection theSelection from the set
   //! and marks BVH tree for rebuild
   void Remove (const Handle(SelectMgr_Selection)& theSelection);
@@ -71,8 +72,7 @@ public:
 
 private:
 
-  NCollection_Sequence<Handle(SelectMgr_SensitiveEntity)> myEntities;       //!< A sequence of calculated sensitives of the object
-  NCollection_Sequence<Standard_Integer>                  myEntityIdxs;     //!< Cached indexes for faster BVH build
+  SelectMgr_IndexedMapOfHSensitive mySensitives;     //!< Map of entities and its corresponding index in BVH
 };
 
 #endif // _SelectMgr_SensitiveEntitySet_HeaderFile
diff --git a/tests/bugs/vis/bug26139 b/tests/bugs/vis/bug26139
new file mode 100644 (file)
index 0000000..6a9ac7d
--- /dev/null
@@ -0,0 +1,15 @@
+puts "============"
+puts "CR26139"
+puts "============"
+puts ""
+
+##########################################################################################
+puts "AIS_InteractiveContext::Display performance regression"
+#     To measure performance downgrade, the time elapsed should be greated than on previous version
+##########################################################################################
+
+pload VISUALIZATION
+pload QAcommands
+
+vinit View1
+OCC26139