1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-04 18:06:22 +03:00

0027797: Visualization - consider ZLayer properties while sorting list of picked entities

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.
This commit is contained in:
kgv 2016-08-23 17:26:22 +03:00 committed by bugmaster
parent 94afca11a0
commit 1593b4eeab
11 changed files with 252 additions and 222 deletions

View File

@ -488,6 +488,50 @@ void OpenGl_GraphicDriver::TextSize (const Handle(Graphic3d_CView)& theView,
OpenGl_Text::StringSize(aCtx, aText, aTextAspect, aTextParam, theView->RenderingParams().Resolution, theWidth, theAscent, theDescent);
}
//=======================================================================
//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);
}
}

View 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)

View File

@ -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

View File

@ -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() );
}

View File

@ -17,14 +17,14 @@
#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:
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
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);
}
//! 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;
}
protected:
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;
}
private:
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;
}
Standard_Integer myPrior;
Standard_Real myDepth;
Standard_Real myDist;
Standard_Real myTol;
Standard_Boolean myPreferClosest;
// 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

View File

@ -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;}

View 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)

View 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:

View 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);
}
}

View 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;
};

33
tests/bugs/vis/bug27797 Normal file
View File

@ -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