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

0026195: Visualization - optimize selection algorithms

- initial transformation of triangulation is now applied to selecting frustum;
- switched from NCollection_Vec3 to gp collections to avoid conversions and usage of macros;
- calculation of frustum was refactored to reduce its build time;
- double pixel tolerances for selection were replaced by integer ones;
- switched to splitting along the main axis only in SelectMgr BVH selection primitive sets.
This commit is contained in:
vpa
2015-08-31 10:29:53 +03:00
committed by bugmaster
parent 646529083a
commit 3bf9a45f7a
50 changed files with 1057 additions and 978 deletions

View File

@@ -66,8 +66,8 @@ namespace {
//=======================================================================
SelectMgr_ToleranceMap::SelectMgr_ToleranceMap()
{
myLargestKey = -1.0;
myCustomTolerance = -1.0;
myLargestKey = -1;
myCustomTolerance = -1;
}
//=======================================================================
@@ -84,7 +84,7 @@ SelectMgr_ToleranceMap::~SelectMgr_ToleranceMap()
// 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)
void SelectMgr_ToleranceMap::Add (const Standard_Integer& theTolerance)
{
if (myTolerances.IsBound (theTolerance))
{
@@ -113,7 +113,7 @@ void SelectMgr_ToleranceMap::Add (const Standard_Real& theTolerance)
// 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)
void SelectMgr_ToleranceMap::Decrement (const Standard_Integer& theTolerance)
{
if (myTolerances.IsBound (theTolerance))
{
@@ -122,8 +122,8 @@ void SelectMgr_ToleranceMap::Decrement (const Standard_Real& theTolerance)
if (Abs (theTolerance - myLargestKey) < Precision::Confusion() && aFreq == 0)
{
myLargestKey = 0.0;
for (NCollection_DataMap<Standard_Real, Standard_Integer>::Iterator anIter (myTolerances); anIter.More(); anIter.Next())
myLargestKey = 0;
for (NCollection_DataMap<Standard_Integer, Standard_Integer>::Iterator anIter (myTolerances); anIter.More(); anIter.Next())
{
if (anIter.Value() != 0)
myLargestKey = Max (myLargestKey, anIter.Key());
@@ -199,35 +199,12 @@ Standard_Boolean SelectMgr_ViewerSelector::isToScaleFrustum (const Handle(Select
&& sensitivity (theEntity) < 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: 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
Standard_Integer SelectMgr_ViewerSelector::sensitivity (const Handle(SelectBasics_SensitiveEntity)& theEntity) const
{
return myTolerances.IsCustomTolSet() ?
theEntity->SensitivityFactor() + myTolerances.CustomTolerance() : theEntity->SensitivityFactor();
@@ -259,7 +236,7 @@ void SelectMgr_ViewerSelector::checkOverlap (const Handle(SelectBasics_Sensitive
Standard_Integer aPriority = anOwner->Priority();
SelectMgr_SortCriterion aCriterion (aPriority, aPickResult.Depth(), aPickResult.DistToGeomCenter(), theEntity->SensitivityFactor() / 33, preferclosest);
SelectMgr_SortCriterion aCriterion (aPriority, aPickResult.Depth(), aPickResult.DistToGeomCenter(), theEntity->SensitivityFactor() / 33.0, preferclosest);
if (mystored.Contains (anOwner))
{
if (theMgr.GetActiveSelectionType() != 1)
@@ -281,6 +258,40 @@ void SelectMgr_ViewerSelector::checkOverlap (const Handle(SelectBasics_Sensitive
}
}
//=======================================================================
// function: computeFrustum
// purpose : Internal function that checks if a current selecting frustum
// needs to be scaled and transformed for the entity and performs
// necessary calculations
//=======================================================================
void SelectMgr_ViewerSelector::computeFrustum (const Handle(SelectBasics_SensitiveEntity)& theEnt,
const gp_Trsf& theInvTrsf,
SelectMgr_FrustumCache& theCachedMgrs,
SelectMgr_SelectingVolumeManager& theResMgr)
{
Standard_Integer aScale = 1;
const Standard_Boolean toScale = isToScaleFrustum (theEnt);
if (toScale)
{
aScale = sensitivity (theEnt);
}
if (theEnt->HasInitLocation())
{
theResMgr =
mySelectingVolumeMgr.ScaleAndTransform (aScale, theEnt->InvInitLocation() * theInvTrsf);
}
else if (toScale)
{
if (!theCachedMgrs.IsBound (aScale))
{
theCachedMgrs.Bind (aScale,
mySelectingVolumeMgr.ScaleAndTransform(aScale, theInvTrsf));
}
theResMgr = theCachedMgrs.Find (aScale);
}
}
//=======================================================================
// function: traverseObject
// purpose : Internal function that checks if there is possible overlap
@@ -321,10 +332,10 @@ void SelectMgr_ViewerSelector::traverseObject (const Handle(SelectMgr_Selectable
}
SelectMgr_SelectingVolumeManager aMgr = aInversedTrsf.Form() != gp_Identity
? mySelectingVolumeMgr.Transform (aInversedTrsf)
? mySelectingVolumeMgr.ScaleAndTransform (1, aInversedTrsf)
: mySelectingVolumeMgr;
NCollection_DataMap<Handle(Standard_Type), SelectMgr_SelectingVolumeManager> aScaledTrnsfFrustums;
SelectMgr_FrustumCache aScaledTrnsfFrustums;
Standard_Integer aNode = 0; // a root node
if (!aMgr.Overlaps (aSensitivesTree->MinPoint (0),
@@ -379,16 +390,7 @@ void SelectMgr_ViewerSelector::traverseObject (const Handle(SelectMgr_Selectable
{
const Handle(SelectBasics_SensitiveEntity)& anEnt = aSensitive->BaseSensitive();
SelectMgr_SelectingVolumeManager aTmpMgr = aMgr;
if (isToScaleFrustum (anEnt))
{
if (!aScaledTrnsfFrustums.IsBound (anEnt->DynamicType()))
{
aScaledTrnsfFrustums.Bind (anEnt->DynamicType(),
scaleAndTransform (sensitivity (anEnt), aInversedTrsf));
}
aTmpMgr = aScaledTrnsfFrustums.Find (anEnt->DynamicType());
}
computeFrustum (anEnt, aInversedTrsf, aScaledTrnsfFrustums, aTmpMgr);
checkOverlap (anEnt, anIdx, aTmpMgr);
}
}