]> OCCT Git - occt-copy.git/commitdiff
0030737: Visualization - implementing new selection schemes in context
authornds <nds@opencascade.com>
Tue, 20 Aug 2019 12:16:34 +0000 (15:16 +0300)
committernds <natalia.ermolaeva@opencascade.com>
Fri, 15 May 2020 18:41:29 +0000 (21:41 +0300)
(cherry picked from commit 8ac88685123f50caef2b53010da626b4682d9bd4)

src/AIS/AIS_InteractiveContext.hxx
src/AIS/AIS_InteractiveContext_1.cxx
src/AIS/AIS_Selection.cxx
src/AIS/AIS_Selection.hxx
src/AIS/AIS_SelectionScheme.hxx [new file with mode: 0644]
src/AIS/FILES

index 42b89bbd270303ee645bce05b6689bd657b56de4..a5e6298160948b08085a1b9cad9316ced08c8f93 100644 (file)
@@ -25,6 +25,7 @@
 #include <AIS_ListOfInteractive.hxx>
 #include <AIS_Selection.hxx>
 #include <AIS_SelectionModesConcurrency.hxx>
+#include <AIS_SelectionScheme.hxx>
 #include <AIS_StatusOfDetection.hxx>
 #include <AIS_StatusOfPick.hxx>
 #include <AIS_TypeOfIso.hxx>
@@ -470,6 +471,24 @@ public: //! @name Selection management
     return AddSelect (theObject->GlobalSelOwner());
   }
 
+  //! Selects everything found in the bounding rectangle defined by the pixel minima and maxima, XPMin, YPMin, XPMax, and YPMax in the view.
+  //! The objects detected are passed to the main viewer, which is then updated.
+  Standard_EXPORT AIS_StatusOfPick Select (const Standard_Integer  theXPMin,
+                                           const Standard_Integer  theYPMin,
+                                           const Standard_Integer  theXPMax,
+                                           const Standard_Integer  theYPMax,
+                                           const Handle(V3d_View)& theView,
+                                           const AIS_SelectionScheme theSelScheme);
+  
+  //! polyline selection; clears the previous picked list
+  Standard_EXPORT AIS_StatusOfPick Select (const TColgp_Array1OfPnt2d& thePolyline,
+                                           const Handle(V3d_View)&     theView,
+                                           const AIS_SelectionScheme   theSelScheme);
+
+  //! Stores and hilights the previous detected; Unhilights the previous picked.
+  //! @sa MoveTo().
+  Standard_EXPORT AIS_StatusOfPick Select (const AIS_SelectionScheme theSelScheme);
+
   //! Selects everything found in the bounding rectangle defined by the pixel minima and maxima, XPMin, YPMin, XPMax, and YPMax in the view.
   //! The objects detected are passed to the main viewer, which is then updated.
   Standard_EXPORT AIS_StatusOfPick Select (const Standard_Integer  theXPMin,
@@ -511,6 +530,13 @@ public: //! @name Selection management
   //! Returns bounding box of selected objects.
   Standard_EXPORT Bnd_Box BoundingBoxOfSelection() const;
 
+  //! Sets list of owner selected/deselected using selection scheme
+  //! It is possible that selection of other objects is changed relatively selection scheme   .
+  //! \param theOwner owners to change selection state
+  //! \param theSelScheme selection scheme
+  Standard_EXPORT AIS_StatusOfPick Select (const AIS_NListOfEntityOwner& theOwners,
+                                           const AIS_SelectionScheme theSelScheme);
+
   //! Fits the view correspondingly to the bounds of selected objects.
   //! Infinite objects are ignored if infinite state of AIS_InteractiveObject is set to true.
   Standard_EXPORT void FitSelected (const Handle(V3d_View)& theView,
index 70ba165da4b8f4d115508fc602665945b9d1a42b..699a8711268700cf2c42c044b36d551700ccb8e1 100644 (file)
@@ -490,38 +490,37 @@ AIS_StatusOfPick AIS_InteractiveContext::Select (const Standard_Integer  theXPMi
                                                  const Standard_Integer  theXPMax,
                                                  const Standard_Integer  theYPMax,
                                                  const Handle(V3d_View)& theView,
-                                                 const Standard_Boolean  toUpdateViewer)
+                                                 const AIS_SelectionScheme theSelScheme)
 {
   if (theView->Viewer() != myMainVwr)
   {
     throw Standard_ProgramError ("AIS_InteractiveContext::Select() - invalid argument");
   }
 
-  // all objects detected by the selector are taken, previous current objects are emptied,
-  // new objects are put...
-  ClearSelected (Standard_False);
   myLastActiveView = theView.get();
-  myMainSel->Pick (theXPMin, theYPMin, theXPMax, theYPMax, theView);
-  for (Standard_Integer aPickIter = 1; aPickIter <= myMainSel->NbPicked(); ++aPickIter)
+  if (!myLastPicked.IsNull())
   {
-    const Handle(SelectMgr_EntityOwner)& aCurOwner = myMainSel->Picked (aPickIter);
-    if (aCurOwner.IsNull() || !aCurOwner->HasSelectable() || !myFilters->IsOk (aCurOwner))
-      continue;
-
-    mySelection->Select (aCurOwner);
+    Graphic3d_Vec2i aMousePos (-1, -1);
+    if (myMainSel->GetManager().GetActiveSelectionType() == SelectBasics_SelectingVolumeManager::Point)
+    {
+      aMousePos.SetValues ((Standard_Integer )myMainSel->GetManager().GetMousePosition().X(),
+                           (Standard_Integer )myMainSel->GetManager().GetMousePosition().Y());
+    }
+    if (myLastPicked->HandleMouseClick (aMousePos, Aspect_VKeyMouse_LeftButton, Aspect_VKeyFlags_NONE, false))
+    {
+      return AIS_SOP_NothingSelected;
+    }
   }
 
-  if (myAutoHilight)
+  myMainSel->Pick (theXPMin, theYPMin, theXPMax, theYPMax, theView);
+
+  AIS_NListOfEntityOwner aPickedOwners;
+  for (Standard_Integer aPickIter = 1; aPickIter <= myMainSel->NbPicked(); ++aPickIter)
   {
-    HilightSelected (toUpdateViewer);
+    aPickedOwners.Append (myMainSel->Picked (aPickIter));
   }
 
-  Standard_Integer aSelNum = NbSelected();
-
-  return (aSelNum == 0) ? AIS_SOP_NothingSelected
-                        : (aSelNum == 1) ? AIS_SOP_OneSelected
-                                         : AIS_SOP_SeveralSelected;
-  
+  return Select (aPickedOwners, theSelScheme);
 }
 
 //=======================================================================
@@ -530,48 +529,38 @@ AIS_StatusOfPick AIS_InteractiveContext::Select (const Standard_Integer  theXPMi
 //=======================================================================
 AIS_StatusOfPick AIS_InteractiveContext::Select (const TColgp_Array1OfPnt2d& thePolyline,
                                                  const Handle(V3d_View)&     theView,
-                                                 const Standard_Boolean      toUpdateViewer)
+                                                 const AIS_SelectionScheme   theSelScheme)
 {
   if (theView->Viewer() != myMainVwr)
   {
     throw Standard_ProgramError ("AIS_InteractiveContext::Select() - invalid argument");
   }
 
-  // all objects detected by the selector are taken, previous current objects are emptied,
-  // new objects are put...
-  ClearSelected (Standard_False);
-  myLastActiveView = theView.get();
   myMainSel->Pick (thePolyline, theView);
-  for (Standard_Integer aPickIter = 1; aPickIter <= myMainSel->NbPicked(); ++aPickIter)
-  {
-    const Handle(SelectMgr_EntityOwner) anOwner = myMainSel->Picked (aPickIter);
-    if (anOwner.IsNull() || !anOwner->HasSelectable() || !myFilters->IsOk (anOwner))
-      continue;
 
-    mySelection->Select (anOwner);
-  }
-
-  if (myAutoHilight)
+  AIS_NListOfEntityOwner aPickedOwners;
+  for (Standard_Integer aPickIter = 1; aPickIter <= myMainSel->NbPicked(); ++aPickIter)
   {
-    HilightSelected (toUpdateViewer);
+    aPickedOwners.Append (myMainSel->Picked (aPickIter));
   }
 
-  Standard_Integer aSelNum = NbSelected();
-
-  return (aSelNum == 0) ? AIS_SOP_NothingSelected
-                        : (aSelNum == 1) ? AIS_SOP_OneSelected
-                                         : AIS_SOP_SeveralSelected;
-  
+  return Select (aPickedOwners, theSelScheme);
 }
 
 //=======================================================================
 //function : Select
 //purpose  : 
 //=======================================================================
-AIS_StatusOfPick AIS_InteractiveContext::Select (const Standard_Boolean toUpdateViewer)
+AIS_StatusOfPick AIS_InteractiveContext::Select (const AIS_SelectionScheme theSelScheme)
 {
-  if (!myLastPicked.IsNull())
+  // special case: single selection of detected owner - is it necessary ?
+  /*if (myWasLastMain && !myLastinMain.IsNull() && !myAutoHilight &&
+      (myLastinMain->IsSelected()
+      && !myLastinMain->IsForcedHilight()
+      && NbSelected() <= 1))
   {
+    mySelection->selectOwner(myLastinMain, aPrevSelected, theSelScheme);
+
     Graphic3d_Vec2i aMousePos (-1, -1);
     if (myMainSel->GetManager().GetActiveSelectionType() == SelectBasics_SelectingVolumeManager::Point)
     {
@@ -582,54 +571,56 @@ AIS_StatusOfPick AIS_InteractiveContext::Select (const Standard_Boolean toUpdate
     {
       return AIS_SOP_NothingSelected;
     }
+    return getStatusOfPick (NbSelected());
+  }*/
 
-    if (myAutoHilight)
-    {
-      clearDynamicHighlight();
-    }
-    if (!myLastPicked->IsSelected()
-      || myLastPicked->IsForcedHilight()
-      || NbSelected() > 1)
-    {
-      SetSelected (myLastPicked, Standard_False);
-      if(toUpdateViewer)
-      {
-        UpdateCurrentViewer();
-      }
-    }
-  }
-  else
-  {
-    ClearSelected (toUpdateViewer);
-  }
-
-  Standard_Integer aSelNum = NbSelected();
+  AIS_NListOfEntityOwner aPickedOwners;
+  aPickedOwners.Append (myLastPicked);
 
-  return (aSelNum == 0) ? AIS_SOP_NothingSelected
-                        : (aSelNum == 1) ? AIS_SOP_OneSelected
-                                         : AIS_SOP_SeveralSelected;
+  return Select (aPickedOwners, theSelScheme);
 }
 
 //=======================================================================
