mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-04-04 18:06:22 +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:
parent
fe3a29bc9a
commit
28ee613b27
@ -429,10 +429,11 @@ is
|
||||
-- aMode provides the selection mode index of the entity aniobj.
|
||||
|
||||
SetPixelTolerance(me:mutable;
|
||||
aPrecision: Real from Standard = 4.0);
|
||||
aPrecision: Real from Standard = 2.0);
|
||||
---Level: Public
|
||||
---Purpose: Define the current selection pixel sensitivity
|
||||
-- for this context or local context if any one is activated.
|
||||
---Purpose: Disables the mechanism of adaptive tolerance calculation in SelectMgr_ViewerSelector and
|
||||
-- sets the given tolerance for ALL sensitive entities activated. For more information, see
|
||||
-- SelectMgr_ViewerSelector documentation
|
||||
-- Warning: When a local context is open the sensitivity is apply on it
|
||||
-- instead on the main context.
|
||||
|
||||
|
@ -1703,6 +1703,7 @@ void AIS_InteractiveContext::redisplayPrsRecModes (const Handle(AIS_InteractiveO
|
||||
{
|
||||
theIObj->Update (aModes.Value(), Standard_False);
|
||||
}
|
||||
theIObj->UpdateSelection();
|
||||
theIObj->SetRecomputeOk();
|
||||
}
|
||||
|
||||
@ -2590,7 +2591,10 @@ void AIS_InteractiveContext::UnsetSelectionMode (const Handle(AIS_InteractiveObj
|
||||
|
||||
//=======================================================================
|
||||
//function : SetPixelTolerance
|
||||
//purpose :
|
||||
//purpose : Disables the mechanism of adaptive tolerance calculation in
|
||||
// SelectMgr_ViewerSelector and sets the given tolerance for ALL
|
||||
// sensitive entities activated. For more information, see
|
||||
// SelectMgr_ViewerSelector.hxx
|
||||
//=======================================================================
|
||||
void AIS_InteractiveContext::SetPixelTolerance (const Standard_Real thePrecision)
|
||||
{
|
||||
@ -2672,8 +2676,8 @@ void AIS_InteractiveContext::InitAttributes()
|
||||
aLineAspect->SetWidth (1.0);
|
||||
aLineAspect->SetTypeOfLine (Aspect_TOL_DASH);
|
||||
|
||||
// tolerance to 4 pixels...
|
||||
SetPixelTolerance();
|
||||
// tolerance to 2 pixels...
|
||||
SetPixelTolerance (2.0);
|
||||
|
||||
// Customizing the drawer for trihedrons and planes...
|
||||
Handle(Prs3d_DatumAspect) aTrihAspect = myDefaultDrawer->DatumAspect();
|
||||
|
@ -187,7 +187,7 @@ void IVtkOCC_ViewerSelector::Activate (const Handle(SelectMgr_Selection)& theSel
|
||||
theSelection->SetSelectionState (SelectMgr_SOS_Activated);
|
||||
|
||||
myTolerances.Add (theSelection->Sensitivity());
|
||||
mytolerance = myTolerances.Largest();
|
||||
mytolerance = myTolerances.Tolerance();
|
||||
myToUpdateTolerance = Standard_True;
|
||||
}
|
||||
|
||||
@ -205,6 +205,6 @@ void IVtkOCC_ViewerSelector::Deactivate (const Handle(SelectMgr_Selection)& theS
|
||||
theSelection->SetSelectionState (SelectMgr_SOS_Deactivated);
|
||||
|
||||
myTolerances.Decrement (theSelection->Sensitivity());
|
||||
mytolerance = myTolerances.Largest();
|
||||
mytolerance = myTolerances.Tolerance();
|
||||
myToUpdateTolerance = Standard_True;
|
||||
}
|
||||
|
@ -54,11 +54,6 @@ is
|
||||
---Purpose: Checks whether the sensitive entity is overlapped by
|
||||
-- current selecting volume
|
||||
|
||||
SetSensitivityFactor (me : mutable;
|
||||
theSensFactor :Real from Standard);
|
||||
---C++: inline
|
||||
---Purpose: Allows to manage the sensitivity of the entity
|
||||
|
||||
SensitivityFactor (me)
|
||||
returns Real from Standard;
|
||||
---C++: inline
|
||||
@ -83,6 +78,12 @@ is
|
||||
Clear (me : mutable) is deferred;
|
||||
---Purpose: Clears up all the resources and memory allocated
|
||||
|
||||
SetSensitivityFactor (me : mutable;
|
||||
theSensFactor :Real from Standard)
|
||||
is protected;
|
||||
---C++: inline
|
||||
---Purpose: Allows to manage the sensitivity of the entity
|
||||
|
||||
|
||||
fields
|
||||
|
||||
|
@ -88,6 +88,10 @@ public:
|
||||
|
||||
virtual NCollection_Handle<SelectMgr_BaseFrustum> Transform (const gp_Trsf& /*theTrsf*/) { return NULL; }
|
||||
|
||||
//! IMPORTANT: Makes sense only for frustum built on a single point!
|
||||
//! Returns a copy of the frustum resized according to the scale factor given
|
||||
virtual NCollection_Handle<SelectMgr_BaseFrustum> Scale (const Standard_Real /*theScaleFactor*/) { return NULL; }
|
||||
|
||||
//! SAT intersection test between defined volume and given axis-aligned box
|
||||
virtual Standard_Boolean Overlaps (const BVH_Box<Standard_Real, 3>& theBndBox,
|
||||
Standard_Real& theDepth);
|
||||
|
@ -154,6 +154,7 @@ void SelectMgr_RectangularFrustum::Build (const gp_Pnt2d &thePoint)
|
||||
myNearPickedPnt = myBuilder->ProjectPntOnViewPlane (thePoint.X(), thePoint.Y(), 0.0);
|
||||
myFarPickedPnt = myBuilder->ProjectPntOnViewPlane (thePoint.X(), thePoint.Y(), 1.0);
|
||||
myViewRayDir = myFarPickedPnt - myNearPickedPnt;
|
||||
myMousePos = thePoint;
|
||||
|
||||
// LeftTopNear
|
||||
myVertices[0] = myBuilder->ProjectPntOnViewPlane (thePoint.X() - myPixelTolerance / 2.0,
|
||||
@ -511,6 +512,136 @@ NCollection_Handle<SelectMgr_BaseFrustum> SelectMgr_RectangularFrustum::Transfor
|
||||
return NCollection_Handle<SelectMgr_BaseFrustum> (aRes);
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : Scale
|
||||
// purpose : IMPORTANT: Makes sense only for frustum built on a single point!
|
||||
// Returns a copy of the frustum resized according to the scale factor given
|
||||
// =======================================================================
|
||||
NCollection_Handle<SelectMgr_BaseFrustum> SelectMgr_RectangularFrustum::Scale (const Standard_Real theScaleFactor)
|
||||
{
|
||||
SelectMgr_RectangularFrustum* aRes = new SelectMgr_RectangularFrustum();
|
||||
|
||||
aRes->myNearPickedPnt = myNearPickedPnt;
|
||||
aRes->myFarPickedPnt = myFarPickedPnt;
|
||||
aRes->myViewRayDir = myViewRayDir;
|
||||
|
||||
aRes->myIsOrthographic = myIsOrthographic;
|
||||
|
||||
// LeftTopNear
|
||||
aRes->myVertices[0] = myBuilder->ProjectPntOnViewPlane (myMousePos.X() - theScaleFactor / 2.0,
|
||||
myMousePos.Y() + theScaleFactor / 2.0,
|
||||
0.0);
|
||||
// LeftTopFar
|
||||
aRes->myVertices[1] = myBuilder->ProjectPntOnViewPlane (myMousePos.X() - theScaleFactor / 2.0,
|
||||
myMousePos.Y() + theScaleFactor / 2.0,
|
||||
1.0);
|
||||
// LeftBottomNear
|
||||
aRes->myVertices[2] = myBuilder->ProjectPntOnViewPlane (myMousePos.X() - theScaleFactor / 2.0,
|
||||
myMousePos.Y() - theScaleFactor / 2.0,
|
||||
0.0);
|
||||
// LeftBottomFar
|
||||
aRes->myVertices[3] = myBuilder->ProjectPntOnViewPlane (myMousePos.X() - theScaleFactor / 2.0,
|
||||
myMousePos.Y() - theScaleFactor / 2.0,
|
||||
1.0);
|
||||
// RightTopNear
|
||||
aRes->myVertices[4] = myBuilder->ProjectPntOnViewPlane (myMousePos.X() + theScaleFactor / 2.0,
|
||||
myMousePos.Y() + theScaleFactor / 2.0,
|
||||
0.0);
|
||||
// RightTopFar
|
||||
aRes->myVertices[5] = myBuilder->ProjectPntOnViewPlane (myMousePos.X() + theScaleFactor / 2.0,
|
||||
myMousePos.Y() + theScaleFactor / 2.0,
|
||||
1.0);
|
||||
// RightBottomNear
|
||||
aRes->myVertices[6] = myBuilder->ProjectPntOnViewPlane (myMousePos.X() + theScaleFactor / 2.0,
|
||||
myMousePos.Y() - theScaleFactor / 2.0,
|
||||
0.0);
|
||||
// RightBottomFar
|
||||
aRes->myVertices[7] = myBuilder->ProjectPntOnViewPlane (myMousePos.X() + theScaleFactor / 2.0,
|
||||
myMousePos.Y() - theScaleFactor / 2.0,
|
||||
1.0);
|
||||
// Top
|
||||
aRes->myPlanes[0] = myBuilder->PlaneEquation (aRes->myVertices[1],
|
||||
aRes->myVertices[0],
|
||||
aRes->myVertices[5],
|
||||
aRes->myVertices[6]);
|
||||
// Bottom
|
||||
aRes->myPlanes[1] = myBuilder->PlaneEquation (aRes->myVertices[3],
|
||||
aRes->myVertices[2],
|
||||
aRes->myVertices[7],
|
||||
aRes->myVertices[4]);
|
||||
// Left
|
||||
aRes->myPlanes[2] = myBuilder->PlaneEquation (aRes->myVertices[1],
|
||||
aRes->myVertices[0],
|
||||
aRes->myVertices[2],
|
||||
aRes->myVertices[6]);
|
||||
// Right
|
||||
aRes->myPlanes[3] = myBuilder->PlaneEquation (aRes->myVertices[5],
|
||||
aRes->myVertices[4],
|
||||
aRes->myVertices[6],
|
||||
aRes->myVertices[2]);
|
||||
// Near
|
||||
aRes->myPlanes[4] = myBuilder->PlaneEquation (aRes->myVertices[4],
|
||||
aRes->myVertices[6],
|
||||
aRes->myVertices[2],
|
||||
aRes->myVertices[3]);
|
||||
// Far
|
||||
aRes->myPlanes[5] = myBuilder->PlaneEquation (aRes->myVertices[5],
|
||||
aRes->myVertices[7],
|
||||
aRes->myVertices[3],
|
||||
aRes->myVertices[2]);
|
||||
|
||||
for (Standard_Integer aPlaneIdx = 0; aPlaneIdx < 6; ++aPlaneIdx)
|
||||
{
|
||||
Standard_Real aMax = -DBL_MAX;
|
||||
Standard_Real aMin = DBL_MAX;
|
||||
const SelectMgr_Vec3 aPlane = aRes->myPlanes[aPlaneIdx];
|
||||
for (Standard_Integer aVertIdx = 0; aVertIdx < 8; ++aVertIdx)
|
||||
{
|
||||
Standard_Real aProjection = DOT (aPlane, aRes->myVertices[aVertIdx]);
|
||||
aMax = Max (aMax, aProjection);
|
||||
aMin = Min (aMin, aProjection);
|
||||
}
|
||||
aRes->myMaxVertsProjections[aPlaneIdx] = aMax;
|
||||
aRes->myMinVertsProjections[aPlaneIdx] = aMin;
|
||||
}
|
||||
|
||||
SelectMgr_Vec3 aDimensions[3] =
|
||||
{
|
||||
SelectMgr_Vec3 (1.0, 0.0, 0.0),
|
||||
SelectMgr_Vec3 (0.0, 1.0, 0.0),
|
||||
SelectMgr_Vec3 (0.0, 0.0, 1.0)
|
||||
};
|
||||
|
||||
for (Standard_Integer aDim = 0; aDim < 3; ++aDim)
|
||||
{
|
||||
Standard_Real aMax = -DBL_MAX;
|
||||
Standard_Real aMin = DBL_MAX;
|
||||
for (Standard_Integer aVertIdx = 0; aVertIdx < 8; ++aVertIdx)
|
||||
{
|
||||
Standard_Real aProjection = DOT (aDimensions[aDim], aRes->myVertices[aVertIdx]);
|
||||
aMax = Max (aMax, aProjection);
|
||||
aMin = Min (aMin, aProjection);
|
||||
}
|
||||
aRes->myMaxOrthoVertsProjections[aDim] = aMax;
|
||||
aRes->myMinOrthoVertsProjections[aDim] = aMin;
|
||||
}
|
||||
|
||||
// Horizontal
|
||||
aRes->myEdgeDirs[0] = aRes->myVertices[4] - aRes->myVertices[0];
|
||||
// Vertical
|
||||
aRes->myEdgeDirs[1] = aRes->myVertices[2] - aRes->myVertices[0];
|
||||
// LeftLower
|
||||
aRes->myEdgeDirs[2] = aRes->myVertices[2] - aRes->myVertices[3];
|
||||
// RightLower
|
||||
aRes->myEdgeDirs[3] = aRes->myVertices[6] - aRes->myVertices[7];
|
||||
// LeftUpper
|
||||
aRes->myEdgeDirs[4] = aRes->myVertices[0] - aRes->myVertices[1];
|
||||
// RightUpper
|
||||
aRes->myEdgeDirs[5] = aRes->myVertices[4] - aRes->myVertices[5];
|
||||
|
||||
return NCollection_Handle<SelectMgr_BaseFrustum> (aRes);
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : Overlaps
|
||||
// purpose : Returns true if selecting volume is overlapped by
|
||||
|
@ -45,6 +45,10 @@ public:
|
||||
//! Returns a copy of the frustum transformed according to the matrix given
|
||||
virtual NCollection_Handle<SelectMgr_BaseFrustum> Transform (const gp_Trsf& theTrsf) Standard_OVERRIDE;
|
||||
|
||||
//! IMPORTANT: Makes sense only for frustum built on a single point!
|
||||
//! Returns a copy of the frustum resized according to the scale factor given
|
||||
virtual NCollection_Handle<SelectMgr_BaseFrustum> Scale (const Standard_Real theScaleFactor) Standard_OVERRIDE;
|
||||
|
||||
|
||||
// SAT Tests for different objects
|
||||
|
||||
@ -107,8 +111,9 @@ protected:
|
||||
private:
|
||||
|
||||
SelectMgr_Vec3 myNearPickedPnt; //!< 3d projection of user-picked selection point onto near view plane
|
||||
SelectMgr_Vec3 myFarPickedPnt; //!< 3d projection of user-picked selection point onto far view plane
|
||||
SelectMgr_Vec3 myFarPickedPnt; //!< 3d projection of user-picked selection point onto far view plane
|
||||
SelectMgr_Vec3 myViewRayDir;
|
||||
gp_Pnt2d myMousePos; //!< Mouse coordinates
|
||||
};
|
||||
|
||||
#endif // _SelectMgr_RectangularFrustum_HeaderFile
|
||||
|
@ -48,6 +48,25 @@ SelectMgr_SelectingVolumeManager SelectMgr_SelectingVolumeManager::Transform (co
|
||||
return aMgr;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
// function : Scale
|
||||
// purpose : IMPORTANT: Makes sense only for point selection!
|
||||
// Returns a copy of the frustum resized according to the scale factor given
|
||||
//=======================================================================
|
||||
SelectMgr_SelectingVolumeManager SelectMgr_SelectingVolumeManager::Scale (const Standard_Real theScaleFactor)
|
||||
{
|
||||
if (myActiveSelectionType != Point)
|
||||
return SelectMgr_SelectingVolumeManager (Standard_False);
|
||||
|
||||
SelectMgr_SelectingVolumeManager aMgr (Standard_False);
|
||||
|
||||
aMgr.myActiveSelectionType = Point;
|
||||
|
||||
aMgr.mySelectingVolumes[Point] = mySelectingVolumes[Point]->Scale (theScaleFactor);
|
||||
|
||||
return aMgr;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
// function : GetActiveSelectionType
|
||||
// purpose :
|
||||
|
@ -40,6 +40,10 @@ public:
|
||||
//! Returns a copy of active frustum transformed according to the matrix given
|
||||
Standard_EXPORT virtual SelectMgr_SelectingVolumeManager Transform (const gp_Trsf& theTrsf);
|
||||
|
||||
//! IMPORTANT: Makes sense only for point selection!
|
||||
//! Returns a copy of the frustum resized according to the scale factor given
|
||||
Standard_EXPORT virtual SelectMgr_SelectingVolumeManager Scale (const Standard_Real theScaleFactor);
|
||||
|
||||
Standard_EXPORT virtual Standard_Integer GetActiveSelectionType() const Standard_OVERRIDE;
|
||||
|
||||
Standard_EXPORT void SetActiveSelectionType (const SelectionType& theType);
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//==================================================
|
||||
|
@ -57,23 +57,41 @@ typedef NCollection_DataMap<Handle(SelectMgr_SelectableObject), NCollection_Hand
|
||||
typedef NCollection_DataMap<Handle(SelectMgr_EntityOwner), Standard_Integer> SelectMgr_MapOfOwnerDetectedEntities;
|
||||
typedef NCollection_DataMap<Handle(SelectMgr_EntityOwner), Standard_Integer>::Iterator SelectMgr_MapOfOwnerDetectedEntitiesIterator;
|
||||
|
||||
//! An internal class for calculation of current largest tolerance value which will be applied
|
||||
//! for creation of selecting frustum by default. Each time the selection set is deactivated,
|
||||
//! maximum tolerance value will be recalculated. If a user enables custom precision using
|
||||
//! StdSelect_ViewerSelector3d::SetPixelTolerance, it will be applied to all sensitive entities
|
||||
//! without any checks.
|
||||
class SelectMgr_ToleranceMap
|
||||
{
|
||||
public:
|
||||
|
||||
//! Sets tolerance values to -1.0
|
||||
SelectMgr_ToleranceMap();
|
||||
|
||||
Standard_EXPORT ~SelectMgr_ToleranceMap();
|
||||
|
||||
//! Adds the value given to map, checks if the current tolerance value
|
||||
//! should be replaced by theTolerance
|
||||
Standard_EXPORT void Add (const Standard_Real& theTolerance);
|
||||
|
||||
//! Decrements a counter of the tolerance given, checks if the current tolerance value
|
||||
//! should be recalculated
|
||||
Standard_EXPORT void Decrement (const Standard_Real& theTolerance);
|
||||
|
||||
Standard_EXPORT Standard_Real Largest();
|
||||
//! Returns a current tolerance that must be applied
|
||||
Standard_EXPORT Standard_Real Tolerance();
|
||||
|
||||
//! Sets tolerance to the given one and disables adaptive checks
|
||||
Standard_EXPORT void SetCustomTolerance (const Standard_Real theTolerance);
|
||||
|
||||
//! Unsets a custom tolerance and enables adaptive checks
|
||||
Standard_EXPORT void ResetDefaults();
|
||||
|
||||
private:
|
||||
NCollection_DataMap<Standard_Real, Standard_Integer> myTolerances;
|
||||
Standard_Real myLargestKey;
|
||||
Standard_Real myCustomTolerance;
|
||||
};
|
||||
|
||||
//! A framework to define finding, sorting the sensitive
|
||||
@ -99,6 +117,13 @@ private:
|
||||
//! SelectMgr_SelectionManager, and manipulate
|
||||
//! the SelectMgr_Selection objects given to them by
|
||||
//! the selection manager.
|
||||
//!
|
||||
//! Tolerances are applied to the entities in the following way:
|
||||
//! 1. tolerance value stored in mytolerance will be used to calculate initial
|
||||
//! selecting frustum, which will be applied for intersection testing during
|
||||
//! BVH traverse;
|
||||
//! 2. if tolerance of sensitive entity is less than mytolerance, the frustum for
|
||||
//! intersection detection will be resized according to its sensitivity.
|
||||
class SelectMgr_ViewerSelector : public MMgt_TShared
|
||||
{
|
||||
public:
|
||||
@ -255,6 +280,13 @@ protected:
|
||||
//! Marks all added sensitive entities of all objects as non-selectable
|
||||
void resetSelectionActivationStatus();
|
||||
|
||||
//! Checks if the entity given requires to scale current selecting frustum
|
||||
Standard_Boolean isToScaleFrustum (const Handle(SelectBasics_SensitiveEntity)& theEntity);
|
||||
|
||||
//! 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);
|
||||
|
@ -97,7 +97,11 @@ void StdSelect_ViewerSelector3d::SetPixelTolerance (const Standard_Real theToler
|
||||
{
|
||||
if (mytolerance != theTolerance)
|
||||
{
|
||||
mytolerance = theTolerance;
|
||||
if (theTolerance < 0.0)
|
||||
myTolerances.ResetDefaults();
|
||||
else
|
||||
myTolerances.SetCustomTolerance (theTolerance);
|
||||
mytolerance = myTolerances.Tolerance();
|
||||
myToUpdateTolerance = Standard_True;
|
||||
}
|
||||
}
|
||||
|
@ -749,7 +749,7 @@ static int VSelPrecision(Draw_Interpretor& di, Standard_Integer argc, const char
|
||||
{
|
||||
if( argc > 2 )
|
||||
{
|
||||
di << "Use: " << argv[0] << " [tolerance_value]\n";
|
||||
di << "Wrong parameters! Must be: " << argv[0] << " [-unset] [tolerance]\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -760,14 +760,20 @@ static int VSelPrecision(Draw_Interpretor& di, Standard_Integer argc, const char
|
||||
if( argc == 1 )
|
||||
{
|
||||
Standard_Real aPixelTolerance = aContext->PixelTolerance();
|
||||
di << "Precision mode : 0 (window)\n";
|
||||
di << "Pixel tolerance : " << aPixelTolerance << "\n";
|
||||
}
|
||||
else if (argc == 2)
|
||||
{
|
||||
|
||||
Standard_Integer aPixelTolerance = Draw::Atoi (argv[1]);
|
||||
aContext->SetPixelTolerance (aPixelTolerance);
|
||||
TCollection_AsciiString anArg = TCollection_AsciiString (argv[1]);
|
||||
anArg.LowerCase();
|
||||
if (anArg == "-unset")
|
||||
{
|
||||
aContext->SetPixelTolerance (-1.0);
|
||||
}
|
||||
else
|
||||
{
|
||||
aContext->SetPixelTolerance (anArg.RealValue());
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -5275,7 +5281,9 @@ void ViewerTest::Commands(Draw_Interpretor& theCommands)
|
||||
__FILE__,VClearSensi,group);
|
||||
|
||||
theCommands.Add("vselprecision",
|
||||
"vselprecision : vselprecision [tolerance_value]",
|
||||
"vselprecision [-unset] [tolerance_value]"
|
||||
"\n\t\t Manages selection precision or prints current value if no parameter is passed."
|
||||
"\n\t\t -unset - restores default selection tolerance behavior, based on individual entity tolerance",
|
||||
__FILE__,VSelPrecision,group);
|
||||
|
||||
theCommands.Add("vperf",
|
||||
|
@ -24,8 +24,8 @@ vfit
|
||||
vtop
|
||||
|
||||
vaspects -setwidth 5
|
||||
vmoveto 199 200
|
||||
if { "[vreadpixel 199 200 rgb name]" != "CYAN1" } {
|
||||
vmoveto 200 200
|
||||
if { "[vreadpixel 200 200 rgb name]" != "CYAN1" } {
|
||||
puts "Error : The box is not selectable!"
|
||||
}
|
||||
|
||||
|
23
tests/bugs/vis/bug26159
Normal file
23
tests/bugs/vis/bug26159
Normal file
@ -0,0 +1,23 @@
|
||||
puts "================================================================"
|
||||
puts "CR26159"
|
||||
puts "Visualization - revise tolerance implementation for selection."
|
||||
puts "================================================================"
|
||||
puts ""
|
||||
|
||||
pload VISUALIZATION MODELING
|
||||
box b1 1 1 1 1 1 1
|
||||
box b2 3 3 3 1 1 1
|
||||
box b3 6 6 6 1 1 1
|
||||
vdisplay b1 b2 b3
|
||||
vfit
|
||||
|
||||
# activate vertex selection
|
||||
vselmode b1 1 1
|
||||
|
||||
# check selection tolerance
|
||||
vmoveto 58 324
|
||||
checkcolor 58 324 0 1 1
|
||||
|
||||
# to print tolerance in case of failure:
|
||||
puts [vselprecision]
|
||||
vdump $imagedir/${casename}
|
Loading…
x
Reference in New Issue
Block a user