]> OCCT Git - occt-copy.git/commitdiff
0026344: Visualization - provide a support of zoom persistent selection CR0-ipdm_CR26344
authorapl <apl@opencascade.com>
Mon, 27 Jul 2015 15:01:34 +0000 (18:01 +0300)
committerapl <apl@opencascade.com>
Mon, 27 Jul 2015 15:01:34 +0000 (18:01 +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.

61 files changed:
src/Graphic3d/FILES
src/Graphic3d/Graphic3d.cdl
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.cdl
src/Graphic3d/Graphic3d_Structure.cxx
src/Graphic3d/Graphic3d_Structure.lxx
src/Graphic3d/Graphic3d_TransformPers.hxx [new file with mode: 0644]
src/Graphic3d/Graphic3d_TransformUtils.hxx [new file with mode: 0644]
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_Utils.hxx [deleted file]
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.cdl
src/PrsMgr/PrsMgr_PresentableObject.cxx
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 14f6e9624cacedf521315ec15e8d1870aa59af9d..a1151c28c1bee488da6e4f5f910c4a81d24837b9 100755 (executable)
@@ -40,7 +40,6 @@ Graphic3d.edl
 Graphic3d_CMPLRS.edl
 Graphic3d_WOKSteps.edl
 Graphic3d_TransModeFlags.hxx
-Graphic3d_CTransPersStruct.hxx
 Graphic3d_NListOfHAsciiString.hxx
 Graphic3d_AspectText3d.cxx
 Graphic3d_PtrFrameBuffer.hxx
@@ -65,3 +64,6 @@ Graphic3d_Camera.cxx
 Graphic3d_Camera.hxx
 Graphic3d_RenderingParams.hxx
 Graphic3d_NMapOfTransient.hxx
+Graphic3d_TransformPers.hxx
+Graphic3d_TransformUtils.hxx
+Graphic3d_WorldViewProjState.hxx
index 7ed61e290ba56bb0a326f0b2e69d11f205e749ce..9765832017a52e4122fc672f84d42aaa33a5830f 100644 (file)
@@ -406,12 +406,11 @@ is
     imported transient class ClipPlane;
     ---Category: Imported types
 
-
     imported CTexture;
 
-    imported CTransPersStruct;
     imported TransModeFlags;
-    
+    imported TransformPers;
+
     imported transient class MarkerImage;
     imported transient class Camera;
 
index 36343c0c66e4fc0407e42ab456a362ba6fb69162..25aafd937c0ab874b38cd3855a962b7f251e8016 100644 (file)
@@ -59,10 +59,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 a16b45c9d473ad51f9915189909ed82636cbe973..b85b620a22abf27f5abee1b7fb45645e0ea2618d 100644 (file)
@@ -22,6 +22,7 @@
 #include <Graphic3d_TypeOfComposition.hxx>
 #include <Graphic3d_ViewAffinity.hxx>
 #include <Graphic3d_StructureManager.hxx>
+#include <Graphic3d_TransformPers.hxx>
 #include <Graphic3d_Vec3.hxx>
 #include <Graphic3d_ZLayerId.hxx>
 #include <Standard_Transient.hxx>
@@ -147,7 +148,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 8184f2eec75374c6173449ef0da027f1ab101e84..aa6e6f1b56740cfdf44d2e92982bbf59731f7e0d 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>
@@ -63,8 +64,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);
 }
 
 // =======================================================================
@@ -73,6 +75,8 @@ Graphic3d_Camera::Graphic3d_Camera()
 // =======================================================================
 Graphic3d_Camera::Graphic3d_Camera (const Handle(Graphic3d_Camera)& theOther)
 {
+  myWorldViewProjState.Initialize (this);
+
   Copy (theOther);
 }
 
@@ -82,17 +86,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();
 }
@@ -103,11 +108,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();
 }
@@ -811,7 +817,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);
 }
 
 // =======================================================================
@@ -822,7 +828,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 56620af801f1128a11d884c48f555909b4a5fc9b..d371e0eb137f9f23d06475658b7f3a8cf32c7bc7 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;
 class Handle(Graphic3d_Camera);
 
 //! Camera class provides object-oriented approach to setting up projection
@@ -437,16 +439,22 @@ 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
@@ -614,8 +622,7 @@ private:
   mutable TransformMatrices<Standard_Real>      myMatricesD;
   mutable TransformMatrices<Standard_ShortReal> myMatricesF;
 
-  mutable Standard_Size myProjectionState;
-  mutable Standard_Size myOrientationState;
+  mutable Graphic3d_WorldViewProjState myWorldViewProjState;
 
 public:
 
index 1710ac2e79c0d7e9f2e1a3c32cfcf6b4dc104475..c433126766ddeca5deb5df80d47433cc86568f59 100644 (file)
@@ -63,6 +63,7 @@ uses
     IndexedMapOfAddress     from Graphic3d,
     StructureManager        from Graphic3d,
     StructureManagerPtr     from Graphic3d,
+    TransformPers           from Graphic3d,
     TypeOfComposition       from Graphic3d,
     TypeOfConnection        from Graphic3d,
     TypeOfPrimitive         from Graphic3d,
@@ -774,6 +775,11 @@ is
        ---Purpose: Get the current point of relative modelling transform persistence
         is static;
 
+   TransformPersistence(me) returns TransformPers from Graphic3d is static;
+   ---Purpose: @return transform persistence of the presentable object.
+   ---C++: inline
+   ---C++: return const&
+
   SetMutable ( me           : mutable;
                theIsMutable : Boolean from Standard )
   is static;
index db64f6646358444f8b4f69bd9dfed1595e19a90c..bb64c12b8b96f7722d9f7e38e53cc8b99032d9ad 100644 (file)
@@ -122,7 +122,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()),
@@ -1707,14 +1707,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();
 }
 
 //=============================================================================
@@ -1723,7 +1719,7 @@ void Graphic3d_Structure::SetTransformPersistence (const Graphic3d_TransModeFlag
 //=============================================================================
 Graphic3d_TransModeFlags Graphic3d_Structure::TransformPersistenceMode() const
 {
-  return myCStructure->TransformPersistence.Flag;
+  return myCStructure->TransformPersistence.Flags;
 }
 
 //=============================================================================
@@ -1733,9 +1729,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 86e906187763d46497762935d460e03f7aab392e..7fd5ec20b06574c271ad0f153d76ffaf27520ff8 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
diff --git a/src/Graphic3d/Graphic3d_TransformUtils.hxx b/src/Graphic3d/Graphic3d_TransformUtils.hxx
new file mode 100644 (file)
index 0000000..f2f4c7c
--- /dev/null
@@ -0,0 +1,452 @@
+// Created on: 2015-06-18
+// 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_TransformUtils_HeaderFile
+#define _Graphic3d_TransformUtils_HeaderFile
+
+#include <Graphic3d_Vec.hxx>
+#include <Standard_math.hxx> // M_PI
+
+//! Helper class that implements transformation matrix functionality.
+namespace Graphic3d_TransformUtils
+{
+  template<class T> struct MatrixType {};
+
+  template<> struct MatrixType<Standard_Real> { typedef Graphic3d_Mat4d Mat4; };
+
+  template<> struct MatrixType<Standard_ShortReal> { typedef Graphic3d_Mat4 Mat4; };
+
+  template<class T> struct VectorType {};
+
+  template<> struct VectorType<Standard_Real> {
+    typedef Graphic3d_Vec2d Vec2;
+    typedef Graphic3d_Vec3d Vec3;
+    typedef Graphic3d_Vec4d Vec4;
+  };
+
+  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);
+
+  //! 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);
+
+  //! Maps object coordinates to window coordinates.
+  template<class T>
+  static Standard_Boolean 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);
+
+  //! Maps window coordinates to object coordinates.
+  template<class T>
+  static Standard_Boolean 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);
+
+  //! Constructs a 4x4 rotation matrix.
+  template<class T>
+  static void ConstructRotate (typename MatrixType<T>::Mat4& theOut,
+                               T                             theA,
+                               T                             theX,
+                               T                             theY,
+                               T                             theZ);
+
+  //! Constructs a 4x4 rotation matrix.
+  template<class T>
+  static void Rotate (typename MatrixType<T>::Mat4& theOut,
+                      T                             theA,
+                      T                             theX,
+                      T                             theY,
+                      T                             theZ);
+
+  //! Constructs a 4x4 scaling matrix.
+  template<class T>
+  static void Scale (typename MatrixType<T>::Mat4& theOut,
+                     T                             theX,
+                     T                             theY,
+                     T                             theZ);
+
+  //! Constructs a 4x4 translation matrix.
+  template<class T>
+  static void Translate (typename MatrixType<T>::Mat4& theOut,
+                         T                             theX,
+                         T                             theY,
+                         T                             theZ);
+}
+
+// =======================================================================
+// function : Rotate
+// purpose  : Constructs a 4x4 rotation matrix
+// =======================================================================
+template<class T>
+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);
+  theOut = theOut * aMat;
+}
+
+// =======================================================================
+// function : Translate
+// purpose  : Constructs a 4x4 translation matrix
+// =======================================================================
+template<class T>
+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 +
+                              theOut.GetValue (0, 2) * theZ +
+                              theOut.GetValue (0, 3);
+
+  theOut.ChangeValue (1, 3) = theOut.GetValue (1, 0) * theX +
+                              theOut.GetValue (1, 1) * theY +
+                              theOut.GetValue (1, 2) * theZ +
+                              theOut.GetValue (1, 3);
+
+  theOut.ChangeValue (2, 3) = theOut.GetValue (2, 0) * theX +
+                              theOut.GetValue (2, 1) * theY +
+                              theOut.GetValue (2, 2) * theZ +
+                              theOut.GetValue (2, 3);
+
+  theOut.ChangeValue (3, 3) = theOut.GetValue (3, 0) * theX +
+                              theOut.GetValue (3, 1) * theY +
+                              theOut.GetValue (3, 2) * theZ +
+                              theOut.GetValue (3, 3);
+}
+
+// =======================================================================
+// function : Scale
+// purpose  : Constructs a 4x4 scaling matrix
+// =======================================================================
+template<class T>
+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;
+  theOut.ChangeValue (2, 0) *= theX;
+  theOut.ChangeValue (3, 0) *= theX;
+
+  theOut.ChangeValue (0, 1) *= theY;
+  theOut.ChangeValue (1, 1) *= theY;
+  theOut.ChangeValue (2, 1) *= theY;
+  theOut.ChangeValue (3, 1) *= theY;
+
+  theOut.ChangeValue (0, 2) *= theZ;
+  theOut.ChangeValue (1, 2) *= theZ;
+  theOut.ChangeValue (2, 2) *= theZ;
+  theOut.ChangeValue (3, 2) *= theZ;
+}
+
+// =======================================================================
+// function : ConstructRotate
+// purpose  : Constructs a 4x4 rotation matrix
+// =======================================================================
+template<class T>
+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));
+
+  const Standard_Boolean isOnlyX = (theX != static_cast<T> (0.0))
+                                && (theY == static_cast<T> (0.0))
+                                && (theZ == static_cast<T> (0.0));
+
+  const Standard_Boolean isOnlyY = (theX == static_cast<T> (0.0))
+                                && (theY != static_cast<T> (0.0))
+                                && (theZ == static_cast<T> (0.0));
+
+  const Standard_Boolean isOnlyZ = (theX == static_cast<T> (0.0))
+                                && (theY == static_cast<T> (0.0))
+                                && (theZ != static_cast<T> (0.0));
+
+  if (isOnlyX) // Rotation only around X.
+  {
+    theOut.SetValue (1, 1, aCos);
+    theOut.SetValue (2, 2, aCos);
+
+    if (theX < static_cast<T> (0.0))
+    {
+      theOut.SetValue (1, 2,  aSin);
+      theOut.SetValue (2, 1, -aSin);
+    }
+    else
+    {
+      theOut.SetValue (1, 2, -aSin);
+      theOut.SetValue (2, 1,  aSin);
+    }
+
+    return;
+  }
+  else if (isOnlyY) // Rotation only around Y.
+  {
+    theOut.SetValue (0, 0, aCos);
+    theOut.SetValue (2, 2, aCos);
+
+    if (theY < static_cast<T> (0.0))
+    {
+      theOut.SetValue (0, 2, -aSin);
+      theOut.SetValue (2, 0,  aSin);
+    }
+    else
+    {
+      theOut.SetValue (0, 2,  aSin);
+      theOut.SetValue (2, 0, -aSin);
+    }
+
+    return;
+  }
+  else if (isOnlyZ) // Rotation only around Z.
+  {
+    theOut.SetValue (0, 0, aCos);
+    theOut.SetValue (1, 1, aCos);
+
+    if (theZ < static_cast<T> (0.0))
+    {
+      theOut.SetValue (0, 1,  aSin);
+      theOut.SetValue (1, 0, -aSin);
+    }
+    else
+    {
+      theOut.SetValue (0, 1, -aSin);
+      theOut.SetValue (1, 0,  aSin);
+    }
+
+    return;
+  }
+
+  T aNorm = std::sqrt (theX * theX + theY * theY + theZ * theZ);
+
+  if (aNorm <= static_cast<T> (1.0e-4))
+  {
+    return; // Negligible rotation.
+  }
+
+  aNorm = static_cast<T> (1.0) / aNorm;
+
+  theX *= aNorm;
+  theY *= aNorm;
+  theZ *= aNorm;
+
+  const T aXX = theX * theX;
+  const T aYY = theY * theY;
+  const T aZZ = theZ * theZ;
+  const T aXY = theX * theY;
+  const T aYZ = theY * theZ;
+  const T aZX = theZ * theX;
+  const T aSinX = theX * aSin;
+  const T aSinY = theY * aSin;
+  const T aSinZ = theZ * aSin;
+
+  const T aOneMinusCos = static_cast<T> (1.0) - aCos;
+
+  theOut.SetValue (0, 0, aOneMinusCos * aXX + aCos);
+  theOut.SetValue (0, 1, aOneMinusCos * aXY - aSinZ);
+  theOut.SetValue (0, 2, aOneMinusCos * aZX + aSinY);
+
+  theOut.SetValue (1, 0, aOneMinusCos * aXY + aSinZ);
+  theOut.SetValue (1, 1, aOneMinusCos * aYY + aCos);
+  theOut.SetValue (1, 2, aOneMinusCos * aYZ - aSinX);
+
+  theOut.SetValue (2, 0, aOneMinusCos * aZX - aSinY);
+  theOut.SetValue (2, 1, aOneMinusCos * aYZ + aSinX);
+  theOut.SetValue (2, 2, aOneMinusCos * aZZ + aCos);
+}
+
+// =======================================================================
+// function : Ortho
+// purpose  : Constructs a 3D orthographic projection matrix
+// =======================================================================
+template<class T>
+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();
+
+  T* aData = theOut.ChangeData();
+
+  const T anInvDx = static_cast<T> (1.0) / (theRight - theLeft);
+  const T anInvDy = static_cast<T> (1.0) / (theTop - theBottom);
+  const T anInvDz = static_cast<T> (1.0) / (theZFar - theZNear);
+
+  aData[0]  = static_cast<T> ( 2.0) * anInvDx;
+  aData[5]  = static_cast<T> ( 2.0) * anInvDy;
+  aData[10] = static_cast<T> (-2.0) * anInvDz;
+
+  aData[12] = -(theRight + theLeft) * anInvDx;
+  aData[13] = -(theTop + theBottom) * anInvDy;
+  aData[14] = -(theZFar + theZNear) * anInvDz;
+}
+
+// =======================================================================
+// function : Ortho2D
+// purpose  : Constructs a 2D orthographic projection matrix
+// =======================================================================
+template<class T>
+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));
+}
+
+// =======================================================================
+// function : Project
+// purpose  : Maps object coordinates to window coordinates
+// =======================================================================
+template<class T>
+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));
+
+  typename VectorType<T>::Vec4 anOut = theProjectMat * (theModViewMat * anIn);
+
+  if (anOut.w() == static_cast<T> (0.0))
+  {
+    return Standard_False;
+  }
+
+  anOut.w() = static_cast<T> (1.0) / anOut.w();
+
+  anOut.x() *= anOut.w();
+  anOut.y() *= anOut.w();
+  anOut.z() *= anOut.w();
+
+  // 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.
+  anOut.x() = anOut.x() * theViewport[2] + theViewport[0];
+  anOut.y() = anOut.y() * theViewport[3] + theViewport[1];
+
+  theWinX = anOut.x();
+  theWinY = anOut.y();
+  theWinZ = anOut.z();
+
+  return Standard_True;
+}
+
+// =======================================================================
+// function : UnProject
+// purpose  : Maps window coordinates to object coordinates
+// =======================================================================
+template<class T>
+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;
+
+  if (!(theProjectMat * theModViewMat).Inverted (anUnviewMat))
+  {
+    return Standard_False;
+  }
+
+  typename VectorType<T>::Vec4 anIn (theWinX, theWinY, theWinZ, static_cast<T> (1.0));
+
+  // 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.
+  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);
+
+  typename VectorType<T>::Vec4 anOut = anUnviewMat * anIn;
+
+  if (anOut.w() == static_cast<T> (0.0))
+  {
+    return Standard_False;
+  }
+
+  anOut.w() = static_cast<T> (1.0) / anOut.w();
+
+  anOut.x() *= anOut.w();
+  anOut.y() *= anOut.w();
+  anOut.z() *= anOut.w();
+
+  theObjX = anOut.x();
+  theObjY = anOut.y();
+  theObjZ = anOut.z();
+
+  return Standard_True;
+}
+
+#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 db4acbf09fd1305d8c9e4138df03f05a82f952f7..0f4c3ddb19a0edd97d08131d3fbea47307069cef 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 de9014dd12631371ce40272209a052e38ac455ba..0d0742eabd90994853a8776a6645a668849af429 100755 (executable)
@@ -70,7 +70,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
@@ -152,11 +151,13 @@ OpenGl_BVHTreeSelector.hxx
 OpenGl_BVHTreeSelector.cxx
 OpenGl_BVHClipPrimitiveSet.cxx
 OpenGl_BVHClipPrimitiveSet.hxx
+OpenGl_BVHClipPrimitiveTrsfPersSet.cxx
+OpenGl_BVHClipPrimitiveTrsfPersSet.hxx
 OpenGl_ArbTexBindless.hxx
 Handle_OpenGl_Sampler.hxx
 OpenGl_Sampler.hxx
 OpenGl_Sampler.cxx
-OpenGl_Utils.hxx
+OpenGl_MatrixState.hxx
 OpenGl_Quadric.hxx
 OpenGl_Quadric.cxx
 OpenGl_Cylinder.hxx
index cda8413d10a877150304f290b55ab32d40989be4..a9eb4c759afae0b1788adc42b42dadbb9ebf77ee 100644 (file)
@@ -41,7 +41,7 @@ Standard_Integer OpenGl_BVHClipPrimitiveSet::Size() const
 // =======================================================================
 Graphic3d_BndBox4f OpenGl_BVHClipPrimitiveSet::Box (const Standard_Integer theIdx) const
 {
-  return myStructs (theIdx + 1)->BoundingBox();
+  return myStructs.FindKey (theIdx + 1)->BoundingBox();
 }
 
 // =======================================================================
@@ -51,12 +51,10 @@ Graphic3d_BndBox4f OpenGl_BVHClipPrimitiveSet::Box (const Standard_Integer theId
 Standard_ShortReal OpenGl_BVHClipPrimitiveSet::Center (const Standard_Integer theIdx,
                                                        const Standard_Integer theAxis) const
 {
-  Graphic3d_BndBox4f aBndBox = myStructs (theIdx + 1)->BoundingBox();
-  Standard_ShortReal aCenter =  theAxis == 0 ? (aBndBox.CornerMin().x() + aBndBox.CornerMax().x()) * 0.5f
-                             : (theAxis == 1 ? (aBndBox.CornerMin().y() + aBndBox.CornerMax().y()) * 0.5f
-                             : (theAxis == 2 ? (aBndBox.CornerMin().z() + aBndBox.CornerMax().z()) * 0.5f
-                             : (aBndBox.CornerMin().w() + aBndBox.CornerMax().w()) * 0.5f));
-  return aCenter;
+  Graphic3d_BndBox4f aBndBox = myStructs.FindKey (theIdx + 1)->BoundingBox();
+
+  return (aBndBox.CornerMin()[theAxis] +
+          aBndBox.CornerMax()[theAxis]) * 0.5f;
 }
 
 // =======================================================================
@@ -68,57 +66,47 @@ void OpenGl_BVHClipPrimitiveSet::Swap (const Standard_Integer theIdx1,
 {
   const OpenGl_Structure* aStruct1 = myStructs (theIdx1 + 1);
   const OpenGl_Structure* aStruct2 = myStructs (theIdx2 + 1);
-  myStructs.ChangeValue (theIdx1 + 1) = aStruct2;
-  myStructs.ChangeValue (theIdx2 + 1) = aStruct1;
+  myStructs.Substitute (theIdx2 + 1, NULL);
+  myStructs.Substitute (theIdx1 + 1, aStruct2);
+  myStructs.Substitute (theIdx2 + 1, aStruct1);
 }
 
 // =======================================================================
-// function : Assign
+// function : Add
 // purpose  :
 // =======================================================================
-void OpenGl_BVHClipPrimitiveSet::Assign (const OpenGl_ArrayOfStructure& theStructs)
+Standard_Boolean OpenGl_BVHClipPrimitiveSet::Add (const OpenGl_Structure* theStruct)
 {
-  myStructs.Clear();
+  const Standard_Integer aSize = myStructs.Size();
 
-  const Standard_Integer aNbPriorities = theStructs.Length();
-  for (Standard_Integer aPriorityIdx = 0; aPriorityIdx < aNbPriorities; ++aPriorityIdx)
+  if (myStructs.Add (theStruct) > aSize) // new structure?
   {
-    for (OpenGl_SequenceOfStructure::Iterator aStructIter (theStructs (aPriorityIdx)); aStructIter.More(); aStructIter.Next())
-    {
-      const OpenGl_Structure* aStruct = aStructIter.Value();
-      if (!aStruct->IsAlwaysRendered())
-        myStructs.Append (aStruct);
-    }
-  }
+    MarkDirty();
 
-  MarkDirty();
-}
+    return Standard_True;
+  }
 
-// =======================================================================
-// function : Add
-// purpose  :
-// =======================================================================
-void OpenGl_BVHClipPrimitiveSet::Add (const OpenGl_Structure* theStruct)
-{
-  myStructs.Append (theStruct);
-  MarkDirty();
+  return Standard_False;
 }
 
 // =======================================================================
 // function : Remove
 // purpose  :
 // =======================================================================
-void OpenGl_BVHClipPrimitiveSet::Remove (const OpenGl_Structure* theStruct)
+Standard_Boolean OpenGl_BVHClipPrimitiveSet::Remove (const OpenGl_Structure* theStruct)
 {
-  for (Standard_Integer anIdx = 1; anIdx <= myStructs.Size(); ++anIdx)
+  const Standard_Integer anIndex = myStructs.FindIndex (theStruct);
+
+  if (anIndex != 0)
   {
-    if (myStructs (anIdx) == theStruct)
-    {
-      myStructs.Remove (anIdx);
-      MarkDirty();
-      break;
-    }
+    Swap (anIndex - 1, Size() - 1);
+    myStructs.RemoveLast();
+    MarkDirty();
+
+    return Standard_True;
   }
+
+  return Standard_False;
 }
 
 // =======================================================================
@@ -137,5 +125,5 @@ void OpenGl_BVHClipPrimitiveSet::Clear()
 // =======================================================================
 const OpenGl_Structure* OpenGl_BVHClipPrimitiveSet::GetStructureById (Standard_Integer theId)
 {
-  return myStructs (theId + 1);
+  return myStructs.FindKey (theId + 1);
 }
index bf3b607f4e89bdc52343e1492764ff10cf374d0b..a525ca7ddcc298ecaf8eb88d62e0101f80b87bd7 100644 (file)
 #define _OpenGl_BVHClipPrimitiveSet_HeaderFile
 
 #include <BVH_PrimitiveSet.hxx>
-#include <NCollection_Array1.hxx>
+#include <NCollection_IndexedMap.hxx>
 
 #include <OpenGl_Vec.hxx>
 #include <OpenGl_Structure.hxx>
 #include <OpenGl_SequenceOfStructure.hxx>
 
-typedef NCollection_Array1<OpenGl_SequenceOfStructure> OpenGl_ArrayOfStructure;
-
 //! Set of OpenGl_Structures for building BVH tree.
 class OpenGl_BVHClipPrimitiveSet : public BVH_PrimitiveSet<Standard_ShortReal, 4>
 {
@@ -51,15 +49,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_ArrayOfStructure& theStructs);
-
   //! Adds structure theStruct 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 OpenGl_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();
@@ -69,7 +65,7 @@ public:
 
 private:
 
-  NCollection_Sequence<const OpenGl_Structure*> myStructs;    //!< Sequence of structures
+  NCollection_IndexedMap<const OpenGl_Structure*> myStructs;    //!< Sequence of structures
 
 };
 
diff --git a/src/OpenGl/OpenGl_BVHClipPrimitiveTrsfPersSet.cxx b/src/OpenGl/OpenGl_BVHClipPrimitiveTrsfPersSet.cxx
new file mode 100644 (file)
index 0000000..07106c0
--- /dev/null
@@ -0,0 +1,179 @@
+// 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;
+
+  const OpenGl_Structure* aStruct1 = myStructs.FindKey (aStructIdx1);
+  const OpenGl_Structure* aStruct2 = myStructs.FindKey (aStructIdx2);
+  myStructs.Substitute (aStructIdx2, NULL);
+  myStructs.Substitute (aStructIdx1, aStruct2);
+  myStructs.Substitute (aStructIdx2, aStruct1);
+
+  const HBndBox4f aBox1 = myStructBoxes.FindKey (aStructIdx1);
+  const HBndBox4f aBox2 = myStructBoxes.FindKey (aStructIdx2);
+  myStructBoxes.Substitute (aStructIdx2, EMPTY_BOX);
+  myStructBoxes.Substitute (aStructIdx1, aBox2);
+  myStructBoxes.Substitute (aStructIdx2, aBox1);
+}
+
+// =======================================================================
+// 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)
+  {
+    Swap (anIndex - 1, Size() - 1);
+    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..56dc317
--- /dev/null
@@ -0,0 +1,108 @@
+// 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;
+
+  HBndBox4f EMPTY_BOX;
+
+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 cac526d8117640873c67ed084aca4431e33fcaa9..07f591763627a5567296afc93c86912524e606e7 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;
@@ -46,32 +51,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;
   }
 
@@ -80,18 +85,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 96183ce4cae8c1038db7a605fb1600648511c0d3..c111c21233cd2cafda19db44867eda753cefe48d 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 47caab9b13d95fc57f7662e6f6b51f49d8ba17a2..45112072903d05aedb55209aeb750a838e8aa7ac 100644 (file)
@@ -31,6 +31,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>
@@ -38,7 +39,6 @@
 #include <TColStd_PackedMapOfInteger.hxx>
 #include <OpenGl_Clipping.hxx>
 #include <OpenGl_GlCore11.hxx>
-#include <OpenGl_Utils.hxx>
 
 //! Forward declarations
 #if defined(__APPLE__)
@@ -681,9 +681,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 5f5523ca1cfa6ca1b11c1d7183f98ae66a0da07d..ecfcef3b3f3b8bea76f41c562236398add8afa0f 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_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>
@@ -129,23 +129,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;
@@ -329,7 +329,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);
@@ -369,14 +369,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);
@@ -402,56 +402,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();
@@ -490,16 +491,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 5ab137cd56c4c815dbffbff77a9ccc045d2014a7..4c817d3980df46d39afa6952e095da49625d40f0 100644 (file)
@@ -21,7 +21,7 @@
 #include <OpenGl_Workspace.hxx>
 
 // =======================================================================
-// function : OpenGl_PriorityList
+// function : OpenGl_Layer
 // purpose  :
 // =======================================================================
 OpenGl_Layer::OpenGl_Layer (const Standard_Integer theNbPriorities)
@@ -63,7 +63,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;
 }
@@ -94,7 +101,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;
@@ -152,8 +162,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_SequenceOfStructure::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();
@@ -190,64 +220,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)
       {
-        aNode = isLeftChildIn ? aLeftChildIdx : aRightChildIdx;
+        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))
+      {
+        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 cc1697ee0d56a63956fa4a943fdbf2d6b3784b1a..b2ed370b0d69ad504936903b4f2b34207e7508cd 100644 (file)
 
 #include <Handle_OpenGl_Workspace.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>
 
 class Handle(OpenGl_Workspace);
@@ -36,6 +38,8 @@ struct OpenGl_GlobalLayerSettings
   GLboolean DepthMask;
 };
 
+typedef NCollection_Array1<OpenGl_SequenceOfStructure> OpenGl_ArrayOfStructure;
+
 //! Presentations list sorted within priorities.
 class OpenGl_Layer
 {
@@ -105,12 +109,25 @@ protected:
 
 private:
 
-  OpenGl_ArrayOfStructure            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
+  OpenGl_ArrayOfStructure myArray;
+
+  //! 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 df77dfcfac99edfa02cba40789c0adf5950f77f2..faa5cb73677afc6310ac9bf64965b5ba2fafabaf 100644 (file)
@@ -120,7 +120,6 @@ public:
 OpenGl_Structure::OpenGl_Structure (const Handle(Graphic3d_StructureManager)& theManager)
 : Graphic3d_CStructure (theManager),
   myTransformation     (NULL),
-  myTransPers          (NULL),
   myAspectLine         (NULL),
   myAspectFace         (NULL),
   myAspectMarker       (NULL),
@@ -143,7 +142,6 @@ OpenGl_Structure::~OpenGl_Structure()
 {
   Release (Handle(OpenGl_Context)());
   delete myTransformation;  myTransformation  = NULL;
-  delete myTransPers;       myTransPers       = NULL;
 }
 
 // =======================================================================
@@ -152,8 +150,6 @@ OpenGl_Structure::~OpenGl_Structure()
 // =======================================================================
 void OpenGl_Structure::UpdateAspects()
 {
-  SetTransformPersistence (TransformPersistence);
-
   if (ContextLine.IsDef)
     SetAspectLine (ContextLine);
 
@@ -196,22 +192,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  :
@@ -560,32 +540,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);
@@ -694,12 +682,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;
@@ -710,12 +708,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 ac9619549b2b0bc45a1f9328197540d75cec00e6..23d79c0552573ba5f769925b2638ab8b5e955e0b 100644 (file)
@@ -114,8 +114,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);
@@ -164,7 +162,7 @@ public:
         || IsForHighlight
         || IsMutable
         || Is2dText
-        || TransformPersistence.Flag != 0;
+        || TransformPersistence.Flags != 0;
   }
 
   //! This method releases GL resources without actual elements destruction.
@@ -183,9 +181,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; }
@@ -206,7 +201,6 @@ protected:
 protected:
 
   OpenGl_Matrix*             myTransformation;
-  TEL_TRANSFORM_PERSISTENCE* myTransPers;
   OpenGl_AspectLine*         myAspectLine;
   OpenGl_AspectFace*         myAspectFace;
   OpenGl_AspectMarker*       myAspectMarker;
index 9cfe62b99fff91d59ca4b328f35eb51a25cd0983..b6765fa5b8e3a8dd2f770bb0e37de908cf293fc5 100644 (file)
@@ -42,7 +42,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 93ceede87e11b6c71d64c1c000924b4b9bf3b155..6982e49cdfc2d0560167c916ec5fe2b5b91967f3 100644 (file)
@@ -13,6 +13,8 @@
 // Alternatively, this file may be used under the terms of Open CASCADE
 // commercial license or contractual agreement.
 
+#include <Graphic3d_TransformUtils.hxx>
+
 #include <OpenGl_AspectText.hxx>
 #include <OpenGl_GlCore11.hxx>
 #include <OpenGl_GraphicDriver.hxx>
@@ -20,7 +22,6 @@
 #include <OpenGl_ShaderProgram.hxx>
 #include <OpenGl_ShaderStates.hxx>
 #include <OpenGl_Text.hxx>
-#include <OpenGl_Utils.hxx>
 #include <OpenGl_Workspace.hxx>
 #include <OpenGl_View.hxx>
 
@@ -484,24 +485,24 @@ 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 (aProjectMat),
-                                            myViewport,
-                                            anObjX,
-                                            anObjY,
-                                            anObjZ);
+    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 (aProjectMat),
+                                                        myViewport,
+                                                        anObjX,
+                                                        anObjY,
+                                                        anObjZ);
 
     if (myHasPlane)
     {
@@ -516,8 +517,8 @@ void OpenGl_Text::setupMatrix (const Handle(OpenGl_PrinterContext)& thePrintCtx,
     }
     else
     {
-      OpenGl_Utils::Translate<GLdouble> (aModViewMat, anObjX, anObjY, anObjZ);
-      OpenGl_Utils::Rotate<GLdouble>    (aModViewMat, theTextAspect.Angle(), 0.0, 0.0, 1.0);
+      Graphic3d_TransformUtils::Translate<GLdouble> (aModViewMat, anObjX, anObjY, anObjZ);
+      Graphic3d_TransformUtils::Rotate<GLdouble>    (aModViewMat, theTextAspect.Angle(), 0.0, 0.0, 1.0);
     }
 
     if (!theTextAspect.IsZoomable())
@@ -533,10 +534,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);
     }
   }
 
