0026462: Visualization - selection does not adapt to line width change
authorvpa <vpa@opencascade.com>
Fri, 28 Aug 2015 19:25:45 +0000 (22:25 +0300)
committerbugmaster <bugmaster@opencascade.com>
Thu, 10 Sep 2015 12:10:56 +0000 (15:10 +0300)
- added interface for changing sensitivity of a particular selection through both interactive and local context;
- added corresponding methods for changing sensitivity to SelectMgr_SelectionManager, SelectMgr_Selection and SelectBasics_SensitiveEntity;
- option -setSensitivity was implemented in vaspects Draw command;
- test case for issue #26462

15 files changed:
src/AIS/AIS_InteractiveContext.cxx
src/AIS/AIS_InteractiveContext.hxx
src/AIS/AIS_LocalContext.cxx
src/AIS/AIS_LocalContext.hxx
src/QABugs/QABugs_19.cxx
src/SelectBasics/SelectBasics_SensitiveEntity.cxx
src/SelectBasics/SelectBasics_SensitiveEntity.hxx
src/SelectBasics/SelectBasics_SensitiveEntity.lxx
src/SelectMgr/SelectMgr_Selection.cxx
src/SelectMgr/SelectMgr_Selection.hxx
src/SelectMgr/SelectMgr_SelectionManager.cxx
src/SelectMgr/SelectMgr_SelectionManager.hxx
src/ViewerTest/ViewerTest.cxx
tests/bugs/vis/bug26462_1 [new file with mode: 0644]
tests/bugs/vis/bug26462_2 [new file with mode: 0644]

index 10da2d29c5343aa71498d6d529138dbf2eaa20db..e2672112b2caa296004e03e42f2e075d2efde612 100644 (file)
@@ -2728,6 +2728,23 @@ Standard_Integer AIS_InteractiveContext::PixelTolerance() const
        : myMainSel->PixelTolerance();
 }
 
+//=======================================================================
+//function : SetSelectionSensitivity
+//purpose  : Allows to manage sensitivity of a particular selection of interactive object theObject
+//=======================================================================
+void AIS_InteractiveContext::SetSelectionSensitivity (const Handle(AIS_InteractiveObject)& theObject,
+                                                      const Standard_Integer theMode,
+                                                      const Standard_Integer theNewSensitivity)
+{
+  if (HasOpenedContext())
+  {
+    myLocalContexts (myCurLocalIndex)->SetSelectionSensitivity (theObject, theMode, theNewSensitivity);
+    return;
+  }
+
+  mgrSelector->SetSelectionSensitivity (theObject, theMode, theNewSensitivity);
+}
+
 //=======================================================================
 //function : IsInLocal
 //purpose  :
index bb711b9bc1cae486258b306b8769d39182cd82f2..9e7c60f55dee2e9b8985e78bb4f94317bd107a3f 100644 (file)
@@ -371,6 +371,13 @@ public:
   
   //! Returns the pixel tolerance.
   Standard_EXPORT Standard_Integer PixelTolerance() const;
+
+  //! Allows to manage sensitivity of a particular selection of interactive object theObject
+  //! and changes previous sensitivity value of all sensitive entities in selection with theMode
+  //! to the given theNewSensitivity.
+  Standard_EXPORT void SetSelectionSensitivity (const Handle(AIS_InteractiveObject)& theObject,
+                                                const Standard_Integer theMode,
+                                                const Standard_Integer theNewSensitivity);
   
   //! Puts the location aLocation on the initial graphic
   //! representation and the selection for the entity aniobj.
index 6505689783dc58ed39c4db5258565d1d76065c8e..d4c400f9f0ac4f97e76f829fcd612e20b0fbc67b 100644 (file)
@@ -1153,3 +1153,14 @@ Standard_Integer AIS_LocalContext::PixelTolerance() const {
 
   return myMainVS->PixelTolerance();
 }
+
+//=======================================================================
+//function : SetSelectionSensitivity
+//purpose  : Allows to manage sensitivity of a particular selection of interactive object theObject
+//=======================================================================
+void AIS_LocalContext::SetSelectionSensitivity (const Handle(AIS_InteractiveObject)& theObject,
+                                                const Standard_Integer theMode,
+                                                const Standard_Integer theNewSensitivity)
+{
+  mySM->SetSelectionSensitivity (theObject, theMode, theNewSensitivity);
+}
index 6a4c66f2181f7fb1f0aca0694c1dd33653973149..eed643be10063faf524a715a471111c1da397b90 100644 (file)
@@ -317,7 +317,14 @@ public:
   
   //! Returns the pixel tolerance.
   Standard_EXPORT Standard_Integer PixelTolerance() const;
