]> OCCT Git - occt-copy.git/commitdiff
draft implementation of the fast map for selection CR0_ALICONA_FAST_MAP
authorasl <asl@opencascade.com>
Tue, 25 Sep 2018 07:00:22 +0000 (10:00 +0300)
committerasl <asl@opencascade.com>
Tue, 25 Sep 2018 12:09:23 +0000 (15:09 +0300)
src/Select3D/Select3D_SensitivePrimitiveArray.cxx
src/Select3D/Select3D_SensitivePrimitiveArray.hxx

index fc0c6ce432044f6b0b70f587328ce9218a322f4e..62e2ff3809a85430e4116bff6fe240ca59d2a0ee 100644 (file)
 
 IMPLEMENT_STANDARD_RTTIEXT(Select3D_SensitivePrimitiveArray, Select3D_SensitiveSet)
 
+const int Stride = sizeof(unsigned int) * 8; // number of bits in unsigned int
+
+const Select3D_BitField& Select3D_BitField::Map() const
+{
+  return *this;
+}
+
+Select3D_BitField& Select3D_BitField::ChangeMap() const
+{
+  return *const_cast<Select3D_BitField*>(this);
+}
+
+void Select3D_BitField::Clear()
+{
+  if (!myData.empty())
+    memset(&myData[0], 0, sizeof(unsigned int)*myData.size());
+}
+
+void Select3D_BitField::Reserve(const Standard_Integer theMax)
+{
+  myData.resize(theMax / Stride + 1, 0);
+}
+
+void Select3D_BitField::Add(const Standard_Integer theIndex)
+{
+  myData[theIndex / Stride] |= (1 << (theIndex % Stride));
+}
+
+void Select3D_BitField::Unite(const Select3D_BitField& theField)
+{
+  size_t aSize = myData.size();
+  if (theField.myData.size() > aSize)
+    aSize = theField.myData.size();
+  Reserve((int)aSize);
+
+  for (int i = 0; i < aSize; i++)
+    myData[i] |= theField.myData[i];
+}
+
+inline void bits_to_vector(unsigned int v, std::vector<unsigned int>& theVector, size_t& s, size_t& j)
+{
+  for (size_t k = 0; k < Stride && v != 0; k++)
+  {
+    if (v % 2 == 1)
+    {
+      theVector[j++] = (unsigned int)(s + k);
+    }
+    v = v >> 1;
+  }
+  s += Stride;
+}
+
+void Select3D_BitField::ToVector(std::vector<unsigned int>& theVector) const
+{
+  size_t n = myData.size();
+  theVector.resize(n*Stride);
+  size_t j = 0, s = 0;
+  for (size_t i = 0; i < n; i++)
+  {
+    bits_to_vector(myData[i], theVector, s, j);
+  }
+  theVector.resize(j);
+}
+
+
+
 namespace
 {
 
@@ -155,7 +221,8 @@ private:
 // function : Select3D_SensitivePrimitiveArray
 // purpose  :
 // =======================================================================
-Select3D_SensitivePrimitiveArray::Select3D_SensitivePrimitiveArray (const Handle(SelectBasics_EntityOwner)& theOwnerId)
+Select3D_SensitivePrimitiveArray::Select3D_SensitivePrimitiveArray (const Handle(SelectBasics_EntityOwner)& theOwnerId,
+                                                                    const Standard_Boolean theIsFastMap)
 : Select3D_SensitiveSet (theOwnerId),
   myPrimType (Graphic3d_TOPA_UNDEFINED),
   myIndexLower (0),
@@ -174,7 +241,8 @@ Select3D_SensitivePrimitiveArray::Select3D_SensitivePrimitiveArray (const Handle
   myDetectedEdgeNode2 (-1),
   myToDetectElem (true),
   myToDetectNode (false),
-  myToDetectEdge (false)
+  myToDetectEdge (false),
+  myIsFastMap(theIsFastMap)
 {
   //
 }
@@ -188,16 +256,19 @@ void Select3D_SensitivePrimitiveArray::SetDetectElementMap (bool theToDetect)
   if (!theToDetect)
   {
     myDetectedElemMap.Nullify();
+    myDetectedElemMapFast.Nullify();
     return;
   }
 
   if (myDetectedElemMap.IsNull())
   {
     myDetectedElemMap = new TColStd_HPackedMapOfInteger();
+    myDetectedElemMapFast = new Select3D_BitField();
   }
   else
   {
     myDetectedElemMap->ChangeMap().Clear();
+    myDetectedElemMapFast->ChangeMap().Clear();
   }
 }
 
@@ -210,16 +281,19 @@ void Select3D_SensitivePrimitiveArray::SetDetectNodeMap (bool theToDetect)
   if (!theToDetect)
   {
     myDetectedNodeMap.Nullify();
+    myDetectedNodeMapFast.Nullify();
     return;
   }
 
   if (myDetectedNodeMap.IsNull())
   {
     myDetectedNodeMap = new TColStd_HPackedMapOfInteger();
+    myDetectedNodeMapFast = new Select3D_BitField();
   }
   else
   {
     myDetectedNodeMap->ChangeMap().Clear();
+    myDetectedNodeMapFast->ChangeMap().Clear();
   }
 }
 
