0027797: Visualization - consider ZLayer properties while sorting list of picked...
authorkgv <kgv@opencascade.com>
Tue, 23 Aug 2016 14:26:22 +0000 (17:26 +0300)
committerbugmaster <bugmaster@opencascade.com>
Thu, 25 Aug 2016 12:10:50 +0000 (15:10 +0300)
OpenGl_GraphicDriver::ZLayers() / V3d_Viewer::GetAllZLayers() now return
the layers sequence following rendering order (taking into account IsImmediate flag).

StdSelect_ViewerSelector3d::Pick() now sort result taking into account ZLayers flags.

src/OpenGl/OpenGl_GraphicDriver.cxx
src/OpenGl/OpenGl_GraphicDriver.hxx
src/SelectMgr/FILES
src/SelectMgr/SelectMgr_SortCriterion.cxx [deleted file]
src/SelectMgr/SelectMgr_SortCriterion.hxx
src/SelectMgr/SelectMgr_SortCriterion.lxx [deleted file]
src/SelectMgr/SelectMgr_ViewerSelector.cxx
src/SelectMgr/SelectMgr_ViewerSelector.hxx
src/StdSelect/StdSelect_ViewerSelector3d.cxx
src/StdSelect/StdSelect_ViewerSelector3d.hxx
tests/bugs/vis/bug27797 [new file with mode: 0644]

index 819f0b3..1c1081b 100644 (file)
@@ -489,6 +489,50 @@ void OpenGl_GraphicDriver::TextSize (const Handle(Graphic3d_CView)& theView,
 }
 
 //=======================================================================
+//function : addZLayerIndex
+//purpose  :
+//=======================================================================
+void OpenGl_GraphicDriver::addZLayerIndex (const Graphic3d_ZLayerId theLayerId)
+{
+  // remove index
+  for (TColStd_SequenceOfInteger::Iterator aLayerIt (myLayerSeq); aLayerIt.More(); aLayerIt.Next())
+  {
+    if (aLayerIt.Value() == theLayerId)
+    {
+      myLayerSeq.Remove (aLayerIt);
+      break;
+    }
+  }
+
+  if (myMapOfZLayerSettings.Find (theLayerId).IsImmediate)
+  {
+    myLayerSeq.Append (theLayerId);
+    return;
+  }
+
+  for (TColStd_SequenceOfInteger::Iterator aLayerIt (myLayerSeq); aLayerIt.More(); aLayerIt.Next())
+  {
+    const Graphic3d_ZLayerSettings& aSettings = myMapOfZLayerSettings.Find (aLayerIt.Value());
+    if (aSettings.IsImmediate)
+    {
+      aLayerIt.Previous();
+      if (aLayerIt.More())
+      {
+        myLayerSeq.InsertAfter (aLayerIt, theLayerId);
+        return;
+      }
+
+      // first non-immediate layer
+      myLayerSeq.Prepend (theLayerId);
+      return;
+    }
+  }
+
+  // no immediate layers
+  myLayerSeq.Append (theLayerId);
+}
+
+//=======================================================================
 //function : AddZLayer
 //purpose  :
 //=======================================================================
@@ -501,11 +545,11 @@ void OpenGl_GraphicDriver::AddZLayer (const Graphic3d_ZLayerId theLayerId)
                            "negative and zero IDs are reserved");
   }
 
-  myLayerIds.Add    (theLayerId);
-  myLayerSeq.Append (theLayerId);
+  myLayerIds.Add (theLayerId);
 
   // Default z-layer settings
   myMapOfZLayerSettings.Bind (theLayerId, Graphic3d_ZLayerSettings());
+  addZLayerIndex (theLayerId);
 
   // Add layer to all views
   NCollection_Map<Handle(OpenGl_View)>::Iterator aViewIt (myMapOfView);
@@ -547,11 +591,11 @@ void OpenGl_GraphicDriver::RemoveZLayer (const Graphic3d_ZLayerId theLayerId)
   }
 
   // Remove index
-  for (int aIdx = 1; aIdx <= myLayerSeq.Length (); aIdx++)
+  for (TColStd_SequenceOfInteger::Iterator aLayerIt (myLayerSeq); aLayerIt.More(); aLayerIt.Next())
   {
-    if (myLayerSeq (aIdx) == theLayerId)
+    if (aLayerIt.Value() == theLayerId)
     {
-      myLayerSeq.Remove (aIdx);
+      myLayerSeq.Remove (aLayerIt);
       break;
     }
   }
@@ -583,13 +627,21 @@ void OpenGl_GraphicDriver::SetZLayerSettings (const Graphic3d_ZLayerId theLayerI
     aViewIt.Value()->SetZLayerSettings (theLayerId, theSettings);
   }
 
-  if (myMapOfZLayerSettings.IsBound (theLayerId))
+  Graphic3d_ZLayerSettings* aSettings = myMapOfZLayerSettings.ChangeSeek (theLayerId);
+  if (aSettings != NULL)
   {
-    myMapOfZLayerSettings.ChangeFind (theLayerId) = theSettings;
+    const bool isChanged = (aSettings->IsImmediate != theSettings.IsImmediate);
+    *aSettings = theSettings;
+    if (isChanged)
+    {
+      addZLayerIndex (theLayerId);
+    }
   }
   else
   {
+    // abnormal case
     myMapOfZLayerSettings.Bind (theLayerId, theSettings);
+    addZLayerIndex (theLayerId);
   }
 }
 
index ad82536..b0e5a00 100644 (file)
@@ -201,6 +201,9 @@ public:
   void*                   getRawGlConfig()  const { return myEglConfig; }
 #endif
 
+  //! Insert index layer at proper position.
+  Standard_EXPORT void addZLayerIndex (const Graphic3d_ZLayerId theLayerId);
+
 public:
 
   DEFINE_STANDARD_RTTIEXT(OpenGl_GraphicDriver,Graphic3d_GraphicDriver)
index d91a639..328bad3 100755 (executable)
@@ -47,9 +47,7 @@ SelectMgr_SequenceOfOwner.hxx
 SelectMgr_SequenceOfSelection.hxx
 SelectMgr_SequenceOfSelector.hxx
 SelectMgr_SOPtr.hxx
-SelectMgr_SortCriterion.cxx
 SelectMgr_SortCriterion.hxx
-SelectMgr_SortCriterion.lxx
 SelectMgr_StateOfSelection.hxx
 SelectMgr_TriangularFrustum.cxx
 SelectMgr_TriangularFrustum.hxx
