1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-14 13:30:48 +03:00

0026344: Visualization - provide a support of zoom persistent selection

1) New Graphic3d_TransformPers structure for defining parameters and algorithm methods, featuring:
    a) application of transformation to projection and world view matrices;
    b) computation of model-world transformation of persistent object;
    c) computation of transformed bounding box of persistent object.

2) Transform persistence algorithm does not make any changes to model-world transformation of object (deals with projection and world view matrices only), thus making possible to employ local transformation in a usual way.

3) Support of BVH selection for transform persistent objects (pan, rotate, zoom, trihedron persistence only).

4) Support efficient frustum culling for transform persistent objects (pan, rotate, zoom, trihedron persistence only).

5) Support of z-fitting algorithm for world-view space transform persistent objects (rotate, zoom persistence only).

6) Rewrite usage of transform persistence structures and utilities classes:
    a) Replaced Graphic3d_CTransPers, TEL_TRANSFORM_PERSISTENCE by Graphic3d_TransformPers;
    b) Move functions from OpenGl_Utils.hxx to Graphic3d_TransformUtils.hxx;
    c) Extract matrix stack class from OpenGl_Utils.hxx to OpenGl_MatrixStack.hxx;

7) New class Graphic3d_WorldViewProjState to keep track of projection, world view matrices changes for a camera.

8) New test case bugs/vis/bug26344.

9) Renamed method Graphic3d_Camera::ModelViewState of  to ::WorldViewState for consistency.
This commit is contained in:
apl
2015-07-20 11:41:38 +03:00
committed by bugmaster
parent 317d68c924
commit 825aa485a3
59 changed files with 2324 additions and 1156 deletions

View File

@@ -29,6 +29,8 @@ SelectMgr_SelectableObject.hxx
SelectMgr_SelectableObject.lxx
SelectMgr_SelectableObjectSet.cxx
SelectMgr_SelectableObjectSet.hxx
SelectMgr_SelectableObjectTrsfPersSet.cxx
SelectMgr_SelectableObjectTrsfPersSet.hxx
SelectMgr_SelectingVolumeManager.cxx
SelectMgr_SelectingVolumeManager.hxx
SelectMgr_Selection.cxx

View File

@@ -33,8 +33,9 @@ SelectMgr_BaseFrustum::SelectMgr_BaseFrustum()
//=======================================================================
void SelectMgr_BaseFrustum::SetCamera (const Handle(Graphic3d_Camera)& theCamera)
{
myBuilder->SetOrientation (theCamera->OrientationMatrix());
myBuilder->SetProjection (theCamera->ProjectionMatrix());
myBuilder->SetWorldViewMatrix (theCamera->OrientationMatrix());
myBuilder->SetProjectionMatrix (theCamera->ProjectionMatrix());
myBuilder->SetWorldViewProjState (theCamera->WorldViewProjState());
myIsOrthographic = theCamera->IsOrthographic();
myBuilder->InvalidateViewport();
}
@@ -44,14 +45,46 @@ void SelectMgr_BaseFrustum::SetCamera (const Handle(Graphic3d_Camera)& theCamera
// purpose : Passes camera projection and orientation matrices to builder
//=======================================================================
void SelectMgr_BaseFrustum::SetCamera (const Graphic3d_Mat4d& theProjection,
const Graphic3d_Mat4d& theOrientation,
const Standard_Integer theIsOrthographic)
const Graphic3d_Mat4d& theWorldView,
const Standard_Integer theIsOrthographic,
const Graphic3d_WorldViewProjState& theWVPState)
{
myBuilder->SetOrientation (theOrientation);
myBuilder->SetProjection (theProjection);
myBuilder->SetWorldViewMatrix (theWorldView);
myBuilder->SetProjectionMatrix (theProjection);
myBuilder->SetWorldViewProjState (theWVPState);
myIsOrthographic = theIsOrthographic;
}
//=======================================================================
// function : ProjectionMatrix
// purpose : Returns current camera projection transformation common for
// all selecting volumes
//=======================================================================
const Graphic3d_Mat4d& SelectMgr_BaseFrustum::ProjectionMatrix() const
{
return myBuilder->ProjectionMatrix();
}
//=======================================================================
// function : WorldViewMatrix
// purpose : Returns current camera world view transformation common for
// all selecting volumes
//=======================================================================
const Graphic3d_Mat4d& SelectMgr_BaseFrustum::WorldViewMatrix() const
{
return myBuilder->WorldViewMatrix();
}
//=======================================================================
// function : WorldViewProjState
// purpose : Returns current camera world view projection transformation
// state
//=======================================================================
const Graphic3d_WorldViewProjState& SelectMgr_BaseFrustum::WorldViewProjState() const
{
return myBuilder->WorldViewProjState();
}
//=======================================================================
// function : SetViewport
// purpose : Passes viewport parameters to builder

View File

@@ -24,6 +24,7 @@
#include <Graphic3d_Camera.hxx>
#include <Graphic3d_ClipPlane.hxx>
#include <Graphic3d_SequenceOfHClipPlane.hxx>
#include <Graphic3d_WorldViewProjState.hxx>
#include <TColgp_HArray1OfPnt.hxx>
#include <TColgp_Array1OfPnt2d.hxx>
@@ -53,8 +54,18 @@ public:
//! Passes camera projection and orientation matrices to builder
void SetCamera (const Graphic3d_Mat4d& theProjection,
const Graphic3d_Mat4d& theOrientation,
const Standard_Integer theIsOrthographic);
const Graphic3d_Mat4d& theWorldView,
const Standard_Integer theIsOrthographic,
const Graphic3d_WorldViewProjState& theWVPState = Graphic3d_WorldViewProjState());
//! @return current camera projection transformation common for all selecting volumes
const Graphic3d_Mat4d& ProjectionMatrix() const;
//! @return current camera world view transformation common for all selecting volumes
const Graphic3d_Mat4d& WorldViewMatrix() const;
//! @return current camera world view projection transformation state
const Graphic3d_WorldViewProjState& WorldViewProjState() const;
void SetPixelTolerance (const Standard_Real theTol);