-  
+
+  //! Allows to manage sensitivity of a particular selection of interactive object theObject
+  //! and changes previous sensitivity value of all sensitive entities in selection with theMode
+  //! to the given theNewSensitivity.
+  Standard_EXPORT void SetSelectionSensitivity (const Handle(AIS_InteractiveObject)& theObject,
+                                                const Standard_Integer theMode,
+                                                const Standard_Integer theNewSensitivity);
+
   //! Resets the transient list of presentations previously displayed in immediate mode
   //! and begins accumulation of new list by following AddToImmediateList()/Color()/Highlight() calls.
   Standard_EXPORT Standard_Boolean BeginImmediateDraw();
index b9a02cb8045be637e728454645d9541744296527..c3966728ee59906d0c8860da0e32d1eed55654fb 100644 (file)
@@ -4034,6 +4034,61 @@ static Standard_Integer OCC26195 (Draw_Interpretor& theDI, Standard_Integer theA
   return 0;
 }
 
+//=======================================================================
+//function : OCC26462
+//purpose  :
+//=======================================================================
+static Standard_Integer OCC26462 (Draw_Interpretor& theDI, Standard_Integer /*theArgNb*/, const char** /*theArgVec*/)
+{
+  if (ViewerTest::GetAISContext().IsNull())
+  {
+    std::cerr << "Error: No opened context!\n";
+    return 1;
+  }
+
+  BRepPrimAPI_MakeBox aBuilder1 (gp_Pnt (10.0, 10.0, 0.0), 10.0, 10.0, 10.0);
+  BRepPrimAPI_MakeBox aBuilder2 (10.0, 10.0, 10.0);
+  Handle(AIS_InteractiveObject) aBox1 = new AIS_Shape (aBuilder1.Shape());
+  Handle(AIS_InteractiveObject) aBox2 = new AIS_Shape (aBuilder2.Shape());
+
+  const Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
+  aCtx->OpenLocalContext();
+  aCtx->Display (aBox1, 0, 2);
+  aCtx->Display (aBox2, 0, 2);
+  ViewerTest::CurrentView()->FitAll();
+  aCtx->SetWidth (aBox1, 3);
+  aCtx->SetWidth (aBox2, 3);
+
+  aCtx->MoveTo (305, 322, ViewerTest::CurrentView());
+  aCtx->ShiftSelect();
+  aCtx->MoveTo (103, 322, ViewerTest::CurrentView());
+  aCtx->ShiftSelect();
+  if (aCtx->NbSelected() != 0)
+  {
+    theDI << "ERROR: no boxes must be selected!\n";
+    return 1;
+  }
+
+  aCtx->SetSelectionSensitivity (aBox1, 2, 5);
+
+  aCtx->MoveTo (305, 322, ViewerTest::CurrentView());
+  aCtx->ShiftSelect();
+  if (aCtx->NbSelected() != 1)
+  {
+    theDI << "ERROR: b1 was not selected\n";
+    return 1;
+  }
+  aCtx->MoveTo (103, 322, ViewerTest::CurrentView());
+  aCtx->ShiftSelect();
+  if (aCtx->NbSelected() != 1)
+  {
+    theDI << "ERROR: b2 is selected after b1's tolerance increased\n";
+    return 1;
+  }
+
+  return 0;
+}
+
 void QABugs::Commands_19(Draw_Interpretor& theCommands) {
   const char *group = "QABugs";
 
@@ -4118,5 +4173,8 @@ void QABugs::Commands_19(Draw_Interpretor& theCommands) {
                    "\n\t\t: [toPrintPixelCoord 0|1] - prints 3d projection of pixel coordinate or center of"
                    "\n\t\t: selecting rectangle onto near and far view frustum planes",
                    __FILE__, OCC26195, group);
+  theCommands.Add ("OCC26462",
+                   "OCC26462: Checks the ability to manage sensitivity of a particular selection mode in local context",
+                   __FILE__, OCC26462, group);
   return;
 }
index eea56949dad8cee8300e4ba33e6741b226b32e42..02392cc9aad48b6bb0529843ae8c2e36b31f1d57 100644 (file)
@@ -45,3 +45,15 @@ const Handle(SelectBasics_EntityOwner)& SelectBasics_SensitiveEntity::OwnerId()
 {
   return myOwnerId;
 }
+
+//=======================================================================
+// function : SetSensitivityFactor
+// purpose  : Allows to manage sensitivity of a particular entity
+//=======================================================================
+void SelectBasics_SensitiveEntity::SetSensitivityFactor (const Standard_Integer theNewSens)
+{
+  Standard_ASSERT_RAISE (theNewSens > 0,
+    "Error! Selection sensitivity have positive value.");
+
+  mySFactor = theNewSens;
+}
index 75897ade27048cc0d972f8835ec38afc46b68358..36b5a6cbc34f95071dc364f6e98bc3aae4820159 100644 (file)
@@ -58,6 +58,9 @@ public:
   //! a specific entity in selection algorithms
   //! useful for small sized entities.
   Standard_EXPORT Standard_Integer SensitivityFactor() const;
+
+  //! Allows to manage sensitivity of a particular sensitive entity
+  Standard_EXPORT void SetSensitivityFactor (const Standard_Integer theNewSens);
   
   //! Returns the number of sub-entities or elements in
   //! sensitive entity. Is used to determine if entity is
@@ -88,9 +91,6 @@ protected:
 
   Standard_EXPORT SelectBasics_SensitiveEntity (const Handle(SelectBasics_EntityOwner)& theOwnerId);
 
-  //! Allows to manage the sensitivity of the entity
-    void SetSensitivityFactor (const Standard_Integer theSensFactor);
-
   Handle(SelectBasics_EntityOwner) myOwnerId;
 
 
index 380ceb17fc7d135b0b71038c5e98a8389f845070..9d134fecc1c46085bb202bb4ae42bda3add6c31f 100644 (file)
 // Alternatively, this file may be used under the terms of Open CASCADE
 // commercial license or contractual agreement.
 
-//=======================================================================
-// function : SetSensitivityFactor
-// purpose  : Allows to manage the sensitivity of the entity
-//=======================================================================
-inline void SelectBasics_SensitiveEntity::SetSensitivityFactor (const Standard_Integer theSensFactor)
-{
-  mySFactor = theSensFactor;
-}
-
 //=======================================================================
 // function : SensitivityFactor
 // purpose  : Gets sensitivity factor for the entity
index 1ed7f78fcb70dc19b8c6e12a9d409c944739c8f8..e7237fbbb9dcf303da5bba4cebfcf036c7eb0f71 100644 (file)
@@ -27,7 +27,8 @@ SelectMgr_Selection::SelectMgr_Selection (const Standard_Integer theModeIdx)
 : myMode (theModeIdx),
   mySelectionState (SelectMgr_SOS_Unknown),
   myBVHUpdateStatus (SelectMgr_TBU_None),
-  mySensFactor (2)
+  mySensFactor (2),
+  myIsCustomSens (Standard_False)
 {}
 
 SelectMgr_Selection::~SelectMgr_Selection()
@@ -71,8 +72,15 @@ void SelectMgr_Selection::Add (const Handle(SelectBasics_SensitiveEntity)& theSe
       anEntity->SetActiveForSelection();
     }
 
-    mySensFactor = Max (mySensFactor,
-                        anEntity->BaseSensitive()->SensitivityFactor());
+    if (myIsCustomSens)
+    {
+      anEntity->BaseSensitive()->SetSensitivityFactor (mySensFactor);
+    }
+    else
+    {
+      mySensFactor = Max (mySensFactor,
+                          anEntity->BaseSensitive()->SensitivityFactor());
+    }
   }
 }      
 
@@ -136,3 +144,20 @@ Standard_Integer SelectMgr_Selection::Sensitivity() const
 {
   return mySensFactor;
 }
+
+//==================================================
+// function: SetSensitivity
+// purpose : Changes sensitivity of the selection and all its entities to the given value.
+//           IMPORTANT: This method does not update any outer selection structures, so for
+//           proper updates use SelectMgr_SelectionManager::SetSelectionSensitivity method.
+//==================================================
+void SelectMgr_Selection::SetSensitivity (const Standard_Integer theNewSens)
+{
+  mySensFactor = theNewSens;
+  myIsCustomSens = Standard_True;
+  for (Standard_Integer anIdx = 0; anIdx < myEntities.Size(); ++anIdx)
+  {
+    Handle(SelectMgr_SensitiveEntity)& anEntity = myEntities.ChangeValue (anIdx);
+    anEntity->BaseSensitive()->SetSensitivityFactor (theNewSens);
+  }
+}
index 1eaa2434052a2d50258ddb6f065a1c6f8ccf443a..59c8eab60ee61a9858dc04abd64fccce0d64247f 100644 (file)
@@ -132,6 +132,11 @@ public:
   //! Returns sensitivity of the selection
   Standard_EXPORT Standard_Integer Sensitivity() const;
 
+  //! Changes sensitivity of the selection and all its entities to the given value.
+  //! IMPORTANT: This method does not update any outer selection structures, so for
+  //! proper updates use SelectMgr_SelectionManager::SetSelectionSensitivity method.
+  Standard_EXPORT void SetSensitivity (const Standard_Integer theNewSens);
+
   DEFINE_STANDARD_RTTI (SelectMgr_Selection, MMgt_TShared)
 
 protected:
@@ -148,6 +153,7 @@ private:
   mutable SelectMgr_StateOfSelection                              mySelectionState;
   mutable SelectMgr_TypeOfBVHUpdate                               myBVHUpdateStatus;
   Standard_Integer                                                mySensFactor;
+  Standard_Boolean                                                myIsCustomSens;
 };
 
 DEFINE_STANDARD_HANDLE(SelectMgr_Selection, MMgt_TShared)
index bc96515bce5c6b3b5ae80f0b351be5c99df1634d..154c2c63c0b699c90e226729371c0a5f6291df1c 100644 (file)
@@ -905,3 +905,51 @@ void SelectMgr_SelectionManager::SetUpdateMode (const Handle(SelectMgr_Selectabl
     theObject->Selection (theMode)->UpdateStatus (theType);
 }
 
+//=======================================================================
+//function : SetSelectionSensitivity
+//purpose  : Allows to manage sensitivity of a particular selection of interactive object theObject and
+//           changes previous sensitivity value of all sensitive entities in selection with theMode
+//           to the given theNewSensitivity.
+//=======================================================================
+void SelectMgr_SelectionManager::SetSelectionSensitivity (const Handle(SelectMgr_SelectableObject)& theObject,
+                                                          const Standard_Integer theMode,
+                                                          const Standard_Integer theNewSens)
+{
+  Standard_ASSERT_RAISE (theNewSens > 0,
+    "Error! Selection sensitivity have positive value.");
+
+  if (theObject.IsNull() || !theObject->HasSelection (theMode))
+    return;
+
+  Handle(SelectMgr_Selection) aSel = theObject->Selection (theMode);
+  const Standard_Integer aPrevSens = aSel->Sensitivity();
+  aSel->SetSensitivity (theNewSens);
+
+  if (!(myGlobal.Contains (theObject) || myLocal.IsBound (theObject)))
+    return;
+
+  if (myGlobal.Contains (theObject))
+  {
+    for (TColStd_MapIteratorOfMapOfTransient aSelectorsIter (mySelectors); aSelectorsIter.More(); aSelectorsIter.Next())
+    {
+      Handle(SelectMgr_ViewerSelector) aSelector = Handle(SelectMgr_ViewerSelector)::DownCast (aSelectorsIter.Key());
+      if (aSelector->Contains (theObject))
+      {
+        aSelector->myTolerances.Decrement (aPrevSens);
+        aSelector->myTolerances.Add (theNewSens);
+        aSelector->myToUpdateTolerance = Standard_True;
+      }
+    }
+  }
+  if (myLocal.IsBound (theObject))
+  {
+    const SelectMgr_SequenceOfSelector& aSelectors = myLocal (theObject);
+    for (SelectMgr_SequenceOfSelector::Iterator aLocalIter (aSelectors); aLocalIter.More(); aLocalIter.Next())
+    {
+      Handle(SelectMgr_ViewerSelector)& aCurSel = aLocalIter.ChangeValue();
+      aCurSel->myTolerances.Decrement (aPrevSens);
+      aCurSel->myTolerances.Add (theNewSens);
+      aCurSel->myToUpdateTolerance = Standard_True;
+    }
+  }
+}
index c0f40ca3850ebbcf9d45f1bb1720d46892465ea9..16a85c94a08e836d113e6f8817c8a7f90e64e096 100644 (file)
@@ -118,8 +118,12 @@ public:
   //! Sets type of update of selection with theMode of theObject to the given theType.
   Standard_EXPORT void SetUpdateMode (const Handle(SelectMgr_SelectableObject)& theObject, const Standard_Integer theMode, const SelectMgr_TypeOfUpdate theType);
 
-
-
+  //! Allows to manage sensitivity of a particular selection of interactive object theObject and
+  //! changes previous sensitivity value of all sensitive entities in selection with theMode
+  //! to the given theNewSensitivity.
+  Standard_EXPORT void SetSelectionSensitivity (const Handle(SelectMgr_SelectableObject)& theObject,
+                                                const Standard_Integer theMode,
+                                                const Standard_Integer theNewSens);
 
   DEFINE_STANDARD_RTTI(SelectMgr_SelectionManager,MMgt_TShared)
 
index 47242fe29edbfa93cbfe7b1b4f699644fa10aca0..be001573029c520df21cacd4d826894eadb4b416 100644 (file)
@@ -1474,6 +1474,10 @@ struct ViewerTest_AspectsChangeSet
   Standard_Integer         ToSetMaxParamValue;
   Standard_Real            MaxParamValue;
 
+  Standard_Integer         ToSetSensitivity;
+  Standard_Integer         SelectionMode;
+  Standard_Integer         Sensitivity;
+
   //! Empty constructor
   ViewerTest_AspectsChangeSet()
   : ToSetVisibility   (0),
@@ -1495,7 +1499,10 @@ struct ViewerTest_AspectsChangeSet
     FreeBoundaryColor          (DEFAULT_FREEBOUNDARY_COLOR),
     ToEnableIsoOnTriangulation (-1),
     ToSetMaxParamValue (0),
-    MaxParamValue (500000) {}
+    MaxParamValue (500000),
+    ToSetSensitivity (0),
+    SelectionMode (-1),
+    Sensitivity (-1) {}
 
   //! @return true if no changes have been requested
   Standard_Boolean IsEmpty() const
@@ -1508,7 +1515,8 @@ struct ViewerTest_AspectsChangeSet
         && ToSetShowFreeBoundary  == 0
         && ToSetFreeBoundaryColor == 0
         && ToSetFreeBoundaryWidth == 0
-        && ToSetMaxParamValue     == 0;
+        && ToSetMaxParamValue     == 0
+        && ToSetSensitivity       == 0;
   }
 
   //! @return true if properties are valid
@@ -1555,6 +1563,11 @@ struct ViewerTest_AspectsChangeSet
       std::cout << "Error: the max parameter value should be greater than zero (specified " << MaxParamValue << ")\n";
       isOk = Standard_False;
     }
+    if (Sensitivity <= 0 && ToSetSensitivity)
+    {
+      std::cout << "Error: sensitivity parameter value should be positive (specified " << Sensitivity << ")\n";
+      isOk = Standard_False;
+    }
     return isOk;
   }
 
@@ -2120,6 +2133,29 @@ static Standard_Integer VAspects (Draw_Interpretor& /*theDI*/,
       aChangeSet->ToSetMaxParamValue = 1;
       aChangeSet->MaxParamValue = Draw::Atof (theArgVec[anArgIter]);
     }
+    else if (anArg == "-setsensitivity")
+    {
+      if (isDefaults)
+      {
+        std::cout << "Error: wrong syntax. -setSensitivity can not be used together with -defaults call!\n";
+        return 1;
+      }
+
+      if (aNames.IsEmpty())
+      {
+        std::cout << "Error: object and selection mode should specified explicitly when -setSensitivity is used!\n";
+        return 1;
+      }
+
+      if (anArgIter + 2 >= theArgNb)
+      {
+        std::cout << "Error: wrong syntax at " << anArg << "\n";
+        return 1;
+      }
+      aChangeSet->ToSetSensitivity = 1;
+      aChangeSet->SelectionMode = Draw::Atoi (theArgVec[++anArgIter]);
+      aChangeSet->Sensitivity = Draw::Atoi (theArgVec[++anArgIter]);
+    }
     else
     {
       std::cout << "Error: wrong syntax at " << anArg << "\n";
@@ -2293,6 +2329,10 @@ static Standard_Integer VAspects (Draw_Interpretor& /*theDI*/,
         aCtx->IsoOnTriangulation (aChangeSet->ToEnableIsoOnTriangulation == 1, aPrs);
         toRedisplay = Standard_True;
       }
+      else if (aChangeSet->ToSetSensitivity != 0)
+      {
+        aCtx->SetSelectionSensitivity (aPrs, aChangeSet->SelectionMode, aChangeSet->Sensitivity);
+      }
       if (!aDrawer.IsNull())
       {
         if (aChangeSet->ToSetShowFreeBoundary == 1)
@@ -2368,6 +2408,10 @@ static Standard_Integer VAspects (Draw_Interpretor& /*theDI*/,
             Handle(AIS_ColoredDrawer) aCurColDrawer = aColoredPrs->CustomAspects (aSubShape);
             aCurColDrawer->SetMaximalParameterValue (aChangeSet->MaxParamValue);
           }
+          if (aChangeSet->ToSetSensitivity != 0)
+          {
+            aCtx->SetSelectionSensitivity (aPrs, aChangeSet->SelectionMode, aChangeSet->Sensitivity);
+          }
         }
       }
       if (toDisplay)
@@ -5541,6 +5585,7 @@ void ViewerTest::Commands(Draw_Interpretor& theCommands)
       "\n\t\t:          [-subshapes subname1 [subname2 [...]]]"
       "\n\t\t:          [-isoontriangulation 0|1]"
       "\n\t\t:          [-setMaxParamValue {value}]"
+      "\n\t\t:          [-setSensitivity {selection_mode} {value}]"
       "\n\t\t: Manage presentation properties of all, selected or named objects."
       "\n\t\t: When -subshapes is specified than following properties will be"
       "\n\t\t: assigned to specified sub-shapes."
diff --git a/tests/bugs/vis/bug26462_1 b/tests/bugs/vis/bug26462_1
new file mode 100644 (file)
index 0000000..ac2bb31
--- /dev/null
@@ -0,0 +1,51 @@
+puts "============"
+puts "CR26462"
+puts "============"
+puts ""
+
+##########################################################################################
+puts "Visualization - selection does not adapt to line width change"
+##########################################################################################
+
+pload VISUALIZATION MODELING
+
+vinit
+box b1 10 10 10
+box b2 10 10 10
+
+vdisplay b1 b2
+vsetlocation b1 10 10 0
+vfit
+
+vaspects b1 b2 -setWidth 3
+
+vselmode 2 1
+# try to select b1 and b2
+vselect 305 322 1
+vselect 103 322 1
+# check that both boxes were not selected with default tolerance value
+set aNbSelected [vnbselected]
+if {$aNbSelected != "0"} {
+  puts "ERROR: no boxes must be selected!"
+}
+
+# increase tolerance for b1
+vaspects b1 -setSensitivity 2 4
+
+# select edge of b1
+vselect 305 322
+# check that b1's edge was selected
+set aNbSelected [vnbselected]
+if {$aNbSelected != "1"} {
+  puts "ERROR: b1 was not selected"
+}
+# try to select b2
+vselect 103 322 1
+# check that increase of tolerance for b1 doesn't influence
+# on b2
+set aNbSelected [vnbselected]
+if {$aNbSelected != "1"} {
+  puts "ERROR: b2 is selected after b1's tolerance increased"
+}
+
+set only_screen 1
diff --git a/tests/bugs/vis/bug26462_2 b/tests/bugs/vis/bug26462_2
new file mode 100644 (file)
index 0000000..7840718
--- /dev/null
@@ -0,0 +1,15 @@
+puts "============"
+puts "CR26462"
+puts "============"
+puts ""
+
+##########################################################################################
+puts "Visualization - selection does not adapt to line width change"
+##########################################################################################
+
+pload VISUALIZATION QAcommands
+
+vinit
+OCC26462
+
+set only_screen 1