0026413: Visualization, SelectMgr_ViewerSelector - Pixel tolerance is overridden...
authorvpa <vpa@opencascade.com>
Mon, 20 Jul 2015 08:46:12 +0000 (11:46 +0300)
committerbugmaster <bugmaster@opencascade.com>
Tue, 28 Jul 2015 14:59:25 +0000 (17:59 +0300)
- now custom pixel tolerance from vselprecision is added to default sensitivity of the primitive;
- unnecessary field mytolerance was removed from SelectMgr_ViewerSelector;
- test case for issue #26413.

src/IVtkOCC/IVtkOCC_ViewerSelector.cxx
src/SelectBasics/SelectBasics_SensitiveEntity.hxx
src/SelectMgr/SelectMgr_ViewerSelector.cxx
src/SelectMgr/SelectMgr_ViewerSelector.hxx
src/SelectMgr/SelectMgr_ViewerSelector.lxx
src/StdSelect/StdSelect_ViewerSelector3d.cxx
src/StdSelect/StdSelect_ViewerSelector3d.hxx
src/StdSelect/StdSelect_ViewerSelector3d.lxx
tests/bugs/vis/bug26413 [new file with mode: 0644]

index a42a295..c485caa 100644 (file)
@@ -185,7 +185,6 @@ void IVtkOCC_ViewerSelector::Activate (const Handle(SelectMgr_Selection)& theSel
   theSelection->SetSelectionState (SelectMgr_SOS_Activated);
 
   myTolerances.Add (theSelection->Sensitivity());
-  mytolerance = myTolerances.Tolerance();
   myToUpdateTolerance = Standard_True;
 }
 
@@ -203,6 +202,5 @@ void IVtkOCC_ViewerSelector::Deactivate (const Handle(SelectMgr_Selection)& theS
   theSelection->SetSelectionState (SelectMgr_SOS_Deactivated);
 
   myTolerances.Decrement (theSelection->Sensitivity());
-  mytolerance = myTolerances.Tolerance();
   myToUpdateTolerance = Standard_True;
 }
index bb3a850..567d055 100644 (file)
@@ -54,7 +54,7 @@ public:
   //! allows a better sensitivity for
   //! a specific entity in selection algorithms
   //! useful for small sized entities.
-    Standard_Real SensitivityFactor() const;
+  Standard_EXPORT Standard_Real SensitivityFactor() const;
   
   //! Returns the number of sub-entities or elements in
   //! sensitive entity. Is used to determine if entity is
index d264e44..a458fe6 100644 (file)
@@ -132,40 +132,12 @@ void SelectMgr_ToleranceMap::Decrement (const Standard_Real& theTolerance)
   }
 }
 
-//=======================================================================
-// function: Tolerance
-// purpose : Returns a current tolerance that must be applied
-//=======================================================================
-Standard_Real SelectMgr_ToleranceMap::Tolerance()
-{
-  return myCustomTolerance < 0.0 ? myLargestKey : myCustomTolerance;
-}
-
-//=======================================================================
-// function: SetCustomTolerance
-// purpose : Sets tolerance to the given one and disables adaptive checks
-//=======================================================================
-void SelectMgr_ToleranceMap::SetCustomTolerance (const Standard_Real theTolerance)
-{
-  myCustomTolerance = theTolerance;
-}
-
-//=======================================================================
-// function: ResetDefaults
-// purpose : Unsets a custom tolerance and enables adaptive checks
-//=======================================================================
-void SelectMgr_ToleranceMap::ResetDefaults()
-{
-  myCustomTolerance = -1.0;
-}
-
 //==================================================
 // Function: Initialize
 // Purpose :
 //==================================================
 SelectMgr_ViewerSelector::SelectMgr_ViewerSelector():
 preferclosest(Standard_True),
-mytolerance(2.0),
 myToUpdateTolerance (Standard_True),
 myCurRank (0),
 myIsLeftChildQueuedFirst (Standard_False),
@@ -189,7 +161,6 @@ void SelectMgr_ViewerSelector::Activate (const Handle(SelectMgr_Selection)& theS
   theSelection->SetSelectionState (SelectMgr_SOS_Activated);
 
   myTolerances.Add (theSelection->Sensitivity());
-  mytolerance = myTolerances.Tolerance();
   myToUpdateTolerance = Standard_True;
 }
 