@@ -751,39 +752,39 @@ void OpenGl_Text::render (const Handle(OpenGl_PrinterContext)& thePrintCtx,
   {
     glGetIntegerv (GL_VIEWPORT,          myViewport);
 
-    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 eb19352bee89c049d21fa59e06ea40178ec9b417..5b5af494fb6f4a5ce1402c5bed16688375403e1f 100644 (file)
@@ -19,6 +19,7 @@
 
 #include <Graphic3d_ArrayOfSegments.hxx>
 #include <Graphic3d_ArrayOfPolylines.hxx>
+#include <Graphic3d_TransformUtils.hxx>
 #include <OpenGl_View.hxx>
 #include <OpenGl_Workspace.hxx>
 #include <Precision.hxx>
@@ -86,25 +87,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;
     }
@@ -231,7 +232,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);
@@ -239,7 +240,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();
 
@@ -249,7 +250,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);
@@ -257,7 +258,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();
 
@@ -267,7 +268,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);
@@ -411,7 +412,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);
@@ -419,11 +420,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);
@@ -431,11 +432,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);
@@ -644,7 +645,7 @@ void OpenGl_Trihedron::Render (const Handle(OpenGl_Workspace)& theWorkspace) con
   }
 
   const Handle(OpenGl_Texture) aPrevTexture = theWorkspace->DisableTexture();
-  theWorkspace->ActiveView()->EndTransformPersistence (theWorkspace->GetGlContext());
+
   theWorkspace->GetGlContext()->ApplyModelViewMatrix();
 
   if (myIsWireframe)
diff --git a/src/OpenGl/OpenGl_Utils.hxx b/src/OpenGl/OpenGl_Utils.hxx
deleted file mode 100644 (file)
index 39702c1..0000000
+++ /dev/null
@@ -1,518 +0,0 @@
-// 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_Utils_H__
-#define _OpenGl_Utils_H__
-
-#include <OpenGl_Vec.hxx>
-#include <NCollection_Vector.hxx>
-
-//! Helper class that implements some functionality of GLU library.
-namespace OpenGl_Utils
-{
-
-  //! Matrix type selector.
-  template<class T>
-  struct MatrixType {
-    //
-  };
-
-  template<>
-  struct MatrixType<Standard_Real> {
-    typedef OpenGl_Mat4d Mat4;
-  };
-
-  template<>
-  struct MatrixType<Standard_ShortReal> {
-    typedef OpenGl_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<>
-  struct VectorType<Standard_ShortReal> {
-    typedef OpenGl_Vec2 Vec2;
-    typedef OpenGl_Vec3 Vec3;
-    typedef OpenGl_Vec4 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
-
-  };
-
-  //! 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);
-
-  //! 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);
-
-  //! Maps object coordinates to window coordinates.
-  template<class T>
-  static Standard_Boolean 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);
-
-  //! Maps window coordinates to object coordinates.
-  template<class T>
-  static Standard_Boolean 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);
-
-  //! Constructs a 4x4 rotation matrix.
-  template<class T>
-  static void ConstructRotate (typename MatrixType<T>::Mat4& theOut,
-                               T                             theA,
-                               T                             theX,
-                               T                             theY,
-                               T                             theZ);
-
-  //! Constructs a 4x4 rotation matrix.
-  template<class T>
-  static void Rotate (typename MatrixType<T>::Mat4& theOut,
-                      T                             theA,
-                      T                             theX,
-                      T                             theY,
-                      T                             theZ);
-
-  //! Constructs a 4x4 scaling matrix.
-  template<class T>
-  static void Scale (typename MatrixType<T>::Mat4& theOut,
-                     T                             theX,
-                     T                             theY,
-                     T                             theZ);
-
-  //! Constructs a 4x4 translation matrix.
-  template<class T>
-  static void Translate (typename MatrixType<T>::Mat4& theOut,
-                         T                             theX,
-                         T                             theY,
-                         T                             theZ);
-
-}
-
-// =======================================================================
-// function : Rotate
-// 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)
-{
-  typename MatrixType<T>::Mat4 aMat;
-  ConstructRotate (aMat, theA, theX, theY, theZ);
-  theOut = theOut * aMat;
-}
-
-// =======================================================================
-// function : Translate
-// purpose  : Constructs a 4x4 translation matrix
-// =======================================================================
-template<class T>
-void OpenGl_Utils::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 +
-                              theOut.GetValue (0, 2) * theZ +
-                              theOut.GetValue (0, 3);
-
-  theOut.ChangeValue (1, 3) = theOut.GetValue (1, 0) * theX +
-                              theOut.GetValue (1, 1) * theY +
-                              theOut.GetValue (1, 2) * theZ +
-                              theOut.GetValue (1, 3);
-
-  theOut.ChangeValue (2, 3) = theOut.GetValue (2, 0) * theX +
-                              theOut.GetValue (2, 1) * theY +
-                              theOut.GetValue (2, 2) * theZ +
-                              theOut.GetValue (2, 3);
-
-  theOut.ChangeValue (3, 3) = theOut.GetValue (3, 0) * theX +
-                              theOut.GetValue (3, 1) * theY +
-                              theOut.GetValue (3, 2) * theZ +
-                              theOut.GetValue (3, 3);
-}
-
-// =======================================================================
-// function : Scale
-// purpose  : Constructs a 4x4 scaling matrix
-// =======================================================================
-template<class T>
-void OpenGl_Utils::Scale (typename MatrixType<T>::Mat4& theOut,
-                          T                             theX,
-                          T                             theY,
-                          T                             theZ)
-{
-  theOut.ChangeValue (0, 0) *= theX;
-  theOut.ChangeValue (1, 0) *= theX;
-  theOut.ChangeValue (2, 0) *= theX;
-  theOut.ChangeValue (3, 0) *= theX;
-
-  theOut.ChangeValue (0, 1) *= theY;
-  theOut.ChangeValue (1, 1) *= theY;
-  theOut.ChangeValue (2, 1) *= theY;
-  theOut.ChangeValue (3, 1) *= theY;
-
-  theOut.ChangeValue (0, 2) *= theZ;
-  theOut.ChangeValue (1, 2) *= theZ;
-  theOut.ChangeValue (2, 2) *= theZ;
-  theOut.ChangeValue (3, 2) *= theZ;
-}
-
-// =======================================================================
-// function : ConstructRotate
-// 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)
-{
-  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));
-
-  const Standard_Boolean isOnlyX = (theX != static_cast<T> (0.0))
-                                && (theY == static_cast<T> (0.0))
-                                && (theZ == static_cast<T> (0.0));
-
-  const Standard_Boolean isOnlyY = (theX == static_cast<T> (0.0))
-                                && (theY != static_cast<T> (0.0))
-                                && (theZ == static_cast<T> (0.0));
-
-  const Standard_Boolean isOnlyZ = (theX == static_cast<T> (0.0))
-                                && (theY == static_cast<T> (0.0))
-                                && (theZ != static_cast<T> (0.0));
-
-  if (isOnlyX) // Rotation only around X
-  {
-    theOut.SetValue (1, 1, aCos);
-    theOut.SetValue (2, 2, aCos);
-
-    if (theX < static_cast<T> (0.0))
-    {
-      theOut.SetValue (1, 2,  aSin);
-      theOut.SetValue (2, 1, -aSin);
-    }
-    else
-    {
-      theOut.SetValue (1, 2, -aSin);
-      theOut.SetValue (2, 1,  aSin);
-    }
-
-    return;
-  }
-  else if (isOnlyY) // Rotation only around Y
-  {
-    theOut.SetValue (0, 0, aCos);
-    theOut.SetValue (2, 2, aCos);
-
-    if (theY < static_cast<T> (0.0))
-    {
-      theOut.SetValue (0, 2, -aSin);
-      theOut.SetValue (2, 0,  aSin);
-    }
-    else
-    {
-      theOut.SetValue (0, 2,  aSin);
-      theOut.SetValue (2, 0, -aSin);
-    }
-
-    return;
-  }
-  else if (isOnlyZ) // Rotation only around Z
-  {
-    theOut.SetValue (0, 0, aCos);
-    theOut.SetValue (1, 1, aCos);
-
-    if (theZ < static_cast<T> (0.0))
-    {
-      theOut.SetValue (0, 1,  aSin);
-      theOut.SetValue (1, 0, -aSin);
-    }
-    else
-    {
-      theOut.SetValue (0, 1, -aSin);
-      theOut.SetValue (1, 0,  aSin);
-    }
-
-    return;
-  }
-
-  T aNorm = std::sqrt (theX * theX + theY * theY + theZ * theZ);
-
-  if (aNorm <= static_cast<T> (1.0e-4))
-  {
-    return; // negligible rotation
-  }
-
-  aNorm = static_cast<T> (1.0) / aNorm;
-
-  theX *= aNorm;
-  theY *= aNorm;
-  theZ *= aNorm;
-
-  const T aXX = theX * theX;
-  const T aYY = theY * theY;
-  const T aZZ = theZ * theZ;
-  const T aXY = theX * theY;
-  const T aYZ = theY * theZ;
-  const T aZX = theZ * theX;
-  const T aSinX = theX * aSin;
-  const T aSinY = theY * aSin;
-  const T aSinZ = theZ * aSin;
-
-  const T aOneMinusCos = static_cast<T> (1.0) - aCos;
-
-  theOut.SetValue (0, 0, aOneMinusCos * aXX + aCos);
-  theOut.SetValue (0, 1, aOneMinusCos * aXY - aSinZ);
-  theOut.SetValue (0, 2, aOneMinusCos * aZX + aSinY);
-
-  theOut.SetValue (1, 0, aOneMinusCos * aXY + aSinZ);
-  theOut.SetValue (1, 1, aOneMinusCos * aYY + aCos);
-  theOut.SetValue (1, 2, aOneMinusCos * aYZ - aSinX);
-
-  theOut.SetValue (2, 0, aOneMinusCos * aZX - aSinY);
-  theOut.SetValue (2, 1, aOneMinusCos * aYZ + aSinX);
-  theOut.SetValue (2, 2, aOneMinusCos * aZZ + aCos);
-}
-
-// =======================================================================
-// function : Ortho
-// 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)
-{
-  theOut.InitIdentity();
-
-  T* aData = theOut.ChangeData();
-
-  const T anInvDx = static_cast<T> (1.0) / (theRight - theLeft);
-  const T anInvDy = static_cast<T> (1.0) / (theTop - theBottom);
-  const T anInvDz = static_cast<T> (1.0) / (theZFar - theZNear);
-
-  aData[0]  = static_cast<T> ( 2.0) * anInvDx;
-  aData[5]  = static_cast<T> ( 2.0) * anInvDy;
-  aData[10] = static_cast<T> (-2.0) * anInvDz;
-
-  aData[12] = -(theRight + theLeft) * anInvDx;
-  aData[13] = -(theTop + theBottom) * anInvDy;
-  aData[14] = -(theZFar + theZNear) * anInvDz;
-}
-
-// =======================================================================
-// function : Ortho2D
-// 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)
-{
-  Ortho (theOut, theLeft, theRight, theBottom, theTop, static_cast<T> (-1.0), static_cast<T> (1.0));
-}
-
-// =======================================================================
-// function : Project
-// 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)
-{
-  typename VectorType<T>::Vec4 anIn (theObjX, theObjY, theObjZ, static_cast<T> (1.0));
-
-  typename VectorType<T>::Vec4 anOut = theProjectMat * (theModViewMat * anIn);
-
-  if (anOut.w() == static_cast<T> (0.0))
-  {
-    return Standard_False;
-  }
-
-  anOut.w() = static_cast<T> (1.0) / anOut.w();
-
-  anOut.x() *= anOut.w();
-  anOut.y() *= anOut.w();
-  anOut.z() *= anOut.w();
-
-  // 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
-  anOut.x() = anOut.x() * theViewport[2] + theViewport[0];
-  anOut.y() = anOut.y() * theViewport[3] + theViewport[1];
-
-  theWinX = anOut.x();
-  theWinY = anOut.y();
-  theWinZ = anOut.z();
-
-  return Standard_True;
-}
-
-// =======================================================================
-// function : UnProject
-// 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)
-{
-  typename MatrixType<T>::Mat4 anUnviewMat;
-
-  if (!(theProjectMat * theModViewMat).Inverted (anUnviewMat))
-  {
-    return Standard_False;
-  }
-
-  typename VectorType<T>::Vec4 anIn (theWinX, theWinY, theWinZ, static_cast<T> (1.0));
-
-  // 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
-  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);
-
-  typename VectorType<T>::Vec4 anOut = anUnviewMat * anIn;
-
-  if (anOut.w() == static_cast<T> (0.0))
-  {
-    return Standard_False;
-  }
-
-  anOut.w() = static_cast<T> (1.0) / anOut.w();
-
-  anOut.x() *= anOut.w();
-  anOut.y() *= anOut.w();
-  anOut.z() *= anOut.w();
-
-  theObjX = anOut.x();
-  theObjY = anOut.y();
-  theObjZ = anOut.z();
-
-  return Standard_True;
-}
-
-#endif // _OpenGl_Utils_H__
index 34c9250984fb7b152654b8b3c58fc310b48978d6..cb4cf962c44164c05e9e2a5573c973a5bccb472c 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 44926c33d2fef251249d569424126bc6cf4596cf..f4ea2af8e711eb4559bdb169602100bfb279e9d0 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>
@@ -39,14 +37,6 @@ static const Tmatrix3 myDefaultMatrix = { { 1.F, 0.F, 0.F, 0.F }, { 0.F, 1.F, 0.
 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 };
-static const GLdouble THE_IDENTITY_MATRIX[4][4] =
-{
-  {1.0, 0.0, 0.0, 0.0},
-  {0.0, 1.0, 0.0, 0.0},
-  {0.0, 0.0, 1.0, 0.0},
-  {0.0, 0.0, 0.0, 1.0}
-};
 
 /*----------------------------------------------------------------------*/
 
@@ -67,10 +57,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()),
@@ -257,246 +244,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 2a16e41593c0ce549f75ca662db837b72d39ae3d..592e7300f28676f84bf473d3981e6ee6b7497b73 100644 (file)
@@ -34,6 +34,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>
@@ -119,12 +120,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
@@ -270,12 +265,8 @@ protected:
   OpenGl_LayerList           myZLayers;       //!< main list of displayed structure, sorted by layers
   OpenGl_SequenceOfStructure 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 3abea5156fe34fef790fbcd7974b58f1d0a61edd..8d3e10feb51dd5b0cb129bbcf741f5d7b8a563a9 100644 (file)
@@ -270,48 +270,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)
@@ -319,6 +296,7 @@ void OpenGl_View::Render (const Handle(OpenGl_PrinterContext)& thePrintContext,
     aContext->ShaderManager()->UpdateModelWorldStateTo (OpenGl_Mat4());
   }
 
+
   // ====================================
   //      Step 2: Redraw background
   // ====================================
index 57c8872b3b353e33a562d2c1fedd75718942bce8..c428289f455f091ebe56c3c609566aaf02ca650e 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>
 
@@ -789,7 +789,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 b93bd86b37933d0db02c0633acf7ea7ac18eccff..491b8b142df40cc3248edad7034a2d8c66024c69 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_TransformUtils.hxx>
 
 #if defined(_WIN32) && defined(HAVE_VIDEOCAPTURE)
   #include <OpenGl_AVIWriter.hxx>
@@ -400,9 +400,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
@@ -1147,7 +1147,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 5101695c75a9b3b95c477b143e4bdfc3dea05c56..0c6457111909a5218bb813d51e3c8103a9fdb8c6 100644 (file)
@@ -62,7 +62,7 @@ uses
     TransModeFlags         from Graphic3d, 
     Pnt                    from gp,
     Trsf                   from gp, 
-    CTransPersStruct       from  Graphic3d,
+    TransformPers          from Graphic3d,
     ZLayerId from Graphic3d
 
 raises
@@ -192,19 +192,21 @@ is
    
     
    GetTransformPersistenceMode( me )  returns  TransModeFlags  from  Graphic3d  is  static;
-    
    ---Level:    Public 
    ---Purpose:  Gets  Transform  Persistence Mode  for  this  object 
    ---Category: Graphic attributes management
 
    GetTransformPersistencePoint( me )  returns  Pnt  from  gp  is  static;
-    
    ---Level:    Public 
    ---Purpose:  Gets  point  of  transform  persistence for  this  object 
    ---Category: Graphic attributes management
-    
    --   ABD 29/10/04  Transform Persistence of Presentation( pan, zoom, rotate )
-    
+
+   TransformPersistence(me) returns TransformPers from Graphic3d is static;
+   ---Purpose: @return transform persistence of the presentable object.
+   ---C++: inline
+   ---C++: return const&
+
    SetTypeOfPresentation(me:mutable; aType: TypeOfPresentation3d from PrsMgr);    
 
    SetToUpdate    (me:mutable;aMode:Integer from Standard);
@@ -321,14 +323,14 @@ is
    -- implementation propagate clip planes to every presentation.
 
 fields
-    myPresentations: Presentations from PrsMgr is protected;
-    myTypeOfPresentation3d: TypeOfPresentation3d from PrsMgr is protected;
-    myClipPlanes : SequenceOfHClipPlane from Graphic3d is protected;
-    myTransformPersistence  :  CTransPersStruct  from  Graphic3d;
-    myIsMutable : Boolean from Standard is protected;
-    myZLayer    : ZLayerId from Graphic3d is protected;
-
-    myHasOwnPresentations : Boolean from Standard is protected; -- shows if object should have own presentations.
+    myPresentations        : Presentations from PrsMgr is protected;
+    myTypeOfPresentation3d : TypeOfPresentation3d from PrsMgr is protected;
+    myClipPlanes           : SequenceOfHClipPlane from Graphic3d is protected;
+    myTransformPersistence : TransformPers from Graphic3d;
+    myIsMutable            : Boolean from Standard is protected;
+    myZLayer               : ZLayerId from Graphic3d is protected;
+
+    myHasOwnPresentations  : Boolean from Standard is protected; -- shows if object should have own presentations.
 
     myParent : PresentableObjectPointer from PrsMgr; -- Reference to parent object in scene hierarchy.
  
index d21b6588d97c3ce4c682fd62855a62d1286d97f8..df9c8f4572f32fd63fbe9915896a4c16280c79b5 100644 (file)
@@ -34,10 +34,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;
+  //
 }
 
 //=======================================================================
@@ -302,10 +299,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.Flag    = 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();
@@ -332,18 +329,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 7beaf60f8e42ed7440d5049ec15fcfa5df05aa8d..352219e0ba6d112b64593443105587c390097b60 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 9bf32bac466089b42d1e3648a31783bec36ab2f2..166f85bd467665b979b4efafea4b9d249a3f56b3 100755 (executable)
@@ -3,6 +3,8 @@ SelectMgr_FrustumBuilder.hxx
 SelectMgr_FrustumBuilder.cxx
 SelectMgr_SelectableObjectSet.hxx
 SelectMgr_SelectableObjectSet.cxx
+SelectMgr_SelectableObjectTrsfPersSet.hxx
+SelectMgr_SelectableObjectTrsfPersSet.cxx
 SelectMgr_BaseFrustum.hxx
 SelectMgr_BaseFrustum.cxx
 SelectMgr_Frustum.hxx
index 62d6de3de9996deb8b934202b003b1cb474dcf54..6d2243798521def64211db6ce4d00b079a37583a 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,14 +45,46 @@ void SelectMgr_BaseFrustum::SetCamera (const Handle(Graphic3d_Camera)& theCamera
 // purpose  : Passes camera projection and orientation matrices to builder
 //=======================================================================
 void SelectMgr_BaseFrustum::SetCamera (const Graphic3d_Mat4d& theProjection,
-                                       const Graphic3d_Mat4d& theOrientation,
-                                       const Standard_Integer theIsOrthographic)
+                                       const Graphic3d_Mat4d& theWorldView,
+                                       const Standard_Integer theIsOrthographic,
+                                       const Graphic3d_WorldViewProjState& theWVPState)
 {
-  myBuilder->SetOrientation (theOrientation);
-  myBuilder->SetProjection (theProjection);
+  myBuilder->SetWorldViewMatrix (theWorldView);
+  myBuilder->SetProjectionMatrix (theProjection);
+  myBuilder->SetWorldViewProjState (theWVPState);
   myIsOrthographic = theIsOrthographic;
 }
 
+//=======================================================================
+// function : ProjectionMatrix
+// purpose  : Returns current camera projection transformation common for
+//            all selecting volumes
+//=======================================================================
+const Graphic3d_Mat4d& SelectMgr_BaseFrustum::ProjectionMatrix() const
+{
+  return myBuilder->ProjectionMatrix();
+}
+
+//=======================================================================
+// function : WorldViewMatrix
+// purpose  : Returns current camera world view transformation common for
+//            all selecting volumes
+//=======================================================================
+const Graphic3d_Mat4d& SelectMgr_BaseFrustum::WorldViewMatrix() const
+{
+  return myBuilder->WorldViewMatrix();
+}
+
+//=======================================================================
+// function : WorldViewProjState
+// purpose  : Returns current camera world view projection transformation
+//            state
+//=======================================================================
+const Graphic3d_WorldViewProjState& SelectMgr_BaseFrustum::WorldViewProjState() const
+{
+  return myBuilder->WorldViewProjState();
+}
+
 //=======================================================================
 // function : SetViewport
 // purpose  : Passes viewport parameters to builder
index 0efa02be3b4a44907a705af97b996bcd6b59cb52..99cd574b354ba23754ffdcad394f30325123d5db 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 91be420ac2851a616a1de2329276fbcb8b413b17..46b4b58ca89622de5a7c3c7c3575c1681363b113 100644 (file)
@@ -26,30 +26,70 @@ IMPLEMENT_STANDARD_RTTIEXT(SelectMgr_FrustumBuilder, Standard_Transient)
 // 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
@@ -133,7 +173,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 8480454cea11fefa62699acebef8359ca66e1648..bda502d5cb30a322a0bfa6054abcac56c3899c27 100644 (file)
@@ -19,6 +19,7 @@
 #include <Standard_DefineHandle.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 3985350d938c0ae307c88c80a6b4a1d75a4f2bb7..320154fceed3b00e7d637ab5f282384f750d0be7 100644 (file)
@@ -234,25 +234,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 91bc2632f1ba50c47c9cb169803688b2ecfad57d..b9c5cbd2d34cc3ab5aed3bacc59220097dac4a33 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 671f99654f194d2ff73b84a69e453dc400d1edeb..bb7ad1596a0eb1778491529322764003467976b6 100644 (file)
@@ -36,37 +36,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..2fc3b70
--- /dev/null
@@ -0,0 +1,173 @@
+// 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;
+
+  const Handle(SelectMgr_SelectableObject) anObj1 = myObjects.FindKey (aStructIdx1);
+  const Handle(SelectMgr_SelectableObject) anObj2 = myObjects.FindKey (aStructIdx2);
+  myObjects.Substitute (aStructIdx2, EMPTY_OBJ);
+  myObjects.Substitute (aStructIdx1, anObj2);
+  myObjects.Substitute (aStructIdx2, anObj1);
+
+  const HBndBox3d aBox1 = myObjectBoxes.FindKey (aStructIdx1);
+  const HBndBox3d aBox2 = myObjectBoxes.FindKey (aStructIdx2);
+  myObjectBoxes.Substitute (aStructIdx2, EMPTY_BOX);
+  myObjectBoxes.Substitute (aStructIdx1, aBox2);
+  myObjectBoxes.Substitute (aStructIdx2, aBox1);
+}
+
+//=======================================================================
+// 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)
+  {
+    Swap (anIndex - 1, Size() - 1);
+    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..e4c3312
--- /dev/null
@@ -0,0 +1,117 @@
+// 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;
+
+  HBndBox3d EMPTY_BOX;
+
+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 aa1ff3ba70f26f086b8b5d039a18b5b50cdc3c28..a7bb82f4785c05f2f78b25d8af11888c3a9984c9 100644 (file)
@@ -106,15 +106,46 @@ void SelectMgr_SelectingVolumeManager::SetCamera (const Handle(Graphic3d_Camera)
 //            selecting volumes
 //=======================================================================
 void SelectMgr_SelectingVolumeManager::SetCamera (const Graphic3d_Mat4d& theProjection,
-                                                  const Graphic3d_Mat4d& theOrientation,
-                                                  const Standard_Boolean theIsOrthographic)
+                                                  const Graphic3d_Mat4d& theWorldView,
+                                                  const Standard_Boolean theIsOrthographic,
+                                                  const Graphic3d_WorldViewProjState& theWVPState)
 {
   for (Standard_Integer anIdx = 0; anIdx < VolumeTypesNb; ++anIdx)
   {
-    mySelectingVolumes[anIdx]->SetCamera (theProjection, theOrientation, theIsOrthographic);
+    mySelectingVolumes[anIdx]->SetCamera (theProjection, theWorldView, theIsOrthographic, theWVPState);
   }
 }
 
+//=======================================================================
+// function : ProjectionMatrix
+// purpose  : Returns current projection transformation common for all
+//            selecting volumes
+//=======================================================================
+const Graphic3d_Mat4d& SelectMgr_SelectingVolumeManager::ProjectionMatrix() const
+{
+  return mySelectingVolumes[Frustum]->ProjectionMatrix();
+}
+
+//=======================================================================
+// function : WorldViewMatrix
+// purpose  : Returns current world view transformation common for all
+//            selecting volumes
+//=======================================================================
+const Graphic3d_Mat4d& SelectMgr_SelectingVolumeManager::WorldViewMatrix() const
+{
+  return mySelectingVolumes[Frustum]->WorldViewMatrix();
+}
+
+//=======================================================================
+// function : WorldViewProjState
+// purpose  : Returns current camera world view projection transformation
+//            state common for all selecting volumes
+//=======================================================================
+const Graphic3d_WorldViewProjState& SelectMgr_SelectingVolumeManager::WorldViewProjState() const
+{
+  return mySelectingVolumes[Frustum]->WorldViewProjState();
+}
+
 //=======================================================================
 // function : SetCamera
 // purpose  : Updates viewport in all selecting volumes
index 6c6a7d7238b96758b5056f20482bda4ef3eeff25..34e514ad24209843864c954ec17904b16245fcc5 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 28a12000fc9f8cd85156681f2736b305ed4f7d96..12383904f2b77f7ee8d0fd05dd51af2428c5ce3a 100644 (file)
@@ -150,10 +150,8 @@ myCurRank (0),
 myIsLeftChildQueuedFirst (Standard_False),
 myEntityIdx (0)
 {
-  mySelectableObjects = new SelectMgr_SelectableObjectSet();
 }
 
-
 //==================================================
 // Function: Activate
 // Purpose :
@@ -172,7 +170,6 @@ void SelectMgr_ViewerSelector::Activate (const Handle(SelectMgr_Selection)& theS
   myToUpdateTolerance = Standard_True;
 }
 
-
 //==================================================
 // Function: Deactivate
 // Purpose :
@@ -299,8 +296,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;
 
@@ -362,7 +383,7 @@ void SelectMgr_ViewerSelector::traverseObject (const Handle(SelectMgr_Selectable
             if (!aScaledTrnsfFrustums.IsBound (anEnt->DynamicType()))
             {
               aScaledTrnsfFrustums.Bind (anEnt->DynamicType(),
-                                         scaleAndTransform (anEnt->SensitivityFactor(), theObject->InversedTransformation()));
+                                         scaleAndTransform (anEnt->SensitivityFactor(), aInversedTrsf));
             }
 
             aTmpMgr = aScaledTrnsfFrustums.Find (anEnt->DynamicType());
@@ -391,45 +412,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;
@@ -439,22 +501,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();
@@ -548,7 +594,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);
 }
 
 //==================================================
@@ -559,7 +606,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)
@@ -582,7 +629,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())
@@ -603,7 +650,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())
@@ -655,7 +702,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";
   }
@@ -710,7 +757,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);
   }
@@ -745,8 +800,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);
   }
 }
 
@@ -772,11 +830,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);
   }
 }
 
@@ -788,7 +852,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 3f9def378b2b06ec744761db74273f2e8e639b3e..6c558f32eb5f6d614f7cde6d8758b8fa619d6afc 100644 (file)
@@ -36,6 +36,7 @@
 #include <SelectMgr_Selection.hxx>
 #include <SelectMgr_SelectableObject.hxx>
 #include <SelectMgr_SelectableObjectSet.hxx>
+#include <SelectMgr_SelectableObjectTrsfPersSet.hxx>
 #include <Handle_SelectMgr_EntityOwner.hxx>
 #include <SelectMgr_StateOfSelection.hxx>
 #include <Standard_OStream.hxx>
@@ -67,7 +68,7 @@ class SelectMgr_ToleranceMap
 public:
 
   //! Sets tolerance values to -1.0
-  SelectMgr_ToleranceMap();
+  Standard_EXPORT SelectMgr_ToleranceMap();
 
   Standard_EXPORT ~SelectMgr_ToleranceMap();
 
@@ -132,7 +133,7 @@ public:
   Standard_EXPORT void Clear();
 
   //! returns the Sensitivity of picking
-  Standard_Real Sensitivity() const;
+  Standard_EXPORT Standard_Real Sensitivity() const;
 
   //! Sorts the detected entites by priority and distance.
   //!          to be redefined if other criterion are used...
@@ -230,21 +231,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();
 
   friend class SelectMgr_SelectionManager;
 
@@ -269,23 +270,23 @@ protected:
   //! Internal function that checks if there is possible overlap
   //! between some entity of selectable object theObject and
   //! current selecting volume
-  void traverseObject (const Handle(SelectMgr_SelectableObject)& theObject);
+  Standard_EXPORT void traverseObject (const Handle(SelectMgr_SelectableObject)& theObject);
 
   //! Internal function that checks if a particular sensitive
   //! entity theEntity overlaps current selecting volume precisely
-  void checkOverlap (const Handle(SelectBasics_SensitiveEntity)& theEntity,
-                     const Standard_Integer theEntityIdx,
-                     SelectMgr_SelectingVolumeManager& theMgr);
+  Standard_EXPORT void checkOverlap (const Handle(SelectBasics_SensitiveEntity)& theEntity,
+                                     const Standard_Integer theEntityIdx,
+                                     SelectMgr_SelectingVolumeManager& theMgr);
 
   //! Marks all added sensitive entities of all objects as non-selectable
-  void resetSelectionActivationStatus();
+  Standard_EXPORT void resetSelectionActivationStatus();
 
   //! Checks if the entity given requires to scale current selecting frustum
-  Standard_Boolean isToScaleFrustum (const Handle(SelectBasics_SensitiveEntity)& theEntity);
+  Standard_EXPORT Standard_Boolean isToScaleFrustum (const Handle(SelectBasics_SensitiveEntity)& theEntity);
 
   //! Applies given scale and transformation matrices to the default selecting volume manager
-  SelectMgr_SelectingVolumeManager scaleAndTransform (const Standard_Real theScale,
-                                                      const gp_Trsf& theTrsf);
+  Standard_EXPORT SelectMgr_SelectingVolumeManager scaleAndTransform (const Standard_Real theScale,
+                                                                      const gp_Trsf& theTrsf);
 
 private:
 
@@ -298,13 +299,14 @@ private:
 
 protected:
 
-  Standard_Boolean preferclosest;
-  Standard_Real mytolerance;
-  Standard_Boolean myToUpdateTolerance;
-  SelectMgr_IndexedDataMapOfOwnerCriterion mystored;
-  SelectMgr_SelectingVolumeManager mySelectingVolumeMgr;
-  mutable NCollection_Handle<SelectMgr_SelectableObjectSet> mySelectableObjects;
-  SelectMgr_ToleranceMap myTolerances;
+  Standard_Boolean                              preferclosest;
+  Standard_Real                                 mytolerance;
+  Standard_Boolean                              myToUpdateTolerance;
+  SelectMgr_IndexedDataMapOfOwnerCriterion      mystored;
+  SelectMgr_SelectingVolumeManager              mySelectingVolumeMgr;
+  mutable SelectMgr_SelectableObjectSet         mySelectableObjects;
+  mutable SelectMgr_SelectableObjectTrsfPersSet mySelectableObjectsTrsfPers;
+  SelectMgr_ToleranceMap                        myTolerances;
 
 private:
 
index 3c0967bb07a64e51efc188138a09813544c77cc3..581694cf6bbbecfa2b06d45b3cd604f465889b1f 100644 (file)
@@ -182,39 +182,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();
 }
@@ -225,19 +237,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();
 }
 
 //=======================================================================
@@ -249,32 +259,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();
 }
@@ -283,9 +279,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;
 
@@ -512,7 +529,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...
@@ -617,12 +634,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++)
     {
@@ -630,8 +647,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 86407bcfd5ea6fb7a9ef38b250099e269f22e528..10e670e03629846f4df02a05818daa577d909e5e 100644 (file)
@@ -23,6 +23,7 @@
 
 #include <Handle_Graphic3d_Group.hxx>
 #include <Handle_Graphic3d_Structure.hxx>
+#include <Graphic3d_SequenceOfStructure.hxx>
 #include <Graphic3d_SequenceOfHClipPlane.hxx>
 #include <SelectMgr_ViewerSelector.hxx>
 #include <SelectMgr_Selection.hxx>
@@ -32,6 +33,7 @@
 
 class Graphic3d_Group;
 class Graphic3d_Structure;
+class Graphic3d_TransformPers;
 class V3d_View;
 class TColgp_Array1OfPnt2d;
 class SelectMgr_EntityOwner;
@@ -102,11 +104,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 dc78b59bd2d89ff3ac0a483c42e6a82b0b2b6466..cf5d0aec05286ec80898db6291269823ac5b8c8d 100644 (file)
@@ -3493,10 +3493,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 164096e86d3c35bdab41d442d8ded098476ad15d..aef29387054905b9ba317ec77a2ac37b168a0a3c 100644 (file)
@@ -1682,53 +1682,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  :
@@ -1753,17 +1706,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