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

0027793: Visualization - object drifts at zoom within Graphic3d_TMF_TriedronPers applied

Graphic3d_TransformPers now takes Graphic3d_Camera definition as argument
for methods applying transformation.

Graphic3d_TransformPers::Apply() now computes Graphic3d_TMF_TriedronPers
transformation in the following way:
- The object is moved onto Z focus distance.
- The object is expected to be defined in pixels.
- The Z coordinate on anchor point is used as offset from the view corner in pixels.
- It is now possible to define not only corners of the view, but also middle of the side.
- Graphic3d_TMF_TriedronPers now works with perspective projection.

OpenGl_LayerList::ChangeLayer() - fixed removing of the element in old ZLayer.

OpenGl_Layer::BoundingBox() now takes into account bounding box
of Graphic3d_TMF_TriedronPers presentations for Z-fit operation.
This commit is contained in:
kgv
2016-08-23 17:11:49 +03:00
committed by abv
parent 742cc8b01d
commit 3fe9ce0edd
28 changed files with 401 additions and 237 deletions

View File

@@ -71,6 +71,14 @@ public:
//! Return structure visibility flag
bool IsVisible() const { return visible != 0; }
//! Return structure visibility considering both View Affinity and global visibility state.
bool IsVisible (const Standard_Integer theViewId) const
{
return visible != 0
&& (ViewAffinity.IsNull()
|| ViewAffinity->IsVisible (theViewId));
}
//! Set z layer ID to display the structure in specified layer
void SetZLayer (const Graphic3d_ZLayerId theLayerIndex) { myZLayer = theLayerIndex; }

View File

@@ -432,7 +432,7 @@ void Graphic3d_CView::DisplayedStructures (Graphic3d_MapOfStructure& theStructur
// function : MinMaxValues
// purpose :
// =======================================================================
Bnd_Box Graphic3d_CView::MinMaxValues (const Standard_Boolean theToIgnoreInfiniteFlag) const
Bnd_Box Graphic3d_CView::MinMaxValues (const Standard_Boolean theToIncludeAuxiliary) const
{
Bnd_Box aResult;
@@ -453,14 +453,18 @@ Bnd_Box Graphic3d_CView::MinMaxValues (const Standard_Boolean theToIgnoreInfinit
aCamera,
aWinWidth,
aWinHeight,
theToIgnoreInfiniteFlag);
theToIncludeAuxiliary);
combineBox (aResult, aBox);
}
Standard_Integer aMaxZLayer = ZLayerMax();
for (Standard_Integer aLayerId = Graphic3d_ZLayerId_Default; aLayerId <= aMaxZLayer; ++aLayerId)
{
Graphic3d_BndBox4f aBox = ZLayerBoundingBox (aLayerId, aCamera, aWinWidth, aWinHeight, theToIgnoreInfiniteFlag);
Graphic3d_BndBox4f aBox = ZLayerBoundingBox (aLayerId,
aCamera,
aWinWidth,
aWinHeight,
theToIncludeAuxiliary);
combineBox (aResult, aBox);
}
@@ -487,12 +491,12 @@ Standard_Real Graphic3d_CView::ConsiderZoomPersistenceObjects()
Standard_Real aMaxCoef = 1.0;
for (Standard_Integer aLayer = 0; aLayer < THE_NB_DEFAULT_LAYERS; ++aLayer)
{
aMaxCoef = Max (aMaxCoef, considerZoomPersistenceObjects (THE_DEFAULT_LAYERS[aLayer], aCamera, aWinWidth, aWinHeight, Standard_False));
aMaxCoef = Max (aMaxCoef, considerZoomPersistenceObjects (THE_DEFAULT_LAYERS[aLayer], aCamera, aWinWidth, aWinHeight));
}
for (Standard_Integer aLayer = Graphic3d_ZLayerId_Default; aLayer <= ZLayerMax(); ++aLayer)
{
aMaxCoef = Max (aMaxCoef, considerZoomPersistenceObjects (aLayer, aCamera, aWinWidth, aWinHeight, Standard_False));
aMaxCoef = Max (aMaxCoef, considerZoomPersistenceObjects (aLayer, aCamera, aWinWidth, aWinHeight));
}
return aMaxCoef;
@@ -519,12 +523,8 @@ Bnd_Box Graphic3d_CView::MinMaxValues (const Graphic3d_MapOfStructure& theSet,
for (Graphic3d_MapIteratorOfMapOfStructure aStructIter (theSet); aStructIter.More(); aStructIter.Next())
{
const Handle(Graphic3d_Structure)& aStructure = aStructIter.Key();
if (!aStructure->IsVisible() || aStructure->IsEmpty())
{
continue;
}
else if (!aStructure->CStructure()->ViewAffinity.IsNull()
&& !aStructure->CStructure()->ViewAffinity->IsVisible (aViewId))
if (aStructure->IsEmpty()
|| !aStructure->CStructure()->IsVisible (aViewId))
{
continue;
}
@@ -554,7 +554,7 @@ Bnd_Box Graphic3d_CView::MinMaxValues (const Graphic3d_MapOfStructure& theSet,
{
const Graphic3d_Mat4d& aProjectionMat = aCamera->ProjectionMatrix();
const Graphic3d_Mat4d& aWorldViewMat = aCamera->OrientationMatrix();
aStructure->TransformPersistence().Apply (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

@@ -135,17 +135,18 @@ public:
Handle(Graphic3d_Structure)& theComputedStruct) const;
//! Returns the bounding box of all structures displayed in the view.
//! If <theToIgnoreInfiniteFlag> is TRUE, then the boundary box
//! also includes minimum and maximum limits of graphical elements
//! forming parts of infinite structures.
Standard_EXPORT Bnd_Box MinMaxValues (const Standard_Boolean theToIgnoreInfiniteFlag = Standard_False) const;
//! If theToIncludeAuxiliary is TRUE, then the boundary box also includes minimum and maximum limits
//! of graphical elements forming parts of infinite and other auxiliary structures.
//! @param theToIncludeAuxiliary consider also auxiliary presentations (with infinite flag or with trihedron transformation persistence)
//! @return computed bounding box
Standard_EXPORT Bnd_Box MinMaxValues (const Standard_Boolean theToIncludeAuxiliary = Standard_False) const;
//! Returns the coordinates of the boundary box of all structures in the set <theSet>.
//! If <theToIgnoreInfiniteFlag> is TRUE, then the boundary box
//! also includes minimum and maximum limits of graphical elements
//! forming parts of infinite structures.
Standard_EXPORT Bnd_Box MinMaxValues (const Graphic3d_MapOfStructure& theSet,
const Standard_Boolean theToIgnoreInfiniteFlag = Standard_False) const;
const Standard_Boolean theToIncludeAuxiliary = Standard_False) const;
//! Returns the structure manager handle which manage structures associated with this view.
const Handle(Graphic3d_StructureManager)& StructureManager() const { return myStructureManager; }
@@ -322,11 +323,17 @@ public:
virtual void InvalidateZLayerBoundingBox (const Graphic3d_ZLayerId theLayerId) const = 0;
//! Returns the bounding box of all structures displayed in the Z layer.
//! @param theLayerId layer identifier
//! @param theCamera camera definition
//! @param theWindowWidth viewport width (for applying transformation-persistence)
//! @param theWindowHeight viewport height (for applying transformation-persistence)
//! @param theToIncludeAuxiliary consider also auxiliary presentations (with infinite flag or with trihedron transformation persistence)
//! @return computed bounding box
virtual Graphic3d_BndBox4f ZLayerBoundingBox (const Graphic3d_ZLayerId theLayerId,
const Handle(Graphic3d_Camera)& theCamera,
const Standard_Integer theWindowWidth,
const Standard_Integer theWindowHeight,
const Standard_Boolean theToIgnoreInfiniteFlag) const = 0;
const Standard_Boolean theToIncludeAuxiliary) const = 0;
//! Remove Z layer from the specified view. All structures
//! displayed at the moment in layer will be displayed in default layer
@@ -473,8 +480,7 @@ private:
virtual Standard_Real considerZoomPersistenceObjects (const Graphic3d_ZLayerId theLayerId,
const Handle(Graphic3d_Camera)& theCamera,
const Standard_Integer theWindowWidth,
const Standard_Integer theWindowHeight,
const Standard_Boolean theToIgnoreInfiniteFlag) const = 0;
const Standard_Integer theWindowHeight) const = 0;
protected:

View File

@@ -270,7 +270,7 @@ void Graphic3d_Camera::SetScale (const Standard_Real theScale)
case Projection_MonoLeftEye :
case Projection_MonoRightEye :
{
Standard_Real aDistance = theScale * 0.5 / Tan(myFOVy * M_PI / 360.0);
Standard_Real aDistance = theScale * 0.5 / Tan(DTR_HALF * myFOVy);
SetDistance (aDistance);
}
@@ -297,7 +297,7 @@ Standard_Real Graphic3d_Camera::Scale() const
// case Projection_MonoLeftEye :
// case Projection_MonoRightEye :
default :
return Distance() * 2.0 * Tan (myFOVy * M_PI / 360.0);
return Distance() * 2.0 * Tan (DTR_HALF * myFOVy);
}
}
@@ -627,10 +627,10 @@ gp_Pnt Graphic3d_Camera::ConvertView2World (const gp_Pnt& thePnt) const
// function : ViewDimensions
// purpose :
// =======================================================================
gp_XYZ Graphic3d_Camera::ViewDimensions() const
gp_XYZ Graphic3d_Camera::ViewDimensions (const Standard_Real theZValue) const
{
// view plane dimensions
Standard_Real aSize = IsOrthographic() ? myScale : (2.0 * Distance() * Tan (DTR_HALF * myFOVy));
Standard_Real aSize = IsOrthographic() ? myScale : (2.0 * theZValue * Tan (DTR_HALF * myFOVy));
Standard_Real aSizeX, aSizeY;
if (myAspect > 1.0)
{

View File

@@ -386,7 +386,16 @@ public:
//! Calculate view plane size at center (target) point
//! and distance between ZFar and ZNear planes.
//! @return values in form of gp_Pnt (Width, Height, Depth).
Standard_EXPORT gp_XYZ ViewDimensions() const;
gp_XYZ ViewDimensions() const
{
return ViewDimensions (Distance());
}
//! Calculate view plane size at center point with specified Z offset
//! and distance between ZFar and ZNear planes.
//! @param theZValue [in] the distance from the eye in eye-to-center direction
//! @return values in form of gp_Pnt (Width, Height, Depth).
Standard_EXPORT gp_XYZ ViewDimensions (const Standard_Real theZValue) const;
//! Calculate WCS frustum planes for the camera projection volume.
//! Frustum is a convex volume determined by six planes directing

View File

@@ -18,6 +18,7 @@
#include <Bnd_Box.hxx>
#include <BVH_Box.hxx>
#include <Graphic3d_Camera.hxx>
#include <Graphic3d_TransformUtils.hxx>
#include <Graphic3d_TransModeFlags.hxx>
#include <NCollection_Mat4.hxx>
@@ -44,26 +45,30 @@ public:
public:
//! Apply transformation to bounding box of presentation.
//! @param theCamera [in] camera definition
//! @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,
void Apply (const Handle(Graphic3d_Camera)& theCamera,
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 theCamera [in] camera definition
//! @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,
void Apply (const Handle(Graphic3d_Camera)& theCamera,
const NCollection_Mat4<T>& theProjection,
const NCollection_Mat4<T>& theWorldView,
const Standard_Integer theViewportWidth,
const Standard_Integer theViewportHeight,
@@ -72,19 +77,22 @@ public:
//! Compute transformation.
//! Computed matrix can be applied to model world transformation
//! of an object to implement effect of transformation persistence.
//! @param theCamera [in] camera definition
//! @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,
NCollection_Mat4<T> Compute (const Handle(Graphic3d_Camera)& theCamera,
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,
void Apply (const Handle(Graphic3d_Camera)& theCamera,
NCollection_Mat4<T>& theProjection,
NCollection_Mat4<T>& theWorldView,
const Standard_Integer theViewportWidth,
const Standard_Integer theViewportHeight) const;
@@ -95,7 +103,8 @@ public:
// purpose : Apply transformation to world view and projection matrices.
// =======================================================================
template<class T>
void Graphic3d_TransformPers::Apply (NCollection_Mat4<T>& theProjection,
void Graphic3d_TransformPers::Apply (const Handle(Graphic3d_Camera)& theCamera,
NCollection_Mat4<T>& theProjection,
NCollection_Mat4<T>& theWorldView,
const Standard_Integer theViewportWidth,
const Standard_Integer theViewportHeight) const
@@ -105,6 +114,53 @@ void Graphic3d_TransformPers::Apply (NCollection_Mat4<T>& theProjection,
return;
}
if (Flags == Graphic3d_TMF_TriedronPers)
{
// reset Z focus for trihedron persistence
const Standard_Real aFocus = theCamera->IsOrthographic()
? theCamera->Distance()
: (theCamera->ZFocusType() == Graphic3d_Camera::FocusType_Relative
? Standard_Real(theCamera->ZFocus() * theCamera->Distance())
: Standard_Real(theCamera->ZFocus()));
// scale factor to pixels
const gp_XYZ aViewDim = theCamera->ViewDimensions (aFocus);
const Standard_Real aScale = Abs(aViewDim.Y()) / Standard_Real(theViewportHeight);
// 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)
{
const gp_Dir aSide = aForward.Crossed (theCamera->Up());
if (Point.x() > 0.0)
{
aCenter += aSide.XYZ() * (Abs(aViewDim.X()) * 0.5 - anOffset);
}
else
{
aCenter -= aSide.XYZ() * (Abs(aViewDim.X()) * 0.5 - anOffset);
}
}
if (Point.y() != 0.0)
{
if (Point.y() > 0.0)
{
aCenter += theCamera->Up().XYZ() * (Abs(aViewDim.Y()) * 0.5 - anOffset);
}
else
{
aCenter -= theCamera->Up().XYZ() * (Abs(aViewDim.Y()) * 0.5 - anOffset);
}
}
Graphic3d_TransformUtils::Translate (theWorldView, T(aCenter.X()), T(aCenter.Y()), T(aCenter.Z()));
Graphic3d_TransformUtils::Scale (theWorldView, T(aScale), T(aScale), T(aScale));
return;
}
if (Flags & Graphic3d_TMF_2d)
{
T aLeft = -static_cast<T> (theViewportWidth / 2);
@@ -158,8 +214,7 @@ void Graphic3d_TransformPers::Apply (NCollection_Mat4<T>& theProjection,
}
// Prevent zooming.
if ((Flags == Graphic3d_TMF_TriedronPers)
|| (Flags & Graphic3d_TMF_ZoomPers))
if ((Flags & Graphic3d_TMF_ZoomPers) != 0)
{
const T aSize = static_cast<T> (1.0);
const Standard_Integer aViewport[4] = { 0, 0, theViewportHeight, theViewportHeight };
@@ -189,7 +244,7 @@ void Graphic3d_TransformPers::Apply (NCollection_Mat4<T>& theProjection,
}
// Prevent translation by nullifying translation component.
if ((Flags & Graphic3d_TMF_PanPers) || Flags == Graphic3d_TMF_TriedronPers)
if ((Flags & Graphic3d_TMF_PanPers) != 0)
{
theWorldView .SetValue (0, 3, static_cast<T> (0.0));
theWorldView .SetValue (1, 3, static_cast<T> (0.0));
@@ -215,35 +270,7 @@ void Graphic3d_TransformPers::Apply (NCollection_Mat4<T>& theProjection,
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)
if ((Flags & Graphic3d_TMF_PanPers) != Graphic3d_TMF_PanPers)
{
NCollection_Mat4<T> anUnviewMat;
@@ -266,12 +293,18 @@ void Graphic3d_TransformPers::Apply (NCollection_Mat4<T>& theProjection,
// purpose : Apply transformation to bounding box of presentation.
// =======================================================================
template<class T>
void Graphic3d_TransformPers::Apply (const NCollection_Mat4<T>& theProjection,
void Graphic3d_TransformPers::Apply (const Handle(Graphic3d_Camera)& theCamera,
const NCollection_Mat4<T>& theProjection,
const NCollection_Mat4<T>& theWorldView,
const Standard_Integer theViewportWidth,
const Standard_Integer theViewportHeight,
Bnd_Box& theBoundingBox) const
{
if (theBoundingBox.IsVoid())
{
return;
}
T aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
theBoundingBox.Get (aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
@@ -280,7 +313,7 @@ void Graphic3d_TransformPers::Apply (const NCollection_Mat4<T>& theProjection,
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);
Apply (theCamera, theProjection, theWorldView, theViewportWidth, theViewportHeight, aBBox);
theBoundingBox = Bnd_Box();
theBoundingBox.Update (aBBox.CornerMin().x(), aBBox.CornerMin().y(), aBBox.CornerMin().z(),
@@ -292,15 +325,16 @@ void Graphic3d_TransformPers::Apply (const NCollection_Mat4<T>& theProjection,
// purpose : Apply transformation to bounding box of presentation.
// =======================================================================
template<class T>
void Graphic3d_TransformPers::Apply (const NCollection_Mat4<T>& theProjection,
void Graphic3d_TransformPers::Apply (const Handle(Graphic3d_Camera)& theCamera,
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())
NCollection_Mat4<T> aTPers = Compute (theCamera, theProjection, theWorldView, theViewportWidth, theViewportHeight);
if (aTPers.IsIdentity()
|| !theBoundingBox.IsValid())
{
return;
}
@@ -333,7 +367,8 @@ void Graphic3d_TransformPers::Apply (const NCollection_Mat4<T>& theProjection,
// purpose : Compute transformation.
// =======================================================================
template<class T>
NCollection_Mat4<T> Graphic3d_TransformPers::Compute (const NCollection_Mat4<T>& theProjection,
NCollection_Mat4<T> Graphic3d_TransformPers::Compute (const Handle(Graphic3d_Camera)& theCamera,
const NCollection_Mat4<T>& theProjection,
const NCollection_Mat4<T>& theWorldView,
const Standard_Integer theViewportWidth,
const Standard_Integer theViewportHeight) const
@@ -353,7 +388,7 @@ NCollection_Mat4<T> Graphic3d_TransformPers::Compute (const NCollection_Mat4<T>&
NCollection_Mat4<T> aProjection (theProjection);
NCollection_Mat4<T> aWorldView (theWorldView);
Apply (aProjection, aWorldView, theViewportWidth, theViewportHeight);
Apply (theCamera, aProjection, aWorldView, theViewportWidth, theViewportHeight);
return anUnviewMat * (aProjection * aWorldView);
}