@@ -208,7 +179,6 @@ void SelectMgr_ViewerSelector::Deactivate (const Handle(SelectMgr_Selection)& th
   theSelection->SetSelectionState (SelectMgr_SOS_Deactivated);
 
   myTolerances.Decrement (theSelection->Sensitivity());
-  mytolerance = myTolerances.Tolerance();
   myToUpdateTolerance = Standard_True;
 }
 
@@ -229,7 +199,7 @@ void SelectMgr_ViewerSelector::Clear()
 Standard_Boolean SelectMgr_ViewerSelector::isToScaleFrustum (const Handle(SelectBasics_SensitiveEntity)& theEntity)
 {
   return mySelectingVolumeMgr.GetActiveSelectionType() == SelectMgr_SelectingVolumeManager::Point
-    && theEntity->SensitivityFactor() < myTolerances.Tolerance();
+    && sensitivity (theEntity) < myTolerances.Tolerance();
 }
 
 //=======================================================================
@@ -256,6 +226,17 @@ SelectMgr_SelectingVolumeManager SelectMgr_ViewerSelector::scaleAndTransform (co
 }
 
 //=======================================================================
+// function: sensitivity
+// purpose : In case if custom tolerance is set, this method will return sum of entity
+//           sensitivity and custom tolerance.
+//=======================================================================
+Standard_Real SelectMgr_ViewerSelector::sensitivity (const Handle(SelectBasics_SensitiveEntity)& theEntity) const
+{
+  return myTolerances.IsCustomTolSet() ?
+    theEntity->SensitivityFactor() + myTolerances.CustomTolerance() : theEntity->SensitivityFactor();
+}
+
+//=======================================================================
 // function: checkOverlap
 // purpose : Internal function that checks if a particular sensitive
 //           entity theEntity overlaps current selecting volume precisely
@@ -382,7 +363,7 @@ void SelectMgr_ViewerSelector::traverseObject (const Handle(SelectMgr_Selectable
             if (!aScaledTrnsfFrustums.IsBound (anEnt->DynamicType()))
             {
               aScaledTrnsfFrustums.Bind (anEnt->DynamicType(),
-                                         scaleAndTransform (anEnt->SensitivityFactor(), theObject->InversedTransformation()));
+                                         scaleAndTransform (sensitivity (anEnt), theObject->InversedTransformation()));
             }
 
             aTmpMgr = aScaledTrnsfFrustums.Find (anEnt->DynamicType());
@@ -825,7 +806,7 @@ void SelectMgr_ViewerSelector::RebuildSensitivesTree (const Handle(SelectMgr_Sel
 // purpose  : Marks all added sensitive entities of all objects as
 //            non-selectable
 //=======================================================================
-void SelectMgr_ViewerSelector::resetSelectionActivationStatus()
+void SelectMgr_ViewerSelector::ResetSelectionActivationStatus()
 {
   SelectMgr_MapOfObjectSensitivesIterator aSensitivesIter (myMapOfObjectSensitives);
   for ( ; aSensitivesIter.More(); aSensitivesIter.Next())
@@ -874,3 +855,15 @@ void SelectMgr_ViewerSelector::ActiveOwners (NCollection_List<Handle(SelectBasic
     }
   }
 }
+
+//=======================================================================
+//function : AllowOverlapDetection
+//purpose  : Sets the detection type: if theIsToAllow is false,
+//           only fully included sensitives will be detected, otherwise
+//           the algorithm will mark both included and overlapped entities
+//           as matched
+//=======================================================================
+void SelectMgr_ViewerSelector::AllowOverlapDetection (const Standard_Boolean theIsToAllow)
+{
+  mySelectingVolumeMgr.AllowOverlapDetection (theIsToAllow);
+}
index bbe7170..6de073c 100644 (file)
@@ -76,13 +76,19 @@ public:
   Standard_EXPORT void Decrement (const Standard_Real& theTolerance);
 
   //! Returns a current tolerance that must be applied
-  Standard_EXPORT Standard_Real Tolerance();
+  inline Standard_Real Tolerance() const;
 
   //! Sets tolerance to the given one and disables adaptive checks
-  Standard_EXPORT void SetCustomTolerance (const Standard_Real theTolerance);
+  inline void SetCustomTolerance (const Standard_Real theTolerance);
 
   //! Unsets a custom tolerance and enables adaptive checks
-  Standard_EXPORT void ResetDefaults();
+  inline void ResetDefaults();
+
+  //! Returns the value of custom tolerance regardless of it validity
+  inline Standard_Real CustomTolerance() const;
+
+  //! Returns true if custom tolerance value is greater than zero
+  inline Standard_Boolean IsCustomTolSet() const;
 
 private:
   NCollection_DataMap<Standard_Real, Standard_Integer> myTolerances;
@@ -242,6 +248,14 @@ public:
   //! Returns instance of selecting volume manager of the viewer selector
   Standard_EXPORT SelectMgr_SelectingVolumeManager& GetManager();
 
+  //! Marks all added sensitive entities of all objects as non-selectable
+  Standard_EXPORT void ResetSelectionActivationStatus();
+
+  //! Is used for rectangular selection only
+  //! If theIsToAllow is false, only fully included sensitives will be detected, otherwise the algorithm will
+  //! mark both included and overlapped entities as matched
+  Standard_EXPORT void AllowOverlapDetection (const Standard_Boolean theIsToAllow);
+
   friend class SelectMgr_SelectionManager;
 
   DEFINE_STANDARD_RTTI(SelectMgr_ViewerSelector, MMgt_TShared)
@@ -265,26 +279,27 @@ protected:
   //! Internal function that checks if there is possible overlap
   //! between some entity of selectable object theObject and
   //! current selecting volume
-  void traverseObject (const Handle(SelectMgr_SelectableObject)& theObject);
+  Standard_EXPORT void traverseObject (const Handle(SelectMgr_SelectableObject)& theObject);
 
   //! Internal function that checks if a particular sensitive
   //! entity theEntity overlaps current selecting volume precisely
-  void checkOverlap (const Handle(SelectBasics_SensitiveEntity)& theEntity,
-                     const Standard_Integer theEntityIdx,
-                     SelectMgr_SelectingVolumeManager& theMgr);
+  Standard_EXPORT void checkOverlap (const Handle(SelectBasics_SensitiveEntity)& theEntity,
+                                     const Standard_Integer theEntityIdx,
+                                     SelectMgr_SelectingVolumeManager& theMgr);
 
-  //! Marks all added sensitive entities of all objects as non-selectable
-  void resetSelectionActivationStatus();
+private:
 
   //! Checks if the entity given requires to scale current selecting frustum
   Standard_Boolean isToScaleFrustum (const Handle(SelectBasics_SensitiveEntity)& theEntity);
 
+  //! In case if custom tolerance is set, this method will return sum of entity sensitivity and
+  //! custom tolerance. Otherwise, pure entity sensitivity factor will be returned.
+  Standard_Real sensitivity (const Handle(SelectBasics_SensitiveEntity)& theEntity) const;
+
   //! Applies given scale and transformation matrices to the default selecting volume manager
   SelectMgr_SelectingVolumeManager scaleAndTransform (const Standard_Real theScale,
                                                       const gp_Trsf& theTrsf);
 
-private:
-
   void Activate (const Handle(SelectMgr_Selection)& theSelection);
 
   void Deactivate (const Handle(SelectMgr_Selection)& theSelection);
@@ -295,7 +310,6 @@ private:
 protected:
 
   Standard_Boolean preferclosest;
-  Standard_Real mytolerance;
   Standard_Boolean myToUpdateTolerance;
   SelectMgr_IndexedDataMapOfOwnerCriterion mystored;
   SelectMgr_SelectingVolumeManager mySelectingVolumeMgr;
@@ -304,7 +318,7 @@ protected:
 
 private:
 
-  Handle(TColStd_HArray1OfInteger)              myIndexes;
+  Handle(TColStd_HArray1OfInteger)             myIndexes;
   Standard_Integer                             myCurRank;
   Standard_Boolean                             myIsLeftChildQueuedFirst;
   Standard_Integer                             myEntityIdx;
index 3f9c991..4a8efc7 100644 (file)
 // Alternatively, this file may be used under the terms of Open CASCADE
 // commercial license or contractual agreement.
 
+//=======================================================================
+// function: Tolerance
+// purpose : Returns a current tolerance that must be applied
+//=======================================================================
+inline Standard_Real SelectMgr_ToleranceMap::Tolerance() const
+{
+  if (myLargestKey < Precision::Confusion())
+    return 2.0; // default tolerance value
+
+  return myCustomTolerance < 0.0 ? myLargestKey : myLargestKey + myCustomTolerance;
+}
+
+//=======================================================================
+// function: SetCustomTolerance
+// purpose : Sets tolerance to the given one and disables adaptive checks
+//=======================================================================
+inline void SelectMgr_ToleranceMap::SetCustomTolerance (const Standard_Real theTolerance)
+{
+  myCustomTolerance = theTolerance;
+}
+
+//=======================================================================
+// function: CustomTolerance
+// purpose : Returns current value of custom tolerance regardless of it is set or not
+//=======================================================================
+inline Standard_Real SelectMgr_ToleranceMap::CustomTolerance() const
+{
+  return myCustomTolerance;
+}
+
+//=======================================================================
+// function: IsCustomTolSet
+// purpose : Checks if custom tolerance value is greater than zero
+//=======================================================================
+inline Standard_Boolean SelectMgr_ToleranceMap::IsCustomTolSet() const
+{
+  return myCustomTolerance > 0.0;
+}
+
+//=======================================================================
+// function: ResetDefaults
+// purpose : Unsets a custom tolerance and enables adaptive checks
+//=======================================================================
+inline void SelectMgr_ToleranceMap::ResetDefaults()
+{
+  myCustomTolerance = -1.0;
+}
+
 inline Standard_Real SelectMgr_ViewerSelector::Sensitivity() const
 {
-  return mytolerance;
+  return myTolerances.Tolerance();
 }
 
 inline void SelectMgr_ViewerSelector::Init() 
index a645173..28cae1a 100644 (file)
@@ -93,13 +93,12 @@ StdSelect_ViewerSelector3d::StdSelect_ViewerSelector3d() {}
 //=======================================================================
 void StdSelect_ViewerSelector3d::SetPixelTolerance (const Standard_Real theTolerance)
 {
-  if (mytolerance != theTolerance)
+  if (myTolerances.Tolerance() != theTolerance)
   {
     if (theTolerance < 0.0)
       myTolerances.ResetDefaults();
     else
       myTolerances.SetCustomTolerance (theTolerance);
-    mytolerance = myTolerances.Tolerance();
     myToUpdateTolerance = Standard_True;
   }
 }
@@ -116,7 +115,7 @@ void StdSelect_ViewerSelector3d::Pick (const Standard_Integer theXPix,
 
   if(myToUpdateTolerance)
   {
-    mySelectingVolumeMgr.SetPixelTolerance (mytolerance);
+    mySelectingVolumeMgr.SetPixelTolerance (myTolerances.Tolerance());
     myToUpdateTolerance = Standard_False;
   }
 
@@ -655,25 +654,3 @@ Standard_Boolean StdSelect_ViewerSelector3d::HasDepthClipping (const Handle(Sele
   const Handle(SelectMgr_SelectableObject)& aSelectable = theOwner->Selectable();
   return (aSelectable->GetClipPlanes().Size() > 0);
 }
-
-//=======================================================================
-//function : ResetSelectionActivationStatus
-//purpose  : Marks all sensitive entities, stored in viewer selector,
-//           as inactive for selection
-//=======================================================================
-void StdSelect_ViewerSelector3d::ResetSelectionActivationStatus()
-{
-  resetSelectionActivationStatus();
-}
-
-//=======================================================================
-//function : AllowOverlapDetection
-//purpose  : Sets the detection type: if theIsToAllow is false,
-//           only fully included sensitives will be detected, otherwise
-//           the algorithm will mark both included and overlapped entities
-//           as matched
-//=======================================================================
-void StdSelect_ViewerSelector3d::AllowOverlapDetection (const Standard_Boolean theIsToAllow)
-{
-  mySelectingVolumeMgr.AllowOverlapDetection (theIsToAllow);
-}
index 7e3260a..dfd4cd5 100644 (file)
@@ -77,16 +77,8 @@ public:
                                          const Handle(V3d_View)& theView,
                                          const Standard_Boolean theToClearOthers = Standard_True);
 
-  //! Marks all sensitive entities, stored in viewer selector, as inactive for selection
-  Standard_EXPORT void ResetSelectionActivationStatus();
-
   Standard_EXPORT virtual Standard_Boolean HasDepthClipping (const Handle(SelectMgr_EntityOwner)& theOwner) const Standard_OVERRIDE;
 
-  //! Is used for rectangular selection only
-  //! If theIsToAllow is false, only fully included sensitives will be detected, otherwise the algorithm will
-  //! mark both included and overlapped entities as matched
-  Standard_EXPORT void AllowOverlapDetection (const Standard_Boolean theIsToAllow);
-
   DEFINE_STANDARD_RTTI(StdSelect_ViewerSelector3d, SelectMgr_ViewerSelector)
 
 protected:
index c29b733..41a8106 100644 (file)
@@ -14,5 +14,5 @@
 
 inline Standard_Real StdSelect_ViewerSelector3d::PixelTolerance() const
 {
-  return mytolerance;
+  return myTolerances.Tolerance();
 }
diff --git a/tests/bugs/vis/bug26413 b/tests/bugs/vis/bug26413
new file mode 100644 (file)
index 0000000..6f00faa
--- /dev/null
@@ -0,0 +1,80 @@
+puts "============"
+puts "CR26413"
+puts "============"
+puts ""
+###################################################################################
+puts "Visualization, SelectMgr_ViewerSelector - Pixel tolerance is overridden by selection sensitivity"
+###################################################################################
+
+pload VISUALIZATION MODELING
+
+vinit View1
+box b 1 1 1
+vdisplay b
+vfit
+
+set x_on_edge 320
+set y_on_edge 340
+set x_on_vert 383
+set y_on_vert 306
+
+set x_sel_precise 228
+set y_sel_precise 393
+set x_sel_tol 228
+set y_sel_tol 400
+
+set x_notol 374
+set y_notol 309
+set x_tol 370
+set y_tol 312
+
+vselmode b 2 1
+
+# check precise selection of the edge
+vmoveto ${x_sel_precise} ${y_sel_precise}
+checkcolor ${x_on_edge} ${y_on_edge} 0 1 1
+# check selection in neighborhood of the edge
+vmoveto 0 0
+vmoveto ${x_sel_tol} ${y_sel_tol}
+checkcolor ${x_on_edge} ${y_on_edge} 1 1 0
+
+vmoveto 0 0
+# increase selection precision
+vselprecision 8
+
+# check precise selection of the edge
+vmoveto ${x_sel_precise} ${y_sel_precise}
+checkcolor ${x_on_edge} ${y_on_edge} 0 1 1
+# check selection in neighborhood of the edge
+vmoveto 0 0
+vmoveto $x_sel_tol ${y_sel_tol}
+checkcolor ${x_on_edge} ${y_on_edge} 0 1 1
+
+# check that after precision reset selection works as usual
+vmoveto 0 0
+vselprecision -1
+vmoveto ${x_sel_precise} ${y_sel_precise}
+checkcolor ${x_on_edge} ${y_on_edge} 0 1 1
+vmoveto 0 0
+vmoveto ${x_sel_tol} ${y_sel_tol}
+checkcolor ${x_on_edge} ${y_on_edge} 1 1 0
+
+# check that point sensitivity is inreased for all types of
+# sensitive entities
+vmoveto 0 0
+vselmode b 1 1
+vselprecision -1
+
+vmoveto ${x_notol} ${y_notol}
+# check that vertex is highlighted and edge is not
+checkcolor ${x_on_edge} ${y_on_edge} 1 1 0
+checkcolor ${x_on_vert} ${y_on_vert} 0 1 1
+
+vmoveto 0 0
+vselprecision 8
+vmoveto ${x_tol} ${y_tol}
+# check that vertex is highlighted and edge is not
+checkcolor ${x_on_edge} ${y_on_edge} 1 1 0
+checkcolor $x_on_vert $y_on_vert 0 1 1
+
+vdump ${imagedir}/${casename}