diff --git a/src/SelectMgr/SelectMgr_SortCriterion.cxx b/src/SelectMgr/SelectMgr_SortCriterion.cxx
deleted file mode 100644 (file)
index b682d55..0000000
+++ /dev/null
@@ -1,104 +0,0 @@
-// Created on: 1998-03-26
-// Created by: Robert COUBLANC
-// Copyright (c) 1998-1999 Matra Datavision
-// Copyright (c) 1999-2014 OPEN CASCADE SAS
-//
-// This file is part of Open CASCADE Technology software library.
-//
-// This library is free software; you can redistribute it and/or modify it under
-// the terms of the GNU Lesser General Public License version 2.1 as published
-// by the Free Software Foundation, with special exception defined in the file
-// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
-// distribution for complete text of the license and disclaimer of any warranty.
-//
-// Alternatively, this file may be used under the terms of Open CASCADE
-// commercial license or contractual agreement.
-
-
-#include <Precision.hxx>
-#include <SelectMgr_SortCriterion.hxx>
-
-//=======================================================================
-//function : SelectMgr_SortCriterion
-//purpose  : Empty constructor
-//=======================================================================
-SelectMgr_SortCriterion::SelectMgr_SortCriterion()
-     : myPrior  (0),
-       myDepth  (0.0),
-       myDist   (0.0),
-       myTol    (0.0),
-       myPreferClosest(Standard_True)
-{}
-
-//=======================================================================
-//function : SelectMgr_SortCriterion
-//purpose  : Constructor
-//=======================================================================
-
-SelectMgr_SortCriterion::SelectMgr_SortCriterion(const Standard_Integer Prior,
-                                                 const Standard_Real Depth,
-                                                 const Standard_Real Dist,
-                                                 const Standard_Real Tol,
-                                                 const Standard_Boolean PreferClosest)
-     : myPrior  (Prior),
-       myDepth  (Depth),
-       myDist   (Dist),
-       myTol    (Tol),
-       myPreferClosest(PreferClosest)
-{}
-
-//=======================================================================
-//function : IsGreater
-//purpose  :  priorite d'abor, puis profondeur + distance...
-//=======================================================================
-Standard_Boolean SelectMgr_SortCriterion::IsGreater
-                                (const SelectMgr_SortCriterion& SC) const
-{
-  if ( myPreferClosest )
-  {
-    // closest object is selected unless difference is within tolerance
-    if ( Abs (myDepth - SC.Depth()) > myTol + SC.Tol() )
-      return myDepth < SC.Depth();
-
-    // if two objects have similar depth, select the one with higher 
-    // priority or, if priorities are equal, one closest to the mouse
-    return myPrior > SC.Priority() ? Standard_True :
-           myPrior < SC.Priority() ? Standard_False :
-           myDist < SC.MinDist();
-  }
-
-  // old logic (OCCT version <= 6.3.1)
-  if(myPrior>SC.Priority()) return Standard_True;
-  if(myPrior<SC.Priority()) return Standard_False;
-  if(Abs(myDepth-SC.Depth())<=Precision::Confusion())
-    return myDist < SC.MinDist();
-  return (myDepth < SC.Depth() );
-}
-
-//=======================================================================
-//function : IsLower
-//purpose  : On n'utilise que les criteres de profondeur et de priorite...
-//=======================================================================
-Standard_Boolean SelectMgr_SortCriterion::IsLower
-                                (const SelectMgr_SortCriterion& SC) const
-{
-  if ( myPreferClosest )
-  {
-    // closest object is selected unless difference is within tolerance
-    if ( myPreferClosest && Abs (myDepth - SC.Depth()) > myTol + SC.Tol() )
-      return myDepth > SC.Depth();
-
-    // if two objects have similar depth, select the one with higher 
-    // priority or, if priorities are equal, one closest to the mouse
-    return myPrior < SC.Priority() ? Standard_True :
-           myPrior > SC.Priority() ? Standard_False :
-           myDist > SC.MinDist();
-  }
-
-  // old logic (OCCT version <= 6.3.1)
-  if(myPrior>SC.Priority()) return Standard_False;
-  if(myPrior<SC.Priority()) return Standard_True;
-  if(Abs(myDepth-SC.Depth())<=Precision::Confusion())
-    return myDist > SC.MinDist();
-  return (myDepth > SC.Depth() );
-}
index 48e12a1..70a924a 100644 (file)
 #ifndef _SelectMgr_SortCriterion_HeaderFile
 #define _SelectMgr_SortCriterion_HeaderFile
 
+#include <Graphic3d_ZLayerId.hxx>
+#include <Precision.hxx>
 #include <Standard.hxx>
+#include <Standard_Boolean.hxx>
 #include <Standard_DefineAlloc.hxx>
 #include <Standard_Handle.hxx>
-
 #include <Standard_Integer.hxx>
 #include <Standard_Real.hxx>
-#include <Standard_Boolean.hxx>
-
 
 //! This class provides data and criterion for sorting candidate
 //! entities in the process of interactive selection by mouse click
@@ -32,75 +32,124 @@ class SelectMgr_SortCriterion
 {
 public:
 
-  DEFINE_STANDARD_ALLOC
-
-  
-  Standard_EXPORT SelectMgr_SortCriterion();
-  
-  //! Defines parameters of selection criterion:
-  //! - Priority: selection priority
-  //! - Depth: distance from the view plane to the entity
-  //! - MinDist: distance from the clicked point to the entity on the view plane
-  //! - Tol: tolerance used for selecting candidates
-  //! - PreferClosest: specify whether closest object is preferred even if
-  //! if has less priority
-  Standard_EXPORT SelectMgr_SortCriterion(const Standard_Integer thePriority, const Standard_Real theDepth, const Standard_Real theMinDist, const Standard_Real theTol, const Standard_Boolean PreferClosest);
-  
-    void SetPriority (const Standard_Integer P);
-  
-    void SetDepth (const Standard_Real D);
-  
-    void SetMinDist (const Standard_Real D);
-  
-    void SetTol (const Standard_Real T);
-  
-    Standard_Integer Priority() const;
-  
-    Standard_Real Depth() const;
-  
-    Standard_Real MinDist() const;
-  
-    Standard_Real Tol() const;
-  
-  Standard_EXPORT Standard_Boolean IsGreater (const SelectMgr_SortCriterion& anOtherCriterion) const;
-Standard_Boolean operator > (const SelectMgr_SortCriterion& anOtherCriterion) const
-{
-  return IsGreater(anOtherCriterion);
-}
-  
-  Standard_EXPORT Standard_Boolean IsLower (const SelectMgr_SortCriterion& anOtherCriterion) const;
-Standard_Boolean operator < (const SelectMgr_SortCriterion& anOtherCriterion) const
-{
-  return IsLower(anOtherCriterion);
-}
-
-
-
-
-protected:
-
-
+  Standard_Real      Depth;           //!< distance from the view plane to the entity
+  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
+  Standard_Integer   ZLayerPosition;  //!< ZLayer rendering order index, stronger than a depth
+  Standard_Boolean   ToPreferClosest; //!< whether closest object is preferred even if has less priority
 
+public:
+  DEFINE_STANDARD_ALLOC
 
-
-private:
-
-
-
-  Standard_Integer myPrior;
-  Standard_Real myDepth;
-  Standard_Real myDist;
-  Standard_Real myTol;
-  Standard_Boolean myPreferClosest;
-
+  //! Empty constructor.
+  SelectMgr_SortCriterion()
+  : Depth    (0.0),
+    MinDist  (0.0),
+    Tolerance(0.0),
+    Priority (0),
+    ZLayerPosition  (0),
+    ToPreferClosest (Standard_True) {}
+
+  //! Comparison operator.
+  bool operator> (const SelectMgr_SortCriterion& theOther) const { return IsGreater (theOther); }
+
+  //! Comparison operator.
+  bool operator< (const SelectMgr_SortCriterion& theOther) const { return IsLower   (theOther); }
+
+  //! Compare with another item.
+  bool IsGreater (const SelectMgr_SortCriterion& theOther) const
+  {
+    // the object within different ZLayer groups can not be compared by depth
+    if (ZLayerPosition != theOther.ZLayerPosition)
+    {
+      return ZLayerPosition > theOther.ZLayerPosition;
+    }
+
+    if (ToPreferClosest)
+    {
+      // closest object is selected unless difference is within tolerance
+      if (Abs (Depth - theOther.Depth) > (Tolerance + theOther.Tolerance))
+      {
+        return Depth < theOther.Depth;
+      }
+
+      // if two objects have similar depth, select the one with higher priority
+      if (Priority > theOther.Priority)
+      {
+        return true;
+      }
+
+      // if priorities are equal, one closest to the mouse
+      return Priority == theOther.Priority
+          && MinDist  <  theOther.MinDist;
+    }
+
+    // old logic (OCCT version <= 6.3.1)
+    if (Priority > theOther.Priority)
+    {
+      return true;
+    }
+    else if (Priority != theOther.Priority)
+    {
+      return false;
+    }
+
+    if (Abs (Depth - theOther.Depth) <= Precision::Confusion())
+    {
+      return MinDist < theOther.MinDist;
+    }
+
+    return Depth < theOther.Depth;
+  }
+
+  //! Compare with another item.
+  bool IsLower (const SelectMgr_SortCriterion& theOther) const
+  {
+    // the object within different ZLayer groups can not be compared by depth
+    if (ZLayerPosition != theOther.ZLayerPosition)
+    {
+      return ZLayerPosition < theOther.ZLayerPosition;
+    }
+
+    if (ToPreferClosest)
+    {
+      // closest object is selected unless difference is within tolerance
+      if (ToPreferClosest
+       && Abs (Depth - theOther.Depth) > (Tolerance + theOther.Tolerance))
+      {
+        return Depth > theOther.Depth;
+      }
+
+      // if two objects have similar depth, select the one with higher priority
+      if (Priority < theOther.Priority)
+      {
+        return true;
+      }
+
+      // if priorities are equal, one closest to the mouse
+      return Priority == theOther.Priority
+          && MinDist  >  theOther.MinDist;
+    }
+
+    // old logic (OCCT version <= 6.3.1)
+    if (Priority > theOther.Priority)
+    {
+      return false;
+    }
+    else if (Priority != theOther.Priority)
+    {
+      return true;
+    }
+
+    if (Abs (Depth - theOther.Depth) <= Precision::Confusion())
+    {
+      return MinDist > theOther.MinDist;
+    }
+
+    return Depth > theOther.Depth;
+  }
 
 };
 
-
-#include <SelectMgr_SortCriterion.lxx>
-
-
-
-
-
 #endif // _SelectMgr_SortCriterion_HeaderFile
diff --git a/src/SelectMgr/SelectMgr_SortCriterion.lxx b/src/SelectMgr/SelectMgr_SortCriterion.lxx
deleted file mode 100644 (file)
index 1ab9716..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-// Created on: 1998-03-26
-// Created by: Robert COUBLANC
-// Copyright (c) 1998-1999 Matra Datavision
-// Copyright (c) 1999-2014 OPEN CASCADE SAS
-//
-// This file is part of Open CASCADE Technology software library.
-//
-// This library is free software; you can redistribute it and/or modify it under
-// the terms of the GNU Lesser General Public License version 2.1 as published
-// by the Free Software Foundation, with special exception defined in the file
-// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
-// distribution for complete text of the license and disclaimer of any warranty.
-//
-// Alternatively, this file may be used under the terms of Open CASCADE
-// commercial license or contractual agreement.
-
-inline void SelectMgr_SortCriterion::SetPriority(const Standard_Integer Prior)
-{myPrior = Prior;}
-
-inline void SelectMgr_SortCriterion::SetDepth(const Standard_Real Depth)
-{myDepth = Depth;}
-
-inline void SelectMgr_SortCriterion::SetMinDist(const Standard_Real Dist)  
-{myDist=Dist;}
-
-inline void SelectMgr_SortCriterion::SetTol(const Standard_Real Tol)  
-{myTol=Tol;}
-
-inline Standard_Integer SelectMgr_SortCriterion::Priority() const
-{return myPrior;}
-
-inline Standard_Real SelectMgr_SortCriterion::Depth() const
-{return myDepth;}
-
-inline Standard_Real SelectMgr_SortCriterion::MinDist() const
-{return myDist;}
-
-inline Standard_Real SelectMgr_SortCriterion::Tol() const
-{return myTol;}
index 9bb2816..16e34cc 100644 (file)
@@ -229,17 +229,22 @@ void SelectMgr_ViewerSelector::checkOverlap (const Handle(SelectBasics_Sensitive
   {
     if (!anOwner.IsNull())
     {
+      Handle(SelectMgr_SelectableObject) aSelectable = anOwner->Selectable();
       if (HasDepthClipping (anOwner) && theMgr.GetActiveSelectionType() == SelectMgr_SelectingVolumeManager::Point)
       {
-        Standard_Boolean isClipped = mySelectingVolumeMgr.IsClipped (anOwner->Selectable()->GetClipPlanes(),
+        Standard_Boolean isClipped = mySelectingVolumeMgr.IsClipped (aSelectable->GetClipPlanes(),
                                                                      aPickResult.Depth());
         if (isClipped)
           return;
       }
 
-      Standard_Integer aPriority = anOwner->Priority();
-
-      SelectMgr_SortCriterion aCriterion (aPriority, aPickResult.Depth(), aPickResult.DistToGeomCenter(), theEntity->SensitivityFactor() / 33.0, preferclosest);
+      SelectMgr_SortCriterion aCriterion;
+      myZLayerOrderMap.Find (aSelectable->ZLayer(), aCriterion.ZLayerPosition);
+      aCriterion.Priority  = anOwner->Priority();
+      aCriterion.Depth     = aPickResult.Depth();
+      aCriterion.MinDist   = aPickResult.DistToGeomCenter();
+      aCriterion.Tolerance = theEntity->SensitivityFactor() / 33.0;
+      aCriterion.ToPreferClosest = preferclosest;
       if (mystored.Contains (anOwner))
       {
         if (theMgr.GetActiveSelectionType() != 1)
index f889297..cdb1064 100644 (file)
@@ -328,6 +328,7 @@ protected:
   mutable SelectMgr_SelectableObjectSet         mySelectableObjects;
   mutable SelectMgr_SelectableObjectTrsfPersSet mySelectableObjectsTrsfPers;
   SelectMgr_ToleranceMap                        myTolerances;
+  NCollection_DataMap<Graphic3d_ZLayerId, Standard_Integer> myZLayerOrderMap;
 
 private:
 
index b2f122c..b42474d 100644 (file)
@@ -113,6 +113,7 @@ void StdSelect_ViewerSelector3d::Pick (const Standard_Integer theXPix,
                                        const Standard_Integer theYPix,
                                        const Handle(V3d_View)& theView)
 {
+  updateZLayers (theView);
   if(myToUpdateTolerance)
   {
     mySelectingVolumeMgr.SetPixelTolerance (myTolerances.Tolerance());
@@ -142,6 +143,7 @@ void StdSelect_ViewerSelector3d::Pick (const Standard_Integer theXPMin,
                                        const Standard_Integer theYPMax,
                                        const Handle(V3d_View)& theView)
 {
+  updateZLayers (theView);
   mySelectingVolumeMgr.SetCamera (theView->Camera());
   mySelectingVolumeMgr.SetActiveSelectionType (SelectMgr_SelectingVolumeManager::Box);
   Standard_Integer aWidth = 0, aHeight = 0;
@@ -164,6 +166,7 @@ void StdSelect_ViewerSelector3d::Pick (const Standard_Integer theXPMin,
 void StdSelect_ViewerSelector3d::Pick (const TColgp_Array1OfPnt2d& thePolyline,
                                        const Handle(V3d_View)& theView)
 {
+  updateZLayers (theView);
   mySelectingVolumeMgr.SetCamera (theView->Camera());
   mySelectingVolumeMgr.SetActiveSelectionType (SelectMgr_SelectingVolumeManager::Polyline);
   Standard_Integer aWidth = 0, aHeight = 0;
@@ -190,7 +193,7 @@ void StdSelect_ViewerSelector3d::DisplaySensitive (const Handle(V3d_View)& theVi
     {
       if (anObj->CurrentSelection()->GetSelectionState() == SelectMgr_SOS_Activated)
       {
-        ComputeSensitivePrs (aStruct, anObj->CurrentSelection(), anObj->Transformation(), Graphic3d_TransformPers());
+        computeSensitivePrs (aStruct, anObj->CurrentSelection(), anObj->Transformation(), Graphic3d_TransformPers());
       }
     }
 
@@ -212,7 +215,7 @@ void StdSelect_ViewerSelector3d::DisplaySensitive (const Handle(V3d_View)& theVi
     {
       if (anObj->CurrentSelection()->GetSelectionState() == SelectMgr_SOS_Activated)
       {
-        ComputeSensitivePrs (aStruct, anObj->CurrentSelection(), anObj->Transformation(), anObj->TransformPersistence());
+        computeSensitivePrs (aStruct, anObj->CurrentSelection(), anObj->Transformation(), anObj->TransformPersistence());
       }
     }
 
@@ -264,7 +267,7 @@ void StdSelect_ViewerSelector3d::DisplaySensitive (const Handle(SelectMgr_Select
 
   Handle(Graphic3d_Structure) aStruct = new Graphic3d_Structure (theView->Viewer()->StructureManager());
 
-  ComputeSensitivePrs (aStruct, theSel, theTrsf, Graphic3d_TransformPers());
+  computeSensitivePrs (aStruct, theSel, theTrsf, Graphic3d_TransformPers());
 
   myStructs.Append (aStruct);
   myStructs.Last()->SetDisplayPriority (10);
@@ -274,10 +277,10 @@ void StdSelect_ViewerSelector3d::DisplaySensitive (const Handle(SelectMgr_Select
 }
 
 //=======================================================================
-//function : ComputeSensitivePrs
+//function : computeSensitivePrs
 //purpose  :
 //=======================================================================
-void StdSelect_ViewerSelector3d::ComputeSensitivePrs (const Handle(Graphic3d_Structure)& theStructure,
+void StdSelect_ViewerSelector3d::computeSensitivePrs (const Handle(Graphic3d_Structure)& theStructure,
                                                       const Handle(SelectMgr_Selection)& theSel,
                                                       const gp_Trsf& theLoc,
                                                       const Graphic3d_TransformPers& theTransPers)
@@ -663,3 +666,27 @@ Standard_Boolean StdSelect_ViewerSelector3d::HasDepthClipping (const Handle(Sele
   const Handle(SelectMgr_SelectableObject)& aSelectable = theOwner->Selectable();
   return (aSelectable->GetClipPlanes().Size() > 0);
 }
+
+//=======================================================================
+// Function: updateZLayers
+// Purpose :
+//=======================================================================
+void StdSelect_ViewerSelector3d::updateZLayers (const Handle(V3d_View)& theView)
+{
+  myZLayerOrderMap.Clear();
+  TColStd_SequenceOfInteger aZLayers;
+  theView->Viewer()->GetAllZLayers (aZLayers);
+  Standard_Integer aPos = 0;
+  Standard_Boolean isPrevDepthWrite = true;
+  for (TColStd_SequenceOfInteger::Iterator aLayerIter (aZLayers); aLayerIter.More(); aLayerIter.Next())
+  {
+    Graphic3d_ZLayerSettings aSettings = theView->Viewer()->ZLayerSettings (aLayerIter.Value());
+    if (aSettings.IsSettingEnabled (Graphic3d_ZLayerDepthClear)
+     || isPrevDepthWrite != aSettings.IsSettingEnabled (Graphic3d_ZLayerDepthWrite))
+    {
+      ++aPos;
+    }
+    isPrevDepthWrite = aSettings.IsSettingEnabled (Graphic3d_ZLayerDepthWrite);
+    myZLayerOrderMap.Bind (aLayerIter.Value(), aPos);
+  }
+}
index 8659b03..37ac007 100644 (file)
@@ -83,12 +83,17 @@ public:
 
   DEFINE_STANDARD_RTTIEXT(StdSelect_ViewerSelector3d,SelectMgr_ViewerSelector)
 
-private:
+protected:
 
-  void ComputeSensitivePrs (const Handle(Graphic3d_Structure)& theStructure,
-                            const Handle(SelectMgr_Selection)& theSel,
-                            const gp_Trsf& theLoc,
-                            const Graphic3d_TransformPers& theTransPers);
+  Standard_EXPORT void computeSensitivePrs (const Handle(Graphic3d_Structure)& theStructure,
+                                            const Handle(SelectMgr_Selection)& theSel,
+                                            const gp_Trsf& theLoc,
+                                            const Graphic3d_TransformPers& theTransPers);
+
+  //! Update z-layers order map.
+  Standard_EXPORT void updateZLayers (const Handle(V3d_View)& theView);
+
+protected:
 
   Graphic3d_SequenceOfStructure myStructs;
 };
diff --git a/tests/bugs/vis/bug27797 b/tests/bugs/vis/bug27797
new file mode 100644 (file)
index 0000000..3f1a3c0
--- /dev/null
@@ -0,0 +1,33 @@
+puts "========"
+puts "Consider ZLayer properties while sorting list of picked entities"
+puts "========"
+
+pload MODELING VISUALIZATION
+
+box b1 0 0 0 2 3 4
+box b2 0 0 0 1 1 2
+vertex v 100 -300 0
+
+vclear
+vinit View1
+catch { vzlayer del 1 }
+vzlayer add 1
+vzlayer enable 1 depthclear
+vaxo
+vdisplay -noupdate -dispMode 1 -highMode 1 b1
+vdisplay -noupdate -dispMode 1 -highMode 1 -layer 1 b2
+vsetcolor -noupdate b1 RED
+vsetcolor -noupdate b2 GREEN
+vfit
+vrotate 0.1 0 0
+vmoveto 100 300
+vstate
+vselect 100 300
+vmoveto 0 0
+
+set aSelColor [vreadpixel 100 300 rgb name]
+if { $aSelColor != "GRAY72"} { puts "Error: wrong object has been selected" }
+
+vdisplay -dispMode 0 -osd -2d -trsfPersPos -1 1 v
+
+vdump $imagedir/${casename}.png