0030686: Visualization, SelectMgr_ViewerSelector - sorting issues of transformation...
[occt.git] / src / SelectMgr / SelectMgr_ViewerSelector.cxx
index 2d3cabf..0099563 100644 (file)
@@ -59,29 +59,61 @@ namespace {
     const SelectMgr_IndexedDataMapOfOwnerCriterion&  myMapOfCriterion;
   };
 
-  //! Compute 3d position for detected entity.
-  inline void updatePoint3d (SelectMgr_SortCriterion& theCriterion,
-                             const gp_GTrsf& theInversedTrsf,
-                             SelectMgr_SelectingVolumeManager& theMgr)
+  static const Graphic3d_Mat4d SelectMgr_ViewerSelector_THE_IDENTITY_MAT;
+}
+
+//=======================================================================
+// function : updatePoint3d
+// purpose  :
+//=======================================================================
+void SelectMgr_ViewerSelector::updatePoint3d (SelectMgr_SortCriterion& theCriterion,
+                                              const SelectBasics_PickResult& thePickResult,
+                                              const Handle(SelectBasics_SensitiveEntity)& theEntity,
+                                              const gp_GTrsf& theInversedTrsf,
+                                              const SelectMgr_SelectingVolumeManager& theMgr) const
+{
+  if (theMgr.GetActiveSelectionType() != SelectMgr_SelectingVolumeManager::Point)
   {
-    if (theMgr.GetActiveSelectionType() != SelectMgr_SelectingVolumeManager::Point)
-    {
-      return;
-    }
+    return;
+  }
 
+  if (thePickResult.HasPickedPoint())
+  {
+    theCriterion.Point = thePickResult.PickedPoint();
+  }
+  else if (!thePickResult.IsValid())
+  {
+    theCriterion.Point = thePickResult.PickedPoint();
+    return;
+  }
+  else
+  {
     theCriterion.Point = theMgr.DetectedPoint (theCriterion.Depth);
-    gp_GTrsf anInvTrsf = theInversedTrsf;
-    if (theCriterion.Entity->HasInitLocation())
-    {
-      anInvTrsf = theCriterion.Entity->InvInitLocation() * anInvTrsf;
-    }
-    if (anInvTrsf.Form() != gp_Identity)
-    {
-      anInvTrsf.Inverted().Transforms (theCriterion.Point.ChangeCoord());
-    }
   }
 
-  static const Graphic3d_Mat4d SelectMgr_ViewerSelector_THE_IDENTITY_MAT;
+  gp_GTrsf anInvTrsf = theInversedTrsf;
+  if (theCriterion.Entity->HasInitLocation())
+  {
+    anInvTrsf = theCriterion.Entity->InvInitLocation() * anInvTrsf;
+  }
+  if (anInvTrsf.Form() != gp_Identity)
+  {
+    anInvTrsf.Inverted().Transforms (theCriterion.Point.ChangeCoord());
+  }
+
+  if (mySelectingVolumeMgr.Camera().IsNull())
+  {
+    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();
+  }
 }
 
 //==================================================
@@ -91,6 +123,7 @@ namespace {
 SelectMgr_ViewerSelector::SelectMgr_ViewerSelector():
 preferclosest(Standard_True),
 myToUpdateTolerance (Standard_True),
+myCameraScale (1.0),
 myCurRank (0),
 myIsLeftChildQueuedFirst (Standard_False),
 myEntityIdx (0)
@@ -109,10 +142,13 @@ void SelectMgr_ViewerSelector::Activate (const Handle(SelectMgr_Selection)& theS
     aSelEntIter.Value()->SetActiveForSelection();
   }
 
-  theSelection->SetSelectionState (SelectMgr_SOS_Activated);
+  if (theSelection->GetSelectionState() != SelectMgr_SOS_Activated)
+  {
+    theSelection->SetSelectionState (SelectMgr_SOS_Activated);
 
-  myTolerances.Add (theSelection->Sensitivity());
-  myToUpdateTolerance = Standard_True;
+    myTolerances.Add (theSelection->Sensitivity());
+    myToUpdateTolerance = Standard_True;
+  }
 }
 
 //==================================================
