]> OCCT Git - occt.git/commitdiff
0031777: Visualization - improve SelectMgr_EntityOwner to process selection scheme IR-2023-04-14
authormzernova <mzernova@opencascade.com>
Tue, 7 Feb 2023 02:17:58 +0000 (02:17 +0000)
committermzernova <mzernova@opencascade.com>
Wed, 5 Apr 2023 16:20:33 +0000 (17:20 +0100)
The selection scheme has been propagated to Owner object interface, and the
AIS_Selection::Select() method has been replaced to unify the logic.

src/AIS/AIS_InteractiveContext.cxx
src/AIS/AIS_InteractiveContext.hxx
src/AIS/AIS_Selection.cxx
src/AIS/AIS_Selection.hxx
src/SelectMgr/SelectMgr_EntityOwner.cxx
src/SelectMgr/SelectMgr_EntityOwner.hxx

index 04d50baf789849eff221050bae5c15d40774fb43..866259af85da90da38677f28713bacb26863fc0c 100644 (file)
@@ -3228,6 +3228,30 @@ void AIS_InteractiveContext::ClearSelected (const Standard_Boolean theToUpdateVi
   }
 }
 
+//=======================================================================
+//function : isDetected
+//purpose  :
+//=======================================================================
+Standard_Boolean AIS_InteractiveContext::isDetected (const Handle(AIS_InteractiveObject)& theObject)
+{
+  for (Standard_Integer aDetIter = myDetectedSeq.Lower(); aDetIter <= myDetectedSeq.Upper(); aDetIter++)
+  {
+    Handle(SelectMgr_EntityOwner) aPicked = MainSelector()->Picked(myDetectedSeq(aDetIter));
+    Handle(AIS_InteractiveObject) anObj;
+    if (!aPicked.IsNull())
+    {
+      anObj = Handle(AIS_InteractiveObject)::DownCast(aPicked->Selectable());
+    }
+
+    if (!anObj.IsNull()
+      && anObj == theObject)
+    {
+      return Standard_True;
+    }
+  }
+  return Standard_False;
+}
+
 //=======================================================================
 //function : SetSelected
 //purpose  : Sets the whole object as selected and highlights it with selection color
@@ -3288,7 +3312,8 @@ void AIS_InteractiveContext::SetSelected (const Handle(AIS_InteractiveObject)& t
   }
 
   // added to avoid untimely viewer update...
