diff --git a/src/Select3D/Select3D_SensitivePrimitiveArray.cxx b/src/Select3D/Select3D_SensitivePrimitiveArray.cxx index 8c0d0d3fdc..f4415291c2 100644 --- a/src/Select3D/Select3D_SensitivePrimitiveArray.cxx +++ b/src/Select3D/Select3D_SensitivePrimitiveArray.cxx @@ -931,7 +931,7 @@ Standard_Boolean Select3D_SensitivePrimitiveArray::Matches (SelectBasics_Selecti { myDetectedNodeMap->ChangeMap().Unite (aChild->myDetectedNodeMap->Map()); } - if (thePickResult.Depth() > aPickResult.Depth()) + if (thePickResult.Depth() > aPickResult.Depth() && thePickResult.IsDirectHit()) { myDetectedIdx = aGroupIter; thePickResult = aPickResult; diff --git a/src/Select3D/Select3D_SensitiveSet.cxx b/src/Select3D/Select3D_SensitiveSet.cxx index 5c737cc025..a8f4376be1 100644 --- a/src/Select3D/Select3D_SensitiveSet.cxx +++ b/src/Select3D/Select3D_SensitiveSet.cxx @@ -111,7 +111,7 @@ Standard_Boolean Select3D_SensitiveSet::processElements (SelectBasics_SelectingV continue; } - if (thePickResult.Depth() > aPickResult.Depth()) + if ((thePickResult.Depth() > aPickResult.Depth()) && (aPickResult.IsDirectHit())) { thePickResult = aPickResult; myDetectedIdx = anIdx; diff --git a/src/SelectBasics/SelectBasics_PickResult.hxx b/src/SelectBasics/SelectBasics_PickResult.hxx index 32ab74a59f..8fdf40634f 100644 --- a/src/SelectBasics/SelectBasics_PickResult.hxx +++ b/src/SelectBasics/SelectBasics_PickResult.hxx @@ -35,7 +35,8 @@ public: SelectBasics_PickResult() : myObjPickedPnt (RealLast(), 0.0, 0.0), myDepth (RealLast()), - myDistToCenter (RealLast()) {} + myDistToCenter (RealLast()), + myIsDirectHit(Standard_False) {} //! Constructor with initialization. SelectBasics_PickResult (Standard_Real theDepth, @@ -43,7 +44,8 @@ public: const gp_Pnt& theObjPickedPnt) : myObjPickedPnt (theObjPickedPnt), myDepth (theDepth), - myDistToCenter (theDistToCenter) {} + myDistToCenter (theDistToCenter), + myIsDirectHit(Standard_False) {} public: @@ -56,6 +58,7 @@ public: myDepth = RealLast(); myObjPickedPnt = gp_Pnt (RealLast(), 0.0, 0.0); myNormal.SetValues (0.0f, 0.0f, 0.0f); + myIsDirectHit = Standard_False; } //! Return depth along picking ray. @@ -93,11 +96,18 @@ public: myNormal.SetValues ((float )theNormal.X(), (float )theNormal.Y(), (float )theNormal.Z()); } + //! Set boolean value for pick result direct hit (true) or indirect hit (false) + void SetDirectHit(Standard_Boolean theIsDirectHit) { myIsDirectHit = theIsDirectHit; } + + //! Return value for direct hit test + Standard_Boolean IsDirectHit() const { return myIsDirectHit; } + private: gp_Pnt myObjPickedPnt; //!< User-picked selection point onto object NCollection_Vec3 myNormal; //!< surface normal Standard_Real myDepth; //!< Depth to detected point Standard_Real myDistToCenter; //!< Distance from 3d projection user-picked selection point to entity's geometry center + Standard_Boolean myIsDirectHit; //!< Checks if the detected point was obtained from a direct hit }; #endif // _SelectBasics_PickResult_HeaderFile diff --git a/src/SelectMgr/SelectMgr_RectangularFrustum.cxx b/src/SelectMgr/SelectMgr_RectangularFrustum.cxx index 9c4c52e9fe..7b328900ca 100644 --- a/src/SelectMgr/SelectMgr_RectangularFrustum.cxx +++ b/src/SelectMgr/SelectMgr_RectangularFrustum.cxx @@ -84,8 +84,7 @@ void SelectMgr_RectangularFrustum::segmentSegmentDistance (const gp_Pnt& theSegP aTc = (Abs (aTd) < gp::Resolution() ? 0.0 : aTn / aTd); const gp_Pnt aClosestPnt = myNearPickedPnt.XYZ() + aV * aTc; - Standard_Real aPenalty = Max(aC/anA, anA/aC); - thePickResult.SetDepth (myNearPickedPnt.Distance (aClosestPnt) * myScale * aPenalty); + thePickResult.SetDepth (myNearPickedPnt.Distance (aClosestPnt) * myScale); const gp_Vec aPickedVec = aClosestPnt.XYZ() - theSegPnt1.XYZ(); const gp_Vec aFigureVec = theSegPnt2.XYZ() - theSegPnt1.XYZ(); @@ -504,6 +503,7 @@ Standard_Boolean SelectMgr_RectangularFrustum::OverlapsBox (const SelectMgr_Vec3 aDepth = aNearestPnt.Distance (myNearPickedPnt); thePickResult.SetDepth (aDepth); + thePickResult.SetDirectHit(Standard_False); return !theClipRange.IsClipped (thePickResult.Depth()); } @@ -516,6 +516,7 @@ Standard_Boolean SelectMgr_RectangularFrustum::OverlapsBox (const SelectMgr_Vec3 } thePickResult.SetDepth (aDepth); + thePickResult.SetDirectHit(Standard_True); return Standard_True; } @@ -539,6 +540,7 @@ Standard_Boolean SelectMgr_RectangularFrustum::OverlapsPoint (const gp_Pnt& theP thePickResult.SetDepth (Abs (aDepth) * myScale); thePickResult.SetPickedPoint (thePnt); + thePickResult.SetDirectHit(Standard_True); return !theClipRange.IsClipped (thePickResult.Depth()); } @@ -571,6 +573,7 @@ Standard_Boolean SelectMgr_RectangularFrustum::OverlapsSegment (const gp_Pnt& th return Standard_False; segmentSegmentDistance (thePnt1, thePnt2, thePickResult); + thePickResult.SetDirectHit(Standard_True); return !theClipRange.IsClipped (thePickResult.Depth()); } @@ -606,6 +609,7 @@ Standard_Boolean SelectMgr_RectangularFrustum::OverlapsPolygon (const TColgp_Arr aMatchingSegmentsNb++; segmentSegmentDistance (aStartPnt, aEndPnt, aPickResult); thePickResult = SelectBasics_PickResult::Min (thePickResult, aPickResult); + thePickResult.SetDirectHit(Standard_True); } } @@ -711,9 +715,10 @@ Standard_Boolean SelectMgr_RectangularFrustum::OverlapsTriangle (const gp_Pnt& t thePickResult.SetDepth (myNearPickedPnt.Distance (aPtOnPlane) * myScale); thePickResult.SetPickedPoint (aPtOnPlane); thePickResult.SetSurfaceNormal (aTriangleNormal); + thePickResult.SetDirectHit(Standard_True); return !theClipRange.IsClipped (thePickResult.Depth()); } - + Standard_Real aMinDist = RealLast(); Standard_Integer aNearestEdgeIdx1 = -1; for (Standard_Integer anEdgeIdx = 0; anEdgeIdx < 3; ++anEdgeIdx) @@ -736,6 +741,7 @@ Standard_Boolean SelectMgr_RectangularFrustum::OverlapsTriangle (const gp_Pnt& t } thePickResult.SetSurfaceNormal (aTriangleNormal); segmentSegmentDistance (aPnts[aNearestEdgeIdx1], aPnts[aNearestEdgeIdx2], thePickResult); + thePickResult.SetDirectHit(Standard_False); } return !theClipRange.IsClipped (thePickResult.Depth()); @@ -786,6 +792,7 @@ Standard_Boolean SelectMgr_RectangularFrustum::OverlapsCylinder (const Standard_ thePickResult.SetSurfaceNormal (gp_Vec (aPntOnCylinder.X(), aPntOnCylinder.Y(), 0.0).Transformed (theTrsf)); } thePickResult.SetPickedPoint (aPntOnCylinder.Transformed (theTrsf)); + thePickResult.SetDirectHit(Standard_True); return !theClipRange.IsClipped (thePickResult.Depth()); } @@ -822,6 +829,7 @@ Standard_Boolean SelectMgr_RectangularFrustum::OverlapsCircle (const Standard_Re } thePickResult.SetDepth (aTime * myScale); + thePickResult.SetDirectHit(Standard_True); if (theClipRange.IsClipped (thePickResult.Depth())) { thePickResult.SetDepth (aTime * myScale); @@ -1011,6 +1019,7 @@ Standard_Boolean SelectMgr_RectangularFrustum::OverlapsSphere (const gp_Pnt& the } thePickResult.SetDepth (aTimeEnter * myScale); + thePickResult.SetDirectHit(Standard_True); if (theClipRange.IsClipped (thePickResult.Depth())) { thePickResult.SetDepth (aTimeLeave * myScale);