@@ -891,10 +965,16 @@ Standard_Boolean Select3D_SensitivePrimitiveArray::Matches (SelectBasics_Selecti
   if (!myDetectedElemMap.IsNull())
   {
     myDetectedElemMap->ChangeMap().Clear();
+    myDetectedElemMapFast->ChangeMap().Clear();
+    int nbTriangles = myIndices->NbElements / 3;
+    myDetectedElemMapFast->Reserve(nbTriangles);
   }
   if (!myDetectedNodeMap.IsNull())
   {
     myDetectedNodeMap->ChangeMap().Clear();
+    myDetectedNodeMapFast->ChangeMap().Clear();
+    int nbPoints = myVerts->NbElements;
+    myDetectedNodeMapFast->Reserve(nbPoints);
   }
   myMinDepthElem      = RealLast();
   myMinDepthNode      = RealLast();
@@ -939,11 +1019,17 @@ Standard_Boolean Select3D_SensitivePrimitiveArray::Matches (SelectBasics_Selecti
       hasResults = true;
       if (!myDetectedElemMap.IsNull())
       {
-        myDetectedElemMap->ChangeMap().Unite (aChild->myDetectedElemMap->Map());
+        if (myIsFastMap)
+          myDetectedElemMapFast->ChangeMap().Unite(aChild->myDetectedElemMapFast->Map());
+        else
+          myDetectedElemMap->ChangeMap().Unite(aChild->myDetectedElemMap->Map());
       }
       if (!myDetectedNodeMap.IsNull())
       {
-        myDetectedNodeMap->ChangeMap().Unite (aChild->myDetectedNodeMap->Map());
+        if (myIsFastMap)
+          myDetectedNodeMapFast->ChangeMap().Unite(aChild->myDetectedNodeMapFast->Map());
+        else
+          myDetectedNodeMap->ChangeMap().Unite(aChild->myDetectedNodeMap->Map());
       }
       if (thePickResult.Depth() > aPickResult.Depth())
       {
@@ -1013,11 +1099,17 @@ Standard_Boolean Select3D_SensitivePrimitiveArray::overlapsElement (SelectBasics
             {
               if (!myDetectedElemMap.IsNull())
               {
-                myDetectedElemMap->ChangeMap().Add (aPointIndex);
+                if (myIsFastMap)
+                  myDetectedElemMapFast->ChangeMap().Add(aPointIndex);
+                else
+                  myDetectedElemMap->ChangeMap().Add(aPointIndex);
               }
               if (!myDetectedNodeMap.IsNull())
               {
-                myDetectedNodeMap->ChangeMap().Add (aPointIndex);
+                if (myIsFastMap)
+                  myDetectedNodeMapFast->ChangeMap().Add(aPointIndex);
+                else
+                  myDetectedNodeMap->ChangeMap().Add(aPointIndex);
               }
             }
             aResult = Standard_True;
@@ -1062,7 +1154,10 @@ Standard_Boolean Select3D_SensitivePrimitiveArray::overlapsElement (SelectBasics
             if (!myDetectedElemMap.IsNull()
               && theMgr.GetActiveSelectionType() != SelectBasics_SelectingVolumeManager::Point)
             {
-              myDetectedElemMap->ChangeMap().Add(aTriIndex);
+              if (myIsFastMap)
+                myDetectedElemMapFast->ChangeMap().Add(aTriIndex);
+              else
+                myDetectedElemMap->ChangeMap().Add(aTriIndex);
             }
           }
         }
@@ -1080,7 +1175,10 @@ Standard_Boolean Select3D_SensitivePrimitiveArray::overlapsElement (SelectBasics
               if (!myDetectedNodeMap.IsNull()
                 && theMgr.GetActiveSelectionType() != SelectBasics_SelectingVolumeManager::Point)
               {
-                myDetectedNodeMap->ChangeMap().Add (aTriNodes[aNodeIter]);
+                if (myIsFastMap)
+                  myDetectedNodeMapFast->ChangeMap().Add(aTriNodes[aNodeIter]);
+                else
+                  myDetectedNodeMap->ChangeMap().Add(aTriNodes[aNodeIter]);
               }
               aResult = Standard_True;
             }
@@ -1170,11 +1268,17 @@ Standard_Boolean Select3D_SensitivePrimitiveArray::elementIsInside (SelectBasics
         {
           if (!myDetectedElemMap.IsNull())
           {
-            myDetectedElemMap->ChangeMap().Add (aPointIndex);
+            if (myIsFastMap)
+              myDetectedElemMapFast->ChangeMap().Add(aPointIndex);
+            else
+              myDetectedElemMap->ChangeMap().Add(aPointIndex);
           }
           if (!myDetectedNodeMap.IsNull())
           {
-            myDetectedNodeMap->ChangeMap().Add (aPointIndex);
+            if (myIsFastMap)
+              myDetectedNodeMapFast->ChangeMap().Add(aPointIndex);
+            else
+              myDetectedNodeMap->ChangeMap().Add(aPointIndex);
           }
         }
       }
@@ -1213,13 +1317,25 @@ Standard_Boolean Select3D_SensitivePrimitiveArray::elementIsInside (SelectBasics
         {
           if (!myDetectedElemMap.IsNull())
           {
-            myDetectedElemMap->ChangeMap().Add (aTriIndex);
+            if (myIsFastMap)
+              myDetectedElemMapFast->ChangeMap().Add(aTriIndex);
+            else
+              myDetectedElemMap->ChangeMap().Add(aTriIndex);
           }
           if (!myDetectedNodeMap.IsNull())
           {
-            myDetectedNodeMap->ChangeMap().Add (aTriNodes[0]);
-            myDetectedNodeMap->ChangeMap().Add (aTriNodes[1]);
-            myDetectedNodeMap->ChangeMap().Add (aTriNodes[2]);
+            if (myIsFastMap)
+            {
+              myDetectedNodeMapFast->ChangeMap().Add(aTriNodes[0]);
+              myDetectedNodeMapFast->ChangeMap().Add(aTriNodes[1]);
+              myDetectedNodeMapFast->ChangeMap().Add(aTriNodes[2]);
+            }
+            else
+            {
+              myDetectedNodeMap->ChangeMap().Add(aTriNodes[0]);
+              myDetectedNodeMap->ChangeMap().Add(aTriNodes[1]);
+              myDetectedNodeMap->ChangeMap().Add(aTriNodes[2]);
+            }
           }
         }
       }
index 50e767bf04066fb43cf524cf182073e682d45afe..d8ad7caa897282423e8bb62412a96d50e1fc9042 100644 (file)
 #include <Select3D_BVHIndexBuffer.hxx>
 #include <TColStd_HPackedMapOfInteger.hxx>
 
+class Select3D_BitField : public Standard_Transient
+{
+public:
+  Standard_EXPORT const Select3D_BitField& Map() const;
+  Standard_EXPORT Select3D_BitField& ChangeMap() const;
+
+  Standard_EXPORT void Clear();
+  Standard_EXPORT void Add(const Standard_Integer);
+  Standard_EXPORT void Reserve(const Standard_Integer);
+  Standard_EXPORT void Unite(const Select3D_BitField&);
+  Standard_EXPORT void ToVector(std::vector<unsigned int>&) const;
+
+private:
+  std::vector<unsigned int> myData;
+};
+
+
 //! Sensitive for triangulation or point set defined by Primitive Array.
 //! The primitives can be optionally combined into patches within BVH tree
 //! to reduce its building time in expense of extra traverse time.
@@ -33,11 +50,14 @@ class Select3D_SensitivePrimitiveArray : public Select3D_SensitiveSet
 public:
 
   //! Constructs an empty sensitive object.
-  Standard_EXPORT Select3D_SensitivePrimitiveArray (const Handle(SelectBasics_EntityOwner)& theOwnerId);
+  Standard_EXPORT Select3D_SensitivePrimitiveArray (const Handle(SelectBasics_EntityOwner)& theOwnerId,
+                                                    const Standard_Boolean theIsFastMap = Standard_False);
 
   //! Return patch size limit (1 by default).
   Standard_Integer PatchSizeMax() const { return myPatchSizeMax; }
 
+  Standard_Boolean IsFastMap() const { return myIsFastMap; }
+
   //! Assign patch size limit.
   //! Should be set before initialization.
   void SetPatchSizeMax (const Standard_Integer thePatchSizeMax) { myPatchSizeMax = thePatchSizeMax; }
@@ -184,12 +204,14 @@ public:
 
   //! Return the index map of last detected elements (rectangle selection).
   const Handle(TColStd_HPackedMapOfInteger)& LastDetectedElementMap() const { return myDetectedElemMap; }
+  const Handle(Select3D_BitField)& LastDetectedElementMapFast() const { return myDetectedElemMapFast; }
 
   //! Return last topmost detected node or -1 if undefined (axis picking).
   Standard_Integer LastDetectedNode() const { return myDetectedNode; }
 
   //! Return the index map of last detected nodes (rectangle selection).
   const Handle(TColStd_HPackedMapOfInteger)& LastDetectedNodeMap() const { return myDetectedNodeMap; }
+  const Handle(Select3D_BitField)& LastDetectedNodeMapFast() const { return myDetectedNodeMapFast; }
 
   //! Return the first node of last topmost detected edge or -1 if undefined (axis picking).
   Standard_Integer LastDetectedEdgeNode1() const { return myDetectedEdgeNode1; }
@@ -317,6 +339,8 @@ private:
   gp_GTrsf                            myInvInitLocation;
   Handle(TColStd_HPackedMapOfInteger) myDetectedElemMap;    //!< index map of last detected elements
   Handle(TColStd_HPackedMapOfInteger) myDetectedNodeMap;    //!< index map of last detected nodes
+  Handle(Select3D_BitField) myDetectedElemMapFast;    //!< index map of last detected elements
+  Handle(Select3D_BitField) myDetectedNodeMapFast;    //!< index map of last detected nodes
   Standard_Real                       myMinDepthElem;       //!< the depth of nearest detected element
   Standard_Real                       myMinDepthNode;       //!< the depth of nearest detected node
   Standard_Real                       myMinDepthEdge;       //!< the depth of nearest detected edge
@@ -327,6 +351,7 @@ private:
   bool                                myToDetectElem;       //!< flag to keep info about last detected element
   bool                                myToDetectNode;       //!< flag to keep info about last detected node
   bool                                myToDetectEdge;       //!< flag to keep info about last detected edge
+  Standard_Boolean                    myIsFastMap;          //!< flag to use optimized (bit field) map
 
 public: