1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-29 14:00:49 +03:00

Compare commits

...

2 Commits

Author SHA1 Message Date
kgv
b9513dc178 0031798: Visualization, SelectMgr_ViewerSelector - fix comparing depth of direct and indirect triangle hits
SelectMgr_RectangularFrustum now stores also a distance from picking Ray within SelectBasics_PickResult
to better prioritize results and prefer entities closer to ray.
2020-09-27 12:42:39 +03:00
kgv
eb9f4fb01b 0031701: Visualization, SelectMgr_ViewerSelector - make depth tolerance configurable
SelectMgr_ViewerSelector::SetDepthTolerance() - added property defining depth tolerance type and value.
Default value remains the same (SelectMgr_TypeOfDepthTolerance_SensitivityFactor),
while new values (SelectMgr_TypeOfDepthTolerance_Uniform, SelectMgr_TypeOfDepthTolerance_UniformPixels) change behavior.

AIS_Manipulator - removed obsolete suggestion to use AIS_InteractiveContext::SetPickClosest()
for issue fixed long time ago by #0027797.
2020-09-24 14:25:32 +03:00
11 changed files with 222 additions and 132 deletions

View File

@@ -94,9 +94,6 @@ DEFINE_STANDARD_HANDLE (AIS_Manipulator, AIS_InteractiveObject)
//! @endcode //! @endcode
//! The last method erases manipulator object. //! The last method erases manipulator object.
//! @warning //! @warning
//! On construction an instance of AIS_Manipulator object is bound to Graphic3d_ZLayerId_Topmost layer,
//! so make sure to call for your AIS_InteractiveContext the method MainSelector()->SetPickClosest (Standard_False)
//! otherwise you may notice issues with activation of modes.
class AIS_Manipulator : public AIS_InteractiveObject class AIS_Manipulator : public AIS_InteractiveObject
{ {
public: public:

View File

@@ -932,7 +932,7 @@ Standard_Boolean Select3D_SensitivePrimitiveArray::Matches (SelectBasics_Selecti
{ {
myDetectedNodeMap->ChangeMap().Unite (aChild->myDetectedNodeMap->Map()); myDetectedNodeMap->ChangeMap().Unite (aChild->myDetectedNodeMap->Map());
} }
if (thePickResult.Depth() > aPickResult.Depth()) if (thePickResult.DepthWithOffset() > aPickResult.DepthWithOffset())
{ {
myDetectedIdx = aGroupIter; myDetectedIdx = aGroupIter;
thePickResult = aPickResult; thePickResult = aPickResult;

View File

@@ -111,6 +111,8 @@ Standard_Boolean Select3D_SensitiveSet::processElements (SelectBasics_SelectingV
continue; continue;
} }
//if (thePickResult.DepthWithOffset() > aPickResult.DepthWithOffset())
//if (thePickResult.Depth() > aPickResult.Depth())
if (thePickResult.Depth() > aPickResult.Depth()) if (thePickResult.Depth() > aPickResult.Depth())
{ {
thePickResult = aPickResult; thePickResult = aPickResult;

View File

@@ -35,6 +35,7 @@ public:
SelectBasics_PickResult() SelectBasics_PickResult()
: myObjPickedPnt (RealLast(), 0.0, 0.0), : myObjPickedPnt (RealLast(), 0.0, 0.0),
myDepth (RealLast()), myDepth (RealLast()),
myRayDistance (0.0),
myDistToCenter (RealLast()) {} myDistToCenter (RealLast()) {}
//! Constructor with initialization. //! Constructor with initialization.
@@ -43,6 +44,7 @@ public:
const gp_Pnt& theObjPickedPnt) const gp_Pnt& theObjPickedPnt)
: myObjPickedPnt (theObjPickedPnt), : myObjPickedPnt (theObjPickedPnt),
myDepth (theDepth), myDepth (theDepth),
myRayDistance (0.0),
myDistToCenter (theDistToCenter) {} myDistToCenter (theDistToCenter) {}
public: public:
@@ -54,6 +56,7 @@ public:
void Invalidate() void Invalidate()
{ {
myDepth = RealLast(); myDepth = RealLast();
myRayDistance = 0.0;
myObjPickedPnt = gp_Pnt (RealLast(), 0.0, 0.0); myObjPickedPnt = gp_Pnt (RealLast(), 0.0, 0.0);
myNormal.SetValues (0.0f, 0.0f, 0.0f); myNormal.SetValues (0.0f, 0.0f, 0.0f);
} }
@@ -64,6 +67,14 @@ public:
//! Set depth along picking ray. //! Set depth along picking ray.
void SetDepth (Standard_Real theDepth) { myDepth = theDepth; } void SetDepth (Standard_Real theDepth) { myDepth = theDepth; }
//! Return distance from picking ray to picked point.
Standard_Real RayDistance() const { return myRayDistance; }
//! Set distance from picking ray to picked point.
void SetRayDistance (Standard_Real theDistance) { myRayDistance = theDistance; }
Standard_Real DepthWithOffset() const { return myDepth + myRayDistance; }
//! Return TRUE if Picked Point lying on detected entity was set. //! Return TRUE if Picked Point lying on detected entity was set.
Standard_Boolean HasPickedPoint() const { return myObjPickedPnt.X() != RealLast(); } Standard_Boolean HasPickedPoint() const { return myObjPickedPnt.X() != RealLast(); }
@@ -97,6 +108,7 @@ private:
gp_Pnt myObjPickedPnt; //!< User-picked selection point onto object gp_Pnt myObjPickedPnt; //!< User-picked selection point onto object
NCollection_Vec3<float> myNormal; //!< surface normal NCollection_Vec3<float> myNormal; //!< surface normal
Standard_Real myDepth; //!< Depth to detected point Standard_Real myDepth; //!< Depth to detected point
Standard_Real myRayDistance; //!< distance from picked ray to detected point
Standard_Real myDistToCenter; //!< Distance from 3d projection user-picked selection point to entity's geometry center Standard_Real myDistToCenter; //!< Distance from 3d projection user-picked selection point to entity's geometry center
}; };

View File

@@ -57,6 +57,7 @@ SelectMgr_TriangularFrustum.hxx
SelectMgr_TriangularFrustumSet.cxx SelectMgr_TriangularFrustumSet.cxx
SelectMgr_TriangularFrustumSet.hxx SelectMgr_TriangularFrustumSet.hxx
SelectMgr_TypeOfBVHUpdate.hxx SelectMgr_TypeOfBVHUpdate.hxx
SelectMgr_TypeOfDepthTolerance.hxx
SelectMgr_TypeOfUpdate.hxx SelectMgr_TypeOfUpdate.hxx
SelectMgr_VectorTypes.hxx SelectMgr_VectorTypes.hxx
SelectMgr_ViewClipRange.cxx SelectMgr_ViewClipRange.cxx

View File

@@ -81,12 +81,14 @@ void SelectMgr_RectangularFrustum::segmentSegmentDistance (const gp_Pnt& theSegP
|| aFigureVecMod <= gp::Resolution()) || aFigureVecMod <= gp::Resolution())
{ {
thePickResult.SetPickedPoint (aClosestPnt); thePickResult.SetPickedPoint (aClosestPnt);
thePickResult.SetRayDistance (0.0);
return; return;
} }
const Standard_Real aCosOfAngle = aFigureVec.Dot (aPickedVec) / (aPickedVecMod * aFigureVecMod); const Standard_Real aCosOfAngle = aFigureVec.Dot (aPickedVec) / (aPickedVecMod * aFigureVecMod);
const Standard_Real aSegPntShift = Min(aFigureVecMod, Max(0.0, aCosOfAngle * aPickedVecMod)); const Standard_Real aSegPntShift = Min(aFigureVecMod, Max(0.0, aCosOfAngle * aPickedVecMod));
thePickResult.SetPickedPoint (theSegPnt1.XYZ() + aFigureVec.XYZ() * (aSegPntShift / aFigureVecMod)); thePickResult.SetPickedPoint (theSegPnt1.XYZ() + aFigureVec.XYZ() * (aSegPntShift / aFigureVecMod));
thePickResult.SetRayDistance (thePickResult.PickedPoint().Distance (aClosestPnt) * myScale); ///
} }
// ======================================================================= // =======================================================================
@@ -537,6 +539,7 @@ Standard_Boolean SelectMgr_RectangularFrustum::Overlaps (const gp_Pnt& thePnt,
thePickResult.SetDepth (Abs (aDepth) * myScale); thePickResult.SetDepth (Abs (aDepth) * myScale);
thePickResult.SetPickedPoint (thePnt); thePickResult.SetPickedPoint (thePnt);
thePickResult.SetRayDistance (thePnt.Distance (myNearPickedPnt.XYZ() + myViewRayDir.XYZ() * aDepth) * myScale);
return !theClipRange.IsClipped (thePickResult.Depth()); return !theClipRange.IsClipped (thePickResult.Depth());
} }
@@ -695,6 +698,7 @@ Standard_Boolean SelectMgr_RectangularFrustum::Overlaps (const gp_Pnt& thePnt1,
{ {
thePickResult.SetDepth (myNearPickedPnt.Distance (aPtOnPlane) * myScale); thePickResult.SetDepth (myNearPickedPnt.Distance (aPtOnPlane) * myScale);
thePickResult.SetPickedPoint (aPtOnPlane); thePickResult.SetPickedPoint (aPtOnPlane);
thePickResult.SetRayDistance (0.0);
thePickResult.SetSurfaceNormal (aTriangleNormal); thePickResult.SetSurfaceNormal (aTriangleNormal);
return !theClipRange.IsClipped (thePickResult.Depth()); return !theClipRange.IsClipped (thePickResult.Depth());
} }

View File

@@ -32,12 +32,12 @@ public:
gp_Pnt Point; //!< 3D point gp_Pnt Point; //!< 3D point
Graphic3d_Vec3 Normal; //!< surface normal or 0 vector if undefined Graphic3d_Vec3 Normal; //!< surface normal or 0 vector if undefined
Standard_Real Depth; //!< distance from the view plane to the entity Standard_Real Depth; //!< distance from the view plane to the entity
Standard_Real RayDistance; //!< distance from picked ray to detected point
Standard_Real MinDist; //!< distance from the clicked point to the entity on the view plane Standard_Real MinDist; //!< distance from the clicked point to the entity on the view plane
Standard_Real Tolerance; //!< tolerance used for selecting candidates Standard_Real Tolerance; //!< tolerance used for selecting candidates
Standard_Integer Priority; //!< selection priority Standard_Integer Priority; //!< selection priority
Standard_Integer ZLayerPosition; //!< ZLayer rendering order index, stronger than a depth Standard_Integer ZLayerPosition; //!< ZLayer rendering order index, stronger than a depth
Standard_Integer NbOwnerMatches; //!< overall number of entities collected for the same owner Standard_Integer NbOwnerMatches; //!< overall number of entities collected for the same owner
Standard_Boolean ToPreferClosest; //!< whether closest object is preferred even if has less priority
public: public:
DEFINE_STANDARD_ALLOC DEFINE_STANDARD_ALLOC
@@ -45,21 +45,17 @@ public:
//! Empty constructor. //! Empty constructor.
SelectMgr_SortCriterion() SelectMgr_SortCriterion()
: Depth (0.0), : Depth (0.0),
RayDistance(0.0),
MinDist (0.0), MinDist (0.0),
Tolerance(0.0), Tolerance(0.0),
Priority (0), Priority (0),
ZLayerPosition (0), ZLayerPosition (0),
NbOwnerMatches (0), NbOwnerMatches (0) {}
ToPreferClosest (Standard_True) {}
//! Comparison operator. Standard_Real DepthWithOffset() const { return Depth + RayDistance; }
bool operator> (const SelectMgr_SortCriterion& theOther) const { return IsGreater (theOther); }
//! Comparison operator. //! Compare with another item by depth, priority and minDist.
bool operator< (const SelectMgr_SortCriterion& theOther) const { return IsLower (theOther); } bool IsCloserDepth (const SelectMgr_SortCriterion& theOther) const
//! Compare with another item.
bool IsGreater (const SelectMgr_SortCriterion& theOther) const
{ {
// the object within different ZLayer groups can not be compared by depth // the object within different ZLayer groups can not be compared by depth
if (ZLayerPosition != theOther.ZLayerPosition) if (ZLayerPosition != theOther.ZLayerPosition)
@@ -67,26 +63,34 @@ public:
return ZLayerPosition > theOther.ZLayerPosition; return ZLayerPosition > theOther.ZLayerPosition;
} }
if (ToPreferClosest) // closest object is selected unless difference is within tolerance
///const Standard_Real aDepthDelta = Depth - theOther.Depth;
const Standard_Real aDepthDelta = DepthWithOffset() - theOther.DepthWithOffset();
if (Abs (aDepthDelta) > (Tolerance + theOther.Tolerance))
{ {
// closest object is selected unless difference is within tolerance return aDepthDelta < 0.0;
if (Abs (Depth - theOther.Depth) > (Tolerance + theOther.Tolerance)) }
{
return Depth < theOther.Depth; // if two objects have similar depth, select the one with higher priority
} if (Priority > theOther.Priority)
{
// if two objects have similar depth, select the one with higher priority return true;
if (Priority > theOther.Priority) }
{
return true; // if priorities are equal, one closest to the mouse
} return Priority == theOther.Priority
&& MinDist < theOther.MinDist;
// if priorities are equal, one closest to the mouse }
return Priority == theOther.Priority
&& MinDist < theOther.MinDist; //! Compare with another item using old logic (OCCT version <= 6.3.1) with priority considered preceding depth.
bool IsHigherPriority (const SelectMgr_SortCriterion& theOther) const
{
// the object within different ZLayer groups can not be compared by depth
if (ZLayerPosition != theOther.ZLayerPosition)
{
return ZLayerPosition > theOther.ZLayerPosition;
} }
// old logic (OCCT version <= 6.3.1)
if (Priority > theOther.Priority) if (Priority > theOther.Priority)
{ {
return true; return true;
@@ -96,7 +100,7 @@ public:
return false; return false;
} }
if (Abs (Depth - theOther.Depth) <= Precision::Confusion()) if (Abs (Depth - theOther.Depth) <= (Tolerance + theOther.Tolerance))
{ {
return MinDist < theOther.MinDist; return MinDist < theOther.MinDist;
} }
@@ -104,53 +108,6 @@ public:
return Depth < theOther.Depth; return Depth < theOther.Depth;
} }
//! Compare with another item.
bool IsLower (const SelectMgr_SortCriterion& theOther) const
{
// the object within different ZLayer groups can not be compared by depth
if (ZLayerPosition != theOther.ZLayerPosition)
{
return ZLayerPosition < theOther.ZLayerPosition;
}
if (ToPreferClosest)
{
// closest object is selected unless difference is within tolerance
if (ToPreferClosest
&& Abs (Depth - theOther.Depth) > (Tolerance + theOther.Tolerance))
{
return Depth > theOther.Depth;
}
// if two objects have similar depth, select the one with higher priority
if (Priority < theOther.Priority)
{
return true;
}
// if priorities are equal, one closest to the mouse
return Priority == theOther.Priority
&& MinDist > theOther.MinDist;
}
// old logic (OCCT version <= 6.3.1)
if (Priority > theOther.Priority)
{
return false;
}
else if (Priority != theOther.Priority)
{
return true;
}
if (Abs (Depth - theOther.Depth) <= Precision::Confusion())
{
return MinDist > theOther.MinDist;
}
return Depth > theOther.Depth;
}
}; };
#endif // _SelectMgr_SortCriterion_HeaderFile #endif // _SelectMgr_SortCriterion_HeaderFile

