From 825aa485a3546bb2fa7a9978bd83592f25adbacb Mon Sep 17 00:00:00 2001 From: apl Date: Mon, 20 Jul 2015 11:41:38 +0300 Subject: [PATCH] 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. --- src/Graphic3d/FILES | 4 +- src/Graphic3d/Graphic3d_CStructure.cxx | 6 - src/Graphic3d/Graphic3d_CStructure.hxx | 3 +- src/Graphic3d/Graphic3d_CTransPersStruct.hxx | 27 -- src/Graphic3d/Graphic3d_Camera.cxx | 52 +-- src/Graphic3d/Graphic3d_Camera.hxx | 21 +- src/Graphic3d/Graphic3d_Structure.cxx | 22 +- src/Graphic3d/Graphic3d_Structure.hxx | 6 +- src/Graphic3d/Graphic3d_Structure.lxx | 9 + src/Graphic3d/Graphic3d_TransformPers.hxx | 357 ++++++++++++++++++ .../Graphic3d_TransformUtils.hxx} | 240 +++++------- .../Graphic3d_WorldViewProjState.hxx | 161 ++++++++ .../InterfaceGraphic_telem.hxx | 10 - src/OpenGl/FILES | 5 +- src/OpenGl/OpenGl_BVHClipPrimitiveSet.cxx | 36 +- src/OpenGl/OpenGl_BVHClipPrimitiveSet.hxx | 16 +- .../OpenGl_BVHClipPrimitiveTrsfPersSet.cxx | 170 +++++++++ .../OpenGl_BVHClipPrimitiveTrsfPersSet.hxx | 106 ++++++ src/OpenGl/OpenGl_BVHTreeSelector.cxx | 75 ++-- src/OpenGl/OpenGl_BVHTreeSelector.hxx | 43 ++- src/OpenGl/OpenGl_Context.hxx | 8 +- src/OpenGl/OpenGl_GraduatedTrihedron.cxx | 101 ++--- src/OpenGl/OpenGl_Layer.cxx | 145 ++++--- src/OpenGl/OpenGl_Layer.hxx | 32 +- src/OpenGl/OpenGl_MatrixState.hxx | 88 +++++ src/OpenGl/OpenGl_Structure.cxx | 74 ++-- src/OpenGl/OpenGl_Structure.hxx | 8 +- src/OpenGl/OpenGl_StructureShadow.cxx | 4 +- src/OpenGl/OpenGl_Text.cxx | 91 ++--- src/OpenGl/OpenGl_Trihedron.cxx | 31 +- src/OpenGl/OpenGl_Vec.hxx | 41 ++ src/OpenGl/OpenGl_View.cxx | 251 +----------- src/OpenGl/OpenGl_View.hxx | 13 +- src/OpenGl/OpenGl_View_2.cxx | 38 +- src/OpenGl/OpenGl_Window.cxx | 4 +- src/OpenGl/OpenGl_Workspace.cxx | 10 +- src/OpenGl/OpenGl_transform_persistence.hxx | 27 -- src/PrsMgr/PrsMgr_PresentableObject.cxx | 23 +- src/PrsMgr/PrsMgr_PresentableObject.hxx | 9 +- src/PrsMgr/PrsMgr_PresentableObject.lxx | 4 + src/SelectMgr/FILES | 2 + src/SelectMgr/SelectMgr_BaseFrustum.cxx | 45 ++- src/SelectMgr/SelectMgr_BaseFrustum.hxx | 15 +- src/SelectMgr/SelectMgr_FrustumBuilder.cxx | 58 ++- src/SelectMgr/SelectMgr_FrustumBuilder.hxx | 22 +- src/SelectMgr/SelectMgr_SelectableObject.cxx | 15 +- .../SelectMgr_SelectableObjectSet.cxx | 31 +- .../SelectMgr_SelectableObjectSet.hxx | 34 +- .../SelectMgr_SelectableObjectTrsfPersSet.cxx | 164 ++++++++ .../SelectMgr_SelectableObjectTrsfPersSet.hxx | 115 ++++++ .../SelectMgr_SelectingVolumeManager.cxx | 37 +- .../SelectMgr_SelectingVolumeManager.hxx | 15 +- src/SelectMgr/SelectMgr_ViewerSelector.cxx | 190 ++++++---- src/SelectMgr/SelectMgr_ViewerSelector.hxx | 24 +- src/StdSelect/StdSelect_ViewerSelector3d.cxx | 127 ++++--- src/StdSelect/StdSelect_ViewerSelector3d.hxx | 11 +- src/ViewerTest/ViewerTest.cxx | 10 +- src/Visual3d/Visual3d_View.cxx | 99 +++-- tests/bugs/vis/bug26344 | 81 ++++ 59 files changed, 2317 insertions(+), 1149 deletions(-) delete mode 100644 src/Graphic3d/Graphic3d_CTransPersStruct.hxx create mode 100644 src/Graphic3d/Graphic3d_TransformPers.hxx rename src/{OpenGl/OpenGl_Utils.hxx => Graphic3d/Graphic3d_TransformUtils.hxx} (67%) create mode 100644 src/Graphic3d/Graphic3d_WorldViewProjState.hxx create mode 100644 src/OpenGl/OpenGl_BVHClipPrimitiveTrsfPersSet.cxx create mode 100644 src/OpenGl/OpenGl_BVHClipPrimitiveTrsfPersSet.hxx create mode 100644 src/OpenGl/OpenGl_MatrixState.hxx delete mode 100644 src/OpenGl/OpenGl_transform_persistence.hxx create mode 100644 src/SelectMgr/SelectMgr_SelectableObjectTrsfPersSet.cxx create mode 100644 src/SelectMgr/SelectMgr_SelectableObjectTrsfPersSet.hxx create mode 100644 tests/bugs/vis/bug26344 diff --git a/src/Graphic3d/FILES b/src/Graphic3d/FILES index c372cde9cd..3cbda2dc6e 100755 --- a/src/Graphic3d/FILES +++ b/src/Graphic3d/FILES @@ -55,7 +55,6 @@ Graphic3d_CStructure.cxx Graphic3d_CStructure.hxx Graphic3d_CStructurePtr.hxx Graphic3d_CTexture.hxx -Graphic3d_CTransPersStruct.hxx Graphic3d_CUserDraw.hxx Graphic3d_CView.hxx Graphic3d_CycleError.hxx @@ -143,6 +142,8 @@ Graphic3d_TextureParams.hxx Graphic3d_TextureRoot.cxx Graphic3d_TextureRoot.hxx Graphic3d_TransformError.hxx +Graphic3d_TransformPers.hxx +Graphic3d_TransformUtils.hxx Graphic3d_TransModeFlags.hxx Graphic3d_TypeOfBackground.hxx Graphic3d_TypeOfComposition.hxx @@ -169,5 +170,6 @@ Graphic3d_Vertex.hxx Graphic3d_VerticalTextAlignment.hxx Graphic3d_ViewAffinity.cxx Graphic3d_ViewAffinity.hxx +Graphic3d_WorldViewProjState.hxx Graphic3d_ZLayerId.hxx Graphic3d_ZLayerSettings.hxx diff --git a/src/Graphic3d/Graphic3d_CStructure.cxx b/src/Graphic3d/Graphic3d_CStructure.cxx index 415377650d..2097704551 100644 --- a/src/Graphic3d/Graphic3d_CStructure.cxx +++ b/src/Graphic3d/Graphic3d_CStructure.cxx @@ -57,10 +57,4 @@ Graphic3d_CStructure::Graphic3d_CStructure (const Handle(Graphic3d_StructureMana ContextFillArea.IsSet = 0, ContextMarker.IsSet = 0, ContextText.IsSet = 0; - - TransformPersistence.IsSet = 0; - TransformPersistence.Flag = Graphic3d_TMF_None; - TransformPersistence.Point.x = 0.0; - TransformPersistence.Point.y = 0.0; - TransformPersistence.Point.z = 0.0; } diff --git a/src/Graphic3d/Graphic3d_CStructure.hxx b/src/Graphic3d/Graphic3d_CStructure.hxx index 90239d6d59..adff5b20eb 100644 --- a/src/Graphic3d/Graphic3d_CStructure.hxx +++ b/src/Graphic3d/Graphic3d_CStructure.hxx @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -143,7 +144,7 @@ public: unsigned IsMutable : 1; unsigned Is2dText : 1; - CALL_DEF_TRANSFORM_PERSISTENCE TransformPersistence; + Graphic3d_TransformPers TransformPersistence; protected: diff --git a/src/Graphic3d/Graphic3d_CTransPersStruct.hxx b/src/Graphic3d/Graphic3d_CTransPersStruct.hxx deleted file mode 100644 index b7bb0f4ebb..0000000000 --- a/src/Graphic3d/Graphic3d_CTransPersStruct.hxx +++ /dev/null @@ -1,27 +0,0 @@ -// 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. - -/*============================================================================*/ -/*==== Titel: Graphic3d_CTransPersStruct.hxx */ -/*==== Role : */ -/*==== */ -/*==== Implementation: This is a primitive type implemented with typedef */ -/*============================================================================*/ - -#ifndef _Graphic3d_CTransPersStruct_HeaderFile -#define _Graphic3d_CTransPersStruct_HeaderFile - -#include -typedef CALL_DEF_TRANSFORM_PERSISTENCE Graphic3d_CTransPersStruct; - -#endif /*_Graphic3d_CTransPersStruct_HeaderFile*/ diff --git a/src/Graphic3d/Graphic3d_Camera.cxx b/src/Graphic3d/Graphic3d_Camera.cxx index 7646957a04..7b38769e67 100644 --- a/src/Graphic3d/Graphic3d_Camera.cxx +++ b/src/Graphic3d/Graphic3d_Camera.cxx @@ -16,8 +16,9 @@ #include #include -#include #include +#include +#include #include #include @@ -50,9 +51,9 @@ namespace static Standard_Real zEpsilon (const Standard_Real theValue) { if (theValue == 0) - { + { return FLT_EPSILON; - } + } Standard_Real aLogRadix = Log10 (Abs (theValue)) / Log10 (FLT_RADIX); Standard_Real aExp = Floor (aLogRadix); return FLT_EPSILON * Pow (FLT_RADIX, aExp); @@ -79,8 +80,9 @@ Graphic3d_Camera::Graphic3d_Camera() myIOD (0.05), myIODType (IODType_Relative) { - myProjectionState = (Standard_Size)Standard_Atomic_Increment (&THE_STATE_COUNTER); - myOrientationState = (Standard_Size)Standard_Atomic_Increment (&THE_STATE_COUNTER); + myWorldViewProjState.Initialize ((Standard_Size)Standard_Atomic_Increment (&THE_STATE_COUNTER), + (Standard_Size)Standard_Atomic_Increment (&THE_STATE_COUNTER), + this); } // ======================================================================= @@ -89,6 +91,8 @@ Graphic3d_Camera::Graphic3d_Camera() // ======================================================================= Graphic3d_Camera::Graphic3d_Camera (const Handle(Graphic3d_Camera)& theOther) { + myWorldViewProjState.Initialize (this); + Copy (theOther); } @@ -98,17 +102,18 @@ Graphic3d_Camera::Graphic3d_Camera (const Handle(Graphic3d_Camera)& theOther) // ======================================================================= void Graphic3d_Camera::CopyMappingData (const Handle(Graphic3d_Camera)& theOtherCamera) { - myFOVy = theOtherCamera->myFOVy; - myZNear = theOtherCamera->myZNear; - myZFar = theOtherCamera->myZFar; - myAspect = theOtherCamera->myAspect; - myScale = theOtherCamera->myScale; - myZFocus = theOtherCamera->myZFocus; - myZFocusType = theOtherCamera->myZFocusType; - myIOD = theOtherCamera->myIOD; - myIODType = theOtherCamera->myIODType; - myProjType = theOtherCamera->myProjType; - myProjectionState = theOtherCamera->myProjectionState; + myFOVy = theOtherCamera->myFOVy; + myZNear = theOtherCamera->myZNear; + myZFar = theOtherCamera->myZFar; + myAspect = theOtherCamera->myAspect; + myScale = theOtherCamera->myScale; + myZFocus = theOtherCamera->myZFocus; + myZFocusType = theOtherCamera->myZFocusType; + myIOD = theOtherCamera->myIOD; + myIODType = theOtherCamera->myIODType; + myProjType = theOtherCamera->myProjType; + + myWorldViewProjState.ProjectionState() = theOtherCamera->ProjectionState(); InvalidateProjection(); } @@ -119,11 +124,12 @@ void Graphic3d_Camera::CopyMappingData (const Handle(Graphic3d_Camera)& theOther // ======================================================================= void Graphic3d_Camera::CopyOrientationData (const Handle(Graphic3d_Camera)& theOtherCamera) { - myUp = theOtherCamera->myUp; - myEye = theOtherCamera->myEye; - myCenter = theOtherCamera->myCenter; - myAxialScale = theOtherCamera->myAxialScale; - myOrientationState = theOtherCamera->myOrientationState; + myUp = theOtherCamera->myUp; + myEye = theOtherCamera->myEye; + myCenter = theOtherCamera->myCenter; + myAxialScale = theOtherCamera->myAxialScale; + + myWorldViewProjState.WorldViewState() = theOtherCamera->WorldViewState(); InvalidateOrientation(); } @@ -847,7 +853,7 @@ void Graphic3d_Camera::InvalidateProjection() { myMatricesD.ResetProjection(); myMatricesF.ResetProjection(); - myProjectionState = (Standard_Size)Standard_Atomic_Increment (&THE_STATE_COUNTER); + myWorldViewProjState.ProjectionState() = (Standard_Size)Standard_Atomic_Increment (&THE_STATE_COUNTER); } // ======================================================================= @@ -858,7 +864,7 @@ void Graphic3d_Camera::InvalidateOrientation() { myMatricesD.ResetOrientation(); myMatricesF.ResetOrientation(); - myOrientationState = (Standard_Size)Standard_Atomic_Increment (&THE_STATE_COUNTER); + myWorldViewProjState.WorldViewState() = (Standard_Size)Standard_Atomic_Increment (&THE_STATE_COUNTER); } // ======================================================================= diff --git a/src/Graphic3d/Graphic3d_Camera.hxx b/src/Graphic3d/Graphic3d_Camera.hxx index cdeda3c910..0450205dee 100644 --- a/src/Graphic3d/Graphic3d_Camera.hxx +++ b/src/Graphic3d/Graphic3d_Camera.hxx @@ -19,6 +19,7 @@ #include #include #include +#include #include @@ -31,6 +32,7 @@ #include //! Forward declaration +class Graphic3d_WorldViewProjState; //! Camera class provides object-oriented approach to setting up projection //! and orientation properties of 3D view. @@ -436,16 +438,23 @@ public: //! @name Camera modification state public: + //! @return projection modification state of the camera. + const Graphic3d_WorldViewProjState& WorldViewProjState() const + { + return myWorldViewProjState; + } + + //! Returns modification state of camera projection matrix Standard_Size ProjectionState() const { - return myProjectionState; + return myWorldViewProjState.ProjectionState(); } - //! Returns modification state of camera model-view matrix - Standard_Size ModelViewState() const + //! Returns modification state of camera world view transformation matrix. + Standard_Size WorldViewState() const { - return myOrientationState; + return myWorldViewProjState.WorldViewState(); } //! @name Lazily-computed orientation and projection matrices derived from camera parameters @@ -613,13 +622,11 @@ private: mutable TransformMatrices myMatricesD; mutable TransformMatrices myMatricesF; - mutable Standard_Size myProjectionState; - mutable Standard_Size myOrientationState; + mutable Graphic3d_WorldViewProjState myWorldViewProjState; public: DEFINE_STANDARD_RTTI(Graphic3d_Camera, Standard_Transient); - }; DEFINE_STANDARD_HANDLE (Graphic3d_Camera, Standard_Transient) diff --git a/src/Graphic3d/Graphic3d_Structure.cxx b/src/Graphic3d/Graphic3d_Structure.cxx index dffbf40d09..a6403b4109 100644 --- a/src/Graphic3d/Graphic3d_Structure.cxx +++ b/src/Graphic3d/Graphic3d_Structure.cxx @@ -132,7 +132,7 @@ void Graphic3d_Structure::CalculateBoundBox() { Graphic3d_BndBox4d aBox; addTransformed (aBox, Standard_True); - if (aBox.IsValid() && myCStructure->TransformPersistence.Flag == 0) + if (aBox.IsValid()) { Graphic3d_Vec4 aMinPt (RealToShortReal (aBox.CornerMin().x()), RealToShortReal (aBox.CornerMin().y()), @@ -1689,14 +1689,10 @@ void Graphic3d_Structure::SetTransformPersistence (const Graphic3d_TransModeFlag { if (IsDeleted()) return; - myCStructure->TransformPersistence.Flag = theFlag; - myCStructure->TransformPersistence.Point.x = float (thePoint.X()); - myCStructure->TransformPersistence.Point.y = float (thePoint.Y()); - myCStructure->TransformPersistence.Point.z = float (thePoint.Z()); - myCStructure->UpdateAspects(); - CalculateBoundBox(); - - myCStructure->TransformPersistence.IsSet = 1; + myCStructure->TransformPersistence.Flags = theFlag; + myCStructure->TransformPersistence.Point.x() = thePoint.X(); + myCStructure->TransformPersistence.Point.y() = thePoint.Y(); + myCStructure->TransformPersistence.Point.z() = thePoint.Z(); } //============================================================================= @@ -1705,7 +1701,7 @@ void Graphic3d_Structure::SetTransformPersistence (const Graphic3d_TransModeFlag //============================================================================= Graphic3d_TransModeFlags Graphic3d_Structure::TransformPersistenceMode() const { - return myCStructure->TransformPersistence.Flag; + return myCStructure->TransformPersistence.Flags; } //============================================================================= @@ -1715,9 +1711,9 @@ Graphic3d_TransModeFlags Graphic3d_Structure::TransformPersistenceMode() const gp_Pnt Graphic3d_Structure::TransformPersistencePoint() const { gp_Pnt aPnt (0.0, 0.0, 0.0); - aPnt.SetX (myCStructure->TransformPersistence.Point.x); - aPnt.SetY (myCStructure->TransformPersistence.Point.y); - aPnt.SetZ (myCStructure->TransformPersistence.Point.z); + aPnt.SetX (myCStructure->TransformPersistence.Point.x()); + aPnt.SetY (myCStructure->TransformPersistence.Point.y()); + aPnt.SetZ (myCStructure->TransformPersistence.Point.z()); return aPnt; } diff --git a/src/Graphic3d/Graphic3d_Structure.hxx b/src/Graphic3d/Graphic3d_Structure.hxx index 5cdbfb0164..b86f0078f0 100644 --- a/src/Graphic3d/Graphic3d_Structure.hxx +++ b/src/Graphic3d/Graphic3d_Structure.hxx @@ -38,6 +38,7 @@ #include #include #include +#include #include #include #include @@ -438,7 +439,10 @@ public: //! Get the current point of relative modelling transform persistence Standard_EXPORT gp_Pnt TransformPersistencePoint() const; - + + //! @return transform persistence of the presentable object. + const Graphic3d_TransformPers& TransformPersistence() const; + //! Sets if the structure location has mutable nature (content or location will be changed regularly). Standard_EXPORT void SetMutable (const Standard_Boolean theIsMutable); diff --git a/src/Graphic3d/Graphic3d_Structure.lxx b/src/Graphic3d/Graphic3d_Structure.lxx index 86e9061877..7fd5ec20b0 100644 --- a/src/Graphic3d/Graphic3d_Structure.lxx +++ b/src/Graphic3d/Graphic3d_Structure.lxx @@ -21,3 +21,12 @@ inline const Handle(Graphic3d_CStructure)& Graphic3d_Structure::CStructure() con { return myCStructure; } + +// ======================================================================= +// function : TransformPersistence +// purpose : +// ======================================================================= +inline const Graphic3d_TransformPers& Graphic3d_Structure::TransformPersistence() const +{ + return myCStructure->TransformPersistence; +} diff --git a/src/Graphic3d/Graphic3d_TransformPers.hxx b/src/Graphic3d/Graphic3d_TransformPers.hxx new file mode 100644 index 0000000000..4f5d6ba625 --- /dev/null +++ b/src/Graphic3d/Graphic3d_TransformPers.hxx @@ -0,0 +1,357 @@ +// Created on: 2015-06-18 +// 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 _Graphic3d_TransformPers_HeaderFile +#define _Graphic3d_TransformPers_HeaderFile + +#include +#include +#include +#include +#include +#include + +//! Class for keeping and computing transformation persistence. +class Graphic3d_TransformPers +{ +public: + + DEFINE_STANDARD_ALLOC + + //! Default constructor. + Graphic3d_TransformPers() + : Flags (Graphic3d_TMF_None), + Point (0.0, 0.0, 0.0) {} + + //! Transformation persistence mode flags. + Graphic3d_TransModeFlags Flags; + + //! Reference point for transformation. + Graphic3d_Vec3d Point; + +public: + + //! Apply transformation to bounding box of presentation. + //! @param theProjection [in] the projection transformation matrix. + //! @param theWorldView [in] the world view transformation matrix. + //! @param theViewportWidth [in] the width of viewport (for 2d persistence). + //! @param theViewportHeight [in] the height of viewport (for 2d persistence). + //! @param theBoundingBox [in/out] the bounding box to transform. + template + void Apply (const NCollection_Mat4& theProjection, + const NCollection_Mat4& theWorldView, + const Standard_Integer theViewportWidth, + const Standard_Integer theViewportHeight, + Bnd_Box& theBoundingBox) const; + + //! Apply transformation to bounding box of presentation + //! @param theProjection [in] the projection transformation matrix. + //! @param theWorldView [in] the world view transformation matrix. + //! @param theViewportWidth [in] the width of viewport (for 2d persistence). + //! @param theViewportHeight [in] the height of viewport (for 2d persistence). + //! @param theBoundingBox [in/out] the bounding box to transform. + template + void Apply (const NCollection_Mat4& theProjection, + const NCollection_Mat4& theWorldView, + const Standard_Integer theViewportWidth, + const Standard_Integer theViewportHeight, + BVH_Box& theBoundingBox) const; + + //! Compute transformation. + //! Computed matrix can be applied to model world transformation + //! of an object to implement effect of transformation persistence. + //! @param theProjection [in] the projection transformation matrix. + //! @param theWorldView [in] the world view transformation matrix. + //! @param theViewportWidth [in] the width of viewport (for 2d persistence). + //! @param theViewportHeight [in] the height of viewport (for 2d persistence). + //! @return transformation matrix to be applied to model world transformation of an object. + template + NCollection_Mat4 Compute (const NCollection_Mat4& theProjection, + const NCollection_Mat4& theWorldView, + const Standard_Integer theViewportWidth, + const Standard_Integer theViewportHeight) const; + + template + void Apply (NCollection_Mat4& theProjection, + NCollection_Mat4& theWorldView, + const Standard_Integer theViewportWidth, + const Standard_Integer theViewportHeight) const; +}; + +// ======================================================================= +// function : Apply +// purpose : Apply transformation to world view and projection matrices. +// ======================================================================= +template +void Graphic3d_TransformPers::Apply (NCollection_Mat4& theProjection, + NCollection_Mat4& theWorldView, + const Standard_Integer theViewportWidth, + const Standard_Integer theViewportHeight) const +{ + if (!Flags) + { + return; + } + + if (Flags & Graphic3d_TMF_2d) + { + T aLeft = -static_cast (theViewportWidth / 2); + T aRight = static_cast (theViewportWidth / 2); + T aBottom = -static_cast (theViewportHeight / 2); + T aTop = static_cast (theViewportHeight / 2); + T aGap = static_cast (Point.z()); + if (Point.x() > 0) + { + aLeft -= static_cast (theViewportWidth / 2) - aGap; + aRight -= static_cast (theViewportWidth / 2) - aGap; + } + else if (Point.x() < 0) + { + aLeft += static_cast (theViewportWidth / 2) - aGap; + aRight += static_cast (theViewportWidth / 2) - aGap; + } + if (Point.y() > 0) + { + aBottom -= static_cast (theViewportHeight / 2) - aGap; + aTop -= static_cast (theViewportHeight / 2) - aGap; + } + else if (Point.y() < 0) + { + aBottom += static_cast (theViewportHeight / 2) - aGap; + aTop += static_cast (theViewportHeight / 2) - aGap; + } + if (Flags == Graphic3d_TMF_2d_IsTopDown) + { + const T aTemp = aTop; + aTop = aBottom; + aBottom = aTemp; + } + + Graphic3d_TransformUtils::Ortho2D (theProjection, aLeft, aRight, aBottom, aTop); + + theWorldView.InitIdentity(); + } + else + { + // Compute reference point for transformation in untransformed projection space. + NCollection_Vec4 aRefPoint (static_cast (Point.x()), + static_cast (Point.y()), + static_cast (Point.z()), + static_cast (1.0)); + NCollection_Vec4 aRefPointProj; + if ((Flags & Graphic3d_TMF_PanPers) != Graphic3d_TMF_PanPers) + { + aRefPointProj = theProjection * (theWorldView * aRefPoint); + aRefPointProj /= aRefPointProj.w(); + } + + // Prevent zooming. + if ((Flags & Graphic3d_TMF_ZoomPers) || (Flags == Graphic3d_TMF_TriedronPers)) + { + // Compute fixed-zoom multiplier. Actually function works ugly with TelPerspective! + const T aDet2 = static_cast (0.002) / Max (theProjection.GetValue (1, 1), theProjection.GetValue (0, 0)); + theProjection.ChangeValue (0, 0) *= aDet2; + theProjection.ChangeValue (1, 1) *= aDet2; + theProjection.ChangeValue (2, 2) *= aDet2; + } + + // Prevent translation by nullifying translation component. + if ((Flags & Graphic3d_TMF_PanPers) || Flags == Graphic3d_TMF_TriedronPers) + { + theWorldView .SetValue (0, 3, static_cast (0.0)); + theWorldView .SetValue (1, 3, static_cast (0.0)); + theWorldView .SetValue (2, 3, static_cast (0.0)); + theProjection.SetValue (0, 3, static_cast (0.0)); + theProjection.SetValue (1, 3, static_cast (0.0)); + theProjection.SetValue (2, 3, static_cast (0.0)); + } + + // Prevent scaling-on-axis. + if (Flags & Graphic3d_TMF_ZoomPers) + { + NCollection_Vec3 aVecX = theWorldView.GetColumn (0).xyz(); + NCollection_Vec3 aVecY = theWorldView.GetColumn (1).xyz(); + NCollection_Vec3 aVecZ = theWorldView.GetColumn (2).xyz(); + T aScaleX = aVecX.Modulus(); + T aScaleY = aVecY.Modulus(); + T aScaleZ = aVecZ.Modulus(); + for (Standard_Integer anI = 0; anI < 3; ++anI) + { + theWorldView.ChangeValue (0, anI) /= aScaleX; + theWorldView.ChangeValue (1, anI) /= aScaleY; + theWorldView.ChangeValue (2, anI) /= aScaleZ; + } + } + + // Prevent rotation by nullifying rotation component. + if (Flags & Graphic3d_TMF_RotatePers) + { + theWorldView.SetValue (0, 0, static_cast (1.0)); + theWorldView.SetValue (1, 0, static_cast (0.0)); + theWorldView.SetValue (2, 0, static_cast (0.0)); + + theWorldView.SetValue (0, 1, static_cast (0.0)); + theWorldView.SetValue (1, 1, static_cast (1.0)); + theWorldView.SetValue (2, 1, static_cast (0.0)); + + theWorldView.SetValue (0, 2, static_cast (0.0)); + theWorldView.SetValue (1, 2, static_cast (0.0)); + theWorldView.SetValue (2, 2, static_cast (1.0)); + } + + if (Flags == Graphic3d_TMF_TriedronPers) + { + if (Point.x() != 0.0 && Point.y() != 0.0) + { + NCollection_Mat4 anUnviewMat; + + if (!(theProjection).Inverted (anUnviewMat)) + { + Standard_ProgramError::Raise ("Graphic3d_TransformPers::Apply, can not inverse projection matrix."); + } + + NCollection_Vec4 aProjMax (static_cast ( 1.0), static_cast ( 1.0), static_cast (0.0), static_cast (1.0)); + NCollection_Vec4 aProjMin (static_cast (-1.0), static_cast (-1.0), static_cast (0.0), static_cast (1.0)); + NCollection_Vec4 aViewMax = anUnviewMat * aProjMax; + NCollection_Vec4 aViewMin = anUnviewMat * aProjMin; + + aViewMax /= aViewMax.w(); + aViewMin /= aViewMin.w(); + + T aMoveX = static_cast (0.5) * (aViewMax.x() - aViewMin.x() - static_cast (Point.z())); + T aMoveY = static_cast (0.5) * (aViewMax.y() - aViewMin.y() - static_cast (Point.z())); + + aMoveX = (Point.x() > 0.0) ? aMoveX : -aMoveX; + aMoveY = (Point.y() > 0.0) ? aMoveY : -aMoveY; + + Graphic3d_TransformUtils::Translate (theProjection, aMoveX, aMoveY, static_cast (0.0)); + } + } + else if ((Flags & Graphic3d_TMF_PanPers) != Graphic3d_TMF_PanPers) + { + NCollection_Mat4 anUnviewMat; + + if (!(theProjection * theWorldView).Inverted (anUnviewMat)) + { + Standard_ProgramError::Raise ("Graphic3d_TransformPers::Apply, can not inverse world view projection matrix."); + } + + // Move to reference point location in transformed view projection space. + aRefPoint = anUnviewMat * aRefPointProj; + aRefPoint /= aRefPoint.w(); + + Graphic3d_TransformUtils::Translate (theWorldView, aRefPoint.x(), aRefPoint.y(), aRefPoint.z()); + } + } +} + +// ======================================================================= +// function : Apply +// purpose : Apply transformation to bounding box of presentation. +// ======================================================================= +template +void Graphic3d_TransformPers::Apply (const NCollection_Mat4& theProjection, + const NCollection_Mat4& theWorldView, + const Standard_Integer theViewportWidth, + const Standard_Integer theViewportHeight, + Bnd_Box& theBoundingBox) const +{ + T aXmin, aYmin, aZmin, aXmax, aYmax, aZmax; + + theBoundingBox.Get (aXmin, aYmin, aZmin, aXmax, aYmax, aZmax); + + typename BVH_Box::BVH_VecNt aMin (aXmin, aYmin, aZmin, static_cast (1.0)); + typename BVH_Box::BVH_VecNt aMax (aXmax, aYmax, aZmax, static_cast (1.0)); + BVH_Box aBBox (aMin, aMax); + + Apply (theProjection, theWorldView, theViewportWidth, theViewportHeight, aBBox); + + theBoundingBox = Bnd_Box(); + theBoundingBox.Update (aBBox.CornerMin().x(), aBBox.CornerMin().y(), aBBox.CornerMin().z(), + aBBox.CornerMax().x(), aBBox.CornerMax().y(), aBBox.CornerMax().z()); +} + +// ======================================================================= +// function : Apply +// purpose : Apply transformation to bounding box of presentation. +// ======================================================================= +template +void Graphic3d_TransformPers::Apply (const NCollection_Mat4& theProjection, + const NCollection_Mat4& theWorldView, + const Standard_Integer theViewportWidth, + const Standard_Integer theViewportHeight, + BVH_Box& theBoundingBox) const +{ + NCollection_Mat4 aTPers = Compute (theProjection, theWorldView, theViewportWidth, theViewportHeight); + + if (aTPers.IsIdentity()) + { + return; + } + + const typename BVH_Box::BVH_VecNt& aMin = theBoundingBox.CornerMin(); + const typename BVH_Box::BVH_VecNt& aMax = theBoundingBox.CornerMax(); + + typename BVH_Box::BVH_VecNt anArrayOfCorners[8]; + anArrayOfCorners[0] = typename BVH_Box::BVH_VecNt (aMin.x(), aMin.y(), aMin.z(), static_cast (1.0)); + anArrayOfCorners[1] = typename BVH_Box::BVH_VecNt (aMin.x(), aMin.y(), aMax.z(), static_cast (1.0)); + anArrayOfCorners[2] = typename BVH_Box::BVH_VecNt (aMin.x(), aMax.y(), aMin.z(), static_cast (1.0)); + anArrayOfCorners[3] = typename BVH_Box::BVH_VecNt (aMin.x(), aMax.y(), aMax.z(), static_cast (1.0)); + anArrayOfCorners[4] = typename BVH_Box::BVH_VecNt (aMax.x(), aMin.y(), aMin.z(), static_cast (1.0)); + anArrayOfCorners[5] = typename BVH_Box::BVH_VecNt (aMax.x(), aMin.y(), aMax.z(), static_cast (1.0)); + anArrayOfCorners[6] = typename BVH_Box::BVH_VecNt (aMax.x(), aMax.y(), aMin.z(), static_cast (1.0)); + anArrayOfCorners[7] = typename BVH_Box::BVH_VecNt (aMax.x(), aMax.y(), aMax.z(), static_cast (1.0)); + + theBoundingBox.Clear(); + for (Standard_Integer anIt = 0; anIt < 8; ++anIt) + { + typename BVH_Box::BVH_VecNt& aCorner = anArrayOfCorners[anIt]; + aCorner = aTPers * aCorner; + aCorner /= aCorner.w(); + theBoundingBox.Add (aCorner); + } +} + +// ======================================================================= +// function : Compute +// purpose : Compute transformation. +// ======================================================================= +template +NCollection_Mat4 Graphic3d_TransformPers::Compute (const NCollection_Mat4& theProjection, + const NCollection_Mat4& theWorldView, + const Standard_Integer theViewportWidth, + const Standard_Integer theViewportHeight) const +{ + if (Flags == Graphic3d_TMF_None) + { + return NCollection_Mat4(); + } + + NCollection_Mat4 anUnviewMat; + + if (!(theProjection * theWorldView).Inverted (anUnviewMat)) + { + return NCollection_Mat4(); + } + + NCollection_Mat4 aProjection (theProjection); + NCollection_Mat4 aWorldView (theWorldView); + + Apply (aProjection, aWorldView, theViewportWidth, theViewportHeight); + + return anUnviewMat * (aProjection * aWorldView); +} + +#endif // _Graphic3d_TransformPers_HeaderFile diff --git a/src/OpenGl/OpenGl_Utils.hxx b/src/Graphic3d/Graphic3d_TransformUtils.hxx similarity index 67% rename from src/OpenGl/OpenGl_Utils.hxx rename to src/Graphic3d/Graphic3d_TransformUtils.hxx index 39702c147d..f2f4c7c391 100644 --- a/src/OpenGl/OpenGl_Utils.hxx +++ b/src/Graphic3d/Graphic3d_TransformUtils.hxx @@ -1,6 +1,5 @@ -// Created on: 2014-09-30 -// Created by: Denis BOGOLEPOV -// Copyright (c) 2014 OPEN CASCADE SAS +// Created on: 2015-06-18 +// Copyright (c) 2015 OPEN CASCADE SAS // // This file is part of Open CASCADE Technology software library. // @@ -13,128 +12,52 @@ // Alternatively, this file may be used under the terms of Open CASCADE // commercial license or contractual agreement. -#ifndef _OpenGl_Utils_H__ -#define _OpenGl_Utils_H__ +#ifndef _Graphic3d_TransformUtils_HeaderFile +#define _Graphic3d_TransformUtils_HeaderFile -#include -#include +#include +#include // M_PI -//! Helper class that implements some functionality of GLU library. -namespace OpenGl_Utils +//! Helper class that implements transformation matrix functionality. +namespace Graphic3d_TransformUtils { + template struct MatrixType {}; - //! Matrix type selector. - template - struct MatrixType { - // - }; + template<> struct MatrixType { typedef Graphic3d_Mat4d Mat4; }; - template<> - struct MatrixType { - typedef OpenGl_Mat4d Mat4; - }; - - template<> - struct MatrixType { - typedef OpenGl_Mat4 Mat4; - }; + template<> struct MatrixType { typedef Graphic3d_Mat4 Mat4; }; - //! Vector type selector. - template - struct VectorType { - // - }; - - template<> - struct VectorType { - typedef OpenGl_Vec2d Vec2; - typedef OpenGl_Vec3d Vec3; - typedef OpenGl_Vec4d Vec4; - }; + template struct VectorType {}; - template<> - struct VectorType { - typedef OpenGl_Vec2 Vec2; - typedef OpenGl_Vec3 Vec3; - typedef OpenGl_Vec4 Vec4; + template<> struct VectorType { + typedef Graphic3d_Vec2d Vec2; + typedef Graphic3d_Vec3d Vec3; + typedef Graphic3d_Vec4d Vec4; }; - //! Software implementation for OpenGL matrix stack. - template - class MatrixState - { - public: - - //! Constructs matrix state object. - MatrixState() - : myStack (8), - myStackHead (-1) - { - // - } - - //! Pushes current matrix into stack. - void Push() - { - if (++myStackHead >= myStack.Size()) - { - myStack.Append (myCurrent); - } - else - { - myStack.SetValue (myStackHead, myCurrent); - } - } - - //! Pops matrix from stack to current. - void Pop() - { - Standard_ASSERT_RETURN (myStackHead != -1, "Matrix stack already empty when MatrixState.Pop() called.", ); - myCurrent = myStack.Value (myStackHead--); - } - - //! @return current matrix. - const typename MatrixType::Mat4& Current() - { - return myCurrent; - } - - //! Sets given matrix as current. - void SetCurrent (const typename MatrixType::Mat4& theNewCurrent) - { - myCurrent = theNewCurrent; - } - - //! Sets given matrix as current. - template - void SetCurrent (const typename MatrixType::Mat4& theNewCurrent) - { - myCurrent.Convert (theNewCurrent); - } - - //! Sets current matrix to identity. - void SetIdentity() - { - myCurrent = typename MatrixType::Mat4(); - } - - private: - - NCollection_Vector::Mat4> myStack; //!< Collection used to maintenance matrix stack - typename MatrixType::Mat4 myCurrent; //!< Current matrix - Standard_Integer myStackHead; //!< Index of stack head - + template<> struct VectorType { + typedef Graphic3d_Vec2 Vec2; + typedef Graphic3d_Vec3 Vec3; + typedef Graphic3d_Vec4 Vec4; }; //! Constructs a 3D orthographic projection matrix. template static void Ortho (typename MatrixType::Mat4& theOut, - const T theLeft, const T theRight, const T theBottom, const T theTop, const T theZNear, const T theZFar); + const T theLeft, + const T theRight, + const T theBottom, + const T theTop, + const T theZNear, + const T theZFar); //! Constructs a 2D orthographic projection matrix. template static void Ortho2D (typename MatrixType::Mat4& theOut, - const T theLeft, const T theRight, const T theBottom, const T theTop); + const T theLeft, + const T theRight, + const T theBottom, + const T theTop); //! Maps object coordinates to window coordinates. template @@ -189,7 +112,6 @@ namespace OpenGl_Utils T theX, T theY, T theZ); - } // ======================================================================= @@ -197,11 +119,11 @@ namespace OpenGl_Utils // purpose : Constructs a 4x4 rotation matrix // ======================================================================= template -void OpenGl_Utils::Rotate (typename MatrixType::Mat4& theOut, - T theA, - T theX, - T theY, - T theZ) +void Graphic3d_TransformUtils::Rotate (typename MatrixType::Mat4& theOut, + T theA, + T theX, + T theY, + T theZ) { typename MatrixType::Mat4 aMat; ConstructRotate (aMat, theA, theX, theY, theZ); @@ -213,10 +135,10 @@ void OpenGl_Utils::Rotate (typename MatrixType::Mat4& theOut, // purpose : Constructs a 4x4 translation matrix // ======================================================================= template -void OpenGl_Utils::Translate (typename MatrixType::Mat4& theOut, - T theX, - T theY, - T theZ) +void Graphic3d_TransformUtils::Translate (typename MatrixType::Mat4& theOut, + T theX, + T theY, + T theZ) { theOut.ChangeValue (0, 3) = theOut.GetValue (0, 0) * theX + theOut.GetValue (0, 1) * theY + @@ -244,10 +166,10 @@ void OpenGl_Utils::Translate (typename MatrixType::Mat4& theOut, // purpose : Constructs a 4x4 scaling matrix // ======================================================================= template -void OpenGl_Utils::Scale (typename MatrixType::Mat4& theOut, - T theX, - T theY, - T theZ) +void Graphic3d_TransformUtils::Scale (typename MatrixType::Mat4& theOut, + T theX, + T theY, + T theZ) { theOut.ChangeValue (0, 0) *= theX; theOut.ChangeValue (1, 0) *= theX; @@ -270,7 +192,11 @@ void OpenGl_Utils::Scale (typename MatrixType::Mat4& theOut, // purpose : Constructs a 4x4 rotation matrix // ======================================================================= template -void OpenGl_Utils::ConstructRotate (typename MatrixType::Mat4& theOut, T theA, T theX, T theY, T theZ) +void Graphic3d_TransformUtils::ConstructRotate (typename MatrixType::Mat4& theOut, + T theA, + T theX, + T theY, + T theZ) { const T aSin = std::sin (theA * static_cast (M_PI / 180.0)); const T aCos = std::cos (theA * static_cast (M_PI / 180.0)); @@ -287,7 +213,7 @@ void OpenGl_Utils::ConstructRotate (typename MatrixType::Mat4& theOut, T theA && (theY == static_cast (0.0)) && (theZ != static_cast (0.0)); - if (isOnlyX) // Rotation only around X + if (isOnlyX) // Rotation only around X. { theOut.SetValue (1, 1, aCos); theOut.SetValue (2, 2, aCos); @@ -305,7 +231,7 @@ void OpenGl_Utils::ConstructRotate (typename MatrixType::Mat4& theOut, T theA return; } - else if (isOnlyY) // Rotation only around Y + else if (isOnlyY) // Rotation only around Y. { theOut.SetValue (0, 0, aCos); theOut.SetValue (2, 2, aCos); @@ -323,7 +249,7 @@ void OpenGl_Utils::ConstructRotate (typename MatrixType::Mat4& theOut, T theA return; } - else if (isOnlyZ) // Rotation only around Z + else if (isOnlyZ) // Rotation only around Z. { theOut.SetValue (0, 0, aCos); theOut.SetValue (1, 1, aCos); @@ -346,7 +272,7 @@ void OpenGl_Utils::ConstructRotate (typename MatrixType::Mat4& theOut, T theA if (aNorm <= static_cast (1.0e-4)) { - return; // negligible rotation + return; // Negligible rotation. } aNorm = static_cast (1.0) / aNorm; @@ -385,8 +311,13 @@ void OpenGl_Utils::ConstructRotate (typename MatrixType::Mat4& theOut, T theA // purpose : Constructs a 3D orthographic projection matrix // ======================================================================= template -void OpenGl_Utils::Ortho (typename MatrixType::Mat4& theOut, - const T theLeft, const T theRight, const T theBottom, const T theTop, const T theZNear, const T theZFar) +void Graphic3d_TransformUtils::Ortho (typename MatrixType::Mat4& theOut, + const T theLeft, + const T theRight, + const T theBottom, + const T theTop, + const T theZNear, + const T theZFar) { theOut.InitIdentity(); @@ -410,8 +341,11 @@ void OpenGl_Utils::Ortho (typename MatrixType::Mat4& theOut, // purpose : Constructs a 2D orthographic projection matrix // ======================================================================= template -void OpenGl_Utils::Ortho2D (typename MatrixType::Mat4& theOut, - const T theLeft, const T theRight, const T theBottom, const T theTop) +void Graphic3d_TransformUtils::Ortho2D (typename MatrixType::Mat4& theOut, + const T theLeft, + const T theRight, + const T theBottom, + const T theTop) { Ortho (theOut, theLeft, theRight, theBottom, theTop, static_cast (-1.0), static_cast (1.0)); } @@ -421,15 +355,15 @@ void OpenGl_Utils::Ortho2D (typename MatrixType::Mat4& theOut, // purpose : Maps object coordinates to window coordinates // ======================================================================= template -static Standard_Boolean OpenGl_Utils::Project (const T theObjX, - const T theObjY, - const T theObjZ, - const typename MatrixType::Mat4& theModViewMat, - const typename MatrixType::Mat4& theProjectMat, - const Standard_Integer theViewport[4], - T& theWinX, - T& theWinY, - T& theWinZ) +static Standard_Boolean Graphic3d_TransformUtils::Project (const T theObjX, + const T theObjY, + const T theObjZ, + const typename MatrixType::Mat4& theModViewMat, + const typename MatrixType::Mat4& theProjectMat, + const Standard_Integer theViewport[4], + T& theWinX, + T& theWinY, + T& theWinZ) { typename VectorType::Vec4 anIn (theObjX, theObjY, theObjZ, static_cast (1.0)); @@ -446,12 +380,12 @@ static Standard_Boolean OpenGl_Utils::Project (const T anOut.y() *= anOut.w(); anOut.z() *= anOut.w(); - // Map x, y and z to range 0-1 + // Map x, y and z to range 0-1. anOut.x() = anOut.x() * static_cast (0.5) + static_cast (0.5); anOut.y() = anOut.y() * static_cast (0.5) + static_cast (0.5); anOut.z() = anOut.z() * static_cast (0.5) + static_cast (0.5); - // Map x,y to viewport + // Map x,y to viewport. anOut.x() = anOut.x() * theViewport[2] + theViewport[0]; anOut.y() = anOut.y() * theViewport[3] + theViewport[1]; @@ -467,15 +401,15 @@ static Standard_Boolean OpenGl_Utils::Project (const T // purpose : Maps window coordinates to object coordinates // ======================================================================= template -static Standard_Boolean OpenGl_Utils::UnProject (const T theWinX, - const T theWinY, - const T theWinZ, - const typename MatrixType::Mat4& theModViewMat, - const typename MatrixType::Mat4& theProjectMat, - const Standard_Integer theViewport[4], - T& theObjX, - T& theObjY, - T& theObjZ) +static Standard_Boolean Graphic3d_TransformUtils::UnProject (const T theWinX, + const T theWinY, + const T theWinZ, + const typename MatrixType::Mat4& theModViewMat, + const typename MatrixType::Mat4& theProjectMat, + const Standard_Integer theViewport[4], + T& theObjX, + T& theObjY, + T& theObjZ) { typename MatrixType::Mat4 anUnviewMat; @@ -486,11 +420,11 @@ static Standard_Boolean OpenGl_Utils::UnProject (const T typename VectorType::Vec4 anIn (theWinX, theWinY, theWinZ, static_cast (1.0)); - // Map x and y from window coordinates + // Map x and y from window coordinates. anIn.x() = (anIn.x() - theViewport[0]) / theViewport[2]; anIn.y() = (anIn.y() - theViewport[1]) / theViewport[3]; - // Map to range -1 to 1 + // Map to range -1 to 1. anIn.x() = anIn.x() * static_cast (2.0) - static_cast (1.0); anIn.y() = anIn.y() * static_cast (2.0) - static_cast (1.0); anIn.z() = anIn.z() * static_cast (2.0) - static_cast (1.0); @@ -515,4 +449,4 @@ static Standard_Boolean OpenGl_Utils::UnProject (const T return Standard_True; } -#endif // _OpenGl_Utils_H__ +#endif // _Graphic3d_TransformUtils_HeaderFile diff --git a/src/Graphic3d/Graphic3d_WorldViewProjState.hxx b/src/Graphic3d/Graphic3d_WorldViewProjState.hxx new file mode 100644 index 0000000000..03713cb8da --- /dev/null +++ b/src/Graphic3d/Graphic3d_WorldViewProjState.hxx @@ -0,0 +1,161 @@ +// 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 _Graphic3d_WorldViewProjState_HeaderFile +#define _Graphic3d_WorldViewProjState_HeaderFile + +#include +#include + +//! Helper class for keeping reference on world-view-projection state. +//! Helpful for synchronizing state of WVP dependent data structures. +class Graphic3d_WorldViewProjState +{ +public: + + //! Default constructor. + Graphic3d_WorldViewProjState() + { + Reset(); + } + + //! Constructor for custom projector type. + //! @param theProjectionState [in] the projection state. + //! @param theWorldViewState [in] the world view state. + //! @param theCamera [in] the pointer to the class supplying projection and + //! world view matrices (camera). + Graphic3d_WorldViewProjState (const Standard_Size theProjectionState, + const Standard_Size theWorldViewState, + const Standard_Transient* theCamera = NULL) + { + Initialize (theProjectionState, theWorldViewState, theCamera); + } + +public: + + //! Check state validity. + //! @return true if state is set. + Standard_Boolean IsValid() + { + return myIsValid; + } + + //! Invalidate world view projection state. + void Reset() + { + myIsValid = Standard_False; + myCamera = NULL; + myProjectionState = 0; + myWorldViewState = 0; + } + + //! Initialize world view projection state. + void Initialize (const Standard_Size theProjectionState, + const Standard_Size theWorldViewState, + const Standard_Transient* theCamera = NULL) + { + myIsValid = Standard_True; + myCamera = const_cast (theCamera); + myProjectionState = theProjectionState; + myWorldViewState = theWorldViewState; + } + + //! Initialize world view projection state. + void Initialize (const Standard_Transient* theCamera = NULL) + { + myIsValid = Standard_True; + myCamera = const_cast (theCamera); + myProjectionState = 0; + myWorldViewState = 0; + } + +public: + + //! @return projection state counter. + Standard_Size& ProjectionState() + { + return myProjectionState; + } + + //! @return world view state counter. + Standard_Size& WorldViewState() + { + return myWorldViewState; + } + +public: + + //! Compare projection with other state. + //! @return true when the projection of the given camera state differs from this one. + Standard_Boolean IsProjectionChanged (const Graphic3d_WorldViewProjState& theState) + { + return myIsValid != theState.myIsValid + || myCamera != theState.myCamera + || myProjectionState != theState.myProjectionState; + } + + //! Compare world view transformation with other state. + //! @return true when the orientation of the given camera state differs from this one. + Standard_Boolean IsWorldViewChanged (const Graphic3d_WorldViewProjState& theState) + { + return myIsValid != theState.myIsValid + || myCamera != theState.myCamera + || myWorldViewState != theState.myWorldViewState; + } + + //! Compare with other world view projection state. + //! @return true when the projection of the given camera state differs from this one. + Standard_Boolean IsChanged (const Graphic3d_WorldViewProjState& theState) + { + return *this != theState; + } + +public: + + //! Compare with other world view projection state. + //! @return true if the other projection state is different to this one. + bool operator != (const Graphic3d_WorldViewProjState& theOther) const + { + return !(*this == theOther); + } + + //! Compare with other world view projection state. + //! @return true if the other projection state is equal to this one. + bool operator == (const Graphic3d_WorldViewProjState& theOther) const + { + return myIsValid == theOther.myIsValid + && myCamera == theOther.myCamera + && myProjectionState == theOther.myProjectionState + && myWorldViewState == theOther.myWorldViewState; + } + + //! Copy world view projection state. + void operator = (const Graphic3d_WorldViewProjState& theOther) + { + myIsValid = theOther.myIsValid; + myCamera = theOther.myCamera; + myProjectionState = theOther.myProjectionState; + myWorldViewState = theOther.myWorldViewState; + } + +private: + + Standard_Boolean myIsValid; + Standard_Transient* myCamera; + Standard_Size myProjectionState; + Standard_Size myWorldViewState; +}; + +#endif diff --git a/src/InterfaceGraphic/InterfaceGraphic_telem.hxx b/src/InterfaceGraphic/InterfaceGraphic_telem.hxx index db4acbf09f..0f4c3ddb19 100644 --- a/src/InterfaceGraphic/InterfaceGraphic_telem.hxx +++ b/src/InterfaceGraphic/InterfaceGraphic_telem.hxx @@ -85,14 +85,4 @@ struct TEL_POFFSET_PARAM }; typedef TEL_POFFSET_PARAM* tel_poffset_param; -struct TEL_TRANSFORM_PERSISTENCE -{ - int mode; - float pointX; - float pointY; - float pointZ; - DEFINE_STANDARD_ALLOC -}; -typedef TEL_TRANSFORM_PERSISTENCE* tel_transform_persistence; - #endif /* INTERFACEGRAPHIC_TELEM_H */ diff --git a/src/OpenGl/FILES b/src/OpenGl/FILES index 9086560843..7cf6f41472 100755 --- a/src/OpenGl/FILES +++ b/src/OpenGl/FILES @@ -40,6 +40,7 @@ OpenGl_GraduatedTrihedron.hxx OpenGl_GraduatedTrihedron.cxx OpenGl_Matrix.hxx OpenGl_Matrix.cxx +OpenGl_MatrixState.hxx OpenGl_CView.hxx OpenGl_NamedStatus.hxx OpenGl_TextParam.hxx @@ -60,7 +61,6 @@ OpenGl_Resource.hxx OpenGl_Resource.cxx OpenGl_telem_util.hxx OpenGl_telem_util.cxx -OpenGl_transform_persistence.hxx OpenGl_Font.hxx OpenGl_Font.cxx OpenGl_tgl_funcs.hxx @@ -68,6 +68,8 @@ OpenGl_BackgroundArray.cxx OpenGl_BackgroundArray.hxx OpenGl_BVHClipPrimitiveSet.cxx OpenGl_BVHClipPrimitiveSet.hxx +OpenGl_BVHClipPrimitiveTrsfPersSet.cxx +OpenGl_BVHClipPrimitiveTrsfPersSet.hxx OpenGl_BVHTreeSelector.cxx OpenGl_BVHTreeSelector.hxx OpenGl_CappingAlgo.cxx @@ -143,7 +145,6 @@ OpenGl_StencilTest.cxx OpenGl_StencilTest.hxx OpenGl_TextureBufferArb.cxx OpenGl_TextureBufferArb.hxx -OpenGl_Utils.hxx OpenGl_Vec.hxx OpenGl_VertexBuffer.cxx OpenGl_VertexBuffer.hxx diff --git a/src/OpenGl/OpenGl_BVHClipPrimitiveSet.cxx b/src/OpenGl/OpenGl_BVHClipPrimitiveSet.cxx index ebb5c87a9c..a249664143 100644 --- a/src/OpenGl/OpenGl_BVHClipPrimitiveSet.cxx +++ b/src/OpenGl/OpenGl_BVHClipPrimitiveSet.cxx @@ -68,49 +68,29 @@ void OpenGl_BVHClipPrimitiveSet::Swap (const Standard_Integer theIdx1, myStructs.Swap (theIdx1 + 1, theIdx2 + 1); } -// ======================================================================= -// function : Assign -// purpose : -// ======================================================================= -void OpenGl_BVHClipPrimitiveSet::Assign (const OpenGl_ArrayOfIndexedMapOfStructure& theStructs) -{ - myStructs.Clear(); - - for (Standard_Integer aPriorityIdx = 0, aNbPriorities = theStructs.Length(); aPriorityIdx < aNbPriorities; ++aPriorityIdx) - { - for (OpenGl_IndexedMapOfStructure::Iterator aStructIter (theStructs (aPriorityIdx)); aStructIter.More(); aStructIter.Next()) - { - const OpenGl_Structure* aStruct = aStructIter.Value(); - - if (!aStruct->IsAlwaysRendered()) - { - myStructs.Add (aStruct); - } - } - } - - MarkDirty(); -} - // ======================================================================= // function : Add // purpose : // ======================================================================= -void OpenGl_BVHClipPrimitiveSet::Add (const OpenGl_Structure* theStruct) +Standard_Boolean OpenGl_BVHClipPrimitiveSet::Add (const OpenGl_Structure* theStruct) { const Standard_Integer aSize = myStructs.Size(); if (myStructs.Add (theStruct) > aSize) // new structure? { MarkDirty(); + + return Standard_True; } + + return Standard_False; } // ======================================================================= // function : Remove // purpose : // ======================================================================= -void OpenGl_BVHClipPrimitiveSet::Remove (const OpenGl_Structure* theStruct) +Standard_Boolean OpenGl_BVHClipPrimitiveSet::Remove (const OpenGl_Structure* theStruct) { const Standard_Integer anIndex = myStructs.FindIndex (theStruct); @@ -119,7 +99,11 @@ void OpenGl_BVHClipPrimitiveSet::Remove (const OpenGl_Structure* theStruct) myStructs.Swap (Size(), anIndex); myStructs.RemoveLast(); MarkDirty(); + + return Standard_True; } + + return Standard_False; } // ======================================================================= diff --git a/src/OpenGl/OpenGl_BVHClipPrimitiveSet.hxx b/src/OpenGl/OpenGl_BVHClipPrimitiveSet.hxx index 4da06c622a..ec6bf33596 100644 --- a/src/OpenGl/OpenGl_BVHClipPrimitiveSet.hxx +++ b/src/OpenGl/OpenGl_BVHClipPrimitiveSet.hxx @@ -22,12 +22,6 @@ #include -//! Defines index map of OpenGL structures. -typedef NCollection_IndexedMap OpenGl_IndexedMapOfStructure; - -//! Defines array of indexed maps of OpenGL structures. -typedef NCollection_Array1 OpenGl_ArrayOfIndexedMapOfStructure; - //! Set of OpenGl_Structures for building BVH tree. class OpenGl_BVHClipPrimitiveSet : public BVH_PrimitiveSet { @@ -54,15 +48,13 @@ public: virtual void Swap (const Standard_Integer theIdx1, const Standard_Integer theIdx2); - //! Replaces the set by the given array taking into account - //! if each structure is cullable or not. - void Assign (const OpenGl_ArrayOfIndexedMapOfStructure& theStructs); - //! Adds structure to the set. - void Add (const OpenGl_Structure* theStruct); + //! @return true if structure added, otherwise returns false (structure already in the set). + Standard_Boolean Add (const OpenGl_Structure* theStruct); //! Removes the given structure from the set. - void Remove (const OpenGl_Structure* theStruct); + //! @return true if structure removed, otherwise returns false (structure is not in the set). + Standard_Boolean Remove (const OpenGl_Structure* theStruct); //! Cleans the whole primitive set. void Clear(); diff --git a/src/OpenGl/OpenGl_BVHClipPrimitiveTrsfPersSet.cxx b/src/OpenGl/OpenGl_BVHClipPrimitiveTrsfPersSet.cxx new file mode 100644 index 0000000000..3555254847 --- /dev/null +++ b/src/OpenGl/OpenGl_BVHClipPrimitiveTrsfPersSet.cxx @@ -0,0 +1,170 @@ +// 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 +#include + +// ======================================================================= +// function : OpenGl_BVHClipPrimitiveTrsfPersSet +// purpose : +// ======================================================================= +OpenGl_BVHClipPrimitiveTrsfPersSet::OpenGl_BVHClipPrimitiveTrsfPersSet() +: myIsDirty (Standard_False), + myBVH (new BVH_Tree()) +{ + myBuilder = new BVH_LinearBuilder (1, 32); +} + +// ======================================================================= +// function : Size +// purpose : +// ======================================================================= +Standard_Integer OpenGl_BVHClipPrimitiveTrsfPersSet::Size() const +{ + return myStructs.Size(); +} + +// ======================================================================= +// function : Box +// purpose : +// ======================================================================= +Graphic3d_BndBox4f OpenGl_BVHClipPrimitiveTrsfPersSet::Box (const Standard_Integer theIdx) const +{ + return *myStructBoxes (theIdx + 1); +} + +// ======================================================================= +// function : Center +// purpose : +// ======================================================================= +Standard_ShortReal OpenGl_BVHClipPrimitiveTrsfPersSet::Center (const Standard_Integer theIdx, + const Standard_Integer theAxis) const +{ + const Graphic3d_BndBox4f& aBndBox = *myStructBoxes (theIdx + 1); + + return (aBndBox.CornerMin()[theAxis] + aBndBox.CornerMax()[theAxis]) * 0.5f; +} + +// ======================================================================= +// function : Swap +// purpose : +// ======================================================================= +void OpenGl_BVHClipPrimitiveTrsfPersSet::Swap (const Standard_Integer theIdx1, + const Standard_Integer theIdx2) +{ + const Standard_Integer aStructIdx1 = theIdx1 + 1; + const Standard_Integer aStructIdx2 = theIdx2 + 1; + + myStructs.Swap (aStructIdx1, aStructIdx2); + myStructBoxes.Swap (aStructIdx1, aStructIdx2); +} + +// ======================================================================= +// function : Add +// purpose : +// ======================================================================= +Standard_Boolean OpenGl_BVHClipPrimitiveTrsfPersSet::Add (const OpenGl_Structure* theStruct) +{ + const Standard_Integer aSize = myStructs.Size(); + + if (myStructs.Add (theStruct) > aSize) // new structure? + { + MarkDirty(); + + return Standard_True; + } + + return Standard_False; +} + +// ======================================================================= +// function : Remove +// purpose : +// ======================================================================= +Standard_Boolean OpenGl_BVHClipPrimitiveTrsfPersSet::Remove (const OpenGl_Structure* theStruct) +{ + const Standard_Integer anIndex = myStructs.FindIndex (theStruct); + + if (anIndex != 0) + { + myStructs.Swap (Size(), anIndex); + myStructs.RemoveLast(); + MarkDirty(); + + return Standard_True; + } + + return Standard_False; +} + +// ======================================================================= +// function : Clear +// purpose : +// ======================================================================= +void OpenGl_BVHClipPrimitiveTrsfPersSet::Clear() +{ + myStructs.Clear(); + MarkDirty(); +} + +// ======================================================================= +// function : GetStructureById +// purpose : +// ======================================================================= +const OpenGl_Structure* OpenGl_BVHClipPrimitiveTrsfPersSet::GetStructureById (Standard_Integer theId) +{ + return myStructs.FindKey (theId + 1); +} + +//======================================================================= +// function : BVH +// purpose : +//======================================================================= +const NCollection_Handle >& + OpenGl_BVHClipPrimitiveTrsfPersSet::BVH (const OpenGl_Mat4& theProjectionMatrix, + const OpenGl_Mat4& theWorldViewMatrix, + const Graphic3d_WorldViewProjState& theWVPState) +{ + if (!myIsDirty && (myStructBoxesState.IsValid() && !myStructBoxesState.IsChanged(theWVPState))) + { + return myBVH; + } + + myStructBoxes.ReSize (myStructs.Size()); + + for (Standard_Integer aStructIdx = 1; aStructIdx <= myStructs.Size(); ++aStructIdx) + { + const OpenGl_Structure* aStructure = myStructs (aStructIdx); + + HBndBox4f aBoundingBox = new Graphic3d_BndBox4f; + + if (aStructure->TransformPersistence.Flags && !(aStructure->TransformPersistence.Flags & Graphic3d_TMF_2d)) + { + *aBoundingBox = aStructure->BoundingBox(); + + aStructure->TransformPersistence.Apply (theProjectionMatrix, theWorldViewMatrix, 0, 0, *aBoundingBox); + } + + myStructBoxes.Add (aBoundingBox); + } + + myBuilder->Build (this, myBVH.operator->(), BVH_Set::Box()); + + myStructBoxesState = theWVPState; + myStructBoxes.Clear(); + myIsDirty = Standard_False; + + return myBVH; +} diff --git a/src/OpenGl/OpenGl_BVHClipPrimitiveTrsfPersSet.hxx b/src/OpenGl/OpenGl_BVHClipPrimitiveTrsfPersSet.hxx new file mode 100644 index 0000000000..563554d708 --- /dev/null +++ b/src/OpenGl/OpenGl_BVHClipPrimitiveTrsfPersSet.hxx @@ -0,0 +1,106 @@ +// 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 _OpenGl_BVHClipPrimitiveTrsfPersSet_HeaderFile +#define _OpenGl_BVHClipPrimitiveTrsfPersSet_HeaderFile + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//! Set of transformation persistent OpenGl_Structure for building BVH tree. +//! 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 OpenGl_BVHClipPrimitiveTrsfPersSet : public BVH_Set +{ +private: + + typedef NCollection_Handle HBndBox4f; + +public: + + //! Creates an empty primitive set for BVH clipping. + OpenGl_BVHClipPrimitiveTrsfPersSet(); + + //! Returns total number of structures. + virtual Standard_Integer Size() const Standard_OVERRIDE; + + //! Returns AABB of the structure. + virtual Graphic3d_BndBox4f Box (const Standard_Integer theIdx) const Standard_OVERRIDE; + + //! Calculates center of the AABB along given axis. + virtual Standard_ShortReal Center (const Standard_Integer theIdx, + const Standard_Integer theAxis) const Standard_OVERRIDE; + + //! Swaps structures with the given indices. + virtual void Swap (const Standard_Integer theIdx1, + const Standard_Integer theIdx2) Standard_OVERRIDE; + + //! Adds structure to the set. + //! @return true if structure added, otherwise returns false (structure already in the set). + Standard_Boolean Add (const OpenGl_Structure* theStruct); + + //! Removes the given structure from the set. + //! @return true if structure removed, otherwise returns false (structure is not in the set). + Standard_Boolean Remove (const OpenGl_Structure* theStruct); + + //! Cleans the whole primitive set. + void Clear(); + + //! Returns the structure corresponding to the given ID. + const OpenGl_Structure* GetStructureById (Standard_Integer theId); + + //! Marks object state as outdated (needs BVH rebuilding). + void MarkDirty() + { + myIsDirty = Standard_True; + } + + //! Returns BVH tree for the given world view projection (builds it if necessary). + const NCollection_Handle >& BVH (const OpenGl_Mat4& theProjectionMatrix, + const OpenGl_Mat4& theWorldViewMatrix, + const Graphic3d_WorldViewProjState& theWVPState); + +private: + + //! Marks internal object state as outdated. + Standard_Boolean myIsDirty; + + //! Constructed bottom-level BVH. + NCollection_Handle > myBVH; + + //! Builder for bottom-level BVH. + NCollection_Handle > myBuilder; + + //! Indexed map of structures. + NCollection_IndexedMap myStructs; + + //! 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 myStructBoxes; + + //! State of world view projection used for generation of transformation persistence bounding boxes. + Graphic3d_WorldViewProjState myStructBoxesState; +}; + +#endif // _OpenGl_BVHClipPrimitiveTrsfPersSet_HeaderFile diff --git a/src/OpenGl/OpenGl_BVHTreeSelector.cxx b/src/OpenGl/OpenGl_BVHTreeSelector.cxx index 7fccc89c51..f71f9bf1d5 100644 --- a/src/OpenGl/OpenGl_BVHTreeSelector.cxx +++ b/src/OpenGl/OpenGl_BVHTreeSelector.cxx @@ -24,22 +24,27 @@ // purpose : // ======================================================================= OpenGl_BVHTreeSelector::OpenGl_BVHTreeSelector() -: myIsProjectionParallel (Standard_True), - myProjectionState (0), - myModelViewState (0) +: myIsProjectionParallel (Standard_True) { // } // ======================================================================= -// function : SetClipVolume -// purpose : Retrieves view volume's planes equations and its vertices from projection and modelview matrices. +// function : SetViewVolume +// purpose : Retrieves view volume's planes equations and its vertices from projection and world-view matrices. // ======================================================================= void OpenGl_BVHTreeSelector::SetViewVolume (const Handle(Graphic3d_Camera)& theCamera) { + if (myWorldViewProjState == theCamera->WorldViewProjState()) + { + return; + } + myIsProjectionParallel = theCamera->IsOrthographic(); - const OpenGl_Mat4& aProjMat = theCamera->ProjectionMatrixF(); - const OpenGl_Mat4& aModelMat = theCamera->OrientationMatrixF(); + + myProjectionMat = theCamera->ProjectionMatrixF(); + myWorldViewMat = theCamera->OrientationMatrixF(); + myWorldViewProjState = theCamera->WorldViewProjState(); Standard_ShortReal nLeft = 0.0f, nRight = 0.0f, nTop = 0.0f, nBottom = 0.0f; Standard_ShortReal fLeft = 0.0f, fRight = 0.0f, fTop = 0.0f, fBottom = 0.0f; @@ -47,32 +52,32 @@ void OpenGl_BVHTreeSelector::SetViewVolume (const Handle(Graphic3d_Camera)& theC if (!myIsProjectionParallel) { // handle perspective projection - aNear = aProjMat.GetValue (2, 3) / (- 1.0f + aProjMat.GetValue (2, 2)); - aFar = aProjMat.GetValue (2, 3) / ( 1.0f + aProjMat.GetValue (2, 2)); + aNear = myProjectionMat.GetValue (2, 3) / (- 1.0f + myProjectionMat.GetValue (2, 2)); + aFar = myProjectionMat.GetValue (2, 3) / ( 1.0f + myProjectionMat.GetValue (2, 2)); // Near plane - nLeft = aNear * (aProjMat.GetValue (0, 2) - 1.0f) / aProjMat.GetValue (0, 0); - nRight = aNear * (aProjMat.GetValue (0, 2) + 1.0f) / aProjMat.GetValue (0, 0); - nTop = aNear * (aProjMat.GetValue (1, 2) + 1.0f) / aProjMat.GetValue (1, 1); - nBottom = aNear * (aProjMat.GetValue (1, 2) - 1.0f) / aProjMat.GetValue (1, 1); + nLeft = aNear * (myProjectionMat.GetValue (0, 2) - 1.0f) / myProjectionMat.GetValue (0, 0); + nRight = aNear * (myProjectionMat.GetValue (0, 2) + 1.0f) / myProjectionMat.GetValue (0, 0); + nTop = aNear * (myProjectionMat.GetValue (1, 2) + 1.0f) / myProjectionMat.GetValue (1, 1); + nBottom = aNear * (myProjectionMat.GetValue (1, 2) - 1.0f) / myProjectionMat.GetValue (1, 1); // Far plane - fLeft = aFar * (aProjMat.GetValue (0, 2) - 1.0f) / aProjMat.GetValue (0, 0); - fRight = aFar * (aProjMat.GetValue (0, 2) + 1.0f) / aProjMat.GetValue (0, 0); - fTop = aFar * (aProjMat.GetValue (1, 2) + 1.0f) / aProjMat.GetValue (1, 1); - fBottom = aFar * (aProjMat.GetValue (1, 2) - 1.0f) / aProjMat.GetValue (1, 1); + fLeft = aFar * (myProjectionMat.GetValue (0, 2) - 1.0f) / myProjectionMat.GetValue (0, 0); + fRight = aFar * (myProjectionMat.GetValue (0, 2) + 1.0f) / myProjectionMat.GetValue (0, 0); + fTop = aFar * (myProjectionMat.GetValue (1, 2) + 1.0f) / myProjectionMat.GetValue (1, 1); + fBottom = aFar * (myProjectionMat.GetValue (1, 2) - 1.0f) / myProjectionMat.GetValue (1, 1); } else { // handle orthographic projection - aNear = (1.0f / aProjMat.GetValue (2, 2)) * (aProjMat.GetValue (2, 3) + 1.0f); - aFar = (1.0f / aProjMat.GetValue (2, 2)) * (aProjMat.GetValue (2, 3) - 1.0f); + aNear = (1.0f / myProjectionMat.GetValue (2, 2)) * (myProjectionMat.GetValue (2, 3) + 1.0f); + aFar = (1.0f / myProjectionMat.GetValue (2, 2)) * (myProjectionMat.GetValue (2, 3) - 1.0f); // Near plane - nLeft = ( 1.0f + aProjMat.GetValue (0, 3)) / (-aProjMat.GetValue (0, 0)); + nLeft = ( 1.0f + myProjectionMat.GetValue (0, 3)) / (-myProjectionMat.GetValue (0, 0)); fLeft = nLeft; - nRight = ( 1.0f - aProjMat.GetValue (0, 3)) / aProjMat.GetValue (0, 0); + nRight = ( 1.0f - myProjectionMat.GetValue (0, 3)) / myProjectionMat.GetValue (0, 0); fRight = nRight; - nTop = ( 1.0f - aProjMat.GetValue (1, 3)) / aProjMat.GetValue (1, 1); + nTop = ( 1.0f - myProjectionMat.GetValue (1, 3)) / myProjectionMat.GetValue (1, 1); fTop = nTop; - nBottom = (-1.0f - aProjMat.GetValue (1, 3)) / aProjMat.GetValue (1, 1); + nBottom = (-1.0f - myProjectionMat.GetValue (1, 3)) / myProjectionMat.GetValue (1, 1); fBottom = nBottom; } @@ -81,18 +86,18 @@ void OpenGl_BVHTreeSelector::SetViewVolume (const Handle(Graphic3d_Camera)& theC OpenGl_Vec4 aRightBottomNear (nRight, nBottom, -aNear, 1.0f), aLeftTopFar (fLeft, fTop, -aFar, 1.0f); OpenGl_Vec4 aRightTopNear (nRight, nTop, -aNear, 1.0f), aLeftBottomFar (fLeft, fBottom, -aFar, 1.0f); - const OpenGl_Mat4 aViewProj = aModelMat * aProjMat; - OpenGl_Mat4 anInvModelView; - aModelMat.Inverted(anInvModelView); - - myClipVerts[ClipVert_LeftTopNear] = anInvModelView * aLeftTopNear; - myClipVerts[ClipVert_RightBottomFar] = anInvModelView * aRightBottomFar; - myClipVerts[ClipVert_LeftBottomNear] = anInvModelView * aLeftBottomNear; - myClipVerts[ClipVert_RightTopFar] = anInvModelView * aRightTopFar; - myClipVerts[ClipVert_RightBottomNear] = anInvModelView * aRightBottomNear; - myClipVerts[ClipVert_LeftTopFar] = anInvModelView * aLeftTopFar; - myClipVerts[ClipVert_RightTopNear] = anInvModelView * aRightTopNear; - myClipVerts[ClipVert_LeftBottomFar] = anInvModelView * aLeftBottomFar; + const OpenGl_Mat4 aViewProj = myWorldViewMat * myProjectionMat; + OpenGl_Mat4 anInvWorldView; + myWorldViewMat.Inverted(anInvWorldView); + + myClipVerts[ClipVert_LeftTopNear] = anInvWorldView * aLeftTopNear; + myClipVerts[ClipVert_RightBottomFar] = anInvWorldView * aRightBottomFar; + myClipVerts[ClipVert_LeftBottomNear] = anInvWorldView * aLeftBottomNear; + myClipVerts[ClipVert_RightTopFar] = anInvWorldView * aRightTopFar; + myClipVerts[ClipVert_RightBottomNear] = anInvWorldView * aRightBottomNear; + myClipVerts[ClipVert_LeftTopFar] = anInvWorldView * aLeftTopFar; + myClipVerts[ClipVert_RightTopNear] = anInvWorldView * aRightTopNear; + myClipVerts[ClipVert_LeftBottomFar] = anInvWorldView * aLeftBottomFar; // UNNORMALIZED! myClipPlanes[Plane_Left] = aViewProj.GetRow (3) + aViewProj.GetRow (0); diff --git a/src/OpenGl/OpenGl_BVHTreeSelector.hxx b/src/OpenGl/OpenGl_BVHTreeSelector.hxx index 96183ce4ca..c111c21233 100644 --- a/src/OpenGl/OpenGl_BVHTreeSelector.hxx +++ b/src/OpenGl/OpenGl_BVHTreeSelector.hxx @@ -17,7 +17,7 @@ #define _OpenGl_BVHTreeSelector_HeaderFile #include - +#include #include //! BVHTreeSelector class provides a possibility to store parameters of view volume, @@ -30,7 +30,7 @@ public: //! Creates an empty selector object with parallel projection type by default. Standard_EXPORT OpenGl_BVHTreeSelector(); - //! Retrieves view volume's planes equations and its vertices from projection and modelview matrices. + //! Retrieves view volume's planes equations and its vertices from projection and world-view matrices. Standard_EXPORT void SetViewVolume (const Handle(Graphic3d_Camera)& theCamera); //! Detects if AABB overlaps view volume using separating axis theorem (SAT). @@ -44,17 +44,23 @@ public: //! Must be called at the beginning of each BVH tree traverse loop. Standard_EXPORT void CacheClipPtsProjections(); - //! Returnes the state of projection matrix previously saved in selector. - Standard_EXPORT const Standard_Size ProjectionState() { return myProjectionState; } - - //! Returnes the link for changing the state of projection matrix. - Standard_EXPORT Standard_Size& ChangeProjectionState() { return myProjectionState; } + //! Returns current projection matrix. + const OpenGl_Mat4& ProjectionMatrix() const + { + return myProjectionMat; + } - //! Returnes the state of model view matrix previously saved in selector. - Standard_EXPORT const Standard_Size ModelViewState() { return myModelViewState; } + //! Returns current world view transformation matrix. + const OpenGl_Mat4& WorldViewMatrix() const + { + return myWorldViewMat; + } - //! Returnes the link for changing the state of model view matrix. - Standard_EXPORT Standard_Size& ChangeModelViewState() { return myModelViewState; } + //! Returns state of current world view projection transformation matrices. + const Graphic3d_WorldViewProjState& WorldViewProjState() const + { + return myWorldViewProjState; + } protected: @@ -94,8 +100,8 @@ protected: protected: - OpenGl_Vec4 myClipPlanes[PlanesNB]; //!< Plane equations - OpenGl_Vec4 myClipVerts[ClipVerticesNB]; //!< Vertices + OpenGl_Vec4 myClipPlanes[PlanesNB]; //!< Plane equations + OpenGl_Vec4 myClipVerts[ClipVerticesNB]; //!< Vertices // for caching clip points projections onto viewing area normals once per traverse // ORDER: TOP, BOTTOM, LEFT, RIGHT, NEAR, FAR @@ -104,14 +110,15 @@ protected: // for caching clip points projections onto AABB normals once per traverse // ORDER: E0, E1, E2 - Standard_ShortReal myMaxOrthoProjectionPts[3]; //!< Max view volume's vertices projections onto normalized dimensions of AABB - Standard_ShortReal myMinOrthoProjectionPts[3]; //!< Min view volume's vertices projections onto normalized dimensions of AABB + Standard_ShortReal myMaxOrthoProjectionPts[3]; //!< Max view volume's vertices projections onto normalized dimensions of AABB + Standard_ShortReal myMinOrthoProjectionPts[3]; //!< Min view volume's vertices projections onto normalized dimensions of AABB - Standard_Boolean myIsProjectionParallel; + Standard_Boolean myIsProjectionParallel; - Standard_Size myProjectionState; //! Caches the state of projection matrix to prevent unnecessary updates. - Standard_Size myModelViewState; //! Caches the state of model view matrix to prevent unnecessary updates. + OpenGl_Mat4 myProjectionMat; + OpenGl_Mat4 myWorldViewMat; + Graphic3d_WorldViewProjState myWorldViewProjState; //!< State of world view projection matrices. }; #endif // _OpenGl_BVHTreeSelector_HeaderFile diff --git a/src/OpenGl/OpenGl_Context.hxx b/src/OpenGl/OpenGl_Context.hxx index d6f024beb1..e4573eb1bc 100644 --- a/src/OpenGl/OpenGl_Context.hxx +++ b/src/OpenGl/OpenGl_Context.hxx @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -34,7 +35,6 @@ #include #include #include -#include #include #include @@ -697,9 +697,9 @@ private: //! @name fields tracking current state public: - OpenGl_Utils::MatrixState ModelWorldState; //!< state of orientation matrix - OpenGl_Utils::MatrixState WorldViewState; //!< state of orientation matrix - OpenGl_Utils::MatrixState ProjectionState; //!< state of projection matrix + OpenGl_MatrixState ModelWorldState; //!< state of orientation matrix + OpenGl_MatrixState WorldViewState; //!< state of orientation matrix + OpenGl_MatrixState ProjectionState; //!< state of projection matrix private: diff --git a/src/OpenGl/OpenGl_GraduatedTrihedron.cxx b/src/OpenGl/OpenGl_GraduatedTrihedron.cxx index 76ef23f112..1eb00d2a89 100755 --- a/src/OpenGl/OpenGl_GraduatedTrihedron.cxx +++ b/src/OpenGl/OpenGl_GraduatedTrihedron.cxx @@ -14,7 +14,6 @@ // commercial license or contractual agreement. #include -#include #include #include #include @@ -24,9 +23,10 @@ #include #include #include +#include +#include #include #include -#include #include #include #include @@ -130,23 +130,23 @@ Standard_ShortReal OpenGl_GraduatedTrihedron::getNormal (const Handle(OpenGl_Con aProjMatrix .Convert (theContext->ProjectionState.Current()); OpenGl_Vec3 aPoint1, aPoint2, aPoint3; - OpenGl_Utils::UnProject ((Standard_ShortReal) aViewport[0], - (Standard_ShortReal) aViewport[1], - 0.0f, - aModelMatrix, aProjMatrix, aViewport, - aPoint1.x(), aPoint1.y(), aPoint1.z()); - - OpenGl_Utils::UnProject ((Standard_ShortReal) (aViewport[0] + aViewport[2]), - (Standard_ShortReal) aViewport[1], - 0.0f, - aModelMatrix, aProjMatrix, aViewport, - aPoint2.x(), aPoint2.y(), aPoint2.z()); - - OpenGl_Utils::UnProject ((Standard_ShortReal) aViewport[0], - (Standard_ShortReal) (aViewport[1] + aViewport[3]), - 0.0f, - aModelMatrix, aProjMatrix, aViewport, - aPoint3.x(), aPoint3.y(), aPoint3.z()); + Graphic3d_TransformUtils::UnProject ((Standard_ShortReal) aViewport[0], + (Standard_ShortReal) aViewport[1], + 0.0f, + aModelMatrix, aProjMatrix, aViewport, + aPoint1.x(), aPoint1.y(), aPoint1.z()); + + Graphic3d_TransformUtils::UnProject ((Standard_ShortReal) (aViewport[0] + aViewport[2]), + (Standard_ShortReal) aViewport[1], + 0.0f, + aModelMatrix, aProjMatrix, aViewport, + aPoint2.x(), aPoint2.y(), aPoint2.z()); + + Graphic3d_TransformUtils::UnProject ((Standard_ShortReal) aViewport[0], + (Standard_ShortReal) (aViewport[1] + aViewport[3]), + 0.0f, + aModelMatrix, aProjMatrix, aViewport, + aPoint3.x(), aPoint3.y(), aPoint3.z()); const OpenGl_Vec3 aD1 = aPoint3 - aPoint1; const OpenGl_Vec3 aD2 = aPoint2 - aPoint1; @@ -330,7 +330,7 @@ void OpenGl_GraduatedTrihedron::renderLine (const OpenGl_PrimitiveArray& theL { const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext(); OpenGl_Mat4 aMat (theMat); - OpenGl_Utils::Translate (aMat, theXt, theYt, theZt); + Graphic3d_TransformUtils::Translate (aMat, theXt, theYt, theZt); aContext->WorldViewState.SetCurrent (aMat); aContext->ApplyWorldViewMatrix(); theLine.Render (theWorkspace); @@ -370,14 +370,14 @@ void OpenGl_GraduatedTrihedron::renderGridPlane (const Handle(OpenGl_Workspace)& aStart.ChangeData()[anIndex] = myMin.GetData()[anIndex]; } - OpenGl_Utils::Translate (aMat, aStart.x(), aStart.y(), aStart.z()); + Graphic3d_TransformUtils::Translate (aMat, aStart.x(), aStart.y(), aStart.z()); aContext->WorldViewState.SetCurrent (aMat); aContext->ApplyWorldViewMatrix(); const OpenGl_Vec3 aStepVec (myAxes[theIndex].Direction * aStep); for (Standard_Integer anIt = myData.ToDrawAxes() ? 1 : 0; anIt < aCurAspect.TickmarksNumber(); ++anIt) { - OpenGl_Utils::Translate (aMat, aStepVec.x(), aStepVec.y(), aStepVec.z()); + Graphic3d_TransformUtils::Translate (aMat, aStepVec.x(), aStepVec.y(), aStepVec.z()); aContext->WorldViewState.SetCurrent (aMat); aContext->ApplyWorldViewMatrix(); anAxis.Line.Render (theWorkspace); @@ -403,56 +403,57 @@ void OpenGl_GraduatedTrihedron::renderAxis (const Handle(OpenGl_Workspace)& theW aContext->ApplyWorldViewMatrix(); // Render arrow - - TEL_TRANSFORM_PERSISTENCE aTransMode; - aTransMode.mode = Graphic3d_TMF_ZoomPers; OpenGl_Vec3 anArrowVec = myMin + anAxis.Direction * (myMax - myMin); - aTransMode.pointX = anArrowVec.x(); - aTransMode.pointY = anArrowVec.y(); - aTransMode.pointZ = anArrowVec.z(); - theWorkspace->ActiveView()->BeginTransformPersistence (aContext, &aTransMode, theWorkspace->Width(), theWorkspace->Height()); + Graphic3d_TransformPers aTransMode; + aTransMode.Flags = Graphic3d_TMF_ZoomPers; + aTransMode.Point.x() = anArrowVec.x(); + aTransMode.Point.y() = anArrowVec.y(); + aTransMode.Point.z() = anArrowVec.z(); + + const OpenGl_Mat4& aProjection = aContext->ProjectionState.Current(); + const OpenGl_Mat4& aWorldView = aContext->WorldViewState.Current(); + const Standard_Integer aWidth = theWorkspace->Width(); + const Standard_Integer aHeight = theWorkspace->Height(); - // NOTE: - // OpenGl_View applies Transform Persistence only in Projection Matrix. // Take into account Transform Persistence + aContext->ModelWorldState.SetCurrent (aTransMode.Compute (aProjection, aWorldView, aWidth, aHeight)); aContext->ApplyModelViewMatrix(); + anAxis.Arrow.Render (theWorkspace); + // Get current Model-View and Projection states OpenGl_Mat4 aModelMat; OpenGl_Mat4 aProjMat; GLint aViewport[4]; aContext->core11fwd->glGetIntegerv (GL_VIEWPORT, aViewport); - aModelMat.Convert (aContext->ModelWorldState.Current() * aContext->WorldViewState.Current()); + aModelMat.Convert (aContext->WorldViewState.Current() * aContext->ModelWorldState.Current()); aProjMat .Convert (aContext->ProjectionState.Current()); - // Get the window's (fixed) coordinates for before matrixes modifications + // Get the window's (fixed) coordinates for before matrices modifications OpenGl_Vec3 aEndPoint = -anAxis.Direction * myData.ArrowsLength(); OpenGl_Vec3 aWinPoint; - OpenGl_Utils::Project (aEndPoint.x(), aEndPoint.y(), aEndPoint.z(), - aModelMat, aProjMat, aViewport, - aWinPoint.x(), aWinPoint.y(), aWinPoint.z()); - anAxis.Arrow.Render (theWorkspace); - theWorkspace->ActiveView()->EndTransformPersistence (aContext); + Graphic3d_TransformUtils::Project (aEndPoint.x(), aEndPoint.y(), aEndPoint.z(), + aModelMat, aProjMat, aViewport, + aWinPoint.x(), aWinPoint.y(), aWinPoint.z()); - // Get current Model-View and Projection states after the end of Transform Persistence - aModelMat.Convert (aContext->ModelWorldState.Current() * aContext->WorldViewState.Current()); + aContext->ModelWorldState.SetIdentity(); + aModelMat.Convert (aContext->WorldViewState.Current()); aProjMat .Convert (aContext->ProjectionState.Current()); // Get start point of zoom persistent arrow OpenGl_Vec3 anArrowStart; - OpenGl_Utils::UnProject (aWinPoint.x(), aWinPoint.y(), aWinPoint.z(), - aModelMat, aProjMat, aViewport, - anArrowStart.x(), anArrowStart.y(), anArrowStart.z()); + Graphic3d_TransformUtils::UnProject (aWinPoint.x(), aWinPoint.y(), aWinPoint.z(), + aModelMat, aProjMat, aViewport, + anArrowStart.x(), anArrowStart.y(), anArrowStart.z()); // Render axis line - aModelMat = theMat; - OpenGl_Utils::Translate (aModelMat, myMin.x(), myMin.y(), myMin.z()); + Graphic3d_TransformUtils::Translate (aModelMat, myMin.x(), myMin.y(), myMin.z()); Standard_ShortReal aScaleFactor = ( (anArrowStart - myMin)*anAxis.Direction ).Modulus() / (anAxis.Direction * (myMax - myMin) ).Modulus(); OpenGl_Vec3 aScaleAxes = anAxis.Direction * aScaleFactor; - OpenGl_Utils::Scale (aModelMat, aScaleAxes.x(), aScaleAxes.y(), aScaleAxes.z()); + Graphic3d_TransformUtils::Scale (aModelMat, aScaleAxes.x(), aScaleAxes.y(), aScaleAxes.z()); aContext->WorldViewState.SetCurrent (aModelMat); aContext->ApplyWorldViewMatrix(); @@ -491,16 +492,16 @@ void OpenGl_GraduatedTrihedron::renderTickmarkLabels (const Handle(OpenGl_Worksp OpenGl_Mat4 aModelMat (theMat); anAxis.InitTickmark (aContext, aDir * (Standard_ShortReal) aCurAspect.TickmarksLength() * theDpix); - OpenGl_Utils::Translate (aModelMat, theGridAxes.Ticks[theIndex].x(), - theGridAxes.Ticks[theIndex].y(), - theGridAxes.Ticks[theIndex].z()); + Graphic3d_TransformUtils::Translate (aModelMat, theGridAxes.Ticks[theIndex].x(), + theGridAxes.Ticks[theIndex].y(), + theGridAxes.Ticks[theIndex].z()); aContext->WorldViewState.SetCurrent (aModelMat); aContext->ApplyWorldViewMatrix(); OpenGl_Vec3 aStepVec = anAxis.Direction * aStep; for (Standard_Integer anIter = 0; anIter <= aCurAspect.TickmarksNumber(); ++anIter) { anAxis.Tickmark.Render (theWorkspace); - OpenGl_Utils::Translate (aModelMat, aStepVec.x(), aStepVec.y(), aStepVec.z()); + Graphic3d_TransformUtils::Translate (aModelMat, aStepVec.x(), aStepVec.y(), aStepVec.z()); aContext->WorldViewState.SetCurrent (aModelMat); aContext->ApplyWorldViewMatrix(); } diff --git a/src/OpenGl/OpenGl_Layer.cxx b/src/OpenGl/OpenGl_Layer.cxx index b0e850921e..9f142bbcf5 100644 --- a/src/OpenGl/OpenGl_Layer.cxx +++ b/src/OpenGl/OpenGl_Layer.cxx @@ -22,7 +22,7 @@ #include // ======================================================================= -// function : OpenGl_PriorityList +// function : OpenGl_Layer // purpose : // ======================================================================= OpenGl_Layer::OpenGl_Layer (const Standard_Integer theNbPriorities) @@ -64,7 +64,14 @@ void OpenGl_Layer::Add (const OpenGl_Structure* theStruct, } else if (!isForChangePriority) { - myBVHPrimitives.Add (theStruct); + if (!theStruct->TransformPersistence.Flags) + { + myBVHPrimitives.Add (theStruct); + } + else + { + myBVHPrimitivesTrsfPers.Add (theStruct); + } } ++myNbStructures; } @@ -97,7 +104,10 @@ bool OpenGl_Layer::Remove (const OpenGl_Structure* theStruct, if (!theStruct->IsAlwaysRendered() && !isForChangePriority) { - myBVHPrimitives.Remove (theStruct); + if (!myBVHPrimitives.Remove (theStruct)) + { + myBVHPrimitivesTrsfPers.Remove (theStruct); + } } --myNbStructures; thePriority = aPriorityIter; @@ -155,8 +165,28 @@ void OpenGl_Layer::renderTraverse (const Handle(OpenGl_Workspace)& theWorkspace) { if (myIsBVHPrimitivesNeedsReset) { - myBVHPrimitives.Assign (myArray); + myBVHPrimitives.Clear(); + myBVHPrimitivesTrsfPers.Clear(); myIsBVHPrimitivesNeedsReset = Standard_False; + for (Standard_Integer aPriorityIdx = 0, aNbPriorities = myArray.Length(); aPriorityIdx < aNbPriorities; ++aPriorityIdx) + { + for (OpenGl_IndexedMapOfStructure::Iterator aStructIter (myArray (aPriorityIdx)); aStructIter.More(); aStructIter.Next()) + { + const OpenGl_Structure* aStruct = aStructIter.Value(); + + if (aStruct->IsAlwaysRendered()) + continue; + + if (!aStruct->TransformPersistence.Flags) + { + myBVHPrimitives.Add (aStruct); + } + else + { + myBVHPrimitivesTrsfPers.Add (aStruct); + } + } + } } OpenGl_BVHTreeSelector& aSelector = theWorkspace->ActiveView()->BVHTreeSelector(); @@ -194,64 +224,93 @@ void OpenGl_Layer::renderTraverse (const Handle(OpenGl_Workspace)& theWorkspace) void OpenGl_Layer::traverse (OpenGl_BVHTreeSelector& theSelector) const { // handle a case when all objects are infinite - if (myBVHPrimitives.Size() == 0) + if (myBVHPrimitives.Size() == 0 && myBVHPrimitivesTrsfPers.Size() == 0) return; - const NCollection_Handle >& aBVHTree = myBVHPrimitives.BVH(); - - Standard_Integer aNode = 0; // a root node theSelector.CacheClipPtsProjections(); - if (!theSelector.Intersect (aBVHTree->MinPoint (0), - aBVHTree->MaxPoint (0))) - { - return; - } - Standard_Integer aStack[32]; - Standard_Integer aHead = -1; - for (;;) + NCollection_Handle > aBVHTree; + + for (Standard_Integer aBVHTreeIdx = 0; aBVHTreeIdx < 2; ++aBVHTreeIdx) { - if (!aBVHTree->IsOuter (aNode)) + const Standard_Boolean isTrsfPers = aBVHTreeIdx == 1; + if (isTrsfPers) { - const Standard_Integer aLeftChildIdx = aBVHTree->LeftChild (aNode); - const Standard_Integer aRightChildIdx = aBVHTree->RightChild (aNode); - const Standard_Boolean isLeftChildIn = theSelector.Intersect (aBVHTree->MinPoint (aLeftChildIdx), - aBVHTree->MaxPoint (aLeftChildIdx)); - const Standard_Boolean isRightChildIn = theSelector.Intersect (aBVHTree->MinPoint (aRightChildIdx), - aBVHTree->MaxPoint (aRightChildIdx)); - if (isLeftChildIn - && isRightChildIn) + if (myBVHPrimitivesTrsfPers.Size() == 0) { - aNode = myBVHIsLeftChildQueuedFirst ? aLeftChildIdx : aRightChildIdx; - aStack[++aHead] = myBVHIsLeftChildQueuedFirst ? aRightChildIdx : aLeftChildIdx; - myBVHIsLeftChildQueuedFirst = !myBVHIsLeftChildQueuedFirst; + continue; } - else if (isLeftChildIn - || isRightChildIn) + const OpenGl_Mat4& aProjection = theSelector.ProjectionMatrix(); + const OpenGl_Mat4& aWorldView = theSelector.WorldViewMatrix(); + const Graphic3d_WorldViewProjState& aWVPState = theSelector.WorldViewProjState(); + aBVHTree = myBVHPrimitivesTrsfPers.BVH (aProjection, aWorldView, aWVPState); + } + else + { + if (myBVHPrimitives.Size() == 0) + { + continue; + } + aBVHTree = myBVHPrimitives.BVH(); + } + + Standard_Integer aNode = 0; // a root node + + if (!theSelector.Intersect (aBVHTree->MinPoint (0), + aBVHTree->MaxPoint (0))) + { + continue; + } + + Standard_Integer aStack[32]; + Standard_Integer aHead = -1; + for (;;) + { + if (!aBVHTree->IsOuter (aNode)) { - aNode = isLeftChildIn ? aLeftChildIdx : aRightChildIdx; + const Standard_Integer aLeftChildIdx = aBVHTree->LeftChild (aNode); + const Standard_Integer aRightChildIdx = aBVHTree->RightChild (aNode); + const Standard_Boolean isLeftChildIn = theSelector.Intersect (aBVHTree->MinPoint (aLeftChildIdx), + aBVHTree->MaxPoint (aLeftChildIdx)); + const Standard_Boolean isRightChildIn = theSelector.Intersect (aBVHTree->MinPoint (aRightChildIdx), + aBVHTree->MaxPoint (aRightChildIdx)); + if (isLeftChildIn + && isRightChildIn) + { + aNode = myBVHIsLeftChildQueuedFirst ? aLeftChildIdx : aRightChildIdx; + aStack[++aHead] = myBVHIsLeftChildQueuedFirst ? aRightChildIdx : aLeftChildIdx; + myBVHIsLeftChildQueuedFirst = !myBVHIsLeftChildQueuedFirst; + } + else if (isLeftChildIn + || isRightChildIn) + { + aNode = isLeftChildIn ? aLeftChildIdx : aRightChildIdx; + } + else + { + if (aHead < 0) + { + break; + } + + aNode = aStack[aHead--]; + } } else { + Standard_Integer aIdx = aBVHTree->BegPrimitive (aNode); + const OpenGl_Structure* aStruct = + isTrsfPers ? myBVHPrimitivesTrsfPers.GetStructureById (aIdx) + : myBVHPrimitives.GetStructureById (aIdx); + aStruct->MarkAsNotCulled(); if (aHead < 0) { - return; + break; } aNode = aStack[aHead--]; } } - else - { - Standard_Integer aIdx = aBVHTree->BegPrimitive (aNode); - myBVHPrimitives.GetStructureById (aIdx)->MarkAsNotCulled(); - if (aHead < 0) - { - return; - } - - aNode = aStack[aHead--]; - } } } diff --git a/src/OpenGl/OpenGl_Layer.hxx b/src/OpenGl/OpenGl_Layer.hxx index f98cd383f3..4edce91d72 100644 --- a/src/OpenGl/OpenGl_Layer.hxx +++ b/src/OpenGl/OpenGl_Layer.hxx @@ -22,9 +22,11 @@ #include #include +#include #include #include +#include #include @@ -34,6 +36,12 @@ struct OpenGl_GlobalLayerSettings GLboolean DepthMask; }; +//! Defines index map of OpenGL structures. +typedef NCollection_IndexedMap OpenGl_IndexedMapOfStructure; + +//! Defines array of indexed maps of OpenGL structures. +typedef NCollection_Array1 OpenGl_ArrayOfIndexedMapOfStructure; + //! Presentations list sorted within priorities. class OpenGl_Layer { @@ -103,12 +111,26 @@ protected: private: + //! Array of OpenGl_Structures by priority rendered in layer. OpenGl_ArrayOfIndexedMapOfStructure myArray; - Standard_Integer myNbStructures; - Graphic3d_ZLayerSettings myLayerSettings; //!< Layer setting flags - mutable OpenGl_BVHClipPrimitiveSet myBVHPrimitives; //!< Set of OpenGl_Structures for building BVH tree - mutable Standard_Boolean myBVHIsLeftChildQueuedFirst; //!< Is needed for implementation of stochastic order of BVH traverse - mutable Standard_Boolean myIsBVHPrimitivesNeedsReset; //!< Defines if the primitive set for BVH is outdated + + //! Overall number of structures rendered in the layer. + Standard_Integer myNbStructures; + + //! Layer setting flags. + Graphic3d_ZLayerSettings myLayerSettings; + + //! Set of OpenGl_Structures structures for building BVH tree. + mutable OpenGl_BVHClipPrimitiveSet myBVHPrimitives; + + //! Set of transform persistent OpenGl_Structures for building BVH tree. + mutable OpenGl_BVHClipPrimitiveTrsfPersSet myBVHPrimitivesTrsfPers; + + //! Is needed for implementation of stochastic order of BVH traverse. + mutable Standard_Boolean myBVHIsLeftChildQueuedFirst; + + //! Defines if the primitive set for BVH is outdated. + mutable Standard_Boolean myIsBVHPrimitivesNeedsReset; public: diff --git a/src/OpenGl/OpenGl_MatrixState.hxx b/src/OpenGl/OpenGl_MatrixState.hxx new file mode 100644 index 0000000000..9e67144a92 --- /dev/null +++ b/src/OpenGl/OpenGl_MatrixState.hxx @@ -0,0 +1,88 @@ +// Created on: 2014-09-30 +// Created by: Denis BOGOLEPOV +// Copyright (c) 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. + +#ifndef _OpenGl_MatrixState_H__ +#define _OpenGl_MatrixState_H__ + +#include +#include + +//! Software implementation for OpenGL matrix stack. +template +class OpenGl_MatrixState +{ +public: + + //! Constructs matrix state object. + OpenGl_MatrixState() + : myStack (8), + myStackHead (-1) + { + // + } + + //! Pushes current matrix into stack. + void Push() + { + if (++myStackHead >= myStack.Size()) + { + myStack.Append (myCurrent); + } + else + { + myStack.SetValue (myStackHead, myCurrent); + } + } + + //! Pops matrix from stack to current. + void Pop() + { + Standard_ASSERT_RETURN (myStackHead != -1, "Matrix stack already empty when MatrixState.Pop() called.", ); + myCurrent = myStack.Value (myStackHead--); + } + + //! @return current matrix. + const typename OpenGl::MatrixType::Mat4& Current() + { + return myCurrent; + } + + //! Sets given matrix as current. + void SetCurrent (const typename OpenGl::MatrixType::Mat4& theNewCurrent) + { + myCurrent = theNewCurrent; + } + + //! Sets given matrix as current. + template + void SetCurrent (const typename OpenGl::MatrixType::Mat4& theNewCurrent) + { + myCurrent.Convert (theNewCurrent); + } + + //! Sets current matrix to identity. + void SetIdentity() + { + myCurrent = typename OpenGl::MatrixType::Mat4(); + } + +private: + + NCollection_Vector::Mat4> myStack; //!< Collection used to maintenance matrix stack + typename OpenGl::MatrixType::Mat4 myCurrent; //!< Current matrix + Standard_Integer myStackHead; //!< Index of stack head +}; + +#endif // _OpenGl_MatrixState_H__ diff --git a/src/OpenGl/OpenGl_Structure.cxx b/src/OpenGl/OpenGl_Structure.cxx index d1e80486bc..c6c04030f8 100644 --- a/src/OpenGl/OpenGl_Structure.cxx +++ b/src/OpenGl/OpenGl_Structure.cxx @@ -118,7 +118,6 @@ public: OpenGl_Structure::OpenGl_Structure (const Handle(Graphic3d_StructureManager)& theManager) : Graphic3d_CStructure (theManager), myTransformation (NULL), - myTransPers (NULL), myAspectLine (NULL), myAspectFace (NULL), myAspectMarker (NULL), @@ -141,7 +140,6 @@ OpenGl_Structure::~OpenGl_Structure() { Release (Handle(OpenGl_Context)()); delete myTransformation; myTransformation = NULL; - delete myTransPers; myTransPers = NULL; } // ======================================================================= @@ -150,8 +148,6 @@ OpenGl_Structure::~OpenGl_Structure() // ======================================================================= void OpenGl_Structure::UpdateAspects() { - SetTransformPersistence (TransformPersistence); - if (ContextLine.IsDef) SetAspectLine (ContextLine); @@ -194,22 +190,6 @@ void OpenGl_Structure::UpdateTransformation() } } -// ======================================================================= -// function : SetTransformPersistence -// purpose : -// ======================================================================= -void OpenGl_Structure::SetTransformPersistence(const CALL_DEF_TRANSFORM_PERSISTENCE &ATransPers) -{ - if (!myTransPers) - myTransPers = new TEL_TRANSFORM_PERSISTENCE; - - myTransPers->mode = ATransPers.Flag; - myTransPers->pointX = ATransPers.Point.x; - myTransPers->pointY = ATransPers.Point.y; - myTransPers->pointZ = ATransPers.Point.z; - MarkAsNotCulled(); -} - // ======================================================================= // function : SetAspectLine // purpose : @@ -558,32 +538,40 @@ void OpenGl_Structure::Render (const Handle(OpenGl_Workspace) &theWorkspace) con const Standard_Boolean anOldGlNormalize = aCtx->IsGlNormalizeEnabled(); // Apply local transformation + OpenGl_Mat4 aModelWorld; if (myTransformation) { - OpenGl_Matrix aModelWorld; - OpenGl_Transposemat3 (&aModelWorld, myTransformation); - aCtx->ModelWorldState.Push(); - aCtx->ModelWorldState.SetCurrent (OpenGl_Mat4::Map ((Standard_ShortReal* )aModelWorld.mat)); + OpenGl_Transposemat3 ((OpenGl_Matrix*)aModelWorld.ChangeData(), myTransformation); - Standard_ShortReal aScaleX = OpenGl_Vec3 (myTransformation->mat[0][0], - myTransformation->mat[0][1], - myTransformation->mat[0][2]).SquareModulus(); + Standard_ShortReal aScaleX = OpenGl_Vec3 (aModelWorld.GetValue (0, 0), + aModelWorld.GetValue (1, 0), + aModelWorld.GetValue (2, 0)).SquareModulus(); // Scale transform detected. if (Abs (aScaleX - 1.f) > Precision::Confusion()) { aCtx->SetGlNormalizeEnabled (Standard_True); } + + aCtx->ModelWorldState.Push(); + aCtx->ModelWorldState.SetCurrent (aModelWorld); } + if (TransformPersistence.Flags) + { + OpenGl_Mat4 aProjection = aCtx->ProjectionState.Current(); + OpenGl_Mat4 aWorldView = aCtx->WorldViewState.Current(); + TransformPersistence.Apply (aProjection, aWorldView, theWorkspace->Width(), theWorkspace->Height()); - // Apply transform persistence - const TEL_TRANSFORM_PERSISTENCE *aTransPersistence = NULL; - if ( myTransPers && myTransPers->mode != 0 ) + aCtx->ProjectionState.Push(); + aCtx->WorldViewState.Push(); + aCtx->ProjectionState.SetCurrent (aProjection); + aCtx->WorldViewState.SetCurrent (aWorldView); + aCtx->ApplyProjectionMatrix(); + } + if (aModelWorld || TransformPersistence.Flags) { - aTransPersistence = theWorkspace->ActiveView()->BeginTransformPersistence (aCtx, myTransPers, theWorkspace->Width(), theWorkspace->Height()); + aCtx->ApplyModelViewMatrix(); } - // Take into account transform persistence - aCtx->ApplyModelViewMatrix(); // Apply aspects const OpenGl_AspectLine *anAspectLine = theWorkspace->AspectLine (Standard_False); @@ -692,12 +680,22 @@ void OpenGl_Structure::Render (const Handle(OpenGl_Workspace) &theWorkspace) con } } - // Apply local transformation - if (myTransformation) + // Restore local transformation + if (!aModelWorld.IsIdentity()) { aCtx->ModelWorldState.Pop(); aCtx->SetGlNormalizeEnabled (anOldGlNormalize); } + if (TransformPersistence.Flags) + { + aCtx->ProjectionState.Pop(); + aCtx->WorldViewState.Pop(); + aCtx->ApplyProjectionMatrix(); + } + if (!aModelWorld.IsIdentity() || TransformPersistence.Flags) + { + aCtx->ApplyWorldViewMatrix(); + } // Restore highlight color theWorkspace->HighlightColor = aHighlightColor; @@ -708,12 +706,6 @@ void OpenGl_Structure::Render (const Handle(OpenGl_Workspace) &theWorkspace) con theWorkspace->SetAspectMarker (anAspectMarker); theWorkspace->SetAspectText (anAspectText); - // Restore transform persistence - if ( myTransPers && myTransPers->mode != 0 ) - { - theWorkspace->ActiveView()->BeginTransformPersistence (aCtx, aTransPersistence, theWorkspace->Width(), theWorkspace->Height()); - } - // Apply highlight box if (!myHighlightBox.IsNull()) { diff --git a/src/OpenGl/OpenGl_Structure.hxx b/src/OpenGl/OpenGl_Structure.hxx index 827694512f..bca38b091c 100644 --- a/src/OpenGl/OpenGl_Structure.hxx +++ b/src/OpenGl/OpenGl_Structure.hxx @@ -115,8 +115,6 @@ public: return (OpenGl_GraphicDriver* )myGraphicDriver.operator->(); } - void SetTransformPersistence (const CALL_DEF_TRANSFORM_PERSISTENCE &ATransPers); - void SetAspectLine (const CALL_DEF_CONTEXTLINE &theAspect); void SetAspectFace (const CALL_DEF_CONTEXTFILLAREA& theAspect); void SetAspectMarker (const CALL_DEF_CONTEXTMARKER& theAspect); @@ -165,7 +163,7 @@ public: || IsForHighlight || IsMutable || Is2dText - || TransformPersistence.Flag != 0; + || TransformPersistence.Flags != 0; } //! This method releases GL resources without actual elements destruction. @@ -184,9 +182,6 @@ public: //! Returns OpenGL transformation matrix. const OpenGl_Matrix* Transformation() const { return myTransformation; } - - //! Returns OpenGL persistent translation. - const TEL_TRANSFORM_PERSISTENCE* PersistentTranslation() const { return myTransPers; } //! Returns structure modification state (for ray-tracing). Standard_Size ModificationState() const { return myModificationState; } @@ -207,7 +202,6 @@ protected: protected: OpenGl_Matrix* myTransformation; - TEL_TRANSFORM_PERSISTENCE* myTransPers; OpenGl_AspectLine* myAspectLine; OpenGl_AspectFace* myAspectFace; OpenGl_AspectMarker* myAspectMarker; diff --git a/src/OpenGl/OpenGl_StructureShadow.cxx b/src/OpenGl/OpenGl_StructureShadow.cxx index 0025e6411b..3b56b0ac8f 100644 --- a/src/OpenGl/OpenGl_StructureShadow.cxx +++ b/src/OpenGl/OpenGl_StructureShadow.cxx @@ -40,7 +40,5 @@ OpenGl_StructureShadow::OpenGl_StructureShadow (const Handle(Graphic3d_Structure } } - TransformPersistence.IsSet = myParent->TransformPersistence.IsSet; - TransformPersistence.Flag = myParent->TransformPersistence.Flag; - TransformPersistence.Point = myParent->TransformPersistence.Point; + TransformPersistence = myParent->TransformPersistence; } diff --git a/src/OpenGl/OpenGl_Text.cxx b/src/OpenGl/OpenGl_Text.cxx index ddc10273d7..5eaaeef664 100644 --- a/src/OpenGl/OpenGl_Text.cxx +++ b/src/OpenGl/OpenGl_Text.cxx @@ -20,10 +20,10 @@ #include #include #include -#include #include #include +#include #include #ifdef HAVE_GL2PS @@ -446,27 +446,28 @@ void OpenGl_Text::setupMatrix (const Handle(OpenGl_PrinterContext)& thePrintCtx, if (myIs2d) { - OpenGl_Utils::Translate (aModViewMat, myPoint.x() + theDVec.x(), myPoint.y() + theDVec.y(), 0.f); - OpenGl_Utils::Scale (aModViewMat, 1.f, -1.f, 1.f); - OpenGl_Utils::Rotate (aModViewMat, theTextAspect.Angle(), 0.f, 0.f, 1.f); + Graphic3d_TransformUtils::Translate (aModViewMat, myPoint.x() + theDVec.x(), myPoint.y() + theDVec.y(), 0.f); + Graphic3d_TransformUtils::Scale (aModViewMat, 1.f, -1.f, 1.f); + Graphic3d_TransformUtils::Rotate (aModViewMat, theTextAspect.Angle(), 0.f, 0.f, 1.f); } else { // align coordinates to the nearest integer // to avoid extra interpolation issues GLdouble anObjX, anObjY, anObjZ; - OpenGl_Utils::UnProject (std::floor (myWinX + theDVec.x()), - std::floor (myWinY + theDVec.y()), - myWinZ + theDVec.z(), - OpenGl_Mat4d::Map (THE_IDENTITY_MATRIX), - OpenGl_Mat4d::Map (myProjMatrix), - myViewport, - anObjX, - anObjY, - anObjZ); - - OpenGl_Utils::Translate (aModViewMat, anObjX, anObjY, anObjZ); - OpenGl_Utils::Rotate (aModViewMat, theTextAspect.Angle(), 0.0, 0.0, 1.0); + Graphic3d_TransformUtils::UnProject (std::floor (myWinX + theDVec.x()), + std::floor (myWinY + theDVec.y()), + myWinZ + theDVec.z(), + OpenGl_Mat4d::Map (THE_IDENTITY_MATRIX), + OpenGl_Mat4d::Map (myProjMatrix), + myViewport, + anObjX, + anObjY, + anObjZ); + + Graphic3d_TransformUtils::Translate (aModViewMat, anObjX, anObjY, anObjZ); + Graphic3d_TransformUtils::Rotate (aModViewMat, theTextAspect.Angle(), 0.0, 0.0, 1.0); + if (!theTextAspect.IsZoomable()) { #ifdef _WIN32 @@ -480,10 +481,10 @@ void OpenGl_Text::setupMatrix (const Handle(OpenGl_PrinterContext)& thePrintCtx, // text should be scaled in all directions with same // factor to save its proportions, so use height (y) scaling // as it is better for keeping text/3d graphics proportions - OpenGl_Utils::Scale (aModViewMat, aTextScaley, aTextScaley, aTextScaley); + Graphic3d_TransformUtils::Scale (aModViewMat, aTextScaley, aTextScaley, aTextScaley); } #endif - OpenGl_Utils::Scale (aModViewMat, myScaleHeight, myScaleHeight, myScaleHeight); + Graphic3d_TransformUtils::Scale (aModViewMat, myScaleHeight, myScaleHeight, myScaleHeight); } } @@ -693,39 +694,39 @@ void OpenGl_Text::render (const Handle(OpenGl_PrinterContext)& thePrintCtx, glGetIntegerv (GL_VIEWPORT, myViewport); myProjMatrix.Convert (theCtx->ProjectionState.Current()); - OpenGl_Utils::Project (myPoint.x(), - myPoint.y(), - myPoint.z(), - myModelMatrix, - myProjMatrix, - myViewport, - myWinX, - myWinY, - myWinZ); + Graphic3d_TransformUtils::Project (myPoint.x(), + myPoint.y(), + myPoint.z(), + myModelMatrix, + myProjMatrix, + myViewport, + myWinX, + myWinY, + myWinZ); // compute scale factor for constant text height GLdouble x1, y1, z1; - OpenGl_Utils::UnProject (myWinX, - myWinY, - myWinZ, - OpenGl_Mat4d::Map (THE_IDENTITY_MATRIX), - myProjMatrix, - myViewport, - x1, - y1, - z1); + Graphic3d_TransformUtils::UnProject (myWinX, + myWinY, + myWinZ, + OpenGl_Mat4d::Map (THE_IDENTITY_MATRIX), + myProjMatrix, + myViewport, + x1, + y1, + z1); GLdouble x2, y2, z2; const GLdouble h = (GLdouble )myFont->FTFont()->PointSize(); - OpenGl_Utils::UnProject (myWinX, - myWinY + h, - myWinZ, - OpenGl_Mat4d::Map (THE_IDENTITY_MATRIX), - myProjMatrix, - myViewport, - x2, - y2, - z2); + Graphic3d_TransformUtils::UnProject (myWinX, + myWinY + h, + myWinZ, + OpenGl_Mat4d::Map (THE_IDENTITY_MATRIX), + myProjMatrix, + myViewport, + x2, + y2, + z2); myScaleHeight = (y2 - y1) / h; if (theTextAspect.IsZoomable()) diff --git a/src/OpenGl/OpenGl_Trihedron.cxx b/src/OpenGl/OpenGl_Trihedron.cxx index 93c06cee3a..60f34bdb6d 100644 --- a/src/OpenGl/OpenGl_Trihedron.cxx +++ b/src/OpenGl/OpenGl_Trihedron.cxx @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -87,25 +88,25 @@ void OpenGl_Trihedron::resetTransformations (const Handle(OpenGl_Workspace)& the { case Aspect_TOTP_LEFT_LOWER: { - OpenGl_Utils::Translate (aProjMatrix, + Graphic3d_TransformUtils::Translate (aProjMatrix, -0.5 * anU + myScale, -0.5 * aV + myScale, 0.0); break; } case Aspect_TOTP_LEFT_UPPER: { - OpenGl_Utils::Translate (aProjMatrix, + Graphic3d_TransformUtils::Translate (aProjMatrix, -0.5 * anU + myScale, 0.5 * aV - myScale - myScale / 3.0, 0.0); break; } case Aspect_TOTP_RIGHT_LOWER: { - OpenGl_Utils::Translate (aProjMatrix, + Graphic3d_TransformUtils::Translate (aProjMatrix, 0.5 * anU - myScale - myScale / 3.0, -0.5 * aV + myScale, 0.0); break; } case Aspect_TOTP_RIGHT_UPPER: { - OpenGl_Utils::Translate (aProjMatrix, + Graphic3d_TransformUtils::Translate (aProjMatrix, 0.5 * anU - myScale - myScale / 3.0, 0.5 * aV - myScale - myScale / 3.0, 0.0); break; } @@ -232,7 +233,7 @@ void OpenGl_Trihedron::redraw (const Handle(OpenGl_Workspace)& theWorkspace) con const OpenGl_AspectFace* anOldAspectFace = theWorkspace->SetAspectFace(&anAspectZ); theWorkspace->SetAspectLine (&anAspectLine); myLine.Render (theWorkspace); - OpenGl_Utils::Translate (aModelViewZ, 0.0, 0.0, aLineLength); + Graphic3d_TransformUtils::Translate (aModelViewZ, 0.0, 0.0, aLineLength); aContext->WorldViewState.SetCurrent(aModelViewZ); aContext->ApplyWorldViewMatrix(); myDisk.Render (theWorkspace); @@ -240,7 +241,7 @@ void OpenGl_Trihedron::redraw (const Handle(OpenGl_Workspace)& theWorkspace) con // X axis theWorkspace->SetAspectFace (&anAspectX); - OpenGl_Utils::Rotate (aModelViewX, 90.0, 0.0, aScale, 0.0); + Graphic3d_TransformUtils::Rotate (aModelViewX, 90.0, 0.0, aScale, 0.0); aContext->WorldViewState.SetCurrent (aModelViewX); aContext->ApplyWorldViewMatrix(); @@ -250,7 +251,7 @@ void OpenGl_Trihedron::redraw (const Handle(OpenGl_Workspace)& theWorkspace) con anAspectLine.SetAspect (aLineAspect); theWorkspace->SetAspectLine (&anAspectLine); myLine.Render (theWorkspace); - OpenGl_Utils::Translate (aModelViewX, 0.0, 0.0, aLineLength); + Graphic3d_TransformUtils::Translate (aModelViewX, 0.0, 0.0, aLineLength); aContext->WorldViewState.SetCurrent (aModelViewX); aContext->ApplyWorldViewMatrix(); myDisk.Render (theWorkspace); @@ -258,7 +259,7 @@ void OpenGl_Trihedron::redraw (const Handle(OpenGl_Workspace)& theWorkspace) con // Y axis theWorkspace->SetAspectFace (&anAspectY); - OpenGl_Utils::Rotate (aModelViewY, -90.0, aScale, 0.0, 0.0); + Graphic3d_TransformUtils::Rotate (aModelViewY, -90.0, aScale, 0.0, 0.0); aContext->WorldViewState.SetCurrent (aModelViewY); aContext->ApplyWorldViewMatrix(); @@ -268,7 +269,7 @@ void OpenGl_Trihedron::redraw (const Handle(OpenGl_Workspace)& theWorkspace) con anAspectLine.SetAspect (aLineAspect); theWorkspace->SetAspectLine (&anAspectLine); myLine.Render (theWorkspace); - OpenGl_Utils::Translate (aModelViewY, 0.0, 0.0, aLineLength); + Graphic3d_TransformUtils::Translate (aModelViewY, 0.0, 0.0, aLineLength); aContext->WorldViewState.SetCurrent (aModelViewY); aContext->ApplyWorldViewMatrix(); myDisk.Render (theWorkspace); @@ -412,7 +413,7 @@ void OpenGl_Trihedron::redrawZBuffer (const Handle(OpenGl_Workspace)& theWorkspa // Z axis theWorkspace->SetAspectFace (&anAspectZ); myCylinder.Render (theWorkspace); - OpenGl_Utils::Translate (aModelViewZ, 0.0, 0.0, aScale * THE_CYLINDER_LENGTH); + Graphic3d_TransformUtils::Translate (aModelViewZ, 0.0, 0.0, aScale * THE_CYLINDER_LENGTH); aContext->WorldViewState.SetCurrent (aModelViewZ); aContext->ApplyWorldViewMatrix(); myDisk.Render (theWorkspace); @@ -420,11 +421,11 @@ void OpenGl_Trihedron::redrawZBuffer (const Handle(OpenGl_Workspace)& theWorkspa // X axis theWorkspace->SetAspectFace (&anAspectX); - OpenGl_Utils::Rotate (aModelViewX, 90.0, aTriedronAxeY[0], aTriedronAxeY[1], aTriedronAxeY[2]); + Graphic3d_TransformUtils::Rotate (aModelViewX, 90.0, aTriedronAxeY[0], aTriedronAxeY[1], aTriedronAxeY[2]); aContext->WorldViewState.SetCurrent (aModelViewX); aContext->ApplyWorldViewMatrix(); myCylinder.Render (theWorkspace); - OpenGl_Utils::Translate (aModelViewX, 0.0, 0.0, aScale * THE_CYLINDER_LENGTH); + Graphic3d_TransformUtils::Translate (aModelViewX, 0.0, 0.0, aScale * THE_CYLINDER_LENGTH); aContext->WorldViewState.SetCurrent (aModelViewX); aContext->ApplyWorldViewMatrix(); myDisk.Render (theWorkspace); @@ -432,11 +433,11 @@ void OpenGl_Trihedron::redrawZBuffer (const Handle(OpenGl_Workspace)& theWorkspa // Y axis theWorkspace->SetAspectFace (&anAspectY); - OpenGl_Utils::Rotate (aModelViewY, -90.0, aTriedronAxeX[0], aTriedronAxeX[1], aTriedronAxeX[2]); + Graphic3d_TransformUtils::Rotate (aModelViewY, -90.0, aTriedronAxeX[0], aTriedronAxeX[1], aTriedronAxeX[2]); aContext->WorldViewState.SetCurrent (aModelViewY); aContext->ApplyWorldViewMatrix(); myCylinder.Render (theWorkspace); - OpenGl_Utils::Translate (aModelViewY, 0.0, 0.0, aScale * THE_CYLINDER_LENGTH); + Graphic3d_TransformUtils::Translate (aModelViewY, 0.0, 0.0, aScale * THE_CYLINDER_LENGTH); aContext->WorldViewState.SetCurrent (aModelViewY); aContext->ApplyWorldViewMatrix(); myDisk.Render (theWorkspace); @@ -645,7 +646,7 @@ void OpenGl_Trihedron::Render (const Handle(OpenGl_Workspace)& theWorkspace) con } const Handle(OpenGl_Texture) aPrevTexture = theWorkspace->DisableTexture(); - theWorkspace->ActiveView()->EndTransformPersistence (theWorkspace->GetGlContext()); + theWorkspace->GetGlContext()->ApplyModelViewMatrix(); if (myIsWireframe) diff --git a/src/OpenGl/OpenGl_Vec.hxx b/src/OpenGl/OpenGl_Vec.hxx index 34c9250984..cb4cf962c4 100755 --- a/src/OpenGl/OpenGl_Vec.hxx +++ b/src/OpenGl/OpenGl_Vec.hxx @@ -45,4 +45,45 @@ typedef Graphic3d_Vec4d OpenGl_Vec4d; typedef Graphic3d_Mat4 OpenGl_Mat4; typedef Graphic3d_Mat4d OpenGl_Mat4d; +namespace OpenGl +{ + //! Tool class for selecting appropriate vector type. + //! \tparam T Numeric data type + template struct VectorType + { + // Not implemented + }; + + template<> struct VectorType + { + typedef OpenGl_Vec2d Vec2; + typedef OpenGl_Vec3d Vec3; + typedef OpenGl_Vec4d Vec4; + }; + + template<> struct VectorType + { + typedef OpenGl_Vec2 Vec2; + typedef OpenGl_Vec3 Vec3; + typedef OpenGl_Vec4 Vec4; + }; + + //! Tool class for selecting appropriate matrix type. + //! \tparam T Numeric data type + template struct MatrixType + { + // Not implemented + }; + + template<> struct MatrixType + { + typedef OpenGl_Mat4d Mat4; + }; + + template<> struct MatrixType + { + typedef OpenGl_Mat4 Mat4; + }; +} + #endif // _OpenGl_Vec_H__ diff --git a/src/OpenGl/OpenGl_View.cxx b/src/OpenGl/OpenGl_View.cxx index f602c2014f..f7f155acfa 100644 --- a/src/OpenGl/OpenGl_View.cxx +++ b/src/OpenGl/OpenGl_View.cxx @@ -22,9 +22,7 @@ #include #include #include -#include #include -#include #include #include @@ -37,7 +35,6 @@ namespace { static const OPENGL_ZCLIP myDefaultZClip = { { Standard_True, 0.F }, { Standard_True, 1.F } }; static const OPENGL_FOG myDefaultFog = { Standard_False, 0.F, 1.F, { { 0.F, 0.F, 0.F, 1.F } } }; - static const TEL_TRANSFORM_PERSISTENCE myDefaultTransPers = { 0, 0.F, 0.F, 0.F }; } /*----------------------------------------------------------------------*/ @@ -59,10 +56,7 @@ OpenGl_View::OpenGl_View (const CALL_DEF_VIEWCONTEXT &AContext, myVisualization(AContext.Visualization), myShadingModel ((Visual3d_TypeOfModel )AContext.Model), myAntiAliasing(Standard_False), - myTransPers(&myDefaultTransPers), - myIsTransPers(Standard_False), - myProjectionState (0), - myModelViewState (0), + myWorldViewProjState(), myStateCounter (theCounter), myLastLightSourceState (0, 0), myTextureParams (new OpenGl_AspectFace()), @@ -249,246 +243,3 @@ void OpenGl_View::GraduatedTrihedronErase (const Handle(OpenGl_Context)& theCtx) myToShowGradTrihedron = false; myGraduatedTrihedron.Release (theCtx.operator->()); } - -/*----------------------------------------------------------------------*/ - -//transform_persistence_end -void OpenGl_View::EndTransformPersistence(const Handle(OpenGl_Context)& theCtx) -{ - if (myIsTransPers) - { - theCtx->WorldViewState.Pop(); - theCtx->ProjectionState.Pop(); - - theCtx->ApplyProjectionMatrix(); - theCtx->ApplyWorldViewMatrix(); - - myIsTransPers = Standard_False; - } -} - -/*----------------------------------------------------------------------*/ - -//transform_persistence_begin -const TEL_TRANSFORM_PERSISTENCE* OpenGl_View::BeginTransformPersistence (const Handle(OpenGl_Context)& theCtx, - const TEL_TRANSFORM_PERSISTENCE* theTransPers, - Standard_Integer theWidth, - Standard_Integer theHeight) -{ - const TEL_TRANSFORM_PERSISTENCE* aTransPersPrev = myTransPers; - myTransPers = theTransPers; - if (theTransPers->mode == 0) - { - EndTransformPersistence (theCtx); - return aTransPersPrev; - } - - GLint aViewport[4]; - OpenGl_Mat4d aModelMatrix, aProjMatrix; - theCtx->core11fwd->glGetIntegerv (GL_VIEWPORT, aViewport); - aModelMatrix.Convert (theCtx->ModelWorldState.Current() * theCtx->WorldViewState.Current()); - aProjMatrix .Convert (theCtx->ProjectionState.Current()); - - const GLdouble aViewportW = (GLdouble )aViewport[2]; - const GLdouble aViewportH = (GLdouble )aViewport[3]; - - if (myIsTransPers) - { - // pop matrix stack - it will be overridden later - theCtx->WorldViewState.Pop(); - theCtx->ProjectionState.Pop(); - } - else - { - myIsTransPers = Standard_True; - } - - if (theTransPers->mode & TPF_2D) - { - GLfloat aLeft = -static_cast (theWidth / 2); - GLfloat aRight = static_cast (theWidth / 2); - GLfloat aBottom = -static_cast (theHeight / 2); - GLfloat aTop = static_cast (theHeight / 2); - GLfloat aGap = static_cast (theTransPers->pointZ); - if (theTransPers->pointX > 0) - { - aLeft -= static_cast (theWidth / 2) - aGap; - aRight -= static_cast (theWidth / 2) - aGap; - } - else if (theTransPers->pointX < 0) - { - aLeft += static_cast (theWidth / 2) - aGap; - aRight += static_cast (theWidth / 2) - aGap; - } - if (theTransPers->pointY > 0) - { - aBottom -= static_cast (theHeight / 2) - aGap; - aTop -= static_cast (theHeight / 2) - aGap; - } - else if (theTransPers->pointY < 0) - { - aBottom += static_cast (theHeight / 2) - aGap; - aTop += static_cast (theHeight / 2) - aGap; - } - if (theTransPers->mode == TPF_2D_ISTOPDOWN) - { - const GLfloat aTemp = aTop; - aTop = aBottom; - aBottom = aTemp; - } - - OpenGl_Mat4 aProjectMat; - OpenGl_Utils::Ortho2D (aProjectMat, - aLeft, aRight, - aBottom, aTop); - - theCtx->WorldViewState.Push(); - theCtx->ProjectionState.Push(); - - theCtx->WorldViewState.SetIdentity(); - theCtx->ProjectionState.SetCurrent (aProjectMat); - - theCtx->ApplyWorldViewMatrix(); - theCtx->ApplyProjectionMatrix(); - return aTransPersPrev; - } - - // push matrices into stack and reset them - theCtx->WorldViewState.Push(); - theCtx->ProjectionState.Push(); - - // get the window's (fixed) coordinates for theTransPers->point before matrixes modifications - GLdouble aWinX = 0.0, aWinY = 0.0, aWinZ = 0.0; - if ((theTransPers->mode & TPF_PAN) != TPF_PAN) - { - OpenGl_Utils::Project (theTransPers->pointX, - theTransPers->pointY, - theTransPers->pointZ, - aModelMatrix, - aProjMatrix, - aViewport, - aWinX, - aWinY, - aWinZ); - } - - // prevent zooming - if ((theTransPers->mode & TPF_ZOOM) - || (theTransPers->mode == TPF_TRIEDRON)) - { - // compute fixed-zoom multiplier - // actually function works ugly with TelPerspective! - const GLdouble aDet2 = 0.002 / (aViewportW > aViewportH ? aProjMatrix.GetValue (1, 1) : aProjMatrix.GetValue (0, 0)); - aProjMatrix.ChangeValue (0, 0) *= aDet2; - aProjMatrix.ChangeValue (1, 1) *= aDet2; - aProjMatrix.ChangeValue (2, 2) *= aDet2; - } - - // prevent translation - annulate translate matrix - if ((theTransPers->mode & TPF_PAN) - || (theTransPers->mode == TPF_TRIEDRON)) - { - aModelMatrix.SetValue (0, 3, 0.0); - aModelMatrix.SetValue (1, 3, 0.0); - aModelMatrix.SetValue (2, 3, 0.0); - aProjMatrix .SetValue (0, 3, 0.0); - aProjMatrix .SetValue (1, 3, 0.0); - aProjMatrix .SetValue (2, 3, 0.0); - } - - // prevent scaling-on-axis - if (theTransPers->mode & TPF_ZOOM) - { - const gp_Pnt anAxialScale = myCamera->AxialScale(); - const double aScaleX = anAxialScale.X(); - const double aScaleY = anAxialScale.Y(); - const double aScaleZ = anAxialScale.Z(); - for (int i = 0; i < 3; ++i) - { - aModelMatrix.ChangeValue (0, i) /= aScaleX; - aModelMatrix.ChangeValue (1, i) /= aScaleY; - aModelMatrix.ChangeValue (2, i) /= aScaleZ; - } - } - - // prevent rotating - annulate rotate matrix - if (theTransPers->mode & TPF_ROTATE) - { - aModelMatrix.SetValue (0, 0, 1.0); - aModelMatrix.SetValue (1, 1, 1.0); - aModelMatrix.SetValue (2, 2, 1.0); - - aModelMatrix.SetValue (1, 0, 0.0); - aModelMatrix.SetValue (2, 0, 0.0); - aModelMatrix.SetValue (0, 1, 0.0); - aModelMatrix.SetValue (2, 1, 0.0); - aModelMatrix.SetValue (0, 2, 0.0); - aModelMatrix.SetValue (1, 2, 0.0); - } - - // load computed matrices - theCtx->ModelWorldState.SetIdentity(); - theCtx->WorldViewState.SetCurrent (aModelMatrix); - theCtx->ProjectionState.SetCurrent (aProjMatrix); - - if (theTransPers->mode == TPF_TRIEDRON) - { - // move to the window corner - if (theTransPers->pointX != 0.0 - && theTransPers->pointY != 0.0) - { - GLdouble aW1, aH1, aW2, aH2, aDummy; - - OpenGl_Mat4d anIdentity; - - OpenGl_Utils::UnProject (0.5 * aViewportW, - 0.5 * aViewportH, - 0.0, - anIdentity, - aProjMatrix, - aViewport, - aW1, - aH1, - aDummy); - - OpenGl_Utils::UnProject (-0.5 * aViewportW, - -0.5 * aViewportH, - 0.0, - anIdentity, - aProjMatrix, - aViewport, - aW2, - aH2, - aDummy); - - GLdouble aMoveX = 0.5 * (aW1 - aW2 - theTransPers->pointZ); - GLdouble aMoveY = 0.5 * (aH1 - aH2 - theTransPers->pointZ); - aMoveX = (theTransPers->pointX > 0.0) ? aMoveX : -aMoveX; - aMoveY = (theTransPers->pointY > 0.0) ? aMoveY : -aMoveY; - - OpenGl_Utils::Translate (aProjMatrix, aMoveX, aMoveY, 0.0); - theCtx->ProjectionState.SetCurrent (aProjMatrix); - } - } - else if ((theTransPers->mode & TPF_PAN) != TPF_PAN) - { - // move to thePoint using saved win-coordinates ('marker-behaviour') - GLdouble aMoveX, aMoveY, aMoveZ; - - OpenGl_Utils::UnProject (aWinX, - aWinY, - aWinZ, - aModelMatrix, - aProjMatrix, - aViewport, - aMoveX, - aMoveY, - aMoveZ); - - OpenGl_Utils::Translate (aModelMatrix, aMoveX, aMoveY, aMoveZ); - theCtx->WorldViewState.SetCurrent (aModelMatrix); - } - - theCtx->ApplyProjectionMatrix(); - return aTransPersPrev; -} diff --git a/src/OpenGl/OpenGl_View.hxx b/src/OpenGl/OpenGl_View.hxx index 86220b2b7b..f5d5176e9c 100644 --- a/src/OpenGl/OpenGl_View.hxx +++ b/src/OpenGl/OpenGl_View.hxx @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include @@ -117,12 +118,6 @@ class OpenGl_View : public MMgt_TShared Standard_Integer Backfacing () const { return myBackfacing; } - const TEL_TRANSFORM_PERSISTENCE * BeginTransformPersistence (const Handle(OpenGl_Context)& theCtx, - const TEL_TRANSFORM_PERSISTENCE *theTransPers, - Standard_Integer theWidth, - Standard_Integer theHeight); - void EndTransformPersistence (const Handle(OpenGl_Context)& theCtx); - //! Add structure to display list with specified priority. //! The structure will be added to associated with it z layer. //! If the z layer is not presented in the view, the structure will @@ -268,12 +263,8 @@ protected: OpenGl_LayerList myZLayers; //!< main list of displayed structure, sorted by layers OpenGl_IndexedMapOfStructure myImmediateList; //!< list of immediate structures rendered on top of main presentation - const TEL_TRANSFORM_PERSISTENCE *myTransPers; - Standard_Boolean myIsTransPers; - //! Modification state - Standard_Size myProjectionState; - Standard_Size myModelViewState; + Graphic3d_WorldViewProjState myWorldViewProjState; OpenGl_StateCounter* myStateCounter; Standard_Size myCurrLightSourceState; diff --git a/src/OpenGl/OpenGl_View_2.cxx b/src/OpenGl/OpenGl_View_2.cxx index 3bf0162936..088b928e64 100644 --- a/src/OpenGl/OpenGl_View_2.cxx +++ b/src/OpenGl/OpenGl_View_2.cxx @@ -276,48 +276,25 @@ void OpenGl_View::Render (const Handle(OpenGl_PrinterContext)& thePrintContext, } #endif - // Update states of OpenGl_BVHTreeSelector (frustum culling algorithm). - Standard_Boolean isProjectionMatUpdateNeeded = Standard_False; - Standard_Boolean isOrientationMatUpdateNeeded = Standard_False; - if (myBVHSelector.ProjectionState() != myCamera->ProjectionState()) - { - isProjectionMatUpdateNeeded = Standard_True; - myBVHSelector.ChangeProjectionState() = myCamera->ProjectionState(); - } - if (myBVHSelector.ModelViewState() != myCamera->ModelViewState()) - { - isOrientationMatUpdateNeeded = Standard_True; - myBVHSelector.ChangeModelViewState() = myCamera->ModelViewState(); - } + Graphic3d_WorldViewProjState aWVPState = myCamera->WorldViewProjState(); - if (isProjectionMatUpdateNeeded - || isOrientationMatUpdateNeeded) - { - myBVHSelector.SetViewVolume (myCamera); - } + // Update states of OpenGl_BVHTreeSelector (frustum culling algorithm). + myBVHSelector.SetViewVolume (myCamera); - const Handle(OpenGl_ShaderManager)& aManager = aContext->ShaderManager(); - const Standard_Boolean isSameView = aManager->IsSameView (this); // force camera state update when needed + const Handle(OpenGl_ShaderManager)& aManager = aContext->ShaderManager(); if (StateInfo (myCurrLightSourceState, aManager->LightSourceState().Index()) != myLastLightSourceState) { aManager->UpdateLightSourceStateTo (&myLights); myLastLightSourceState = StateInfo (myCurrLightSourceState, aManager->LightSourceState().Index()); } - if (myProjectionState != myCamera->ProjectionState() - || !isSameView) + if (myWorldViewProjState != aWVPState) { - myProjectionState = myCamera->ProjectionState(); aContext->ProjectionState.SetCurrent (myCamera->ProjectionMatrixF()); - aContext->ApplyProjectionMatrix(); - } - - if (myModelViewState != myCamera->ModelViewState() - || !isSameView) - { - myModelViewState = myCamera->ModelViewState(); aContext->WorldViewState.SetCurrent (myCamera->OrientationMatrixF()); + aContext->ApplyProjectionMatrix(); aContext->ApplyWorldViewMatrix(); + myWorldViewProjState = aWVPState; } if (aManager->ModelWorldState().Index() == 0) @@ -325,6 +302,7 @@ void OpenGl_View::Render (const Handle(OpenGl_PrinterContext)& thePrintContext, aContext->ShaderManager()->UpdateModelWorldStateTo (OpenGl_Mat4()); } + // ==================================== // Step 2: Redraw background // ==================================== diff --git a/src/OpenGl/OpenGl_Window.cxx b/src/OpenGl/OpenGl_Window.cxx index 668cd8f259..997e45bf45 100644 --- a/src/OpenGl/OpenGl_Window.cxx +++ b/src/OpenGl/OpenGl_Window.cxx @@ -19,9 +19,9 @@ #include #include #include -#include #include +#include #include #include #include @@ -788,7 +788,7 @@ void OpenGl_Window::ReadDepths (const Standard_Integer theX, const Standard_ return; OpenGl_Mat4 aProjectMat; - OpenGl_Utils::Ortho2D (aProjectMat, + Graphic3d_TransformUtils::Ortho2D (aProjectMat, 0.f, static_cast (myWidth), 0.f, static_cast (myHeight)); myGlContext->WorldViewState.Push(); diff --git a/src/OpenGl/OpenGl_Workspace.cxx b/src/OpenGl/OpenGl_Workspace.cxx index 7a9d4eae30..b26a554254 100644 --- a/src/OpenGl/OpenGl_Workspace.cxx +++ b/src/OpenGl/OpenGl_Workspace.cxx @@ -29,12 +29,12 @@ #include #include #include -#include #include #include #include #include +#include #if defined(_WIN32) && defined(HAVE_VIDEOCAPTURE) #include @@ -421,9 +421,9 @@ void OpenGl_Workspace::setTextureParams (Handle(OpenGl_Texture)& OpenGl_Mat4 aTextureMat; const Graphic3d_Vec2& aScale = aParams->Scale(); const Graphic3d_Vec2& aTrans = aParams->Translation(); - OpenGl_Utils::Scale (aTextureMat, aScale.x(), aScale.y(), 1.0f); - OpenGl_Utils::Translate (aTextureMat, -aTrans.x(), -aTrans.y(), 0.0f); - OpenGl_Utils::Rotate (aTextureMat, -aParams->Rotation(), 0.0f, 0.0f, 1.0f); + Graphic3d_TransformUtils::Scale (aTextureMat, aScale.x(), aScale.y(), 1.0f); + Graphic3d_TransformUtils::Translate (aTextureMat, -aTrans.x(), -aTrans.y(), 0.0f); + Graphic3d_TransformUtils::Rotate (aTextureMat, -aParams->Rotation(), 0.0f, 0.0f, 1.0f); glLoadMatrixf (aTextureMat); GLint anEnvMode = GL_MODULATE; // lighting mode @@ -1302,7 +1302,7 @@ void OpenGl_Workspace::copyBackToFront() #if !defined(GL_ES_VERSION_2_0) OpenGl_Mat4 aProjectMat; - OpenGl_Utils::Ortho2D (aProjectMat, + Graphic3d_TransformUtils::Ortho2D (aProjectMat, 0.f, static_cast (myWidth), 0.f, static_cast (myHeight)); myGlContext->WorldViewState.Push(); diff --git a/src/OpenGl/OpenGl_transform_persistence.hxx b/src/OpenGl/OpenGl_transform_persistence.hxx deleted file mode 100644 index 6d14deb337..0000000000 --- a/src/OpenGl/OpenGl_transform_persistence.hxx +++ /dev/null @@ -1,27 +0,0 @@ -// 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. - -#ifndef OPENGL_TRANSFORM_PERSISTENCE_H -#define OPENGL_TRANSFORM_PERSISTENCE_H - -enum TP_FLAGS -{ - TPF_PAN = 0x001, - TPF_ZOOM = 0x002, - TPF_ROTATE = 0x008, - TPF_TRIEDRON = 0x020, - TPF_2D = 0x040, - TPF_2D_ISTOPDOWN = 0x041 -}; - -#endif /*OPENGL_TRANSFORM_PERSISTENCE_H*/ diff --git a/src/PrsMgr/PrsMgr_PresentableObject.cxx b/src/PrsMgr/PrsMgr_PresentableObject.cxx index 6aed91d4b7..82120a7e1e 100644 --- a/src/PrsMgr/PrsMgr_PresentableObject.cxx +++ b/src/PrsMgr/PrsMgr_PresentableObject.cxx @@ -43,10 +43,7 @@ PrsMgr_PresentableObject::PrsMgr_PresentableObject (const PrsMgr_TypeOfPresentat myHasOwnPresentations (Standard_True), myParent (NULL) { - myTransformPersistence.Flag = 0; - myTransformPersistence.Point.x = 0.0; - myTransformPersistence.Point.y = 0.0; - myTransformPersistence.Point.z = 0.0; + // } //======================================================================= @@ -311,10 +308,10 @@ void PrsMgr_PresentableObject::UpdateTransformation(const Handle(Prs3d_Presentat void PrsMgr_PresentableObject::SetTransformPersistence (const Graphic3d_TransModeFlags& theFlag, const gp_Pnt& thePoint) { - myTransformPersistence.Flag = theFlag; - myTransformPersistence.Point.x = (Standard_ShortReal )thePoint.X(); - myTransformPersistence.Point.y = (Standard_ShortReal )thePoint.Y(); - myTransformPersistence.Point.z = (Standard_ShortReal )thePoint.Z(); + myTransformPersistence.Flags = theFlag; + myTransformPersistence.Point.x() = thePoint.X(); + myTransformPersistence.Point.y() = thePoint.Y(); + myTransformPersistence.Point.z() = thePoint.Z(); for (Standard_Integer aPrsIter = 1; aPrsIter <= myPresentations.Length(); ++aPrsIter) { const Handle(PrsMgr_Presentation)& aPrs3d = myPresentations (aPrsIter).Presentation(); @@ -341,18 +338,20 @@ void PrsMgr_PresentableObject::SetTransformPersistence( //function : GetTransformPersistence //purpose : //======================================================================= -Graphic3d_TransModeFlags PrsMgr_PresentableObject::GetTransformPersistenceMode() const +Graphic3d_TransModeFlags PrsMgr_PresentableObject::GetTransformPersistenceMode() const { - return myTransformPersistence.Flag; + return myTransformPersistence.Flags; } //======================================================================= //function : GetTransformPersistence //purpose : //======================================================================= -gp_Pnt PrsMgr_PresentableObject::GetTransformPersistencePoint() const +gp_Pnt PrsMgr_PresentableObject::GetTransformPersistencePoint() const { - return gp_Pnt( myTransformPersistence.Point.x, myTransformPersistence.Point.y, myTransformPersistence.Point.z ); + return gp_Pnt (myTransformPersistence.Point.x(), + myTransformPersistence.Point.y(), + myTransformPersistence.Point.z()); } //======================================================================= diff --git a/src/PrsMgr/PrsMgr_PresentableObject.hxx b/src/PrsMgr/PrsMgr_PresentableObject.hxx index 34055ba0c3..e69c471244 100644 --- a/src/PrsMgr/PrsMgr_PresentableObject.hxx +++ b/src/PrsMgr/PrsMgr_PresentableObject.hxx @@ -23,7 +23,6 @@ #include #include #include -#include #include #include #include @@ -33,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -107,7 +107,10 @@ public: //! Gets point of transform persistence for this object Standard_EXPORT gp_Pnt GetTransformPersistencePoint() const; - + + //! @return transform persistence of the presentable object. + const Graphic3d_TransformPers& TransformPersistence() const; + Standard_EXPORT void SetTypeOfPresentation (const PrsMgr_TypeOfPresentation3d aType); //! flags the Prs of mode to be Updated. @@ -281,7 +284,7 @@ Standard_EXPORT virtual ~PrsMgr_PresentableObject(); private: - Graphic3d_CTransPersStruct myTransformPersistence; + Graphic3d_TransformPers myTransformPersistence; PrsMgr_PresentableObjectPointer myParent; gp_Trsf myLocalTransformation; gp_Trsf myTransformation; diff --git a/src/PrsMgr/PrsMgr_PresentableObject.lxx b/src/PrsMgr/PrsMgr_PresentableObject.lxx index 7beaf60f8e..352219e0ba 100644 --- a/src/PrsMgr/PrsMgr_PresentableObject.lxx +++ b/src/PrsMgr/PrsMgr_PresentableObject.lxx @@ -17,6 +17,10 @@ inline PrsMgr_TypeOfPresentation3d PrsMgr_PresentableObject::TypeOfPresentation3d() const {return myTypeOfPresentation3d;} +inline const Graphic3d_TransformPers& PrsMgr_PresentableObject::TransformPersistence() const +{ + return myTransformPersistence; +} inline const gp_Trsf& PrsMgr_PresentableObject::LocalTransformation() const { diff --git a/src/SelectMgr/FILES b/src/SelectMgr/FILES index 17bc333bb9..cd3af8a2a6 100755 --- a/src/SelectMgr/FILES +++ b/src/SelectMgr/FILES @@ -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 diff --git a/src/SelectMgr/SelectMgr_BaseFrustum.cxx b/src/SelectMgr/SelectMgr_BaseFrustum.cxx index 62d6de3de9..6d22437985 100644 --- a/src/SelectMgr/SelectMgr_BaseFrustum.cxx +++ b/src/SelectMgr/SelectMgr_BaseFrustum.cxx @@ -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 diff --git a/src/SelectMgr/SelectMgr_BaseFrustum.hxx b/src/SelectMgr/SelectMgr_BaseFrustum.hxx index e2e466e7d5..634b113dfd 100644 --- a/src/SelectMgr/SelectMgr_BaseFrustum.hxx +++ b/src/SelectMgr/SelectMgr_BaseFrustum.hxx @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -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); diff --git a/src/SelectMgr/SelectMgr_FrustumBuilder.cxx b/src/SelectMgr/SelectMgr_FrustumBuilder.cxx index c0d85fc5f2..09fa64462c 100644 --- a/src/SelectMgr/SelectMgr_FrustumBuilder.cxx +++ b/src/SelectMgr/SelectMgr_FrustumBuilder.cxx @@ -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) {} + myIsViewportSet (Standard_False) +{ + // +} //======================================================================= -// function : SetOrientation -// purpose : Stores current orientation matrix +// function : SetWorldViewMatrix +// purpose : Stores current world view transformation matrix //======================================================================= -void SelectMgr_FrustumBuilder::SetOrientation (const Graphic3d_Mat4d& theOrientation) +void SelectMgr_FrustumBuilder::SetWorldViewMatrix (const Graphic3d_Mat4d& theWorldView) { - myOrientation = theOrientation; + myWorldView = theWorldView; } //======================================================================= -// function : SetProjection +// 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); } diff --git a/src/SelectMgr/SelectMgr_FrustumBuilder.hxx b/src/SelectMgr/SelectMgr_FrustumBuilder.hxx index 2a09a2e01c..d090bf4515 100644 --- a/src/SelectMgr/SelectMgr_FrustumBuilder.hxx +++ b/src/SelectMgr/SelectMgr_FrustumBuilder.hxx @@ -19,6 +19,7 @@ #include #include +#include #include #include @@ -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 myViewport; diff --git a/src/SelectMgr/SelectMgr_SelectableObject.cxx b/src/SelectMgr/SelectMgr_SelectableObject.cxx index 8de0f94d9e..7a64cbb362 100644 --- a/src/SelectMgr/SelectMgr_SelectableObject.cxx +++ b/src/SelectMgr/SelectMgr_SelectableObject.cxx @@ -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(); + PrsMgr_PresentableObject::UpdateTransformation(); } - //======================================================================= //function : UpdateTransformation //purpose : diff --git a/src/SelectMgr/SelectMgr_SelectableObjectSet.cxx b/src/SelectMgr/SelectMgr_SelectableObjectSet.cxx index 91bc2632f1..b9c5cbd2d3 100644 --- a/src/SelectMgr/SelectMgr_SelectableObjectSet.cxx +++ b/src/SelectMgr/SelectMgr_SelectableObjectSet.cxx @@ -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); -} diff --git a/src/SelectMgr/SelectMgr_SelectableObjectSet.hxx b/src/SelectMgr/SelectMgr_SelectableObjectSet.hxx index 76ccc209c0..dd8c570bdd 100644 --- a/src/SelectMgr/SelectMgr_SelectableObjectSet.hxx +++ b/src/SelectMgr/SelectMgr_SelectableObjectSet.hxx @@ -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: diff --git a/src/SelectMgr/SelectMgr_SelectableObjectTrsfPersSet.cxx b/src/SelectMgr/SelectMgr_SelectableObjectTrsfPersSet.cxx new file mode 100644 index 0000000000..aec1b107b4 --- /dev/null +++ b/src/SelectMgr/SelectMgr_SelectableObjectTrsfPersSet.cxx @@ -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 + +#include +#include +#include + +//======================================================================= +// function : SelectMgr_SelectableObjectTrsfPersSet +// purpose : +//======================================================================= +SelectMgr_SelectableObjectTrsfPersSet::SelectMgr_SelectableObjectTrsfPersSet() +: myIsDirty (Standard_False), + myBVH (new BVH_Tree()) +{ + myBuilder = new BVH_LinearBuilder (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 >& + 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::Box()); + + myObjectBoxesState = theWVPState; + myObjectBoxes.Clear(); + myIsDirty = Standard_False; + + return myBVH; +} diff --git a/src/SelectMgr/SelectMgr_SelectableObjectTrsfPersSet.hxx b/src/SelectMgr/SelectMgr_SelectableObjectTrsfPersSet.hxx new file mode 100644 index 0000000000..7d252abf3a --- /dev/null +++ b/src/SelectMgr/SelectMgr_SelectableObjectTrsfPersSet.hxx @@ -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 +#include +#include +#include +#include +#include +#include +#include +#include + +//! 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 +{ +private: + + typedef NCollection_Handle 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 (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 > myBVH; + + //! Builder for bottom-level BVH. + NCollection_Handle > myBuilder; + + //! Set of transform persistence objects. + NCollection_IndexedMap 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 myObjectBoxes; + + //! State of world view projection used for generation of transformation persistence bounding boxes. + Graphic3d_WorldViewProjState myObjectBoxesState; +}; + +#endif diff --git a/src/SelectMgr/SelectMgr_SelectingVolumeManager.cxx b/src/SelectMgr/SelectMgr_SelectingVolumeManager.cxx index aa1ff3ba70..a7bb82f478 100644 --- a/src/SelectMgr/SelectMgr_SelectingVolumeManager.cxx +++ b/src/SelectMgr/SelectMgr_SelectingVolumeManager.cxx @@ -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 diff --git a/src/SelectMgr/SelectMgr_SelectingVolumeManager.hxx b/src/SelectMgr/SelectMgr_SelectingVolumeManager.hxx index 6c6a7d7238..34e514ad24 100644 --- a/src/SelectMgr/SelectMgr_SelectingVolumeManager.hxx +++ b/src/SelectMgr/SelectMgr_SelectingVolumeManager.hxx @@ -20,6 +20,7 @@ #include #include +#include #include #include @@ -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, diff --git a/src/SelectMgr/SelectMgr_ViewerSelector.cxx b/src/SelectMgr/SelectMgr_ViewerSelector.cxx index a458fe6c43..69f479d405 100644 --- a/src/SelectMgr/SelectMgr_ViewerSelector.cxx +++ b/src/SelectMgr/SelectMgr_ViewerSelector.cxx @@ -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 >& 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 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 >& anObjectsTree = mySelectableObjects->BVH(); - - Standard_Integer aNode = 0; - if (!mySelectingVolumeMgr.Overlaps (anObjectsTree->MinPoint (0), - anObjectsTree->MaxPoint (0))) - { - return; - } - Standard_Integer aStack[32]; - Standard_Integer aHead = -1; - for (;;) + NCollection_Handle > aBVHTree; + for (Standard_Integer aBVHTreeIdx = 0; aBVHTreeIdx < 2; ++aBVHTreeIdx) { - 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 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& anEntitySet = myMapOfObjectSensitives.ChangeFind (theObject); diff --git a/src/SelectMgr/SelectMgr_ViewerSelector.hxx b/src/SelectMgr/SelectMgr_ViewerSelector.hxx index 6de073c537..5d5123720d 100644 --- a/src/SelectMgr/SelectMgr_ViewerSelector.hxx +++ b/src/SelectMgr/SelectMgr_ViewerSelector.hxx @@ -36,6 +36,7 @@ #include #include #include +#include #include #include @@ -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 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: diff --git a/src/StdSelect/StdSelect_ViewerSelector3d.cxx b/src/StdSelect/StdSelect_ViewerSelector3d.cxx index 28cae1a9b6..ba52120a13 100644 --- a/src/StdSelect/StdSelect_ViewerSelector3d.cxx +++ b/src/StdSelect/StdSelect_ViewerSelector3d.cxx @@ -179,39 +179,51 @@ void StdSelect_ViewerSelector3d::Pick (const TColgp_Array1OfPnt2d& thePolyline, //======================================================================= void StdSelect_ViewerSelector3d::DisplaySensitive (const Handle(V3d_View)& theView) { - // Preparation des structures - if (mystruct.IsNull()) + for (Standard_Integer anObjectIdx = 0; anObjectIdx <= mySelectableObjects.Size(); ++anObjectIdx) { - mystruct = new Graphic3d_Structure (theView->Viewer()->Viewer()); + const Handle (SelectMgr_SelectableObject)& anObj = mySelectableObjects.GetObjectById (anObjectIdx); + + Handle(Graphic3d_Structure) aStruct = new Graphic3d_Structure (theView->Viewer()->Viewer()); + + for (anObj->Init(); anObj->More(); anObj->Next()) + { + if (anObj->CurrentSelection()->GetSelectionState() == SelectMgr_SOS_Activated) + { + ComputeSensitivePrs (aStruct, anObj->CurrentSelection(), anObj->Transformation(), Graphic3d_TransformPers()); + } + } + + myStructs.Append (aStruct); } - if (mysensgroup.IsNull()) + for (Standard_Integer anObjectIdx = 0; anObjectIdx <= mySelectableObjectsTrsfPers.Size(); ++anObjectIdx) { - mysensgroup = mystruct->NewGroup(); - } + const Handle (SelectMgr_SelectableObject)& anObj = mySelectableObjectsTrsfPers.GetObjectById (anObjectIdx); - Quantity_Color aColor (Quantity_NOC_INDIANRED3); - Handle(Graphic3d_AspectMarker3d) aMarkerAspect = - new Graphic3d_AspectMarker3d (Aspect_TOM_O_PLUS, aColor, 2.0); + Handle(Graphic3d_Structure) aStruct = new Graphic3d_Structure (theView->Viewer()->Viewer()); - mysensgroup->SetPrimitivesAspect (aMarkerAspect); - mysensgroup->SetPrimitivesAspect ( - new Graphic3d_AspectLine3d (Quantity_NOC_GRAY40, Aspect_TOL_SOLID, 2.0)); + if (!anObj->TransformPersistence().Flags || (anObj->TransformPersistence().Flags & Graphic3d_TMF_2d)) + { + continue; + } - for (Standard_Integer anObjectIdx = 0; anObjectIdx <= mySelectableObjects->Size(); ++anObjectIdx) - { - const Handle (SelectMgr_SelectableObject)& anObject = mySelectableObjects->GetObjectById (anObjectIdx); - for (anObject->Init(); anObject->More(); anObject->Next()) + for (anObj->Init(); anObj->More(); anObj->Next()) { - if (anObject->CurrentSelection()->GetSelectionState() == SelectMgr_SOS_Activated) + if (anObj->CurrentSelection()->GetSelectionState() == SelectMgr_SOS_Activated) { - ComputeSensitivePrs (anObject->CurrentSelection(), anObject->Transformation()); + ComputeSensitivePrs (aStruct, anObj->CurrentSelection(), anObj->Transformation(), anObj->TransformPersistence()); } } + + myStructs.Append (aStruct); } - mysensgroup->Structure()->SetDisplayPriority (10); - mystruct->Display(); + for (Standard_Integer aStructIdx = 1; aStructIdx <= myStructs.Length(); ++aStructIdx) + { + Handle(Graphic3d_Structure)& aStruct = myStructs.ChangeValue (aStructIdx); + aStruct->SetDisplayPriority (10); + aStruct->Display(); + } theView->Update(); } @@ -222,19 +234,17 @@ void StdSelect_ViewerSelector3d::DisplaySensitive (const Handle(V3d_View)& theVi //======================================================================= void StdSelect_ViewerSelector3d::ClearSensitive (const Handle(V3d_View)& theView) { - if (mysensgroup.IsNull()) + for (Standard_Integer aStructIdx = 1; aStructIdx <= myStructs.Length(); ++aStructIdx) { - return; + myStructs.Value (aStructIdx)->Remove(); } - mysensgroup->Clear(); + myStructs.Clear(); - if (theView.IsNull()) + if (!theView.IsNull()) { - return; + theView->Update(); } - - theView->Update(); } //======================================================================= @@ -246,32 +256,18 @@ void StdSelect_ViewerSelector3d::DisplaySensitive (const Handle(SelectMgr_Select const Handle(V3d_View)& theView, const Standard_Boolean theToClearOthers) { - if (mystruct.IsNull()) - { - mystruct = new Graphic3d_Structure (theView->Viewer()->Viewer()); - } - - if (mysensgroup.IsNull()) - { - mysensgroup = mystruct->NewGroup(); - Quantity_Color aColor (Quantity_NOC_INDIANRED3); - Handle(Graphic3d_AspectMarker3d) aMarkerAspect = - new Graphic3d_AspectMarker3d (Aspect_TOM_O_PLUS, aColor, 2.0); - - mysensgroup-> SetPrimitivesAspect (aMarkerAspect); - mysensgroup->SetPrimitivesAspect ( - new Graphic3d_AspectLine3d (Quantity_NOC_GRAY40, Aspect_TOL_SOLID, 2.0)); - } - if (theToClearOthers) { - mysensgroup->Clear(); + ClearSensitive (theView); } - ComputeSensitivePrs (theSel, theTrsf); + Handle(Graphic3d_Structure) aStruct = new Graphic3d_Structure (theView->Viewer()->Viewer()); - mystruct->SetDisplayPriority (10); - mystruct->Display(); + ComputeSensitivePrs (aStruct, theSel, theTrsf, Graphic3d_TransformPers()); + + myStructs.Append (aStruct); + myStructs.Last()->SetDisplayPriority (10); + myStructs.Last()->Display(); theView->Update(); } @@ -280,9 +276,30 @@ void StdSelect_ViewerSelector3d::DisplaySensitive (const Handle(SelectMgr_Select //function : ComputeSensitivePrs //purpose : //======================================================================= -void StdSelect_ViewerSelector3d::ComputeSensitivePrs (const Handle(SelectMgr_Selection)& theSel, - const gp_Trsf& theLoc) +void StdSelect_ViewerSelector3d::ComputeSensitivePrs (const Handle(Graphic3d_Structure)& theStructure, + const Handle(SelectMgr_Selection)& theSel, + const gp_Trsf& theLoc, + const Graphic3d_TransformPers& theTransPers) { + theStructure->SetTransformPersistence (theTransPers.Flags, gp_Pnt (theTransPers.Point.x(), + theTransPers.Point.y(), + theTransPers.Point.z())); + + Handle(Graphic3d_Group) aSensGroup = theStructure->NewGroup(); + + Quantity_Color aColor (Quantity_NOC_INDIANRED3); + Handle(Graphic3d_AspectMarker3d) aMarkerAspect = + new Graphic3d_AspectMarker3d (Aspect_TOM_O_PLUS, aColor, 2.0); + + aSensGroup->SetPrimitivesAspect (aMarkerAspect); + aSensGroup->SetPrimitivesAspect ( + new Graphic3d_AspectLine3d (Quantity_NOC_GRAY40, Aspect_TOL_SOLID, 2.0)); + + Handle(Graphic3d_Group) anAreaGroup = theStructure->NewGroup(); + + anAreaGroup->SetPrimitivesAspect ( + new Graphic3d_AspectLine3d (Quantity_NOC_AQUAMARINE1, Aspect_TOL_DASH, 1.0)); + TColgp_SequenceOfPnt aSeqLines, aSeqFree; TColStd_SequenceOfInteger aSeqBnds; @@ -509,7 +526,7 @@ void StdSelect_ViewerSelector3d::ComputeSensitivePrs (const Handle(SelectMgr_Sel Handle(Select3D_SensitivePoint)::DownCast(Ent)->Point().Transformed (theLoc); Handle(Graphic3d_ArrayOfPoints) anArrayOfPoints = new Graphic3d_ArrayOfPoints (1); anArrayOfPoints->AddVertex (P.X(), P.Y(), P.Z()); - mysensgroup->AddPrimitiveArray (anArrayOfPoints); + aSensGroup->AddPrimitiveArray (anArrayOfPoints); } //============================================================ // Triangulation : On met un petit offset ves l'interieur... @@ -613,12 +630,12 @@ void StdSelect_ViewerSelector3d::ComputeSensitivePrs (const Handle(SelectMgr_Sel aPrims->AddVertex(aSeqLines(i)); for (i = 1; i <= aSeqBnds.Length(); i++) aPrims->AddBound(aSeqBnds(i)); - myareagroup->AddPrimitiveArray(aPrims); + anAreaGroup->AddPrimitiveArray(aPrims); } if (aSeqFree.Length()) { - mysensgroup->SetPrimitivesAspect (new Graphic3d_AspectLine3d (Quantity_NOC_GREEN, Aspect_TOL_SOLID, 2.0)); + aSensGroup->SetPrimitivesAspect (new Graphic3d_AspectLine3d (Quantity_NOC_GREEN, Aspect_TOL_SOLID, 2.0)); Handle(Graphic3d_ArrayOfPolylines) aPrims = new Graphic3d_ArrayOfPolylines(aSeqFree.Length(),aSeqFree.Length()/2); for (i = 1; i <= aSeqFree.Length(); i++) { @@ -626,8 +643,8 @@ void StdSelect_ViewerSelector3d::ComputeSensitivePrs (const Handle(SelectMgr_Sel aPrims->AddVertex(aSeqLines(i++)); aPrims->AddVertex(aSeqLines(i)); } - mysensgroup->AddPrimitiveArray(aPrims); - mysensgroup->SetPrimitivesAspect (new Graphic3d_AspectLine3d (Quantity_NOC_GRAY40, Aspect_TOL_SOLID, 2.0)); + aSensGroup->AddPrimitiveArray(aPrims); + aSensGroup->SetPrimitivesAspect (new Graphic3d_AspectLine3d (Quantity_NOC_GRAY40, Aspect_TOL_SOLID, 2.0)); } } diff --git a/src/StdSelect/StdSelect_ViewerSelector3d.hxx b/src/StdSelect/StdSelect_ViewerSelector3d.hxx index dfd4cd5295..41e4c03320 100644 --- a/src/StdSelect/StdSelect_ViewerSelector3d.hxx +++ b/src/StdSelect/StdSelect_ViewerSelector3d.hxx @@ -21,6 +21,7 @@ #include #include +#include #include #include #include @@ -28,6 +29,7 @@ class Graphic3d_Group; class Graphic3d_Structure; +class Graphic3d_TransformPers; class V3d_View; class SelectMgr_EntityOwner; class SelectMgr_SelectableObjectSet; @@ -89,11 +91,12 @@ protected: private: - void ComputeSensitivePrs (const Handle(SelectMgr_Selection)& theSel, const gp_Trsf& theLoc); + void ComputeSensitivePrs (const Handle(Graphic3d_Structure)& theStructure, + const Handle(SelectMgr_Selection)& theSel, + const gp_Trsf& theLoc, + const Graphic3d_TransformPers& theTransPers); - Handle(Graphic3d_Group) myareagroup; - Handle(Graphic3d_Group) mysensgroup; - Handle(Graphic3d_Structure) mystruct; + Graphic3d_SequenceOfStructure myStructs; Graphic3d_SequenceOfHClipPlane myClipPlanes; }; diff --git a/src/ViewerTest/ViewerTest.cxx b/src/ViewerTest/ViewerTest.cxx index aac3b95325..1607d0c75e 100644 --- a/src/ViewerTest/ViewerTest.cxx +++ b/src/ViewerTest/ViewerTest.cxx @@ -3535,10 +3535,7 @@ static int VDisplay2 (Draw_Interpretor& theDI, ? aCtx->DisplayMode() : 0); Standard_Integer aSelMode = -1; - if ( isSelectable == 1 - || (isSelectable == -1 - && aCtx->GetAutoActivateSelection() - && aShape->GetTransformPersistenceMode() == 0)) + if (isSelectable == 1 || (isSelectable == -1 && aCtx->GetAutoActivateSelection())) { aSelMode = aShape->HasSelectionMode() ? aShape->SelectionMode() : -1; } @@ -3589,10 +3586,7 @@ static int VDisplay2 (Draw_Interpretor& theDI, ? aCtx->DisplayMode() : 0); Standard_Integer aSelMode = -1; - if ( isSelectable == 1 - || (isSelectable == -1 - && aCtx->GetAutoActivateSelection() - && aShape->GetTransformPersistenceMode() == 0)) + if (isSelectable == 1 || (isSelectable == -1 && aCtx->GetAutoActivateSelection())) { aSelMode = aShape->HasSelectionMode() ? aShape->SelectionMode() : -1; } diff --git a/src/Visual3d/Visual3d_View.cxx b/src/Visual3d/Visual3d_View.cxx index 1f6a8d41ac..f2f4a568c1 100644 --- a/src/Visual3d/Visual3d_View.cxx +++ b/src/Visual3d/Visual3d_View.cxx @@ -1674,53 +1674,6 @@ Standard_Boolean Visual3d_View::ContainsFacet (const Graphic3d_MapOfStructure& t return Standard_False; } -//! Auxiliary method for MinMaxValues() method -inline void addStructureBndBox (const Handle(Graphic3d_Structure)& theStruct, - const Standard_Boolean theToIgnoreInfiniteFlag, - Bnd_Box& theBndBox) -{ - if (!theStruct->IsVisible()) - { - return; - } - else if (theStruct->IsInfinite() - && !theToIgnoreInfiniteFlag) - { - // XMin, YMin .... ZMax are initialized by means of infinite line data - const Bnd_Box aBox = theStruct->MinMaxValues (Standard_False); - if (!aBox.IsWhole() - && !aBox.IsVoid()) - { - theBndBox.Add (aBox); - } - return; - } - - // Only non-empty and non-infinite structures - // are taken into account for calculation of MinMax - if (theStruct->IsEmpty() - || theStruct->TransformPersistenceMode() != Graphic3d_TMF_None) - { - return; - } - - // "FitAll" operation ignores object with transform persistence parameter - const Bnd_Box aBox = theStruct->MinMaxValues (theToIgnoreInfiniteFlag); - - // To prevent float overflow at camera parameters calculation and further - // rendering, bounding boxes with at least one vertex coordinate out of - // float range are skipped by view fit algorithms - if (Abs (aBox.CornerMax().X()) >= ShortRealLast() || - Abs (aBox.CornerMax().Y()) >= ShortRealLast() || - Abs (aBox.CornerMax().Z()) >= ShortRealLast() || - Abs (aBox.CornerMin().X()) >= ShortRealLast() || - Abs (aBox.CornerMin().Y()) >= ShortRealLast() || - Abs (aBox.CornerMin().Z()) >= ShortRealLast()) - return; - - theBndBox.Add (aBox); -} - // ======================================================================== // function : MinMaxValues // purpose : @@ -1745,17 +1698,61 @@ Bnd_Box Visual3d_View::MinMaxValues (const Graphic3d_MapOfStructure& theSet, for (Graphic3d_MapIteratorOfMapOfStructure aStructIter (theSet); aStructIter.More(); aStructIter.Next()) { const Handle(Graphic3d_Structure)& aStructure = aStructIter.Key(); - if (!aStructIter.Value()->IsVisible()) + if (!aStructure->IsVisible()|| aStructure->IsEmpty()) { continue; } - else if (!aStructIter.Value()->CStructure()->ViewAffinity.IsNull() - && !aStructIter.Value()->CStructure()->ViewAffinity->IsVisible (aViewId)) + else if (!aStructure->CStructure()->ViewAffinity.IsNull() + && !aStructure->CStructure()->ViewAffinity->IsVisible (aViewId)) + { + continue; + } + + // "FitAll" operation ignores object with transform persistence parameter + if (aStructure->TransformPersistence().Flags) + { + // Panning and 2d persistence apply changes to projection or/and its translation components. + // It makes them incompatible with z-fitting algorithm. Ignored by now. + if (!theToIgnoreInfiniteFlag || + (aStructure->TransformPersistence().Flags & Graphic3d_TMF_2d) || + (aStructure->TransformPersistence().Flags & Graphic3d_TMF_PanPers)) + { + continue; + } + } + + Bnd_Box aBox = aStructure->MinMaxValues (theToIgnoreInfiniteFlag); + + if (aBox.IsWhole() || aBox.IsVoid()) + { + continue; + } + + if (aStructure->TransformPersistence().Flags) + { + Standard_Integer aWidth, aHeight; + Window()->Size (aWidth, aHeight); + + const Graphic3d_Mat4d& aProjectionMat = MyCView.Context.Camera->ProjectionMatrix(); + const Graphic3d_Mat4d& aWorldViewMat = MyCView.Context.Camera->OrientationMatrix(); + + aStructure->TransformPersistence().Apply (aProjectionMat, aWorldViewMat, aWidth, aHeight, aBox); + } + + // To prevent float overflow at camera parameters calculation and further + // rendering, bounding boxes with at least one vertex coordinate out of + // float range are skipped by view fit algorithms + if (Abs (aBox.CornerMax().X()) >= ShortRealLast() || + Abs (aBox.CornerMax().Y()) >= ShortRealLast() || + Abs (aBox.CornerMax().Z()) >= ShortRealLast() || + Abs (aBox.CornerMin().X()) >= ShortRealLast() || + Abs (aBox.CornerMin().Y()) >= ShortRealLast() || + Abs (aBox.CornerMin().Z()) >= ShortRealLast()) { continue; } - addStructureBndBox (aStructure, theToIgnoreInfiniteFlag, aResult); + aResult.Add (aBox); } return aResult; } diff --git a/tests/bugs/vis/bug26344 b/tests/bugs/vis/bug26344 new file mode 100644 index 0000000000..8a2f5893f4 --- /dev/null +++ b/tests/bugs/vis/bug26344 @@ -0,0 +1,81 @@ +puts "============" +puts "CR26344" +puts "============" +puts "" + +########################################################################################## +puts "Visualization - provide a support of zoom persistent selection" +########################################################################################## + +vinit View1 w=409 h=409 +vtrihedron tri +vpan 50 50 + +box b1 50 50 50 +box b2 50 50 50 +box b3 100 100 100 +box b4 100 100 100 +box b5 100 100 100 + +# 1) Zoom persistence +vpoint p1 200 200 200 + +vdisplay b1 -trsfPers zoom -trsfPersPos 200 200 200 +vdisplay b2 -trsfPers zoom -trsfPersPos 200 200 200 +vsetlocation b2 -50 -50 -50 + +vmoveto 384 78 +if { ![checkcolor 384 78 0 1 1] } { + puts "Error picking zoom persistence object" +} + +vmoveto 356 96 +if { ![checkcolor 356 96 0 1 1] } { + puts "Error picking zoom persistent object with location" +} + +vselect 330 120 400 50 + +if { ![checkcolor 384 78 0.8 0.8 0.8] || ![checkcolor 356 96 0.8 0.8 0.8] } { + puts "Error selecting zoom persistence object(s)" +} + +# 2) Rotate persistence + +vdisplay b3 -trsfPers rotate -trsfPersPos -200 -200 -200 +vmoveto 160 200 +if { ![checkcolor 160 180 0 1 1] } { + puts "Error picking rotate persistence object" +} +vselect 130 230 190 170 +if { ![checkcolor 160 180 0.8 0.8 0.8] } { + puts "Error selecting rotate persistence object" +} + +# 3) Pan persistence + +vdisplay b4 -trsfPers pan +vmoveto 233 188 +if { ![checkcolor 233 188 0 1 1] } { + puts "Error picking pan persistence object" +} +vselect 200 230 270 140 +if { ![checkcolor 233 188 0.8 0.8 0.8] } { + puts "Error selecting pan persistence object" +} + +# 4) Trihedron persistence + +vdisplay b5 -trsfPers trihedron -trsfPersPos -1 -1 300 +vmoveto 90 300 +if { ![checkcolor 90 300 0 1 1] } { + puts "Error picking trihedron persistence object" +} +vselect 50 380 140 280 +if { ![checkcolor 90 300 0.8 0.8 0.8] } { + puts "Error selecting trihedron persistence object" +} + +vselect 50 380 400 50 + +set only_screen 1 \ No newline at end of file -- 2.20.1