From: kgv Date: Sun, 27 Sep 2020 09:42:10 +0000 (+0300) Subject: 0031798: Visualization, SelectMgr_ViewerSelector - fix comparing depth of direct... X-Git-Url: http://git.dev.opencascade.org/gitweb/?a=commitdiff_plain;h=b9513dc178fc229cd8398901920e3b1b54460d8f;p=occt-copy.git 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. --- diff --git a/src/Select3D/Select3D_SensitivePrimitiveArray.cxx b/src/Select3D/Select3D_SensitivePrimitiveArray.cxx index 96e9922087..4cc802acf6 100644 --- a/src/Select3D/Select3D_SensitivePrimitiveArray.cxx +++ b/src/Select3D/Select3D_SensitivePrimitiveArray.cxx @@ -932,7 +932,7 @@ Standard_Boolean Select3D_SensitivePrimitiveArray::Matches (SelectBasics_Selecti { myDetectedNodeMap->ChangeMap().Unite (aChild->myDetectedNodeMap->Map()); } - if (thePickResult.Depth() > aPickResult.Depth()) + if (thePickResult.DepthWithOffset() > aPickResult.DepthWithOffset()) { myDetectedIdx = aGroupIter; thePickResult = aPickResult; diff --git a/src/Select3D/Select3D_SensitiveSet.cxx b/src/Select3D/Select3D_SensitiveSet.cxx index 3c2b460b1f..69e71c65f0 100644 --- a/src/Select3D/Select3D_SensitiveSet.cxx +++ b/src/Select3D/Select3D_SensitiveSet.cxx @@ -111,6 +111,8 @@ Standard_Boolean Select3D_SensitiveSet::processElements (SelectBasics_SelectingV continue; } + //if (thePickResult.DepthWithOffset() > aPickResult.DepthWithOffset()) + //if (thePickResult.Depth() > aPickResult.Depth()) if (thePickResult.Depth() > aPickResult.Depth()) { thePickResult = aPickResult; diff --git a/src/SelectBasics/SelectBasics_PickResult.hxx b/src/SelectBasics/SelectBasics_PickResult.hxx index 32ab74a59f..6912e7bf53 100644 --- a/src/SelectBasics/SelectBasics_PickResult.hxx +++ b/src/SelectBasics/SelectBasics_PickResult.hxx @@ -35,6 +35,7 @@ public: SelectBasics_PickResult() : myObjPickedPnt (RealLast(), 0.0, 0.0), myDepth (RealLast()), + myRayDistance (0.0), myDistToCenter (RealLast()) {} //! Constructor with initialization. @@ -43,6 +44,7 @@ public: const gp_Pnt& theObjPickedPnt) : myObjPickedPnt (theObjPickedPnt), myDepth (theDepth), + myRayDistance (0.0), myDistToCenter (theDistToCenter) {} public: @@ -54,6 +56,7 @@ public: void Invalidate() { myDepth = RealLast(); + myRayDistance = 0.0; myObjPickedPnt = gp_Pnt (RealLast(), 0.0, 0.0); myNormal.SetValues (0.0f, 0.0f, 0.0f); } @@ -64,6 +67,14 @@ public: //! 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(); } @@ -97,6 +108,7 @@ private: gp_Pnt myObjPickedPnt; //!< User-picked selection point onto object NCollection_Vec3 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 }; diff --git a/src/SelectMgr/SelectMgr_RectangularFrustum.cxx b/src/SelectMgr/SelectMgr_RectangularFrustum.cxx index 17286557ad..7bcee8daa0 100644 --- a/src/SelectMgr/SelectMgr_RectangularFrustum.cxx +++ b/src/SelectMgr/SelectMgr_RectangularFrustum.cxx @@ -81,12 +81,14 @@ void SelectMgr_RectangularFrustum::segmentSegmentDistance (const gp_Pnt& theSegP || 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); /// } // ======================================================================= @@ -537,6 +539,7 @@ Standard_Boolean SelectMgr_RectangularFrustum::Overlaps (const gp_Pnt& thePnt, thePickResult.SetDepth (Abs (aDepth) * myScale); thePickResult.SetPickedPoint (thePnt); + thePickResult.SetRayDistance (thePnt.Distance (myNearPickedPnt.XYZ() + myViewRayDir.XYZ() * aDepth) * myScale); 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.SetPickedPoint (aPtOnPlane); + thePickResult.SetRayDistance (0.0); thePickResult.SetSurfaceNormal (aTriangleNormal); return !theClipRange.IsClipped (thePickResult.Depth()); } diff --git a/src/SelectMgr/SelectMgr_SortCriterion.hxx b/src/SelectMgr/SelectMgr_SortCriterion.hxx index 29fc12b303..5616b33c5f 100644 --- a/src/SelectMgr/SelectMgr_SortCriterion.hxx +++ b/src/SelectMgr/SelectMgr_SortCriterion.hxx @@ -32,6 +32,7 @@ public: 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 @@ -44,12 +45,15 @@ public: //! 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 { @@ -60,9 +64,11 @@ public: } // 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 @@ -94,8 +100,7 @@ public: 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; } diff --git a/src/SelectMgr/SelectMgr_ViewerSelector.cxx b/src/SelectMgr/SelectMgr_ViewerSelector.cxx index c1102fba7f..8a36fbd95f 100644 --- a/src/SelectMgr/SelectMgr_ViewerSelector.cxx +++ b/src/SelectMgr/SelectMgr_ViewerSelector.cxx @@ -287,6 +287,7 @@ void SelectMgr_ViewerSelector::checkOverlap (const Handle(Select3D_SensitiveEnti 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)) diff --git a/src/ViewerTest/ViewerTest_ViewerCommands.cxx b/src/ViewerTest/ViewerTest_ViewerCommands.cxx index 000537ac57..5cb578d938 100644 --- a/src/ViewerTest/ViewerTest_ViewerCommands.cxx +++ b/src/ViewerTest/ViewerTest_ViewerCommands.cxx @@ -12821,7 +12821,6 @@ static int VManipulator (Draw_Interpretor& theDi, { Handle(V3d_View) aCurrentView = ViewerTest::CurrentView(); Handle(V3d_Viewer) aViewer = ViewerTest::GetViewerFromContext(); - ViewerTest::GetAISContext()->MainSelector()->SetPickClosest (Standard_False); if (aCurrentView.IsNull() || aViewer.IsNull()) {