1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-09-03 14:10:33 +03:00

0027860: Visualization - clean up Transformation Persistence API

Graphic3d_Camera::TransformMatrices redundant NCollection_Handle usage
has been replaced with validity flags.

Graphic3d_TransModeFlags now defined as enumeration, not integer bit flags.
Graphic3d_TMF_PanPers and Graphic3d_TMF_FullPers have been removed.
Graphic3d_TMF_ZoomRotatePers has been introduced.

Graphic3d_TransformPers is now inherits Standard_Transient.
Graphic3d_TransformPers now defines dedicated constructors
for 3D persistence (zoom / rotate) and 2D persistence (2d / trihedron).
2D persistence now supports dedicated values for X and Y offsets.
The corner is now specified by enumeration Aspect_TypeOfTriedronPosition
instead of indirect interpretation of anchor point values.
Fixed handling of Graphic3d_TMF_ZoomRotatePers (combination of Graphic3d_TMF_RotatePers + Graphic3d_TMF_ZoomPers).

PrsMgr_PresentableObject, Graphic3d_CStructure now hold
Handle(Graphic3d_TransformPers) instead of a value.
Method ::SetTransformPersistence(), ::TransformPersistence()
now works with Handle(Graphic3d_TransformPers).
Old methods have been marked deprecated.
This commit is contained in:
kgv
2016-09-19 23:40:07 +03:00
parent 27ba9c6006
commit 778cd66786
53 changed files with 863 additions and 648 deletions

View File

@@ -98,7 +98,6 @@ Graphic3d_SortType.hxx
Graphic3d_StereoMode.hxx
Graphic3d_Structure.cxx
Graphic3d_Structure.hxx
Graphic3d_Structure.lxx
Graphic3d_Structure.pxx
Graphic3d_StructureDefinitionError.hxx
Graphic3d_StructureManager.cxx
@@ -126,6 +125,7 @@ Graphic3d_TextureRoot.cxx
Graphic3d_TextureRoot.hxx
Graphic3d_TransformError.hxx
Graphic3d_TransformPers.hxx
Graphic3d_TransformPers.cxx
Graphic3d_TransformUtils.hxx
Graphic3d_TransModeFlags.hxx
Graphic3d_TypeOfAnswer.hxx

View File

@@ -46,6 +46,12 @@ public:
return myGroups;
}
//! Return transformation persistence.
const Handle(Graphic3d_TransformPers)& TransformPersistence() const { return myTrsfPers; }
//! Set transformation persistence.
void SetTransformPersistence (const Handle(Graphic3d_TransformPers)& theTrsfPers) { myTrsfPers = theTrsfPers; }
//! @return associated clip planes
const Handle(Graphic3d_SequenceOfHClipPlane)& ClipPlanes() const
{
@@ -143,8 +149,6 @@ public:
unsigned IsMutable : 1;
unsigned Is2dText : 1;
Graphic3d_TransformPers TransformPersistence;
protected:
//! Create empty structure.
@@ -155,6 +159,7 @@ protected:
Handle(Graphic3d_GraphicDriver) myGraphicDriver;
Graphic3d_SequenceOfGroup myGroups;
Graphic3d_BndBox4f myBndBox;
Handle(Graphic3d_TransformPers) myTrsfPers;
Handle(Graphic3d_SequenceOfHClipPlane) myClipPlanes;
public:

View File

@@ -530,14 +530,12 @@ Bnd_Box Graphic3d_CView::MinMaxValues (const Graphic3d_MapOfStructure& theSet,
}
// "FitAll" operation ignores object with transform persistence parameter
if (aStructure->TransformPersistence().Flags != Graphic3d_TMF_None)
if (!aStructure->TransformPersistence().IsNull())
{
// 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) ||
(aStructure->TransformPersistence().Flags & Graphic3d_TMF_TriedronPers))
if (!theToIgnoreInfiniteFlag
|| aStructure->TransformPersistence()->IsTrihedronOr2d())
{
continue;
}
@@ -550,11 +548,11 @@ Bnd_Box Graphic3d_CView::MinMaxValues (const Graphic3d_MapOfStructure& theSet,
continue;
}
if (aStructure->TransformPersistence().Flags != Graphic3d_TMF_None)
if (!aStructure->TransformPersistence().IsNull())
{
const Graphic3d_Mat4d& aProjectionMat = aCamera->ProjectionMatrix();
const Graphic3d_Mat4d& aWorldViewMat = aCamera->OrientationMatrix();
aStructure->TransformPersistence().Apply (aCamera, aProjectionMat, aWorldViewMat, aWinWidth, aWinHeight, aBox);
aStructure->TransformPersistence()->Apply (aCamera, aProjectionMat, aWorldViewMat, aWinWidth, aWinHeight, aBox);
}
// To prevent float overflow at camera parameters calculation and further

View File

@@ -74,6 +74,7 @@ Graphic3d_Camera::Graphic3d_Camera()
myAxialScale (1.0, 1.0, 1.0),
myProjType (Projection_Orthographic),
myFOVy (45.0),
myFOVyTan (Tan (DTR_HALF * 45.0)),
myZNear (DEFAULT_ZNEAR),
myZFar (DEFAULT_ZFAR),
myAspect (1.0),
@@ -271,7 +272,7 @@ void Graphic3d_Camera::SetScale (const Standard_Real theScale)
case Projection_MonoLeftEye :
case Projection_MonoRightEye :
{
Standard_Real aDistance = theScale * 0.5 / Tan(DTR_HALF * myFOVy);
Standard_Real aDistance = theScale * 0.5 / myFOVyTan;
SetDistance (aDistance);
}
@@ -298,7 +299,7 @@ Standard_Real Graphic3d_Camera::Scale() const
// case Projection_MonoLeftEye :
// case Projection_MonoRightEye :
default :
return Distance() * 2.0 * Tan (DTR_HALF * myFOVy);
return Distance() * 2.0 * myFOVyTan;
}
}
@@ -344,6 +345,7 @@ void Graphic3d_Camera::SetFOVy (const Standard_Real theFOVy)
}
myFOVy = theFOVy;
myFOVyTan = Tan(DTR_HALF * myFOVy);
InvalidateProjection();
}
@@ -646,7 +648,7 @@ gp_Pnt Graphic3d_Camera::ConvertView2World (const gp_Pnt& thePnt) const
gp_XYZ Graphic3d_Camera::ViewDimensions (const Standard_Real theZValue) const
{
// view plane dimensions
Standard_Real aSize = IsOrthographic() ? myScale : (2.0 * theZValue * Tan (DTR_HALF * myFOVy));
Standard_Real aSize = IsOrthographic() ? myScale : (2.0 * theZValue * myFOVyTan);
Standard_Real aSizeX, aSizeY;
if (myAspect > 1.0)
{
@@ -719,7 +721,7 @@ void Graphic3d_Camera::Frustum (gp_Pln& theLeft,
// =======================================================================
const Graphic3d_Mat4d& Graphic3d_Camera::OrientationMatrix() const
{
return *UpdateOrientation (myMatricesD).Orientation;
return UpdateOrientation (myMatricesD).Orientation;
}
// =======================================================================
@@ -728,7 +730,7 @@ const Graphic3d_Mat4d& Graphic3d_Camera::OrientationMatrix() const
// =======================================================================
const Graphic3d_Mat4& Graphic3d_Camera::OrientationMatrixF() const
{
return *UpdateOrientation (myMatricesF).Orientation;
return UpdateOrientation (myMatricesF).Orientation;
}
// =======================================================================
@@ -737,7 +739,7 @@ const Graphic3d_Mat4& Graphic3d_Camera::OrientationMatrixF() const
// =======================================================================
const Graphic3d_Mat4d& Graphic3d_Camera::ProjectionMatrix() const
{
return *UpdateProjection (myMatricesD).MProjection;
return UpdateProjection (myMatricesD).MProjection;
}
// =======================================================================
@@ -746,7 +748,7 @@ const Graphic3d_Mat4d& Graphic3d_Camera::ProjectionMatrix() const
// =======================================================================
const Graphic3d_Mat4& Graphic3d_Camera::ProjectionMatrixF() const
{
return *UpdateProjection (myMatricesF).MProjection;
return UpdateProjection (myMatricesF).MProjection;
}
// =======================================================================
@@ -755,7 +757,7 @@ const Graphic3d_Mat4& Graphic3d_Camera::ProjectionMatrixF() const
// =======================================================================
const Graphic3d_Mat4d& Graphic3d_Camera::ProjectionStereoLeft() const
{
return *UpdateProjection (myMatricesD).LProjection;
return UpdateProjection (myMatricesD).LProjection;
}
// =======================================================================
@@ -764,7 +766,7 @@ const Graphic3d_Mat4d& Graphic3d_Camera::ProjectionStereoLeft() const
// =======================================================================
const Graphic3d_Mat4& Graphic3d_Camera::ProjectionStereoLeftF() const
{
return *UpdateProjection (myMatricesF).LProjection;
return UpdateProjection (myMatricesF).LProjection;
}
// =======================================================================
@@ -773,7 +775,7 @@ const Graphic3d_Mat4& Graphic3d_Camera::ProjectionStereoLeftF() const
// =======================================================================
const Graphic3d_Mat4d& Graphic3d_Camera::ProjectionStereoRight() const
{
return *UpdateProjection (myMatricesD).RProjection;
return UpdateProjection (myMatricesD).RProjection;
}
// =======================================================================
@@ -782,7 +784,7 @@ const Graphic3d_Mat4d& Graphic3d_Camera::ProjectionStereoRight() const
// =======================================================================
const Graphic3d_Mat4& Graphic3d_Camera::ProjectionStereoRightF() const
{
return *UpdateProjection (myMatricesF).RProjection;
return UpdateProjection (myMatricesF).RProjection;
}
// =======================================================================
@@ -813,8 +815,8 @@ Graphic3d_Camera::TransformMatrices<Elem_t>&
}
else
{
aDXHalf = aZNear * Elem_t (Tan (DTR_HALF * myFOVy));
aDYHalf = aZNear * Elem_t (Tan (DTR_HALF * myFOVy));
aDXHalf = aZNear * Elem_t (myFOVyTan);
aDYHalf = aZNear * Elem_t (myFOVyTan);
}
if (anAspect > 1.0)
@@ -854,19 +856,19 @@ Graphic3d_Camera::TransformMatrices<Elem_t>&
switch (myProjType)
{
case Projection_Orthographic :
OrthoProj (aLeft, aRight, aBot, aTop, aZNear, aZFar, *theMatrices.MProjection);
OrthoProj (aLeft, aRight, aBot, aTop, aZNear, aZFar, theMatrices.MProjection);
break;
case Projection_Perspective :
PerspectiveProj (aLeft, aRight, aBot, aTop, aZNear, aZFar, *theMatrices.MProjection);
PerspectiveProj (aLeft, aRight, aBot, aTop, aZNear, aZFar, theMatrices.MProjection);
break;
case Projection_MonoLeftEye :
{
StereoEyeProj (aLeft, aRight, aBot, aTop,
aZNear, aZFar, aIOD, aFocus,
Standard_True, *theMatrices.MProjection);
*theMatrices.LProjection = *theMatrices.MProjection;
Standard_True, theMatrices.MProjection);
theMatrices.LProjection = theMatrices.MProjection;
break;
}
@@ -874,24 +876,24 @@ Graphic3d_Camera::TransformMatrices<Elem_t>&
{
StereoEyeProj (aLeft, aRight, aBot, aTop,
aZNear, aZFar, aIOD, aFocus,
Standard_False, *theMatrices.MProjection);
*theMatrices.RProjection = *theMatrices.MProjection;
Standard_False, theMatrices.MProjection);
theMatrices.RProjection = theMatrices.MProjection;
break;
}
case Projection_Stereo :
{
PerspectiveProj (aLeft, aRight, aBot, aTop, aZNear, aZFar, *theMatrices.MProjection);
PerspectiveProj (aLeft, aRight, aBot, aTop, aZNear, aZFar, theMatrices.MProjection);
StereoEyeProj (aLeft, aRight, aBot, aTop,
aZNear, aZFar, aIOD, aFocus,
Standard_True,
*theMatrices.LProjection);
theMatrices.LProjection);
StereoEyeProj (aLeft, aRight, aBot, aTop,
aZNear, aZFar, aIOD, aFocus,
Standard_False,
*theMatrices.RProjection);
theMatrices.RProjection);
break;
}
}
@@ -930,7 +932,7 @@ Graphic3d_Camera::TransformMatrices<Elem_t>&
static_cast<Elem_t> (myAxialScale.Y()),
static_cast<Elem_t> (myAxialScale.Z()));
LookOrientation (anEye, aCenter, anUp, anAxialScale, *theMatrices.Orientation);
LookOrientation (anEye, aCenter, anUp, anAxialScale, theMatrices.Orientation);
return theMatrices; // for inline accessors
}

View File

@@ -22,8 +22,6 @@
#include <Graphic3d_Vec3.hxx>
#include <Graphic3d_WorldViewProjState.hxx>
#include <NCollection_Handle.hxx>
#include <gp_Dir.hxx>
#include <gp_Pnt.hxx>
@@ -45,46 +43,50 @@ private:
template<typename Elem_t>
struct TransformMatrices
{
//! Default constructor.
TransformMatrices() : myIsOrientationValid (Standard_False), myIsProjectionValid (Standard_False) {}
//! Initialize orientation.
void InitOrientation()
{
Orientation = new NCollection_Mat4<Elem_t>();
myIsOrientationValid = Standard_True;
Orientation.InitIdentity();
}
//! Initialize projection.
void InitProjection()
{
MProjection = new NCollection_Mat4<Elem_t>();
LProjection = new NCollection_Mat4<Elem_t>();
RProjection = new NCollection_Mat4<Elem_t>();
myIsProjectionValid = Standard_True;
MProjection.InitIdentity();
LProjection.InitIdentity();
RProjection.InitIdentity();
}
void ResetOrientation()
{
Orientation.Nullify();
}
//! Invalidate orientation.
void ResetOrientation() { myIsOrientationValid = Standard_False; }
void ResetProjection()
{
MProjection.Nullify();
LProjection.Nullify();
RProjection.Nullify();
}
//! Invalidate projection.
void ResetProjection() { myIsProjectionValid = Standard_False; }
Standard_Boolean IsOrientationValid()
{
return !Orientation.IsNull();
}
//! Return true if Orientation was not invalidated.
Standard_Boolean IsOrientationValid() const { return myIsOrientationValid; }
Standard_Boolean IsProjectionValid()
{
return !MProjection.IsNull() &&
!LProjection.IsNull() &&
!RProjection.IsNull();
}
//! Return true if Projection was not invalidated.
Standard_Boolean IsProjectionValid() const { return myIsProjectionValid; }
public:
NCollection_Mat4<Elem_t> Orientation;
NCollection_Mat4<Elem_t> MProjection;
NCollection_Mat4<Elem_t> LProjection;
NCollection_Mat4<Elem_t> RProjection;
private:
Standard_Boolean myIsOrientationValid;
Standard_Boolean myIsProjectionValid;
NCollection_Handle< NCollection_Mat4<Elem_t> > Orientation;
NCollection_Handle< NCollection_Mat4<Elem_t> > MProjection;
NCollection_Handle< NCollection_Mat4<Elem_t> > LProjection;
NCollection_Handle< NCollection_Mat4<Elem_t> > RProjection;
};
public:
@@ -637,6 +639,7 @@ private:
Projection myProjType; //!< Projection type used for rendering.
Standard_Real myFOVy; //!< Field Of View in y axis.
Standard_Real myFOVyTan; //!< Field Of View as Tan(DTR_HALF * myFOVy)
Standard_Real myZNear; //!< Distance to near clipping plane.
Standard_Real myZFar; //!< Distance to far clipping plane.
Standard_Real myAspect; //!< Width to height display ratio.

View File

@@ -1103,46 +1103,14 @@ Standard_Integer Graphic3d_Structure::Identification() const
//function : SetTransformPersistence
//purpose :
//=============================================================================
void Graphic3d_Structure::SetTransformPersistence (const Graphic3d_TransModeFlags& theFlag)
void Graphic3d_Structure::SetTransformPersistence (const Handle(Graphic3d_TransformPers)& theTrsfPers)
{
SetTransformPersistence (theFlag, gp_Pnt (0.0, 0.0, 0.0));
}
if (IsDeleted())
{
return;
}
//=============================================================================
//function : SetTransformPersistence
//purpose :
//=============================================================================
void Graphic3d_Structure::SetTransformPersistence (const Graphic3d_TransModeFlags& theFlag,
const gp_Pnt& thePoint)
{
if (IsDeleted()) return;
myCStructure->TransformPersistence.Flags = theFlag;
myCStructure->TransformPersistence.Point.x() = thePoint.X();
myCStructure->TransformPersistence.Point.y() = thePoint.Y();
myCStructure->TransformPersistence.Point.z() = thePoint.Z();
}
//=============================================================================
//function : TransformPersistenceMode
//purpose :
//=============================================================================
Graphic3d_TransModeFlags Graphic3d_Structure::TransformPersistenceMode() const
{
return myCStructure->TransformPersistence.Flags;
}
//=============================================================================
//function : TransformPersistencePoint
//purpose :
//=============================================================================
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());
return aPnt;
myCStructure->SetTransformPersistence (theTrsfPers);
}
//=============================================================================

View File

@@ -377,20 +377,12 @@ public:
//! Returns the transformation associated with
//! the structure <me>.
Standard_EXPORT void Transform (TColStd_Array2OfReal& AMatrix) const;
//! Modifies the current modelling transform persistence (pan, zoom or rotate)
Standard_EXPORT void SetTransformPersistence (const Graphic3d_TransModeFlags& AFlag, const gp_Pnt& APoint);
Standard_EXPORT void SetTransformPersistence (const Graphic3d_TransModeFlags& AFlag);
//! Get the current modelling transform persistence (pan, zoom or rotate)
Standard_EXPORT Graphic3d_TransModeFlags TransformPersistenceMode() const;
//! Get the current point of relative modelling transform persistence
Standard_EXPORT gp_Pnt TransformPersistencePoint() const;
//! Modifies the current transform persistence (pan, zoom or rotate)
Standard_EXPORT void SetTransformPersistence (const Handle(Graphic3d_TransformPers)& theTrsfPers);
//! @return transform persistence of the presentable object.
const Graphic3d_TransformPers& TransformPersistence() const;
const Handle(Graphic3d_TransformPers)& TransformPersistence() const { return myCStructure->TransformPersistence(); }
//! Sets if the structure location has mutable nature (content or location will be changed regularly).
Standard_EXPORT void SetMutable (const Standard_Boolean theIsMutable);
@@ -439,7 +431,7 @@ public:
Standard_EXPORT static Graphic3d_Vertex Transforms (const TColStd_Array2OfReal& ATrsf, const Graphic3d_Vertex& Coord);
//! Returns the low-level structure
const Handle(Graphic3d_CStructure)& CStructure() const;
const Handle(Graphic3d_CStructure)& CStructure() const { return myCStructure; }
friend class Graphic3d_Group;
@@ -505,14 +497,6 @@ protected:
Standard_Address myOwner;
Graphic3d_TypeOfStructure myVisual;
};
#include <Graphic3d_Structure.lxx>
#endif // _Graphic3d_Structure_HeaderFile

View File

@@ -1,32 +0,0 @@
// Created on: 2014-03-23
// Created by: Kirill Gavrilov
// 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.
// =======================================================================
// function : CStructure
// purpose : Returns the low-level structure
// =======================================================================
inline const Handle(Graphic3d_CStructure)& Graphic3d_Structure::CStructure() const
{
return myCStructure;
}
// =======================================================================
// function : TransformPersistence
// purpose :
// =======================================================================
inline const Graphic3d_TransformPers& Graphic3d_Structure::TransformPersistence() const
{
return myCStructure->TransformPersistence;
}

View File

@@ -16,17 +16,16 @@
#ifndef Graphic3d_TRANS_MODE_FLAGS_HXX
#define Graphic3d_TRANS_MODE_FLAGS_HXX
typedef Standard_Integer Graphic3d_TransModeFlags;
enum {
Graphic3d_TMF_None = 0x0000,
Graphic3d_TMF_PanPers = 0x0001,
Graphic3d_TMF_ZoomPers = 0x0002,
Graphic3d_TMF_RotatePers = 0x0008,
Graphic3d_TMF_TriedronPers = 0x0020,
Graphic3d_TMF_2d = 0x0040,
Graphic3d_TMF_FullPers = Graphic3d_TMF_PanPers | Graphic3d_TMF_ZoomPers | Graphic3d_TMF_RotatePers
//! Transform Persistence Mode defining whether to lock in object position, rotation and / or zooming relative to camera position.
enum Graphic3d_TransModeFlags
{
Graphic3d_TMF_None = 0x0000, //!< no persistence attributes (normal 3D object)
Graphic3d_TMF_ZoomPers = 0x0002, //!< object does not resize
Graphic3d_TMF_RotatePers = 0x0008, //!< object does not rotate;
Graphic3d_TMF_TriedronPers = 0x0020, //!< object behaves like trihedron - it is fixed at the corner of view and does not resizing (but rotating)
Graphic3d_TMF_2d = 0x0040, //!< object is defined in 2D screen coordinates (pixels) and does not resize, pan and rotate
Graphic3d_TMF_ZoomRotatePers = Graphic3d_TMF_ZoomPers
| Graphic3d_TMF_RotatePers //!< object doesn't resize and rotate
};
#endif

View File

@@ -0,0 +1,53 @@
// Copyright (c) 2016 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 <Graphic3d_TransformPers.hxx>
IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_TransformPers, Standard_Transient)
// =======================================================================
// function : FromDeprecatedParams
// purpose :
// =======================================================================
Handle(Graphic3d_TransformPers) Graphic3d_TransformPers::FromDeprecatedParams (Graphic3d_TransModeFlags theFlag,
const gp_Pnt& thePoint)
{
Handle(Graphic3d_TransformPers) aTrsfPers;
if (Graphic3d_TransformPers::IsZoomOrRotate (theFlag))
{
aTrsfPers = new Graphic3d_TransformPers (theFlag, thePoint);
}
else if (Graphic3d_TransformPers::IsTrihedronOr2d (theFlag))
{
Standard_Integer aCorner = Aspect_TOTP_CENTER;
const Graphic3d_Vec2i anOffset (Standard_Integer(thePoint.Z()), Standard_Integer(thePoint.Z()));
if (thePoint.X() > 0.0)
{
aCorner |= Aspect_TOTP_RIGHT;
}
else if (thePoint.X() < 0.0)
{
aCorner |= Aspect_TOTP_LEFT;
}
if (thePoint.Y() > 0.0)
{
aCorner |= Aspect_TOTP_TOP;
}
else if (thePoint.Y() < 0.0)
{
aCorner |= Aspect_TOTP_BOTTOM;
}
aTrsfPers = new Graphic3d_TransformPers (theFlag, Aspect_TypeOfTriedronPosition(aCorner), anOffset);
}
return aTrsfPers;
}

View File

@@ -16,31 +16,197 @@
#ifndef _Graphic3d_TransformPers_HeaderFile
#define _Graphic3d_TransformPers_HeaderFile
#include <Aspect_TypeOfTriedronPosition.hxx>
#include <Bnd_Box.hxx>
#include <BVH_Box.hxx>
#include <Graphic3d_Camera.hxx>
#include <Graphic3d_TransformUtils.hxx>
#include <Graphic3d_TransModeFlags.hxx>
#include <Graphic3d_Vec.hxx>
#include <NCollection_Mat4.hxx>
#include <NCollection_Vec4.hxx>
DEFINE_STANDARD_HANDLE(Graphic3d_TransformPers, Standard_Transient)
//! Class for keeping and computing transformation persistence.
class Graphic3d_TransformPers
//! Note that instance of this class can not define
//! no transformation persistence Graphic3d_TMF_None - NULL handle should be used for this purpose.
class Graphic3d_TransformPers : public Standard_Transient
{
DEFINE_STANDARD_RTTIEXT(Graphic3d_TransformPers, Standard_Transient)
public:
DEFINE_STANDARD_ALLOC
//! Return true if specified mode is zoom/rotate transformation persistence.
static Standard_Boolean IsZoomOrRotate (Graphic3d_TransModeFlags theMode)
{
return (theMode & (Graphic3d_TMF_ZoomPers | Graphic3d_TMF_RotatePers)) != 0;
}
//! Default constructor.
Graphic3d_TransformPers()
: Flags (Graphic3d_TMF_None),
Point (0.0, 0.0, 0.0) {}
//! Return true if specified mode is 2d/trihedron transformation persistence.
static Standard_Boolean IsTrihedronOr2d (Graphic3d_TransModeFlags theMode)
{
return (theMode & (Graphic3d_TMF_TriedronPers | Graphic3d_TMF_2d)) != 0;
}
//! Create Graphic3d_TransformPers instance from deprecated parameters set
//! decoding 2D corner + offset parameters from 3D point.
Standard_EXPORT static Handle(Graphic3d_TransformPers) FromDeprecatedParams (Graphic3d_TransModeFlags theFlag,
const gp_Pnt& thePoint);
public:
//! Set transformation persistence.
Graphic3d_TransformPers (const Graphic3d_TransModeFlags theMode)
: myMode (theMode)
{
if (IsZoomOrRotate (theMode))
{
SetPersistence (theMode, gp_Pnt(0.0, 0.0, 0.0));
}
else if (IsTrihedronOr2d (theMode))
{
SetPersistence (theMode, Aspect_TOTP_LEFT_LOWER, Graphic3d_Vec2i (0, 0));
}
else
{
Standard_ProgramError::Raise ("Graphic3d_TransformPers::SetPersistence(), wrong persistence mode.");
}
}
//! Set Zoom/Rotate transformation persistence with an anchor 3D point.
//! Throws an exception if persistence mode is not Graphic3d_TMF_ZoomPers, Graphic3d_TMF_ZoomRotatePers or Graphic3d_TMF_RotatePers.
Graphic3d_TransformPers (const Graphic3d_TransModeFlags theMode,
const gp_Pnt& thePnt)
: myMode (Graphic3d_TMF_None)
{
SetPersistence (theMode, thePnt);
}
//! Set 2d/trihedron transformation persistence with a corner and 2D offset.
//! Throws an exception if persistence mode is not Graphic3d_TMF_TriedronPers or Graphic3d_TMF_2d.
//! The offset is a positive displacement from the view corner in pixels.
Graphic3d_TransformPers (const Graphic3d_TransModeFlags theMode,
const Aspect_TypeOfTriedronPosition theCorner,
const Graphic3d_Vec2i& theOffset = Graphic3d_Vec2i (0, 0))
: myMode (Graphic3d_TMF_None)
{
SetPersistence (theMode, theCorner, theOffset);
}
//! Return true for Graphic3d_TMF_ZoomPers, Graphic3d_TMF_ZoomRotatePers or Graphic3d_TMF_RotatePers modes.
Standard_Boolean IsZoomOrRotate() const { return IsZoomOrRotate (myMode); }
//! Return true for Graphic3d_TMF_TriedronPers and Graphic3d_TMF_2d modes.
Standard_Boolean IsTrihedronOr2d() const { return IsTrihedronOr2d (myMode); }
//! Transformation persistence mode flags.
Graphic3d_TransModeFlags Flags;
Graphic3d_TransModeFlags Mode() const { return myMode; }
//! Reference point for transformation.
Graphic3d_Vec3d Point;
//! Transformation persistence mode flags.
Graphic3d_TransModeFlags Flags() const { return myMode; }
//! Set Zoom/Rotate transformation persistence with an anchor 3D point.
//! Throws an exception if persistence mode is not Graphic3d_TMF_ZoomPers, Graphic3d_TMF_ZoomRotatePers or Graphic3d_TMF_RotatePers.
void SetPersistence (const Graphic3d_TransModeFlags theMode,
const gp_Pnt& thePnt)
{
if (!IsZoomOrRotate (theMode))
{
Standard_ProgramError::Raise ("Graphic3d_TransformPers::SetPersistence(), wrong persistence mode.");
}
myMode = theMode;
myParams.Params3d.PntX = thePnt.X();
myParams.Params3d.PntY = thePnt.Y();
myParams.Params3d.PntZ = thePnt.Z();
}
//! Set 2d/trihedron transformation persistence with a corner and 2D offset.
//! Throws an exception if persistence mode is not Graphic3d_TMF_TriedronPers or Graphic3d_TMF_2d.
void SetPersistence (const Graphic3d_TransModeFlags theMode,
const Aspect_TypeOfTriedronPosition theCorner,
const Graphic3d_Vec2i& theOffset)
{
if (!IsTrihedronOr2d (theMode))
{
Standard_ProgramError::Raise ("Graphic3d_TransformPers::SetPersistence(), wrong persistence mode.");
}
myMode = theMode;
myParams.Params2d.Corner = theCorner;
myParams.Params2d.OffsetX = theOffset.x();
myParams.Params2d.OffsetY = theOffset.y();
}
public:
//! Return the anchor point for zoom/rotate transformation persistence.
gp_Pnt AnchorPoint() const
{
if (!IsZoomOrRotate())
{
Standard_ProgramError::Raise ("Graphic3d_TransformPers::AnchorPoint(), wrong persistence mode.");
}
return gp_Pnt (myParams.Params3d.PntX, myParams.Params3d.PntY, myParams.Params3d.PntZ);
}
//! Set the anchor point for zoom/rotate transformation persistence.
void SetAnchorPoint (const gp_Pnt& thePnt)
{
if (!IsZoomOrRotate())
{
Standard_ProgramError::Raise ("Graphic3d_TransformPers::SetAnchorPoint(), wrong persistence mode.");
}
myParams.Params3d.PntX = thePnt.X();
myParams.Params3d.PntY = thePnt.Y();
myParams.Params3d.PntZ = thePnt.Z();
}
//! Return the corner for 2d/trihedron transformation persistence.
Aspect_TypeOfTriedronPosition Corner2d() const
{
if (!IsTrihedronOr2d())
{
Standard_ProgramError::Raise ("Graphic3d_TransformPers::Corner2d(), wrong persistence mode.");
}
return myParams.Params2d.Corner;
}
//! Set the corner for 2d/trihedron transformation persistence.
void SetCorner2d (const Aspect_TypeOfTriedronPosition thePos)
{
if (!IsTrihedronOr2d())
{
Standard_ProgramError::Raise ("Graphic3d_TransformPers::SetCorner2d(), wrong persistence mode.");
}
myParams.Params2d.Corner = thePos;
}
//! Return the offset from the corner for 2d/trihedron transformation persistence.
Graphic3d_Vec2i Offset2d() const
{
if (!IsTrihedronOr2d())
{
Standard_ProgramError::Raise ("Graphic3d_TransformPers::Offset2d(), wrong persistence mode.");
}
return Graphic3d_Vec2i (myParams.Params2d.OffsetX, myParams.Params2d.OffsetY);
}
//! Set the offset from the corner for 2d/trihedron transformation persistence.
void SetOffset2d (const Graphic3d_Vec2i& theOffset)
{
if (!IsTrihedronOr2d())
{
Standard_ProgramError::Raise ("Graphic3d_TransformPers::SetOffset2d(), wrong persistence mode.");
}
myParams.Params2d.OffsetX = theOffset.x();
myParams.Params2d.OffsetY = theOffset.y();
}
public:
@@ -98,16 +264,37 @@ public:
//! @param theViewportHeight viewport height
template<class T>
void Apply (const Handle(Graphic3d_Camera)& theCamera,
NCollection_Mat4<T>& theProjection,
const NCollection_Mat4<T>& theProjection,
NCollection_Mat4<T>& theWorldView,
const Standard_Integer theViewportWidth,
const Standard_Integer theViewportHeight) const;
//! Return true if transformation persistence alters projection matrix.
bool AltersProjectionMatrix() const
private:
//! 3D anchor point for zoom/rotate transformation persistence.
struct PersParams3d
{
return (Flags & Graphic3d_TMF_PanPers) != 0;
}
Standard_Real PntX;
Standard_Real PntY;
Standard_Real PntZ;
};
//! 2d/trihedron transformation persistence parameters.
struct PersParams2d
{
Standard_Integer OffsetX;
Standard_Integer OffsetY;
Aspect_TypeOfTriedronPosition Corner;
};
private:
Graphic3d_TransModeFlags myMode; //!< Transformation persistence mode flags
union
{
PersParams3d Params3d;
PersParams2d Params2d;
} myParams;
};
@@ -117,20 +304,26 @@ public:
// =======================================================================
template<class T>
void Graphic3d_TransformPers::Apply (const Handle(Graphic3d_Camera)& theCamera,
NCollection_Mat4<T>& theProjection,
const NCollection_Mat4<T>& theProjection,
NCollection_Mat4<T>& theWorldView,
const Standard_Integer theViewportWidth,
const Standard_Integer theViewportHeight) const
{
(void )theViewportWidth;
if (Flags == Graphic3d_TMF_None
(void )theProjection;
if (myMode == Graphic3d_TMF_None
|| theViewportHeight == 0)
{
return;
}
// use total size when tiling is active
const Standard_Integer aVPSizeY = theCamera->Tile().IsValid() ? theCamera->Tile().TotalSize.y() : theViewportHeight;
if (Flags == Graphic3d_TMF_TriedronPers)
// a small enough jitter compensation offset
// to avoid image dragging within single pixel in corner cases
const Standard_Real aJitterComp = 0.001;
if (myMode == Graphic3d_TMF_TriedronPers)
{
// reset Z focus for trihedron persistence
const Standard_Real aFocus = theCamera->IsOrthographic()
@@ -142,41 +335,43 @@ void Graphic3d_TransformPers::Apply (const Handle(Graphic3d_Camera)& theCamera,
// scale factor to pixels
const gp_XYZ aViewDim = theCamera->ViewDimensions (aFocus);
const Standard_Real aScale = Abs(aViewDim.Y()) / Standard_Real(aVPSizeY);
// offset from the corner
const Standard_Real anOffset = Point.z() * aScale;
const gp_Dir aForward (theCamera->Center().XYZ() - theCamera->Eye().XYZ());
gp_XYZ aCenter = theCamera->Center().XYZ() + aForward.XYZ() * (aFocus - theCamera->Distance());
if (Point.x() != 0.0)
if ((myParams.Params2d.Corner & (Aspect_TOTP_LEFT | Aspect_TOTP_RIGHT)) != 0)
{
const gp_Dir aSide = aForward.Crossed (theCamera->Up());
if (Point.x() > 0.0)
const Standard_Real anOffsetX = (Standard_Real(myParams.Params2d.OffsetX) + aJitterComp) * aScale;
const gp_Dir aSide = aForward.Crossed (theCamera->Up());
const gp_XYZ aDeltaX = aSide.XYZ() * (Abs(aViewDim.X()) * 0.5 - anOffsetX);
if ((myParams.Params2d.Corner & Aspect_TOTP_RIGHT) != 0)
{
aCenter += aSide.XYZ() * (Abs(aViewDim.X()) * 0.5 - anOffset);
aCenter += aDeltaX;
}
else
{
aCenter -= aSide.XYZ() * (Abs(aViewDim.X()) * 0.5 - anOffset);
aCenter -= aDeltaX;
}
}
if (Point.y() != 0.0)
if ((myParams.Params2d.Corner & (Aspect_TOTP_TOP | Aspect_TOTP_BOTTOM)) != 0)
{
if (Point.y() > 0.0)
const Standard_Real anOffsetY = (Standard_Real(myParams.Params2d.OffsetY) + aJitterComp) * aScale;
const gp_XYZ aDeltaY = theCamera->Up().XYZ() * (Abs(aViewDim.Y()) * 0.5 - anOffsetY);
if ((myParams.Params2d.Corner & Aspect_TOTP_TOP) != 0)
{
aCenter += theCamera->Up().XYZ() * (Abs(aViewDim.Y()) * 0.5 - anOffset);
aCenter += aDeltaY;
}
else
{
aCenter -= theCamera->Up().XYZ() * (Abs(aViewDim.Y()) * 0.5 - anOffset);
aCenter -= aDeltaY;
}
}
Graphic3d_TransformUtils::Translate (theWorldView, T(aCenter.X()), T(aCenter.Y()), T(aCenter.Z()));
Graphic3d_TransformUtils::Scale (theWorldView, T(aScale), T(aScale), T(aScale));
NCollection_Mat4<Standard_Real> aWorldView = theCamera->OrientationMatrix();
Graphic3d_TransformUtils::Translate (aWorldView, aCenter.X(), aCenter.Y(), aCenter.Z());
Graphic3d_TransformUtils::Scale (aWorldView, aScale, aScale, aScale);
theWorldView.ConvertFrom (aWorldView);
return;
}
else if (Flags == Graphic3d_TMF_2d)
else if (myMode == Graphic3d_TMF_2d)
{
const Standard_Real aFocus = theCamera->IsOrthographic()
? theCamera->Distance()
@@ -188,18 +383,18 @@ void Graphic3d_TransformPers::Apply (const Handle(Graphic3d_Camera)& theCamera,
const gp_XYZ aViewDim = theCamera->ViewDimensions (aFocus);
const Standard_Real aScale = Abs(aViewDim.Y()) / Standard_Real(aVPSizeY);
gp_XYZ aCenter (0.0, 0.0, -aFocus);
if (Point.x() != 0.0)
if ((myParams.Params2d.Corner & (Aspect_TOTP_LEFT | Aspect_TOTP_RIGHT)) != 0)
{
aCenter.SetX (-aViewDim.X() * 0.5 + Point.z() * aScale);
if (Point.x() > 0.0)
aCenter.SetX (-aViewDim.X() * 0.5 + (Standard_Real(myParams.Params2d.OffsetX) + aJitterComp) * aScale);
if ((myParams.Params2d.Corner & Aspect_TOTP_RIGHT) != 0)
{
aCenter.SetX (-aCenter.X());
}
}
if (Point.y() != 0.0)
if ((myParams.Params2d.Corner & (Aspect_TOTP_TOP | Aspect_TOTP_BOTTOM)) != 0)
{
aCenter.SetY (-aViewDim.Y() * 0.5 + Point.z() * aScale);
if (Point.y() > 0.0)
aCenter.SetY (-aViewDim.Y() * 0.5 + (Standard_Real(myParams.Params2d.OffsetY) + aJitterComp) * aScale);
if ((myParams.Params2d.Corner & Aspect_TOTP_TOP) != 0)
{
aCenter.SetY (-aCenter.Y());
}
@@ -210,92 +405,42 @@ void Graphic3d_TransformPers::Apply (const Handle(Graphic3d_Camera)& theCamera,
Graphic3d_TransformUtils::Scale (theWorldView, T(aScale), T(aScale), T(aScale));
return;
}
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()),
NCollection_Vec4<T> aRefPoint (static_cast<T> (myParams.Params3d.PntX),
static_cast<T> (myParams.Params3d.PntY),
static_cast<T> (myParams.Params3d.PntZ),
static_cast<T> (1.0));
NCollection_Vec4<T> aRefPointProj;
if ((Flags & Graphic3d_TMF_PanPers) != Graphic3d_TMF_PanPers)
Graphic3d_TransformUtils::Translate<T> (theWorldView, aRefPoint.x(), aRefPoint.y(), aRefPoint.z());
if ((myMode & Graphic3d_TMF_RotatePers) != 0)
{
aRefPointProj = theProjection * (theWorldView * aRefPoint);
aRefPointProj /= aRefPointProj.w();
// lock rotation by nullifying rotation component
theWorldView.SetValue (0, 0, static_cast<T> (1));
theWorldView.SetValue (1, 0, static_cast<T> (0));
theWorldView.SetValue (2, 0, static_cast<T> (0));
theWorldView.SetValue (0, 1, static_cast<T> (0));
theWorldView.SetValue (1, 1, static_cast<T> (1));
theWorldView.SetValue (2, 1, static_cast<T> (0));
theWorldView.SetValue (0, 2, static_cast<T> (0));
theWorldView.SetValue (1, 2, static_cast<T> (0));
theWorldView.SetValue (2, 2, static_cast<T> (1));
}
// Prevent zooming.
if ((Flags & Graphic3d_TMF_ZoomPers) != 0)
if ((myMode & Graphic3d_TMF_ZoomPers) != 0)
{
const T aSize = static_cast<T> (1.0);
const Standard_Integer aViewport[4] = { 0, 0, theViewportHeight, theViewportHeight };
NCollection_Mat4<T> aWorldView;
aWorldView.InitIdentity();
NCollection_Vec3<T> aWinCoordsRefPoint;
Graphic3d_TransformUtils::Project (static_cast<T> (Point.x()),
static_cast<T> (Point.y()),
static_cast<T> (Point.z()),
theWorldView, theProjection, aViewport,
aWinCoordsRefPoint.x(), aWinCoordsRefPoint.y(), aWinCoordsRefPoint.z());
NCollection_Vec3<T> anUnProj1;
Graphic3d_TransformUtils::UnProject (aWinCoordsRefPoint.x(), aWinCoordsRefPoint.y(), aWinCoordsRefPoint.z(),
aWorldView, theProjection, aViewport,
anUnProj1.x(), anUnProj1.y(), anUnProj1.z());
NCollection_Vec3<T> anUnProj2;
Graphic3d_TransformUtils::UnProject (aWinCoordsRefPoint.x(), aWinCoordsRefPoint.y() + aSize, aWinCoordsRefPoint.z(),
aWorldView, theProjection, aViewport,
anUnProj2.x(), anUnProj2.y(), anUnProj2.z());
const T aScale = (anUnProj2.y() - anUnProj1.y()) / aSize;
Graphic3d_TransformUtils::Scale (theWorldView, aScale, aScale, aScale);
}
// Prevent translation by nullifying translation component.
if ((Flags & Graphic3d_TMF_PanPers) != 0)
{
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 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_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());
// lock zooming
gp_Vec aVecToEye (theCamera->Direction());
gp_Vec aVecToObj (theCamera->Eye(), gp_Pnt (myParams.Params3d.PntX, myParams.Params3d.PntY, myParams.Params3d.PntZ));
const Standard_Real aFocus = aVecToObj.Dot (aVecToEye);
const gp_XYZ aViewDim = theCamera->ViewDimensions (aFocus);
const Standard_Real aScale = Abs(aViewDim.Y()) / Standard_Real(aVPSizeY);
Graphic3d_TransformUtils::Scale (theWorldView, T(aScale), T(aScale), T(aScale));
}
return;
}
}
@@ -384,26 +529,13 @@ NCollection_Mat4<T> Graphic3d_TransformPers::Compute (const Handle(Graphic3d_Cam
const Standard_Integer theViewportWidth,
const Standard_Integer theViewportHeight) const
{
if (Flags == Graphic3d_TMF_None)
if (myMode == Graphic3d_TMF_None)
{
return NCollection_Mat4<T>();
}
NCollection_Mat4<T> aProjection (theProjection);
NCollection_Mat4<T> aWorldView (theWorldView);
NCollection_Mat4<T> aWorldView (theWorldView);
NCollection_Mat4<T> anUnviewMat;
if (AltersProjectionMatrix())
{
// destructive transformation persistence which directly modifies projection matrix
if (!(theProjection * theWorldView).Inverted (anUnviewMat))
{
return NCollection_Mat4<T>();
}
Apply (theCamera, aProjection, aWorldView, theViewportWidth, theViewportHeight);
return anUnviewMat * (aProjection * aWorldView);
}
if (!theWorldView.Inverted (anUnviewMat))
{
return NCollection_Mat4<T>();
@@ -411,7 +543,7 @@ NCollection_Mat4<T> Graphic3d_TransformPers::Compute (const Handle(Graphic3d_Cam
// compute only world-view matrix difference to avoid floating point instability
// caused by projection matrix modifications outside of this algorithm (e.g. by Z-fit)
Apply (theCamera, aProjection, aWorldView, theViewportWidth, theViewportHeight);
Apply (theCamera, theProjection, aWorldView, theViewportWidth, theViewportHeight);
return anUnviewMat * aWorldView;
}