]> OCCT Git - occt.git/commitdiff
0030484: Visualization, SelectMgr_ViewerSelector - Graphic3d_TMF_2d persistence sorti...
authordrochalo <diogo.lopes@opencascade.com>
Wed, 17 Jan 2024 10:36:42 +0000 (10:36 +0000)
committerdpasukhi <dpasukhi@opencascade.com>
Sun, 19 May 2024 15:03:08 +0000 (16:03 +0100)
Added property to SelectableObject for selection focused on display priority.
Modified SelectMgr_ViewerSelector CompareResults based on the focus priority property.
Added display priority to the sorting criterion
Added tests for multiple types of sensitive entities.
Modified vpriority command to change an object's selection priority.

src/SelectMgr/SelectMgr_SortCriterion.hxx
src/SelectMgr/SelectMgr_ViewerSelector.cxx
src/ViewerTest/ViewerTest_ViewerCommands.cxx
tests/vselect/bugs/bug30484_1 [new file with mode: 0644]
tests/vselect/bugs/bug30484_2 [new file with mode: 0644]
tests/vselect/bugs/bug30484_3 [new file with mode: 0644]
tests/vselect/bugs/bug30484_4 [new file with mode: 0644]

index 183965efc50ee2a697e8fb90c77cacf2b96e9933..689f6a7bf6dc0dda55c43bb518d483637e2450fd 100644 (file)
@@ -28,14 +28,16 @@ class SelectMgr_SortCriterion
 public:
 
   Handle(Select3D_SensitiveEntity) Entity; //!< detected entity
-  gp_Pnt             Point;           //!< 3D point
-  Graphic3d_Vec3     Normal;          //!< surface normal or 0 vector if undefined
-  Standard_Real      Depth;           //!< distance from the view plane to the entity
-  Standard_Real      MinDist;         //!< distance from the clicked point to the entity on the view plane
-  Standard_Real      Tolerance;       //!< tolerance used for selecting candidates
-  Standard_Integer   Priority;        //!< selection priority
-  Standard_Integer   ZLayerPosition;  //!< ZLayer rendering order index, stronger than a depth
-  Standard_Integer   NbOwnerMatches;  //!< overall number of entities collected for the same owner
+  gp_Pnt             Point;             //!< 3D point
+  Graphic3d_Vec3     Normal;            //!< surface normal or 0 vector if undefined
+  Standard_Real      Depth;             //!< distance from the view plane to the entity
+  Standard_Real      MinDist;           //!< distance from the clicked point to the entity on the view plane
+  Standard_Real      Tolerance;         //!< tolerance used for selecting candidates
+  Standard_Integer   SelectionPriority; //!< selection priority
+  Standard_Integer   DisplayPriority;   //!< display priority
+  Standard_Integer   ZLayerPosition;    //!< ZLayer rendering order index, stronger than a depth
+  Standard_Integer   NbOwnerMatches;    //!< overall number of entities collected for the same owner
+  Standard_Boolean   IsPreferPriority;  //!< flag to signal comparison to be done over priority
 
 public:
   DEFINE_STANDARD_ALLOC
@@ -45,9 +47,11 @@ public:
   : Depth    (0.0),
     MinDist  (0.0),
     Tolerance(0.0),
-    Priority (0),
+    SelectionPriority (0),
+    DisplayPriority(0),
     ZLayerPosition (0),
-    NbOwnerMatches (0) {}
+    NbOwnerMatches (0),
+    IsPreferPriority (Standard_False) {}
 
   //! Compare with another item by depth, priority and minDist.
   bool IsCloserDepth (const SelectMgr_SortCriterion& theOther) const
@@ -86,13 +90,18 @@ public:
     }
 
     // if two objects have similar depth, select the one with higher priority
-    if (Priority > theOther.Priority)
+    if (SelectionPriority > theOther.SelectionPriority)
+    {
+      return true;
+    }
+
+    if (DisplayPriority > theOther.DisplayPriority)
     {
       return true;
     }
 
     // if priorities are equal, one closest to the mouse
