]> OCCT Git - occt-copy.git/commitdiff
0031798: Visualization, SelectMgr_ViewerSelector - fix comparing depth of direct... CR31798_1
authorkgv <kgv@opencascade.com>
Sun, 27 Sep 2020 09:42:10 +0000 (12:42 +0300)
committerkgv <kgv@opencascade.com>
Sun, 27 Sep 2020 09:42:39 +0000 (12:42 +0300)
SelectMgr_RectangularFrustum now stores also a distance from picking Ray within SelectBasics_PickResult
to better prioritize results and prefer entities closer to ray.

src/Select3D/Select3D_SensitivePrimitiveArray.cxx
src/Select3D/Select3D_SensitiveSet.cxx
src/SelectBasics/SelectBasics_PickResult.hxx
src/SelectMgr/SelectMgr_RectangularFrustum.cxx
src/SelectMgr/SelectMgr_SortCriterion.hxx
src/SelectMgr/SelectMgr_ViewerSelector.cxx
src/ViewerTest/ViewerTest_ViewerCommands.cxx

index 96e9922087689ef5f0df89763015f8f71772fa3d..4cc802acf65887e9540367111c438a0d91d72c8e 100644 (file)
@@ -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;
index 3c2b460b1fb564272778608d744ec2d2e5f3fe29..69e71c65f0e5ba15275ecc206b1edd61a99936da 100644 (file)
@@ -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;
index 32ab74a59f7e2ee88da8e9cb66b752c80352e678..6912e7bf5325bca8560d68f9fafce0ced2e8587d 100644 (file)
@@ -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<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
 };
 
index 17286557ad8e705cba886472f6266126518237a3..7bcee8daa0b8505ea8f75c6f5a5b5b745d083eac 100644 (file)
@@ -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());
     }
index 29fc12b303aa856b440301f94875b0e4e389c582..5616b33c5f1130d4b1207f7e41df8e3653e09ba1 100644 (file)
@@ -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;
     }
index c1102fba7f54659c09902ddee5b8bc4b908d36e8..8a36fbd95f40a2e0d531da05b0ad0df4729085ea 100644 (file)
@@ -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))
index 000537ac573e11bedd88d91e82939f43b6396ac0..5cb578d9389658a1613150c12dd438aabae4fe0e 100644 (file)
@@ -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())
   {