SelectMgr_RectangularFrustum now stores also a distance from picking Ray within SelectBasics_PickResult
to better prioritize results and prefer entities closer to ray.
{
myDetectedNodeMap->ChangeMap().Unite (aChild->myDetectedNodeMap->Map());
}
- if (thePickResult.Depth() > aPickResult.Depth())
+ if (thePickResult.DepthWithOffset() > aPickResult.DepthWithOffset())
{
myDetectedIdx = aGroupIter;
thePickResult = aPickResult;
continue;
}
+ //if (thePickResult.DepthWithOffset() > aPickResult.DepthWithOffset())
+ //if (thePickResult.Depth() > aPickResult.Depth())
if (thePickResult.Depth() > aPickResult.Depth())
{
thePickResult = aPickResult;
SelectBasics_PickResult()
: myObjPickedPnt (RealLast(), 0.0, 0.0),
myDepth (RealLast()),
+ myRayDistance (0.0),
myDistToCenter (RealLast()) {}
//! Constructor with initialization.
const gp_Pnt& theObjPickedPnt)
: myObjPickedPnt (theObjPickedPnt),
myDepth (theDepth),
+ myRayDistance (0.0),
myDistToCenter (theDistToCenter) {}
public:
void Invalidate()
{
myDepth = RealLast();
+ myRayDistance = 0.0;
myObjPickedPnt = gp_Pnt (RealLast(), 0.0, 0.0);
myNormal.SetValues (0.0f, 0.0f, 0.0f);
}
//! Set depth along picking ray.
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.
Standard_Boolean HasPickedPoint() const { return myObjPickedPnt.X() != RealLast(); }
gp_Pnt myObjPickedPnt; //!< User-picked selection point onto object
NCollection_Vec3<float> myNormal; //!< surface normal
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
};
|| aFigureVecMod <= gp::Resolution())
{
thePickResult.SetPickedPoint (aClosestPnt);
+ thePickResult.SetRayDistance (0.0);
return;
}
const Standard_Real aCosOfAngle = aFigureVec.Dot (aPickedVec) / (aPickedVecMod * aFigureVecMod);
const Standard_Real aSegPntShift = Min(aFigureVecMod, Max(0.0, aCosOfAngle * aPickedVecMod));
thePickResult.SetPickedPoint (theSegPnt1.XYZ() + aFigureVec.XYZ() * (aSegPntShift / aFigureVecMod));
+ thePickResult.SetRayDistance (thePickResult.PickedPoint().Distance (aClosestPnt) * myScale); ///
}
// =======================================================================
thePickResult.SetDepth (Abs (aDepth) * myScale);
thePickResult.SetPickedPoint (thePnt);
+ thePickResult.SetRayDistance (thePnt.Distance (myNearPickedPnt.XYZ() + myViewRayDir.XYZ() * aDepth) * myScale);
return !theClipRange.IsClipped (thePickResult.Depth());
}
{
thePickResult.SetDepth (myNearPickedPnt.Distance (aPtOnPlane) * myScale);
thePickResult.SetPickedPoint (aPtOnPlane);
+ thePickResult.SetRayDistance (0.0);
thePickResult.SetSurfaceNormal (aTriangleNormal);
return !theClipRange.IsClipped (thePickResult.Depth());
}
gp_Pnt Point; //!< 3D point
Graphic3d_Vec3 Normal; //!< surface normal or 0 vector if undefined
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 Tolerance; //!< tolerance used for selecting candidates
Standard_Integer Priority; //!< selection priority
//! Empty constructor.
SelectMgr_SortCriterion()
: Depth (0.0),
+ RayDistance(0.0),
MinDist (0.0),
Tolerance(0.0),
Priority (0),
ZLayerPosition (0),
NbOwnerMatches (0) {}
+ Standard_Real DepthWithOffset() const { return Depth + RayDistance; }
+
//! Compare with another item by depth, priority and minDist.
bool IsCloserDepth (const SelectMgr_SortCriterion& theOther) const
{
}
// closest object is selected unless difference is within tolerance
- if (Abs (Depth - theOther.Depth) > (Tolerance + theOther.Tolerance))
+ ///const Standard_Real aDepthDelta = Depth - theOther.Depth;
+ const Standard_Real aDepthDelta = DepthWithOffset() - theOther.DepthWithOffset();
+ if (Abs (aDepthDelta) > (Tolerance + theOther.Tolerance))
{
- return Depth < theOther.Depth;
+ return aDepthDelta < 0.0;
}
// if two objects have similar depth, select the one with higher priority
return false;
}
- //if (Abs (Depth - theOther.Depth) <= (Tolerance + theOther.Tolerance))
- if (Abs (Depth - theOther.Depth) <= Precision::Confusion())
+ if (Abs (Depth - theOther.Depth) <= (Tolerance + theOther.Tolerance))
{
return MinDist < theOther.MinDist;
}
aCriterion.Entity = theEntity;
aCriterion.Priority = anOwner->Priority();
aCriterion.Depth = aPickResult.Depth();
+ aCriterion.RayDistance = aPickResult.RayDistance();
aCriterion.MinDist = aPickResult.DistToGeomCenter();
if (SelectMgr_SortCriterion* aPrevCriterion = mystored.ChangeSeek (anOwner))
{
Handle(V3d_View) aCurrentView = ViewerTest::CurrentView();
Handle(V3d_Viewer) aViewer = ViewerTest::GetViewerFromContext();
- ViewerTest::GetAISContext()->MainSelector()->SetPickClosest (Standard_False);
if (aCurrentView.IsNull()
|| aViewer.IsNull())
{