-    return Priority == theOther.Priority
+    return SelectionPriority == theOther.SelectionPriority
         && MinDist  <  theOther.MinDist;
   }
 
@@ -105,13 +114,14 @@ public:
       return ZLayerPosition > theOther.ZLayerPosition;
     }
 
-    if (Priority > theOther.Priority)
+    if (SelectionPriority != theOther.SelectionPriority)
     {
-      return true;
+      return SelectionPriority > theOther.SelectionPriority;
     }
-    else if (Priority != theOther.Priority)
+
+    if (DisplayPriority != theOther.DisplayPriority)
     {
-      return false;
+      return DisplayPriority > theOther.DisplayPriority;
     }
 
     //if (Abs (Depth - theOther.Depth) <= (Tolerance + theOther.Tolerance))
index 6c23ee7ee973a27e32ae8fded0d440a1c851b168..28609bb7d96dcdb9fdb43861995f04a80e58ac9a 100644 (file)
@@ -16,6 +16,7 @@
 
 #include <SelectMgr_ViewerSelector.hxx>
 
+#include <AIS_InteractiveObject.hxx>
 #include <BVH_Tree.hxx>
 #include <gp_GTrsf.hxx>
 #include <gp_Pnt.hxx>
@@ -54,13 +55,13 @@ namespace
     {
       const SelectMgr_SortCriterion& anElemLeft  = myMapOfCriterion->FindFromIndex (theLeft);
       const SelectMgr_SortCriterion& anElemRight = myMapOfCriterion->FindFromIndex (theRight);
-      if (myToPreferClosest)
+      if ((anElemLeft.IsPreferPriority && anElemRight.IsPreferPriority) || !myToPreferClosest)
       {
-        return anElemLeft.IsCloserDepth (anElemRight);
+        return anElemLeft.IsHigherPriority (anElemRight);
       }
       else
       {
-        return anElemLeft.IsHigherPriority (anElemRight);
+        return anElemLeft.IsCloserDepth (anElemRight);
       }
     }
 
@@ -270,13 +271,32 @@ void SelectMgr_ViewerSelector::checkOverlap (const Handle(Select3D_SensitiveEnti
   {
     return;
   }
-
   SelectMgr_SortCriterion aCriterion;
   myZLayerOrderMap.Find (!aSelectable.IsNull() ? aSelectable->ZLayer() : Graphic3d_ZLayerId_Default, aCriterion.ZLayerPosition);
-  aCriterion.Entity    = theEntity;
-  aCriterion.Priority  = anOwner->Priority();
-  aCriterion.Depth     = aPickResult.Depth();
-  aCriterion.MinDist   = aPickResult.DistToGeomCenter();
+  aCriterion.Entity            = theEntity;
+  aCriterion.SelectionPriority = anOwner->Priority();
+  aCriterion.Depth             = aPickResult.Depth();
+  aCriterion.MinDist           = aPickResult.DistToGeomCenter();
+  Handle(AIS_InteractiveObject) anObj = Handle(AIS_InteractiveObject)::DownCast (aSelectable);
+  if (!aSelectable.IsNull())
+  {
+    if (aSelectable->Presentations().Size() > 0 && !aSelectable->TransformPersistence().IsNull())
+    {
+      if (aSelectable->TransformPersistence()->Mode() == Graphic3d_TMF_2d)
+      {
+        aCriterion.IsPreferPriority = Standard_True;
+        aCriterion.DisplayPriority = Graphic3d_DisplayPriority_INVALID;
+        if (!anObj.IsNull())
+        {
+          Handle(Prs3d_Presentation) aPrs = anObj->Presentation();
+          if (!aPrs.IsNull())
+          {
+            aCriterion.DisplayPriority = aPrs->DisplayPriority();
+          }
+        }
+      }
+    }
+  }
 
   if (SelectMgr_SortCriterion* aPrevCriterion = mystored.ChangeSeek (anOwner))
   {
index d700adce803dae7ba38b9e8d77a0db929e36e944..630ac437f4c09d3c56c5cd05c0b14e3d8ace9d15 100644 (file)
@@ -6390,6 +6390,79 @@ static Standard_Integer VSelect (Draw_Interpretor& ,
   return 0;
 }
 
+//=======================================================================
+//function : VSelectPriority
+//purpose  : Prints or sets the selection priority for an object
+//=======================================================================
+static Standard_Integer VSelectPriority (Draw_Interpretor& theDI,
+                                         Standard_Integer theNbArgs,
+                                         const char** theArgVec)
+{
+  Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
+  ViewerTest_AutoUpdater anUpdateTool (aContext, ViewerTest::CurrentView());
+  if (aContext.IsNull())
+  {
+    Message::SendFail("Error: no active viewer");
+    return 1;
+  }
+
+  TCollection_AsciiString aLastArg(theArgVec[theNbArgs - 1]);
+  Standard_Integer aPriority = -1;
+  Standard_Integer aNbArgs = theNbArgs;
+  if (aNbArgs < 2 || aNbArgs > 3)
+  {
+    Message::SendFail("Syntax error: wrong number of arguments! See usage:");
+    theDI.PrintHelp (theArgVec[0]);
+    return 1;
+  }
+
+  if (aLastArg.IsIntegerValue())
+  {
+    TCollection_AsciiString aFocusArg(theArgVec[1]);
+    aPriority = aLastArg.IntegerValue();
+    --aNbArgs;
+    if (aPriority < 0)
+    {
+      Message::SendFail() << "Syntax error: the specified selection priority value '" << aLastArg << "' is invalid ]";
+      return 1;
+    }
+  }
+  else
+  {
+    anUpdateTool.Invalidate();
+  }
+
+  for (Standard_Integer anArgIter = 1; anArgIter < aNbArgs; ++anArgIter)
+  {
+    TCollection_AsciiString aName(theArgVec[anArgIter]);
+    Handle(AIS_InteractiveObject) anIObj;
+    GetMapOfAIS().Find2 (aName, anIObj);
+    if (anIObj.IsNull())
+    {
+      Message::SendFail() << "Error: the object '" << theArgVec[1] << "' is not displayed";
+      return 1;
+    }
+
+    Handle(SelectMgr_EntityOwner) anOwner = anIObj->GlobalSelOwner();
+    if (!anOwner.IsNull())
+    {
+      if (aPriority == Graphic3d_DisplayPriority_INVALID)
+      {
+        theDI << anOwner->Priority() << " ";
+      }
+      else
+      {
+        anOwner->SetPriority (aPriority);
+      }
+    }
+    else 
+    {
+      Message::SendFail() << "Error: the object '" << theArgVec[1] << "' is does not have a selection priority attached.";
+      return 1;
+    }
+  }
+  return 0;
+}
 //=======================================================================
 //function : VMoveTo
 //purpose  : Emulates cursor movement to defined pixel position
@@ -14431,6 +14504,11 @@ Emulate different types of selection:
  5) Selection scheme replace, replaceextra, xor, add or remove (replace by default).
 )" /* [vselect] */);
 
+addCmd("vselectpriority", VSelectPriority, /* [vselectpriority] */ R"(
+vselectpriority name [value]
+Prints or sets the selection priority for an object.
+)" /* [vselectpriority] */);
+
   addCmd ("vmoveto", VMoveTo, /* [vmoveto] */ R"(
 vmoveto [x y] [-reset]
 Emulate cursor movement to pixel position (x,y).
diff --git a/tests/vselect/bugs/bug30484_1 b/tests/vselect/bugs/bug30484_1
new file mode 100644 (file)
index 0000000..2db672e
--- /dev/null
@@ -0,0 +1,51 @@
+puts "============="
+puts "0030484: Visualization - 2d persistent: order of detection doesn't coincide with order of objects creation"
+puts "============="
+
+pload MODELING VISUALIZATION
+vclear
+vinit
+vselprops dynHighlight -dispMode 1 -color WHITE
+# compare boxes displayed with 2d transform persistence 
+# with the same properties (zlayer, depth and priority)
+box box_1 75 -250 0 200 200 200
+box box_2 175 -300 0 200 200 200
+vdisplay box_1 -2d topLeft -top -dispmode 1
+vsetmaterial box_1  PLASTIC
+vsetcolor    box_1 DEEPPINK2
+vdisplay box_2 -2d topLeft -top -dispmode 1
+vsetmaterial box_2 PLASTIC
+vsetcolor    box_2 PALEGREEN2
+# verify colors
+if { [vreadpixel 205 170 rgb name] != "DARKSEAGREEN4" } { puts "Error: selected pixel should be green." }
+if { [vreadpixel 150 170 rgb name] != "MAROON" } { puts "Error: selected pixel should be maroon." }
+vmoveto 205 170
+if { [vreadpixel 205 170 rgb name] != "WHITE" } { puts "Error: box_1 should be highlighted" }
+# dump image
+vdump $imagedir/${casename}_boxes_undefined.png
+
+# modify display priority and test selection based on display priority
+# Set box_1 with higher priority
+vmoveto 0 0
+vpriority -update box_1 5
+vpriority -update box_2 4
+# test if box_1 is selected by moving mouse close to 
+# edge close to box_2
+vmoveto 270 170
+if { [vreadpixel 100 170 rgb name] != "WHITE" } { puts "Error: box_1 should be highlighted" }
+vdump $imagedir/${casename}_highlight_box1.png
+vmoveto 280 170
+if { [vreadpixel 350 170 rgb name] != "WHITE" } { puts "Error: box_2 should be highlighted" }
+vdump $imagedir/${casename}_highlight_box2.png
+
+# modify selection priority and test selection based on selection priority
+# Set box_2 with higher priority
+vmoveto 0 0
+vselectpriority box_1 4
+vselectpriority box_2 5
+vmoveto 180 170
+if { [vreadpixel 350 170 rgb name] != "WHITE" } { puts "Error: box_2 should be highlighted" }
+vdump $imagedir/${casename}_highlight_box1.png
+vmoveto 170 170
+if { [vreadpixel 100 170 rgb name] != "WHITE" } { puts "Error: box_1 should be highlighted" }
+vdump $imagedir/${casename}_highlight_box2.png
diff --git a/tests/vselect/bugs/bug30484_2 b/tests/vselect/bugs/bug30484_2
new file mode 100644 (file)
index 0000000..96db37d
--- /dev/null
@@ -0,0 +1,121 @@
+puts "============="
+puts "0030484: Visualization - 2d persistent: order of detection doesn't coincide with order of objects creation"
+puts "============="
+
+pload MODELING VISUALIZATION
+vclear
+vinit
+vselprops dynHighlight -dispMode 1 -color WHITE
+# Compare behaviour in a scene with a quad (2 triangles)
+# 4 segments on the edges and a circle on the center
+vpoint pt1 75 -250 0
+vpoint pt2 275 -250 0
+vpoint pt3 275 -50 0
+vpoint pt4 75 -50 0
+vtriangle tri1 pt1 pt2 pt3
+vtriangle tri2 pt3 pt4 pt1
+vdisplay tri1 -2d topLeft -top -dispmode 1
+vdisplay tri2 -2d topLeft -top -dispmode 1
+vsetmaterial tri1 PLASTIC
+vsetcolor tri1 ORANGE
+vsetmaterial tri2 PLASTIC
+vsetcolor tri2 ORANGE
+vremove pt1 pt2 pt3 pt4
+vaspects -update tri1 -faceBoundaryDraw 1
+vaspects -update tri2 -faceBoundaryDraw 1
+
+vdrawparray seg1 segments v 76 -249 0 c 1 0 0 v 274 -249 0 c 1 0 0 
+vdrawparray seg2 segments v 274 -249 0 c 1 0 0 v 274 -51 0 c 1 0 0
+vdrawparray seg3 segments v 274 -51 0 c 1 0 0 v 76 -51 0 c 1 0 0
+vdrawparray seg4 segments v 76 -51 0 c 1 0 0 v 76 -249 0 c 1 0 0
+vdisplay seg1 -2d topLeft -top -dispmode 1
+vdisplay seg2 -2d topLeft -top -dispmode 1
+vdisplay seg3 -2d topLeft -top -dispmode 1
+vdisplay seg4 -2d topLeft -top -dispmode 1
+vsetmaterial seg1 PLASTIC
+vsetmaterial seg2 PLASTIC
+vsetmaterial seg3 PLASTIC
+vsetmaterial seg4 PLASTIC
+vsetcolor seg1 RED
+vsetcolor seg2 RED
+vsetcolor seg3 RED
+vsetcolor seg4 RED
+
+vpoint pr1 170 -145 0
+vpoint pr2 180 -145 0
+vpoint pr3 180 -155 0
+vcircle circle1 pr1 pr2 pr3 1
+vdisplay circle1 -2d topLeft -top
+vsetmaterial circle1 PLASTIC
+vsetcolor circle1 BROWN3
+vremove pr1 pr2 pr3
+vaspects -update circle1 -faceBoundaryDraw 1
+
+# dump image
+vdump $imagedir/${casename}_quad_segments_circle.png
+# test selection with undefined behaviour
+vmoveto 75 150
+if { [vreadpixel 75 100 rgb name] != "WHITE" } { puts "Error: segment should be highlighted" }
+vdump $imagedir/${casename}_undefined_segmenthighlight.png
+vmoveto 100 150
+if { [vreadpixel 100 100 rgb name] != "WHITE" } { puts "Error: tri2 should be highlighted" }
+vdump $imagedir/${casename}_undefined_tri2highlight.png
+vmoveto 200 150
+if { [vreadpixel 200 200 rgb name] != "WHITE" } { puts "Error: tri1 should be highlighted" }
+vdump $imagedir/${casename}_undefined_tri1highlight.png
+vmoveto 175 150
+vdump $imagedir/${casename}_undefined_circle.png
+
+# change selection priority for each element and 
+# test selection priority focused selection
+vselectpriority tri1 6
+vselectpriority tri2 6
+vselectpriority seg1 4
+vselectpriority seg2 4
+vselectpriority seg3 4
+vselectpriority seg4 4
+vselectpriority circle1 4
+vmoveto 175 150
+if { [vreadpixel 200 200 rgb name] != "WHITE" } { puts "Error: tri1 should be highlighted" }
+# show image with display priority focused
+vdump $imagedir/${casename}_quad_focused1.png
+vmoveto 170 140
+if { [vreadpixel 100 100 rgb name] != "WHITE" } { puts "Error: tri2 should be highlighted" }
+# show image with display priority focused
+vdump $imagedir/${casename}_quad_focused2.png
+
+# test priority selection for circle
+vmoveto 0 0
+vselectpriority tri1 4
+vselectpriority tri2 4
+vselectpriority seg1 4
+vselectpriority seg2 4
+vselectpriority seg3 4
+vselectpriority seg4 4
+vselectpriority circle1 6
+# show image with priority focused
+vdump $imagedir/${casename}_circle_focused.png
+vmoveto 175 150
+vselect
+# show image with priority focused
+vdump $imagedir/${casename}_circle_selected.png
+
+# test priority selection for segments
+vmoveto 0 0
+vselect
+vselectpriority tri1 4
+vselectpriority tri2 4
+vselectpriority seg1 6
+vselectpriority seg2 6
+vselectpriority seg3 6
+vselectpriority seg4 6
+vselectpriority circle1 4
+
+vmoveto 175 250
+vdump $imagedir/${casename}_segment1_focused.png
+vmoveto 276 150
+vdump $imagedir/${casename}_segment2_focused.png
+vmoveto 175 49
+vdump $imagedir/${casename}_segment3_focused.png
+vmoveto 75 150
+vdump $imagedir/${casename}_segment4_focused.png
diff --git a/tests/vselect/bugs/bug30484_3 b/tests/vselect/bugs/bug30484_3
new file mode 100644 (file)
index 0000000..081dc94
--- /dev/null
@@ -0,0 +1,54 @@
+puts "============="
+puts "0030484: Visualization - 2d persistent: order of detection doesn't coincide with order of objects creation"
+puts "============="
+
+pload MODELING VISUALIZATION
+vclear
+vinit
+vselprops dynHighlight -dispMode 1 -color WHITE
+# Compare behaviour in a scene with a quad (2 triangles)
+# and a point in the center
+vpoint pt1 75 -250 0
+vpoint pt2 275 -250 0
+vpoint pt3 275 -50 0
+vpoint pt4 75 -50 0
+vtriangle tri1 pt1 pt2 pt3
+vtriangle tri2 pt3 pt4 pt1
+vdisplay tri1 -2d topLeft -top -dispmode 1
+vdisplay tri2 -2d topLeft -top -dispmode 1
+vsetmaterial tri1 PLASTIC
+vsetcolor tri1 ORANGE
+vsetmaterial tri2 PLASTIC
+vsetcolor tri2 ORANGE
+vremove pt1 pt2 pt3 pt4
+vaspects -update tri1 -faceBoundaryDraw 1
+vaspects -update tri2 -faceBoundaryDraw 1
+
+vpoint p1 175 150 -2d
+vdisplay p1 -2d topLeft -top -dispmode 1
+
+# dump image
+vdump $imagedir/${casename}_quad_point_undefined.png
+vmoveto 175 150
+if { [vreadpixel 175 150 rgb name] != "CYAN" } { puts "Error: point should be highlighted" }
+vdump $imagedir/${casename}_quad_point_onpoint.png
+vmoveto 150 100
+vdump $imagedir/${casename}_quad_point_ontri2.png
+vmoveto 200 200
+vdump $imagedir/${casename}_quad_point_ontri1.png
+
+# test selection priority
+vmoveto 0 0
+vpriority -update tri1 4
+vpriority -update tri2 4
+vpriority -update p1 4
+vselectpriority tri1 6
+vselectpriority tri2 6
+vselectpriority p1 5
+vmoveto 175 150
+if { [vreadpixel 175 150 rgb name] == "CYAN" } { puts "Error: point should not be highlighted" }
+vdump $imagedir/${casename}_quad_point_changedpriorityfocus.png
+vmoveto 0 0
+vselectpriority p1 4
+vmoveto 175 150
+vdump $imagedir/${casename}_quad_point_reducedpointpriority.png
diff --git a/tests/vselect/bugs/bug30484_4 b/tests/vselect/bugs/bug30484_4
new file mode 100644 (file)
index 0000000..935d217
--- /dev/null
@@ -0,0 +1,37 @@
+puts "============="
+puts "0030484: Visualization - 2d persistent: order of detection doesn't coincide with order of objects creation"
+puts "============="
+
+pload MODELING VISUALIZATION
+vclear
+vinit
+vselprops dynHighlight -dispMode 1 -color WHITE
+# Compare behaviour in a scene with two quads
+# 1 from a box and another from primitive array
+# quad primitive array only highlights in the corners
+box box_1 75 -250 0 200 200 200
+vdisplay box_1 -2d topLeft -top -dispmode 1
+vsetmaterial box_1  PLASTIC
+vsetcolor    box_1 DEEPPINK2
+
+vdrawparray quad1 quads v 175 -300 0 c 0 0 1 v 375 -300 0 c 0 0 1 v 375 -100 0 c 0 0 1 v 175 -100 0 c 0 0 1
+vdisplay quad1 -2d topLeft -top -dispmode 1
+vsetmaterial quad1 PLASTIC
+vsetcolor    quad1 PALEGREEN2
+
+# dump image
+vdump $imagedir/${casename}_box_quad_undefined.png
+vmoveto 100 100
+vdump $imagedir/${casename}_box_quad_boxhighlight.png
+vmoveto 376 100
+vdump $imagedir/${casename}_box_quad_quadhighlight.png
+
+#test selection priority
+vmoveto 0 0
+vpriority -update box_1 6
+vpriority -update quad1 5
+vselectpriority box_1 5
+vselectpriority quad1 6
+vmoveto 175 99
+if { [vreadpixel 300 200 rgb name] != "WHITE" } { puts "Error: quad primitive should be highlighted" }
+vdump $imagedir/${casename}_box_quad_selectionpriority_focused.png