From 6054db8a2941a8533893bd3a6cdaca78b7ea66a3 Mon Sep 17 00:00:00 2001 From: kgv Date: Mon, 26 Jul 2021 17:16:13 +0300 Subject: [PATCH] 0032482: Visualization - Object owner isn't removed from picked owner when object is removed SelectMgr_ViewerSelector::RemoveSelectableObject() now removes object from picking results. --- src/AIS/AIS_InteractiveContext.cxx | 4 +- src/SelectMgr/SelectMgr_ViewerSelector.cxx | 74 ++++++++++++++++------ src/SelectMgr/SelectMgr_ViewerSelector.hxx | 16 +++-- tests/vselect/bugs/bug32482 | 17 +++++ 4 files changed, 84 insertions(+), 27 deletions(-) create mode 100644 tests/vselect/bugs/bug32482 diff --git a/src/AIS/AIS_InteractiveContext.cxx b/src/AIS/AIS_InteractiveContext.cxx index 3566fcab4e..fee11abb9f 100644 --- a/src/AIS/AIS_InteractiveContext.cxx +++ b/src/AIS/AIS_InteractiveContext.cxx @@ -682,6 +682,8 @@ void AIS_InteractiveContext::Remove (const Handle(AIS_InteractiveObject)& theIOb //======================================================================= void AIS_InteractiveContext::RemoveAll (const Standard_Boolean theToUpdateViewer) { + ClearDetected(); + AIS_ListOfInteractive aList; ObjectsInside (aList); for (AIS_ListOfInteractive::Iterator aListIterator (aList); aListIterator.More(); aListIterator.Next()) @@ -1899,7 +1901,6 @@ void AIS_InteractiveContext::ClearGlobal (const Handle(AIS_InteractiveObject)& t theIObj->ErasePresentations (true); // make sure highlighting presentations are properly erased // Object removes from Detected sequence - Standard_DISABLE_DEPRECATION_WARNINGS for (Standard_Integer aDetIter = myDetectedSeq.Lower(); aDetIter <= myDetectedSeq.Upper();) { Handle(SelectMgr_EntityOwner) aPicked = myMainSel->Picked (myDetectedSeq (aDetIter)); @@ -1927,7 +1928,6 @@ void AIS_InteractiveContext::ClearGlobal (const Handle(AIS_InteractiveObject)& t aDetIter++; } } - Standard_ENABLE_DEPRECATION_WARNINGS // remove IO from the selection manager to avoid memory leaks const Handle(SelectMgr_SelectableObject)& anObj = theIObj; // to avoid ambiguity diff --git a/src/SelectMgr/SelectMgr_ViewerSelector.cxx b/src/SelectMgr/SelectMgr_ViewerSelector.cxx index 1ebf8c1604..d1e646928e 100644 --- a/src/SelectMgr/SelectMgr_ViewerSelector.cxx +++ b/src/SelectMgr/SelectMgr_ViewerSelector.cxx @@ -165,6 +165,7 @@ SelectMgr_ViewerSelector::SelectMgr_ViewerSelector() myToPreferClosest (Standard_True), myCameraScale (1.0), myToPrebuildBVH (Standard_False), + myIsSorted (Standard_False), myIsLeftChildQueuedFirst (Standard_False) { myEntitySetBuilder = new BVH_BinnedBuilder (BVH_Constants_LeafNodeSizeSingle, BVH_Constants_MaxTreeDepth, Standard_True); @@ -228,15 +229,6 @@ void SelectMgr_ViewerSelector::Deactivate (const Handle(SelectMgr_Selection)& th } } -//================================================== -// Function: Clear -// Purpose : -//================================================== -void SelectMgr_ViewerSelector::Clear() -{ - mystored.Clear(); -} - //======================================================================= // function: isToScaleFrustum // purpose : Checks if the entity given requires to scale current selecting frustum @@ -612,6 +604,7 @@ void SelectMgr_ViewerSelector::TraverseSensitives() SelectMgr_BVHThreadPool::Sentry aSentry (myBVHThreadPool); mystored.Clear(); + myIsSorted = false; Graphic3d_Vec2i aWinSize; mySelectingVolumeMgr.WindowSize (aWinSize.x(), aWinSize.y()); @@ -760,6 +753,38 @@ void SelectMgr_ViewerSelector::TraverseSensitives() void SelectMgr_ViewerSelector::ClearPicked() { mystored.Clear(); + myIsSorted = true; +} + +//================================================== +// Function: RemovePicked +// Purpose : +//================================================== +bool SelectMgr_ViewerSelector::RemovePicked (const Handle(SelectMgr_SelectableObject)& theObject) +{ + if (mystored.IsEmpty() + || !mySelectableObjects.Contains (theObject)) + { + return false; + } + + bool isRemoved = false; + for (Standard_Integer aPickIter = 1; aPickIter <= mystored.Extent(); ++aPickIter) + { + const Handle(SelectMgr_EntityOwner)& aStoredOwner = mystored.FindKey (aPickIter); + if (!aStoredOwner.IsNull() + && aStoredOwner->IsSameSelectable (theObject)) + { + mystored.RemoveFromIndex (aPickIter); + --aPickIter; + isRemoved = true; + } + } + if (isRemoved) + { + myIsSorted = false; + } + return isRemoved; } //======================================================================= @@ -773,7 +798,12 @@ Handle(SelectMgr_EntityOwner) SelectMgr_ViewerSelector::Picked (const Standard_I return Handle(SelectMgr_EntityOwner)(); } - const Standard_Integer anOwnerIdx = myIndexes->Value (theRank); + if (!myIsSorted) + { + SortResult(); + } + + const Standard_Integer anOwnerIdx = myIndexes.Value (theRank); const Handle(SelectMgr_EntityOwner)& aStoredOwner = mystored.FindKey (anOwnerIdx); return aStoredOwner; } @@ -785,7 +815,12 @@ Handle(SelectMgr_EntityOwner) SelectMgr_ViewerSelector::Picked (const Standard_I const SelectMgr_SortCriterion& SelectMgr_ViewerSelector::PickedData(const Standard_Integer theRank) const { Standard_OutOfRange_Raise_if (theRank < 1 || theRank > NbPicked(), "SelectMgr_ViewerSelector::PickedData() out of range index"); - const Standard_Integer anOwnerIdx = myIndexes->Value (theRank); + if (!myIsSorted) + { + SortResult(); + } + + const Standard_Integer anOwnerIdx = myIndexes.Value (theRank); return mystored.FindFromIndex (anOwnerIdx); } @@ -911,25 +946,26 @@ TCollection_AsciiString SelectMgr_ViewerSelector::Status (const Handle(SelectMgr //function : SortResult //purpose : //======================================================================= -void SelectMgr_ViewerSelector::SortResult() +void SelectMgr_ViewerSelector::SortResult() const { if (mystored.IsEmpty()) { + myIsSorted = true; return; } const Standard_Integer anExtent = mystored.Extent(); - if (myIndexes.IsNull() || anExtent != myIndexes->Length()) + if (anExtent != myIndexes.Length()) { - myIndexes = new TColStd_HArray1OfInteger (1, anExtent); + myIndexes.Resize (1, anExtent, false); } - TColStd_Array1OfInteger& anIndexArray = myIndexes->ChangeArray1(); for (Standard_Integer anIndexIter = 1; anIndexIter <= anExtent; ++anIndexIter) { - anIndexArray.SetValue (anIndexIter, anIndexIter); + myIndexes.SetValue (anIndexIter, anIndexIter); } - std::sort (anIndexArray.begin(), anIndexArray.end(), CompareResults (mystored, myToPreferClosest)); + std::sort (myIndexes.begin(), myIndexes.end(), CompareResults (mystored, myToPreferClosest)); + myIsSorted = true; } //======================================================================= @@ -983,6 +1019,7 @@ void SelectMgr_ViewerSelector::RemoveSelectableObject (const Handle(SelectMgr_Se Handle(SelectMgr_SelectableObject) anObj = theObject; if (myMapOfObjectSensitives.UnBind (theObject)) { + RemovePicked (theObject); mySelectableObjects.Remove (theObject); } } @@ -1118,8 +1155,7 @@ void SelectMgr_ViewerSelector::DumpJson (Standard_OStream& theOStream, Standard_ OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, &myCameraDir) OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myCameraScale) - if (!myIndexes.IsNull()) - OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myIndexes->Size()) + OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myIndexes.Size()) OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myIsLeftChildQueuedFirst) OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myMapOfObjectSensitives.Extent()) diff --git a/src/SelectMgr/SelectMgr_ViewerSelector.hxx b/src/SelectMgr/SelectMgr_ViewerSelector.hxx index fc8ea81b8f..ef5b6276c8 100644 --- a/src/SelectMgr/SelectMgr_ViewerSelector.hxx +++ b/src/SelectMgr/SelectMgr_ViewerSelector.hxx @@ -84,9 +84,6 @@ class SelectMgr_ViewerSelector : public Standard_Transient friend class SelectMgr_SelectionManager; public: - //! Empties all the tables, removes all selections... - Standard_EXPORT void Clear(); - //! Returns custom pixel tolerance value. Standard_Integer CustomPixelTolerance() const { return myTolerances.CustomTolerance(); } @@ -99,8 +96,8 @@ public: //! Returns the largest pixel tolerance. Standard_Integer PixelTolerance() const { return myTolerances.Tolerance(); } - //! Sorts the detected entites by priority and distance. - Standard_EXPORT virtual void SortResult(); + //! Sorts the detected entities by priority and distance. + Standard_EXPORT virtual void SortResult() const; //! Returns the picked element with the highest priority, //! and which is the closest to the last successful mouse position. @@ -144,6 +141,9 @@ public: //! Clears picking results. Standard_EXPORT void ClearPicked(); + //! Empties all the tables, removes all selections... + void Clear() { ClearPicked(); } + //! Returns the entity Owner for the object picked at specified position. //! @param theRank rank of detected object within range 1...NbPicked() Standard_EXPORT Handle(SelectMgr_EntityOwner) Picked (const Standard_Integer theRank) const; @@ -161,6 +161,9 @@ public: //! @param theRank rank of detected object within range 1...NbPicked() gp_Pnt PickedPoint (const Standard_Integer theRank) const { return PickedData (theRank).Point; } + //! Remove picked entities associated with specified object. + Standard_EXPORT Standard_Boolean RemovePicked (const Handle(SelectMgr_SelectableObject)& theObject); + Standard_EXPORT Standard_Boolean Contains (const Handle(SelectMgr_SelectableObject)& theObject) const; //! Returns the default builder used to construct BVH of entity set. @@ -341,7 +344,8 @@ protected: Standard_Boolean myToPrebuildBVH; Handle(SelectMgr_BVHThreadPool) myBVHThreadPool; - Handle(TColStd_HArray1OfInteger) myIndexes; + mutable TColStd_Array1OfInteger myIndexes; + mutable Standard_Boolean myIsSorted; Standard_Boolean myIsLeftChildQueuedFirst; SelectMgr_MapOfObjectSensitives myMapOfObjectSensitives; diff --git a/tests/vselect/bugs/bug32482 b/tests/vselect/bugs/bug32482 new file mode 100644 index 0000000000..760938b4db --- /dev/null +++ b/tests/vselect/bugs/bug32482 @@ -0,0 +1,17 @@ +puts "========" +puts "0032482: Visualization - Object owner isn't removed from picked owner when object is removed" +puts "========" +puts "" + +pload MODELING VISUALIZATION +box b1 1 2 3 +box b2 -0.5 -0.5 -0.5 3 2 1 +vinit View1 +vdisplay -dispMode 1 b1 b2 +vfit +vmoveto 200 200 +vstate -entities +vremove b1 +vstate -entities + +vdump $imagedir/${casename}.png