From 29a4908e1892840679c4fdc360ba1e8e92931ae5 Mon Sep 17 00:00:00 2001 From: vpa Date: Mon, 20 Jul 2015 11:46:12 +0300 Subject: [PATCH] 0026413: Visualization, SelectMgr_ViewerSelector - Pixel tolerance is overridden by selection sensitivity - 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 | 2 - .../SelectBasics_SensitiveEntity.hxx | 2 +- src/SelectMgr/SelectMgr_ViewerSelector.cxx | 59 ++++++-------- src/SelectMgr/SelectMgr_ViewerSelector.hxx | 40 +++++++--- src/SelectMgr/SelectMgr_ViewerSelector.lxx | 50 +++++++++++- src/StdSelect/StdSelect_ViewerSelector3d.cxx | 27 +------ src/StdSelect/StdSelect_ViewerSelector3d.hxx | 8 -- src/StdSelect/StdSelect_ViewerSelector3d.lxx | 2 +- tests/bugs/vis/bug26413 | 80 +++++++++++++++++++ 9 files changed, 186 insertions(+), 84 deletions(-) create mode 100644 tests/bugs/vis/bug26413 diff --git a/src/IVtkOCC/IVtkOCC_ViewerSelector.cxx b/src/IVtkOCC/IVtkOCC_ViewerSelector.cxx index a42a29515c..c485caa3bd 100644 --- a/src/IVtkOCC/IVtkOCC_ViewerSelector.cxx +++ b/src/IVtkOCC/IVtkOCC_ViewerSelector.cxx @@ -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; } diff --git a/src/SelectBasics/SelectBasics_SensitiveEntity.hxx b/src/SelectBasics/SelectBasics_SensitiveEntity.hxx index bb3a85009b..567d055037 100644 --- a/src/SelectBasics/SelectBasics_SensitiveEntity.hxx +++ b/src/SelectBasics/SelectBasics_SensitiveEntity.hxx @@ -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 diff --git a/src/SelectMgr/SelectMgr_ViewerSelector.cxx b/src/SelectMgr/SelectMgr_ViewerSelector.cxx index d264e443a7..a458fe6c43 100644 --- a/src/SelectMgr/SelectMgr_ViewerSelector.cxx +++ b/src/SelectMgr/SelectMgr_ViewerSelector.cxx @@ -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(); } //======================================================================= @@ -255,6 +225,17 @@ SelectMgr_SelectingVolumeManager SelectMgr_ViewerSelector::scaleAndTransform (co return aMgr; } +//======================================================================= +// 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 @@ -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 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; diff --git a/src/SelectMgr/SelectMgr_ViewerSelector.lxx b/src/SelectMgr/SelectMgr_ViewerSelector.lxx index 3f9c99183a..4a8efc74ab 100644 --- a/src/SelectMgr/SelectMgr_ViewerSelector.lxx +++ b/src/SelectMgr/SelectMgr_ViewerSelector.lxx @@ -12,9 +12,57 @@ // 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() diff --git a/src/StdSelect/StdSelect_ViewerSelector3d.cxx b/src/StdSelect/StdSelect_ViewerSelector3d.cxx index a645173faf..28cae1a9b6 100644 --- a/src/StdSelect/StdSelect_ViewerSelector3d.cxx +++ b/src/StdSelect/StdSelect_ViewerSelector3d.cxx @@ -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); -} diff --git a/src/StdSelect/StdSelect_ViewerSelector3d.hxx b/src/StdSelect/StdSelect_ViewerSelector3d.hxx index 7e3260a9fc..dfd4cd5295 100644 --- a/src/StdSelect/StdSelect_ViewerSelector3d.hxx +++ b/src/StdSelect/StdSelect_ViewerSelector3d.hxx @@ -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: diff --git a/src/StdSelect/StdSelect_ViewerSelector3d.lxx b/src/StdSelect/StdSelect_ViewerSelector3d.lxx index c29b733070..41a8106315 100644 --- a/src/StdSelect/StdSelect_ViewerSelector3d.lxx +++ b/src/StdSelect/StdSelect_ViewerSelector3d.lxx @@ -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 index 0000000000..6f00faa49b --- /dev/null +++ b/tests/bugs/vis/bug26413 @@ -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} -- 2.39.5