]> OCCT Git - occt-copy.git/commitdiff
0030737: Visualization - implementing new selection schemes in context
authornds <nds@opencascade.com>
Thu, 23 May 2019 16:58:59 +0000 (19:58 +0300)
committernds <nds@opencascade.com>
Tue, 11 Jun 2019 10:46:58 +0000 (13:46 +0300)
(cherry picked from commit f9d4ea66dbba0c6fb70d0232d9fd326722e83fbc)
(cherry picked from commit 1c7d53e55ac3c0c75ee828e2817b96434104d291)
(cherry picked from commit e2b319869af281f741ad97595c23de6d3128bce2)

# Conflicts:
# src/AIS/AIS_InteractiveContext_1.cxx

src/AIS/AIS_InteractiveContext.cxx
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/AIS_SelectionType.hxx [new file with mode: 0644]
src/AIS/FILES

index 2167506cbc0c7c9c424623fc655c7af3e7d10a42..7cc82a3524759328a13f6641bbd650559828bb02 100644 (file)
@@ -161,6 +161,12 @@ myIsAutoActivateSelMode(Standard_True)
     aStyle->SetMethod(Aspect_TOHM_COLOR);
     aStyle->SetColor (Quantity_NOC_GRAY40);
   }
+  SetSelectionScheme (AIS_SelectionType_Select,       AIS_SelectionScheme_ClearAndAdd);
+  SetSelectionScheme (AIS_SelectionType_SelectInRect, AIS_SelectionScheme_ClearAndAdd);
+  SetSelectionScheme (AIS_SelectionType_SelectInPoly, AIS_SelectionScheme_ClearAndAdd); 
+  SetSelectionScheme (AIS_SelectionType_ShiftSelect,       AIS_SelectionScheme_Switch);
+  SetSelectionScheme (AIS_SelectionType_ShiftSelectInRect, AIS_SelectionScheme_Switch);
+  SetSelectionScheme (AIS_SelectionType_ShiftSelectInPoly, AIS_SelectionScheme_Switch);
 
   InitAttributes();
 }
index 06dc107f9b233912ddf254749cba48c8a76b8457..1a5597531c5e4ba78bfc2b65c1ae1cd94e99c5b9 100644 (file)
@@ -25,6 +25,8 @@
 #include <AIS_ListOfInteractive.hxx>
 #include <AIS_Selection.hxx>
 #include <AIS_SelectionModesConcurrency.hxx>
+#include <AIS_SelectionScheme.hxx>
+#include <AIS_SelectionType.hxx>
 #include <AIS_StatusOfDetection.hxx>
 #include <AIS_StatusOfPick.hxx>
 #include <AIS_TypeOfIso.hxx>
@@ -467,6 +469,14 @@ public: //! @name Selection management
     return AddSelect (theObject->GlobalSelOwner());
   }
 
+  //! Returns selection scheme used in Select
+  AIS_SelectionScheme SelectionScheme (const AIS_SelectionType theType) const
+  { return mySelectionSchemes.Find (theType); }
+
+  //! Returns selection scheme used in Select
+  void SetSelectionScheme (const AIS_SelectionType theType, const AIS_SelectionScheme theScheme)
+  { mySelectionSchemes.Bind (theType, theScheme); }
+
   //! 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,
@@ -1390,6 +1400,7 @@ protected: //! @name internal fields
   Standard_Boolean myAutoHilight;
   Standard_Boolean myIsAutoActivateSelMode;
 
+  NCollection_DataMap<AIS_SelectionType, AIS_SelectionScheme> mySelectionSchemes;
 };
 
 DEFINE_STANDARD_HANDLE(AIS_InteractiveContext, Standard_Transient)
index cfac0ebdc6ea7031f27f8807c8a24bb81b638be5..aec3d2a25d85b1bb4d913c6ee588858a1effa67c 100644 (file)
@@ -461,16 +461,20 @@ AIS_StatusOfPick AIS_InteractiveContext::Select (const Standard_Integer  theXPMi
 
   // all objects detected by the selector are taken, previous current objects are emptied,
   // new objects are put...
-  ClearSelected (Standard_False);
+  if (myAutoHilight)
+  {
+    clearDynamicHighlight();
+    UnhilightSelected (Standard_False);
+  }
+
   myMainSel->Pick (theXPMin, theYPMin, theXPMax, theYPMax, theView);
+
+  AIS_NListOfEntityOwner aPickedOwners;
   for (Standard_Integer aPickIter = 1; aPickIter <= myMainSel->NbPicked(); ++aPickIter)
   {
-    const Handle(SelectMgr_EntityOwner)& aCurOwner = myMainSel->Picked (aPickIter);
-    if (aCurOwner.IsNull() || !aCurOwner->HasSelectable() || !myFilters->IsOk (aCurOwner))
-      continue;
-
-    mySelection->Select (aCurOwner);
+    aPickedOwners.Append (myMainSel->Picked (aPickIter));
   }
+  mySelection->SelectOwners (aPickedOwners, SelectionScheme (AIS_SelectionType_SelectInRect), myFilters);
 
   if (myAutoHilight)
   {
@@ -500,16 +504,20 @@ AIS_StatusOfPick AIS_InteractiveContext::Select (const TColgp_Array1OfPnt2d& the
 
   // all objects detected by the selector are taken, previous current objects are emptied,
   // new objects are put...
-  ClearSelected (Standard_False);
+  if (myAutoHilight)
+  {
+    clearDynamicHighlight();
+    UnhilightSelected (Standard_False);
+  }
+
   myMainSel->Pick (thePolyline, theView);
+
+  AIS_NListOfEntityOwner aPickedOwners;
   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);
+    aPickedOwners.Append (myMainSel->Picked (aPickIter));
   }
+  mySelection->SelectOwners (aPickedOwners, SelectionScheme (AIS_SelectionType_SelectInPoly), myFilters);
 
   if (myAutoHilight)
   {
@@ -530,26 +538,34 @@ AIS_StatusOfPick AIS_InteractiveContext::Select (const TColgp_Array1OfPnt2d& the
 //=======================================================================
 AIS_StatusOfPick AIS_InteractiveContext::Select (const Standard_Boolean toUpdateViewer)
 {
-  if (!myLastPicked.IsNull())
+  // special case: single selection of detected owner - is it necessary ?
+  /*if (myWasLastMain && !myLastinMain.IsNull() && !myAutoHilight &&
+      (myLastinMain->IsSelected()
+      && !myLastinMain->IsForcedHilight()
+      && NbSelected() <= 1))
   {
-    if (myAutoHilight)
-    {
-      clearDynamicHighlight();
-    }
-    if (!myLastPicked->IsSelected()
-      || myLastPicked->IsForcedHilight()
-      || NbSelected() > 1)
-    {
-      SetSelected (myLastPicked, Standard_False);
-      if(toUpdateViewer)
-      {
-        UpdateCurrentViewer();
-      }
-    }
+    mySelection->selectOwner(myLastinMain, aPrevSelected, SelectionScheme (AIS_SelectionType_Select));
+    return getStatusOfPick (NbSelected());
+  }*/
+
+  if (myAutoHilight)
+  {
+    clearDynamicHighlight();
+    UnhilightSelected (Standard_False);
   }
-  else
+
+  AIS_NListOfEntityOwner aPickedOwners;
+  aPickedOwners.Append (myLastinMain);
+  mySelection->SelectOwners (aPickedOwners, SelectionScheme (AIS_SelectionType_Select), myFilters);
+
+  if (myAutoHilight)
   {
-    ClearSelected (toUpdateViewer);
+    HilightSelected (toUpdateViewer);
+  }
+
+  if(toUpdateViewer)
+  {
+    UpdateCurrentViewer();
   }
 
   Standard_Integer aSelNum = NbSelected();
@@ -565,15 +581,25 @@ AIS_StatusOfPick AIS_InteractiveContext::Select (const Standard_Boolean toUpdate
 //=======================================================================
 AIS_StatusOfPick AIS_InteractiveContext::ShiftSelect (const Standard_Boolean toUpdateViewer)
 {
+  AIS_NListOfEntityOwner aPrevSelected = mySelection->Objects();
   if (myAutoHilight)
   {
     clearDynamicHighlight();
+    UnhilightSelected (Standard_False);
   }
-  if (!myLastPicked.IsNull())
+
+  AIS_NListOfEntityOwner aPickedOwners;
+  aPickedOwners.Append (myLastinMain);
+  mySelection->SelectOwners (aPickedOwners, SelectionScheme (AIS_SelectionType_ShiftSelect), myFilters);
+
+  if (myAutoHilight)
   {
-    AddOrRemoveSelected (myLastPicked, toUpdateViewer);
+    HilightSelected (toUpdateViewer);
   }
 
+  if (toUpdateViewer)
+    UpdateCurrentViewer();
+
   Standard_Integer aSelNum = NbSelected();
 
   return (aSelNum == 0) ? AIS_SOP_NothingSelected
@@ -597,19 +623,20 @@ AIS_StatusOfPick AIS_InteractiveContext::ShiftSelect (const Standard_Integer the
     throw Standard_ProgramError ("AIS_InteractiveContext::ShiftSelect() - invalid argument");
   }
 
+  AIS_NListOfEntityOwner aPrevSelected = mySelection->Objects();
   if (myAutoHilight)
   {
+    clearDynamicHighlight();
     UnhilightSelected (Standard_False);
   }
   myMainSel->Pick (theXPMin, theYPMin, theXPMax, theYPMax, theView);
+
+  AIS_NListOfEntityOwner aPickedOwners;
   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);
+    aPickedOwners.Append (myMainSel->Picked (aPickIter));
   }
+  mySelection->SelectOwners (aPickedOwners, SelectionScheme (AIS_SelectionType_ShiftSelectInRect), myFilters);
 
   if (myAutoHilight)
   {
@@ -637,19 +664,20 @@ AIS_StatusOfPick AIS_InteractiveContext::ShiftSelect (const TColgp_Array1OfPnt2d
     throw Standard_ProgramError ("AIS_InteractiveContext::ShiftSelect() - invalid argument");
   }
 
+  AIS_NListOfEntityOwner aPrevSelected = mySelection->Objects();
   if (myAutoHilight)
   {
+    clearDynamicHighlight();
     UnhilightSelected (Standard_False);
   }
   myMainSel->Pick (thePolyline, theView);
+
+  AIS_NListOfEntityOwner aPickedOwners;
   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);
+    aPickedOwners.Append (myMainSel->Picked (aPickIter));
   }
+  mySelection->SelectOwners (aPickedOwners, SelectionScheme (AIS_SelectionType_ShiftSelectInPoly), myFilters);
 
   if (myAutoHilight)
   {
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..d34c3f4
--- /dev/null
@@ -0,0 +1,31 @@
+// 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_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
+};
+
+#endif // _AIS_SelectionScheme_HeaderFile
diff --git a/src/AIS/AIS_SelectionType.hxx b/src/AIS/AIS_SelectionType.hxx
new file mode 100644 (file)
index 0000000..22c11aa
--- /dev/null
@@ -0,0 +1,31 @@
+// 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_SelectionType_HeaderFile
+#define _AIS_SelectionType_HeaderFile
+
+
+//! Sets selection schemes for interactive contexts.
+//! It is possible to use combination of schemes.
+enum AIS_SelectionType
+{
+  AIS_SelectionType_Select,
+  AIS_SelectionType_SelectInRect,
+  AIS_SelectionType_SelectInPoly,
+  AIS_SelectionType_ShiftSelect,
+  AIS_SelectionType_ShiftSelectInRect,
+  AIS_SelectionType_ShiftSelectInPoly
+};
+
+#endif // _AIS_SelectionType_HeaderFile
index b8555d373fb4ef39e3bd7feb7d8bd7dfb157004a..5328697ca36c3355e15fd53969a7a3aed894da0e 100644 (file)
@@ -141,6 +141,8 @@ AIS_Selection.cxx
 AIS_Selection.hxx
 AIS_SelectStatus.hxx
 AIS_SelectionModesConcurrency.hxx
+AIS_SelectionScheme.hxx
+AIS_SelectionType.hxx
 AIS_SequenceOfDimension.hxx
 AIS_SequenceOfInteractive.hxx
 AIS_Shape.cxx