@@ -126,10 +162,13 @@ void SelectMgr_ViewerSelector::Deactivate (const Handle(SelectMgr_Selection)& th
     aSelEntIter.Value()->ResetSelectionActiveStatus();
   }
 
-  theSelection->SetSelectionState (SelectMgr_SOS_Deactivated);
+  if (theSelection->GetSelectionState() == SelectMgr_SOS_Activated)
+  {
+    theSelection->SetSelectionState (SelectMgr_SOS_Deactivated);
 
-  myTolerances.Decrement (theSelection->Sensitivity());
-  myToUpdateTolerance = Standard_True;
+    myTolerances.Decrement (theSelection->Sensitivity());
+    myToUpdateTolerance = Standard_True;
+  }
 }
 
 //==================================================
@@ -177,6 +216,9 @@ void SelectMgr_ViewerSelector::checkOverlap (const Handle(SelectBasics_Sensitive
   if (!anOwner.IsNull())
   {
     aSelectable = anOwner->Selectable();
+  }
+  if (!aSelectable.IsNull())
+  {
     if (!aSelectable->ClipPlanes().IsNull()
       && aSelectable->ClipPlanes()->ToOverrideGlobal())
     {
@@ -203,9 +245,8 @@ void SelectMgr_ViewerSelector::checkOverlap (const Handle(SelectBasics_Sensitive
             continue;
           }
 
-          const Graphic3d_Vec4d& aPlaneEquation = aPlane->GetEquation();
-          const Graphic3d_Vec4d  aCheckPnt (anAnchor.X(), anAnchor.Y(), anAnchor.Z(), 1.0);
-          if (aPlaneEquation.Dot (aCheckPnt) < 0.0) // vertex is outside the half-space
+          const Graphic3d_Vec4d aCheckPnt (anAnchor.X(), anAnchor.Y(), anAnchor.Z(), 1.0);
+          if (aPlane->ProbePoint (aCheckPnt) == Graphic3d_ClipState_Out)
           {
             return;
           }
@@ -231,6 +272,7 @@ void SelectMgr_ViewerSelector::checkOverlap (const Handle(SelectBasics_Sensitive
   }
 
   if (HasDepthClipping (anOwner)
+  && !aSelectable.IsNull()
   &&  theMgr.GetActiveSelectionType() == SelectMgr_SelectingVolumeManager::Point)
   {
     Standard_Boolean isClipped = mySelectingVolumeMgr.IsClipped (*aSelectable->ClipPlanes(),
@@ -240,12 +282,11 @@ void SelectMgr_ViewerSelector::checkOverlap (const Handle(SelectBasics_Sensitive
   }
 
   SelectMgr_SortCriterion aCriterion;
-  myZLayerOrderMap.Find (aSelectable->ZLayer(), aCriterion.ZLayerPosition);
+  myZLayerOrderMap.Find (!aSelectable.IsNull() ? aSelectable->ZLayer() : Graphic3d_ZLayerId_Default, aCriterion.ZLayerPosition);
   aCriterion.Entity    = theEntity;
   aCriterion.Priority  = anOwner->Priority();
   aCriterion.Depth     = aPickResult.Depth();
   aCriterion.MinDist   = aPickResult.DistToGeomCenter();
-  aCriterion.Tolerance = theEntity->SensitivityFactor() / 33.0;
   aCriterion.ToPreferClosest = preferclosest;
 
   if (SelectMgr_SortCriterion* aPrevCriterion = mystored.ChangeSeek (anOwner))
@@ -256,7 +297,7 @@ void SelectMgr_ViewerSelector::checkOverlap (const Handle(SelectBasics_Sensitive
     {
       if (aCriterion > *aPrevCriterion)
       {
-        updatePoint3d (aCriterion, theInversedTrsf, theMgr);
+        updatePoint3d (aCriterion, aPickResult, theEntity, theInversedTrsf, theMgr);
         *aPrevCriterion = aCriterion;
       }
     }
@@ -264,7 +305,7 @@ void SelectMgr_ViewerSelector::checkOverlap (const Handle(SelectBasics_Sensitive
   else
   {
     aCriterion.NbOwnerMatches = 1;
-    updatePoint3d (aCriterion, theInversedTrsf, theMgr);
+    updatePoint3d (aCriterion, aPickResult, theEntity, theInversedTrsf, theMgr);
     mystored.Add (anOwner, aCriterion);
   }
 }
@@ -473,6 +514,17 @@ void SelectMgr_ViewerSelector::TraverseSensitives()
                                  mySelectingVolumeMgr.WorldViewMatrix(),
                                  mySelectingVolumeMgr.WorldViewProjState(),
                                  aWidth, aHeight);
+  const Handle(Graphic3d_Camera)& aCamera = mySelectingVolumeMgr.Camera();
+  if (!aCamera.IsNull())
+  {
+    myCameraEye = aCamera->Eye().XYZ();
+    myCameraDir = aCamera->Direction().XYZ();
+    myCameraScale = aCamera->IsOrthographic()
+                  ? aCamera->Scale()
+                  : 2.0 * Tan (aCamera->FOVy() * M_PI / 360.0);
+    const double aPixelSize = Max (1.0 / aWidth, 1.0 / aHeight);
+    myCameraScale *= aPixelSize;
+  }
 
   for (Standard_Integer aBVHSetIt = 0; aBVHSetIt < SelectMgr_SelectableObjectSet::BVHSubsetNb; ++aBVHSetIt)
   {
@@ -517,7 +569,6 @@ void SelectMgr_ViewerSelector::TraverseSensitives()
       aMgr = mySelectingVolumeMgr;
     }
 
-    const Handle(Graphic3d_Camera)& aCamera = mySelectingVolumeMgr.Camera();
     const Graphic3d_Mat4d& aProjectionMat   = mySelectingVolumeMgr.ProjectionMatrix();
     const Graphic3d_Mat4d& aWorldViewMat    = aBVHSubset != SelectMgr_SelectableObjectSet::BVHSubset_2dPersistent
                                             ? mySelectingVolumeMgr.WorldViewMatrix()
@@ -591,6 +642,15 @@ void SelectMgr_ViewerSelector::TraverseSensitives()
   SortResult();
 }
 
+//==================================================
+// Function: ClearPicked
+// Purpose :
+//==================================================
+void SelectMgr_ViewerSelector::ClearPicked()
+{
+  mystored.Clear();
+}
+
 //==================================================
 // Function: Picked
 // Purpose :
@@ -672,14 +732,14 @@ Standard_Boolean SelectMgr_ViewerSelector::Modes (const Handle(SelectMgr_Selecta
   Standard_Boolean hasActivatedStates = Contains (theSelectableObject);
   for (SelectMgr_SequenceOfSelection::Iterator aSelIter (theSelectableObject->Selections()); aSelIter.More(); aSelIter.Next())
   {
-      if (theWantedState == SelectMgr_SOS_Any)
-      {
-        theModeList.Append (aSelIter.Value()->Mode());
-      }
-      else if (theWantedState == aSelIter.Value()->GetSelectionState())
-      {
-        theModeList.Append (aSelIter.Value()->Mode());
-      }
+    if (theWantedState == SelectMgr_SOS_Any)
+    {
+      theModeList.Append (aSelIter.Value()->Mode());
+    }
+    else if (theWantedState == aSelIter.Value()->GetSelectionState())
+    {
+      theModeList.Append (aSelIter.Value()->Mode());
+    }
   }
 
   return hasActivatedStates;