View File

@@ -0,0 +1,26 @@
// Copyright (c) 2020 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#ifndef _SelectMgr_TypeOfDepthTolerance_HeaderFile
#define _SelectMgr_TypeOfDepthTolerance_HeaderFile
//! Define the type of depth tolerance for considering picked entities to lie on the same depth (distance from eye to entity).
//! @sa SelectMgr_SortCriterion, SelectMgr_ViewerSelector
enum SelectMgr_TypeOfDepthTolerance
{
SelectMgr_TypeOfDepthTolerance_Uniform, //!< use a predefined tolerance value (defined in 3D world scale) to compare any entities
SelectMgr_TypeOfDepthTolerance_UniformPixels, //!< use a predefined tolerance value (defined in pixels) to compare any entities
SelectMgr_TypeOfDepthTolerance_SensitivityFactor, //!< use sensitivity factor (in pixels) assigned to specific entity
};
#endif // _SelectMgr_TypeOfDepthTolerance_HeaderFile

View File

@@ -42,18 +42,28 @@ namespace
{ {
public: public:
CompareResults (const SelectMgr_IndexedDataMapOfOwnerCriterion& theMapOfCriterion) CompareResults (const SelectMgr_IndexedDataMapOfOwnerCriterion& theMapOfCriterion,
: myMapOfCriterion (&theMapOfCriterion) bool theToPreferClosest)
{ : myMapOfCriterion (&theMapOfCriterion),
} myToPreferClosest (theToPreferClosest) {}
Standard_Boolean operator() (Standard_Integer theLeft, Standard_Integer theRight) const Standard_Boolean operator() (Standard_Integer theLeft, Standard_Integer theRight) const
{ {
return myMapOfCriterion->FindFromIndex (theLeft) > myMapOfCriterion->FindFromIndex (theRight); const SelectMgr_SortCriterion& anElemLeft = myMapOfCriterion->FindFromIndex (theLeft);
const SelectMgr_SortCriterion& anElemRight = myMapOfCriterion->FindFromIndex (theRight);
if (myToPreferClosest)
{
return anElemLeft.IsCloserDepth (anElemRight);
}
else
{
return anElemLeft.IsHigherPriority (anElemRight);
}
} }
private: private:
const SelectMgr_IndexedDataMapOfOwnerCriterion* myMapOfCriterion; const SelectMgr_IndexedDataMapOfOwnerCriterion* myMapOfCriterion;
bool myToPreferClosest;
}; };
static const Graphic3d_Mat4d SelectMgr_ViewerSelector_THE_IDENTITY_MAT; static const Graphic3d_Mat4d SelectMgr_ViewerSelector_THE_IDENTITY_MAT;
@@ -114,18 +124,33 @@ void SelectMgr_ViewerSelector::updatePoint3d (SelectMgr_SortCriterion& theCriter
} }
} }
if (mySelectingVolumeMgr.Camera().IsNull()) const Standard_Real aSensFactor = myDepthTolType == SelectMgr_TypeOfDepthTolerance_SensitivityFactor ? theEntity->SensitivityFactor() : myDepthTolerance;
switch (myDepthTolType)
{ {
theCriterion.Tolerance = theEntity->SensitivityFactor() / 33.0; case SelectMgr_TypeOfDepthTolerance_Uniform:
} {
else if (mySelectingVolumeMgr.Camera()->IsOrthographic()) theCriterion.Tolerance = myDepthTolerance;
{ break;
theCriterion.Tolerance = myCameraScale * theEntity->SensitivityFactor(); }
} case SelectMgr_TypeOfDepthTolerance_UniformPixels:
else case SelectMgr_TypeOfDepthTolerance_SensitivityFactor:
{ {
const Standard_Real aDistFromEye = Abs ((theCriterion.Point.XYZ() - myCameraEye.XYZ()).Dot (myCameraDir.XYZ())); if (mySelectingVolumeMgr.Camera().IsNull())
theCriterion.Tolerance = aDistFromEye * myCameraScale * theEntity->SensitivityFactor(); {
// fallback for an arbitrary projection matrix
theCriterion.Tolerance = aSensFactor / 33.0;
}
else if (mySelectingVolumeMgr.Camera()->IsOrthographic())
{
theCriterion.Tolerance = myCameraScale * aSensFactor;
}
else
{
const Standard_Real aDistFromEye = Abs ((theCriterion.Point.XYZ() - myCameraEye.XYZ()).Dot (myCameraDir.XYZ()));
theCriterion.Tolerance = aDistFromEye * myCameraScale * aSensFactor;
}
break;
}
} }
} }
@@ -133,14 +158,15 @@ void SelectMgr_ViewerSelector::updatePoint3d (SelectMgr_SortCriterion& theCriter
// Function: Initialize // Function: Initialize
// Purpose : // Purpose :
//================================================== //==================================================
SelectMgr_ViewerSelector::SelectMgr_ViewerSelector(): SelectMgr_ViewerSelector::SelectMgr_ViewerSelector()
preferclosest(Standard_True), : myDepthTolerance (0.0),
myToUpdateTolerance (Standard_True), myDepthTolType (SelectMgr_TypeOfDepthTolerance_SensitivityFactor),
myCameraScale (1.0), myToPreferClosest (Standard_True),
myToPrebuildBVH (Standard_False), myToUpdateTolerance (Standard_True),
myCurRank (0), myCameraScale (1.0),
myIsLeftChildQueuedFirst (Standard_False), myToPrebuildBVH (Standard_False),
myEntityIdx (0) myCurRank (0),
myIsLeftChildQueuedFirst (Standard_False)
{ {
myEntitySetBuilder = new BVH_BinnedBuilder<Standard_Real, 3, 4> (BVH_Constants_LeafNodeSizeSingle, BVH_Constants_MaxTreeDepth, Standard_True); myEntitySetBuilder = new BVH_BinnedBuilder<Standard_Real, 3, 4> (BVH_Constants_LeafNodeSizeSingle, BVH_Constants_MaxTreeDepth, Standard_True);
} }
@@ -261,8 +287,8 @@ void SelectMgr_ViewerSelector::checkOverlap (const Handle(Select3D_SensitiveEnti
aCriterion.Entity = theEntity; aCriterion.Entity = theEntity;
aCriterion.Priority = anOwner->Priority(); aCriterion.Priority = anOwner->Priority();
aCriterion.Depth = aPickResult.Depth(); aCriterion.Depth = aPickResult.Depth();
aCriterion.RayDistance = aPickResult.RayDistance();
aCriterion.MinDist = aPickResult.DistToGeomCenter(); aCriterion.MinDist = aPickResult.DistToGeomCenter();
aCriterion.ToPreferClosest = preferclosest;
if (SelectMgr_SortCriterion* aPrevCriterion = mystored.ChangeSeek (anOwner)) if (SelectMgr_SortCriterion* aPrevCriterion = mystored.ChangeSeek (anOwner))
{ {
@@ -270,7 +296,7 @@ void SelectMgr_ViewerSelector::checkOverlap (const Handle(Select3D_SensitiveEnti
aCriterion.NbOwnerMatches = aPrevCriterion->NbOwnerMatches; aCriterion.NbOwnerMatches = aPrevCriterion->NbOwnerMatches;
if (theMgr.GetActiveSelectionType() != SelectBasics_SelectingVolumeManager::Box) if (theMgr.GetActiveSelectionType() != SelectBasics_SelectingVolumeManager::Box)
{ {
if (aCriterion > *aPrevCriterion) if (aCriterion.IsCloserDepth (*aPrevCriterion))
{ {
updatePoint3d (aCriterion, aPickResult, theEntity, theInversedTrsf, theMgr); updatePoint3d (aCriterion, aPickResult, theEntity, theInversedTrsf, theMgr);
*aPrevCriterion = aCriterion; *aPrevCriterion = aCriterion;
@@ -887,28 +913,27 @@ TCollection_AsciiString SelectMgr_ViewerSelector::Status (const Handle(SelectMgr
//======================================================================= //=======================================================================
//function : SortResult //function : SortResult
//purpose : there is a certain number of entities ranged by criteria //purpose :
// (depth, size, priority, mouse distance from borders or
// CDG of the detected primitive. Parsing :
// maximum priorities .
// then a reasonable compromise between depth and distance...
// finally the ranges are stored in myindexes depending on the parsing.
// so, it is possible to only read
//======================================================================= //=======================================================================
void SelectMgr_ViewerSelector::SortResult() void SelectMgr_ViewerSelector::SortResult()
{ {
if(mystored.IsEmpty()) return; if (mystored.IsEmpty())
{
return;
}
const Standard_Integer anExtent = mystored.Extent(); const Standard_Integer anExtent = mystored.Extent();
if(myIndexes.IsNull() || anExtent != myIndexes->Length()) if (myIndexes.IsNull() || anExtent != myIndexes->Length())
{
myIndexes = new TColStd_HArray1OfInteger (1, anExtent); myIndexes = new TColStd_HArray1OfInteger (1, anExtent);
}
TColStd_Array1OfInteger& anIndexArray = myIndexes->ChangeArray1(); TColStd_Array1OfInteger& anIndexArray = myIndexes->ChangeArray1();
for (Standard_Integer anIndexIter = 1; anIndexIter <= anExtent; ++anIndexIter) for (Standard_Integer anIndexIter = 1; anIndexIter <= anExtent; ++anIndexIter)
{ {
anIndexArray.SetValue (anIndexIter, anIndexIter); anIndexArray.SetValue (anIndexIter, anIndexIter);
} }
std::sort (anIndexArray.begin(), anIndexArray.end(), CompareResults (mystored)); std::sort (anIndexArray.begin(), anIndexArray.end(), CompareResults (mystored, myToPreferClosest));
} }
//======================================================================= //=======================================================================
@@ -1094,7 +1119,7 @@ void SelectMgr_ViewerSelector::DumpJson (Standard_OStream& theOStream, Standard_
{ {
OCCT_DUMP_TRANSIENT_CLASS_BEGIN (theOStream) OCCT_DUMP_TRANSIENT_CLASS_BEGIN (theOStream)
OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, preferclosest) OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myToPreferClosest)
OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myToUpdateTolerance) OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myToUpdateTolerance)
OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, mystored.Extent()) OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, mystored.Extent())
@@ -1122,7 +1147,6 @@ void SelectMgr_ViewerSelector::DumpJson (Standard_OStream& theOStream, Standard_
OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myCurRank) OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myCurRank)
OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myIsLeftChildQueuedFirst) OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myIsLeftChildQueuedFirst)
OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myEntityIdx)
OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myMapOfObjectSensitives.Extent()) OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myMapOfObjectSensitives.Extent())
} }

View File

@@ -30,6 +30,7 @@
#include <SelectMgr_SelectableObjectSet.hxx> #include <SelectMgr_SelectableObjectSet.hxx>
#include <SelectMgr_StateOfSelection.hxx> #include <SelectMgr_StateOfSelection.hxx>
#include <SelectMgr_ToleranceMap.hxx> #include <SelectMgr_ToleranceMap.hxx>
#include <SelectMgr_TypeOfDepthTolerance.hxx>
#include <Standard_OStream.hxx> #include <Standard_OStream.hxx>
#include <SelectMgr_BVHThreadPool.hxx> #include <SelectMgr_BVHThreadPool.hxx>
@@ -99,8 +100,7 @@ public:
Standard_Integer PixelTolerance() const { return myTolerances.Tolerance(); } Standard_Integer PixelTolerance() const { return myTolerances.Tolerance(); }
//! Sorts the detected entites by priority and distance. //! Sorts the detected entites by priority and distance.
//! to be redefined if other criterion are used... Standard_EXPORT virtual void SortResult();
Standard_EXPORT void SortResult();
//! Returns the picked element with the highest priority, //! Returns the picked element with the highest priority,
//! and which is the closest to the last successful mouse position. //! and which is the closest to the last successful mouse position.
@@ -111,13 +111,32 @@ public:
: Picked (1); : Picked (1);
} }
//! Set preference of selecting one object for OnePicked() method: //! Return the flag determining precedence of picked depth (distance from eye to entity) over entity priority in sorted results; TRUE by default.
//! - If True, objects with less depth (distance fron the view plane) are //! When flag is TRUE, priority will be considered only if entities have the same depth within the tolerance.
//! preferred regardless of priority (priority is used then to choose among //! When flag is FALSE, entities with higher priority will be in front regardless of their depth (like x-ray).
//! objects with similar depth), bool ToPickClosest() const { return myToPreferClosest; }
//! - If False, objects with higher priority are preferred regardless of the
//! depth which is used to choose among objects of the same priority. //! Set flag determining precedence of picked depth over entity priority in sorted results.
void SetPickClosest (const Standard_Boolean theToPreferClosest) { preferclosest = theToPreferClosest; } void SetPickClosest (bool theToPreferClosest) { myToPreferClosest = theToPreferClosest; }
//! Return the type of tolerance for considering two entities having a similar depth (distance from eye to entity);
//! SelectMgr_TypeOfDepthTolerance_SensitivityFactor by default.
SelectMgr_TypeOfDepthTolerance DepthToleranceType() const { return myDepthTolType; }
//! Return the tolerance for considering two entities having a similar depth (distance from eye to entity).
Standard_Real DepthTolerance() const { return myDepthTolerance; }
//! Set the tolerance for considering two entities having a similar depth (distance from eye to entity).
//! @param theType [in] type of tolerance value
//! @param theTolerance [in] tolerance value in 3D scale (SelectMgr_TypeOfDepthTolerance_Uniform)
//! or in pixels (SelectMgr_TypeOfDepthTolerance_UniformPixels);
//! value is ignored in case of SelectMgr_TypeOfDepthTolerance_SensitivityFactor
void SetDepthTolerance (SelectMgr_TypeOfDepthTolerance theType,
Standard_Real theTolerance)
{
myDepthTolType = theType;
myDepthTolerance = theTolerance;
}
//! Returns the number of detected owners. //! Returns the number of detected owners.
Standard_Integer NbPicked() const { return mystored.Extent(); } Standard_Integer NbPicked() const { return mystored.Extent(); }
@@ -357,7 +376,9 @@ private: // implementation of deprecated methods
protected: protected:
Standard_Boolean preferclosest; Standard_Real myDepthTolerance;
SelectMgr_TypeOfDepthTolerance myDepthTolType;
Standard_Boolean myToPreferClosest;
Standard_Boolean myToUpdateTolerance; Standard_Boolean myToUpdateTolerance;
SelectMgr_IndexedDataMapOfOwnerCriterion mystored; SelectMgr_IndexedDataMapOfOwnerCriterion mystored;
SelectMgr_SelectingVolumeManager mySelectingVolumeMgr; SelectMgr_SelectingVolumeManager mySelectingVolumeMgr;
@@ -372,12 +393,9 @@ protected:
Standard_Boolean myToPrebuildBVH; Standard_Boolean myToPrebuildBVH;
Handle(SelectMgr_BVHThreadPool) myBVHThreadPool; Handle(SelectMgr_BVHThreadPool) myBVHThreadPool;
private:
Handle(TColStd_HArray1OfInteger) myIndexes; Handle(TColStd_HArray1OfInteger) myIndexes;
Standard_Integer myCurRank; Standard_Integer myCurRank;
Standard_Boolean myIsLeftChildQueuedFirst; Standard_Boolean myIsLeftChildQueuedFirst;
Standard_Integer myEntityIdx;
SelectMgr_MapOfObjectSensitives myMapOfObjectSensitives; SelectMgr_MapOfObjectSensitives myMapOfObjectSensitives;
}; };

