1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-04 13:13:25 +03:00

0026159: Visualization - revise tolerance implementation for selection

Max tolerance is now applied to all objects and entities by default;
if there is an entity with a lower tolerance, selecting frustum will be recalculated for it.
The ability to set sensitivity for each entity individually is moved to protected section of SelectBasics_SensitiveEntity
SetPixelTolerance from AIS_InteractiveContext now sets custom tolerance that is applied to all sensitives.
Added -unset option to vselprecision command to disable custom tolerances.
Test case for issue #26159
This commit is contained in:
vpa
2015-05-06 15:35:36 +03:00
committed by abv
parent fe3a29bc9a
commit 28ee613b27
15 changed files with 362 additions and 79 deletions

View File

@@ -39,28 +39,30 @@
IMPLEMENT_STANDARD_HANDLE (SelectMgr_ViewerSelector, MMgt_TShared)
IMPLEMENT_STANDARD_RTTIEXT(SelectMgr_ViewerSelector, MMgt_TShared)
static Standard_Boolean SelectDebugModeOnVS()
{
static Standard_Integer isDebugMode( -1 );
if ( isDebugMode < 0 ) {
isDebugMode = 1;
OSD_Environment selectdb("SELDEBUGMODE");
if ( selectdb.Value().IsEmpty() )
isDebugMode = 0;
}
return ( isDebugMode != 0 );
}
//=======================================================================
// function: SelectMgr_ToleranceMap
// purpose : Sets tolerance values to -1.0
//=======================================================================
SelectMgr_ToleranceMap::SelectMgr_ToleranceMap()
{
myLargestKey = -1;
myLargestKey = -1.0;
myCustomTolerance = -1.0;
}
//=======================================================================
// function: ~SelectMgr_ToleranceMap
// purpose :
//=======================================================================
SelectMgr_ToleranceMap::~SelectMgr_ToleranceMap()
{
myTolerances.Clear();
}
//=======================================================================
// function: Add
// purpose : Adds the value given to map, checks if the current tolerance value
// should be replaced by theTolerance
//=======================================================================
void SelectMgr_ToleranceMap::Add (const Standard_Real& theTolerance)
{
if (myTolerances.IsBound (theTolerance))
@@ -68,14 +70,8 @@ void SelectMgr_ToleranceMap::Add (const Standard_Real& theTolerance)
Standard_Integer& aFreq = myTolerances.ChangeFind (theTolerance);
aFreq++;
if (theTolerance == myLargestKey)
return;
Standard_Integer aMaxFreq = myTolerances.Find (myLargestKey);
if (aFreq >= aMaxFreq)
{
myLargestKey = aFreq == aMaxFreq ? Max (myLargestKey, theTolerance) : theTolerance;
}
if (aFreq == 1 && theTolerance != myLargestKey)
myLargestKey = Max (theTolerance, myLargestKey);
}
else
{
@@ -87,14 +83,15 @@ void SelectMgr_ToleranceMap::Add (const Standard_Real& theTolerance)
}
myTolerances.Bind (theTolerance, 1);
Standard_Integer aMaxFreq = myTolerances.Find (myLargestKey);
if (aMaxFreq <= 1)
{
myLargestKey = aMaxFreq == 1 ? Max (myLargestKey, theTolerance) : theTolerance;
}
myLargestKey = Max (theTolerance, myLargestKey);
}
}
//=======================================================================
// function: Decrement
// purpose : Decrements a counter of the tolerance given, checks if the current tolerance value
// should be recalculated
//=======================================================================
void SelectMgr_ToleranceMap::Decrement (const Standard_Real& theTolerance)
{
if (myTolerances.IsBound (theTolerance))
@@ -102,24 +99,43 @@ void SelectMgr_ToleranceMap::Decrement (const Standard_Real& theTolerance)
Standard_Integer& aFreq = myTolerances.ChangeFind (theTolerance);
aFreq--;
if (theTolerance == myLargestKey)
if (Abs (theTolerance - myLargestKey) < Precision::Confusion() && aFreq == 0)
{
Standard_Integer aMaxFreq = aFreq;
myLargestKey = 0.0;
for (NCollection_DataMap<Standard_Real, Standard_Integer>::Iterator anIter (myTolerances); anIter.More(); anIter.Next())
{
if (aMaxFreq <= anIter.Value() && myLargestKey != anIter.Key())
{
aMaxFreq = anIter.Value();
myLargestKey = anIter.Key();
}
if (anIter.Value() != 0)
myLargestKey = Max (myLargestKey, anIter.Key());
}
}
}
}
Standard_Real SelectMgr_ToleranceMap::Largest()
//=======================================================================
// function: Tolerance
// purpose : Returns a current tolerance that must be applied
//=======================================================================
Standard_Real SelectMgr_ToleranceMap::Tolerance()
{
return myLargestKey;
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;
}
//==================================================
@@ -152,7 +168,7 @@ void SelectMgr_ViewerSelector::Activate (const Handle(SelectMgr_Selection)& theS
theSelection->SetSelectionState (SelectMgr_SOS_Activated);
myTolerances.Add (theSelection->Sensitivity());
mytolerance = myTolerances.Largest();
mytolerance = myTolerances.Tolerance();
myToUpdateTolerance = Standard_True;
}
@@ -171,7 +187,7 @@ void SelectMgr_ViewerSelector::Deactivate (const Handle(SelectMgr_Selection)& th
theSelection->SetSelectionState (SelectMgr_SOS_Deactivated);
myTolerances.Decrement (theSelection->Sensitivity());
mytolerance = myTolerances.Largest();
mytolerance = myTolerances.Tolerance();
myToUpdateTolerance = Standard_True;
}
@@ -185,6 +201,39 @@ void SelectMgr_ViewerSelector::Clear()
myMapOfDetected.Clear();
}
//=======================================================================
// function: isToScaleFrustum
// purpose : Checks if the entity given requires to scale current selecting frustum
//=======================================================================
Standard_Boolean SelectMgr_ViewerSelector::isToScaleFrustum (const Handle(SelectBasics_SensitiveEntity)& theEntity)
{
return mySelectingVolumeMgr.GetActiveSelectionType() == SelectMgr_SelectingVolumeManager::Point
&& theEntity->SensitivityFactor() < myTolerances.Tolerance();
}
//=======================================================================
// function: scaleAndTransform
// purpose : Applies given scale and transformation matrices to the default selecting volume manager
//=======================================================================
SelectMgr_SelectingVolumeManager SelectMgr_ViewerSelector::scaleAndTransform (const Standard_Real theScale,
const gp_Trsf& theTrsf)
{
SelectMgr_SelectingVolumeManager aMgr;
if (theScale > Precision::Angular())
{
aMgr = mySelectingVolumeMgr.Scale (theScale);
}
if (theTrsf.Form() != gp_Identity)
{
aMgr = aMgr.GetActiveSelectionType() == SelectMgr_SelectingVolumeManager::Unknown ?
mySelectingVolumeMgr.Transform (theTrsf) : aMgr.Transform (theTrsf);
}
return aMgr;
}
//=======================================================================
// function: checkOverlap
// purpose : Internal function that checks if a particular sensitive
@@ -202,9 +251,7 @@ void SelectMgr_ViewerSelector::checkOverlap (const Handle(SelectBasics_Sensitive
{
if (!anOwner.IsNull())
{
Standard_Boolean isPointSelection =
theMgr.GetActiveSelectionType() == SelectMgr_SelectingVolumeManager::Point;
if (HasDepthClipping (anOwner) && isPointSelection)
if (HasDepthClipping (anOwner) && theMgr.GetActiveSelectionType() == SelectMgr_SelectingVolumeManager::Point)
{
Standard_Boolean isClipped = theMgr.IsClipped (anOwner->Selectable()->GetClipPlanes(),
aPickResult.Depth());
@@ -255,6 +302,8 @@ void SelectMgr_ViewerSelector::traverseObject (const Handle(SelectMgr_Selectable
SelectMgr_SelectingVolumeManager aMgr = theObject->HasTransformation() ?
mySelectingVolumeMgr.Transform (theObject->InversedTransformation()) : mySelectingVolumeMgr;
NCollection_DataMap<Handle(Standard_Type), SelectMgr_SelectingVolumeManager> aScaledTrnsfFrustums;
Standard_Integer aNode = 0; // a root node
if (!aMgr.Overlaps (aSensitivesTree->MinPoint (0),
aSensitivesTree->MaxPoint (0)))
@@ -306,7 +355,19 @@ void SelectMgr_ViewerSelector::traverseObject (const Handle(SelectMgr_Selectable
anEntitySet->GetSensitiveById (anIdx);
if (aSensitive->IsActiveForSelection())
{
checkOverlap (aSensitive->BaseSensitive(), anIdx, aMgr);
const Handle(SelectBasics_SensitiveEntity)& anEnt = aSensitive->BaseSensitive();
SelectMgr_SelectingVolumeManager aTmpMgr = aMgr;
if (isToScaleFrustum (anEnt))
{
if (!aScaledTrnsfFrustums.IsBound (anEnt->DynamicType()))
{
aScaledTrnsfFrustums.Bind (anEnt->DynamicType(),
scaleAndTransform (anEnt->SensitivityFactor(), theObject->InversedTransformation()));
}
aTmpMgr = aScaledTrnsfFrustums.Find (anEnt->DynamicType());
}
checkOverlap (anEnt, anIdx, aTmpMgr);
}
}
if (aHead < 0)
@@ -397,20 +458,6 @@ void SelectMgr_ViewerSelector::TraverseSensitives()
}
SortResult();
if (SelectDebugModeOnVS())
{
cout<<"\tSelectMgr_VS:: Resultat du move"<<endl;
cout<<"\tNb Detectes :"<<mystored.Extent()<<endl;
for(Standard_Integer i=1; i<=mystored.Extent(); i++)
{
const SelectMgr_SortCriterion& Crit = mystored (myIndexes->Value(i));
cout << "\t" << i << " - Prior" << Crit.Priority()
<< " - prof :" << Crit.Depth()
<< " - Dist. :" << Crit.MinDist() << endl;
}
}
}
//==================================================