From: asl Date: Tue, 25 Sep 2018 07:00:22 +0000 (+0300) Subject: draft implementation of the fast map for selection X-Git-Url: http://git.dev.opencascade.org/gitweb/?a=commitdiff_plain;h=07890cb2e4e89a530970c0a84718b71c0d9ef6e9;p=occt-copy.git draft implementation of the fast map for selection --- diff --git a/src/Select3D/Select3D_SensitivePrimitiveArray.cxx b/src/Select3D/Select3D_SensitivePrimitiveArray.cxx index fc0c6ce432..62e2ff3809 100644 --- a/src/Select3D/Select3D_SensitivePrimitiveArray.cxx +++ b/src/Select3D/Select3D_SensitivePrimitiveArray.cxx @@ -21,6 +21,72 @@ 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(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& 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& 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]); + } } } } diff --git a/src/Select3D/Select3D_SensitivePrimitiveArray.hxx b/src/Select3D/Select3D_SensitivePrimitiveArray.hxx index 50e767bf04..d8ad7caa89 100644 --- a/src/Select3D/Select3D_SensitivePrimitiveArray.hxx +++ b/src/Select3D/Select3D_SensitivePrimitiveArray.hxx @@ -24,6 +24,23 @@ #include #include +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&) const; + +private: + std::vector 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: