0026344: Visualization - provide a support of zoom persistent selection
authorapl <apl@opencascade.com>
Mon, 20 Jul 2015 08:41:38 +0000 (11:41 +0300)
committerbugmaster <bugmaster@opencascade.com>
Wed, 29 Jul 2015 10:39:27 +0000 (13:39 +0300)
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.

59 files changed:
src/Graphic3d/FILES
src/Graphic3d/Graphic3d_CStructure.cxx
src/Graphic3d/Graphic3d_CStructure.hxx
src/Graphic3d/Graphic3d_CTransPersStruct.hxx [deleted file]
src/Graphic3d/Graphic3d_Camera.cxx
src/Graphic3d/Graphic3d_Camera.hxx
src/Graphic3d/Graphic3d_Structure.cxx
src/Graphic3d/Graphic3d_Structure.hxx
src/Graphic3d/Graphic3d_Structure.lxx
src/Graphic3d/Graphic3d_TransformPers.hxx [new file with mode: 0644]
src/Graphic3d/Graphic3d_TransformUtils.hxx [moved from src/OpenGl/OpenGl_Utils.hxx with 67% similarity]
src/Graphic3d/Graphic3d_WorldViewProjState.hxx [new file with mode: 0644]
src/InterfaceGraphic/InterfaceGraphic_telem.hxx
src/OpenGl/FILES
src/OpenGl/OpenGl_BVHClipPrimitiveSet.cxx
src/OpenGl/OpenGl_BVHClipPrimitiveSet.hxx
src/OpenGl/OpenGl_BVHClipPrimitiveTrsfPersSet.cxx [new file with mode: 0644]
src/OpenGl/OpenGl_BVHClipPrimitiveTrsfPersSet.hxx [new file with mode: 0644]
src/OpenGl/OpenGl_BVHTreeSelector.cxx
src/OpenGl/OpenGl_BVHTreeSelector.hxx
src/OpenGl/OpenGl_Context.hxx
src/OpenGl/OpenGl_GraduatedTrihedron.cxx
src/OpenGl/OpenGl_Layer.cxx
src/OpenGl/OpenGl_Layer.hxx
src/OpenGl/OpenGl_MatrixState.hxx [new file with mode: 0644]
src/OpenGl/OpenGl_Structure.cxx
src/OpenGl/OpenGl_Structure.hxx
src/OpenGl/OpenGl_StructureShadow.cxx
src/OpenGl/OpenGl_Text.cxx
src/OpenGl/OpenGl_Trihedron.cxx
src/OpenGl/OpenGl_Vec.hxx
src/OpenGl/OpenGl_View.cxx
src/OpenGl/OpenGl_View.hxx
src/OpenGl/OpenGl_View_2.cxx
src/OpenGl/OpenGl_Window.cxx
src/OpenGl/OpenGl_Workspace.cxx
src/OpenGl/OpenGl_transform_persistence.hxx [deleted file]
src/PrsMgr/PrsMgr_PresentableObject.cxx
src/PrsMgr/PrsMgr_PresentableObject.hxx
src/PrsMgr/PrsMgr_PresentableObject.lxx
src/SelectMgr/FILES
src/SelectMgr/SelectMgr_BaseFrustum.cxx
src/SelectMgr/SelectMgr_BaseFrustum.hxx
src/SelectMgr/SelectMgr_FrustumBuilder.cxx
src/SelectMgr/SelectMgr_FrustumBuilder.hxx
src/SelectMgr/SelectMgr_SelectableObject.cxx
src/SelectMgr/SelectMgr_SelectableObjectSet.cxx
src/SelectMgr/SelectMgr_SelectableObjectSet.hxx
src/SelectMgr/SelectMgr_SelectableObjectTrsfPersSet.cxx [new file with mode: 0644]
src/SelectMgr/SelectMgr_SelectableObjectTrsfPersSet.hxx [new file with mode: 0644]
src/SelectMgr/SelectMgr_SelectingVolumeManager.cxx
src/SelectMgr/SelectMgr_SelectingVolumeManager.hxx
src/SelectMgr/SelectMgr_ViewerSelector.cxx
src/SelectMgr/SelectMgr_ViewerSelector.hxx
src/StdSelect/StdSelect_ViewerSelector3d.cxx
src/StdSelect/StdSelect_ViewerSelector3d.hxx
src/ViewerTest/ViewerTest.cxx
src/Visual3d/Visual3d_View.cxx
tests/bugs/vis/bug26344 [new file with mode: 0644]

index c372cde..3cbda2d 100755 (executable)
@@ -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
index 4153776..2097704 100644 (file)
@@ -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;
 }
index 90239d6..adff5b2 100644 (file)
@@ -21,6 +21,7 @@
 #include <Graphic3d_SequenceOfHClipPlane.hxx>
 #include <Graphic3d_TypeOfComposition.hxx>
 #include <Graphic3d_ViewAffinity.hxx>
+#include <Graphic3d_TransformPers.hxx>
 #include <Graphic3d_Vec3.hxx>
 #include <Graphic3d_ZLayerId.hxx>
 
@@ -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 (file)
index b7bb0f4..0000000
+++ /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 <InterfaceGraphic_Graphic3d.hxx>
-typedef CALL_DEF_TRANSFORM_PERSISTENCE Graphic3d_CTransPersStruct;
-
-#endif /*_Graphic3d_CTransPersStruct_HeaderFile*/
index 7646957..7b38769 100644 (file)
@@ -16,8 +16,9 @@
 #include <gp_Pln.hxx>
 #include <Standard_ShortReal.hxx>
 
-#include <Graphic3d_Vec4.hxx>
 #include <Graphic3d_Camera.hxx>
+#include <Graphic3d_Vec4.hxx>
+#include <Graphic3d_WorldViewProjState.hxx>
 
 #include <Standard_Atomic.hxx>
 #include <Standard_Assert.hxx>
@@ -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);
 }
 
 // =======================================================================
index cdeda3c..0450205 100644 (file)
@@ -19,6 +19,7 @@
 #include <Graphic3d_Mat4d.hxx>
 #include <Graphic3d_Mat4.hxx>
 #include <Graphic3d_Vec3.hxx>
+#include <Graphic3d_WorldViewProjState.hxx>
 
 #include <NCollection_Handle.hxx>
 
@@ -31,6 +32,7 @@
 #include <Bnd_Box.hxx>
 
 //! 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<Standard_Real>      myMatricesD;
   mutable TransformMatrices<Standard_ShortReal> 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)
index dffbf40..a6403b4 100644 (file)
@@ -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;
 }
 
index 5cdbfb0..b86f007 100644 (file)
@@ -38,6 +38,7 @@
 #include <Graphic3d_TypeOfConnection.hxx>
 #include <Graphic3d_MapOfStructure.hxx>
 #include <Graphic3d_TypeOfComposition.hxx>
+#include <Graphic3d_TransformPers.hxx>
 #include <Graphic3d_TransModeFlags.hxx>
 #include <Graphic3d_BndBox4f.hxx>
 #include <Graphic3d_BndBox4d.hxx>
@@ -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);
   
index 86e9061..7fd5ec2 100644 (file)
@@ -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 (file)
index 0000000..4f5d6ba
--- /dev/null
@@ -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 <Bnd_Box.hxx>
+#include <BVH_Box.hxx>
+#include <Graphic3d_TransformUtils.hxx>
+#include <Graphic3d_TransModeFlags.hxx>
+#include <NCollection_Mat4.hxx>
+#include <NCollection_Vec4.hxx>
+
+//! 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<class T>
+  void Apply (const NCollection_Mat4<T>& theProjection,
+              const NCollection_Mat4<T>& 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<class T>
+  void Apply (const NCollection_Mat4<T>& theProjection,
+              const NCollection_Mat4<T>& theWorldView,
+              const Standard_Integer theViewportWidth,
+              const Standard_Integer theViewportHeight,
+              BVH_Box<T, 4>& 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<class T>
+  NCollection_Mat4<T> Compute (const NCollection_Mat4<T>& theProjection,
+                               const NCollection_Mat4<T>& theWorldView,
+                               const Standard_Integer theViewportWidth,
+                               const Standard_Integer theViewportHeight) const;
+
+  template<class T>
+  void Apply (NCollection_Mat4<T>& theProjection,
+              NCollection_Mat4<T>& theWorldView,
+              const Standard_Integer theViewportWidth,
+              const Standard_Integer theViewportHeight) const;
+};
+
+// =======================================================================
+// function : Apply
+// purpose  : Apply transformation to world view and projection matrices.
+// =======================================================================
+template<class T>
+void Graphic3d_TransformPers::Apply (NCollection_Mat4<T>& theProjection,
+                                     NCollection_Mat4<T>& theWorldView,
+                                     const Standard_Integer theViewportWidth,
+                                     const Standard_Integer theViewportHeight) const
+{
+  if (!Flags)
+  {
+    return;
+  }
+
+  if (Flags & Graphic3d_TMF_2d)
+  {
+    T aLeft   = -static_cast<T> (theViewportWidth  / 2);
+    T aRight  =  static_cast<T> (theViewportWidth  / 2);
+    T aBottom = -static_cast<T> (theViewportHeight / 2);
+    T aTop    =  static_cast<T> (theViewportHeight / 2);
+    T aGap    =  static_cast<T> (Point.z());
+    if (Point.x() > 0)
+    {
+      aLeft  -= static_cast<T> (theViewportWidth / 2) - aGap;
+      aRight -= static_cast<T> (theViewportWidth / 2) - aGap;
+    }
+    else if (Point.x() < 0)
+    {
+      aLeft  += static_cast<T> (theViewportWidth / 2) - aGap;
+      aRight += static_cast<T> (theViewportWidth / 2) - aGap;
+    }
+    if (Point.y() > 0)
+    {
+      aBottom -= static_cast<T> (theViewportHeight / 2) - aGap;
+      aTop    -= static_cast<T> (theViewportHeight / 2) - aGap;
+    }
+    else if (Point.y() < 0)
+    {
+      aBottom += static_cast<T> (theViewportHeight / 2) - aGap;
+      aTop    += static_cast<T> (theViewportHeight / 2) - aGap;
+    }
+    if (Flags == Graphic3d_TMF_2d_IsTopDown)
+    {
+      const T aTemp = aTop;
+      aTop    = aBottom;
+      aBottom = aTemp;
+    }
+
+    Graphic3d_TransformUtils::Ortho2D<T> (theProjection, aLeft, aRight, aBottom, aTop);
+
+    theWorldView.InitIdentity();
+  }
+  else
+  {
+    // Compute reference point for transformation in untransformed projection space.
+    NCollection_Vec4<T> aRefPoint (static_cast<T> (Point.x()),
+                                   static_cast<T> (Point.y()),
+                                   static_cast<T> (Point.z()),
+                                   static_cast<T> (1.0));
+    NCollection_Vec4<T> 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<T> (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<T> (0.0));
+      theWorldView .SetValue (1, 3, static_cast<T> (0.0));
+      theWorldView .SetValue (2, 3, static_cast<T> (0.0));
+      theProjection.SetValue (0, 3, static_cast<T> (0.0));
+      theProjection.SetValue (1, 3, static_cast<T> (0.0));
+      theProjection.SetValue (2, 3, static_cast<T> (0.0));
+    }
+
+    // Prevent scaling-on-axis.
+    if (Flags & Graphic3d_TMF_ZoomPers)
+    {
+      NCollection_Vec3<T> aVecX = theWorldView.GetColumn (0).xyz();
+      NCollection_Vec3<T> aVecY = theWorldView.GetColumn (1).xyz();
+      NCollection_Vec3<T> 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<T> (1.0));
+      theWorldView.SetValue (1, 0, static_cast<T> (0.0));
+      theWorldView.SetValue (2, 0, static_cast<T> (0.0));
+
+      theWorldView.SetValue (0, 1, static_cast<T> (0.0));
+      theWorldView.SetValue (1, 1, static_cast<T> (1.0));
+      theWorldView.SetValue (2, 1, static_cast<T> (0.0));
+
+      theWorldView.SetValue (0, 2, static_cast<T> (0.0));
+      theWorldView.SetValue (1, 2, static_cast<T> (0.0));
+      theWorldView.SetValue (2, 2, static_cast<T> (1.0));
+    }
+
+    if (Flags == Graphic3d_TMF_TriedronPers)
+    {
+      if (Point.x() != 0.0 && Point.y() != 0.0)
+      {
+        NCollection_Mat4<T> anUnviewMat;
+
+        if (!(theProjection).Inverted (anUnviewMat))
+        {
+          Standard_ProgramError::Raise ("Graphic3d_TransformPers::Apply, can not inverse projection matrix.");
+        }
+
+        NCollection_Vec4<T> aProjMax (static_cast<T> ( 1.0), static_cast<T> ( 1.0), static_cast<T> (0.0), static_cast<T> (1.0));
+        NCollection_Vec4<T> aProjMin (static_cast<T> (-1.0), static_cast<T> (-1.0), static_cast<T> (0.0), static_cast<T> (1.0));
+        NCollection_Vec4<T> aViewMax = anUnviewMat * aProjMax;
+        NCollection_Vec4<T> aViewMin = anUnviewMat * aProjMin;
+
+        aViewMax /= aViewMax.w();
+        aViewMin /= aViewMin.w();
+
+        T aMoveX = static_cast<T> (0.5) * (aViewMax.x() - aViewMin.x() - static_cast<T> (Point.z()));
+        T aMoveY = static_cast<T> (0.5) * (aViewMax.y() - aViewMin.y() - static_cast<T> (Point.z()));
+
+        aMoveX = (Point.x() > 0.0) ? aMoveX : -aMoveX;
+        aMoveY = (Point.y() > 0.0) ? aMoveY : -aMoveY;
+
+        Graphic3d_TransformUtils::Translate<T> (theProjection, aMoveX, aMoveY, static_cast<T> (0.0));
+      }
+    }
+    else if ((Flags & Graphic3d_TMF_PanPers) != Graphic3d_TMF_PanPers)
+    {
+      NCollection_Mat4<T> 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<T> (theWorldView, aRefPoint.x(), aRefPoint.y(), aRefPoint.z());
+    }
+  }
+}
+
+// =======================================================================
+// function : Apply
+// purpose  : Apply transformation to bounding box of presentation.
+// =======================================================================
+template<class T>
+void Graphic3d_TransformPers::Apply (const NCollection_Mat4<T>& theProjection,
+                                     const NCollection_Mat4<T>& 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<T, 4>::BVH_VecNt aMin (aXmin, aYmin, aZmin, static_cast<T> (1.0));
+  typename BVH_Box<T, 4>::BVH_VecNt aMax (aXmax, aYmax, aZmax, static_cast<T> (1.0));
+  BVH_Box<T, 4> 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<class T>
+void Graphic3d_TransformPers::Apply (const NCollection_Mat4<T>& theProjection,
+                                     const NCollection_Mat4<T>& theWorldView,
+                                     const Standard_Integer theViewportWidth,
+                                     const Standard_Integer theViewportHeight,
+                                     BVH_Box<T, 4>& theBoundingBox) const
+{
+  NCollection_Mat4<T> aTPers = Compute (theProjection, theWorldView, theViewportWidth, theViewportHeight);
+
+  if (aTPers.IsIdentity())
+  {
+    return;
+  }
+
+  const typename BVH_Box<T, 4>::BVH_VecNt& aMin = theBoundingBox.CornerMin();
+  const typename BVH_Box<T, 4>::BVH_VecNt& aMax = theBoundingBox.CornerMax();
+
+  typename BVH_Box<T, 4>::BVH_VecNt anArrayOfCorners[8];
+  anArrayOfCorners[0] = typename BVH_Box<T, 4>::BVH_VecNt (aMin.x(), aMin.y(), aMin.z(), static_cast<T> (1.0));
+  anArrayOfCorners[1] = typename BVH_Box<T, 4>::BVH_VecNt (aMin.x(), aMin.y(), aMax.z(), static_cast<T> (1.0));
+  anArrayOfCorners[2] = typename BVH_Box<T, 4>::BVH_VecNt (aMin.x(), aMax.y(), aMin.z(), static_cast<T> (1.0));
+  anArrayOfCorners[3] = typename BVH_Box<T, 4>::BVH_VecNt (aMin.x(), aMax.y(), aMax.z(), static_cast<T> (1.0));
+  anArrayOfCorners[4] = typename BVH_Box<T, 4>::BVH_VecNt (aMax.x(), aMin.y(), aMin.z(), static_cast<T> (1.0));
+  anArrayOfCorners[5] = typename BVH_Box<T, 4>::BVH_VecNt (aMax.x(), aMin.y(), aMax.z(), static_cast<T> (1.0));
+  anArrayOfCorners[6] = typename BVH_Box<T, 4>::BVH_VecNt (aMax.x(), aMax.y(), aMin.z(), static_cast<T> (1.0));
+  anArrayOfCorners[7] = typename BVH_Box<T, 4>::BVH_VecNt (aMax.x(), aMax.y(), aMax.z(), static_cast<T> (1.0));
+
+  theBoundingBox.Clear();
+  for (Standard_Integer anIt = 0; anIt < 8; ++anIt)
+  {
+    typename BVH_Box<T, 4>::BVH_VecNt& aCorner = anArrayOfCorners[anIt];
+    aCorner  = aTPers * aCorner;
+    aCorner /= aCorner.w();
+    theBoundingBox.Add (aCorner);
+  }
+}
+
+// =======================================================================
+// function : Compute
+// purpose  : Compute transformation.
+// =======================================================================
+template<class T>
+NCollection_Mat4<T> Graphic3d_TransformPers::Compute (const NCollection_Mat4<T>& theProjection,
+                                                      const NCollection_Mat4<T>& theWorldView,
+                                                      const Standard_Integer theViewportWidth,
+                                                      const Standard_Integer theViewportHeight) const
+{
+  if (Flags == Graphic3d_TMF_None)
+  {
+    return NCollection_Mat4<T>();
+  }
+
+  NCollection_Mat4<T> anUnviewMat;
+
+  if (!(theProjection * theWorldView).Inverted (anUnviewMat))
+  {
+    return NCollection_Mat4<T>();
+  }
+
+  NCollection_Mat4<T> aProjection (theProjection);
+  NCollection_Mat4<T> aWorldView (theWorldView);
+
+  Apply (aProjection, aWorldView, theViewportWidth, theViewportHeight);
+
+  return anUnviewMat * (aProjection * aWorldView);
+}
+
+#endif // _Graphic3d_TransformPers_HeaderFile
similarity index 67%
rename from src/OpenGl/OpenGl_Utils.hxx
rename to src/Graphic3d/Graphic3d_TransformUtils.hxx
index 39702c1..f2f4c7c 100644 (file)
@@ -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.
 //
 // 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 <OpenGl_Vec.hxx>
-#include <NCollection_Vector.hxx>
+#include <Graphic3d_Vec.hxx>
+#include <Standard_math.hxx> // 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<class T> struct MatrixType {};
 
-  //! Matrix type selector.
-  template<class T>
-  struct MatrixType {
-    //
-  };
+  template<> struct MatrixType<Standard_Real> { typedef Graphic3d_Mat4d Mat4; };
 
-  template<>
-  struct MatrixType<Standard_Real> {
-    typedef OpenGl_Mat4d Mat4;
-  };
-
-  template<>
-  struct MatrixType<Standard_ShortReal> {
-    typedef OpenGl_Mat4 Mat4;
-  };
+  template<> struct MatrixType<Standard_ShortReal> { typedef Graphic3d_Mat4 Mat4; };
 
-  //! Vector type selector.
-  template<class T>
-  struct VectorType {
-    //
-  };
-
-  template<>
-  struct VectorType<Standard_Real> {
-    typedef OpenGl_Vec2d Vec2;
-    typedef OpenGl_Vec3d Vec3;
-    typedef OpenGl_Vec4d Vec4;
-  };
+  template<class T> struct VectorType {};
 
-  template<>
-  struct VectorType<Standard_ShortReal> {
-    typedef OpenGl_Vec2 Vec2;
-    typedef OpenGl_Vec3 Vec3;
-    typedef OpenGl_Vec4 Vec4;
+  template<> struct VectorType<Standard_Real> {
+    typedef Graphic3d_Vec2d Vec2;
+    typedef Graphic3d_Vec3d Vec3;
+    typedef Graphic3d_Vec4d Vec4;
   };
 
-  //! Software implementation for OpenGL matrix stack.
-  template<class T>
-  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<T>::Mat4& Current()
-    {
-      return myCurrent;
-    }
-
-    //! Sets given matrix as current.
-    void SetCurrent (const typename MatrixType<T>::Mat4& theNewCurrent)
-    {
-      myCurrent = theNewCurrent;
-    }
-
-    //! Sets given matrix as current.
-    template <typename Other_t>
-    void SetCurrent (const typename MatrixType<Other_t>::Mat4& theNewCurrent)
-    {
-      myCurrent.Convert (theNewCurrent);
-    }
-
-    //! Sets current matrix to identity.
-    void SetIdentity()
-    {
-      myCurrent = typename MatrixType<T>::Mat4();
-    }
-
-  private:
-
-    NCollection_Vector<typename MatrixType<T>::Mat4> myStack;     //!< Collection used to maintenance matrix stack
-    typename MatrixType<T>::Mat4                     myCurrent;   //!< Current matrix
-    Standard_Integer                                 myStackHead; //!< Index of stack head
-
+  template<> struct VectorType<Standard_ShortReal> {
+    typedef Graphic3d_Vec2 Vec2;
+    typedef Graphic3d_Vec3 Vec3;
+    typedef Graphic3d_Vec4 Vec4;
   };
 
   //! Constructs a 3D orthographic projection matrix.
   template<class T>
   static void Ortho (typename MatrixType<T>::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<class T>
   static void Ortho2D (typename MatrixType<T>::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<class T>
@@ -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<class T>
-void OpenGl_Utils::Rotate (typename MatrixType<T>::Mat4& theOut,
-                           T                             theA,
-                           T                             theX,
-                           T                             theY,
-                           T                             theZ)
+void Graphic3d_TransformUtils::Rotate (typename MatrixType<T>::Mat4& theOut,
+                                       T                             theA,
+                                       T                             theX,
+                                       T                             theY,
+                                       T                             theZ)
 {
   typename MatrixType<T>::Mat4 aMat;
   ConstructRotate (aMat, theA, theX, theY, theZ);
@@ -213,10 +135,10 @@ void OpenGl_Utils::Rotate (typename MatrixType<T>::Mat4& theOut,
 // purpose  : Constructs a 4x4 translation matrix
 // =======================================================================
 template<class T>
-void OpenGl_Utils::Translate (typename MatrixType<T>::Mat4& theOut,
-                              T                             theX,
-                              T                             theY,
-                              T                             theZ)
+void Graphic3d_TransformUtils::Translate (typename MatrixType<T>::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<T>::Mat4& theOut,
 // purpose  : Constructs a 4x4 scaling matrix
 // =======================================================================
 template<class T>
-void OpenGl_Utils::Scale (typename MatrixType<T>::Mat4& theOut,
-                          T                             theX,
-                          T                             theY,
-                          T                             theZ)
+void Graphic3d_TransformUtils::Scale (typename MatrixType<T>::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<T>::Mat4& theOut,
 // purpose  : Constructs a 4x4 rotation matrix
 // =======================================================================
 template<class T>
-void OpenGl_Utils::ConstructRotate (typename MatrixType<T>::Mat4& theOut, T theA, T theX, T theY, T theZ)
+void Graphic3d_TransformUtils::ConstructRotate (typename MatrixType<T>::Mat4& theOut,
+                                                T                             theA,
+                                                T                             theX,
+                                                T                             theY,
+                                                T                             theZ)
 {
   const T aSin = std::sin (theA * static_cast<T> (M_PI / 180.0));
   const T aCos = std::cos (theA * static_cast<T> (M_PI / 180.0));
@@ -287,7 +213,7 @@ void OpenGl_Utils::ConstructRotate (typename MatrixType<T>::Mat4& theOut, T theA
                                 && (theY == static_cast<T> (0.0))
                                 && (theZ != static_cast<T> (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<T>::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<T>::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<T>::Mat4& theOut, T theA
 
   if (aNorm <= static_cast<T> (1.0e-4))
   {
-    return; // negligible rotation
+    return; // Negligible rotation.
   }
 
   aNorm = static_cast<T> (1.0) / aNorm;
@@ -385,8 +311,13 @@ void OpenGl_Utils::ConstructRotate (typename MatrixType<T>::Mat4& theOut, T theA
 // purpose  : Constructs a 3D orthographic projection matrix
 // =======================================================================
 template<class T>
-void OpenGl_Utils::Ortho (typename MatrixType<T>::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<T>::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<T>::Mat4& theOut,
 // purpose  : Constructs a 2D orthographic projection matrix
 // =======================================================================
 template<class T>
-void OpenGl_Utils::Ortho2D (typename MatrixType<T>::Mat4& theOut,
-  const T theLeft, const T theRight, const T theBottom, const T theTop)
+void Graphic3d_TransformUtils::Ortho2D (typename MatrixType<T>::Mat4& theOut,
+                                        const T                       theLeft,
+                                        const T                       theRight,
+                                        const T                       theBottom,
+                                        const T                       theTop)
 {
   Ortho (theOut, theLeft, theRight, theBottom, theTop, static_cast<T> (-1.0), static_cast<T> (1.0));
 }
@@ -421,15 +355,15 @@ void OpenGl_Utils::Ortho2D (typename MatrixType<T>::Mat4& theOut,
 // purpose  : Maps object coordinates to window coordinates
 // =======================================================================
 template<class T>
-static Standard_Boolean OpenGl_Utils::Project (const T                             theObjX,
-                                               const T                             theObjY,
-                                               const T                             theObjZ,
-                                               const typename MatrixType<T>::Mat4& theModViewMat,
-                                               const typename MatrixType<T>::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<T>::Mat4& theModViewMat,
+                                                           const typename MatrixType<T>::Mat4& theProjectMat,
+                                                           const Standard_Integer              theViewport[4],
+                                                           T&                                  theWinX,
+                                                           T&                                  theWinY,
+                                                           T&                                  theWinZ)
 {
   typename VectorType<T>::Vec4 anIn (theObjX, theObjY, theObjZ, static_cast<T> (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<T> (0.5) + static_cast<T> (0.5);
   anOut.y() = anOut.y() * static_cast<T> (0.5) + static_cast<T> (0.5);
   anOut.z() = anOut.z() * static_cast<T> (0.5) + static_cast<T> (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<class T>
-static Standard_Boolean OpenGl_Utils::UnProject (const T                             theWinX,
-                                                 const T                             theWinY,
-                                                 const T                             theWinZ,
-                                                 const typename MatrixType<T>::Mat4& theModViewMat,
-                                                 const typename MatrixType<T>::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<T>::Mat4& theModViewMat,
+                                                             const typename MatrixType<T>::Mat4& theProjectMat,
+                                                             const Standard_Integer              theViewport[4],
+                                                             T&                                  theObjX,
+                                                             T&                                  theObjY,
+                                                             T&                                  theObjZ)
 {
   typename MatrixType<T>::Mat4 anUnviewMat;
 
@@ -486,11 +420,11 @@ static Standard_Boolean OpenGl_Utils::UnProject (const T
 
   typename VectorType<T>::Vec4 anIn (theWinX, theWinY, theWinZ, static_cast<T> (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<T> (2.0) - static_cast<T> (1.0);
   anIn.y() = anIn.y() * static_cast<T> (2.0) - static_cast<T> (1.0);
   anIn.z() = anIn.z() * static_cast<T> (2.0) - static_cast<T> (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 (file)
index 0000000..03713cb
--- /dev/null
@@ -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 <Standard_Transient.hxx>
+#include <Standard_TypeDef.hxx>
+
+//! 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<Standard_Transient*> (theCamera);
+    myProjectionState = theProjectionState;
+    myWorldViewState  = theWorldViewState;
+  }
+
+  //! Initialize world view projection state.
+  void Initialize (const Standard_Transient* theCamera = NULL)
+  {
+    myIsValid         = Standard_True;
+    myCamera          = const_cast<Standard_Transient*> (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
index db4acbf..0f4c3dd 100644 (file)
@@ -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 */
index 9086560..7cf6f41 100755 (executable)
@@ -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
index ebb5c87..a249664 100644 (file)
@@ -69,48 +69,28 @@ void OpenGl_BVHClipPrimitiveSet::Swap (const Standard_Integer theIdx1,
 }
 
 // =======================================================================
-// 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;
 }
 
 // =======================================================================
index 4da06c6..ec6bf33 100644 (file)
 
 #include <OpenGl_Structure.hxx>
 
-//! Defines index map of OpenGL structures.
-typedef NCollection_IndexedMap<const OpenGl_Structure*> OpenGl_IndexedMapOfStructure;
-
-//! Defines array of indexed maps of OpenGL structures.
-typedef NCollection_Array1<OpenGl_IndexedMapOfStructure> OpenGl_ArrayOfIndexedMapOfStructure;
-
 //! Set of OpenGl_Structures for building BVH tree.
 class OpenGl_BVHClipPrimitiveSet : public BVH_PrimitiveSet<Standard_ShortReal, 4>
 {
@@ -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 (file)
index 0000000..3555254
--- /dev/null
@@ -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 <OpenGl_BVHClipPrimitiveTrsfPersSet.hxx>
+#include <BVH_LinearBuilder.hxx>
+
+// =======================================================================
+// function : OpenGl_BVHClipPrimitiveTrsfPersSet
+// purpose  :
+// =======================================================================
+OpenGl_BVHClipPrimitiveTrsfPersSet::OpenGl_BVHClipPrimitiveTrsfPersSet()
+: myIsDirty (Standard_False),
+  myBVH (new BVH_Tree<Standard_ShortReal, 4>())
+{
+  myBuilder = new BVH_LinearBuilder<Standard_ShortReal, 4> (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<BVH_Tree<Standard_ShortReal, 4> >&
+  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<Standard_ShortReal, 4>::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 (file)
index 0000000..563554d
--- /dev/null
@@ -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 <BVH_Builder.hxx>
+#include <BVH_Set.hxx>
+#include <BVH_Tree.hxx>
+#include <Graphic3d_BndBox4f.hxx>
+#include <Graphic3d_WorldViewProjState.hxx>
+#include <NCollection_Handle.hxx>
+#include <NCollection_IndexedMap.hxx>
+#include <OpenGl_Structure.hxx>
+#include <OpenGl_Vec.hxx>
+
+//! 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<Standard_ShortReal, 4>
+{
+private:
+
+  typedef NCollection_Handle<Graphic3d_BndBox4f> 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_Tree<Standard_ShortReal, 4> >& 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<BVH_Tree<Standard_ShortReal, 4> > myBVH;
+
+  //! Builder for bottom-level BVH.
+  NCollection_Handle<BVH_Builder<Standard_ShortReal, 4> > myBuilder;
+
+  //! Indexed map of structures.
+  NCollection_IndexedMap<const OpenGl_Structure*> 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<HBndBox4f> myStructBoxes;
+
+  //! State of world view projection used for generation of transformation persistence bounding boxes.
+  Graphic3d_WorldViewProjState myStructBoxesState;
+};
+
+#endif // _OpenGl_BVHClipPrimitiveTrsfPersSet_HeaderFile
index 7fccc89..f71f9bf 100644 (file)
 // 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);
index 96183ce..c111c21 100644 (file)
@@ -17,7 +17,7 @@
 #define _OpenGl_BVHTreeSelector_HeaderFile
 
 #include <Graphic3d_Camera.hxx>
-
+#include <Graphic3d_WorldViewProjState.hxx>
 #include <OpenGl_Vec.hxx>
 
 //! 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
index d6f024b..e4573eb 100644 (file)
@@ -27,6 +27,7 @@
 #include <NCollection_List.hxx>
 #include <Message.hxx>
 #include <OpenGl_Caps.hxx>
+#include <OpenGl_MatrixState.hxx>
 #include <OpenGl_Vec.hxx>
 #include <OpenGl_Resource.hxx>
 #include <Standard_Transient.hxx>
@@ -34,7 +35,6 @@
 #include <TColStd_PackedMapOfInteger.hxx>
 #include <OpenGl_Clipping.hxx>
 #include <OpenGl_GlCore11.hxx>
-#include <OpenGl_Utils.hxx>
 #include <OpenGl_ShaderProgram.hxx>
 
 #include <NCollection_Shared.hxx>
@@ -697,9 +697,9 @@ private: //! @name fields tracking current state
 
 public:
 
-  OpenGl_Utils::MatrixState<Standard_ShortReal> ModelWorldState; //!< state of orientation matrix
-  OpenGl_Utils::MatrixState<Standard_ShortReal> WorldViewState;  //!< state of orientation matrix
-  OpenGl_Utils::MatrixState<Standard_ShortReal> ProjectionState; //!< state of projection  matrix
+  OpenGl_MatrixState<Standard_ShortReal> ModelWorldState; //!< state of orientation matrix
+  OpenGl_MatrixState<Standard_ShortReal> WorldViewState;  //!< state of orientation matrix
+  OpenGl_MatrixState<Standard_ShortReal> ProjectionState; //!< state of projection  matrix
 
 private:
 
index 76ef23f..1eb00d2 100755 (executable)
@@ -14,7 +14,6 @@
 // commercial license or contractual agreement.
 
 #include <OpenGl_GlCore11.hxx>
-#include <OpenGl_Utils.hxx>
 #include <InterfaceGraphic_Graphic3d.hxx>
 #include <InterfaceGraphic_Aspect.hxx>
 #include <InterfaceGraphic_Visual3d.hxx>
 #include <Graphic3d_ArrayOfPolylines.hxx>
 #include <Graphic3d_ArrayOfSegments.hxx>
 #include <Graphic3d_GraphicDriver.hxx>
+#include <Graphic3d_TransformPers.hxx>
+#include <Graphic3d_TransformUtils.hxx>
 #include <gp_Ax3.hxx>
 #include <OpenGl_AspectLine.hxx>
-#include <OpenGl_Utils.hxx>
 #include <OpenGl_Workspace.hxx>
 #include <OpenGl_View.hxx>
 #include <OpenGl_Cylinder.hxx>
@@ -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> ((Standard_ShortReal) aViewport[0],
-                                               (Standard_ShortReal) aViewport[1],
-                                               0.0f,
-                                               aModelMatrix, aProjMatrix, aViewport,
-                                               aPoint1.x(), aPoint1.y(), aPoint1.z());
-
-  OpenGl_Utils::UnProject<Standard_ShortReal> ((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> ((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> ((Standard_ShortReal) aViewport[0],
+                                                           (Standard_ShortReal) aViewport[1],
+                                                           0.0f,
+                                                           aModelMatrix, aProjMatrix, aViewport,
+                                                           aPoint1.x(), aPoint1.y(), aPoint1.z());
+
+  Graphic3d_TransformUtils::UnProject<Standard_ShortReal> ((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> ((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<Standard_ShortReal> (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<Standard_ShortReal> (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<Standard_ShortReal> (aWinPoint.x(), aWinPoint.y(), aWinPoint.z(),
-                                               aModelMat, aProjMat, aViewport,
-                                               anArrowStart.x(), anArrowStart.y(), anArrowStart.z());
+  Graphic3d_TransformUtils::UnProject<Standard_ShortReal> (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();
     }
index b0e8509..9f142bb 100644 (file)
@@ -22,7 +22,7 @@
 #include <Graphic3d_GraphicDriver.hxx>
 
 // =======================================================================
-// 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<BVH_Tree<Standard_ShortReal, 4> >& 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<BVH_Tree<Standard_ShortReal, 4> > 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--];
-    }
   }
 }
 
index f98cd38..4edce91 100644 (file)
 #include <InterfaceGraphic_telem.hxx>
 
 #include <OpenGl_BVHClipPrimitiveSet.hxx>
+#include <OpenGl_BVHClipPrimitiveTrsfPersSet.hxx>
 #include <OpenGl_BVHTreeSelector.hxx>
 
 #include <Graphic3d_ZLayerSettings.hxx>
+#include <Graphic3d_Camera.hxx>
 #include <OpenGl_GlCore11.hxx>
 
 
@@ -34,6 +36,12 @@ struct OpenGl_GlobalLayerSettings
   GLboolean DepthMask;
 };
 
+//! Defines index map of OpenGL structures.
+typedef NCollection_IndexedMap<const OpenGl_Structure*> OpenGl_IndexedMapOfStructure;
+
+//! Defines array of indexed maps of OpenGL structures.
+typedef NCollection_Array1<OpenGl_IndexedMapOfStructure> 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 (file)
index 0000000..9e67144
--- /dev/null
@@ -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 <OpenGl_Vec.hxx>
+#include <NCollection_Vector.hxx>
+
+//! Software implementation for OpenGL matrix stack.
+template<class T>
+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<T>::Mat4& Current()
+  {
+    return myCurrent;
+  }
+
+  //! Sets given matrix as current.
+  void SetCurrent (const typename OpenGl::MatrixType<T>::Mat4& theNewCurrent)
+  {
+    myCurrent = theNewCurrent;
+  }
+
+  //! Sets given matrix as current.
+  template <typename Other_t>
+  void SetCurrent (const typename OpenGl::MatrixType<Other_t>::Mat4& theNewCurrent)
+  {
+    myCurrent.Convert (theNewCurrent);
+  }
+
+  //! Sets current matrix to identity.
+  void SetIdentity()
+  {
+    myCurrent = typename OpenGl::MatrixType<T>::Mat4();
+  }
+
+private:
+
+  NCollection_Vector<typename OpenGl::MatrixType<T>::Mat4> myStack;     //!< Collection used to maintenance matrix stack
+  typename OpenGl::MatrixType<T>::Mat4                     myCurrent;   //!< Current matrix
+  Standard_Integer                                         myStackHead; //!< Index of stack head
+};
+
+#endif // _OpenGl_MatrixState_H__
index d1e8048..c6c0403 100644 (file)
@@ -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);
 
@@ -195,22 +191,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())
   {
index 8276945..bca38b0 100644 (file)
@@ -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;
index 0025e64..3b56b0a 100644 (file)
@@ -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;
 }
index ddc1027..5eaaeef 100644 (file)
 #include <OpenGl_ShaderProgram.hxx>
 #include <OpenGl_ShaderStates.hxx>
 #include <OpenGl_Text.hxx>
-#include <OpenGl_Utils.hxx>
 #include <OpenGl_Workspace.hxx>
 
 #include <Font_FontMgr.hxx>
+#include <Graphic3d_TransformUtils.hxx>
 #include <TCollection_HAsciiString.hxx>
 
 #ifdef HAVE_GL2PS
@@ -446,27 +446,28 @@ void OpenGl_Text::setupMatrix (const Handle(OpenGl_PrinterContext)& thePrintCtx,
 
   if (myIs2d)
   {
-    OpenGl_Utils::Translate<GLdouble> (aModViewMat, myPoint.x() + theDVec.x(), myPoint.y() + theDVec.y(), 0.f);
-    OpenGl_Utils::Scale<GLdouble> (aModViewMat, 1.f, -1.f, 1.f);
-    OpenGl_Utils::Rotate<GLdouble> (aModViewMat, theTextAspect.Angle(), 0.f, 0.f, 1.f);
+    Graphic3d_TransformUtils::Translate<GLdouble> (aModViewMat, myPoint.x() + theDVec.x(), myPoint.y() + theDVec.y(), 0.f);
+    Graphic3d_TransformUtils::Scale<GLdouble> (aModViewMat, 1.f, -1.f, 1.f);
+    Graphic3d_TransformUtils::Rotate<GLdouble> (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<Standard_Real> (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<GLdouble> (aModViewMat, anObjX, anObjY, anObjZ);
-    OpenGl_Utils::Rotate<GLdouble>    (aModViewMat, theTextAspect.Angle(), 0.0, 0.0, 1.0);
+    Graphic3d_TransformUtils::UnProject<Standard_Real> (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<GLdouble> (aModViewMat, anObjX, anObjY, anObjZ);
+    Graphic3d_TransformUtils::Rotate<GLdouble>    (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<GLdouble> (aModViewMat, aTextScaley, aTextScaley, aTextScaley);
+        Graphic3d_TransformUtils::Scale<GLdouble> (aModViewMat, aTextScaley, aTextScaley, aTextScaley);
       }
     #endif
-      OpenGl_Utils::Scale<GLdouble> (aModViewMat, myScaleHeight, myScaleHeight, myScaleHeight);
+      Graphic3d_TransformUtils::Scale<GLdouble> (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<Standard_Real> (myPoint.x(),
-                                          myPoint.y(),
-                                          myPoint.z(),
-                                          myModelMatrix,
-                                          myProjMatrix,
-                                          myViewport,
-                                          myWinX,
-                                          myWinY,
-                                          myWinZ);
+    Graphic3d_TransformUtils::Project<Standard_Real> (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<Standard_Real> (myWinX,
-                                            myWinY,
-                                            myWinZ,
-                                            OpenGl_Mat4d::Map (THE_IDENTITY_MATRIX),
-                                            myProjMatrix,
-                                            myViewport,
-                                            x1,
-                                            y1,
-                                            z1);
+    Graphic3d_TransformUtils::UnProject<Standard_Real> (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<Standard_Real> (myWinX,
-                                            myWinY + h,
-                                            myWinZ,
-                                            OpenGl_Mat4d::Map (THE_IDENTITY_MATRIX),
-                                            myProjMatrix,
-                                            myViewport,
-                                            x2,
-                                            y2,
-                                            z2);
+    Graphic3d_TransformUtils::UnProject<Standard_Real> (myWinX,
+                                                        myWinY + h,
+                                                        myWinZ,
+                                                        OpenGl_Mat4d::Map (THE_IDENTITY_MATRIX),
+                                                        myProjMatrix,
+                                                        myViewport,
+                                                        x2,
+                                                        y2,
+                                                        z2);
 
     myScaleHeight = (y2 - y1) / h;
     if (theTextAspect.IsZoomable())
index 93c06ce..60f34bd 100644 (file)
@@ -20,6 +20,7 @@
 #include <Graphic3d_ArrayOfSegments.hxx>
 #include <Graphic3d_ArrayOfPolylines.hxx>
 #include <Graphic3d_GraphicDriver.hxx>
+#include <Graphic3d_TransformUtils.hxx>
 #include <OpenGl_View.hxx>
 #include <OpenGl_Workspace.hxx>
 #include <Precision.hxx>
@@ -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<Standard_Real>(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<Standard_Real> (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<Standard_Real> (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<Standard_Real> (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<Standard_Real> (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<Standard_Real> (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<Standard_Real> (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<Standard_Real> (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<Standard_Real> (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<Standard_Real> (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)
index 34c9250..cb4cf96 100755 (executable)
@@ -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<class T> struct VectorType
+  {
+    // Not implemented
+  };
+
+  template<> struct VectorType<Standard_Real>
+  {
+    typedef OpenGl_Vec2d Vec2;
+    typedef OpenGl_Vec3d Vec3;
+    typedef OpenGl_Vec4d Vec4;
+  };
+
+  template<> struct VectorType<Standard_ShortReal>
+  {
+    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<class T> struct MatrixType
+  {
+    // Not implemented
+  };
+
+  template<> struct MatrixType<Standard_Real>
+  {
+    typedef OpenGl_Mat4d Mat4;
+  };
+
+  template<> struct MatrixType<Standard_ShortReal>
+  {
+    typedef OpenGl_Mat4 Mat4;
+  };
+}
+
 #endif // _OpenGl_Vec_H__
index f602c20..f7f155a 100644 (file)
@@ -22,9 +22,7 @@
 #include <OpenGl_ShaderManager.hxx>
 #include <OpenGl_Texture.hxx>
 #include <OpenGl_Trihedron.hxx>
-#include <OpenGl_transform_persistence.hxx>
 #include <OpenGl_View.hxx>
-#include <OpenGl_Utils.hxx>
 #include <OpenGl_Workspace.hxx>
 
 #include <Graphic3d_TextureEnv.hxx>
@@ -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<GLfloat> (theWidth  / 2);
-    GLfloat aRight  =  static_cast<GLfloat> (theWidth  / 2);
-    GLfloat aBottom = -static_cast<GLfloat> (theHeight / 2);
-    GLfloat aTop    =  static_cast<GLfloat> (theHeight / 2);
-    GLfloat aGap    =  static_cast<GLfloat> (theTransPers->pointZ);
-    if (theTransPers->pointX > 0)
-    {
-      aLeft  -= static_cast<GLfloat> (theWidth / 2) - aGap;
-      aRight -= static_cast<GLfloat> (theWidth / 2) - aGap;
-    }
-    else if (theTransPers->pointX < 0)
-    {
-      aLeft  += static_cast<GLfloat> (theWidth / 2) - aGap;
-      aRight += static_cast<GLfloat> (theWidth / 2) - aGap;
-    }
-    if (theTransPers->pointY > 0)
-    {
-      aBottom -= static_cast<GLfloat> (theHeight / 2) - aGap;
-      aTop    -= static_cast<GLfloat> (theHeight / 2) - aGap;
-    }
-    else if (theTransPers->pointY < 0)
-    {
-      aBottom += static_cast<GLfloat> (theHeight / 2) - aGap;
-      aTop    += static_cast<GLfloat> (theHeight / 2) - aGap;
-    }
-    if (theTransPers->mode == TPF_2D_ISTOPDOWN)
-    {
-      const GLfloat aTemp = aTop;
-      aTop    = aBottom;
-      aBottom = aTemp;
-    }
-
-    OpenGl_Mat4 aProjectMat;
-    OpenGl_Utils::Ortho2D<Standard_ShortReal> (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<Standard_Real> (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<Standard_Real> (aModelMatrix);
-  theCtx->ProjectionState.SetCurrent<Standard_Real> (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<Standard_Real> (0.5 * aViewportW,
-                                              0.5 * aViewportH,
-                                              0.0,
-                                              anIdentity,
-                                              aProjMatrix,
-                                              aViewport,
-                                              aW1,
-                                              aH1,
-                                              aDummy);
-
-      OpenGl_Utils::UnProject<Standard_Real> (-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<Standard_Real> (aProjMatrix, aMoveX, aMoveY, 0.0);
-      theCtx->ProjectionState.SetCurrent<Standard_Real> (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<Standard_Real> (aWinX,
-                                            aWinY,
-                                            aWinZ,
-                                            aModelMatrix,
-                                            aProjMatrix,
-                                            aViewport,
-                                            aMoveX,
-                                            aMoveY,
-                                            aMoveZ);
-
-    OpenGl_Utils::Translate<Standard_Real> (aModelMatrix, aMoveX, aMoveY, aMoveZ);
-    theCtx->WorldViewState.SetCurrent<Standard_Real> (aModelMatrix);
-  }
-
-  theCtx->ApplyProjectionMatrix();
-  return aTransPersPrev;
-}
index 86220b2..f5d5176 100644 (file)
@@ -35,6 +35,7 @@
 #include <Graphic3d_CView.hxx>
 #include <Graphic3d_GraduatedTrihedron.hxx>
 #include <Graphic3d_SequenceOfHClipPlane.hxx>
+#include <Graphic3d_WorldViewProjState.hxx>
 #include <Graphic3d_ZLayerSettings.hxx>
 #include <Visual3d_TypeOfSurfaceDetail.hxx>
 #include <Visual3d_TypeOfModel.hxx>
@@ -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;
index 3bf0162..088b928 100644 (file)
@@ -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
   // ====================================
index 668cd8f..997e45b 100644 (file)
@@ -19,9 +19,9 @@
 #include <OpenGl_Context.hxx>
 #include <OpenGl_GraphicDriver.hxx>
 #include <OpenGl_Window.hxx>
-#include <OpenGl_Utils.hxx>
 
 #include <Aspect_GraphicDeviceDefinitionError.hxx>
+#include <Graphic3d_TransformUtils.hxx>
 #include <TCollection_AsciiString.hxx>
 #include <TCollection_ExtendedString.hxx>
 #include <Graphic3d_GraphicDriver.hxx>
@@ -788,7 +788,7 @@ void OpenGl_Window::ReadDepths (const Standard_Integer theX,     const Standard_
     return;
 
   OpenGl_Mat4 aProjectMat;
-  OpenGl_Utils::Ortho2D<Standard_ShortReal> (aProjectMat,
+  Graphic3d_TransformUtils::Ortho2D (aProjectMat,
     0.f, static_cast<GLfloat> (myWidth), 0.f, static_cast<GLfloat> (myHeight));
 
   myGlContext->WorldViewState.Push();
index 7a9d4ea..b26a554 100644 (file)
 #include <OpenGl_Sampler.hxx>
 #include <OpenGl_ShaderManager.hxx>
 #include <OpenGl_Texture.hxx>
-#include <OpenGl_Utils.hxx>
 #include <OpenGl_View.hxx>
 #include <OpenGl_Workspace.hxx>
 
 #include <Graphic3d_TextureParams.hxx>
 #include <Graphic3d_GraphicDriver.hxx>
+#include <Graphic3d_TransformUtils.hxx>
 
 #if defined(_WIN32) && defined(HAVE_VIDEOCAPTURE)
   #include <OpenGl_AVIWriter.hxx>
@@ -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<Standard_ShortReal> (aProjectMat,
+  Graphic3d_TransformUtils::Ortho2D (aProjectMat,
     0.f, static_cast<GLfloat> (myWidth), 0.f, static_cast<GLfloat> (myHeight));
 
   myGlContext->WorldViewState.Push();
diff --git a/src/OpenGl/OpenGl_transform_persistence.hxx b/src/OpenGl/OpenGl_transform_persistence.hxx
deleted file mode 100644 (file)
index 6d14deb..0000000
+++ /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*/
index 6aed91d..82120a7 100644 (file)
@@ -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());
 }
 
 //=======================================================================
index 34055ba..e69c471 100644 (file)
@@ -23,7 +23,6 @@
 #include <PrsMgr_Presentations.hxx>
 #include <PrsMgr_TypeOfPresentation3d.hxx>
 #include <Graphic3d_SequenceOfHClipPlane.hxx>
-#include <Graphic3d_CTransPersStruct.hxx>
 #include <Standard_Boolean.hxx>
 #include <Graphic3d_ZLayerId.hxx>
 #include <PrsMgr_PresentableObjectPointer.hxx>
@@ -33,6 +32,7 @@
 #include <PrsMgr_Presentation.hxx>
 #include <PrsMgr_PresentationManager3d.hxx>
 #include <Standard_Integer.hxx>
+#include <Graphic3d_TransformPers.hxx>
 #include <Graphic3d_TransModeFlags.hxx>
 #include <TColStd_ListOfInteger.hxx>
 #include <Graphic3d_ClipPlane.hxx>
@@ -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 <AMode> 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;
index 7beaf60..352219e 100644 (file)
 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
 {
index 17bc333..cd3af8a 100755 (executable)
@@ -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
index 62d6de3..6d22437 100644 (file)
@@ -33,8 +33,9 @@ SelectMgr_BaseFrustum::SelectMgr_BaseFrustum()
 //=======================================================================
 void SelectMgr_BaseFrustum::SetCamera (const Handle(Graphic3d_Camera)& theCamera)
 {
-  myBuilder->SetOrientation (theCamera->OrientationMatrix());
-  myBuilder->SetProjection (theCamera->ProjectionMatrix());
+  myBuilder->SetWorldViewMatrix (theCamera->OrientationMatrix());
+  myBuilder->SetProjectionMatrix (theCamera->ProjectionMatrix());
+  myBuilder->SetWorldViewProjState (theCamera->WorldViewProjState());
   myIsOrthographic = theCamera->IsOrthographic();
   myBuilder->InvalidateViewport();
 }
@@ -44,15 +45,47 @@ 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
 //=======================================================================
index e2e466e..634b113 100644 (file)
@@ -24,6 +24,7 @@
 #include <Graphic3d_Camera.hxx>
 #include <Graphic3d_ClipPlane.hxx>
 #include <Graphic3d_SequenceOfHClipPlane.hxx>
+#include <Graphic3d_WorldViewProjState.hxx>
 
 #include <TColgp_HArray1OfPnt.hxx>
 #include <TColgp_Array1OfPnt2d.hxx>
@@ -53,8 +54,18 @@ public:
 
   //! Passes camera projection and orientation matrices to builder
   void SetCamera (const Graphic3d_Mat4d& theProjection,
-                  const Graphic3d_Mat4d& theOrientation,
-                  const Standard_Integer theIsOrthographic);
+                  const Graphic3d_Mat4d& theWorldView,
+                  const Standard_Integer theIsOrthographic,
+                  const Graphic3d_WorldViewProjState& theWVPState = Graphic3d_WorldViewProjState());
+
+  //! @return current camera projection transformation common for all selecting volumes
+  const Graphic3d_Mat4d& ProjectionMatrix() const;
+
+  //! @return current camera world view transformation common for all selecting volumes
+  const Graphic3d_Mat4d& WorldViewMatrix() const;
+
+  //! @return current camera world view projection transformation state
+  const Graphic3d_WorldViewProjState& WorldViewProjState() const;
 
   void SetPixelTolerance (const Standard_Real theTol);
 
index c0d85fc..09fa644 100644 (file)
 // 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);
   }
index 2a09a2e..d090bf4 100644 (file)
@@ -19,6 +19,7 @@
 #include <Standard_Type.hxx>
 
 #include <Graphic3d_Camera.hxx>
+#include <Graphic3d_WorldViewProjState.hxx>
 #include <Precision.hxx>
 #include <SelectMgr_VectorTypes.hxx>
 
@@ -31,11 +32,23 @@ public:
   //! Creates new frustum builder with empty matrices
   SelectMgr_FrustumBuilder();
 
-  //! Stores current orientation matrix
-  void SetOrientation (const Graphic3d_Mat4d& theOrientation);
+  //! Stores current world view transformation matrix
+  void SetWorldViewMatrix (const Graphic3d_Mat4d& theWorldViewMatrix);
+
+  //! @return current world view transformation matrix
+  const Graphic3d_Mat4d& WorldViewMatrix() const;
 
   //! Stores current projection matrix
-  void SetProjection (const Graphic3d_Mat4d& theProjection);
+  void SetProjectionMatrix (const Graphic3d_Mat4d& theProjection);
+
+  //! @return current projection matrix
+  const Graphic3d_Mat4d& ProjectionMatrix() const;
+
+  //! Stores current world view projection matrix state for the orientation and projection matrices
+  void SetWorldViewProjState (const Graphic3d_WorldViewProjState& theState);
+
+  //! @return current world view projection state
+  const Graphic3d_WorldViewProjState& WorldViewProjState() const;
 
   //! Stores current window width and height
   void SetWindowSize (const Standard_Integer theWidth,
@@ -70,8 +83,9 @@ private:
 
 private:
 
-  Graphic3d_Mat4d                   myOrientation;
+  Graphic3d_Mat4d                   myWorldView;
   Graphic3d_Mat4d                   myProjection;
+  Graphic3d_WorldViewProjState      myWorldViewProjState;
   Standard_Integer                  myWidth;
   Standard_Integer                  myHeight;
   NCollection_Vec4<Standard_Real>   myViewport;
index 8de0f94..7a64cbb 100644 (file)
@@ -247,25 +247,20 @@ void SelectMgr_SelectableObject::ResetTransformation()
   PrsMgr_PresentableObject::ResetTransformation();
 }
 
-
 //=======================================================================
 //function : UpdateTransformation
 //purpose  : 
 //=======================================================================
-void SelectMgr_SelectableObject::UpdateTransformation() 
+void SelectMgr_SelectableObject::UpdateTransformation()
 {
-  
-  Handle(Select3D_SensitiveEntity) SE;
-  for(Init();More();Next()){
-    const Handle(SelectMgr_Selection) & Sel =  CurrentSelection();
-    Sel->UpdateStatus(SelectMgr_TOU_Partial);
-    Sel->UpdateBVHStatus (SelectMgr_TBU_Invalidate);
+  for (Init(); More(); Next())
+  {
+    CurrentSelection()->UpdateStatus (SelectMgr_TOU_Partial);
   }
-  PrsMgr_PresentableObject::UpdateTransformation();
 
+  PrsMgr_PresentableObject::UpdateTransformation();
 }
 
-
 //=======================================================================
 //function : UpdateTransformation
 //purpose  : 
index 91bc263..b9c5cbd 100644 (file)
@@ -32,13 +32,18 @@ SelectMgr_SelectableObjectSet::SelectMgr_SelectableObjectSet()
 // function : Append
 // purpose  : Adds new object to the set and marks BVH tree for rebuild
 //=======================================================================
-void SelectMgr_SelectableObjectSet::Append (const Handle(SelectMgr_SelectableObject)& theObject)
+Standard_Boolean SelectMgr_SelectableObjectSet::Append (const Handle(SelectMgr_SelectableObject)& theObject)
 {
   Standard_Integer aSize = Size();
+
   if (aSize < myObjects.Add (theObject))
   {
     MarkDirty();
+
+    return Standard_True;
   }
+
+  return Standard_False;
 }
 
 //=======================================================================
@@ -46,7 +51,7 @@ void SelectMgr_SelectableObjectSet::Append (const Handle(SelectMgr_SelectableObj
 // purpose  : Removes object theObject from set and marks BVH tree for
 //            rebuild
 //=======================================================================
-void SelectMgr_SelectableObjectSet::Remove (const Handle(SelectMgr_SelectableObject)& theObject)
+Standard_Boolean SelectMgr_SelectableObjectSet::Remove (const Handle(SelectMgr_SelectableObject)& theObject)
 {
   const Standard_Integer anIndex = myObjects.FindIndex (theObject);
 
@@ -60,7 +65,11 @@ void SelectMgr_SelectableObjectSet::Remove (const Handle(SelectMgr_SelectableObj
     myObjects.RemoveLast();
 
     MarkDirty();
+
+    return Standard_True;
   }
+
+  return Standard_False;
 }
 
 //=======================================================================
@@ -119,21 +128,3 @@ Standard_Integer SelectMgr_SelectableObjectSet::Size() const
 {
   return myObjects.Size();
 }
-
-//=======================================================================
-// function : GetObjectById
-// purpose  : Returns object from set by theIndex given
-//=======================================================================
-const Handle(SelectMgr_SelectableObject)& SelectMgr_SelectableObjectSet::GetObjectById (const Standard_Integer theIndex) const
-{
-  return myObjects.FindKey (theIndex + 1);
-}
-
-//=======================================================================
-// function : Contains
-// purpose  : Returns true if this objects set contains theObject given
-//=======================================================================
-Standard_Boolean SelectMgr_SelectableObjectSet::Contains (const Handle(SelectMgr_SelectableObject)& theObject) const
-{
-  return myObjects.Contains (theObject);
-}
index 76ccc20..dd8c570 100644 (file)
@@ -35,37 +35,45 @@ public:
 
   //! Creates new empty objects set and initializes BVH tree
   //! builder to Binned builder with 1 element per list
-  SelectMgr_SelectableObjectSet();
+  Standard_EXPORT SelectMgr_SelectableObjectSet();
 
   //! Releases resources of selectable object set.
   virtual ~SelectMgr_SelectableObjectSet() { }
 
-  //! Adds new object to the set and marks BVH tree for rebuild
-  void Append (const Handle(SelectMgr_SelectableObject)& theObject);
+  //! Adds new object to the set and marks BVH tree for rebuild.
+  //! @return true if structure added, otherwise returns false (structure already in the set).
+  Standard_EXPORT Standard_Boolean Append (const Handle(SelectMgr_SelectableObject)& theObject);
 
-  //! Removes object theObject from set and marks BVH tree for rebuild
-  void Remove (const Handle(SelectMgr_SelectableObject)& theObject);
+  //! Removes object theObject from set and marks BVH tree for rebuild.
+  //! @return true if structure removed, otherwise returns false (structure is not in the set).
+  Standard_EXPORT Standard_Boolean Remove (const Handle(SelectMgr_SelectableObject)& theObject);
 
   //! Returns bounding box of object with index theIndex
-  virtual Select3D_BndBox3d Box (const Standard_Integer theIndex) const Standard_OVERRIDE;
+  Standard_EXPORT virtual Select3D_BndBox3d Box (const Standard_Integer theIndex) const Standard_OVERRIDE;
 
   //! Returns center of object with index theIndex in the set
   //! along the given axis theAxis
-  virtual Standard_Real Center (const Standard_Integer theIndex,
-                                const Standard_Integer theAxis) const Standard_OVERRIDE;
+  Standard_EXPORT virtual Standard_Real Center (const Standard_Integer theIndex,
+                                                const Standard_Integer theAxis) const Standard_OVERRIDE;
 
   //! Swaps items with indexes theIndex1 and theIndex2 in the set
-  virtual void Swap (const Standard_Integer theIndex1,
-                     const Standard_Integer theIndex2) Standard_OVERRIDE;
+  Standard_EXPORT virtual void Swap (const Standard_Integer theIndex1,
+                                     const Standard_Integer theIndex2) Standard_OVERRIDE;
 
   //! Returns size of objects set
-  virtual Standard_Integer Size() const Standard_OVERRIDE;
+  Standard_EXPORT virtual Standard_Integer Size() const Standard_OVERRIDE;
 
   //! Returns object from set by theIndex given
-  const Handle(SelectMgr_SelectableObject)& GetObjectById (const Standard_Integer theIndex) const;
+  const Handle(SelectMgr_SelectableObject)& GetObjectById (const Standard_Integer theIndex) const
+  {
+    return myObjects.FindKey (theIndex + 1);
+  }
 
   //! Returns true if this objects set contains theObject given
-  Standard_Boolean Contains (const Handle(SelectMgr_SelectableObject)& theObject) const;
+  Standard_Boolean Contains (const Handle(SelectMgr_SelectableObject)& theObject) const
+  {
+    return myObjects.Contains (theObject);
+  }
 
 private:
 
diff --git a/src/SelectMgr/SelectMgr_SelectableObjectTrsfPersSet.cxx b/src/SelectMgr/SelectMgr_SelectableObjectTrsfPersSet.cxx
new file mode 100644 (file)
index 0000000..aec1b10
--- /dev/null
@@ -0,0 +1,164 @@
+// Created on: 2015-06-30
+// Created by: Anton POLETAEV
+// Copyright (c) 2015 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#include <SelectMgr_SelectableObjectTrsfPersSet.hxx>
+
+#include <Bnd_Box.hxx>
+#include <BVH_LinearBuilder.hxx>
+#include <SelectMgr_VectorTypes.hxx>
+
+//=======================================================================
+// function : SelectMgr_SelectableObjectTrsfPersSet
+// purpose  :
+//=======================================================================
+SelectMgr_SelectableObjectTrsfPersSet::SelectMgr_SelectableObjectTrsfPersSet()
+: myIsDirty (Standard_False),
+  myBVH (new BVH_Tree<Standard_Real, 3>())
+{
+  myBuilder = new BVH_LinearBuilder<Standard_Real, 3> (1, 32);
+}
+
+//=======================================================================
+// function : Size
+// purpose  :
+//=======================================================================
+Standard_Integer SelectMgr_SelectableObjectTrsfPersSet::Size() const
+{
+  return myObjects.Size();
+}
+
+//=======================================================================
+// function : Box
+// purpose  :
+//=======================================================================
+Select3D_BndBox3d SelectMgr_SelectableObjectTrsfPersSet::Box (const Standard_Integer theIndex) const
+{
+  return *myObjectBoxes (theIndex + 1);
+}
+
+//=======================================================================
+// function : Center
+// purpose  :
+//=======================================================================
+Standard_Real SelectMgr_SelectableObjectTrsfPersSet::Center (const Standard_Integer theIndex,
+                                                             const Standard_Integer theAxis) const
+{
+  const Select3D_BndBox3d& aBndBox = *myObjectBoxes (theIndex + 1);
+
+  return (aBndBox.CornerMin()[theAxis] + aBndBox.CornerMax()[theAxis]) * 0.5;
+}
+
+//=======================================================================
+// function : Swap
+// purpose  :
+//=======================================================================
+void SelectMgr_SelectableObjectTrsfPersSet::Swap (const Standard_Integer theIndex1,
+                                                  const Standard_Integer theIndex2)
+{
+  const Standard_Integer aStructIdx1 = theIndex1 + 1;
+  const Standard_Integer aStructIdx2 = theIndex2 + 1;
+
+  myObjects.Swap (aStructIdx1, aStructIdx2);
+  myObjectBoxes.Swap (aStructIdx1, aStructIdx2);
+}
+
+//=======================================================================
+// function : Append
+// purpose  :
+//=======================================================================
+Standard_Boolean SelectMgr_SelectableObjectTrsfPersSet::Append (const Handle(SelectMgr_SelectableObject)& theObject)
+{
+  Standard_Integer aSize = Size();
+
+  if (aSize < myObjects.Add (theObject))
+  {
+    MarkDirty();
+
+    return Standard_True;
+  }
+
+  return Standard_False;
+}
+
+//=======================================================================
+// function : Remove
+// purpose  :
+//=======================================================================
+Standard_Boolean SelectMgr_SelectableObjectTrsfPersSet::Remove (const Handle(SelectMgr_SelectableObject)& theObject)
+{
+  const Standard_Integer anIndex = myObjects.FindIndex (theObject);
+
+  if (anIndex != 0)
+  {
+    myObjects.Swap (Size(), anIndex);
+    myObjects.RemoveLast();
+    MarkDirty();
+
+    return Standard_True;
+  }
+
+  return Standard_False;
+}
+
+//=======================================================================
+// function : BVH
+// purpose  :
+//=======================================================================
+const NCollection_Handle<BVH_Tree<Standard_Real, 3> >&
+  SelectMgr_SelectableObjectTrsfPersSet::BVH (const Graphic3d_Mat4d& theProjectionMatrix,
+                                              const Graphic3d_Mat4d& theWorldViewMatrix,
+                                              const Graphic3d_WorldViewProjState& theWVPState)
+{
+  if (!myIsDirty && (myObjectBoxesState.IsValid() && !myObjectBoxesState.IsChanged(theWVPState)))
+  {
+    return myBVH;
+  }
+
+  myObjectBoxes.ReSize (myObjects.Size());
+
+  for (Standard_Integer anObjectIdx = 1; anObjectIdx <= myObjects.Size(); ++anObjectIdx)
+  {
+    const Handle(SelectMgr_SelectableObject)& anObject = myObjects (anObjectIdx);
+
+    Bnd_Box aBoundingBox;
+
+    if (anObject->TransformPersistence().Flags && !(anObject->TransformPersistence().Flags & Graphic3d_TMF_2d))
+    {
+      anObject->BoundingBox (aBoundingBox);
+      anObject->TransformPersistence().Apply (theProjectionMatrix, theWorldViewMatrix, 0, 0, aBoundingBox);
+    }
+
+    if (aBoundingBox.IsVoid())
+    {
+      myObjectBoxes.Add (new Select3D_BndBox3d());
+    }
+    else
+    {
+      gp_Pnt aMin = aBoundingBox.CornerMin();
+      gp_Pnt aMax = aBoundingBox.CornerMax();
+
+      myObjectBoxes.Add (new Select3D_BndBox3d (Select3D_Vec3 (aMin.X(), aMin.Y(), aMin.Z()),
+                                                Select3D_Vec3 (aMax.X(), aMax.Y(), aMax.Z())));
+    }
+  }
+
+  myBuilder->Build (this, myBVH.operator->(), BVH_Set<Standard_Real, 3>::Box());
+
+  myObjectBoxesState = theWVPState;
+  myObjectBoxes.Clear();
+  myIsDirty = Standard_False;
+
+  return myBVH;
+}
diff --git a/src/SelectMgr/SelectMgr_SelectableObjectTrsfPersSet.hxx b/src/SelectMgr/SelectMgr_SelectableObjectTrsfPersSet.hxx
new file mode 100644 (file)
index 0000000..7d252ab
--- /dev/null
@@ -0,0 +1,115 @@
+// Created on: 2015-06-30
+// Created by: Anton POLETAEV
+// Copyright (c) 2015 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _SelectMgr_SelectableObjectTrsfPersSet_HeaderFile
+#define _SelectMgr_SelectableObjectTrsfPersSet_HeaderFile
+
+#include <BVH_Builder.hxx>
+#include <BVH_Set.hxx>
+#include <BVH_Tree.hxx>
+#include <Graphic3d_Camera.hxx>
+#include <Graphic3d_WorldViewProjState.hxx>
+#include <NCollection_Handle.hxx>
+#include <NCollection_IndexedMap.hxx>
+#include <Select3D_BndBox3d.hxx>
+#include <SelectMgr_SelectableObject.hxx>
+
+//! Primitive set specialized for transformation persistent selectable objects.
+//! Provides built-in mechanism to invalidate tree when world view projection state changes.
+//! Due to frequent invalidation of BVH tree the choice of BVH tree builder is made
+//! in favor of BVH linear builder (quick rebuild).
+class SelectMgr_SelectableObjectTrsfPersSet : public BVH_Set<Standard_Real, 3>
+{
+private:
+
+  typedef NCollection_Handle<Select3D_BndBox3d> HBndBox3d;
+
+  Handle(SelectMgr_SelectableObject) EMPTY_OBJ;
+
+public:
+
+  //! Creates new empty objects set and initializes BVH tree
+  //! builder to Linear builder with 1 element per list.
+  Standard_EXPORT SelectMgr_SelectableObjectTrsfPersSet();
+
+  //! Returns size of objects set.
+  Standard_EXPORT virtual Standard_Integer Size() const Standard_OVERRIDE;
+
+  //! Returns bounding box of object with index theIndex.
+  Standard_EXPORT virtual Select3D_BndBox3d Box (const Standard_Integer theIndex) const Standard_OVERRIDE;
+
+  //! Returns center of object with index theIndex in the set along the given axis theAxis.
+  Standard_EXPORT virtual Standard_Real Center (const Standard_Integer theIndex,
+                                                const Standard_Integer theAxis) const Standard_OVERRIDE;
+
+  //! Swaps items with indexes theIndex1 and theIndex2 in the set.
+  Standard_EXPORT virtual void Swap (const Standard_Integer theIndex1,
+                                     const Standard_Integer theIndex2) Standard_OVERRIDE;
+
+  //! Adds new selectable object to the set.
+  //! @return true if structure added, otherwise returns false (structure already in the set).
+  Standard_EXPORT Standard_Boolean Append (const Handle(SelectMgr_SelectableObject)& theObject);
+
+  //! Removes selectable object from set.
+  //! @return true if structure removed, otherwise returns false (structure is not in the set).
+  Standard_EXPORT Standard_Boolean Remove (const Handle(SelectMgr_SelectableObject)& theObject);
+
+  //! Returns object from set by theIndex given.
+  const Handle(SelectMgr_SelectableObject)& GetObjectById (const Standard_Integer theIndex) const
+  {
+    return myObjects.FindKey (theIndex + 1);
+  }
+
+  //! Marks object state as outdated (needs BVH rebuilding).
+  void MarkDirty()
+  {
+    myIsDirty = Standard_True;
+  }
+
+  //! Returns true if this objects set contains theObject given
+  Standard_Boolean Contains (const Handle(SelectMgr_SelectableObject)& theObject) const
+  {
+    return myObjects.Contains (theObject);
+  }
+
+  //! Returns BVH tree for the given world view projection (builds it if necessary).
+  const NCollection_Handle<BVH_Tree<Standard_Real, 3> >& BVH (const Graphic3d_Mat4d& theProjectionMatrix,
+                                                              const Graphic3d_Mat4d& theWorldViewMatrix,
+                                                              const Graphic3d_WorldViewProjState& theWVPState);
+
+private:
+
+  //! Marks internal object state as outdated.
+  Standard_Boolean myIsDirty;
+
+  //! Constructed bottom-level BVH.
+  NCollection_Handle<BVH_Tree<Standard_Real, 3> > myBVH;
+
+  //! Builder for bottom-level BVH.
+  NCollection_Handle<BVH_Builder<Standard_Real, 3> > myBuilder;
+
+  //! Set of transform persistence objects.
+  NCollection_IndexedMap<Handle(SelectMgr_SelectableObject)> myObjects;
+
+  //! Cached set of bounding boxes precomputed for transformation persistent selectable objects.
+  //! Cache exists only during computation of BVH Tree. Bounding boxes are world view projection
+  //! dependent and should by synchronized.
+  NCollection_IndexedMap<HBndBox3d> myObjectBoxes;
+
+  //! State of world view projection used for generation of transformation persistence bounding boxes.
+  Graphic3d_WorldViewProjState myObjectBoxesState;
+};
+
+#endif
index aa1ff3b..a7bb82f 100644 (file)
@@ -106,16 +106,47 @@ 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
 //=======================================================================
index 6c6a7d7..34e514a 100644 (file)
@@ -20,6 +20,7 @@
 
 #include <Graphic3d_Camera.hxx>
 #include <Graphic3d_SequenceOfHClipPlane.hxx>
+#include <Graphic3d_WorldViewProjState.hxx>
 
 #include <SelectMgr_BaseFrustum.hxx>
 #include <SelectMgr_RectangularFrustum.hxx>
@@ -53,8 +54,18 @@ public:
 
   //! Updates camera projection and orientation matrices in all selecting volumes
   Standard_EXPORT void SetCamera (const Graphic3d_Mat4d& theProjection,
-                                  const Graphic3d_Mat4d& theOrientation,
-                                  const Standard_Boolean theIsOrthographic);
+                                  const Graphic3d_Mat4d& theWorldView,
+                                  const Standard_Boolean theIsOrthographic,
+                                  const Graphic3d_WorldViewProjState& theWVPState = Graphic3d_WorldViewProjState());
+
+  //! @return current projection transformation common for all selecting volumes
+  Standard_EXPORT const Graphic3d_Mat4d& ProjectionMatrix() const;
+
+  //! @return current world view transformation common for all selecting volumes
+  Standard_EXPORT const Graphic3d_Mat4d& WorldViewMatrix() const;
+
+  //! @return current camera world view projection transformation state common for all selecting volumes
+  Standard_EXPORT const Graphic3d_WorldViewProjState& WorldViewProjState() const;
 
   //! Updates viewport in all selecting volumes
   Standard_EXPORT void SetViewport (const Standard_Real theX,
index a458fe6..69f479d 100644 (file)
@@ -143,10 +143,8 @@ myCurRank (0),
 myIsLeftChildQueuedFirst (Standard_False),
 myEntityIdx (0)
 {
-  mySelectableObjects = new SelectMgr_SelectableObjectSet();
 }
 
-
 //==================================================
 // Function: Activate
 // Purpose :
@@ -164,7 +162,6 @@ void SelectMgr_ViewerSelector::Activate (const Handle(SelectMgr_Selection)& theS
   myToUpdateTolerance = Standard_True;
 }
 
-
 //==================================================
 // Function: Deactivate
 // Purpose :
@@ -300,8 +297,32 @@ void SelectMgr_ViewerSelector::traverseObject (const Handle(SelectMgr_Selectable
 
   const NCollection_Handle<BVH_Tree<Standard_Real, 3> >& aSensitivesTree = anEntitySet->BVH();
 
-  SelectMgr_SelectingVolumeManager aMgr = theObject->HasTransformation() ?
-    mySelectingVolumeMgr.Transform (theObject->InversedTransformation()) : mySelectingVolumeMgr;
+  gp_Trsf aInversedTrsf;
+
+  if (theObject->HasTransformation() || theObject->TransformPersistence().Flags)
+  {
+    if (!theObject->TransformPersistence().Flags)
+    {
+      aInversedTrsf = theObject->InversedTransformation();
+    }
+    else
+    {
+      const Graphic3d_Mat4d& aProjection = mySelectingVolumeMgr.ProjectionMatrix();
+      const Graphic3d_Mat4d& aWorldView  = mySelectingVolumeMgr.WorldViewMatrix();
+
+      gp_Trsf aTPers;
+      Graphic3d_Mat4d aMat = theObject->TransformPersistence().Compute (aProjection, aWorldView, 0, 0);
+      aTPers.SetValues (aMat.GetValue (0, 0), aMat.GetValue (0, 1), aMat.GetValue (0, 2), aMat.GetValue (0, 3),
+                        aMat.GetValue (1, 0), aMat.GetValue (1, 1), aMat.GetValue (1, 2), aMat.GetValue (1, 3),
+                        aMat.GetValue (2, 0), aMat.GetValue (2, 1), aMat.GetValue (2, 2), aMat.GetValue (2, 3));
+
+      aInversedTrsf = (aTPers * theObject->Transformation()).Inverted();
+    }
+  }
+
+  SelectMgr_SelectingVolumeManager aMgr = aInversedTrsf.Form() != gp_Identity
+                                        ? mySelectingVolumeMgr.Transform (aInversedTrsf)
+                                        : mySelectingVolumeMgr;
 
   NCollection_DataMap<Handle(Standard_Type), SelectMgr_SelectingVolumeManager> aScaledTrnsfFrustums;
 
@@ -363,7 +384,7 @@ void SelectMgr_ViewerSelector::traverseObject (const Handle(SelectMgr_Selectable
             if (!aScaledTrnsfFrustums.IsBound (anEnt->DynamicType()))
             {
               aScaledTrnsfFrustums.Bind (anEnt->DynamicType(),
-                                         scaleAndTransform (sensitivity (anEnt), theObject->InversedTransformation()));
+                                         scaleAndTransform (sensitivity (anEnt), aInversedTrsf));
             }
 
             aTmpMgr = aScaledTrnsfFrustums.Find (anEnt->DynamicType());
@@ -392,45 +413,86 @@ void SelectMgr_ViewerSelector::TraverseSensitives()
   mystored.Clear();
   myMapOfDetected.Clear();
 
-  if (mySelectableObjects->Size() == 0)
-    return;
-
-  const NCollection_Handle<BVH_Tree<Standard_Real, 3> >& anObjectsTree = mySelectableObjects->BVH();
-
-  Standard_Integer aNode = 0;
-  if (!mySelectingVolumeMgr.Overlaps (anObjectsTree->MinPoint (0),
-                                      anObjectsTree->MaxPoint (0)))
-  {
-    return;
-  }
-  Standard_Integer aStack[32];
-  Standard_Integer aHead = -1;
-  for (;;)
+  NCollection_Handle<BVH_Tree<Standard_Real, 3> > 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<SelectMgr_SensitiveEntitySet> anEntitySet = new SelectMgr_SensitiveEntitySet();
     myMapOfObjectSensitives.Bind (theObject, anEntitySet);
   }
@@ -746,8 +801,11 @@ void SelectMgr_ViewerSelector::RemoveSelectableObject (const Handle(SelectMgr_Se
 {
   if (myMapOfObjectSensitives.IsBound (theObject))
   {
+    if (!mySelectableObjects.Remove (theObject))
+    {
+      mySelectableObjectsTrsfPers.Remove (theObject);
+    }
     myMapOfObjectSensitives.UnBind (theObject);
-    mySelectableObjects->Remove (theObject);
   }
 }
 
@@ -773,11 +831,17 @@ void SelectMgr_ViewerSelector::RemoveSelectionOfObject (const Handle(SelectMgr_S
 //=======================================================================
 void SelectMgr_ViewerSelector::RebuildObjectsTree (const Standard_Boolean theIsForce)
 {
-  mySelectableObjects->MarkDirty();
+  mySelectableObjects.MarkDirty();
+  mySelectableObjectsTrsfPers.MarkDirty();
 
   if (theIsForce)
   {
-    mySelectableObjects->BVH();
+    const Graphic3d_Mat4d& aProjection            = mySelectingVolumeMgr.ProjectionMatrix();
+    const Graphic3d_Mat4d& aWorldView             = mySelectingVolumeMgr.WorldViewMatrix();
+    const Graphic3d_WorldViewProjState& aWVPState = mySelectingVolumeMgr.WorldViewProjState();
+
+    mySelectableObjects.BVH();
+    mySelectableObjectsTrsfPers.BVH (aProjection, aWorldView, aWVPState);
   }
 }
 
@@ -789,7 +853,7 @@ void SelectMgr_ViewerSelector::RebuildObjectsTree (const Standard_Boolean theIsF
 void SelectMgr_ViewerSelector::RebuildSensitivesTree (const Handle(SelectMgr_SelectableObject)& theObject,
                                                       const Standard_Boolean theIsForce)
 {
-  if (!mySelectableObjects->Contains (theObject))
+  if (!Contains (theObject))
     return;
 
   NCollection_Handle<SelectMgr_SensitiveEntitySet>& anEntitySet = myMapOfObjectSensitives.ChangeFind (theObject);
index 6de073c..5d51237 100644 (file)
@@ -36,6 +36,7 @@
 #include <SelectMgr_Selection.hxx>
 #include <SelectMgr_SelectableObject.hxx>
 #include <SelectMgr_SelectableObjectSet.hxx>
+#include <SelectMgr_SelectableObjectTrsfPersSet.hxx>
 #include <SelectMgr_StateOfSelection.hxx>
 #include <Standard_OStream.hxx>
 
@@ -63,7 +64,7 @@ class SelectMgr_ToleranceMap
 public:
 
   //! Sets tolerance values to -1.0
-  SelectMgr_ToleranceMap();
+  Standard_EXPORT SelectMgr_ToleranceMap();
 
   Standard_EXPORT ~SelectMgr_ToleranceMap();
 
@@ -232,21 +233,21 @@ public:
                                               const Standard_Boolean theIsForce = Standard_False);
 
   //! Initializes internal iterator for stored detected sensitive entities
-  Standard_EXPORT void InitDetected();
+  void InitDetected();
 
   //! Makes a step along the map of detected sensitive entities and their owners
-  Standard_EXPORT void NextDetected();
+  void NextDetected();
 
   //! Returns true if iterator of map of detected sensitive entities has reached
   //! its end
-  Standard_EXPORT Standard_Boolean MoreDetected();
+  Standard_Boolean MoreDetected();
 
   //! Returns sensitive entity that was detected during the previous run of
   //! selection algorithm
   Standard_EXPORT const Handle(SelectBasics_SensitiveEntity)& DetectedEntity() const;
 
   //! Returns instance of selecting volume manager of the viewer selector
-  Standard_EXPORT SelectMgr_SelectingVolumeManager& GetManager();
+  SelectMgr_SelectingVolumeManager& GetManager();
 
   //! Marks all added sensitive entities of all objects as non-selectable
   Standard_EXPORT void ResetSelectionActivationStatus();
@@ -309,12 +310,13 @@ private:
 
 protected:
 
-  Standard_Boolean preferclosest;
-  Standard_Boolean myToUpdateTolerance;
-  SelectMgr_IndexedDataMapOfOwnerCriterion mystored;
-  SelectMgr_SelectingVolumeManager mySelectingVolumeMgr;
-  mutable NCollection_Handle<SelectMgr_SelectableObjectSet> mySelectableObjects;
-  SelectMgr_ToleranceMap myTolerances;
+  Standard_Boolean                              preferclosest;
+  Standard_Boolean                              myToUpdateTolerance;
+  SelectMgr_IndexedDataMapOfOwnerCriterion      mystored;
+  SelectMgr_SelectingVolumeManager              mySelectingVolumeMgr;
+  mutable SelectMgr_SelectableObjectSet         mySelectableObjects;
+  mutable SelectMgr_SelectableObjectTrsfPersSet mySelectableObjectsTrsfPers;
+  SelectMgr_ToleranceMap                        myTolerances;
 
 private:
 
index 28cae1a..ba52120 100644 (file)
@@ -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));
   }
 }
 
index dfd4cd5..41e4c03 100644 (file)
@@ -21,6 +21,7 @@
 #include <Standard_Type.hxx>
 #include <Standard_Type.hxx>
 
+#include <Graphic3d_SequenceOfStructure.hxx>
 #include <Graphic3d_SequenceOfHClipPlane.hxx>
 #include <SelectMgr_ViewerSelector.hxx>
 #include <SelectMgr_Selection.hxx>
@@ -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;
 };
 
index aac3b95..1607d0c 100644 (file)
@@ -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;
     }
index 1f6a8d4..f2f4a56 100644 (file)
@@ -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 (file)
index 0000000..8a2f589
--- /dev/null
@@ -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