-//function : ShiftSelect
+//function : Select
 //purpose  : 
 //=======================================================================
-AIS_StatusOfPick AIS_InteractiveContext::ShiftSelect (const Standard_Boolean toUpdateViewer)
+AIS_StatusOfPick AIS_InteractiveContext::Select (const Standard_Integer  theXPMin,
+                                                 const Standard_Integer  theYPMin,
+                                                 const Standard_Integer  theXPMax,
+                                                 const Standard_Integer  theYPMax,
+                                                 const Handle(V3d_View)& theView,
+                                                 const Standard_Boolean)
 {
-  if (myAutoHilight)
-  {
-    clearDynamicHighlight();
-  }
-  if (!myLastPicked.IsNull())
-  {
-    AddOrRemoveSelected (myLastPicked, toUpdateViewer);
-  }
+  return Select (theXPMin, theYPMin, theXPMax, theYPMax, theView, AIS_SelectionScheme_ClearAndAdd);
+}
 
-  Standard_Integer aSelNum = NbSelected();
+//=======================================================================
+//function : Select
+//purpose  : Selection by polyline
+//=======================================================================
+AIS_StatusOfPick AIS_InteractiveContext::Select (const TColgp_Array1OfPnt2d& thePolyline,
+                                                 const Handle(V3d_View)&     theView,
+                                                 const Standard_Boolean)
+{
+  return Select (thePolyline, theView, AIS_SelectionScheme_ClearAndAdd);
+}
 