View File

@@ -12821,7 +12821,6 @@ static int VManipulator (Draw_Interpretor& theDi,
{ {
Handle(V3d_View) aCurrentView = ViewerTest::CurrentView(); Handle(V3d_View) aCurrentView = ViewerTest::CurrentView();
Handle(V3d_Viewer) aViewer = ViewerTest::GetViewerFromContext(); Handle(V3d_Viewer) aViewer = ViewerTest::GetViewerFromContext();
ViewerTest::GetAISContext()->MainSelector()->SetPickClosest (Standard_False);
if (aCurrentView.IsNull() if (aCurrentView.IsNull()
|| aViewer.IsNull()) || aViewer.IsNull())
{ {
@@ -13300,6 +13299,52 @@ static int VSelectionProperties (Draw_Interpretor& theDi,
{ {
aCtx->SetPixelTolerance (Draw::Atoi (theArgVec[++anArgIter])); aCtx->SetPixelTolerance (Draw::Atoi (theArgVec[++anArgIter]));
} }
else if (anArg == "-preferclosest")
{
bool toPreferClosest = true;
if (anArgIter + 1 < theArgsNb
&& Draw::ParseOnOff (theArgVec[anArgIter + 1], toPreferClosest))
{
++anArgIter;
}
aCtx->MainSelector()->SetPickClosest (toPreferClosest);
}
else if ((anArg == "-depthtol"
|| anArg == "-depthtolerance")
&& anArgIter + 1 < theArgsNb)
{
TCollection_AsciiString aTolType (theArgVec[++anArgIter]);
aTolType.LowerCase();
if (aTolType == "uniform")
{
if (anArgIter + 1 >= theArgsNb)
{
Message::SendFail() << "Syntax error: wrong number of arguments";
return 1;
}
aCtx->MainSelector()->SetDepthTolerance (SelectMgr_TypeOfDepthTolerance_Uniform,
Draw::Atof (theArgVec[++anArgIter]));
}
else if (aTolType == "uniformpx")
{
if (anArgIter + 1 >= theArgsNb)
{
Message::SendFail() << "Syntax error: wrong number of arguments";
return 1;
}
aCtx->MainSelector()->SetDepthTolerance (SelectMgr_TypeOfDepthTolerance_UniformPixels,
Draw::Atof (theArgVec[++anArgIter]));
}
else if (aTolType == "sensfactor")
{
aCtx->MainSelector()->SetDepthTolerance (SelectMgr_TypeOfDepthTolerance_SensitivityFactor, 0.0);
}
else
{
Message::SendFail() << "Syntax error at '" << aTolType << "'";
return 1;
}
}
else if ((anArg == "-mode" else if ((anArg == "-mode"
|| anArg == "-dispmode") || anArg == "-dispmode")
&& anArgIter + 1 < theArgsNb) && anArgIter + 1 < theArgsNb)
@@ -13429,6 +13474,7 @@ static int VSelectionProperties (Draw_Interpretor& theDi,
else else
{ {
Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'"; Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
return 1;
} }
} }
@@ -14898,6 +14944,9 @@ void ViewerTest::ViewerCommands(Draw_Interpretor& theCommands)
"\n 'first' to pick first acceptable (default)" "\n 'first' to pick first acceptable (default)"
"\n 'topmost' to pick only topmost (and nothing, if topmost is rejected by filters)" "\n 'topmost' to pick only topmost (and nothing, if topmost is rejected by filters)"
"\n -pixTol value : sets up pixel tolerance" "\n -pixTol value : sets up pixel tolerance"
"\n -depthTol {uniform|uniformpx} value : sets tolerance for sorting results by depth"
"\n -depthTol {sensfactor} : use sensitive factor for sorting results by depth"
"\n -preferClosest {0|1} : sets if depth should take precedence over priority while sorting results"
"\n -dispMode dispMode : sets display mode for highlighting" "\n -dispMode dispMode : sets display mode for highlighting"
"\n -layer ZLayer : sets ZLayer for highlighting" "\n -layer ZLayer : sets ZLayer for highlighting"
"\n -color {name|r g b} : sets highlight color" "\n -color {name|r g b} : sets highlight color"