0031701: Visualization, SelectMgr_ViewerSelector - make depth tolerance configurable
[occt.git] / src / SelectMgr / SelectMgr_ViewerSelector.cxx
index 9de4105..c1102fb 100644 (file)
@@ -42,18 +42,28 @@ namespace
   {
   public:
 
-    CompareResults (const SelectMgr_IndexedDataMapOfOwnerCriterion& theMapOfCriterion)
-    : myMapOfCriterion (&theMapOfCriterion)
-    {
-    }
+    CompareResults (const SelectMgr_IndexedDataMapOfOwnerCriterion& theMapOfCriterion,
+                    bool theToPreferClosest)
+    : myMapOfCriterion (&theMapOfCriterion),
+      myToPreferClosest (theToPreferClosest) {}
 
     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:
     const SelectMgr_IndexedDataMapOfOwnerCriterion* myMapOfCriterion;
+    bool myToPreferClosest;
   };
 
   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;
-  }
-  else if (mySelectingVolumeMgr.Camera()->IsOrthographic())
-  {
-    theCriterion.Tolerance = myCameraScale * theEntity->SensitivityFactor();
-  }
-  else
-  {
-    const Standard_Real aDistFromEye = Abs ((theCriterion.Point.XYZ() - myCameraEye.XYZ()).Dot (myCameraDir.XYZ()));
-    theCriterion.Tolerance = aDistFromEye * myCameraScale * theEntity->SensitivityFactor();
+    case SelectMgr_TypeOfDepthTolerance_Uniform:
+    {
+      theCriterion.Tolerance = myDepthTolerance;
+      break;
+    }
+    case SelectMgr_TypeOfDepthTolerance_UniformPixels:
+    case SelectMgr_TypeOfDepthTolerance_SensitivityFactor:
+    {
+      if (mySelectingVolumeMgr.Camera().IsNull())
+      {
+        // 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
 // Purpose :
 //==================================================
-SelectMgr_ViewerSelector::SelectMgr_ViewerSelector():
-preferclosest(Standard_True),
-myToUpdateTolerance (Standard_True),
-myCameraScale (1.0),
-myToPrebuildBVH (Standard_False),
-myCurRank (0),
-myIsLeftChildQueuedFirst (Standard_False),
-myEntityIdx (0)
+SelectMgr_ViewerSelector::SelectMgr_ViewerSelector()
+: myDepthTolerance (0.0),
+  myDepthTolType (SelectMgr_TypeOfDepthTolerance_SensitivityFactor),
+  myToPreferClosest (Standard_True),
+  myToUpdateTolerance (Standard_True),
+  myCameraScale (1.0),
+  myToPrebuildBVH (Standard_False),
+  myCurRank (0),
+  myIsLeftChildQueuedFirst (Standard_False)
 {
   myEntitySetBuilder = new BVH_BinnedBuilder<Standard_Real, 3, 4> (BVH_Constants_LeafNodeSizeSingle, BVH_Constants_MaxTreeDepth, Standard_True);
 }
@@ -262,7 +288,6 @@ void SelectMgr_ViewerSelector::checkOverlap (const Handle(Select3D_SensitiveEnti
   aCriterion.Priority  = anOwner->Priority();
   aCriterion.Depth     = aPickResult.Depth();
   aCriterion.MinDist   = aPickResult.DistToGeomCenter();
-  aCriterion.ToPreferClosest = preferclosest;
 
   if (SelectMgr_SortCriterion* aPrevCriterion = mystored.ChangeSeek (anOwner))
   {
@@ -270,7 +295,7 @@ void SelectMgr_ViewerSelector::checkOverlap (const Handle(Select3D_SensitiveEnti
     aCriterion.NbOwnerMatches = aPrevCriterion->NbOwnerMatches;
     if (theMgr.GetActiveSelectionType() != SelectBasics_SelectingVolumeManager::Box)
     {
-      if (aCriterion > *aPrevCriterion)
+      if (aCriterion.IsCloserDepth (*aPrevCriterion))
       {
         updatePoint3d (aCriterion, aPickResult, theEntity, theInversedTrsf, theMgr);
         *aPrevCriterion = aCriterion;
@@ -887,28 +912,27 @@ TCollection_AsciiString SelectMgr_ViewerSelector::Status (const Handle(SelectMgr
 
 //=======================================================================
 //function : SortResult
-//purpose  :  there is a certain number of entities ranged by criteria
-//            (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
+//purpose  :
 //=======================================================================
 void SelectMgr_ViewerSelector::SortResult()
 {
-  if(mystored.IsEmpty()) return;
+  if (mystored.IsEmpty())
+  {
+    return;
+  }
 
   const Standard_Integer anExtent = mystored.Extent();
-  if(myIndexes.IsNull() || anExtent != myIndexes->Length())
+  if (myIndexes.IsNull() || anExtent != myIndexes->Length())
+  {
     myIndexes = new TColStd_HArray1OfInteger (1, anExtent);
+  }
 
   TColStd_Array1OfInteger& anIndexArray = myIndexes->ChangeArray1();
   for (Standard_Integer anIndexIter = 1; anIndexIter <= anExtent; ++anIndexIter)
   {
     anIndexArray.SetValue (anIndexIter, anIndexIter);
   }
-  std::sort (anIndexArray.begin(), anIndexArray.end(), CompareResults (mystored));
+  std::sort (anIndexArray.begin(), anIndexArray.end(), CompareResults (mystored, myToPreferClosest));
 }
 
 //=======================================================================
@@ -1094,7 +1118,7 @@ void SelectMgr_ViewerSelector::DumpJson (Standard_OStream& theOStream, Standard_
 {
   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, mystored.Extent())
 
@@ -1122,7 +1146,6 @@ void SelectMgr_ViewerSelector::DumpJson (Standard_OStream& theOStream, Standard_
 
   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myCurRank)
   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myIsLeftChildQueuedFirst)
-  OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myEntityIdx)
   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myMapOfObjectSensitives.Extent())
 }