-  return (aSelNum == 0) ? AIS_SOP_NothingSelected
-                        : (aSelNum == 1) ? AIS_SOP_OneSelected
-                        : AIS_SOP_SeveralSelected;
+//=======================================================================
+//function : Select
+//purpose  : 
+//=======================================================================
+AIS_StatusOfPick AIS_InteractiveContext::Select (const Standard_Boolean)
+{
+  return Select (AIS_SelectionScheme_ClearAndAdd);
+}
+
+//=======================================================================
+//function : ShiftSelect
+//purpose  : 
+//=======================================================================
+AIS_StatusOfPick AIS_InteractiveContext::ShiftSelect (const Standard_Boolean)
+{
+  return Select (AIS_SelectionScheme_Switch);
 }
 
 //=======================================================================
@@ -641,39 +632,9 @@ AIS_StatusOfPick AIS_InteractiveContext::ShiftSelect (const Standard_Integer the
                                                       const Standard_Integer theXPMax,
                                                       const Standard_Integer theYPMax,
                                                       const Handle(V3d_View)& theView,
-                                                      const Standard_Boolean toUpdateViewer)
+                                                      const Standard_Boolean)
 {
-  if (theView->Viewer() != myMainVwr)
-  {
-    throw Standard_ProgramError ("AIS_InteractiveContext::ShiftSelect() - invalid argument");
-  }
-
-  myLastActiveView = theView.get();
-  if (myAutoHilight)
-  {
-    UnhilightSelected (Standard_False);
-  }
-  myMainSel->Pick (theXPMin, theYPMin, theXPMax, theYPMax, theView);
-  for (Standard_Integer aPickIter = 1; aPickIter <= myMainSel->NbPicked(); ++aPickIter)
-  {
-    const Handle(SelectMgr_EntityOwner) anOwner = myMainSel->Picked (aPickIter);
-    if (anOwner.IsNull() || !anOwner->HasSelectable() || !myFilters->IsOk (anOwner))
-      continue;
-
-    mySelection->Select (anOwner);
-  }
-
-  if (myAutoHilight)
-  {
-    HilightSelected (toUpdateViewer);
-  }
-
-  Standard_Integer aSelNum = NbSelected();
-
-  return (aSelNum == 0) ? AIS_SOP_NothingSelected
-                        : (aSelNum == 1) ? AIS_SOP_OneSelected
-                                         : AIS_SOP_SeveralSelected;
-
+  return Select (theXPMin, theYPMin, theXPMax, theYPMax, theView, AIS_SelectionScheme_Switch);
 }
 
 //=======================================================================
@@ -682,31 +643,31 @@ AIS_StatusOfPick AIS_InteractiveContext::ShiftSelect (const Standard_Integer the
 //=======================================================================
 AIS_StatusOfPick AIS_InteractiveContext::ShiftSelect (const TColgp_Array1OfPnt2d& thePolyline,
                                                       const Handle(V3d_View)& theView,
-                                                      const Standard_Boolean toUpdateViewer)
+                                                      const Standard_Boolean)
 {
-  if (theView->Viewer() != myMainVwr)
-  {
-    throw Standard_ProgramError ("AIS_InteractiveContext::ShiftSelect() - invalid argument");
-  }
+  return Select (thePolyline, theView, AIS_SelectionScheme_Switch);
+}
 
-  myLastActiveView = theView.get();
+//=======================================================================
+//function : Select
+//purpose  :
+//=======================================================================
+AIS_StatusOfPick AIS_InteractiveContext::Select (const AIS_NListOfEntityOwner& theOwners,
+                                                 const AIS_SelectionScheme theSelScheme)
+{
+  // all objects detected by the selector are taken, previous current objects are emptied,
+  // new objects are put...
   if (myAutoHilight)
   {
+    clearDynamicHighlight();
     UnhilightSelected (Standard_False);
   }
-  myMainSel->Pick (thePolyline, theView);
-  for (Standard_Integer aPickIter = 1; aPickIter <= myMainSel->NbPicked(); ++aPickIter)
-  {
-    const Handle(SelectMgr_EntityOwner) anOwner = myMainSel->Picked (aPickIter);
-    if (anOwner.IsNull() || !anOwner->HasSelectable() || !myFilters->IsOk (anOwner))
-      continue;
 
-    mySelection->Select (anOwner);
-  }
+  mySelection->SelectOwners (theOwners, theSelScheme, myFilters);
 
   if (myAutoHilight)
   {
-    HilightSelected (toUpdateViewer);
+    HilightSelected (Standard_False);
   }
 
   Standard_Integer aSelNum = NbSelected();
index e26bddf82834634843ed256bffbbe47d3c2665f7..8569e8a2b72d210ec50c37b393ad398b8e3acd39 100644 (file)
@@ -15,6 +15,8 @@
 #include <AIS_Selection.hxx>
 
 #include <AIS_InteractiveObject.hxx>
+#include <AIS_SelectionScheme.hxx>
+#include <SelectMgr_Filter.hxx>
 
 IMPLEMENT_STANDARD_RTTIEXT(AIS_Selection, Standard_Transient)
 
@@ -130,3 +132,71 @@ AIS_SelectStatus AIS_Selection::AddSelect (const Handle(SelectMgr_EntityOwner)&
   theObject->SetSelected (Standard_True);
   return AIS_SS_Added;
 }
+
+//=======================================================================
+//function : SelectOwners
+//purpose  : 
+//=======================================================================
+void AIS_Selection::SelectOwners (const AIS_NListOfEntityOwner& thePickedOwners,
+                                  const int theSelScheme,
+                                  const Handle(SelectMgr_Filter)& theFilter)
+{
+  int aSelScheme = theSelScheme;
+  AIS_NListOfEntityOwner aPrevSelected = Objects();
+  if (theSelScheme & AIS_SelectionScheme_Clear)
+  {
+    Clear();
+
+    if (theSelScheme & AIS_SelectionScheme_Switch &&
+        theSelScheme & AIS_SelectionScheme_PickedIfEmpty &&
+        thePickedOwners.Size() < aPrevSelected.Size())
+    {
+      // check if all picked objects are in previous selected list, if so, all objects will be deselected,
+      // but in mode AIS_SelectionScheme_PickedIfEmpty new picked objects should be selected, here, after Clear, Add
+      Standard_Boolean anOtherFound = Standard_False;
+      for (AIS_NListOfEntityOwner::Iterator aSelIter (thePickedOwners); aSelIter.More(); aSelIter.Next())
+      {
+        anOtherFound = !aPrevSelected.Contains (aSelIter.Value());
+        if (anOtherFound)
+          break;
+      }
+      if (!anOtherFound)
+        aSelScheme = AIS_SelectionScheme_Add;
+    }
+  }
+
+  for (AIS_NListOfEntityOwner::Iterator aSelIter (thePickedOwners); aSelIter.More(); aSelIter.Next())
+  {
+    selectOwner(aSelIter.Value(), aPrevSelected, aSelScheme, theFilter);
+  }
+}
+
+//=======================================================================
+//function : selectOwner
+//purpose  : 
+//=======================================================================
+AIS_SelectStatus AIS_Selection::selectOwner (const Handle(SelectMgr_EntityOwner)& theOwner,
+                                             const AIS_NListOfEntityOwner& thePreviousSelected,
+                                             const int theSelScheme,
+                                             const Handle(SelectMgr_Filter)& theFilter)
+{
+  if (theOwner.IsNull() || !theOwner->HasSelectable() || !theFilter->IsOk (theOwner))
+    return AIS_SS_NotDone;
+
+  if (theSelScheme & AIS_SelectionScheme_Add)
+  {
+    return AddSelect (theOwner);
+  }
+  else if (theSelScheme & AIS_SelectionScheme_Switch)
+  {
+    if (thePreviousSelected.Contains (theOwner)) // was selected, should not be now
+    {
+      if (theOwner->IsSelected())
+        return Select (theOwner); // deselect
+    }
+    else
+      return AddSelect (theOwner); // was not selected, should be now
+  }
+
+  return AIS_SS_NotDone;
+}
index 8e7cf50e91dd39aa26c7571670340a74175016b2..dc56d6dad6aa5d18b7edfe3170ab75bf92f0387c 100644 (file)
@@ -22,6 +22,8 @@
 #include <Standard.hxx>
 #include <Standard_Type.hxx>
 
+class SelectMgr_Filter;
+
 //! Class holding the list of selected owners.
 class AIS_Selection : public Standard_Transient
 {
@@ -75,6 +77,28 @@ public:
   //! Return selected object at iterator position.
   const Handle(SelectMgr_EntityOwner)& Value() const { return myIterator.Value(); }
 
+  //! Select or deselect owners depending on the selection scheme
+  //! \param theOwners elements to change selection state
+  //! \param theSelScheme selection scheme, defines how owner is selected
+  //! \param theFilter context filter to skip not acceptable owners
+  //! \return result of selection
+  Standard_EXPORT virtual void SelectOwners (const AIS_NListOfEntityOwner& thePickedOwners,
+                                             const int theSelScheme,
+                                             const Handle(SelectMgr_Filter)& theFilter);
+
+protected:
+  //! Select or deselect owner depending on the selection scheme
+  //! \param theOwner element to change selection state
+  //! \param thePreviousSelected previous selected objects
+  //! \param theSelScheme selection scheme, defines how owner is selected
+  //! \param theFilter context filter to skip not acceptable owners
+  //! \return result of selection
+  Standard_EXPORT virtual AIS_SelectStatus selectOwner (const Handle(SelectMgr_EntityOwner)& theOwner,
+                                                        const AIS_NListOfEntityOwner& thePreviousSelected,
+                                                        const int theSelScheme,
+                                                        const Handle(SelectMgr_Filter)& theFilter);
+
+
 private:
 
   AIS_NListOfEntityOwner myresult;
diff --git a/src/AIS/AIS_SelectionScheme.hxx b/src/AIS/AIS_SelectionScheme.hxx
new file mode 100644 (file)
index 0000000..0dc03a3
--- /dev/null
@@ -0,0 +1,34 @@
+// Copyright (c) 2019 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+
+#ifndef _AIS_SelectionScheme_HeaderFile
+#define _AIS_SelectionScheme_HeaderFile
+
+
+//! Sets selection schemes for interactive contexts.
+//! It is possible to use combination of schemes.
+enum AIS_SelectionScheme
+{
+  AIS_SelectionScheme_Empty         = 0x0000, // do nothing
+  AIS_SelectionScheme_Clear         = 0x0001, // clears current selection
+  AIS_SelectionScheme_Add           = 0x0002, // add detected object to current selection
+  AIS_SelectionScheme_Switch        = 0x0004, // switch selection state in values selected/deselected
+  AIS_SelectionScheme_PickedIfEmpty = 0x0008, // if after switch, result selection is empty, select picked objects
+  AIS_SelectionScheme_ClearAndSwitch = AIS_SelectionScheme_Clear | AIS_SelectionScheme_Switch,
+  AIS_SelectionScheme_ClearAndAdd = AIS_SelectionScheme_Clear | AIS_SelectionScheme_Add,
+  AIS_SelectionScheme_ClearAndSwitchAndPicked = AIS_SelectionScheme_ClearAndSwitch | AIS_SelectionScheme_PickedIfEmpty,
+  AIS_SelectionScheme_Custom // reserved item for custom selection scheme
+};
+
+#endif // _AIS_SelectionScheme_HeaderFile
index e5bebe3142a8653c69f8b55747d4456e3e08e982..1f9b18b48f1553902a9696f087deec197e037678 100644 (file)
@@ -88,6 +88,7 @@ AIS_Selection.cxx
 AIS_Selection.hxx
 AIS_SelectStatus.hxx
 AIS_SelectionModesConcurrency.hxx
+AIS_SelectionScheme.hxx
 AIS_SequenceOfInteractive.hxx
 AIS_Shape.cxx
 AIS_Shape.hxx