0028390: Visualization, AIS_InteractiveContext - add topmost-only picking strategy
authorkgv <kgv@opencascade.com>
Tue, 11 Apr 2017 07:25:21 +0000 (10:25 +0300)
committerbugmaster <bugmaster@opencascade.com>
Fri, 14 Apr 2017 10:04:03 +0000 (13:04 +0300)
AIS_InteractiveContext::PickingStrategy(), added new property
defining picking strategy SelectMgr_PickingStrategy.
Strategy SelectMgr_PickingStrategy_OnlyTopmost allows picking only
topmost detected entity not rejected by Selection Filters.

src/AIS/AIS_InteractiveContext.cxx
src/AIS/AIS_InteractiveContext.hxx
src/AIS/AIS_InteractiveContext_1.cxx
src/SelectMgr/FILES
src/SelectMgr/SelectMgr_PickingStrategy.hxx [new file with mode: 0644]
src/ViewerTest/ViewerTest_ViewerCommands.cxx
tests/v3d/face/F3 [new file with mode: 0644]

index ac91d36..c60b74f 100644 (file)
@@ -119,6 +119,7 @@ myDefaultDrawer(new Prs3d_Drawer()),
 myCurLocalIndex(0),
 myCurDetected(0),
 myCurHighlighted(0),
+myPickingStrategy (SelectMgr_PickingStrategy_FirstAcceptable),
 myIsAutoActivateSelMode(Standard_True)
 {
   myStyles[Prs3d_TypeOfHighlight_None]          = myDefaultDrawer;
index ca775d8..7a55ce7 100644 (file)
 #ifndef _AIS_InteractiveContext_HeaderFile
 #define _AIS_InteractiveContext_HeaderFile
 
-#include <Standard.hxx>
-#include <Standard_Type.hxx>
-
-#include <AIS_DataMapOfIOStatus.hxx>
-#include <PrsMgr_PresentationManager3d.hxx>
-#include <StdSelect_ViewerSelector3d.hxx>
-#include <TCollection_AsciiString.hxx>
-#include <Standard_Boolean.hxx>
-#include <Prs3d_Drawer.hxx>
-#include <Quantity_NameOfColor.hxx>
-#include <Standard_Integer.hxx>
 #include <AIS_DataMapOfILC.hxx>
+#include <AIS_DataMapOfIOStatus.hxx>
+#include <AIS_DisplayMode.hxx>
 #include <AIS_DisplayStatus.hxx>
+#include <AIS_ClearMode.hxx>
 #include <AIS_KindOfInteractive.hxx>
-#include <Standard_Real.hxx>
-#include <Aspect_TypeOfFacingModel.hxx>
-#include <Graphic3d_NameOfMaterial.hxx>
-#include <Standard_ShortReal.hxx>
-#include <TColStd_ListOfInteger.hxx>
-#include <AIS_DisplayMode.hxx>
-#include <AIS_TypeOfIso.hxx>
+#include <AIS_ListOfInteractive.hxx>
+#include <AIS_Selection.hxx>
 #include <AIS_StatusOfDetection.hxx>
 #include <AIS_StatusOfPick.hxx>
-#include <TColgp_Array1OfPnt2d.hxx>
+#include <AIS_TypeOfIso.hxx>
+#include <Aspect_TypeOfFacingModel.hxx>
+#include <Graphic3d_NameOfMaterial.hxx>
+#include <Prs3d_Drawer.hxx>
+#include <Prs3d_TypeOfHighlight.hxx>
+#include <PrsMgr_PresentationManager3d.hxx>
 #include <SelectMgr_IndexedMapOfOwner.hxx>
-#include <AIS_ClearMode.hxx>
-#include <TopAbs_ShapeEnum.hxx>
 #include <SelectMgr_ListOfFilter.hxx>
-#include <AIS_ListOfInteractive.hxx>
-#include <Standard_CString.hxx>
-#include <AIS_Selection.hxx>
-#include <Prs3d_TypeOfHighlight.hxx>
+#include <SelectMgr_PickingStrategy.hxx>
+#include <Standard.hxx>
+#include <Standard_Type.hxx>
+#include <StdSelect_ViewerSelector3d.hxx>
+#include <TCollection_AsciiString.hxx>
+#include <TColgp_Array1OfPnt2d.hxx>
+#include <TColStd_ListOfInteger.hxx>
+#include <TopAbs_ShapeEnum.hxx>
+#include <Quantity_Color.hxx>
+
 class SelectMgr_SelectionManager;
 class V3d_Viewer;
 class AIS_InteractiveObject;
@@ -56,12 +52,10 @@ class SelectMgr_OrFilter;
 class V3d_View;
 class AIS_LocalContext;
 class TopLoc_Location;
-class Quantity_Color;
 class TCollection_ExtendedString;
 class Prs3d_LineAspect;
 class Prs3d_BasicAspect;
 class SelectMgr_EntityOwner;
-class Standard_Transient;
 class SelectMgr_Filter;
 class TCollection_AsciiString;
 
@@ -144,6 +138,26 @@ public:
   
   Standard_EXPORT Standard_Boolean GetAutoActivateSelection() const;
   
+  //! Setup picking strategy - which entities detected by picking line will be accepted, considering Selection Filters.
+  //! By default (SelectMgr_PickingStrategy_FirstAcceptable), Selection Filters reduce the list of entities
+  //! so that the context accepts topmost in remaining.
+  //!
+  //! This means that entities behind non-selectable (by filters) parts can be picked by user.
+  //! If this behavior is undesirable, and user wants that non-selectable (by filters) parts
+  //! should remain an obstacle for picking, SelectMgr_PickingStrategy_OnlyTopmost can be set instead.
+  //!
+  //! Notice, that since Selection Manager operates only objects registered in it,
+  //! SelectMgr_PickingStrategy_OnlyTopmost will NOT prevent picking entities behind
+  //! visible by unregistered in Selection Manager presentations (e.g. deactivated).
+  //! Hence, SelectMgr_PickingStrategy_OnlyTopmost changes behavior only with Selection Filters enabled.
+  void SetPickingStrategy (const SelectMgr_PickingStrategy theStrategy)
+  {
+    myPickingStrategy = theStrategy;
+  }
+
+  //! Return picking strategy; SelectMgr_PickingStrategy_FirstAcceptable by default.
+  SelectMgr_PickingStrategy PickingStrategy() const { return myPickingStrategy; }
+
   //! Controls the choice between the using the display
   //! and selection modes of open local context which you
   //! have defined and activating those available by default.
@@ -1864,6 +1878,7 @@ protected:
   TColStd_SequenceOfInteger myDetectedSeq;
   Standard_Integer myCurDetected;
   Standard_Integer myCurHighlighted;
+  SelectMgr_PickingStrategy myPickingStrategy; //!< picking strategy to be applied within MoveTo()
   Standard_Boolean myIsAutoActivateSelMode;
 
 };
index 0c181b4..eced2f0 100644 (file)
@@ -331,16 +331,22 @@ AIS_StatusOfDetection AIS_InteractiveContext::MoveTo (const Standard_Integer  th
   // (the objects must be AIS_Shapes)
   const Standard_Integer aDetectedNb = myMainSel->NbPicked();
   Standard_Integer aNewDetected = 0;
+  Standard_Boolean toIgnoreDetTop = Standard_False;
   for (Standard_Integer aDetIter = 1; aDetIter <= aDetectedNb; ++aDetIter)
   {
     Handle(SelectMgr_EntityOwner) anOwner = myMainSel->Picked (aDetIter);
     if (anOwner.IsNull()
      || !myFilters->IsOk (anOwner))
     {
+      if (myPickingStrategy == SelectMgr_PickingStrategy_OnlyTopmost)
+      {
+        toIgnoreDetTop = Standard_True;
+      }
       continue;
     }
 
-    if (aNewDetected < 1)
+    if (aNewDetected < 1
+    && !toIgnoreDetTop)
     {
       aNewDetected = aDetIter;
     }
index b01ff67..943b815 100755 (executable)
@@ -21,6 +21,7 @@ SelectMgr_ListIteratorOfListOfFilter.hxx
 SelectMgr_ListOfFilter.hxx
 SelectMgr_OrFilter.cxx
 SelectMgr_OrFilter.hxx
+SelectMgr_PickingStrategy.hxx
 SelectMgr_RectangularFrustum.cxx
 SelectMgr_RectangularFrustum.hxx
 SelectMgr_SelectableObject.cxx
diff --git a/src/SelectMgr/SelectMgr_PickingStrategy.hxx b/src/SelectMgr/SelectMgr_PickingStrategy.hxx
new file mode 100644 (file)
index 0000000..303ce6e
--- /dev/null
@@ -0,0 +1,24 @@
+// Copyright (c) 2017 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 _SelectMgr_PickingStrategy_HeaderFile
+#define _SelectMgr_PickingStrategy_HeaderFile
+
+//! Enumeration defines picking strategy - which entities detected by picking line will be accepted, considering selection filters.
+enum SelectMgr_PickingStrategy
+{
+  SelectMgr_PickingStrategy_FirstAcceptable, //!< the first detected entity passing selection filter is accepted (e.g. any)
+  SelectMgr_PickingStrategy_OnlyTopmost      //!< only topmost detected entity passing selection filter is accepted
+};
+
+#endif // _SelectMgr_PickingStrategy_HeaderFile
index 4674f35..797d630 100644 (file)
@@ -10175,6 +10175,37 @@ static int VSelectionProperties (Draw_Interpretor& theDi,
       }
       aCtx->SetAutoActivateSelection (toEnable);
     }
+    else if (anArg == "-pickstrategy"
+          || anArg == "-pickingstrategy")
+    {
+      if (++anArgIter >= theArgsNb)
+      {
+        std::cout << "Syntax error: type of highlighting is undefined\n";
+        return 1;
+      }
+
+      SelectMgr_PickingStrategy aStrategy = SelectMgr_PickingStrategy_FirstAcceptable;
+      TCollection_AsciiString aVal (theArgVec[anArgIter]);
+      aVal.LowerCase();
+      if (aVal == "first"
+       || aVal == "firstaccepted"
+       || aVal == "firstacceptable")
+      {
+        aStrategy = SelectMgr_PickingStrategy_FirstAcceptable;
+      }
+      else if (aVal == "topmost"
+            || aVal == "onlyTopmost")
+      {
+        aStrategy = SelectMgr_PickingStrategy_OnlyTopmost;
+      }
+      else
+      {
+        std::cout << "Syntax error: unknwon picking strategy '" << aVal << "'\n";
+        return 1;
+      }
+
+      aCtx->SetPickingStrategy (aStrategy);
+    }
     else if (anArg == "-pixtol"
           && anArgIter + 1 < theArgsNb)
     {
@@ -11103,6 +11134,9 @@ void ViewerTest::ViewerCommands(Draw_Interpretor& theCommands)
     "\n    vselprops [dynHighlight|localDynHighlight|selHighlight|localSelHighlight] [options]"
     "\n    Customizes selection and dynamic highlight parameters for the whole interactive context:"
     "\n    -autoActivate {0|1}     : disables|enables default computation and activation of global selection mode"
+    "\n    -pickStrategy {first|topmost} : defines picking strategy"
+    "\n                            'first'   to pick first acceptable (default)"
+    "\n                            'topmost' to pick only topmost (and nothing, if topmost is rejected by filters)"
     "\n    -pixTol    value        : sets up pixel tolerance"
     "\n    -dispMode  dispMode     : sets display mode for highlighting"
     "\n    -layer     ZLayer       : sets ZLayer for highlighting"
diff --git a/tests/v3d/face/F3 b/tests/v3d/face/F3
new file mode 100644 (file)
index 0000000..da57961
--- /dev/null
@@ -0,0 +1,26 @@
+box b1 0 0 0 1 1 1
+box b2 2 0 0 1 1 1
+vclear
+vinit View1
+vviewparams -scale 404 -proj 0.8 -0.16 0.5 -up -0.4 0.4 0.8 -at 1.5 0.5 0.5
+vsetfilter -clear
+vselprops -pickStrategy first
+vdisplay -dispMode 1 -highMode 1 b1 b2
+vfit
+
+vselmode b1 4 1
+vmoveto 220 220
+if { [vreadpixel 220 220 rgb name] != "TURQUOISE3" } { puts "Error: box b2 should be highlighted" }
+
+vsetfilter -type=FACE
+vmoveto 0 0
+vmoveto 220 220
+if { [vreadpixel 150 150 rgb name] != "CYAN1" } { puts "Error: face of box b1 should be highlighted" }
+
+vselprops -pickStrategy topmost
+vmoveto 0 0
+vmoveto 220 220
+if { [vreadpixel 150 150 rgb name] == "CYAN1" } { puts "Error: face of box b1 should NOT be highlighted" }
+
+vmoveto 150 150
+if { [vreadpixel 150 150 rgb name] != "CYAN1" } { puts "Error: face of box b1 should be highlighted" }