-  mySelection->ClearAndSelect (anOwner);
+  const Handle(AIS_InteractiveObject) anObj = Handle(AIS_InteractiveObject)::DownCast (anOwner->Selectable());
+  mySelection->ClearAndSelect (anOwner, myFilters, isDetected (anObj));
 
   if (myAutoHilight)
   {
@@ -3350,7 +3375,7 @@ void AIS_InteractiveContext::SetSelected (const Handle(SelectMgr_EntityOwner)& t
     unhighlightSelected();
   }
 
-  mySelection->ClearAndSelect (theOwner);
+  mySelection->ClearAndSelect (theOwner, myFilters, isDetected (anObject));
   if (myAutoHilight)
   {
     Handle(Prs3d_Drawer) aCustomStyle;
@@ -3401,16 +3426,17 @@ void AIS_InteractiveContext::AddOrRemoveSelected (const Handle(SelectMgr_EntityO
     return;
   }
 
-  if (!myFilters->IsOk(theOwner) && !theOwner->IsSelected())
+  if (!myFilters->IsOk (theOwner) && !theOwner->IsSelected())
   {
     return;
   }
 
-  mySelection->Select (theOwner);
+  AIS_SelectionScheme aSelScheme = theOwner->IsSelected() ? AIS_SelectionScheme_Remove : AIS_SelectionScheme_Add;
+  const Handle(AIS_InteractiveObject) anObj = Handle(AIS_InteractiveObject)::DownCast (theOwner->Selectable());
+  mySelection->Select (theOwner, myFilters, aSelScheme, isDetected (anObj));
 
   if (myAutoHilight)
   {
-    const Handle(AIS_InteractiveObject) anObj = Handle(AIS_InteractiveObject)::DownCast (theOwner->Selectable());
     Handle(AIS_GlobalStatus)* aStatusPtr = myObjects.ChangeSeek (anObj);
     if (!aStatusPtr)
     {
@@ -3469,7 +3495,8 @@ Standard_Boolean AIS_InteractiveContext::SetSelectedState (const Handle(SelectMg
   }
   else
   {
-    const AIS_SelectStatus aSelStatus = mySelection->Select (theEntity);
+    const Handle(AIS_InteractiveObject) anObj = Handle(AIS_InteractiveObject)::DownCast(theEntity->Selectable());
+    const AIS_SelectStatus aSelStatus = mySelection->Select (theEntity, myFilters, AIS_SelectionScheme_Remove, isDetected (anObj));
     theEntity->SetSelected (false);
     return aSelStatus == AIS_SS_Removed;
   }
index 36c0cb174bbc14eec273ae51d2468da07151e198..64c30eb89d679e1476411f834d2d50bffe866a75 100644 (file)
@@ -1302,6 +1302,9 @@ protected: //! @name internal methods
   Standard_EXPORT AIS_StatusOfDetection moveTo (const Handle(V3d_View)& theView,
                                                 const Standard_Boolean  theToRedrawOnUpdate);
 
+  //! Returns True if the object is detected.
+  Standard_EXPORT Standard_Boolean isDetected (const Handle(AIS_InteractiveObject)& theObject);
+
   //! Helper function to unhighlight all entity owners currently highlighted with seleciton color.
   Standard_EXPORT void unselectOwners (const Handle(AIS_InteractiveObject)& theObject);
 
index 2b55208576e20048a19dca76ce64b5947cfdef83..b0acb5ffa1b0ffc5b0b75ce596d47e7281dc9ccd 100644 (file)
@@ -55,24 +55,38 @@ void AIS_Selection::Clear()
 //function : Select
 //purpose  :
 //=======================================================================
-AIS_SelectStatus AIS_Selection::Select (const Handle(SelectMgr_EntityOwner)& theObject)
+AIS_SelectStatus AIS_Selection::Select (const Handle(SelectMgr_EntityOwner)& theOwner,
+                                        const Handle(SelectMgr_Filter)& theFilter,
+                                        const AIS_SelectionScheme theSelScheme,
+                                        const Standard_Boolean theIsDetected)
 {
-  if (theObject.IsNull()
-  || !theObject->HasSelectable())
+  if (theOwner.IsNull()
+  || !theOwner->HasSelectable())
   {
     return AIS_SS_NotDone;
   }
 
-  if (!myResultMap.IsBound (theObject))
+  const Standard_Boolean isDetected = theIsDetected
+                                   && (theFilter.IsNull() || theFilter->IsOk (theOwner));
+
+  const Standard_Boolean wasSelected = theOwner->IsSelected();
+  const Standard_Boolean toSelect = theOwner->Select (theSelScheme, isDetected);
+
+  if (toSelect && !wasSelected)
   {
     AIS_NListOfEntityOwner::Iterator aListIter;
-    myresult.Append  (theObject, aListIter);
-    myResultMap.Bind (theObject, aListIter);
-    theObject->SetSelected (Standard_True);
+    myresult.Append  (theOwner, aListIter);
+    myResultMap.Bind (theOwner, aListIter);
+    theOwner->SetSelected (Standard_True);
     return AIS_SS_Added;
   }
 
-  AIS_NListOfEntityOwner::Iterator aListIter = myResultMap.Find (theObject);
+  if (!toSelect && !wasSelected)
+  {
+    return AIS_SS_NotDone;
+  }
+
+  AIS_NListOfEntityOwner::Iterator aListIter = myResultMap.Find (theOwner);
   if (myIterator == aListIter)
   {
     if (myIterator.More())
@@ -88,14 +102,14 @@ AIS_SelectStatus AIS_Selection::Select (const Handle(SelectMgr_EntityOwner)& the
   // In the mode of advanced mesh selection only one owner is created for all selection modes.
   // It is necessary to check the current detected entity
   // and remove the owner from map only if the detected entity is the same as previous selected (IsForcedHilight call)
-  if (theObject->IsForcedHilight())
+  if (theOwner->IsForcedHilight())
   {
     return AIS_SS_Added;
   }
 
   myresult.Remove (aListIter);
-  myResultMap.UnBind (theObject);
-  theObject->SetSelected (Standard_False);
+  myResultMap.UnBind (theOwner);
+  theOwner->SetSelected (Standard_False);
 
   // update list iterator for next object in <myresult> list if any
   if (aListIter.More())
@@ -142,87 +156,40 @@ void AIS_Selection::SelectOwners (const AIS_NArray1OfEntityOwner& thePickedOwner
                                   const Standard_Boolean theToAllowSelOverlap,
                                   const Handle(SelectMgr_Filter)& theFilter)
 {
-  (void )theToAllowSelOverlap;
-  switch (theSelScheme)
-  {
-    case AIS_SelectionScheme_UNKNOWN:
-    {
-      return;
-    }
-    case AIS_SelectionScheme_ReplaceExtra:
-    {
-      // If picked owners is equivalent to the selected then just clear selected
-      // Else go to AIS_SelectionScheme_Replace
-      if (thePickedOwners.Size() == myresult.Size())
-      {
-        Standard_Boolean isTheSame = Standard_True;
-        for (AIS_NArray1OfEntityOwner::Iterator aSelIter (thePickedOwners); aSelIter.More(); aSelIter.Next())
-        {
-          if (!myResultMap.IsBound (aSelIter.Value()))
-          {
-            isTheSame = Standard_False;
-            break;
-          }
-        }
-        if (isTheSame)
-        {
-          Clear();
-          return;
-        }
-      }
-    }
-    Standard_FALLTHROUGH
-    case AIS_SelectionScheme_Replace:
-    {
-      Clear();
-      for (AIS_NArray1OfEntityOwner::Iterator aSelIter (thePickedOwners); aSelIter.More(); aSelIter.Next())
-      {
-        appendOwner (aSelIter.Value(), theFilter);
-      }
+  (void)theToAllowSelOverlap;
 
-      return;
-    }
-    case AIS_SelectionScheme_Add:
-    {
-      for (AIS_NArray1OfEntityOwner::Iterator aSelIter (thePickedOwners); aSelIter.More(); aSelIter.Next())
-      {
-        appendOwner (aSelIter.Value(), theFilter);
-      }
-      return;
-    }
-    case AIS_SelectionScheme_Remove:
-    {
-      for (AIS_NArray1OfEntityOwner::Iterator aSelIter (thePickedOwners); aSelIter.More(); aSelIter.Next())
-      {
-        if (myResultMap.IsBound (aSelIter.Value()))
-        {
-          Select (aSelIter.Value());
-        }
-      }
-      return;
-    }
-    case AIS_SelectionScheme_XOR:
+  if (theSelScheme == AIS_SelectionScheme_ReplaceExtra
+   && thePickedOwners.Size() == myresult.Size())
+  {
+    // If picked owners is equivalent to the selected then just clear selected.
+    Standard_Boolean isTheSame = Standard_True;
+    for (AIS_NArray1OfEntityOwner::Iterator aPickedIter (thePickedOwners); aPickedIter.More(); aPickedIter.Next())
     {
-      for (AIS_NArray1OfEntityOwner::Iterator aSelIter (thePickedOwners); aSelIter.More(); aSelIter.Next())
+      if (!myResultMap.IsBound (aPickedIter.Value()))
       {
-        const Handle(SelectMgr_EntityOwner)& anOwner = aSelIter.Value();
-        if (anOwner.IsNull()
-        || !anOwner->HasSelectable()
-        || !theFilter->IsOk (anOwner))
-        {
-          continue;
-        }
-
-        Select (anOwner);
+        isTheSame = Standard_False;
+        break;
       }
-      return;
     }
-    case AIS_SelectionScheme_Clear:
+    if (isTheSame)
     {
-      Clear();
-      return;
+       Clear();
+       return;
     }
   }
+
+  if (theSelScheme == AIS_SelectionScheme_Replace
+   || theSelScheme == AIS_SelectionScheme_ReplaceExtra
+   || theSelScheme == AIS_SelectionScheme_Clear)
+  {
+    Clear();
+  }
+
+  for (AIS_NArray1OfEntityOwner::Iterator aPickedIter (thePickedOwners); aPickedIter.More(); aPickedIter.Next())
+  {
+    const Handle(SelectMgr_EntityOwner)& anOwner = aPickedIter.Value();
+    Select (anOwner, theFilter, theSelScheme, true);
+  }
 }
 
 //=======================================================================
index ce18b38ff787188c81cff91247dceeacec2c2db4..f95a94422d723fca4bc74253749238d4a5f10389 100644 (file)
@@ -34,23 +34,36 @@ public:
 
   //! creates a new selection.
   Standard_EXPORT AIS_Selection();
-  
+
   //! removes all the object of the selection.
   Standard_EXPORT virtual void Clear();
-  
+
   //! if the object is not yet in the selection, it will be added.
   //! if the object is already in the selection, it will be removed.
-  Standard_EXPORT virtual AIS_SelectStatus Select (const Handle(SelectMgr_EntityOwner)& theObject);
-  
+  //! @param[in] theOwner element to change selection state
+  //! @param[in] theFilter context filter
+  //! @param[in] theSelScheme selection scheme
+  //! @param[in] theIsDetected flag of object detection
+  //! @return result of selection
+  Standard_EXPORT virtual AIS_SelectStatus Select (const Handle(SelectMgr_EntityOwner)& theOwner,
+                                                   const Handle(SelectMgr_Filter)& theFilter,
+                                                   const AIS_SelectionScheme theSelScheme,
+                                                   const Standard_Boolean theIsDetected);
+
   //! the object is always add int the selection.
   //! faster when the number of objects selected is great.
   Standard_EXPORT virtual AIS_SelectStatus AddSelect (const Handle(SelectMgr_EntityOwner)& theObject);
 
   //! clears the selection and adds the object in the selection.
-  virtual void ClearAndSelect (const Handle(SelectMgr_EntityOwner)& theObject)
+  //! @param[in] theObject element to change selection state
+  //! @param[in] theFilter context filter
+  //! @param[in] theIsDetected flag of object detection
+  virtual void ClearAndSelect (const Handle(SelectMgr_EntityOwner)& theObject,
+                               const Handle(SelectMgr_Filter)& theFilter,
+                               const Standard_Boolean theIsDetected)
   {
     Clear();
-    Select (theObject);
+    Select (theObject, theFilter, AIS_SelectionScheme_Add, theIsDetected);
   }
 
   //! checks if the object is in the selection.
index 357684c0c81e41e6acbe7551cbafbd3436ebe066..8f1077a293e9f8aec02bbec69974b01f2b8d5359 100644 (file)
@@ -83,6 +83,51 @@ void SelectMgr_EntityOwner::HilightWithColor (const Handle(PrsMgr_PresentationMa
   }
 }
 
+// =======================================================================
+// function : Select
+// purpose  :
+// =======================================================================
+Standard_Boolean SelectMgr_EntityOwner::Select (const AIS_SelectionScheme theSelScheme,
+                                                const Standard_Boolean theIsDetected) const
+{
+  switch (theSelScheme)
+  {
+    case AIS_SelectionScheme_UNKNOWN:
+    {
+      return myIsSelected;
+    }
+    case AIS_SelectionScheme_Replace:
+    {
+      return theIsDetected;
+    }
+    case AIS_SelectionScheme_Add:
+    {
+      return !myIsSelected || theIsDetected || IsForcedHilight();
+    }
+    case AIS_SelectionScheme_Remove:
+    {
+      return myIsSelected && !theIsDetected;
+    }
+    case AIS_SelectionScheme_XOR:
+    {
+      if (theIsDetected)
+      {
+        return !myIsSelected && !IsForcedHilight();
+      }
+      return myIsSelected;
+    }
+    case AIS_SelectionScheme_Clear:
+    {
+      return Standard_False;
+    }
+    case AIS_SelectionScheme_ReplaceExtra:
+    {
+      return theIsDetected;
+    }
+  }
+  return Standard_False;
+}
+
 // =======================================================================
 // function : DumpJson
 // purpose  :
index f2cebbbdc246013ec3d09bb5e02f89426c0c742d..2454db8dcfa98d71de28c03f1e55fd5c0ffacb6a 100644 (file)
@@ -17,6 +17,7 @@
 #ifndef _SelectMgr_EntityOwner_HeaderFile
 #define _SelectMgr_EntityOwner_HeaderFile
 
+#include <AIS_SelectionScheme.hxx>
 #include <Aspect_VKey.hxx>
 #include <PrsMgr_PresentationManager.hxx>
 #include <SelectMgr_SelectableObject.hxx>
@@ -139,6 +140,12 @@ public:
   //! @param theIsSelected [in] shows if owner is selected.
   void SetSelected (const Standard_Boolean theIsSelected) { myIsSelected = theIsSelected; }
 
+  //! If the object needs to be selected, it returns true.
+  //! @param[in] theSelScheme  selection scheme
+  //! @param[in] theIsDetected flag of object detection
+  Standard_EXPORT Standard_Boolean Select (const AIS_SelectionScheme theSelScheme,
+                                           const Standard_Boolean theIsDetected) const;
+
   //! Returns selection state.
   Standard_DEPRECATED ("Deprecated method - IsSelected() should be used instead")
   Standard_Integer State() const { return myIsSelected ? 1 : 0; }