View File

@@ -24,30 +24,70 @@
// purpose : Creates new frustum builder with empty matrices
//=======================================================================
SelectMgr_FrustumBuilder::SelectMgr_FrustumBuilder()
: myOrientation(),
: myWorldView(),
myProjection(),
myWorldViewProjState(),
myWidth (INT_MAX),
myHeight (INT_MAX),
myIsViewportSet (Standard_False) {}
//=======================================================================
// function : SetOrientation
// purpose : Stores current orientation matrix
//=======================================================================
void SelectMgr_FrustumBuilder::SetOrientation (const Graphic3d_Mat4d& theOrientation)
myIsViewportSet (Standard_False)
{
myOrientation = theOrientation;
//
}
//=======================================================================
// function : SetProjection
// function : SetWorldViewMatrix
// purpose : Stores current world view transformation matrix
//=======================================================================
void SelectMgr_FrustumBuilder::SetWorldViewMatrix (const Graphic3d_Mat4d& theWorldView)
{
myWorldView = theWorldView;
}
//=======================================================================
// function : WorldViewMatrix
// purpose : Returns current world view transformation matrix
//=======================================================================
const Graphic3d_Mat4d& SelectMgr_FrustumBuilder::WorldViewMatrix() const
{
return myWorldView;
}
//=======================================================================
// function : SetProjectionMatrix
// purpose : Stores current projection matrix
//=======================================================================
void SelectMgr_FrustumBuilder::SetProjection (const Graphic3d_Mat4d& theProjection)
void SelectMgr_FrustumBuilder::SetProjectionMatrix (const Graphic3d_Mat4d& theProjection)
{
myProjection = theProjection;
}
//=======================================================================
// function : ProjectionMatrix
// purpose : Returns current projection matrix
//=======================================================================
const Graphic3d_Mat4d& SelectMgr_FrustumBuilder::ProjectionMatrix() const
{
return myProjection;
}
//=======================================================================
// function : SetWorldViewProjState
// purpose : Stores current world view projection matrix state
//=======================================================================
void SelectMgr_FrustumBuilder::SetWorldViewProjState (const Graphic3d_WorldViewProjState& theState)
{
myWorldViewProjState = theState;
}
//=======================================================================
// function : WorldViewProjState
// purpose : Returns current world view projection matrix state
//=======================================================================
const Graphic3d_WorldViewProjState& SelectMgr_FrustumBuilder::WorldViewProjState() const
{
return myWorldViewProjState;
}
//=======================================================================
// function : SetWindowSize
// purpose : Stores current window width and height
@@ -131,7 +171,7 @@ SelectMgr_Vec3 SelectMgr_FrustumBuilder::unProject (const gp_Pnt& thePnt) const
Graphic3d_Mat4d aInvProj;
// this case should never happen
if (!myOrientation.Inverted (aInvView) || !myProjection.Inverted (aInvProj))
if (!myWorldView.Inverted (aInvView) || !myProjection.Inverted (aInvProj))
{
return SelectMgr_Vec3 (0.0, 0.0, 0.0);
}

View File

@@ -19,6 +19,7 @@
#include <Standard_Type.hxx>
#include <Graphic3d_Camera.hxx>
#include <Graphic3d_WorldViewProjState.hxx>
#include <Precision.hxx>
#include <SelectMgr_VectorTypes.hxx>
@@ -31,11 +32,23 @@ public:
//! Creates new frustum builder with empty matrices
SelectMgr_FrustumBuilder();
//! Stores current orientation matrix
void SetOrientation (const Graphic3d_Mat4d& theOrientation);
//! Stores current world view transformation matrix
void SetWorldViewMatrix (const Graphic3d_Mat4d& theWorldViewMatrix);
//! @return current world view transformation matrix
const Graphic3d_Mat4d& WorldViewMatrix() const;
//! Stores current projection matrix
void SetProjection (const Graphic3d_Mat4d& theProjection);
void SetProjectionMatrix (const Graphic3d_Mat4d& theProjection);
//! @return current projection matrix
const Graphic3d_Mat4d& ProjectionMatrix() const;
//! Stores current world view projection matrix state for the orientation and projection matrices
void SetWorldViewProjState (const Graphic3d_WorldViewProjState& theState);
//! @return current world view projection state
const Graphic3d_WorldViewProjState& WorldViewProjState() const;
//! Stores current window width and height
void SetWindowSize (const Standard_Integer theWidth,
@@ -70,8 +83,9 @@ private:
private:
Graphic3d_Mat4d myOrientation;
Graphic3d_Mat4d myWorldView;
Graphic3d_Mat4d myProjection;
Graphic3d_WorldViewProjState myWorldViewProjState;
Standard_Integer myWidth;
Standard_Integer myHeight;
NCollection_Vec4<Standard_Real> myViewport;

View File

@@ -247,25 +247,20 @@ void SelectMgr_SelectableObject::ResetTransformation()
PrsMgr_PresentableObject::ResetTransformation();
}
//=======================================================================
//function : UpdateTransformation
//purpose :
//=======================================================================
void SelectMgr_SelectableObject::UpdateTransformation()
void SelectMgr_SelectableObject::UpdateTransformation()
{
Handle(Select3D_SensitiveEntity) SE;
for(Init();More();Next()){
const Handle(SelectMgr_Selection) & Sel = CurrentSelection();
Sel->UpdateStatus(SelectMgr_TOU_Partial);
Sel->UpdateBVHStatus (SelectMgr_TBU_Invalidate);
for (Init(); More(); Next())
{
CurrentSelection()->UpdateStatus (SelectMgr_TOU_Partial);
}
PrsMgr_PresentableObject::UpdateTransformation();
}
//=======================================================================
//function : UpdateTransformation
//purpose :

View File

@@ -32,13 +32,18 @@ SelectMgr_SelectableObjectSet::SelectMgr_SelectableObjectSet()
// function : Append
// purpose : Adds new object to the set and marks BVH tree for rebuild
//=======================================================================
void SelectMgr_SelectableObjectSet::Append (const Handle(SelectMgr_SelectableObject)& theObject)
Standard_Boolean SelectMgr_SelectableObjectSet::Append (const Handle(SelectMgr_SelectableObject)& theObject)
{
Standard_Integer aSize = Size();
if (aSize < myObjects.Add (theObject))
{
MarkDirty();
return Standard_True;
}
return Standard_False;
}
//=======================================================================
@@ -46,7 +51,7 @@ void SelectMgr_SelectableObjectSet::Append (const Handle(SelectMgr_SelectableObj
// purpose : Removes object theObject from set and marks BVH tree for
// rebuild
//=======================================================================
void SelectMgr_SelectableObjectSet::Remove (const Handle(SelectMgr_SelectableObject)& theObject)
Standard_Boolean SelectMgr_SelectableObjectSet::Remove (const Handle(SelectMgr_SelectableObject)& theObject)
{
const Standard_Integer anIndex = myObjects.FindIndex (theObject);
@@ -60,7 +65,11 @@ void SelectMgr_SelectableObjectSet::Remove (const Handle(SelectMgr_SelectableObj
myObjects.RemoveLast();
MarkDirty();
return Standard_True;
}
return Standard_False;
}
//=======================================================================
@@ -119,21 +128,3 @@ Standard_Integer SelectMgr_SelectableObjectSet::Size() const
{
return myObjects.Size();
}
//=======================================================================
// function : GetObjectById
// purpose : Returns object from set by theIndex given
//=======================================================================
const Handle(SelectMgr_SelectableObject)& SelectMgr_SelectableObjectSet::GetObjectById (const Standard_Integer theIndex) const
{
return myObjects.FindKey (theIndex + 1);
}
//=======================================================================
// function : Contains
// purpose : Returns true if this objects set contains theObject given
//=======================================================================
Standard_Boolean SelectMgr_SelectableObjectSet::Contains (const Handle(SelectMgr_SelectableObject)& theObject) const
{
return myObjects.Contains (theObject);
}

View File

@@ -35,37 +35,45 @@ public:
//! Creates new empty objects set and initializes BVH tree
//! builder to Binned builder with 1 element per list
SelectMgr_SelectableObjectSet();
Standard_EXPORT SelectMgr_SelectableObjectSet();
//! Releases resources of selectable object set.
virtual ~SelectMgr_SelectableObjectSet() { }
//! Adds new object to the set and marks BVH tree for rebuild
void Append (const Handle(SelectMgr_SelectableObject)& theObject);
//! Adds new object to the set and marks BVH tree for rebuild.
//! @return true if structure added, otherwise returns false (structure already in the set).
Standard_EXPORT Standard_Boolean Append (const Handle(SelectMgr_SelectableObject)& theObject);
//! Removes object theObject from set and marks BVH tree for rebuild
void Remove (const Handle(SelectMgr_SelectableObject)& theObject);
//! Removes object theObject from set and marks BVH tree for rebuild.
//! @return true if structure removed, otherwise returns false (structure is not in the set).
Standard_EXPORT Standard_Boolean Remove (const Handle(SelectMgr_SelectableObject)& theObject);
//! Returns bounding box of object with index theIndex
virtual Select3D_BndBox3d Box (const Standard_Integer theIndex) const Standard_OVERRIDE;
Standard_EXPORT virtual Select3D_BndBox3d Box (const Standard_Integer theIndex) const Standard_OVERRIDE;
//! Returns center of object with index theIndex in the set
//! along the given axis theAxis
virtual Standard_Real Center (const Standard_Integer theIndex,
const Standard_Integer theAxis) const Standard_OVERRIDE;
Standard_EXPORT virtual Standard_Real Center (const Standard_Integer theIndex,
const Standard_Integer theAxis) const Standard_OVERRIDE;
//! Swaps items with indexes theIndex1 and theIndex2 in the set
virtual void Swap (const Standard_Integer theIndex1,
const Standard_Integer theIndex2) Standard_OVERRIDE;
Standard_EXPORT virtual void Swap (const Standard_Integer theIndex1,
const Standard_Integer theIndex2) Standard_OVERRIDE;
//! Returns size of objects set
virtual Standard_Integer Size() const Standard_OVERRIDE;
Standard_EXPORT virtual Standard_Integer Size() const Standard_OVERRIDE;
//! Returns object from set by theIndex given
const Handle(SelectMgr_SelectableObject)& GetObjectById (const Standard_Integer theIndex) const;
const Handle(SelectMgr_SelectableObject)& GetObjectById (const Standard_Integer theIndex) const
{
return myObjects.FindKey (theIndex + 1);
}
//! Returns true if this objects set contains theObject given
Standard_Boolean Contains (const Handle(SelectMgr_SelectableObject)& theObject) const;
Standard_Boolean Contains (const Handle(SelectMgr_SelectableObject)& theObject) const
{
return myObjects.Contains (theObject);
}
private:

View File

@@ -0,0 +1,164 @@
// Created on: 2015-06-30
// Created by: Anton POLETAEV
// Copyright (c) 2015 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 <SelectMgr_SelectableObjectTrsfPersSet.hxx>
#include <Bnd_Box.hxx>
#include <BVH_LinearBuilder.hxx>
#include <SelectMgr_VectorTypes.hxx>
//=======================================================================
// function : SelectMgr_SelectableObjectTrsfPersSet
// purpose :
//=======================================================================
SelectMgr_SelectableObjectTrsfPersSet::SelectMgr_SelectableObjectTrsfPersSet()
: myIsDirty (Standard_False),
myBVH (new BVH_Tree<Standard_Real, 3>())
{
myBuilder = new BVH_LinearBuilder<Standard_Real, 3> (1, 32);
}
//=======================================================================
// function : Size
// purpose :
//=======================================================================
Standard_Integer SelectMgr_SelectableObjectTrsfPersSet::Size() const
{
return myObjects.Size();
}
//=======================================================================
// function : Box
// purpose :
//=======================================================================
Select3D_BndBox3d SelectMgr_SelectableObjectTrsfPersSet::Box (const Standard_Integer theIndex) const
{
return *myObjectBoxes (theIndex + 1);
}
//=======================================================================
// function : Center
// purpose :
//=======================================================================
Standard_Real SelectMgr_SelectableObjectTrsfPersSet::Center (const Standard_Integer theIndex,
const Standard_Integer theAxis) const
{
const Select3D_BndBox3d& aBndBox = *myObjectBoxes (theIndex + 1);
return (aBndBox.CornerMin()[theAxis] + aBndBox.CornerMax()[theAxis]) * 0.5;
}
//=======================================================================
// function : Swap
// purpose :
//=======================================================================
void SelectMgr_SelectableObjectTrsfPersSet::Swap (const Standard_Integer theIndex1,
const Standard_Integer theIndex2)
{
const Standard_Integer aStructIdx1 = theIndex1 + 1;
const Standard_Integer aStructIdx2 = theIndex2 + 1;
myObjects.Swap (aStructIdx1, aStructIdx2);
myObjectBoxes.Swap (aStructIdx1, aStructIdx2);
}
//=======================================================================
// function : Append
// purpose :
//=======================================================================
Standard_Boolean SelectMgr_SelectableObjectTrsfPersSet::Append (const Handle(SelectMgr_SelectableObject)& theObject)
{
Standard_Integer aSize = Size();
if (aSize < myObjects.Add (theObject))
{
MarkDirty();
return Standard_True;
}
return Standard_False;
}
//=======================================================================
// function : Remove
// purpose :
//=======================================================================
Standard_Boolean SelectMgr_SelectableObjectTrsfPersSet::Remove (const Handle(SelectMgr_SelectableObject)& theObject)
{
const Standard_Integer anIndex = myObjects.FindIndex (theObject);
if (anIndex != 0)
{
myObjects.Swap (Size(), anIndex);
myObjects.RemoveLast();
MarkDirty();
return Standard_True;
}
return Standard_False;
}
//=======================================================================
// function : BVH
// purpose :
//=======================================================================
const NCollection_Handle<BVH_Tree<Standard_Real, 3> >&
SelectMgr_SelectableObjectTrsfPersSet::BVH (const Graphic3d_Mat4d& theProjectionMatrix,
const Graphic3d_Mat4d& theWorldViewMatrix,
const Graphic3d_WorldViewProjState& theWVPState)
{
if (!myIsDirty && (myObjectBoxesState.IsValid() && !myObjectBoxesState.IsChanged(theWVPState)))
{
return myBVH;
}
myObjectBoxes.ReSize (myObjects.Size());
for (Standard_Integer anObjectIdx = 1; anObjectIdx <= myObjects.Size(); ++anObjectIdx)
{
const Handle(SelectMgr_SelectableObject)& anObject = myObjects (anObjectIdx);
Bnd_Box aBoundingBox;
if (anObject->TransformPersistence().Flags && !(anObject->TransformPersistence().Flags & Graphic3d_TMF_2d))
{
anObject->BoundingBox (aBoundingBox);
anObject->TransformPersistence().Apply (theProjectionMatrix, theWorldViewMatrix, 0, 0, aBoundingBox);
}
if (aBoundingBox.IsVoid())
{
myObjectBoxes.Add (new Select3D_BndBox3d());
}
else
{
gp_Pnt aMin = aBoundingBox.CornerMin();
gp_Pnt aMax = aBoundingBox.CornerMax();
myObjectBoxes.Add (new Select3D_BndBox3d (Select3D_Vec3 (aMin.X(), aMin.Y(), aMin.Z()),
Select3D_Vec3 (aMax.X(), aMax.Y(), aMax.Z())));
}
}
myBuilder->Build (this, myBVH.operator->(), BVH_Set<Standard_Real, 3>::Box());
myObjectBoxesState = theWVPState;
myObjectBoxes.Clear();
myIsDirty = Standard_False;
return myBVH;
}

View File

@@ -0,0 +1,115 @@
// Created on: 2015-06-30
// Created by: Anton POLETAEV
// Copyright (c) 2015 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.
#ifndef _SelectMgr_SelectableObjectTrsfPersSet_HeaderFile
#define _SelectMgr_SelectableObjectTrsfPersSet_HeaderFile
#include <BVH_Builder.hxx>
#include <BVH_Set.hxx>
#include <BVH_Tree.hxx>
#include <Graphic3d_Camera.hxx>
#include <Graphic3d_WorldViewProjState.hxx>
#include <NCollection_Handle.hxx>
#include <NCollection_IndexedMap.hxx>
#include <Select3D_BndBox3d.hxx>
#include <SelectMgr_SelectableObject.hxx>
//! Primitive set specialized for transformation persistent selectable objects.
//! Provides built-in mechanism to invalidate tree when world view projection state changes.
//! Due to frequent invalidation of BVH tree the choice of BVH tree builder is made
//! in favor of BVH linear builder (quick rebuild).
class SelectMgr_SelectableObjectTrsfPersSet : public BVH_Set<Standard_Real, 3>
{
private:
typedef NCollection_Handle<Select3D_BndBox3d> HBndBox3d;
Handle(SelectMgr_SelectableObject) EMPTY_OBJ;
public:
//! Creates new empty objects set and initializes BVH tree
//! builder to Linear builder with 1 element per list.
Standard_EXPORT SelectMgr_SelectableObjectTrsfPersSet();
//! Returns size of objects set.
Standard_EXPORT virtual Standard_Integer Size() const Standard_OVERRIDE;
//! Returns bounding box of object with index theIndex.
Standard_EXPORT virtual Select3D_BndBox3d Box (const Standard_Integer theIndex) const Standard_OVERRIDE;
//! Returns center of object with index theIndex in the set along the given axis theAxis.
Standard_EXPORT virtual Standard_Real Center (const Standard_Integer theIndex,
const Standard_Integer theAxis) const Standard_OVERRIDE;
//! Swaps items with indexes theIndex1 and theIndex2 in the set.
Standard_EXPORT virtual void Swap (const Standard_Integer theIndex1,
const Standard_Integer theIndex2) Standard_OVERRIDE;
//! Adds new selectable object to the set.
//! @return true if structure added, otherwise returns false (structure already in the set).
Standard_EXPORT Standard_Boolean Append (const Handle(SelectMgr_SelectableObject)& theObject);
//! Removes selectable object from set.
//! @return true if structure removed, otherwise returns false (structure is not in the set).
Standard_EXPORT Standard_Boolean Remove (const Handle(SelectMgr_SelectableObject)& theObject);
//! Returns object from set by theIndex given.
const Handle(SelectMgr_SelectableObject)& GetObjectById (const Standard_Integer theIndex) const
{
return myObjects.FindKey (theIndex + 1);
}
//! Marks object state as outdated (needs BVH rebuilding).
void MarkDirty()
{
myIsDirty = Standard_True;
}
//! Returns true if this objects set contains theObject given
Standard_Boolean Contains (const Handle(SelectMgr_SelectableObject)& theObject) const
{
return myObjects.Contains (theObject);
}
//! Returns BVH tree for the given world view projection (builds it if necessary).
const NCollection_Handle<BVH_Tree<Standard_Real, 3> >& BVH (const Graphic3d_Mat4d& theProjectionMatrix,
const Graphic3d_Mat4d& theWorldViewMatrix,
const Graphic3d_WorldViewProjState& theWVPState);
private:
//! Marks internal object state as outdated.
Standard_Boolean myIsDirty;
//! Constructed bottom-level BVH.
NCollection_Handle<BVH_Tree<Standard_Real, 3> > myBVH;
//! Builder for bottom-level BVH.
NCollection_Handle<BVH_Builder<Standard_Real, 3> > myBuilder;
//! Set of transform persistence objects.
NCollection_IndexedMap<Handle(SelectMgr_SelectableObject)> myObjects;
//! Cached set of bounding boxes precomputed for transformation persistent selectable objects.
//! Cache exists only during computation of BVH Tree. Bounding boxes are world view projection
//! dependent and should by synchronized.
NCollection_IndexedMap<HBndBox3d> myObjectBoxes;
//! State of world view projection used for generation of transformation persistence bounding boxes.
Graphic3d_WorldViewProjState myObjectBoxesState;
};
#endif

View File

@@ -106,15 +106,46 @@ void SelectMgr_SelectingVolumeManager::SetCamera (const Handle(Graphic3d_Camera)
// selecting volumes
//=======================================================================
void SelectMgr_SelectingVolumeManager::SetCamera (const Graphic3d_Mat4d& theProjection,
const Graphic3d_Mat4d& theOrientation,
const Standard_Boolean theIsOrthographic)
const Graphic3d_Mat4d& theWorldView,
const Standard_Boolean theIsOrthographic,
const Graphic3d_WorldViewProjState& theWVPState)
{
for (Standard_Integer anIdx = 0; anIdx < VolumeTypesNb; ++anIdx)
{
mySelectingVolumes[anIdx]->SetCamera (theProjection, theOrientation, theIsOrthographic);
mySelectingVolumes[anIdx]->SetCamera (theProjection, theWorldView, theIsOrthographic, theWVPState);
}
}
//=======================================================================
// function : ProjectionMatrix
// purpose : Returns current projection transformation common for all
// selecting volumes
//=======================================================================
const Graphic3d_Mat4d& SelectMgr_SelectingVolumeManager::ProjectionMatrix() const
{
return mySelectingVolumes[Frustum]->ProjectionMatrix();
}
//=======================================================================
// function : WorldViewMatrix
// purpose : Returns current world view transformation common for all
// selecting volumes
//=======================================================================
const Graphic3d_Mat4d& SelectMgr_SelectingVolumeManager::WorldViewMatrix() const
{
return mySelectingVolumes[Frustum]->WorldViewMatrix();
}
//=======================================================================
// function : WorldViewProjState
// purpose : Returns current camera world view projection transformation
// state common for all selecting volumes
//=======================================================================
const Graphic3d_WorldViewProjState& SelectMgr_SelectingVolumeManager::WorldViewProjState() const
{
return mySelectingVolumes[Frustum]->WorldViewProjState();
}
//=======================================================================
// function : SetCamera
// purpose : Updates viewport in all selecting volumes

View File

@@ -20,6 +20,7 @@
#include <Graphic3d_Camera.hxx>
#include <Graphic3d_SequenceOfHClipPlane.hxx>
#include <Graphic3d_WorldViewProjState.hxx>
#include <SelectMgr_BaseFrustum.hxx>
#include <SelectMgr_RectangularFrustum.hxx>
@@ -53,8 +54,18 @@ public:
//! Updates camera projection and orientation matrices in all selecting volumes
Standard_EXPORT void SetCamera (const Graphic3d_Mat4d& theProjection,
const Graphic3d_Mat4d& theOrientation,
const Standard_Boolean theIsOrthographic);
const Graphic3d_Mat4d& theWorldView,
const Standard_Boolean theIsOrthographic,
const Graphic3d_WorldViewProjState& theWVPState = Graphic3d_WorldViewProjState());
//! @return current projection transformation common for all selecting volumes
Standard_EXPORT const Graphic3d_Mat4d& ProjectionMatrix() const;
//! @return current world view transformation common for all selecting volumes
Standard_EXPORT const Graphic3d_Mat4d& WorldViewMatrix() const;
//! @return current camera world view projection transformation state common for all selecting volumes
Standard_EXPORT const Graphic3d_WorldViewProjState& WorldViewProjState() const;
//! Updates viewport in all selecting volumes
Standard_EXPORT void SetViewport (const Standard_Real theX,

View File

@@ -143,10 +143,8 @@ myCurRank (0),
myIsLeftChildQueuedFirst (Standard_False),
myEntityIdx (0)
{
mySelectableObjects = new SelectMgr_SelectableObjectSet();
}
//==================================================
// Function: Activate
// Purpose :
@@ -164,7 +162,6 @@ void SelectMgr_ViewerSelector::Activate (const Handle(SelectMgr_Selection)& theS
myToUpdateTolerance = Standard_True;
}
//==================================================
// Function: Deactivate
// Purpose :
@@ -300,8 +297,32 @@ void SelectMgr_ViewerSelector::traverseObject (const Handle(SelectMgr_Selectable
const NCollection_Handle<BVH_Tree<Standard_Real, 3> >& aSensitivesTree = anEntitySet->BVH();
SelectMgr_SelectingVolumeManager aMgr = theObject->HasTransformation() ?
mySelectingVolumeMgr.Transform (theObject->InversedTransformation()) : mySelectingVolumeMgr;
gp_Trsf aInversedTrsf;
if (theObject->HasTransformation() || theObject->TransformPersistence().Flags)
{
if (!theObject->TransformPersistence().Flags)
{
aInversedTrsf = theObject->InversedTransformation();
}
else
{
const Graphic3d_Mat4d& aProjection = mySelectingVolumeMgr.ProjectionMatrix();
const Graphic3d_Mat4d& aWorldView = mySelectingVolumeMgr.WorldViewMatrix();
gp_Trsf aTPers;
Graphic3d_Mat4d aMat = theObject->TransformPersistence().Compute (aProjection, aWorldView, 0, 0);
aTPers.SetValues (aMat.GetValue (0, 0), aMat.GetValue (0, 1), aMat.GetValue (0, 2), aMat.GetValue (0, 3),
aMat.GetValue (1, 0), aMat.GetValue (1, 1), aMat.GetValue (1, 2), aMat.GetValue (1, 3),
aMat.GetValue (2, 0), aMat.GetValue (2, 1), aMat.GetValue (2, 2), aMat.GetValue (2, 3));
aInversedTrsf = (aTPers * theObject->Transformation()).Inverted();
}
}
SelectMgr_SelectingVolumeManager aMgr = aInversedTrsf.Form() != gp_Identity
? mySelectingVolumeMgr.Transform (aInversedTrsf)
: mySelectingVolumeMgr;
NCollection_DataMap<Handle(Standard_Type), SelectMgr_SelectingVolumeManager> aScaledTrnsfFrustums;
@@ -363,7 +384,7 @@ void SelectMgr_ViewerSelector::traverseObject (const Handle(SelectMgr_Selectable
if (!aScaledTrnsfFrustums.IsBound (anEnt->DynamicType()))
{
aScaledTrnsfFrustums.Bind (anEnt->DynamicType(),
scaleAndTransform (sensitivity (anEnt), theObject->InversedTransformation()));
scaleAndTransform (sensitivity (anEnt), aInversedTrsf));
}
aTmpMgr = aScaledTrnsfFrustums.Find (anEnt->DynamicType());
@@ -392,45 +413,86 @@ void SelectMgr_ViewerSelector::TraverseSensitives()
mystored.Clear();
myMapOfDetected.Clear();
if (mySelectableObjects->Size() == 0)
return;
const NCollection_Handle<BVH_Tree<Standard_Real, 3> >& anObjectsTree = mySelectableObjects->BVH();
Standard_Integer aNode = 0;
if (!mySelectingVolumeMgr.Overlaps (anObjectsTree->MinPoint (0),
anObjectsTree->MaxPoint (0)))
NCollection_Handle<BVH_Tree<Standard_Real, 3> > aBVHTree;
for (Standard_Integer aBVHTreeIdx = 0; aBVHTreeIdx < 2; ++aBVHTreeIdx)
{
return;
}
Standard_Integer aStack[32];
Standard_Integer aHead = -1;
for (;;)
{
if (!anObjectsTree->IsOuter (aNode))
const Standard_Boolean isTrsfPers = aBVHTreeIdx == 1;
if (isTrsfPers)
{
const Standard_Integer aLeftChildIdx = anObjectsTree->LeftChild (aNode);
const Standard_Integer aRightChildIdx = anObjectsTree->RightChild (aNode);
const Standard_Boolean isLeftChildIn =
mySelectingVolumeMgr.Overlaps (anObjectsTree->MinPoint (aLeftChildIdx),
anObjectsTree->MaxPoint (aLeftChildIdx));
const Standard_Boolean isRightChildIn =
mySelectingVolumeMgr.Overlaps (anObjectsTree->MinPoint (aRightChildIdx),
anObjectsTree->MaxPoint (aRightChildIdx));
if (isLeftChildIn
&& isRightChildIn)
if (mySelectableObjectsTrsfPers.Size() == 0)
{
aNode = aLeftChildIdx;
++aHead;
aStack[aHead] = aRightChildIdx;
continue;
}
else if (isLeftChildIn
|| isRightChildIn)
const Graphic3d_Mat4d& aProjection = mySelectingVolumeMgr.ProjectionMatrix();
const Graphic3d_Mat4d& aWorldView = mySelectingVolumeMgr.WorldViewMatrix();
const Graphic3d_WorldViewProjState& aWVPState = mySelectingVolumeMgr.WorldViewProjState();
aBVHTree = mySelectableObjectsTrsfPers.BVH (aProjection, aWorldView, aWVPState);
}
else
{
if (mySelectableObjects.Size() == 0)
{
aNode = isLeftChildIn ? aLeftChildIdx : aRightChildIdx;
continue;
}
aBVHTree = mySelectableObjects.BVH();
}
Standard_Integer aNode = 0;
if (!mySelectingVolumeMgr.Overlaps (aBVHTree->MinPoint (0),
aBVHTree->MaxPoint (0)))
{
continue;
}
Standard_Integer aStack[32];
Standard_Integer aHead = -1;
for (;;)
{
if (!aBVHTree->IsOuter (aNode))
{
const Standard_Integer aLeftChildIdx = aBVHTree->LeftChild (aNode);
const Standard_Integer aRightChildIdx = aBVHTree->RightChild (aNode);
const Standard_Boolean isLeftChildIn =
mySelectingVolumeMgr.Overlaps (aBVHTree->MinPoint (aLeftChildIdx),
aBVHTree->MaxPoint (aLeftChildIdx));
const Standard_Boolean isRightChildIn =
mySelectingVolumeMgr.Overlaps (aBVHTree->MinPoint (aRightChildIdx),
aBVHTree->MaxPoint (aRightChildIdx));
if (isLeftChildIn
&& isRightChildIn)
{
aNode = aLeftChildIdx;
++aHead;
aStack[aHead] = aRightChildIdx;
}
else if (isLeftChildIn
|| isRightChildIn)
{
aNode = isLeftChildIn ? aLeftChildIdx : aRightChildIdx;
}
else
{
if (aHead < 0)
{
break;
}
aNode = aStack[aHead];
--aHead;
}
}
else
{
Standard_Integer aStartIdx = aBVHTree->BegPrimitive (aNode);
Standard_Integer anEndIdx = aBVHTree->EndPrimitive (aNode);
for (Standard_Integer anIdx = aStartIdx; anIdx <= anEndIdx; ++anIdx)
{
Handle(SelectMgr_SelectableObject) aSelectableObject =
isTrsfPers ? mySelectableObjectsTrsfPers.GetObjectById (anIdx)
: mySelectableObjects.GetObjectById (anIdx);
traverseObject (aSelectableObject);
}
if (aHead < 0)
{
break;
@@ -440,22 +502,6 @@ void SelectMgr_ViewerSelector::TraverseSensitives()
--aHead;
}
}
else
{
Standard_Integer aStartIdx = anObjectsTree->BegPrimitive (aNode);
Standard_Integer anEndIdx = anObjectsTree->EndPrimitive (aNode);
for (Standard_Integer anIdx = aStartIdx; anIdx <= anEndIdx; ++anIdx)
{
traverseObject (mySelectableObjects->GetObjectById (anIdx));
}
if (aHead < 0)
{
break;
}
aNode = aStack[aHead];
--aHead;
}
}
SortResult();
@@ -549,7 +595,8 @@ Handle(SelectMgr_EntityOwner) SelectMgr_ViewerSelector::Picked(const Standard_In
//==================================================
Standard_Boolean SelectMgr_ViewerSelector::Contains (const Handle(SelectMgr_SelectableObject)& theObject) const
{
return mySelectableObjects->Contains (theObject);
return mySelectableObjects.Contains (theObject)
|| mySelectableObjectsTrsfPers.Contains (theObject);
}
//==================================================
@@ -560,7 +607,7 @@ Standard_Boolean SelectMgr_ViewerSelector::Modes (const Handle(SelectMgr_Selecta
TColStd_ListOfInteger& theModeList,
const SelectMgr_StateOfSelection theWantedState) const
{
Standard_Boolean hasActivatedStates = mySelectableObjects->Contains (theSelectableObject);
Standard_Boolean hasActivatedStates = Contains (theSelectableObject);
for (theSelectableObject->Init(); theSelectableObject->More(); theSelectableObject->Next())
{
if (theWantedState == SelectMgr_SOS_Any)
@@ -583,7 +630,7 @@ Standard_Boolean SelectMgr_ViewerSelector::Modes (const Handle(SelectMgr_Selecta
Standard_Boolean SelectMgr_ViewerSelector::IsActive (const Handle(SelectMgr_SelectableObject)& theSelectableObject,
const Standard_Integer theMode) const
{
if (!mySelectableObjects->Contains (theSelectableObject))
if (!Contains (theSelectableObject))
return Standard_False;
for (theSelectableObject->Init(); theSelectableObject->More(); theSelectableObject->Next())
@@ -604,7 +651,7 @@ Standard_Boolean SelectMgr_ViewerSelector::IsActive (const Handle(SelectMgr_Sele
Standard_Boolean SelectMgr_ViewerSelector::IsInside (const Handle(SelectMgr_SelectableObject)& theSelectableObject,
const Standard_Integer theMode) const
{
if (!mySelectableObjects->Contains (theSelectableObject))
if (!Contains (theSelectableObject))
return Standard_False;
for (theSelectableObject->Init(); theSelectableObject->More(); theSelectableObject->Next())
@@ -656,7 +703,7 @@ TCollection_AsciiString SelectMgr_ViewerSelector::Status (const Handle(SelectMgr
}
}
if (mySelectableObjects->Contains (theSelectableObject))
if (!Contains (theSelectableObject))
{
aStatus = aStatus + "Not Present in the selector\n\n";
}
@@ -711,7 +758,15 @@ void SelectMgr_ViewerSelector::AddSelectableObject (const Handle(SelectMgr_Selec
{
if (!myMapOfObjectSensitives.IsBound (theObject))
{
mySelectableObjects->Append (theObject);
if (!theObject->TransformPersistence().Flags)
{
mySelectableObjects.Append (theObject);
}
else
{
mySelectableObjectsTrsfPers.Append (theObject);
}
NCollection_Handle<SelectMgr_SensitiveEntitySet> anEntitySet = new SelectMgr_SensitiveEntitySet();
myMapOfObjectSensitives.Bind (theObject, anEntitySet);
}
@@ -746,8 +801,11 @@ void SelectMgr_ViewerSelector::RemoveSelectableObject (const Handle(SelectMgr_Se
{
if (myMapOfObjectSensitives.IsBound (theObject))
{
if (!mySelectableObjects.Remove (theObject))
{
mySelectableObjectsTrsfPers.Remove (theObject);
}
myMapOfObjectSensitives.UnBind (theObject);
mySelectableObjects->Remove (theObject);
}
}
@@ -773,11 +831,17 @@ void SelectMgr_ViewerSelector::RemoveSelectionOfObject (const Handle(SelectMgr_S
//=======================================================================
void SelectMgr_ViewerSelector::RebuildObjectsTree (const Standard_Boolean theIsForce)
{
mySelectableObjects->MarkDirty();
mySelectableObjects.MarkDirty();
mySelectableObjectsTrsfPers.MarkDirty();
if (theIsForce)
{
mySelectableObjects->BVH();
const Graphic3d_Mat4d& aProjection = mySelectingVolumeMgr.ProjectionMatrix();
const Graphic3d_Mat4d& aWorldView = mySelectingVolumeMgr.WorldViewMatrix();
const Graphic3d_WorldViewProjState& aWVPState = mySelectingVolumeMgr.WorldViewProjState();
mySelectableObjects.BVH();
mySelectableObjectsTrsfPers.BVH (aProjection, aWorldView, aWVPState);
}
}
@@ -789,7 +853,7 @@ void SelectMgr_ViewerSelector::RebuildObjectsTree (const Standard_Boolean theIsF
void SelectMgr_ViewerSelector::RebuildSensitivesTree (const Handle(SelectMgr_SelectableObject)& theObject,
const Standard_Boolean theIsForce)
{
if (!mySelectableObjects->Contains (theObject))
if (!Contains (theObject))
return;
NCollection_Handle<SelectMgr_SensitiveEntitySet>& anEntitySet = myMapOfObjectSensitives.ChangeFind (theObject);

View File

@@ -36,6 +36,7 @@
#include <SelectMgr_Selection.hxx>
#include <SelectMgr_SelectableObject.hxx>
#include <SelectMgr_SelectableObjectSet.hxx>
#include <SelectMgr_SelectableObjectTrsfPersSet.hxx>
#include <SelectMgr_StateOfSelection.hxx>
#include <Standard_OStream.hxx>
@@ -63,7 +64,7 @@ class SelectMgr_ToleranceMap
public:
//! Sets tolerance values to -1.0
SelectMgr_ToleranceMap();
Standard_EXPORT SelectMgr_ToleranceMap();
Standard_EXPORT ~SelectMgr_ToleranceMap();
@@ -232,21 +233,21 @@ public:
const Standard_Boolean theIsForce = Standard_False);
//! Initializes internal iterator for stored detected sensitive entities
Standard_EXPORT void InitDetected();
void InitDetected();
//! Makes a step along the map of detected sensitive entities and their owners
Standard_EXPORT void NextDetected();
void NextDetected();
//! Returns true if iterator of map of detected sensitive entities has reached
//! its end
Standard_EXPORT Standard_Boolean MoreDetected();
Standard_Boolean MoreDetected();
//! Returns sensitive entity that was detected during the previous run of
//! selection algorithm
Standard_EXPORT const Handle(SelectBasics_SensitiveEntity)& DetectedEntity() const;
//! Returns instance of selecting volume manager of the viewer selector
Standard_EXPORT SelectMgr_SelectingVolumeManager& GetManager();
SelectMgr_SelectingVolumeManager& GetManager();
//! Marks all added sensitive entities of all objects as non-selectable
Standard_EXPORT void ResetSelectionActivationStatus();
@@ -309,12 +310,13 @@ private:
protected:
Standard_Boolean preferclosest;
Standard_Boolean myToUpdateTolerance;
SelectMgr_IndexedDataMapOfOwnerCriterion mystored;
SelectMgr_SelectingVolumeManager mySelectingVolumeMgr;
mutable NCollection_Handle<SelectMgr_SelectableObjectSet> mySelectableObjects;
SelectMgr_ToleranceMap myTolerances;
Standard_Boolean preferclosest;
Standard_Boolean myToUpdateTolerance;
SelectMgr_IndexedDataMapOfOwnerCriterion mystored;
SelectMgr_SelectingVolumeManager mySelectingVolumeMgr;
mutable SelectMgr_SelectableObjectSet mySelectableObjects;
mutable SelectMgr_SelectableObjectTrsfPersSet mySelectableObjectsTrsfPers;
SelectMgr_ToleranceMap myTolerances;
private: