1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-03 17:56:21 +03:00

0024393: Visualization - objects position with enchanced precision

Graphic3d_ZLayerSettings - public fields have been replaced by methods.
Added new property Origin defining local coordinate system for all Layer objects.

Syntax of Draw Harness command VZLayer has been redesigned.

Graphic3d_CStructure now stores bounding box with double precision floats.
OpenGl_BVHTreeSelector - frustum culling now works with double precision floats.
This commit is contained in:
kgv 2016-10-02 19:36:14 +03:00 committed by apn
parent ebc369da1d
commit 7c3ef2f752
42 changed files with 1341 additions and 845 deletions

View File

@ -2404,19 +2404,55 @@ For each z-layer, it is allowed to:
* Enable / disable depth buffer clearing.
* Enable / disable polygon offset.
The corresponding method *SetZLayerOption (...)* is available in *Graphic3d_GraphicDriver* interface. You can get the options using getter from *Visual3d_ViewManager* and *V3d_Viewer*. It returns *Graphic3d_ZLayerSettings* cached in *Visual3d_ViewManager* for a given *LayerId*.
You can get the options using getter from *Visual3d_ViewManager* and *V3d_Viewer*. It returns *Graphic3d_ZLayerSettings* for a given *LayerId*.
Example:
~~~~~
// change z-layer settings
Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (anId);
aSettings.EnableSetting (Graphic3d_ZLayerDepthTest);
aSettings.EnableSetting (Graphic3d_ZLayerDepthWrite);
aSettings.EnableSetting (Graphic3d_ZLayerDepthClear);
aSettings.EnableSetting (Graphic3d_ZLayerDepthOffset);
aSettings.SetEnableDepthTest (Standard_True);
aSettings.SetEnableDepthWrite(Standard_True);
aSettings.SetClearDepth (Standard_True);
aSettings.SetPolygonOffset (Graphic3d_PolygonOffset());
aViewer->SetZLayerSettings (anId, aSettings);
~~~~~
Another application for Z-Layer feature is treating visual precision issues when displaying objects far from the World Center.
The key problem with such objects is that visualization data is stored and manipulated with single precision floating-point numbers (32-bit).
Single precision 32-bit floating-point number gives only 6-9 significant decimal digits precision,
while double precision 64-bit number gives 1517 significant decimal digits precision - sufficient enough for most applications.
When moving Object far from the World Center, float number steadily eats precision.
The camera Eye position adds leading decimal digits to overall Object transformation which discards smaller digits due to floating point number nature.
For example, the object of size 0.0000123 moved to position 1000 has result transformation 1000.0000123,
which overflows single precision floating point - considering the most optimistic scenario of 9 significant digits (but it is really not this case), the result number will be 1000.00001.
The result of this imprecision are visual artifacts in 3D Viewer of two kinds:
* Overall per-vertex Object distortion.
This happens when each vertex position have been defined within World Coordinate system.
* Object is not distorted itself, but its position in the World is unstable and imprecise - object jumps during camera manipulations.
This happens when vertices have been defined within Local Coordinate system at the distance small enough to keep precision within single precision float,
however Local Transformation applied to the Object is corrupted due to single precision float.
The first issue can not be handled without switching entire presentation into double precision (for each vertex position).
However, visualization hardware is much faster using single precision float number rather than double precision - so this is not an option in most cases.
The second issue, however, can be negated by applying special rendering tricks.
So, to apply this feature in OCCT, application needs:
* Define Local Transformation for each object so that presentation data will fit into single precision float without distortion.
* Spatially split the world into smaller areas/cells where single precision float will be sufficient.
The size of such cell might vary and depends on the precision required by application (e.g. how much user is able to zoom in camera within application).
* Define more Z-Layer for each spatial cell containing any object.
Define the *Local Origin* property of the Z-Layer according to the center of the cell.
Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (anId);
aSettings.SetLocalOrigin (400.0, 0.0, 0.0);
* Assign presentable object to the nearest Z-Layer.
Note that *Local Origin* of the Layer is a rendering-only thing - everything outside will be still defined in the World Coordinate System,
including Local Transformation of the Object and Detection results.
E.g., while moving presentation between Z-layers with different Local Origin, the Object will be still left at the same place - only visualization quality will vary.
@subsubsection occt_visu_4_4_16 Clipping planes

View File

@ -567,7 +567,7 @@ void AIS_InteractiveObject::BoundingBox (Bnd_Box& theBndBox)
{
const Handle(PrsMgr_Presentation)& aPrs3d = myPresentations.First().Presentation();
const Handle(Graphic3d_Structure)& aStruct = aPrs3d->Presentation();
const Graphic3d_BndBox4f& aBndBox = aStruct->CStructure()->BoundingBox();
const Graphic3d_BndBox3d& aBndBox = aStruct->CStructure()->BoundingBox();
if (!aBndBox.IsValid())
{
@ -575,12 +575,8 @@ void AIS_InteractiveObject::BoundingBox (Bnd_Box& theBndBox)
return;
}
theBndBox.Update (static_cast<Standard_Real> (aBndBox.CornerMin().x()),
static_cast<Standard_Real> (aBndBox.CornerMin().y()),
static_cast<Standard_Real> (aBndBox.CornerMin().z()),
static_cast<Standard_Real> (aBndBox.CornerMax().x()),
static_cast<Standard_Real> (aBndBox.CornerMax().y()),
static_cast<Standard_Real> (aBndBox.CornerMax().z()));
theBndBox.Update (aBndBox.CornerMin().x(), aBndBox.CornerMin().y(), aBndBox.CornerMin().z(),
aBndBox.CornerMax().x(), aBndBox.CornerMax().y(), aBndBox.CornerMax().z());
return;
}
else
@ -607,7 +603,7 @@ void AIS_InteractiveObject::BoundingBox (Bnd_Box& theBndBox)
{
const Handle(PrsMgr_Presentation)& aPrs3d = myPresentations (aPrsIter).Presentation();
const Handle(Graphic3d_Structure)& aStruct = aPrs3d->Presentation();
const Graphic3d_BndBox4f& aBndBox = aStruct->CStructure()->BoundingBox();
const Graphic3d_BndBox3d& aBndBox = aStruct->CStructure()->BoundingBox();
if (!aBndBox.IsValid())
{
@ -615,12 +611,8 @@ void AIS_InteractiveObject::BoundingBox (Bnd_Box& theBndBox)
return;
}
theBndBox.Update (static_cast<Standard_Real> (aBndBox.CornerMin().x()),
static_cast<Standard_Real> (aBndBox.CornerMin().y()),
static_cast<Standard_Real> (aBndBox.CornerMin().z()),
static_cast<Standard_Real> (aBndBox.CornerMax().x()),
static_cast<Standard_Real> (aBndBox.CornerMax().y()),
static_cast<Standard_Real> (aBndBox.CornerMax().z()));
theBndBox.Update (aBndBox.CornerMin().x(), aBndBox.CornerMin().y(), aBndBox.CornerMin().z(),
aBndBox.CornerMax().x(), aBndBox.CornerMax().y(), aBndBox.CornerMax().z());
return;
}
}

View File

@ -28,6 +28,7 @@ Graphic3d_AspectMarker3d.hxx
Graphic3d_AspectText3d.cxx
Graphic3d_AspectText3d.hxx
Graphic3d_AspectTextDefinitionError.hxx
Graphic3d_BndBox3d.hxx
Graphic3d_BndBox4d.hxx
Graphic3d_BndBox4f.hxx
Graphic3d_BoundBuffer.hxx

View File

@ -0,0 +1,22 @@
// 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.
#ifndef _Graphic3d_BndBox3d_Header
#define _Graphic3d_BndBox3d_Header
#include <BVH_Box.hxx>
#include <BVH_Types.hxx>
typedef BVH_Box<Standard_Real, 3> Graphic3d_BndBox3d;
#endif // _Graphic3d_BndBox3d_Header

View File

@ -24,14 +24,14 @@ struct Graphic3d_CLight
public:
Graphic3d_Vec3d Position; //!< light position
Graphic3d_Vec4 Color; //!< light color
Graphic3d_Vec4 Position; //!< light position
Graphic3d_Vec4 Direction; //!< direction of directional/spot light
Graphic3d_Vec4 Params; //!< packed light parameters
Graphic3d_TypeOfLightSource Type; //!< Graphic3d_TypeOfLightSource enumeration
Standard_Boolean IsHeadlight; //!< flag to mark head light
Standard_ShortReal Smoothness; //!< radius (cone angle) for point (directional) light
Standard_ShortReal Intensity; //!< intensity multiplier for light
Graphic3d_TypeOfLightSource Type; //!< Graphic3d_TypeOfLightSource enumeration
Standard_Boolean IsHeadlight; //!< flag to mark head light
//! Const attenuation factor of positional light source
Standard_ShortReal ConstAttenuation() const { return Params.x(); }
@ -58,14 +58,14 @@ public:
//! Empty constructor
Graphic3d_CLight()
: Color (1.0f, 1.0f, 1.0f, 1.0f),
Position (0.0f, 0.0f, 0.0f, 1.0f),
: Position (0.0, 0.0, 0.0),
Color (1.0f, 1.0f, 1.0f, 1.0f),
Direction (0.0f, 0.0f, 0.0f, 0.0f),
Params (0.0f, 0.0f, 0.0f, 0.0f),
Type (Graphic3d_TOLS_AMBIENT),
IsHeadlight (Standard_False),
Smoothness (0.0f),
Intensity (1.0f)
Intensity (1.0f),
Type (Graphic3d_TOLS_AMBIENT),
IsHeadlight (Standard_False)
{
//
}

View File

@ -15,7 +15,7 @@
#ifndef _Graphic3d_CStructure_HeaderFile
#define _Graphic3d_CStructure_HeaderFile
#include <Graphic3d_BndBox4f.hxx>
#include <Graphic3d_BndBox3d.hxx>
#include <Graphic3d_Group.hxx>
#include <Graphic3d_HighlightStyle.hxx>
#include <Graphic3d_SequenceOfGroup.hxx>
@ -58,7 +58,7 @@ public:
const Handle(Graphic3d_TransformPers)& TransformPersistence() const { return myTrsfPers; }
//! Set transformation persistence.
void SetTransformPersistence (const Handle(Graphic3d_TransformPers)& theTrsfPers) { myTrsfPers = theTrsfPers; }
virtual void SetTransformPersistence (const Handle(Graphic3d_TransformPers)& theTrsfPers) { myTrsfPers = theTrsfPers; }
//! @return associated clip planes
const Handle(Graphic3d_SequenceOfHClipPlane)& ClipPlanes() const
@ -70,14 +70,14 @@ public:
void SetClipPlanes (const Handle(Graphic3d_SequenceOfHClipPlane)& thePlanes) { myClipPlanes = thePlanes; }
//! @return bounding box of this presentation
const Graphic3d_BndBox4f& BoundingBox() const
const Graphic3d_BndBox3d& BoundingBox() const
{
return myBndBox;
}
//! @return bounding box of this presentation
//! without transformation matrix applied
Graphic3d_BndBox4f& ChangeBoundingBox()
Graphic3d_BndBox3d& ChangeBoundingBox()
{
return myBndBox;
}
@ -94,7 +94,7 @@ public:
}
//! Set z layer ID to display the structure in specified layer
void SetZLayer (const Graphic3d_ZLayerId theLayerIndex) { myZLayer = theLayerIndex; }
virtual void SetZLayer (const Graphic3d_ZLayerId theLayerIndex) { myZLayer = theLayerIndex; }
//! Get z layer ID
Graphic3d_ZLayerId ZLayer() const { return myZLayer; }
@ -163,7 +163,7 @@ protected:
Handle(Graphic3d_GraphicDriver) myGraphicDriver;
Graphic3d_SequenceOfGroup myGroups;
Graphic3d_BndBox4f myBndBox;
Graphic3d_BndBox3d myBndBox;
Handle(Geom_Transformation) myTrsf;
Handle(Graphic3d_TransformPers) myTrsfPers;
Handle(Graphic3d_SequenceOfHClipPlane) myClipPlanes;

View File

@ -26,18 +26,6 @@ namespace
static const int THE_NB_DEFAULT_LAYERS = sizeof(THE_DEFAULT_LAYERS) / sizeof(*THE_DEFAULT_LAYERS);
void combineBox (Bnd_Box& aCombined, const Graphic3d_BndBox4f& theBox)
{
if (theBox.IsValid())
{
aCombined.Add (gp_Pnt (theBox.CornerMin().x(),
theBox.CornerMin().y(),
theBox.CornerMin().z()));
aCombined.Add (gp_Pnt (theBox.CornerMax().x(),
theBox.CornerMax().y(),
theBox.CornerMax().z()));
}
}
}
//=======================================================================
@ -436,23 +424,23 @@ Bnd_Box Graphic3d_CView::MinMaxValues (const Standard_Boolean theToIncludeAuxili
for (Standard_Integer aLayer = 0; aLayer < THE_NB_DEFAULT_LAYERS; ++aLayer)
{
Graphic3d_BndBox4f aBox = ZLayerBoundingBox (THE_DEFAULT_LAYERS[aLayer],
aCamera,
aWinWidth,
aWinHeight,
theToIncludeAuxiliary);
combineBox (aResult, aBox);
Bnd_Box aBox = ZLayerBoundingBox (THE_DEFAULT_LAYERS[aLayer],
aCamera,
aWinWidth,
aWinHeight,
theToIncludeAuxiliary);
aResult.Add (aBox);
}
Standard_Integer aMaxZLayer = ZLayerMax();
for (Standard_Integer aLayerId = Graphic3d_ZLayerId_Default; aLayerId <= aMaxZLayer; ++aLayerId)
{
Graphic3d_BndBox4f aBox = ZLayerBoundingBox (aLayerId,
aCamera,
aWinWidth,
aWinHeight,
theToIncludeAuxiliary);
combineBox (aResult, aBox);
Bnd_Box aBox = ZLayerBoundingBox (aLayerId,
aCamera,
aWinWidth,
aWinHeight,
theToIncludeAuxiliary);
aResult.Add(aBox);
}
return aResult;

View File

@ -308,11 +308,11 @@ public:
//! @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 theToIncludeAuxiliary) const = 0;
virtual Bnd_Box ZLayerBoundingBox (const Graphic3d_ZLayerId theLayerId,
const Handle(Graphic3d_Camera)& theCamera,
const Standard_Integer theWindowWidth,
const Standard_Integer theWindowHeight,
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

View File

@ -44,13 +44,14 @@ namespace
// purpose :
// =======================================================================
Graphic3d_ClipPlane::Graphic3d_ClipPlane()
: myAspect (defaultAspect()),
myEquation (0.0, 0.0, 1.0, 0.0),
myFlags (Graphic3d_CappingFlags_None),
myIsOn (Standard_True),
myIsCapping (Standard_False),
: myAspect (defaultAspect()),
myPlane (0.0, 0.0, 1.0, 0.0),
myEquation (0.0, 0.0, 1.0, 0.0),
myFlags (Graphic3d_CappingFlags_None),
myEquationMod(0),
myAspectMod(0)
myAspectMod (0),
myIsOn (Standard_True),
myIsCapping (Standard_False)
{
makeId();
}
@ -60,13 +61,14 @@ Graphic3d_ClipPlane::Graphic3d_ClipPlane()
// purpose :
// =======================================================================
Graphic3d_ClipPlane::Graphic3d_ClipPlane(const Equation& theEquation)
: myAspect (defaultAspect()),
myEquation (theEquation),
myFlags (Graphic3d_CappingFlags_None),
myIsOn (Standard_True),
myIsCapping (Standard_False),
: myAspect (defaultAspect()),
myPlane (theEquation.x(), theEquation.y(), theEquation.z(), theEquation.w()),
myEquation (theEquation),
myFlags (Graphic3d_CappingFlags_None),
myEquationMod(0),
myAspectMod(0)
myAspectMod (0),
myIsOn (Standard_True),
myIsCapping (Standard_False)
{
makeId();
}
@ -77,13 +79,14 @@ Graphic3d_ClipPlane::Graphic3d_ClipPlane(const Equation& theEquation)
// =======================================================================
Graphic3d_ClipPlane::Graphic3d_ClipPlane(const Graphic3d_ClipPlane& theOther)
: Standard_Transient(theOther),
myAspect (defaultAspect()),
myEquation (theOther.myEquation),
myFlags (theOther.myFlags),
myIsOn (theOther.myIsOn),
myIsCapping (theOther.myIsCapping),
myEquationMod (0),
myAspectMod (0)
myAspect (defaultAspect()),
myPlane (theOther.myPlane),
myEquation (theOther.myEquation),
myFlags (theOther.myFlags),
myEquationMod(0),
myAspectMod (0),
myIsOn (theOther.myIsOn),
myIsCapping (theOther.myIsCapping)
{
makeId();
*myAspect = *theOther.CappingAspect();
@ -94,16 +97,16 @@ Graphic3d_ClipPlane::Graphic3d_ClipPlane(const Graphic3d_ClipPlane& theOther)
// purpose :
// =======================================================================
Graphic3d_ClipPlane::Graphic3d_ClipPlane(const gp_Pln& thePlane)
: myAspect (defaultAspect()),
myEquation (),
myFlags (Graphic3d_CappingFlags_None),
myIsOn (Standard_True),
myIsCapping (Standard_False),
: myAspect (defaultAspect()),
myPlane (thePlane),
myFlags (Graphic3d_CappingFlags_None),
myEquationMod(0),
myAspectMod(0)
myAspectMod (0),
myIsOn (Standard_True),
myIsCapping (Standard_False)
{
thePlane.Coefficients (myEquation[0], myEquation[1], myEquation[2], myEquation[3]);
makeId();
SetEquation (thePlane);
}
// =======================================================================
@ -112,6 +115,7 @@ Graphic3d_ClipPlane::Graphic3d_ClipPlane(const gp_Pln& thePlane)
// =======================================================================
void Graphic3d_ClipPlane::SetEquation (const Equation& theEquation)
{
myPlane = gp_Pln (theEquation.x(), theEquation.y(), theEquation.z(), theEquation.w());
myEquation = theEquation;
myEquationMod++;
}
@ -122,6 +126,7 @@ void Graphic3d_ClipPlane::SetEquation (const Equation& theEquation)
// =======================================================================
void Graphic3d_ClipPlane::SetEquation (const gp_Pln& thePlane)
{
myPlane = thePlane;
thePlane.Coefficients (myEquation[0],
myEquation[1],
myEquation[2],
@ -147,18 +152,6 @@ void Graphic3d_ClipPlane::SetCapping (const Standard_Boolean theIsOn)
myIsCapping = theIsOn;
}
// =======================================================================
// function : ToPlane
// purpose :
// =======================================================================
gp_Pln Graphic3d_ClipPlane::ToPlane() const
{
return gp_Pln (myEquation[0],
myEquation[1],
myEquation[2],
myEquation[3]);
}
// =======================================================================
// function : Clone
// purpose :

View File

@ -16,16 +16,15 @@
#ifndef _Graphic3d_ClipPlane_HeaderFile
#define _Graphic3d_ClipPlane_HeaderFile
#include <Standard_Macro.hxx>
#include <Standard_TypeDef.hxx>
#include <Standard_Transient.hxx>
#include <NCollection_Vec4.hxx>
#include <Aspect_HatchStyle.hxx>
#include <gp_Pln.hxx>
#include <Graphic3d_AspectFillArea3d.hxx>
#include <Graphic3d_CappingFlags.hxx>
#include <Graphic3d_TextureMap.hxx>
#include <Aspect_HatchStyle.hxx>
class gp_Pln;
#include <NCollection_Vec4.hxx>
#include <Standard_Macro.hxx>
#include <Standard_TypeDef.hxx>
#include <Standard_Transient.hxx>
//! Container for properties describing graphic driver clipping planes.
//! It is up to application to create instances of this class and specify its
@ -114,10 +113,9 @@ public:
return myIsCapping;
}
//! Get geometrical definition. The plane is built up
//! from the equation clipping plane equation vector.
//! @return geometrical definition of clipping plane.
Standard_EXPORT gp_Pln ToPlane() const;
//! Get geometrical definition.
//! @return geometrical definition of clipping plane
const gp_Pln& ToPlane() const { return myPlane; }
//! Clone plane. Virtual method to simplify copying procedure if plane
//! class is redefined at application level to add specific fields to it
@ -228,12 +226,13 @@ private:
Handle(Graphic3d_AspectFillArea3d) myAspect; //!< fill area aspect
TCollection_AsciiString myId; //!< resource id
gp_Pln myPlane; //!< plane definition
Equation myEquation; //!< plane equation vector
unsigned int myFlags; //!< capping flags
Standard_Boolean myIsOn; //!< state of the clipping plane
Standard_Boolean myIsCapping; //!< state of graphic driver capping
unsigned int myEquationMod; //!< modification counter for equation
unsigned int myAspectMod; //!< modification counter of aspect
Standard_Boolean myIsOn; //!< state of the clipping plane
Standard_Boolean myIsCapping; //!< state of graphic driver capping
public:

View File

@ -130,7 +130,7 @@ public:
virtual void SetZLayerSettings (const Graphic3d_ZLayerId theLayerId, const Graphic3d_ZLayerSettings& theSettings) = 0;
//! Returns the settings of a single Z layer.
virtual Graphic3d_ZLayerSettings ZLayerSettings (const Graphic3d_ZLayerId theLayerId) = 0;
virtual const Graphic3d_ZLayerSettings& ZLayerSettings (const Graphic3d_ZLayerId theLayerId) const = 0;
//! Returns view associated with the window if it is exists and is activated.
//! Returns Standard_True if the view associated to the window exists.

View File

@ -100,24 +100,9 @@ void Graphic3d_Structure::Clear (const Standard_Boolean theWithDestruction)
//=======================================================================
void Graphic3d_Structure::CalculateBoundBox()
{
Graphic3d_BndBox4d aBox;
Graphic3d_BndBox3d aBox;
addTransformed (aBox, Standard_True);
if (aBox.IsValid())
{
Graphic3d_Vec4 aMinPt (RealToShortReal (aBox.CornerMin().x()),
RealToShortReal (aBox.CornerMin().y()),
RealToShortReal (aBox.CornerMin().z()),
1.0f);
Graphic3d_Vec4 aMaxPt (RealToShortReal (aBox.CornerMax().x()),
RealToShortReal (aBox.CornerMax().y()),
RealToShortReal (aBox.CornerMax().z()),
1.0f);
myCStructure->ChangeBoundingBox() = Graphic3d_BndBox4f (aMinPt, aMaxPt);
}
else
{
myCStructure->ChangeBoundingBox().Clear();
}
myCStructure->ChangeBoundingBox() = aBox;
}
//=============================================================================
@ -968,28 +953,26 @@ void Graphic3d_Structure::SetTransformation (const Handle(Geom_Transformation)&
//=============================================================================
Bnd_Box Graphic3d_Structure::MinMaxValues (const Standard_Boolean theToIgnoreInfiniteFlag) const
{
Graphic3d_BndBox4d aBox;
Bnd_Box aResult;
Graphic3d_BndBox3d aBox;
addTransformed (aBox, theToIgnoreInfiniteFlag);
if (aBox.IsValid())
if (!aBox.IsValid())
{
aResult.Add (gp_Pnt (aBox.CornerMin().x(),
aBox.CornerMin().y(),
aBox.CornerMin().z()));
aResult.Add (gp_Pnt (aBox.CornerMax().x(),
aBox.CornerMax().y(),
aBox.CornerMax().z()));
return Bnd_Box();
}
Standard_Real aLimMin = ShortRealFirst() + 1.0;
Standard_Real aLimMax = ShortRealLast() - 1.0;
gp_Pnt aMin = aResult.CornerMin();
gp_Pnt aMax = aResult.CornerMax();
if (aMin.X() < aLimMin && aMin.Y() < aLimMin && aMin.Z() < aLimMin &&
aMax.X() > aLimMax && aMax.Y() > aLimMax && aMax.Z() > aLimMax)
{
//For structure which infinite in all three dimensions the Whole bounding box will be returned
aResult.SetWhole();
}
Bnd_Box aResult;
aResult.Update (aBox.CornerMin().x(), aBox.CornerMin().y(), aBox.CornerMin().z(),
aBox.CornerMax().x(), aBox.CornerMax().y(), aBox.CornerMax().z());
Standard_Real aLimMin = ShortRealFirst() + 1.0;
Standard_Real aLimMax = ShortRealLast() - 1.0;
gp_Pnt aMin = aResult.CornerMin();
gp_Pnt aMax = aResult.CornerMax();
if (aMin.X() < aLimMin && aMin.Y() < aLimMin && aMin.Z() < aLimMin
&& aMax.X() > aLimMax && aMax.Y() > aLimMax && aMax.Z() > aLimMax)
{
//For structure which infinite in all three dimensions the Whole bounding box will be returned
aResult.SetWhole();
}
return aResult;
}
@ -1086,33 +1069,31 @@ Graphic3d_BndBox4f Graphic3d_Structure::minMaxCoord() const
//function : addTransformed
//purpose :
//=============================================================================
void Graphic3d_Structure::getBox (Graphic3d_BndBox4d& theBox,
void Graphic3d_Structure::getBox (Graphic3d_BndBox3d& theBox,
const Standard_Boolean theToIgnoreInfiniteFlag) const
{
Graphic3d_BndBox4f aBoxF = minMaxCoord();
if (aBoxF.IsValid())
{
theBox = Graphic3d_BndBox4d (Graphic3d_Vec4d ((Standard_Real )aBoxF.CornerMin().x(),
theBox = Graphic3d_BndBox3d (Graphic3d_Vec3d ((Standard_Real )aBoxF.CornerMin().x(),
(Standard_Real )aBoxF.CornerMin().y(),
(Standard_Real )aBoxF.CornerMin().z(),
(Standard_Real )aBoxF.CornerMin().w()),
Graphic3d_Vec4d ((Standard_Real )aBoxF.CornerMax().x(),
(Standard_Real )aBoxF.CornerMin().z()),
Graphic3d_Vec3d ((Standard_Real )aBoxF.CornerMax().x(),
(Standard_Real )aBoxF.CornerMax().y(),
(Standard_Real )aBoxF.CornerMax().z(),
(Standard_Real )aBoxF.CornerMax().w()));
(Standard_Real )aBoxF.CornerMax().z()));
if (IsInfinite()
&& !theToIgnoreInfiniteFlag)
{
const Graphic3d_Vec4d aDiagVec = theBox.CornerMax() - theBox.CornerMin();
if (aDiagVec.xyz().SquareModulus() >= 500000.0 * 500000.0)
const Graphic3d_Vec3d aDiagVec = theBox.CornerMax() - theBox.CornerMin();
if (aDiagVec.SquareModulus() >= 500000.0 * 500000.0)
{
// bounding borders of infinite line has been calculated as own point in center of this line
theBox = Graphic3d_BndBox4d ((theBox.CornerMin() + theBox.CornerMax()) * 0.5);
theBox = Graphic3d_BndBox3d ((theBox.CornerMin() + theBox.CornerMax()) * 0.5);
}
else
{
theBox = Graphic3d_BndBox4d (Graphic3d_Vec4d (RealFirst(), RealFirst(), RealFirst(), 1.0),
Graphic3d_Vec4d (RealLast(), RealLast(), RealLast(), 1.0));
theBox = Graphic3d_BndBox3d (Graphic3d_Vec3d (RealFirst(), RealFirst(), RealFirst()),
Graphic3d_Vec3d (RealLast(), RealLast(), RealLast()));
return;
}
}
@ -1123,10 +1104,10 @@ void Graphic3d_Structure::getBox (Graphic3d_BndBox4d& theBox,
//function : addTransformed
//purpose :
//=============================================================================
void Graphic3d_Structure::addTransformed (Graphic3d_BndBox4d& theBox,
void Graphic3d_Structure::addTransformed (Graphic3d_BndBox3d& theBox,
const Standard_Boolean theToIgnoreInfiniteFlag) const
{
Graphic3d_BndBox4d aCombinedBox, aBox;
Graphic3d_BndBox3d aCombinedBox, aBox;
getBox (aCombinedBox, theToIgnoreInfiniteFlag);
for (Graphic3d_IndexedMapOfAddress::Iterator anIter (myDescendants); anIter.More(); anIter.Next())

View File

@ -425,10 +425,10 @@ private:
Standard_EXPORT Graphic3d_BndBox4f minMaxCoord() const;
//! Gets untransformed bounding box from structure.
Standard_EXPORT void getBox (Graphic3d_BndBox4d& theBox, const Standard_Boolean theToIgnoreInfiniteFlag = Standard_False) const;
Standard_EXPORT void getBox (Graphic3d_BndBox3d& theBox, const Standard_Boolean theToIgnoreInfiniteFlag = Standard_False) const;
//! Adds transformed (with myCStructure->Transformation) bounding box of structure to theBox.
Standard_EXPORT void addTransformed (Graphic3d_BndBox4d& theBox, const Standard_Boolean theToIgnoreInfiniteFlag = Standard_False) const;
Standard_EXPORT void addTransformed (Graphic3d_BndBox3d& theBox, const Standard_Boolean theToIgnoreInfiniteFlag = Standard_False) const;
//! Returns the manager to which <me> is associated.
Standard_EXPORT Handle(Graphic3d_StructureManager) StructureManager() const;

View File

@ -238,7 +238,7 @@ public:
const NCollection_Mat4<T>& theWorldView,
const Standard_Integer theViewportWidth,
const Standard_Integer theViewportHeight,
BVH_Box<T, 4>& theBoundingBox) const;
BVH_Box<T, 3>& theBoundingBox) const;
//! Compute transformation.
//! Computed matrix can be applied to model world transformation
@ -408,26 +408,22 @@ void Graphic3d_TransformPers::Apply (const Handle(Graphic3d_Camera)& theCamera,
else
{
// Compute reference point for transformation in untransformed projection space.
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));
Graphic3d_TransformUtils::Translate<T> (theWorldView, aRefPoint.x(), aRefPoint.y(), aRefPoint.z());
NCollection_Mat4<Standard_Real> aWorldView = theCamera->OrientationMatrix();
Graphic3d_TransformUtils::Translate (aWorldView, myParams.Params3d.PntX, myParams.Params3d.PntY, myParams.Params3d.PntZ);
if ((myMode & Graphic3d_TMF_RotatePers) != 0)
{
// 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));
aWorldView.SetValue (0, 0, 1.0);
aWorldView.SetValue (1, 0, 0.0);
aWorldView.SetValue (2, 0, 0.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));
aWorldView.SetValue (0, 1, 0.0);
aWorldView.SetValue (1, 1, 1.0);
aWorldView.SetValue (2, 1, 0.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));
aWorldView.SetValue (0, 2, 0.0);
aWorldView.SetValue (1, 2, 0.0);
aWorldView.SetValue (2, 2, 1.0);
}
if ((myMode & Graphic3d_TMF_ZoomPers) != 0)
@ -438,8 +434,9 @@ void Graphic3d_TransformPers::Apply (const Handle(Graphic3d_Camera)& theCamera,
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));
Graphic3d_TransformUtils::Scale (aWorldView, aScale, aScale, aScale);
}
theWorldView.ConvertFrom (aWorldView);
return;
}
}
@ -465,9 +462,9 @@ void Graphic3d_TransformPers::Apply (const Handle(Graphic3d_Camera)& theCamera,
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);
typename BVH_Box<T, 3>::BVH_VecNt aMin (aXmin, aYmin, aZmin);
typename BVH_Box<T, 3>::BVH_VecNt aMax (aXmax, aYmax, aZmax);
BVH_Box<T, 3> aBBox (aMin, aMax);
Apply (theCamera, theProjection, theWorldView, theViewportWidth, theViewportHeight, aBBox);
@ -486,7 +483,7 @@ void Graphic3d_TransformPers::Apply (const Handle(Graphic3d_Camera)& theCamera,
const NCollection_Mat4<T>& theWorldView,
const Standard_Integer theViewportWidth,
const Standard_Integer theViewportHeight,
BVH_Box<T, 4>& theBoundingBox) const
BVH_Box<T, 3>& theBoundingBox) const
{
NCollection_Mat4<T> aTPers = Compute (theCamera, theProjection, theWorldView, theViewportWidth, theViewportHeight);
if (aTPers.IsIdentity()
@ -495,8 +492,8 @@ void Graphic3d_TransformPers::Apply (const Handle(Graphic3d_Camera)& theCamera,
return;
}
const typename BVH_Box<T, 4>::BVH_VecNt& aMin = theBoundingBox.CornerMin();
const typename BVH_Box<T, 4>::BVH_VecNt& aMax = theBoundingBox.CornerMax();
const typename BVH_Box<T, 3>::BVH_VecNt& aMin = theBoundingBox.CornerMin();
const typename BVH_Box<T, 3>::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));
@ -514,7 +511,7 @@ void Graphic3d_TransformPers::Apply (const Handle(Graphic3d_Camera)& theCamera,
typename BVH_Box<T, 4>::BVH_VecNt& aCorner = anArrayOfCorners[anIt];
aCorner = aTPers * aCorner;
aCorner /= aCorner.w();
theBoundingBox.Add (aCorner);
theBoundingBox.Add (aCorner.xyz());
}
}

View File

@ -14,7 +14,10 @@
#ifndef _Graphic3d_ZLayerSettings_HeaderFile
#define _Graphic3d_ZLayerSettings_HeaderFile
#include <Standard_TypeDef.hxx>
#include <gp_XYZ.hxx>
#include <Geom_Transformation.hxx>
#include <Graphic3d_PolygonOffset.hxx>
#include <TCollection_AsciiString.hxx>
enum Graphic3d_ZLayerSetting
{
@ -30,58 +33,141 @@ struct Graphic3d_ZLayerSettings
//! Default settings.
Graphic3d_ZLayerSettings()
: DepthOffsetFactor (1.0f),
DepthOffsetUnits (1.0f),
Flags (Graphic3d_ZLayerDepthTest
| Graphic3d_ZLayerDepthWrite
| Graphic3d_ZLayerDepthClear),
IsImmediate (false),
UseEnvironmentTexture (true)
{}
: myIsImmediate (Standard_False),
myUseEnvironmentTexture (Standard_True),
myToEnableDepthTest (Standard_True),
myToEnableDepthWrite(Standard_True),
myToClearDepth (Standard_True) {}
//! Return user-provided name.
const TCollection_AsciiString& Name() const { return myName; }
//! Set custom name.
void SetName (const TCollection_AsciiString& theName) { myName = theName; }
//! Return the origin of all objects within the layer.
const gp_XYZ& Origin() const { return myOrigin; }
//! Return the transformation to the origin.
const Handle(Geom_Transformation)& OriginTransformation() const { return myOriginTrsf; }
//! Set the origin of all objects within the layer.
void SetOrigin (const gp_XYZ& theOrigin)
{
myOrigin = theOrigin;
myOriginTrsf.Nullify();
if (!theOrigin.IsEqual (gp_XYZ(0.0, 0.0, 0.0), gp::Resolution()))
{
myOriginTrsf = new Geom_Transformation();
}
}
//! Return true if this layer should be drawn after all normal (non-immediate) layers.
Standard_Boolean IsImmediate() const { return myIsImmediate; }
//! Set the flag indicating the immediate layer, which should be drawn after all normal (non-immediate) layers.
void SetImmediate (const Standard_Boolean theValue) { myIsImmediate = theValue; }
//! Return flag to allow/prevent environment texture mapping usage for specific layer.
Standard_Boolean UseEnvironmentTexture() const { return myUseEnvironmentTexture; }
//! Set the flag to allow/prevent environment texture mapping usage for specific layer.
void SetEnvironmentTexture (const Standard_Boolean theValue) { myUseEnvironmentTexture = theValue; }
//! Return true if depth test should be enabled.
Standard_Boolean ToEnableDepthTest() const { return myToEnableDepthTest; }
//! Set if depth test should be enabled.
void SetEnableDepthTest(const Standard_Boolean theValue) { myToEnableDepthTest = theValue; }
//! Return true depth values should be written during rendering.
Standard_Boolean ToEnableDepthWrite() const { return myToEnableDepthWrite; }
//! Set if depth values should be written during rendering.
void SetEnableDepthWrite (const Standard_Boolean theValue) { myToEnableDepthWrite = theValue; }
//! Return true if depth values should be cleared before drawing the layer.
Standard_Boolean ToClearDepth() const { return myToClearDepth; }
//! Set if depth values should be cleared before drawing the layer.
void SetClearDepth (const Standard_Boolean theValue) { myToClearDepth = theValue; }
//! Return glPolygonOffset() arguments.
const Graphic3d_PolygonOffset& PolygonOffset() const { return myPolygonOffset; }
//! Setup glPolygonOffset() arguments.
void SetPolygonOffset (const Graphic3d_PolygonOffset& theParams) { myPolygonOffset = theParams; }
//! Modify glPolygonOffset() arguments.
Graphic3d_PolygonOffset& ChangePolygonOffset() { return myPolygonOffset; }
//! Returns true if theSetting is enabled.
Standard_DEPRECATED("Deprecated method IsSettingEnabled() should be replaced by individual property getters")
Standard_Boolean IsSettingEnabled (const Graphic3d_ZLayerSetting theSetting) const
{
return (Flags & theSetting) == theSetting;
switch (theSetting)
{
case Graphic3d_ZLayerDepthTest: return myToEnableDepthTest;
case Graphic3d_ZLayerDepthWrite: return myToEnableDepthWrite;
case Graphic3d_ZLayerDepthClear: return myToClearDepth;
case Graphic3d_ZLayerDepthOffset: return myPolygonOffset.Mode != Aspect_POM_Off;
}
return Standard_False;
}
//! Enables theSetting
Standard_DEPRECATED("Deprecated method EnableSetting() should be replaced by individual property getters")
void EnableSetting (const Graphic3d_ZLayerSetting theSetting)
{
Flags = Flags | theSetting;
switch (theSetting)
{
case Graphic3d_ZLayerDepthTest: myToEnableDepthTest = Standard_True; return;
case Graphic3d_ZLayerDepthWrite: myToEnableDepthWrite = Standard_True; return;
case Graphic3d_ZLayerDepthClear: myToClearDepth = Standard_True; return;
case Graphic3d_ZLayerDepthOffset: myPolygonOffset.Mode = Aspect_POM_Fill; return;
}
}
//! Disables theSetting
Standard_DEPRECATED("Deprecated method DisableSetting() should be replaced by individual property getters")
void DisableSetting (const Graphic3d_ZLayerSetting theSetting)
{
Flags = Flags & (~theSetting);
switch (theSetting)
{
case Graphic3d_ZLayerDepthTest: myToEnableDepthTest = Standard_False; return;
case Graphic3d_ZLayerDepthWrite: myToEnableDepthWrite = Standard_False; return;
case Graphic3d_ZLayerDepthClear: myToClearDepth = Standard_False; return;
case Graphic3d_ZLayerDepthOffset: myPolygonOffset.Mode = Aspect_POM_Off; return;
}
}
//! Sets minimal possible positive depth offset.
//! Access DepthOffsetFactor and DepthOffsetUnits values for manual offset control.
void SetDepthOffsetPositive()
{
DepthOffsetFactor = 1.f;
DepthOffsetUnits = 1.f;
EnableSetting (Graphic3d_ZLayerDepthOffset);
myPolygonOffset.Mode = Aspect_POM_Fill;
myPolygonOffset.Factor = 1.0f;
myPolygonOffset.Units = 1.0f;
}
//! Sets minimal possible negative depth offset.
//! Access DepthOffsetFactor and DepthOffsetUnits values for manual offset control.
void SetDepthOffsetNegative()
{
DepthOffsetFactor = 1.f;
DepthOffsetUnits = -1.f;
EnableSetting (Graphic3d_ZLayerDepthOffset);
myPolygonOffset.Mode = Aspect_POM_Fill;
myPolygonOffset.Factor = 1.0f;
myPolygonOffset.Units =-1.0f;
}
public:
protected:
Standard_ShortReal DepthOffsetFactor; //!< factor argument value for OpenGl glPolygonOffset function
Standard_ShortReal DepthOffsetUnits; //!< units argument value for OpenGl glPolygonOffset function
Standard_Integer Flags; //!< storage field for settings
bool IsImmediate; //!< immediate layer will be drawn after all normal layers
bool UseEnvironmentTexture; //!< flag to allow/prevent environment texture mapping usage for specific layer
TCollection_AsciiString myName; //!< user-provided name
Handle(Geom_Transformation) myOriginTrsf; //!< transformation to the origin
gp_XYZ myOrigin; //!< the origin of all objects within the layer
Graphic3d_PolygonOffset myPolygonOffset; //!< glPolygonOffset() arguments
Standard_Boolean myIsImmediate; //!< immediate layer will be drawn after all normal layers
Standard_Boolean myUseEnvironmentTexture; //!< flag to allow/prevent environment texture mapping usage for specific layer
Standard_Boolean myToEnableDepthTest; //!< option to enable depth test
Standard_Boolean myToEnableDepthWrite; //!< option to enable write depth values
Standard_Boolean myToClearDepth; //!< option to clear depth values before drawing the layer
};

View File

@ -24,7 +24,7 @@
// =======================================================================
OpenGl_BVHClipPrimitiveSet::OpenGl_BVHClipPrimitiveSet()
{
myBuilder = new BVH_BinnedBuilder<Standard_ShortReal, 4> (1, 32);
myBuilder = new BVH_BinnedBuilder<Standard_Real, 3> (1, 32);
}
// =======================================================================
@ -40,7 +40,7 @@ Standard_Integer OpenGl_BVHClipPrimitiveSet::Size() const
// function : Box
// purpose :
// =======================================================================
Graphic3d_BndBox4f OpenGl_BVHClipPrimitiveSet::Box (const Standard_Integer theIdx) const
Graphic3d_BndBox3d OpenGl_BVHClipPrimitiveSet::Box (const Standard_Integer theIdx) const
{
return myStructs.FindKey (theIdx + 1)->BoundingBox();
}
@ -49,22 +49,15 @@ Graphic3d_BndBox4f OpenGl_BVHClipPrimitiveSet::Box (const Standard_Integer theId
// function : Center
// purpose :
// =======================================================================
Standard_ShortReal OpenGl_BVHClipPrimitiveSet::Center (const Standard_Integer theIdx,
const Standard_Integer theAxis) const
Standard_Real OpenGl_BVHClipPrimitiveSet::Center (const Standard_Integer theIdx,
const Standard_Integer theAxis) const
{
Graphic3d_BndBox4f aBndBox = myStructs.FindKey (theIdx + 1)->BoundingBox();
Graphic3d_BndBox3d aBndBox = myStructs.FindKey (theIdx + 1)->BoundingBox();
// to prevent float overflow
const Standard_Real aMin = Standard_Real (aBndBox.CornerMin()[theAxis]);
const Standard_Real aMax = Standard_Real (aBndBox.CornerMax()[theAxis]);
const Standard_Real aMin = aBndBox.CornerMin()[theAxis];
const Standard_Real aMax = aBndBox.CornerMax()[theAxis];
const Standard_Real aCenter = (aMin + aMax) * 0.5;
if (aCenter <= Standard_Real (-ShortRealLast()))
return -ShortRealLast();
if (aCenter >= Standard_Real (ShortRealLast()))
return ShortRealLast();
return Standard_ShortReal (aCenter);
return aCenter;
}
// =======================================================================

View File

@ -23,11 +23,11 @@
#include <OpenGl_Structure.hxx>
//! Set of OpenGl_Structures for building BVH tree.
class OpenGl_BVHClipPrimitiveSet : public BVH_PrimitiveSet<Standard_ShortReal, 4>
class OpenGl_BVHClipPrimitiveSet : public BVH_PrimitiveSet<Standard_Real, 3>
{
protected:
using BVH_PrimitiveSet<Standard_ShortReal, 4>::Box;
using BVH_PrimitiveSet<Standard_Real, 3>::Box;
public:
@ -38,11 +38,11 @@ public:
virtual Standard_Integer Size() const;
//! Returns AABB of the structure.
virtual Graphic3d_BndBox4f Box (const Standard_Integer theIdx) const;
virtual Graphic3d_BndBox3d Box (const Standard_Integer theIdx) const;
//! Calculates center of the AABB along given axis.
virtual Standard_ShortReal Center (const Standard_Integer theIdx,
const Standard_Integer theAxis) const;
virtual Standard_Real Center (const Standard_Integer theIdx,
const Standard_Integer theAxis) const;
//! Swaps structures with the given indices.
virtual void Swap (const Standard_Integer theIdx1,

View File

@ -22,9 +22,9 @@
// =======================================================================
OpenGl_BVHClipPrimitiveTrsfPersSet::OpenGl_BVHClipPrimitiveTrsfPersSet()
: myIsDirty (Standard_False),
myBVH (new BVH_Tree<Standard_ShortReal, 4>())
myBVH (new BVH_Tree<Standard_Real, 3>())
{
myBuilder = new BVH_LinearBuilder<Standard_ShortReal, 4> (1, 32);
myBuilder = new BVH_LinearBuilder<Standard_Real, 3> (1, 32);
}
// =======================================================================
@ -40,7 +40,7 @@ Standard_Integer OpenGl_BVHClipPrimitiveTrsfPersSet::Size() const
// function : Box
// purpose :
// =======================================================================
Graphic3d_BndBox4f OpenGl_BVHClipPrimitiveTrsfPersSet::Box (const Standard_Integer theIdx) const
Graphic3d_BndBox3d OpenGl_BVHClipPrimitiveTrsfPersSet::Box (const Standard_Integer theIdx) const
{
return *myStructBoxes (theIdx + 1);
}
@ -49,12 +49,11 @@ Graphic3d_BndBox4f OpenGl_BVHClipPrimitiveTrsfPersSet::Box (const Standard_Integ
// function : Center
// purpose :
// =======================================================================
Standard_ShortReal OpenGl_BVHClipPrimitiveTrsfPersSet::Center (const Standard_Integer theIdx,
const Standard_Integer theAxis) const
Standard_Real 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;
const Graphic3d_BndBox3d& aBndBox = *myStructBoxes (theIdx + 1);
return (aBndBox.CornerMin()[theAxis] + aBndBox.CornerMax()[theAxis]) * 0.5;
}
// =======================================================================
@ -132,10 +131,10 @@ const OpenGl_Structure* OpenGl_BVHClipPrimitiveTrsfPersSet::GetStructureById (St
// function : BVH
// purpose :
//=======================================================================
const NCollection_Handle<BVH_Tree<Standard_ShortReal, 4> >&
const NCollection_Handle<BVH_Tree<Standard_Real, 3> >&
OpenGl_BVHClipPrimitiveTrsfPersSet::BVH (const Handle(Graphic3d_Camera)& theCamera,
const OpenGl_Mat4& theProjectionMatrix,
const OpenGl_Mat4& theWorldViewMatrix,
const OpenGl_Mat4d& theProjectionMatrix,
const OpenGl_Mat4d& theWorldViewMatrix,
const Standard_Integer theViewportWidth,
const Standard_Integer theViewportHeight,
const Graphic3d_WorldViewProjState& theWVPState)
@ -153,7 +152,7 @@ const NCollection_Handle<BVH_Tree<Standard_ShortReal, 4> >&
{
const OpenGl_Structure* aStructure = myStructs (aStructIdx);
HBndBox4f aBoundingBox = new Graphic3d_BndBox4f;
Handle(HBndBox3d) aBoundingBox = new HBndBox3d();
*aBoundingBox = aStructure->BoundingBox();
if (!aStructure->TransformPersistence().IsNull())
{
@ -163,7 +162,7 @@ const NCollection_Handle<BVH_Tree<Standard_ShortReal, 4> >&
myStructBoxes.Add (aBoundingBox);
}
myBuilder->Build (this, myBVH.operator->(), BVH_Set<Standard_ShortReal, 4>::Box());
myBuilder->Build (this, myBVH.operator->(), BVH_Set<Standard_Real, 3>::Box());
myStructBoxesState = theWVPState;
myStructBoxes.Clear();

View File

@ -21,7 +21,7 @@
#include <BVH_Tree.hxx>
#include <Graphic3d_BndBox4f.hxx>
#include <Graphic3d_WorldViewProjState.hxx>
#include <NCollection_Handle.hxx>
#include <NCollection_Shared.hxx>
#include <NCollection_IndexedMap.hxx>
#include <OpenGl_Structure.hxx>
#include <OpenGl_Vec.hxx>
@ -30,11 +30,11 @@
//! 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>
class OpenGl_BVHClipPrimitiveTrsfPersSet : public BVH_Set<Standard_Real, 3>
{
private:
typedef NCollection_Handle<Graphic3d_BndBox4f> HBndBox4f;
typedef NCollection_Shared<Graphic3d_BndBox3d> HBndBox3d;
public:
@ -45,11 +45,11 @@ public:
virtual Standard_Integer Size() const Standard_OVERRIDE;
//! Returns AABB of the structure.
virtual Graphic3d_BndBox4f Box (const Standard_Integer theIdx) const Standard_OVERRIDE;
virtual Graphic3d_BndBox3d 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;
virtual Standard_Real 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,
@ -76,12 +76,12 @@ public:
}
//! Returns BVH tree for the given world view projection (builds it if necessary).
const NCollection_Handle<BVH_Tree<Standard_ShortReal, 4> >& BVH (const Handle(Graphic3d_Camera)& theCamera,
const OpenGl_Mat4& theProjectionMatrix,
const OpenGl_Mat4& theWorldViewMatrix,
const Standard_Integer theViewportWidth,
const Standard_Integer theViewportHeight,
const Graphic3d_WorldViewProjState& theWVPState);
const NCollection_Handle<BVH_Tree<Standard_Real, 3> >& BVH (const Handle(Graphic3d_Camera)& theCamera,
const OpenGl_Mat4d& theProjectionMatrix,
const OpenGl_Mat4d& theWorldViewMatrix,
const Standard_Integer theViewportWidth,
const Standard_Integer theViewportHeight,
const Graphic3d_WorldViewProjState& theWVPState);
private:
@ -89,10 +89,10 @@ private:
Standard_Boolean myIsDirty;
//! Constructed bottom-level BVH.
NCollection_Handle<BVH_Tree<Standard_ShortReal, 4> > myBVH;
NCollection_Handle<BVH_Tree<Standard_Real, 3> > myBVH;
//! Builder for bottom-level BVH.
NCollection_Handle<BVH_Builder<Standard_ShortReal, 4> > myBuilder;
NCollection_Handle<BVH_Builder<Standard_Real, 3> > myBuilder;
//! Indexed map of structures.
NCollection_IndexedMap<const OpenGl_Structure*> myStructs;
@ -100,7 +100,7 @@ private:
//! 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;
NCollection_IndexedMap<Handle(HBndBox3d)> myStructBoxes;
//! State of world view projection used for generation of transformation persistence bounding boxes.
Graphic3d_WorldViewProjState myStructBoxesState;

View File

@ -41,53 +41,53 @@ void OpenGl_BVHTreeSelector::SetViewVolume (const Handle(Graphic3d_Camera)& theC
myIsProjectionParallel = theCamera->IsOrthographic();
myCamera = theCamera;
myProjectionMat = theCamera->ProjectionMatrixF();
myWorldViewMat = theCamera->OrientationMatrixF();
myProjectionMat = theCamera->ProjectionMatrix();
myWorldViewMat = theCamera->OrientationMatrix();
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;
Standard_ShortReal aNear = 0.0f, aFar = 0.0f;
Standard_Real nLeft = 0.0, nRight = 0.0, nTop = 0.0, nBottom = 0.0;
Standard_Real fLeft = 0.0, fRight = 0.0, fTop = 0.0, fBottom = 0.0;
Standard_Real aNear = 0.0, aFar = 0.0;
if (!myIsProjectionParallel)
{
// handle perspective projection
aNear = myProjectionMat.GetValue (2, 3) / (- 1.0f + myProjectionMat.GetValue (2, 2));
aFar = myProjectionMat.GetValue (2, 3) / ( 1.0f + myProjectionMat.GetValue (2, 2));
aNear = myProjectionMat.GetValue (2, 3) / (- 1.0 + myProjectionMat.GetValue (2, 2));
aFar = myProjectionMat.GetValue (2, 3) / ( 1.0 + myProjectionMat.GetValue (2, 2));
// Near plane
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);
nLeft = aNear * (myProjectionMat.GetValue (0, 2) - 1.0) / myProjectionMat.GetValue (0, 0);
nRight = aNear * (myProjectionMat.GetValue (0, 2) + 1.0) / myProjectionMat.GetValue (0, 0);
nTop = aNear * (myProjectionMat.GetValue (1, 2) + 1.0) / myProjectionMat.GetValue (1, 1);
nBottom = aNear * (myProjectionMat.GetValue (1, 2) - 1.0) / myProjectionMat.GetValue (1, 1);
// Far plane
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);
fLeft = aFar * (myProjectionMat.GetValue (0, 2) - 1.0) / myProjectionMat.GetValue (0, 0);
fRight = aFar * (myProjectionMat.GetValue (0, 2) + 1.0) / myProjectionMat.GetValue (0, 0);
fTop = aFar * (myProjectionMat.GetValue (1, 2) + 1.0) / myProjectionMat.GetValue (1, 1);
fBottom = aFar * (myProjectionMat.GetValue (1, 2) - 1.0) / myProjectionMat.GetValue (1, 1);
}
else
{
// handle orthographic projection
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);
aNear = (1.0 / myProjectionMat.GetValue (2, 2)) * (myProjectionMat.GetValue (2, 3) + 1.0);
aFar = (1.0 / myProjectionMat.GetValue (2, 2)) * (myProjectionMat.GetValue (2, 3) - 1.0);
// Near plane
nLeft = ( 1.0f + myProjectionMat.GetValue (0, 3)) / (-myProjectionMat.GetValue (0, 0));
nLeft = ( 1.0 + myProjectionMat.GetValue (0, 3)) / (-myProjectionMat.GetValue (0, 0));
fLeft = nLeft;
nRight = ( 1.0f - myProjectionMat.GetValue (0, 3)) / myProjectionMat.GetValue (0, 0);
nRight = ( 1.0 - myProjectionMat.GetValue (0, 3)) / myProjectionMat.GetValue (0, 0);
fRight = nRight;
nTop = ( 1.0f - myProjectionMat.GetValue (1, 3)) / myProjectionMat.GetValue (1, 1);
nTop = ( 1.0 - myProjectionMat.GetValue (1, 3)) / myProjectionMat.GetValue (1, 1);
fTop = nTop;
nBottom = (-1.0f - myProjectionMat.GetValue (1, 3)) / myProjectionMat.GetValue (1, 1);
nBottom = (-1.0 - myProjectionMat.GetValue (1, 3)) / myProjectionMat.GetValue (1, 1);
fBottom = nBottom;
}
OpenGl_Vec4 aLeftTopNear (nLeft, nTop, -aNear, 1.0f), aRightBottomFar (fRight, fBottom, -aFar, 1.0f);
OpenGl_Vec4 aLeftBottomNear (nLeft, nBottom, -aNear, 1.0f), aRightTopFar (fRight, fTop, -aFar, 1.0f);
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);
OpenGl_Vec4d aLeftTopNear (nLeft, nTop, -aNear, 1.0), aRightBottomFar (fRight, fBottom, -aFar, 1.0);
OpenGl_Vec4d aLeftBottomNear (nLeft, nBottom, -aNear, 1.0), aRightTopFar (fRight, fTop, -aFar, 1.0);
OpenGl_Vec4d aRightBottomNear (nRight, nBottom, -aNear, 1.0), aLeftTopFar (fLeft, fTop, -aFar, 1.0);
OpenGl_Vec4d aRightTopNear (nRight, nTop, -aNear, 1.0), aLeftBottomFar (fLeft, fBottom, -aFar, 1.0);
const OpenGl_Mat4 aViewProj = myWorldViewMat * myProjectionMat;
OpenGl_Mat4 anInvWorldView;
myWorldViewMat.Inverted(anInvWorldView);
const OpenGl_Mat4d aViewProj = myWorldViewMat * myProjectionMat;
OpenGl_Mat4d anInvWorldView;
myWorldViewMat.Inverted (anInvWorldView);
myClipVerts[ClipVert_LeftTopNear] = anInvWorldView * aLeftTopNear;
myClipVerts[ClipVert_RightBottomFar] = anInvWorldView * aRightBottomFar;
@ -107,17 +107,14 @@ void OpenGl_BVHTreeSelector::SetViewVolume (const Handle(Graphic3d_Camera)& theC
myClipPlanes[Plane_Far] = aViewProj.GetRow (3) - aViewProj.GetRow (2);
gp_Pnt aPtCenter = theCamera->Center();
OpenGl_Vec4 aCenter (static_cast<Standard_ShortReal> (aPtCenter.X()),
static_cast<Standard_ShortReal> (aPtCenter.Y()),
static_cast<Standard_ShortReal> (aPtCenter.Z()),
1.0f);
OpenGl_Vec4d aCenter (aPtCenter.X(), aPtCenter.Y(), aPtCenter.Z(), 1.0);
for (Standard_Integer aPlaneIter = 0; aPlaneIter < PlanesNB; ++aPlaneIter)
{
OpenGl_Vec4 anEq = myClipPlanes[aPlaneIter];
OpenGl_Vec4d anEq = myClipPlanes[aPlaneIter];
if (SignedPlanePointDistance (anEq, aCenter) > 0)
{
anEq *= -1.0f;
anEq *= -1.0;
myClipPlanes[aPlaneIter] = anEq;
}
}
@ -138,21 +135,21 @@ void OpenGl_BVHTreeSelector::SetViewportSize (const Standard_Integer theViewport
// function : SignedPlanePointDistance
// purpose :
// =======================================================================
Standard_ShortReal OpenGl_BVHTreeSelector::SignedPlanePointDistance (const OpenGl_Vec4& theNormal,
const OpenGl_Vec4& thePnt)
Standard_Real OpenGl_BVHTreeSelector::SignedPlanePointDistance (const OpenGl_Vec4d& theNormal,
const OpenGl_Vec4d& thePnt)
{
const Standard_ShortReal aNormLength = std::sqrt (theNormal.x() * theNormal.x()
+ theNormal.y() * theNormal.y()
+ theNormal.z() * theNormal.z());
const Standard_Real aNormLength = std::sqrt (theNormal.x() * theNormal.x()
+ theNormal.y() * theNormal.y()
+ theNormal.z() * theNormal.z());
if (aNormLength < FLT_EPSILON)
return 0.0f;
if (aNormLength < gp::Resolution())
return 0.0;
const Standard_ShortReal anInvNormLength = 1.0f / aNormLength;
const Standard_ShortReal aD = theNormal.w() * anInvNormLength;
const Standard_ShortReal anA = theNormal.x() * anInvNormLength;
const Standard_ShortReal aB = theNormal.y() * anInvNormLength;
const Standard_ShortReal aC = theNormal.z() * anInvNormLength;
const Standard_Real anInvNormLength = 1.0 / aNormLength;
const Standard_Real aD = theNormal.w() * anInvNormLength;
const Standard_Real anA = theNormal.x() * anInvNormLength;
const Standard_Real aB = theNormal.y() * anInvNormLength;
const Standard_Real aC = theNormal.z() * anInvNormLength;
return aD + (anA * thePnt.x() + aB * thePnt.y() + aC * thePnt.z());
}
@ -166,14 +163,14 @@ void OpenGl_BVHTreeSelector::CacheClipPtsProjections()
const Standard_Integer anIncFactor = myIsProjectionParallel ? 2 : 1;
for (Standard_Integer aPlaneIter = 0; aPlaneIter < 5; aPlaneIter += anIncFactor)
{
const OpenGl_Vec4 aPlane = myClipPlanes[aPlaneIter];
Standard_ShortReal aMaxProj = -std::numeric_limits<Standard_ShortReal>::max();
Standard_ShortReal aMinProj = std::numeric_limits<Standard_ShortReal>::max();
const OpenGl_Vec4d aPlane = myClipPlanes[aPlaneIter];
Standard_Real aMaxProj = -std::numeric_limits<Standard_Real>::max();
Standard_Real aMinProj = std::numeric_limits<Standard_Real>::max();
for (Standard_Integer aCornerIter = 0; aCornerIter < ClipVerticesNB; ++aCornerIter)
{
Standard_ShortReal aProjection = aPlane.x() * myClipVerts[aCornerIter].x() +
aPlane.y() * myClipVerts[aCornerIter].y() +
aPlane.z() * myClipVerts[aCornerIter].z();
Standard_Real aProjection = aPlane.x() * myClipVerts[aCornerIter].x()
+ aPlane.y() * myClipVerts[aCornerIter].y()
+ aPlane.z() * myClipVerts[aCornerIter].z();
aMaxProj = Max (aProjection, aMaxProj);
aMinProj = Min (aProjection, aMinProj);
}
@ -183,12 +180,15 @@ void OpenGl_BVHTreeSelector::CacheClipPtsProjections()
for (Standard_Integer aDim = 0; aDim < 3; ++aDim)
{
Standard_ShortReal aMaxProj = -std::numeric_limits<Standard_ShortReal>::max();
Standard_ShortReal aMinProj = std::numeric_limits<Standard_ShortReal>::max();
Standard_Real aMaxProj = -std::numeric_limits<Standard_Real>::max();
Standard_Real aMinProj = std::numeric_limits<Standard_Real>::max();
for (Standard_Integer aCornerIter = 0; aCornerIter < ClipVerticesNB; ++aCornerIter)
{
Standard_ShortReal aProjection = aDim == 0 ? myClipVerts[aCornerIter].x()
: (aDim == 1 ? myClipVerts[aCornerIter].y() : myClipVerts[aCornerIter].z());
Standard_Real aProjection = aDim == 0
? myClipVerts[aCornerIter].x()
: (aDim == 1
? myClipVerts[aCornerIter].y()
: myClipVerts[aCornerIter].z());
aMaxProj = Max (aProjection, aMaxProj);
aMinProj = Min (aProjection, aMinProj);
}
@ -201,8 +201,8 @@ void OpenGl_BVHTreeSelector::CacheClipPtsProjections()
// function : Intersect
// purpose : Detects if AABB overlaps view volume using separating axis theorem (SAT)
// =======================================================================
Standard_Boolean OpenGl_BVHTreeSelector::Intersect (const OpenGl_Vec4& theMinPt,
const OpenGl_Vec4& theMaxPt) const
Standard_Boolean OpenGl_BVHTreeSelector::Intersect (const OpenGl_Vec3d& theMinPt,
const OpenGl_Vec3d& theMaxPt) const
{
// E1
// |_ E0
@ -230,23 +230,23 @@ Standard_Boolean OpenGl_BVHTreeSelector::Intersect (const OpenGl_Vec4& theMinPt,
return Standard_False;
}
Standard_ShortReal aBoxProjMax = 0.0f, aBoxProjMin = 0.0f;
Standard_Real aBoxProjMax = 0.0, aBoxProjMin = 0.0;
const Standard_Integer anIncFactor = myIsProjectionParallel ? 2 : 1;
for (Standard_Integer aPlaneIter = 0; aPlaneIter < 5; aPlaneIter += anIncFactor)
{
OpenGl_Vec4 aPlane = myClipPlanes[aPlaneIter];
aBoxProjMax = (aPlane.x() > 0.f ? (aPlane.x() * theMaxPt.x()) : aPlane.x() * theMinPt.x()) +
(aPlane.y() > 0.f ? (aPlane.y() * theMaxPt.y()) : aPlane.y() * theMinPt.y()) +
(aPlane.z() > 0.f ? (aPlane.z() * theMaxPt.z()) : aPlane.z() * theMinPt.z());
OpenGl_Vec4d aPlane = myClipPlanes[aPlaneIter];
aBoxProjMax = (aPlane.x() > 0.0 ? (aPlane.x() * theMaxPt.x()) : aPlane.x() * theMinPt.x())
+ (aPlane.y() > 0.0 ? (aPlane.y() * theMaxPt.y()) : aPlane.y() * theMinPt.y())
+ (aPlane.z() > 0.0 ? (aPlane.z() * theMaxPt.z()) : aPlane.z() * theMinPt.z());
if (aBoxProjMax > myMinClipProjectionPts[aPlaneIter]
&& aBoxProjMax < myMaxClipProjectionPts[aPlaneIter])
{
continue;
}
aBoxProjMin = (aPlane.x() < 0.f ? aPlane.x() * theMaxPt.x() : aPlane.x() * theMinPt.x()) +
(aPlane.y() < 0.f ? aPlane.y() * theMaxPt.y() : aPlane.y() * theMinPt.y()) +
(aPlane.z() < 0.f ? aPlane.z() * theMaxPt.z() : aPlane.z() * theMinPt.z());
aBoxProjMin = (aPlane.x() < 0.0 ? aPlane.x() * theMaxPt.x() : aPlane.x() * theMinPt.x())
+ (aPlane.y() < 0.0 ? aPlane.y() * theMaxPt.y() : aPlane.y() * theMinPt.y())
+ (aPlane.z() < 0.0 ? aPlane.z() * theMaxPt.z() : aPlane.z() * theMinPt.z());
if (aBoxProjMin > myMaxClipProjectionPts[aPlaneIter]
|| aBoxProjMax < myMinClipProjectionPts[aPlaneIter])
{

View File

@ -39,8 +39,8 @@ public:
//! @param theMinPt [in] maximum point of AABB.
//! @param theMaxPt [in] minimum point of AABB.
//! @return Standard_True, if AABB is in viewing area, Standard_False otherwise.
Standard_EXPORT Standard_Boolean Intersect (const OpenGl_Vec4& theMinPt,
const OpenGl_Vec4& theMaxPt) const;
Standard_EXPORT Standard_Boolean Intersect (const OpenGl_Vec3d& theMinPt,
const OpenGl_Vec3d& theMaxPt) const;
//! Caches view volume's vertices projections along its normals and AABBs dimensions.
//! Must be called at the beginning of each BVH tree traverse loop.
@ -50,13 +50,13 @@ public:
const Handle(Graphic3d_Camera)& Camera() const { return myCamera; }
//! Returns current projection matrix.
const OpenGl_Mat4& ProjectionMatrix() const
const OpenGl_Mat4d& ProjectionMatrix() const
{
return myProjectionMat;
}
//! Returns current world view transformation matrix.
const OpenGl_Mat4& WorldViewMatrix() const
const OpenGl_Mat4d& WorldViewMatrix() const
{
return myWorldViewMat;
}
@ -82,8 +82,8 @@ protected:
//! Calculates signed distance from plane to point.
//! @param theNormal [in] the plane's normal.
//! @param thePnt [in]
Standard_EXPORT Standard_ShortReal SignedPlanePointDistance (const OpenGl_Vec4& theNormal,
const OpenGl_Vec4& thePnt);
Standard_EXPORT Standard_Real SignedPlanePointDistance (const OpenGl_Vec4d& theNormal,
const OpenGl_Vec4d& thePnt);
protected:
@ -115,25 +115,25 @@ protected:
protected:
OpenGl_Vec4 myClipPlanes[PlanesNB]; //!< Plane equations
OpenGl_Vec4 myClipVerts[ClipVerticesNB]; //!< Vertices
OpenGl_Vec4d myClipPlanes[PlanesNB]; //!< Plane equations
OpenGl_Vec4d myClipVerts[ClipVerticesNB]; //!< Vertices
Handle(Graphic3d_Camera) myCamera; //!< camera definition
// for caching clip points projections onto viewing area normals once per traverse
// ORDER: TOP, BOTTOM, LEFT, RIGHT, NEAR, FAR
Standard_ShortReal myMaxClipProjectionPts[PlanesNB]; //!< Max view volume's vertices projections onto its normals
Standard_ShortReal myMinClipProjectionPts[PlanesNB]; //!< Min view volume's vertices projections onto its normals
Standard_Real myMaxClipProjectionPts[PlanesNB]; //!< Max view volume's vertices projections onto its normals
Standard_Real myMinClipProjectionPts[PlanesNB]; //!< Min view volume's vertices projections onto its normals
// 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_Real myMaxOrthoProjectionPts[3]; //!< Max view volume's vertices projections onto normalized dimensions of AABB
Standard_Real myMinOrthoProjectionPts[3]; //!< Min view volume's vertices projections onto normalized dimensions of AABB
Standard_Boolean myIsProjectionParallel;
OpenGl_Mat4 myProjectionMat;
OpenGl_Mat4 myWorldViewMat;
OpenGl_Mat4d myProjectionMat;
OpenGl_Mat4d myWorldViewMat;
Standard_Integer myViewportWidth;
Standard_Integer myViewportHeight;

View File

@ -101,46 +101,70 @@ OpenGl_GraphicDriver::OpenGl_GraphicDriver (const Handle(Aspect_DisplayConnectio
}
// default layers are always presented in display layer sequence it can not be removed
Graphic3d_ZLayerSettings anUnderlaySettings;
anUnderlaySettings.Flags = 0;
anUnderlaySettings.IsImmediate = false;
anUnderlaySettings.UseEnvironmentTexture = false;
myLayerIds.Add (Graphic3d_ZLayerId_BotOSD);
myLayerSeq.Append (Graphic3d_ZLayerId_BotOSD);
myMapOfZLayerSettings.Bind (Graphic3d_ZLayerId_BotOSD, anUnderlaySettings);
{
Graphic3d_ZLayerSettings aSettings;
aSettings.SetImmediate (Standard_False);
aSettings.SetEnvironmentTexture (Standard_False);
aSettings.SetEnableDepthTest (Standard_False);
aSettings.SetEnableDepthWrite (Standard_False);
aSettings.SetClearDepth (Standard_False);
aSettings.SetPolygonOffset (Graphic3d_PolygonOffset());
myLayerIds.Add (Graphic3d_ZLayerId_BotOSD);
myLayerSeq.Append (Graphic3d_ZLayerId_BotOSD);
myMapOfZLayerSettings.Bind (Graphic3d_ZLayerId_BotOSD, aSettings);
}
Graphic3d_ZLayerSettings aDefSettings;
aDefSettings.Flags = Graphic3d_ZLayerDepthTest
| Graphic3d_ZLayerDepthWrite;
aDefSettings.IsImmediate = false;
myLayerIds.Add (Graphic3d_ZLayerId_Default);
myLayerSeq.Append (Graphic3d_ZLayerId_Default);
myMapOfZLayerSettings.Bind (Graphic3d_ZLayerId_Default, aDefSettings);
{
Graphic3d_ZLayerSettings aSettings;
aSettings.SetImmediate (Standard_False);
aSettings.SetEnvironmentTexture (Standard_True);
aSettings.SetEnableDepthTest (Standard_True);
aSettings.SetEnableDepthWrite (Standard_True);
aSettings.SetClearDepth (Standard_False);
aSettings.SetPolygonOffset (Graphic3d_PolygonOffset());
myLayerIds.Add (Graphic3d_ZLayerId_Default);
myLayerSeq.Append (Graphic3d_ZLayerId_Default);
myMapOfZLayerSettings.Bind (Graphic3d_ZLayerId_Default, aSettings);
}
Graphic3d_ZLayerSettings aTopSettings;
aTopSettings.Flags = Graphic3d_ZLayerDepthTest
| Graphic3d_ZLayerDepthWrite;
aTopSettings.IsImmediate = true;
myLayerIds.Add (Graphic3d_ZLayerId_Top);
myLayerSeq.Append (Graphic3d_ZLayerId_Top);
myMapOfZLayerSettings.Bind (Graphic3d_ZLayerId_Top, aTopSettings);
{
Graphic3d_ZLayerSettings aSettings;
aSettings.SetImmediate (Standard_True);
aSettings.SetEnvironmentTexture (Standard_True);
aSettings.SetEnableDepthTest (Standard_True);
aSettings.SetEnableDepthWrite (Standard_True);
aSettings.SetClearDepth (Standard_False);
aSettings.SetPolygonOffset (Graphic3d_PolygonOffset());
myLayerIds.Add (Graphic3d_ZLayerId_Top);
myLayerSeq.Append (Graphic3d_ZLayerId_Top);
myMapOfZLayerSettings.Bind (Graphic3d_ZLayerId_Top, aSettings);
}
Graphic3d_ZLayerSettings aTopmostSettings;
aTopmostSettings.Flags = Graphic3d_ZLayerDepthTest
| Graphic3d_ZLayerDepthWrite
| Graphic3d_ZLayerDepthClear;
aTopmostSettings.IsImmediate = true;
myLayerIds.Add (Graphic3d_ZLayerId_Topmost);
myLayerSeq.Append (Graphic3d_ZLayerId_Topmost);
myMapOfZLayerSettings.Bind (Graphic3d_ZLayerId_Topmost, aTopmostSettings);
{
Graphic3d_ZLayerSettings aSettings;
aSettings.SetImmediate (Standard_True);
aSettings.SetEnvironmentTexture (Standard_True);
aSettings.SetEnableDepthTest (Standard_True);
aSettings.SetEnableDepthWrite (Standard_True);
aSettings.SetClearDepth (Standard_True);
aSettings.SetPolygonOffset (Graphic3d_PolygonOffset());
myLayerIds.Add (Graphic3d_ZLayerId_Topmost);
myLayerSeq.Append (Graphic3d_ZLayerId_Topmost);
myMapOfZLayerSettings.Bind (Graphic3d_ZLayerId_Topmost, aSettings);
}
Graphic3d_ZLayerSettings anOsdSettings;
anOsdSettings.Flags = 0;
anOsdSettings.IsImmediate = true;
anOsdSettings.UseEnvironmentTexture = false;
myLayerIds.Add (Graphic3d_ZLayerId_TopOSD);
myLayerSeq.Append (Graphic3d_ZLayerId_TopOSD);
myMapOfZLayerSettings.Bind (Graphic3d_ZLayerId_TopOSD, anOsdSettings);
{
Graphic3d_ZLayerSettings aSettings;
aSettings.SetImmediate (Standard_True);
aSettings.SetEnvironmentTexture (Standard_False);
aSettings.SetEnableDepthTest (Standard_False);
aSettings.SetEnableDepthWrite (Standard_False);
aSettings.SetClearDepth (Standard_False);
aSettings.SetPolygonOffset (Graphic3d_PolygonOffset());
myLayerIds.Add (Graphic3d_ZLayerId_TopOSD);
myLayerSeq.Append (Graphic3d_ZLayerId_TopOSD);
myMapOfZLayerSettings.Bind (Graphic3d_ZLayerId_TopOSD, aSettings);
}
}
// =======================================================================
@ -511,7 +535,7 @@ void OpenGl_GraphicDriver::addZLayerIndex (const Graphic3d_ZLayerId theLayerId)
}
}
if (myMapOfZLayerSettings.Find (theLayerId).IsImmediate)
if (myMapOfZLayerSettings.Find (theLayerId).IsImmediate())
{
myLayerSeq.Append (theLayerId);
return;
@ -520,7 +544,7 @@ void OpenGl_GraphicDriver::addZLayerIndex (const Graphic3d_ZLayerId theLayerId)
for (TColStd_SequenceOfInteger::Iterator aLayerIt (myLayerSeq); aLayerIt.More(); aLayerIt.Next())
{
const Graphic3d_ZLayerSettings& aSettings = myMapOfZLayerSettings.Find (aLayerIt.Value());
if (aSettings.IsImmediate)
if (aSettings.IsImmediate())
{
aLayerIt.Previous();
if (aLayerIt.More())
@ -627,17 +651,10 @@ void OpenGl_GraphicDriver::ZLayers (TColStd_SequenceOfInteger& theLayerSeq) cons
void OpenGl_GraphicDriver::SetZLayerSettings (const Graphic3d_ZLayerId theLayerId,
const Graphic3d_ZLayerSettings& theSettings)
{
// Change Z layer settings in all managed views
NCollection_Map<Handle(OpenGl_View)>::Iterator aViewIt (myMapOfView);
for (; aViewIt.More(); aViewIt.Next())
{
aViewIt.Value()->SetZLayerSettings (theLayerId, theSettings);
}
Graphic3d_ZLayerSettings* aSettings = myMapOfZLayerSettings.ChangeSeek (theLayerId);
if (aSettings != NULL)
{
const bool isChanged = (aSettings->IsImmediate != theSettings.IsImmediate);
const bool isChanged = (aSettings->IsImmediate() != theSettings.IsImmediate());
*aSettings = theSettings;
if (isChanged)
{
@ -650,13 +667,19 @@ void OpenGl_GraphicDriver::SetZLayerSettings (const Graphic3d_ZLayerId theLayerI
myMapOfZLayerSettings.Bind (theLayerId, theSettings);
addZLayerIndex (theLayerId);
}
// Change Z layer settings in all managed views
for (NCollection_Map<Handle(OpenGl_View)>::Iterator aViewIt (myMapOfView); aViewIt.More(); aViewIt.Next())
{
aViewIt.Value()->SetZLayerSettings (theLayerId, theSettings);
}
}
//=======================================================================
//function : ZLayerSettings
//purpose :
//=======================================================================
Graphic3d_ZLayerSettings OpenGl_GraphicDriver::ZLayerSettings (const Graphic3d_ZLayerId theLayerId)
const Graphic3d_ZLayerSettings& OpenGl_GraphicDriver::ZLayerSettings (const Graphic3d_ZLayerId theLayerId) const
{
Standard_ASSERT_RAISE (myLayerIds.Contains (theLayerId),
"OpenGl_GraphicDriver::ZLayerSettings, "

View File

@ -157,7 +157,7 @@ public:
Standard_EXPORT void SetZLayerSettings (const Graphic3d_ZLayerId theLayerId, const Graphic3d_ZLayerSettings& theSettings) Standard_OVERRIDE;
//! Returns the settings of a single Z layer.
Standard_EXPORT virtual Graphic3d_ZLayerSettings ZLayerSettings (const Graphic3d_ZLayerId theLayerId) Standard_OVERRIDE;
Standard_EXPORT virtual const Graphic3d_ZLayerSettings& ZLayerSettings (const Graphic3d_ZLayerId theLayerId) const Standard_OVERRIDE;
public:

View File

@ -17,6 +17,7 @@
#include <OpenGl_BVHTreeSelector.hxx>
#include <OpenGl_Structure.hxx>
#include <OpenGl_ShaderManager.hxx>
#include <OpenGl_View.hxx>
#include <OpenGl_Workspace.hxx>
#include <Graphic3d_GraphicDriver.hxx>
@ -144,17 +145,17 @@ void OpenGl_Layer::InvalidateBVHData() const
}
//! Calculate a finite bounding box of infinite object as its middle point.
inline Graphic3d_BndBox4f centerOfinfiniteBndBox (const Graphic3d_BndBox4f& theBndBox)
inline Graphic3d_BndBox3d centerOfinfiniteBndBox (const Graphic3d_BndBox3d& theBndBox)
{
// bounding borders of infinite line has been calculated as own point in center of this line
const Graphic3d_Vec4 aDiagVec = theBndBox.CornerMax() - theBndBox.CornerMin();
return aDiagVec.xyz().SquareModulus() >= 500000.0f * 500000.0f
? Graphic3d_BndBox4f ((theBndBox.CornerMin() + theBndBox.CornerMax()) * 0.5f)
: Graphic3d_BndBox4f();
const Graphic3d_Vec3d aDiagVec = theBndBox.CornerMax() - theBndBox.CornerMin();
return aDiagVec.SquareModulus() >= 500000.0 * 500000.0
? Graphic3d_BndBox3d ((theBndBox.CornerMin() + theBndBox.CornerMax()) * 0.5)
: Graphic3d_BndBox3d();
}
//! Return true if at least one vertex coordinate out of float range.
inline bool isInfiniteBndBox (const Graphic3d_BndBox4f& theBndBox)
inline bool isInfiniteBndBox (const Graphic3d_BndBox3d& theBndBox)
{
return Abs (theBndBox.CornerMax().x()) >= ShortRealLast()
|| Abs (theBndBox.CornerMax().y()) >= ShortRealLast()
@ -168,29 +169,28 @@ inline bool isInfiniteBndBox (const Graphic3d_BndBox4f& theBndBox)
// function : BoundingBox
// purpose :
// =======================================================================
Graphic3d_BndBox4f OpenGl_Layer::BoundingBox (const Standard_Integer theViewId,
const Handle(Graphic3d_Camera)& theCamera,
const Standard_Integer theWindowWidth,
const Standard_Integer theWindowHeight,
const Standard_Boolean theToIncludeAuxiliary) const
Bnd_Box OpenGl_Layer::BoundingBox (const Standard_Integer theViewId,
const Handle(Graphic3d_Camera)& theCamera,
const Standard_Integer theWindowWidth,
const Standard_Integer theWindowHeight,
const Standard_Boolean theToIncludeAuxiliary) const
{
updateBVH();
const Standard_Integer aBoxId = !theToIncludeAuxiliary ? 0 : 1;
const Graphic3d_Mat4& aProjectionMat = theCamera->ProjectionMatrixF();
const Graphic3d_Mat4& aWorldViewMat = theCamera->OrientationMatrixF();
const Graphic3d_Mat4d& aProjectionMat = theCamera->ProjectionMatrix();
const Graphic3d_Mat4d& aWorldViewMat = theCamera->OrientationMatrix();
if (myIsBoundingBoxNeedsReset[aBoxId])
{
// Recompute layer bounding box
myBoundingBox[aBoxId].Clear();
myBoundingBox[aBoxId].SetVoid();
const Standard_Integer aNbPriorities = myArray.Length();
for (Standard_Integer aPriorityIter = 0; aPriorityIter < aNbPriorities; ++aPriorityIter)
for (OpenGl_ArrayOfIndexedMapOfStructure::Iterator aMapIter (myArray); aMapIter.More(); aMapIter.Next())
{
const OpenGl_IndexedMapOfStructure& aStructures = myArray (aPriorityIter);
for (Standard_Integer aStructIdx = 1; aStructIdx <= aStructures.Size(); ++aStructIdx)
const OpenGl_IndexedMapOfStructure& aStructures = aMapIter.Value();
for (OpenGl_IndexedMapOfStructure::Iterator aStructIter (aStructures); aStructIter.More(); aStructIter.Next())
{
const OpenGl_Structure* aStructure = aStructures.FindKey (aStructIdx);
const OpenGl_Structure* aStructure = aStructIter.Value();
if (!aStructure->IsVisible (theViewId))
{
continue;
@ -204,12 +204,7 @@ Graphic3d_BndBox4f OpenGl_Layer::BoundingBox (const Standard_Integer th
&& aStructure->TransformPersistence()->IsZoomOrRotate())
{
const gp_Pnt anAnchor = aStructure->TransformPersistence()->AnchorPoint();
BVH_Vec4f aTPPoint (static_cast<float> (anAnchor.X()),
static_cast<float> (anAnchor.Y()),
static_cast<float> (anAnchor.Z()),
1.0f);
myBoundingBox[aBoxId].Combine (aTPPoint);
myBoundingBox[aBoxId].Add (anAnchor);
continue;
}
// Panning and 2d persistence apply changes to projection or/and its translation components.
@ -221,7 +216,7 @@ Graphic3d_BndBox4f OpenGl_Layer::BoundingBox (const Standard_Integer th
}
}
Graphic3d_BndBox4f aBox = aStructure->BoundingBox();
Graphic3d_BndBox3d aBox = aStructure->BoundingBox();
if (!aBox.IsValid())
{
continue;
@ -240,9 +235,11 @@ Graphic3d_BndBox4f OpenGl_Layer::BoundingBox (const Standard_Integer th
}
// skip too big boxes to prevent float overflow at camera parameters calculation
if (!isInfiniteBndBox (aBox))
if (aBox.IsValid()
&& !isInfiniteBndBox (aBox))
{
myBoundingBox[aBoxId].Combine (aBox);
myBoundingBox[aBoxId].Add (gp_Pnt (aBox.CornerMin().x(), aBox.CornerMin().y(), aBox.CornerMin().z()));
myBoundingBox[aBoxId].Add (gp_Pnt (aBox.CornerMax().x(), aBox.CornerMax().y(), aBox.CornerMax().z()));
}
}
}
@ -250,14 +247,14 @@ Graphic3d_BndBox4f OpenGl_Layer::BoundingBox (const Standard_Integer th
myIsBoundingBoxNeedsReset[aBoxId] = false;
}
Bnd_Box aResBox = myBoundingBox[aBoxId];
if (!theToIncludeAuxiliary
|| myAlwaysRenderedMap.IsEmpty())
{
return myBoundingBox[aBoxId];
return aResBox;
}
// add transformation-persistent objects which depend on camera position (and thus can not be cached) for operations like Z-fit
Graphic3d_BndBox4f aResBox = myBoundingBox[aBoxId];
for (NCollection_IndexedMap<const OpenGl_Structure*>::Iterator aStructIter (myAlwaysRenderedMap); aStructIter.More(); aStructIter.Next())
{
const OpenGl_Structure* aStructure = aStructIter.Value();
@ -271,16 +268,18 @@ Graphic3d_BndBox4f OpenGl_Layer::BoundingBox (const Standard_Integer th
continue;
}
Graphic3d_BndBox4f aBox = aStructure->BoundingBox();
Graphic3d_BndBox3d aBox = aStructure->BoundingBox();
if (!aBox.IsValid())
{
continue;
}
aStructure->TransformPersistence()->Apply (theCamera, aProjectionMat, aWorldViewMat, theWindowWidth, theWindowHeight, aBox);
if (!isInfiniteBndBox (aBox))
if (aBox.IsValid()
&& !isInfiniteBndBox (aBox))
{
aResBox.Combine (aBox);
aResBox.Add (gp_Pnt (aBox.CornerMin().x(), aBox.CornerMin().y(), aBox.CornerMin().z()));
aResBox.Add (gp_Pnt (aBox.CornerMax().x(), aBox.CornerMax().y(), aBox.CornerMax().z()));
}
}
@ -301,17 +300,16 @@ Standard_Real OpenGl_Layer::considerZoomPersistenceObjects (const Standard_Integ
return 1.0;
}
const Standard_Integer aNbPriorities = myArray.Length();
const Graphic3d_Mat4& aProjectionMat = theCamera->ProjectionMatrixF();
const Graphic3d_Mat4& aWorldViewMat = theCamera->OrientationMatrixF();
const Graphic3d_Mat4d& aProjectionMat = theCamera->ProjectionMatrix();
const Graphic3d_Mat4d& aWorldViewMat = theCamera->OrientationMatrix();
Standard_Real aMaxCoef = -std::numeric_limits<double>::max();
for (Standard_Integer aPriorityIter = 0; aPriorityIter < aNbPriorities; ++aPriorityIter)
for (OpenGl_ArrayOfIndexedMapOfStructure::Iterator aMapIter (myArray); aMapIter.More(); aMapIter.Next())
{
const OpenGl_IndexedMapOfStructure& aStructures = myArray (aPriorityIter);
for (Standard_Integer aStructIdx = 1; aStructIdx <= aStructures.Size(); ++aStructIdx)
const OpenGl_IndexedMapOfStructure& aStructures = aMapIter.Value();
for (OpenGl_IndexedMapOfStructure::Iterator aStructIter (aStructures); aStructIter.More(); aStructIter.Next())
{
OpenGl_Structure* aStructure = const_cast<OpenGl_Structure*> (aStructures.FindKey (aStructIdx));
const OpenGl_Structure* aStructure = aStructIter.Value();
if (!aStructure->IsVisible (theViewId)
|| aStructure->TransformPersistence().IsNull()
|| !aStructure->TransformPersistence()->IsZoomOrRotate())
@ -319,7 +317,7 @@ Standard_Real OpenGl_Layer::considerZoomPersistenceObjects (const Standard_Integ
continue;
}
Graphic3d_BndBox4f aBox = aStructure->BoundingBox();
Graphic3d_BndBox3d aBox = aStructure->BoundingBox();
if (!aBox.IsValid())
{
continue;
@ -327,8 +325,8 @@ Standard_Real OpenGl_Layer::considerZoomPersistenceObjects (const Standard_Integ
aStructure->TransformPersistence()->Apply (theCamera, aProjectionMat, aWorldViewMat, theWindowWidth, theWindowHeight, aBox);
const BVH_Vec4f& aCornerMin = aBox.CornerMin();
const BVH_Vec4f& aCornerMax = aBox.CornerMax();
const BVH_Vec3d& aCornerMin = aBox.CornerMin();
const BVH_Vec3d& aCornerMax = aBox.CornerMax();
const Standard_Integer aNbOfPoints = 8;
const gp_Pnt aPoints[aNbOfPoints] = { gp_Pnt (aCornerMin.x(), aCornerMin.y(), aCornerMin.z()),
gp_Pnt (aCornerMin.x(), aCornerMin.y(), aCornerMax.z()),
@ -416,14 +414,13 @@ Standard_Real OpenGl_Layer::considerZoomPersistenceObjects (const Standard_Integ
// =======================================================================
void OpenGl_Layer::renderAll (const Handle(OpenGl_Workspace)& theWorkspace) const
{
const Standard_Integer aNbPriorities = myArray.Length();
const Standard_Integer aViewId = theWorkspace->View()->Identification();
for (Standard_Integer aPriorityIter = 0; aPriorityIter < aNbPriorities; ++aPriorityIter)
const Standard_Integer aViewId = theWorkspace->View()->Identification();
for (OpenGl_ArrayOfIndexedMapOfStructure::Iterator aMapIter (myArray); aMapIter.More(); aMapIter.Next())
{
const OpenGl_IndexedMapOfStructure& aStructures = myArray (aPriorityIter);
for (Standard_Integer aStructIdx = 1; aStructIdx <= aStructures.Size(); ++aStructIdx)
const OpenGl_IndexedMapOfStructure& aStructures = aMapIter.Value();
for (OpenGl_IndexedMapOfStructure::Iterator aStructIter (aStructures); aStructIter.More(); aStructIter.Next())
{
const OpenGl_Structure* aStruct = aStructures.FindKey (aStructIdx);
const OpenGl_Structure* aStruct = aStructIter.Value();
if (!aStruct->IsVisible())
{
continue;
@ -454,9 +451,10 @@ void OpenGl_Layer::updateBVH() const
myBVHPrimitivesTrsfPers.Clear();
myAlwaysRenderedMap.Clear();
myIsBVHPrimitivesNeedsReset = Standard_False;
for (Standard_Integer aPriorityIdx = 0, aNbPriorities = myArray.Length(); aPriorityIdx < aNbPriorities; ++aPriorityIdx)
for (OpenGl_ArrayOfIndexedMapOfStructure::Iterator aMapIter (myArray); aMapIter.More(); aMapIter.Next())
{
for (OpenGl_IndexedMapOfStructure::Iterator aStructIter (myArray (aPriorityIdx)); aStructIter.More(); aStructIter.Next())
const OpenGl_IndexedMapOfStructure& aStructures = aMapIter.Value();
for (OpenGl_IndexedMapOfStructure::Iterator aStructIter (aStructures); aStructIter.More(); aStructIter.Next())
{
const OpenGl_Structure* aStruct = aStructIter.Value();
if (aStruct->IsAlwaysRendered())
@ -487,14 +485,13 @@ void OpenGl_Layer::renderTraverse (const Handle(OpenGl_Workspace)& theWorkspace)
OpenGl_BVHTreeSelector& aSelector = theWorkspace->View()->BVHTreeSelector();
traverse (aSelector);
const Standard_Integer aNbPriorities = myArray.Length();
const Standard_Integer aViewId = theWorkspace->View()->Identification();
for (Standard_Integer aPriorityIter = 0; aPriorityIter < aNbPriorities; ++aPriorityIter)
const Standard_Integer aViewId = theWorkspace->View()->Identification();
for (OpenGl_ArrayOfIndexedMapOfStructure::Iterator aMapIter (myArray); aMapIter.More(); aMapIter.Next())
{
const OpenGl_IndexedMapOfStructure& aStructures = myArray (aPriorityIter);
for (Standard_Integer aStructIdx = 1; aStructIdx <= aStructures.Size(); ++aStructIdx)
const OpenGl_IndexedMapOfStructure& aStructures = aMapIter.Value();
for (OpenGl_IndexedMapOfStructure::Iterator aStructIter (aStructures); aStructIter.More(); aStructIter.Next())
{
const OpenGl_Structure* aStruct = aStructures.FindKey (aStructIdx);
const OpenGl_Structure* aStruct = aStructIter.Value();
if (aStruct->IsCulled()
|| !aStruct->IsVisible (aViewId))
{
@ -520,7 +517,7 @@ void OpenGl_Layer::traverse (OpenGl_BVHTreeSelector& theSelector) const
theSelector.CacheClipPtsProjections();
NCollection_Handle<BVH_Tree<Standard_ShortReal, 4> > aBVHTree;
NCollection_Handle<BVH_Tree<Standard_Real, 3> > aBVHTree;
for (Standard_Integer aBVHTreeIdx = 0; aBVHTreeIdx < 2; ++aBVHTreeIdx)
{
@ -530,8 +527,8 @@ void OpenGl_Layer::traverse (OpenGl_BVHTreeSelector& theSelector) const
if (myBVHPrimitivesTrsfPers.Size() == 0)
continue;
const OpenGl_Mat4& aProjection = theSelector.ProjectionMatrix();
const OpenGl_Mat4& aWorldView = theSelector.WorldViewMatrix();
const OpenGl_Mat4d& aProjection = theSelector.ProjectionMatrix();
const OpenGl_Mat4d& aWorldView = theSelector.WorldViewMatrix();
const Graphic3d_WorldViewProjState& aWVPState = theSelector.WorldViewProjState();
const Standard_Integer aViewportWidth = theSelector.ViewportWidth();
const Standard_Integer aViewportHeight = theSelector.ViewportHeight();
@ -623,15 +620,37 @@ Standard_Boolean OpenGl_Layer::Append (const OpenGl_Layer& theOther)
for (Standard_Integer aPriorityIter = 0; aPriorityIter < aNbPriorities; ++aPriorityIter)
{
const OpenGl_IndexedMapOfStructure& aStructures = theOther.myArray (aPriorityIter);
for (Standard_Integer aStructIdx = 1; aStructIdx <= aStructures.Size(); ++aStructIdx)
for (OpenGl_IndexedMapOfStructure::Iterator aStructIter (aStructures); aStructIter.More(); aStructIter.Next())
{
Add (aStructures.FindKey (aStructIdx), aPriorityIter);
Add (aStructIter.Value(), aPriorityIter);
}
}
return Standard_True;
}
//=======================================================================
//function : SetLayerSettings
//purpose :
//=======================================================================
void OpenGl_Layer::SetLayerSettings (const Graphic3d_ZLayerSettings& theSettings)
{
const Standard_Boolean toUpdateTrsf = !myLayerSettings.Origin().IsEqual (theSettings.Origin(), gp::Resolution());
myLayerSettings = theSettings;
if (toUpdateTrsf)
{
for (OpenGl_ArrayOfIndexedMapOfStructure::Iterator aMapIter (myArray); aMapIter.More(); aMapIter.Next())
{
OpenGl_IndexedMapOfStructure& aStructures = aMapIter.ChangeValue();
for (OpenGl_IndexedMapOfStructure::Iterator aStructIter (aStructures); aStructIter.More(); aStructIter.Next())
{
OpenGl_Structure* aStructure = const_cast<OpenGl_Structure*> (aStructIter.Value());
aStructure->updateLayerTransformation();
}
}
}
}
//=======================================================================
//function : Render
//purpose :
@ -639,16 +658,16 @@ Standard_Boolean OpenGl_Layer::Append (const OpenGl_Layer& theOther)
void OpenGl_Layer::Render (const Handle(OpenGl_Workspace)& theWorkspace,
const OpenGl_GlobalLayerSettings& theDefaultSettings) const
{
Graphic3d_PolygonOffset anAppliedOffsetParams = theWorkspace->AppliedPolygonOffset();
const Graphic3d_PolygonOffset anAppliedOffsetParams = theWorkspace->AppliedPolygonOffset();
// separate depth buffers
if (IsSettingEnabled (Graphic3d_ZLayerDepthClear))
if (myLayerSettings.ToClearDepth())
{
glClear (GL_DEPTH_BUFFER_BIT);
}
// handle depth test
if (IsSettingEnabled (Graphic3d_ZLayerDepthTest))
if (myLayerSettings.ToEnableDepthTest())
{
// assuming depth test is enabled by default
glDepthFunc (theDefaultSettings.DepthFunc);
@ -660,37 +679,86 @@ void OpenGl_Layer::Render (const Handle(OpenGl_Workspace)& theWorkspace,
// save environment texture
Handle(OpenGl_Texture) anEnvironmentTexture = theWorkspace->EnvironmentTexture();
if (!myLayerSettings.UseEnvironmentTexture)
if (!myLayerSettings.UseEnvironmentTexture())
{
theWorkspace->SetEnvironmentTexture (Handle(OpenGl_Texture)());
}
// handle depth offset
if (IsSettingEnabled (Graphic3d_ZLayerDepthOffset))
{
Graphic3d_PolygonOffset aLayerPolygonOffset;
aLayerPolygonOffset.Mode = Aspect_POM_Fill;
aLayerPolygonOffset.Factor = myLayerSettings.DepthOffsetFactor;
aLayerPolygonOffset.Units = myLayerSettings.DepthOffsetUnits;
theWorkspace->SetPolygonOffset (aLayerPolygonOffset);
}
else
{
theWorkspace->SetPolygonOffset (anAppliedOffsetParams);
}
theWorkspace->SetPolygonOffset (myLayerSettings.PolygonOffset());
// handle depth write
theWorkspace->UseDepthWrite() = IsSettingEnabled (Graphic3d_ZLayerDepthWrite);
theWorkspace->UseDepthWrite() = myLayerSettings.ToEnableDepthWrite();
glDepthMask (theWorkspace->UseDepthWrite() ? GL_TRUE : GL_FALSE);
const Standard_Boolean hasLocalCS = !myLayerSettings.OriginTransformation().IsNull();
const Handle(OpenGl_Context)& aCtx = theWorkspace->GetGlContext();
const Handle(Graphic3d_Camera)& aWorldCamera = theWorkspace->View()->Camera();
Handle(Graphic3d_Camera) aCameraBack;
if (hasLocalCS)
{
// Apply local camera transformation.
// The vertex position is computed by the following formula in GLSL program:
// gl_Position = occProjectionMatrix * occWorldViewMatrix * occModelWorldMatrix * occVertex;
// where:
// occProjectionMatrix - matrix defining orthographic/perspective/stereographic projection
// occWorldViewMatrix - world-view matrix defining Camera position and orientation
// occModelWorldMatrix - model-world matrix defining Object transformation from local coordinate system to the world coordinate system
// occVertex - input vertex position
//
// Since double precision is quite expensive on modern GPUs, and not available on old hardware,
// all these values are passed with single float precision to the shader.
// As result, single precision become insufficient for handling objects far from the world origin.
//
// Several approaches can be used to solve precision issues:
// - [Broute force] migrate to double precision for all matrices and vertex position.
// This is too expensive for most hardware.
// - Store only translation part with double precision and pass it to GLSL program.
// This requires modified GLSL programs for computing transformation
// and extra packing mechanism for hardware not supporting double precision natively.
// This solution is less expensive then previous one.
// - Move translation part of occModelWorldMatrix into occWorldViewMatrix.
// The main idea here is that while moving Camera towards the object,
// Camera translation part and Object translation part will compensate each other
// to fit into single float precision.
// But this operation should be performed with double precision - this is why we are moving
// translation part of occModelWorldMatrix to occWorldViewMatrix.
//
// All approaches might be useful in different scenarios, but for the moment we consider the last one as main scenario.
// Here we do the trick:
// - OpenGl_Layer defines the Local Origin, which is expected to be the center of objects stored within it.
// This Local Origin is included into occWorldViewMatrix during rendering.
// - OpenGl_Structure defines Object local transformation occModelWorldMatrix with subtracted Local Origin of the Layer.
// This means that Object itself should be defined within either Local Transformation equal or near to Local Origin of the Layer.
theWorkspace->View()->SetLocalOrigin (myLayerSettings.Origin());
NCollection_Mat4<Standard_Real> aWorldView = aWorldCamera->OrientationMatrix();
Graphic3d_TransformUtils::Translate (aWorldView, myLayerSettings.Origin().X(), myLayerSettings.Origin().Y(), myLayerSettings.Origin().Z());
NCollection_Mat4<Standard_ShortReal> aWorldViewF;
aWorldViewF.ConvertFrom (aWorldView);
aCtx->WorldViewState.SetCurrent (aWorldViewF);
aCtx->ShaderManager()->UpdateClippingState();
aCtx->ShaderManager()->UpdateLightSourceState();
}
// render priority list
theWorkspace->IsCullingEnabled() ? renderTraverse (theWorkspace) : renderAll (theWorkspace);
if (hasLocalCS)
{
aCtx->ShaderManager()->RevertClippingState();
aCtx->ShaderManager()->UpdateLightSourceState();
aCtx->WorldViewState.SetCurrent (aWorldCamera->OrientationMatrixF());
theWorkspace->View() ->SetLocalOrigin (gp_XYZ (0.0, 0.0, 0.0));
}
// always restore polygon offset between layers rendering
theWorkspace->SetPolygonOffset (anAppliedOffsetParams);
// restore environment texture
if (!myLayerSettings.UseEnvironmentTexture)
if (!myLayerSettings.UseEnvironmentTexture())
{
theWorkspace->SetEnvironmentTexture (anEnvironmentTexture);
}

View File

@ -51,20 +51,14 @@ public:
//! Destructor.
virtual ~OpenGl_Layer();
//! Return true if layer was marked with immediate flag.
Standard_Boolean IsImmediate() const { return myLayerSettings.IsImmediate(); }
//! Returns settings of the layer object.
const Graphic3d_ZLayerSettings& LayerSettings() const { return myLayerSettings; };
//! Sets settings of the layer object.
void SetLayerSettings (const Graphic3d_ZLayerSettings& theSettings)
{
myLayerSettings = theSettings;
}
//! Returns true if theSetting is enabled for the layer.
Standard_Boolean IsSettingEnabled (const Graphic3d_ZLayerSetting theSetting) const
{
return myLayerSettings.IsSettingEnabled (theSetting);
}
void SetLayerSettings (const Graphic3d_ZLayerSettings& theSettings);
void Add (const OpenGl_Structure* theStruct,
const Standard_Integer thePriority,
@ -105,11 +99,11 @@ public:
//! @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
Graphic3d_BndBox4f BoundingBox (const Standard_Integer theViewId,
const Handle(Graphic3d_Camera)& theCamera,
const Standard_Integer theWindowWidth,
const Standard_Integer theWindowHeight,
const Standard_Boolean theToIncludeAuxiliary) const;
Bnd_Box BoundingBox (const Standard_Integer theViewId,
const Handle(Graphic3d_Camera)& theCamera,
const Standard_Integer theWindowWidth,
const Standard_Integer theWindowHeight,
const Standard_Boolean theToIncludeAuxiliary) const;
//! Returns zoom-scale factor.
Standard_Real considerZoomPersistenceObjects (const Standard_Integer theViewId,
@ -171,7 +165,7 @@ private:
mutable bool myIsBoundingBoxNeedsReset[2];
//! Cached layer bounding box.
mutable Graphic3d_BndBox4f myBoundingBox[2];
mutable Bnd_Box myBoundingBox[2];
public:

View File

@ -148,7 +148,7 @@ void OpenGl_LayerList::AddStructure (const OpenGl_Structure* theStruct,
OpenGl_Layer& aLayer = myLayers.ChangeValue (aSeqPos);
aLayer.Add (theStruct, thePriority, isForChangePriority);
++myNbStructures;
if (aLayer.LayerSettings().IsImmediate)
if (aLayer.IsImmediate())
{
++myImmediateNbStructures;
}
@ -179,7 +179,7 @@ void OpenGl_LayerList::RemoveStructure (const OpenGl_Structure* theStructure)
if (aLayer.Remove (theStructure, aPriority))
{
--myNbStructures;
if (aLayer.LayerSettings().IsImmediate)
if (aLayer.IsImmediate())
{
--myImmediateNbStructures;
}
@ -206,7 +206,7 @@ void OpenGl_LayerList::RemoveStructure (const OpenGl_Structure* theStructure)
if (aLayerEx.Remove (theStructure, aPriority))
{
--myNbStructures;
if (aLayerEx.LayerSettings().IsImmediate)
if (aLayerEx.IsImmediate())
{
--myImmediateNbStructures;
}
@ -258,7 +258,7 @@ void OpenGl_LayerList::ChangeLayer (const OpenGl_Structure* theStructure,
}
--myNbStructures;
if (aLayer.LayerSettings().IsImmediate)
if (aLayer.IsImmediate())
{
--myImmediateNbStructures;
}
@ -289,7 +289,7 @@ void OpenGl_LayerList::ChangeLayer (const OpenGl_Structure* theStructure,
}
--myNbStructures;
if (aLayerEx.LayerSettings().IsImmediate)
if (aLayerEx.IsImmediate())
{
--myImmediateNbStructures;
}
@ -318,7 +318,7 @@ void OpenGl_LayerList::ChangePriority (const OpenGl_Structure* theStructure,
if (aLayer.Remove (theStructure, anOldPriority, Standard_True))
{
--myNbStructures;
if (aLayer.LayerSettings().IsImmediate)
if (aLayer.IsImmediate())
{
--myImmediateNbStructures;
}
@ -339,7 +339,7 @@ void OpenGl_LayerList::ChangePriority (const OpenGl_Structure* theStructure,
if (aLayerEx.Remove (theStructure, anOldPriority, Standard_True))
{
--myNbStructures;
if (aLayerEx.LayerSettings().IsImmediate)
if (aLayerEx.IsImmediate())
{
--myImmediateNbStructures;
}
@ -358,9 +358,9 @@ void OpenGl_LayerList::SetLayerSettings (const Graphic3d_ZLayerId theLaye
const Graphic3d_ZLayerSettings& theSettings)
{
OpenGl_Layer& aLayer = Layer (theLayerId);
if (aLayer.LayerSettings().IsImmediate != theSettings.IsImmediate)
if (aLayer.LayerSettings().IsImmediate() != theSettings.IsImmediate())
{
if (theSettings.IsImmediate)
if (theSettings.IsImmediate())
{
myImmediateNbStructures += aLayer.NbStructures();
}
@ -409,14 +409,14 @@ void OpenGl_LayerList::Render (const Handle(OpenGl_Workspace)& theWorkspace,
}
else if (theToDrawImmediate)
{
if (!aLayer.LayerSettings().IsImmediate)
if (!aLayer.IsImmediate())
{
continue;
}
}
else
{
if (aLayer.LayerSettings().IsImmediate)
if (aLayer.IsImmediate())
{
continue;
}

View File

@ -258,6 +258,7 @@ const char THE_FRAG_CLIP_PLANES_2[] =
OpenGl_ShaderManager::OpenGl_ShaderManager (OpenGl_Context* theContext)
: myShadingModel (Graphic3d_TOSM_VERTEX),
myContext (theContext),
myHasLocalOrigin (Standard_False),
myLastView (NULL)
{
//
@ -430,6 +431,15 @@ void OpenGl_ShaderManager::UpdateLightSourceStateTo (const OpenGl_ListOfLight* t
switchLightPrograms();
}
// =======================================================================
// function : UpdateLightSourceState
// purpose :
// =======================================================================
void OpenGl_ShaderManager::UpdateLightSourceState()
{
myLightSourceState.Update();
}
// =======================================================================
// function : SetShadingModel
// purpose :
@ -506,36 +516,6 @@ const OpenGl_WorldViewState& OpenGl_ShaderManager::WorldViewState() const
return myWorldViewState;
}
//! Packed properties of light source
class OpenGl_ShaderLightParameters
{
public:
OpenGl_Vec4 Color;
OpenGl_Vec4 Position;
OpenGl_Vec4 Direction;
OpenGl_Vec4 Parameters;
//! Returns packed (serialized) representation of light source properties
const OpenGl_Vec4* Packed() const { return reinterpret_cast<const OpenGl_Vec4*> (this); }
static Standard_Integer NbOfVec4() { return 4; }
};
//! Packed light source type information
class OpenGl_ShaderLightType
{
public:
Standard_Integer Type;
Standard_Integer IsHeadlight;
//! Returns packed (serialized) representation of light source type
const OpenGl_Vec2i* Packed() const { return reinterpret_cast<const OpenGl_Vec2i*> (this); }
static Standard_Integer NbOfVec2i() { return 1; }
};
// =======================================================================
// function : PushLightSourceState
// purpose : Pushes state of OCCT light sources to the program
@ -548,10 +528,9 @@ void OpenGl_ShaderManager::PushLightSourceState (const Handle(OpenGl_ShaderProgr
return;
}
OpenGl_ShaderLightType* aLightTypeArray = new OpenGl_ShaderLightType[OpenGLMaxLights];
for (Standard_Integer aLightIt = 0; aLightIt < OpenGLMaxLights; ++aLightIt)
{
aLightTypeArray[aLightIt].Type = -1;
myLightTypeArray[aLightIt].Type = -1;
}
const Standard_Integer aLightsDefNb = Min (myLightSourceState.LightSources()->Size(), OpenGLMaxLights);
@ -566,14 +545,11 @@ void OpenGl_ShaderManager::PushLightSourceState (const Handle(OpenGl_ShaderProgr
theProgram->SetUniform (myContext,
theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_TYPES),
OpenGLMaxLights * OpenGl_ShaderLightType::NbOfVec2i(),
aLightTypeArray[0].Packed());
myLightTypeArray[0].Packed());
theProgram->UpdateState (OpenGl_LIGHT_SOURCES_STATE, myLightSourceState.Index());
delete[] aLightTypeArray;
return;
}
OpenGl_ShaderLightParameters* aLightParamsArray = new OpenGl_ShaderLightParameters[aLightsDefNb];
OpenGl_Vec4 anAmbient (0.0f, 0.0f, 0.0f, 0.0f);
Standard_Integer aLightsNb = 0;
for (OpenGl_ListOfLight::Iterator anIter (*myLightSourceState.LightSources()); anIter.More(); anIter.Next())
@ -589,15 +565,31 @@ void OpenGl_ShaderManager::PushLightSourceState (const Handle(OpenGl_ShaderProgr
continue;
}
OpenGl_ShaderLightType& aLightType = aLightTypeArray[aLightsNb];
OpenGl_ShaderLightType& aLightType = myLightTypeArray[aLightsNb];
aLightType.Type = aLight.Type;
aLightType.IsHeadlight = aLight.IsHeadlight;
OpenGl_ShaderLightParameters& aLightParams = aLightParamsArray[aLightsNb];
aLightParams.Color = aLight.Color;
aLightParams.Position = aLight.Type == Graphic3d_TOLS_DIRECTIONAL
? -aLight.Direction
: aLight.Position;
OpenGl_ShaderLightParameters& aLightParams = myLightParamsArray[aLightsNb];
aLightParams.Color = aLight.Color;
if (aLight.Type == Graphic3d_TOLS_DIRECTIONAL)
{
aLightParams.Position = -aLight.Direction;
}
else if (!aLight.IsHeadlight)
{
aLightParams.Position.x() = static_cast<float>(aLight.Position.x() - myLocalOrigin.X());
aLightParams.Position.y() = static_cast<float>(aLight.Position.y() - myLocalOrigin.Y());
aLightParams.Position.z() = static_cast<float>(aLight.Position.z() - myLocalOrigin.Z());
aLightParams.Position.w() = 1.0f;
}
else
{
aLightParams.Position.x() = static_cast<float>(aLight.Position.x());
aLightParams.Position.y() = static_cast<float>(aLight.Position.y());
aLightParams.Position.z() = static_cast<float>(aLight.Position.z());
aLightParams.Position.w() = 1.0f;
}
if (aLight.Type == Graphic3d_TOLS_SPOT)
{
aLightParams.Direction = aLight.Direction;
@ -615,16 +607,14 @@ void OpenGl_ShaderManager::PushLightSourceState (const Handle(OpenGl_ShaderProgr
theProgram->SetUniform (myContext,
theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_TYPES),
OpenGLMaxLights * OpenGl_ShaderLightType::NbOfVec2i(),
aLightTypeArray[0].Packed());
myLightTypeArray[0].Packed());
if (aLightsNb > 0)
{
theProgram->SetUniform (myContext,
theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_PARAMS),
aLightsNb * OpenGl_ShaderLightParameters::NbOfVec4(),
aLightParamsArray[0].Packed());
myLightParamsArray[0].Packed());
}
delete[] aLightParamsArray;
delete[] aLightTypeArray;
theProgram->UpdateState (OpenGl_LIGHT_SOURCES_STATE, myLightSourceState.Index());
}
@ -794,10 +784,17 @@ void OpenGl_ShaderManager::PushClippingState (const Handle(OpenGl_ShaderProgram)
}
const Graphic3d_ClipPlane::Equation& anEquation = aPlane->GetEquation();
anEquations[aPlaneId] = OpenGl_Vec4 ((float) anEquation.x(),
(float) anEquation.y(),
(float) anEquation.z(),
(float) anEquation.w());
OpenGl_Vec4& aPlaneEq = anEquations[aPlaneId];
aPlaneEq.x() = float(anEquation.x());
aPlaneEq.y() = float(anEquation.y());
aPlaneEq.z() = float(anEquation.z());
aPlaneEq.w() = float(anEquation.w());
if (myHasLocalOrigin)
{
const gp_XYZ aPos = aPlane->ToPlane().Position().Location().XYZ() - myLocalOrigin;
const Standard_Real aD = -(anEquation.x() * aPos.X() + anEquation.y() * aPos.Y() + anEquation.z() * aPos.Z());
aPlaneEq.w() = float(aD);
}
++aPlaneId;
}

View File

@ -56,6 +56,16 @@ public:
//! Release all resources.
Standard_EXPORT void clear();
//! Return local camera transformation.
const gp_XYZ& LocalOrigin() const { return myLocalOrigin; }
//! Setup local camera transformation for compensating float precision issues.
void SetLocalOrigin (const gp_XYZ& theOrigin)
{
myLocalOrigin = theOrigin;
myHasLocalOrigin = !theOrigin.IsEqual (gp_XYZ(0.0, 0.0, 0.0), gp::Resolution());
}
//! Creates new shader program or re-use shared instance.
//! @param theProxy [IN] program definition
//! @param theShareKey [OUT] sharing key
@ -186,6 +196,9 @@ public:
//! Updates state of OCCT light sources.
Standard_EXPORT void UpdateLightSourceStateTo (const OpenGl_ListOfLight* theLights);
//! Invalidate state of OCCT light sources.
Standard_EXPORT void UpdateLightSourceState();
//! Pushes current state of OCCT light sources to specified program.
Standard_EXPORT void PushLightSourceState (const Handle(OpenGl_ShaderProgram)& theProgram) const;
@ -379,6 +392,32 @@ protected:
Standard_EXPORT Standard_Boolean prepareStdProgramStereo (Handle(OpenGl_ShaderProgram)& theProgram,
const Graphic3d_StereoMode theStereoMode);
protected:
//! Packed properties of light source
struct OpenGl_ShaderLightParameters
{
OpenGl_Vec4 Color;
OpenGl_Vec4 Position;
OpenGl_Vec4 Direction;
OpenGl_Vec4 Parameters;
//! Returns packed (serialized) representation of light source properties
const OpenGl_Vec4* Packed() const { return reinterpret_cast<const OpenGl_Vec4*> (this); }
static Standard_Integer NbOfVec4() { return 4; }
};
//! Packed light source type information
struct OpenGl_ShaderLightType
{
Standard_Integer Type;
Standard_Integer IsHeadlight;
//! Returns packed (serialized) representation of light source type
const OpenGl_Vec2i* Packed() const { return reinterpret_cast<const OpenGl_Vec2i*> (this); }
static Standard_Integer NbOfVec2i() { return 1; }
};
protected:
Graphic3d_TypeOfShadingModel myShadingModel; //!< lighting shading model
@ -400,6 +439,11 @@ protected:
OpenGl_WorldViewState myWorldViewState; //!< State of OCCT world-view transformation
OpenGl_ClippingState myClippingState; //!< State of OCCT clipping planes
OpenGl_LightSourceState myLightSourceState; //!< State of OCCT light sources
gp_XYZ myLocalOrigin; //!< local camera transformation
Standard_Boolean myHasLocalOrigin; //!< flag indicating that local camera transformation has been set
mutable OpenGl_ShaderLightType myLightTypeArray [OpenGLMaxLights];
mutable OpenGl_ShaderLightParameters myLightParamsArray[OpenGLMaxLights];
private:

View File

@ -36,14 +36,14 @@ class OpenGl_BndBoxPrs : public OpenGl_Element
public:
//! Main constructor
OpenGl_BndBoxPrs (const Graphic3d_BndBox4f& theBndBox)
OpenGl_BndBoxPrs (const Graphic3d_BndBox3d& theBndBox)
{
const float Xm = theBndBox.CornerMin().x();
const float Ym = theBndBox.CornerMin().y();
const float Zm = theBndBox.CornerMin().z();
const float XM = theBndBox.CornerMax().x();
const float YM = theBndBox.CornerMax().y();
const float ZM = theBndBox.CornerMax().z();
const float Xm = (float )theBndBox.CornerMin().x();
const float Ym = (float)theBndBox.CornerMin().y();
const float Zm = (float)theBndBox.CornerMin().z();
const float XM = (float)theBndBox.CornerMax().x();
const float YM = (float)theBndBox.CornerMax().y();
const float ZM = (float)theBndBox.CornerMax().z();
myVerts[0] = OpenGl_Vec3 (Xm, Ym, Zm);
myVerts[1] = OpenGl_Vec3 (Xm, Ym, ZM);
@ -125,7 +125,7 @@ OpenGl_Structure::OpenGl_Structure (const Handle(Graphic3d_StructureManager)& th
myIsCulled (Standard_True),
myIsMirrored (Standard_False)
{
//
updateLayerTransformation();
}
// =======================================================================
@ -137,6 +137,16 @@ OpenGl_Structure::~OpenGl_Structure()
Release (Handle(OpenGl_Context)());
}
// =======================================================================
// function : SetZLayer
// purpose :
// =======================================================================
void OpenGl_Structure::SetZLayer (const Graphic3d_ZLayerId theLayerIndex)
{
Graphic3d_CStructure::SetZLayer (theLayerIndex);
updateLayerTransformation();
}
// =======================================================================
// function : SetTransformation
// purpose :
@ -154,12 +164,44 @@ void OpenGl_Structure::SetTransformation (const Handle(Geom_Transformation)& the
myIsMirrored = aDet < 0.0;
}
updateLayerTransformation();
if (IsRaytracable())
{
++myModificationState;
}
}
// =======================================================================
// function : SetTransformPersistence
// purpose :
// =======================================================================
void OpenGl_Structure::SetTransformPersistence (const Handle(Graphic3d_TransformPers)& theTrsfPers)
{
myTrsfPers = theTrsfPers;
updateLayerTransformation();
}
// =======================================================================
// function : updateLayerTransformation
// purpose :
// =======================================================================
void OpenGl_Structure::updateLayerTransformation()
{
gp_Trsf aRenderTrsf;
if (!myTrsf.IsNull())
{
aRenderTrsf = myTrsf->Trsf();
}
const Graphic3d_ZLayerSettings& aLayer = myGraphicDriver->ZLayerSettings (myZLayer);
if (!aLayer.OriginTransformation().IsNull()
&& myTrsfPers.IsNull())
{
aRenderTrsf.SetTranslationPart (aRenderTrsf.TranslationPart() - aLayer.Origin());
}
aRenderTrsf.GetMat4 (myRenderTrsf);
}
// =======================================================================
// function : clearHighlightBox
// purpose :
@ -441,17 +483,9 @@ void OpenGl_Structure::Render (const Handle(OpenGl_Workspace) &theWorkspace) con
// Apply local transformation
aCtx->ModelWorldState.Push();
OpenGl_Mat4& aModelWorld = aCtx->ModelWorldState.ChangeCurrent();
if (!myTrsf.IsNull())
{
myTrsf->Trsf().GetMat4 (aModelWorld);
}
else
{
aModelWorld.InitIdentity();
}
aModelWorld = myRenderTrsf;
const Standard_Boolean anOldGlNormalize = aCtx->IsGlNormalizeEnabled();
#if !defined(GL_ES_VERSION_2_0)
// detect scale transform
if (aCtx->core11 != NULL
@ -467,19 +501,18 @@ void OpenGl_Structure::Render (const Handle(OpenGl_Workspace) &theWorkspace) con
if (!myTrsfPers.IsNull())
{
OpenGl_Mat4 aWorldView = aCtx->WorldViewState.Current();
myTrsfPers->Apply (theWorkspace->View()->Camera(), aCtx->ProjectionState.Current(), aWorldView,
aCtx->Viewport()[2], aCtx->Viewport()[3]);
aCtx->WorldViewState.Push();
aCtx->WorldViewState.SetCurrent (aWorldView);
OpenGl_Mat4& aWorldView = aCtx->WorldViewState.ChangeCurrent();
myTrsfPers->Apply (theWorkspace->View()->Camera(),
aCtx->ProjectionState.Current(), aWorldView,
aCtx->Viewport()[2], aCtx->Viewport()[3]);
#if !defined(GL_ES_VERSION_2_0)
if (!aCtx->IsGlNormalizeEnabled()
&& aCtx->core11 != NULL)
{
const Standard_Real aScale = Graphic3d_TransformUtils::ScaleFactor<Standard_ShortReal> (aWorldView);
if (Abs (aScale - 1.0f) > Precision::Confusion())
if (Abs (aScale - 1.0) > Precision::Confusion())
{
aCtx->SetGlNormalizeEnabled (Standard_True);
}
@ -515,7 +548,7 @@ void OpenGl_Structure::Render (const Handle(OpenGl_Workspace) &theWorkspace) con
bool hasDisabled = false;
if (aCtx->Clipping().IsClippingOrCappingOn())
{
const Graphic3d_BndBox4f& aBBox = BoundingBox();
const Graphic3d_BndBox3d& aBBox = BoundingBox();
if (!myClipPlanes.IsNull()
&& myClipPlanes->ToOverrideGlobal())
{

View File

@ -80,6 +80,12 @@ public:
//! Synchronize structure transformation
Standard_EXPORT virtual void SetTransformation (const Handle(Geom_Transformation)& theTrsf) Standard_OVERRIDE;
//! Set transformation persistence.
Standard_EXPORT virtual void SetTransformPersistence (const Handle(Graphic3d_TransformPers)& theTrsfPers) Standard_OVERRIDE;
//! Set z layer ID to display the structure in specified layer
Standard_EXPORT virtual void SetZLayer(const Graphic3d_ZLayerId theLayerIndex) Standard_OVERRIDE;
//! Highlights structure according to the given style and updates corresponding class fields
//! (highlight status and style)
Standard_EXPORT virtual void GraphicHighlight (const Handle(Graphic3d_HighlightStyle)& theStyle,
@ -161,6 +167,9 @@ public:
//! Is the structure ray-tracable (contains ray-tracable elements)?
Standard_Boolean IsRaytracable() const;
//! Update render transformation matrix.
Standard_EXPORT void updateLayerTransformation();
protected:
Standard_EXPORT virtual ~OpenGl_Structure();
@ -185,6 +194,7 @@ protected:
Handle(OpenGl_Group) myHighlightBox;
OpenGl_Structure* myInstancedStructure;
Graphic3d_Mat4 myRenderTrsf; //!< transformation, actually used for rendering (includes Local Origin shift)
mutable Standard_Boolean myIsRaytracable;
mutable Standard_Size myModificationState;

View File

@ -171,6 +171,29 @@ void OpenGl_View::Remove()
Graphic3d_CView::Remove();
}
// =======================================================================
// function : SetTextureEnv
// purpose :
// =======================================================================
void OpenGl_View::SetCamera(const Handle(Graphic3d_Camera)& theCamera)
{
myCamera = theCamera;
}
// =======================================================================
// function : SetLocalOrigin
// purpose :
// =======================================================================
void OpenGl_View::SetLocalOrigin (const gp_XYZ& theOrigin)
{
myLocalOrigin = theOrigin;
const Handle(OpenGl_Context)& aCtx = myWorkspace->GetGlContext();
if (!aCtx.IsNull())
{
aCtx->ShaderManager()->SetLocalOrigin (theOrigin);
}
}
// =======================================================================
// function : SetTextureEnv
// purpose :
@ -488,13 +511,13 @@ void OpenGl_View::InvalidateZLayerBoundingBox (const Graphic3d_ZLayerId theLayer
//function : ZLayerBoundingBox
//purpose :
//=======================================================================
Graphic3d_BndBox4f OpenGl_View::ZLayerBoundingBox (const Graphic3d_ZLayerId theLayerId,
const Handle(Graphic3d_Camera)& theCamera,
const Standard_Integer theWindowWidth,
const Standard_Integer theWindowHeight,
const Standard_Boolean theToIncludeAuxiliary) const
Bnd_Box OpenGl_View::ZLayerBoundingBox (const Graphic3d_ZLayerId theLayerId,
const Handle(Graphic3d_Camera)& theCamera,
const Standard_Integer theWindowWidth,
const Standard_Integer theWindowHeight,
const Standard_Boolean theToIncludeAuxiliary) const
{
Graphic3d_BndBox4f aBox;
Bnd_Box aBox;
if (myZLayers.LayerIDs().IsBound (theLayerId))
{
aBox = myZLayers.Layer (theLayerId).BoundingBox (Identification(),
@ -515,10 +538,10 @@ Graphic3d_BndBox4f OpenGl_View::ZLayerBoundingBox (const Graphic3d_ZLayerId
// We add here full-screen plane with 2D transformation persistence
// for simplicity (myBgTextureArray might define a little bit different options
// but it is updated within ::Render())
const Graphic3d_Mat4& aProjectionMat = theCamera->ProjectionMatrixF();
const Graphic3d_Mat4& aWorldViewMat = theCamera->OrientationMatrixF();
Graphic3d_BndBox4f aBox2d (Graphic3d_Vec4 (0.0f, 0.0f, 0.0f, 0.0f),
Graphic3d_Vec4 (float(theWindowWidth), float(theWindowHeight), 0.0f, 0.0f));
const Graphic3d_Mat4d& aProjectionMat = theCamera->ProjectionMatrix();
const Graphic3d_Mat4d& aWorldViewMat = theCamera->OrientationMatrix();
Graphic3d_BndBox3d aBox2d (Graphic3d_Vec3d (0.0, 0.0, 0.0),
Graphic3d_Vec3d (double(theWindowWidth), double(theWindowHeight), 0.0));
Graphic3d_TransformPers aTrsfPers (Graphic3d_TMF_2d, Aspect_TOTP_LEFT_LOWER);
aTrsfPers.Apply (theCamera,
@ -527,7 +550,8 @@ Graphic3d_BndBox4f OpenGl_View::ZLayerBoundingBox (const Graphic3d_ZLayerId
theWindowWidth,
theWindowHeight,
aBox2d);
aBox.Combine (aBox2d);
aBox.Add (gp_Pnt (aBox2d.CornerMin().x(), aBox2d.CornerMin().y(), aBox2d.CornerMin().z()));
aBox.Add (gp_Pnt (aBox2d.CornerMax().x(), aBox2d.CornerMax().y(), aBox2d.CornerMax().z()));
}
return aBox;

View File

@ -183,11 +183,11 @@ public:
//! @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
Standard_EXPORT virtual Graphic3d_BndBox4f ZLayerBoundingBox (const Graphic3d_ZLayerId theLayerId,
const Handle(Graphic3d_Camera)& theCamera,
const Standard_Integer theWindowWidth,
const Standard_Integer theWindowHeight,
const Standard_Boolean theToIncludeAuxiliary) const Standard_OVERRIDE;
Standard_EXPORT virtual Bnd_Box ZLayerBoundingBox (const Graphic3d_ZLayerId theLayerId,
const Handle(Graphic3d_Camera)& theCamera,
const Standard_Integer theWindowWidth,
const Standard_Integer theWindowHeight,
const Standard_Boolean theToIncludeAuxiliary) const Standard_OVERRIDE;
//! Returns pointer to an assigned framebuffer object.
Standard_EXPORT virtual Handle(Standard_Transient) FBO() const Standard_OVERRIDE;
@ -268,8 +268,14 @@ public:
//! Returns camera object of the view.
virtual const Handle(Graphic3d_Camera)& Camera() const Standard_OVERRIDE { return myCamera; }
//! Returns local camera origin currently set for rendering, might be modified during rendering.
const gp_XYZ& LocalOrigin() const { return myLocalOrigin; }
//! Setup local camera origin currently set for rendering.
Standard_EXPORT void SetLocalOrigin (const gp_XYZ& theOrigin);
//! Sets camera used by the view.
virtual void SetCamera (const Handle(Graphic3d_Camera)& theCamera) Standard_OVERRIDE { myCamera = theCamera; }
Standard_EXPORT virtual void SetCamera (const Handle(Graphic3d_Camera)& theCamera) Standard_OVERRIDE;
//! Returns list of lights of the view.
virtual const Graphic3d_ListOfCLight& Lights() const Standard_OVERRIDE { return myLights; }
@ -453,6 +459,7 @@ protected:
Quantity_ColorRGBA myBgColor;
Handle(Graphic3d_SequenceOfHClipPlane) myClipPlanes;
Handle(Graphic3d_Camera) myCamera;
gp_XYZ myLocalOrigin;
Handle(OpenGl_FrameBuffer) myFBO;
Standard_Boolean myToShowGradTrihedron;
TCollection_AsciiString myBackgroundImagePath;

View File

@ -2239,9 +2239,9 @@ Standard_Boolean OpenGl_View::updateRaytraceLightSources (const OpenGl_Mat4& the
if (aLight.Type != Graphic3d_TOLS_DIRECTIONAL)
{
aPosition = BVH_Vec4f (aLight.Position.x(),
aLight.Position.y(),
aLight.Position.z(),
aPosition = BVH_Vec4f (static_cast<float>(aLight.Position.x()),
static_cast<float>(aLight.Position.y()),
static_cast<float>(aLight.Position.z()),
1.0f);
// store smoothing radius in w-component

View File

@ -107,10 +107,11 @@ static void bindLight (const OpenGl_Light& theLight,
case Graphic3d_TOLS_POSITIONAL:
{
// to create a realistic effect, set the GL_SPECULAR parameter to the same value as the GL_DIFFUSE
const OpenGl_Vec4 aPosition (static_cast<float>(theLight.Position.x()), static_cast<float>(theLight.Position.y()), static_cast<float>(theLight.Position.z()), 1.0f);
glLightfv (theLightGlId, GL_AMBIENT, THE_DEFAULT_AMBIENT);
glLightfv (theLightGlId, GL_DIFFUSE, theLight.Color.GetData());
glLightfv (theLightGlId, GL_SPECULAR, theLight.Color.GetData());
glLightfv (theLightGlId, GL_POSITION, theLight.Position.GetData());
glLightfv (theLightGlId, GL_POSITION, aPosition.GetData());
glLightfv (theLightGlId, GL_SPOT_DIRECTION, THE_DEFAULT_SPOT_DIR);
glLightf (theLightGlId, GL_SPOT_EXPONENT, THE_DEFAULT_SPOT_EXPONENT);
glLightf (theLightGlId, GL_SPOT_CUTOFF, THE_DEFAULT_SPOT_CUTOFF);
@ -121,10 +122,11 @@ static void bindLight (const OpenGl_Light& theLight,
}
case Graphic3d_TOLS_SPOT:
{
const OpenGl_Vec4 aPosition (static_cast<float>(theLight.Position.x()), static_cast<float>(theLight.Position.y()), static_cast<float>(theLight.Position.z()), 1.0f);
glLightfv (theLightGlId, GL_AMBIENT, THE_DEFAULT_AMBIENT);
glLightfv (theLightGlId, GL_DIFFUSE, theLight.Color.GetData());
glLightfv (theLightGlId, GL_SPECULAR, theLight.Color.GetData());
glLightfv (theLightGlId, GL_POSITION, theLight.Position.GetData());
glLightfv (theLightGlId, GL_POSITION, aPosition.GetData());
glLightfv (theLightGlId, GL_SPOT_DIRECTION, theLight.Direction.GetData());
glLightf (theLightGlId, GL_SPOT_EXPONENT, theLight.Concentration() * 128.0f);
glLightf (theLightGlId, GL_SPOT_CUTOFF, (theLight.Angle() * 180.0f) / GLfloat(M_PI));
@ -241,9 +243,9 @@ void OpenGl_View::Redraw()
myWindow->SetSwapInterval();
++myFrameCounter;
const Graphic3d_StereoMode aStereoMode = myRenderParams.StereoMode;
Graphic3d_Camera::Projection aProjectType = myCamera->ProjectionType();
Handle(OpenGl_Context) aCtx = myWorkspace->GetGlContext();
const Graphic3d_StereoMode aStereoMode = myRenderParams.StereoMode;
Graphic3d_Camera::Projection aProjectType = myCamera->ProjectionType();
Handle(OpenGl_Context) aCtx = myWorkspace->GetGlContext();
// release pending GL resources
aCtx->ReleaseDelayed();
@ -768,31 +770,22 @@ void OpenGl_View::render (Graphic3d_Camera::Projection theProjection,
// Update matrices if camera has changed.
Graphic3d_WorldViewProjState aWVPState = myCamera->WorldViewProjState();
const Standard_Boolean isCameraChanged = myWorldViewProjState != aWVPState;
const Standard_Boolean isSameView = aManager->IsSameView (this);
if (isCameraChanged)
if (myWorldViewProjState != aWVPState)
{
aContext->ProjectionState.SetCurrent (myCamera->ProjectionMatrixF());
aContext->WorldViewState .SetCurrent (myCamera->OrientationMatrixF());
myAccumFrames = 0;
myWorldViewProjState = aWVPState;
}
// Apply new matrix state if camera has changed or this view differs from the one
// that was previously used for configuring matrices of shader manager
// (ApplyProjectionMatrix and ApplyWorldViewMatrix will affect the manager).
if (isCameraChanged || !isSameView)
{
aContext->ApplyProjectionMatrix();
aContext->ApplyWorldViewMatrix();
}
myLocalOrigin.SetCoord (0.0, 0.0, 0.0);
aContext->ProjectionState.SetCurrent (myCamera->ProjectionMatrixF());
aContext->WorldViewState .SetCurrent (myCamera->OrientationMatrixF());
aContext->ApplyProjectionMatrix();
aContext->ApplyWorldViewMatrix();
if (aManager->ModelWorldState().Index() == 0)
{
aContext->ShaderManager()->UpdateModelWorldStateTo (OpenGl_Mat4());
}
myWorldViewProjState = aWVPState;
// ====================================
// Step 2: Redraw background
// ====================================

View File

@ -660,12 +660,12 @@ void StdSelect_ViewerSelector3d::updateZLayers (const Handle(V3d_View)& theView)
for (TColStd_SequenceOfInteger::Iterator aLayerIter (aZLayers); aLayerIter.More(); aLayerIter.Next())
{
Graphic3d_ZLayerSettings aSettings = theView->Viewer()->ZLayerSettings (aLayerIter.Value());
if (aSettings.IsSettingEnabled (Graphic3d_ZLayerDepthClear)
|| isPrevDepthWrite != aSettings.IsSettingEnabled (Graphic3d_ZLayerDepthWrite))
if (aSettings.ToClearDepth()
|| isPrevDepthWrite != aSettings.ToEnableDepthWrite())
{
++aPos;
}
isPrevDepthWrite = aSettings.IsSettingEnabled (Graphic3d_ZLayerDepthWrite);
isPrevDepthWrite = aSettings.ToEnableDepthWrite();
myZLayerOrderMap.Bind (aLayerIter.Value(), aPos);
}
}

View File

@ -119,9 +119,9 @@ void V3d_PositionalLight::SetPosition (const Standard_Real theXp,
const Standard_Real theYp,
const Standard_Real theZp)
{
myLight.Position.x() = static_cast<Standard_ShortReal> (theXp);
myLight.Position.y() = static_cast<Standard_ShortReal> (theYp);
myLight.Position.z() = static_cast<Standard_ShortReal> (theZp);
myLight.Position.x() = theXp;
myLight.Position.y() = theYp;
myLight.Position.z() = theZp;
}
// =======================================================================

View File

@ -113,9 +113,9 @@ void V3d_SpotLight::SetPosition (const Standard_Real theXp,
const Standard_Real theYp,
const Standard_Real theZp)
{
myLight.Position.x() = static_cast<Standard_ShortReal> (theXp);
myLight.Position.y() = static_cast<Standard_ShortReal> (theYp);
myLight.Position.z() = static_cast<Standard_ShortReal> (theZp);
myLight.Position.x() = theXp;
myLight.Position.y() = theYp;
myLight.Position.z() = theZp;
}
// =======================================================================

View File

@ -2113,7 +2113,7 @@ void V3d_View::Gravity (Standard_Real& theX,
continue;
}
const Graphic3d_BndBox4f& aBox = aStruct->CStructure()->BoundingBox();
const Graphic3d_BndBox3d& aBox = aStruct->CStructure()->BoundingBox();
if (!aBox.IsValid())
{
continue;
@ -2126,12 +2126,12 @@ void V3d_View::Gravity (Standard_Real& theX,
}
// use camera projection to find gravity point
Xmin = (Standard_Real )aBox.CornerMin().x();
Ymin = (Standard_Real )aBox.CornerMin().y();
Zmin = (Standard_Real )aBox.CornerMin().z();
Xmax = (Standard_Real )aBox.CornerMax().x();
Ymax = (Standard_Real )aBox.CornerMax().y();
Zmax = (Standard_Real )aBox.CornerMax().z();
Xmin = aBox.CornerMin().x();
Ymin = aBox.CornerMin().y();
Zmin = aBox.CornerMin().z();
Xmax = aBox.CornerMax().x();
Ymax = aBox.CornerMax().y();
Zmax = aBox.CornerMax().z();
gp_Pnt aPnts[THE_NB_BOUND_POINTS] =
{
gp_Pnt (Xmin, Ymin, Zmin), gp_Pnt (Xmin, Ymin, Zmax),

View File

@ -4391,210 +4391,377 @@ static int VTile (Draw_Interpretor& theDI,
return 0;
}
//! Format ZLayer ID.
inline const char* formZLayerId (const Standard_Integer theLayerId)
{
switch (theLayerId)
{
case Graphic3d_ZLayerId_UNKNOWN: return "[INVALID]";
case Graphic3d_ZLayerId_Default: return "[DEFAULT]";
case Graphic3d_ZLayerId_Top: return "[TOP]";
case Graphic3d_ZLayerId_Topmost: return "[TOPMOST]";
case Graphic3d_ZLayerId_TopOSD: return "[OVERLAY]";
case Graphic3d_ZLayerId_BotOSD: return "[UNDERLAY]";
}
return "";
}
//! Print the ZLayer information.
inline void printZLayerInfo (Draw_Interpretor& theDI,
const Graphic3d_ZLayerSettings& theLayer)
{
if (!theLayer.Name().IsEmpty())
{
theDI << " Name: " << theLayer.Name() << "\n";
}
if (theLayer.IsImmediate())
{
theDI << " Immediate: TRUE\n";
}
theDI << " Origin: " << theLayer.Origin().X() << " " << theLayer.Origin().Y() << " " << theLayer.Origin().Z() << "\n";
theDI << " Depth test: " << (theLayer.ToEnableDepthTest() ? "enabled" : "disabled") << "\n";
theDI << " Depth write: " << (theLayer.ToEnableDepthWrite() ? "enabled" : "disabled") << "\n";
theDI << " Depth buffer clearing: " << (theLayer.ToClearDepth() ? "enabled" : "disabled") << "\n";
if (theLayer.PolygonOffset().Mode != Aspect_POM_None)
{
theDI << " Depth offset: " << theLayer.PolygonOffset().Factor << " " << theLayer.PolygonOffset().Units << "\n";
}
}
//==============================================================================
//function : VZLayer
//purpose : Test z layer operations for v3d viewer
//==============================================================================
static int VZLayer (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
static int VZLayer (Draw_Interpretor& theDI,
Standard_Integer theArgNb,
const char** theArgVec)
{
Handle(AIS_InteractiveContext) aContextAIS = ViewerTest::GetAISContext ();
Handle(AIS_InteractiveContext) aContextAIS = ViewerTest::GetAISContext();
if (aContextAIS.IsNull())
{
di << "Call vinit before!\n";
return 1;
}
else if (argc < 2)
{
di << di.PrintHelp (argv[0]);
std::cout << "No active viewer!\n";
return 1;
}
const Handle(V3d_Viewer)& aViewer = aContextAIS->CurrentViewer();
if (aViewer.IsNull())
if (theArgNb < 2)
{
di << "No active viewer!\n";
TColStd_SequenceOfInteger aLayers;
aViewer->GetAllZLayers (aLayers);
for (TColStd_SequenceOfInteger::Iterator aLayeriter (aLayers); aLayeriter.More(); aLayeriter.Next())
{
theDI << "ZLayer " << aLayeriter.Value() << " " << formZLayerId (aLayeriter.Value()) << "\n";
Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayeriter.Value());
printZLayerInfo (theDI, aSettings);
}
return 1;
}
// perform operation
TCollection_AsciiString anOp = TCollection_AsciiString (argv[1]);
if (anOp == "add")
Standard_Integer anArgIter = 1;
Standard_Integer aLayerId = Graphic3d_ZLayerId_UNKNOWN;
ViewerTest_AutoUpdater anUpdateTool (aContextAIS, ViewerTest::CurrentView());
if (anUpdateTool.parseRedrawMode (theArgVec[anArgIter]))
{
Standard_Integer aNewId;
if (!aViewer->AddZLayer (aNewId))
{
di << "Impossible to add new z layer!\n";
return 1;
}
di << "New z layer added with index: " << aNewId << "\n";
++anArgIter;
}
else if (anOp == "del")
TCollection_AsciiString aFirstArg (theArgVec[anArgIter]);
if (aFirstArg.IsIntegerValue())
{
if (argc < 3)
{
di << "Please also provide as argument id of z layer to remove\n";
return 1;
}
Standard_Integer aDelId = Draw::Atoi (argv[2]);
if (!aViewer->RemoveZLayer (aDelId))
{
di << "Impossible to remove the z layer or invalid id!\n";
return 1;
}
for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anObjIter (GetMapOfAIS());
anObjIter.More(); anObjIter.Next())
{
Handle(PrsMgr_PresentableObject) aPrs = Handle(PrsMgr_PresentableObject)::DownCast (anObjIter.Key1());
if (aPrs.IsNull()
|| aPrs->ZLayer() != aDelId)
{
continue;
}
aPrs->SetZLayer (Graphic3d_ZLayerId_Default);
}
di << "Z layer " << aDelId << " has been removed\n";
}
else if (anOp == "get")
{
TColStd_SequenceOfInteger anIds;
aViewer->GetAllZLayers (anIds);
for (Standard_Integer aSeqIdx = 1; aSeqIdx <= anIds.Length(); aSeqIdx++)
{
di << anIds.Value (aSeqIdx) << " ";
}
di << "\n";
}
else if (anOp == "settings")
{
if (argc < 3)
{
di << "Please also provide an id\n";
return 1;
}
Standard_Integer anId = Draw::Atoi (argv[2]);
Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (anId);
di << "Depth test - " << (aSettings.IsSettingEnabled (Graphic3d_ZLayerDepthTest) ? "enabled" : "disabled") << "\n";
di << "Depth write - " << (aSettings.IsSettingEnabled (Graphic3d_ZLayerDepthWrite) ? "enabled" : "disabled") << "\n";
di << "Depth buffer clearing - " << (aSettings.IsSettingEnabled (Graphic3d_ZLayerDepthClear) ? "enabled" : "disabled") << "\n";
di << "Depth offset - " << (aSettings.IsSettingEnabled (Graphic3d_ZLayerDepthOffset) ? "enabled" : "disabled") << "\n";
}
else if (anOp == "enable")
{
if (argc < 3)
{
di << "Please also provide an option to enable\n";
return 1;
}
if (argc < 4)
{
di << "Please also provide a layer id\n";
return 1;
}
TCollection_AsciiString aSubOp = TCollection_AsciiString (argv[2]);
Standard_Integer anId = Draw::Atoi (argv[3]);
Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (anId);
if (aSubOp == "depthtest" || aSubOp == "test")
{
aSettings.EnableSetting (Graphic3d_ZLayerDepthTest);
}
else if (aSubOp == "depthwrite" || aSubOp == "write")
{
aSettings.EnableSetting (Graphic3d_ZLayerDepthWrite);
}
else if (aSubOp == "depthclear" || aSubOp == "clear")
{
aSettings.EnableSetting (Graphic3d_ZLayerDepthClear);
}
else if (aSubOp == "depthoffset" || aSubOp == "offset")
{
if (argc < 6)
{
di << "Please also provide a factor and units values for depth offset\n";
di << "Format is: vzlayer enable offset [factor] [units] [layerId]\n";
return 1;
}
Standard_ShortReal aFactor = static_cast<Standard_ShortReal> (Draw::Atof (argv[3]));
Standard_ShortReal aUnits = static_cast<Standard_ShortReal> (Draw::Atof (argv[4]));
anId = Draw::Atoi (argv[5]);
aSettings = aViewer->ZLayerSettings (anId);
aSettings.DepthOffsetFactor = aFactor;
aSettings.DepthOffsetUnits = aUnits;
aSettings.EnableSetting (Graphic3d_ZLayerDepthOffset);
}
else if (aSubOp == "positiveoffset" || aSubOp == "poffset")
{
aSettings.SetDepthOffsetPositive();
}
else if (aSubOp == "negativeoffset" || aSubOp == "noffset")
{
aSettings.SetDepthOffsetNegative();
}
else if (aSubOp == "textureenv")
{
aSettings.UseEnvironmentTexture = true;
}
aViewer->SetZLayerSettings (anId, aSettings);
}
else if (anOp == "disable")
{
if (argc < 3)
{
di << "Please also provide an option to disable\n";
return 1;
}
if (argc < 4)
{
di << "Please also provide a layer id\n";
return 1;
}
TCollection_AsciiString aSubOp = TCollection_AsciiString (argv[2]);
Standard_Integer anId = Draw::Atoi (argv[3]);
Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (anId);
if (aSubOp == "depthtest" || aSubOp == "test")
{
aSettings.DisableSetting (Graphic3d_ZLayerDepthTest);
}
else if (aSubOp == "depthwrite" || aSubOp == "write")
{
aSettings.DisableSetting (Graphic3d_ZLayerDepthWrite);
}
else if (aSubOp == "depthclear" || aSubOp == "clear")
{
aSettings.DisableSetting (Graphic3d_ZLayerDepthClear);
}
else if (aSubOp == "depthoffset" || aSubOp == "offset")
{
aSettings.DisableSetting (Graphic3d_ZLayerDepthOffset);
}
else if (aSubOp == "textureenv")
{
aSettings.UseEnvironmentTexture = false;
}
aViewer->SetZLayerSettings (anId, aSettings);
++anArgIter;
aLayerId = aFirstArg.IntegerValue();
}
else
{
di << "Invalid operation, please use { add / del / get / settings / enable / disable}\n";
return 1;
aFirstArg.LowerCase();
if (aFirstArg == "default"
|| aFirstArg == "def")
{
aLayerId = Graphic3d_ZLayerId_Default;
++anArgIter;
}
else if (aFirstArg == "top")
{
aLayerId = Graphic3d_ZLayerId_Top;
++anArgIter;
}
else if (aFirstArg == "topmost")
{
aLayerId = Graphic3d_ZLayerId_Topmost;
++anArgIter;
}
else if (aFirstArg == "overlay"
|| aFirstArg == "toposd")
{
aLayerId = Graphic3d_ZLayerId_TopOSD;
++anArgIter;
}
else if (aFirstArg == "underlay"
|| aFirstArg == "botosd")
{
aLayerId = Graphic3d_ZLayerId_BotOSD;
++anArgIter;
}
else
{
TColStd_SequenceOfInteger aLayers;
aViewer->GetAllZLayers (aLayers);
for (TColStd_SequenceOfInteger::Iterator aLayeriter (aLayers); aLayeriter.More(); aLayeriter.Next())
{
Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayeriter.Value());
if (TCollection_AsciiString::IsSameString (aSettings.Name(), aFirstArg, Standard_False))
{
aLayerId = aLayeriter.Value();
++anArgIter;
break;
}
}
}
}
for (; anArgIter < theArgNb; ++anArgIter)
{
// perform operation
TCollection_AsciiString anArg (theArgVec[anArgIter]);
anArg.LowerCase();
if (anUpdateTool.parseRedrawMode (anArg))
{
//
}
else if (anArg == "-add"
|| anArg == "add")
{
aLayerId = Graphic3d_ZLayerId_UNKNOWN;
if (!aViewer->AddZLayer (aLayerId))
{
std::cout << "Error: can not add a new z layer!\n";
return 0;
}
theDI << aLayerId;
}
else if (anArg == "-del"
|| anArg == "-delete"
|| anArg == "del")
{
if (aLayerId == Graphic3d_ZLayerId_UNKNOWN)
{
if (++anArgIter >= theArgNb)
{
std::cout << "Syntax error: id of z layer to remove is missing\n";
return 1;
}
aLayerId = Draw::Atoi (theArgVec[anArgIter]);
}
if (aLayerId == Graphic3d_ZLayerId_UNKNOWN
|| aLayerId == Graphic3d_ZLayerId_Default
|| aLayerId == Graphic3d_ZLayerId_Top
|| aLayerId == Graphic3d_ZLayerId_Topmost
|| aLayerId == Graphic3d_ZLayerId_TopOSD
|| aLayerId == Graphic3d_ZLayerId_BotOSD)
{
std::cout << "Syntax error: standard Z layer can not be removed\n";
return 1;
}
// move all object displayed in removing layer to default layer
for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anObjIter (GetMapOfAIS());
anObjIter.More(); anObjIter.Next())
{
Handle(PrsMgr_PresentableObject) aPrs = Handle(PrsMgr_PresentableObject)::DownCast (anObjIter.Key1());
if (aPrs.IsNull()
|| aPrs->ZLayer() != aLayerId)
{
continue;
}
aPrs->SetZLayer (Graphic3d_ZLayerId_Default);
}
if (!aViewer->RemoveZLayer (aLayerId))
{
std::cout << "Z layer can not be removed!\n";
}
else
{
theDI << aLayerId << " ";
}
}
else if (anArg == "-get"
|| anArg == "get")
{
TColStd_SequenceOfInteger aLayers;
aViewer->GetAllZLayers (aLayers);
for (TColStd_SequenceOfInteger::Iterator aLayeriter (aLayers); aLayeriter.More(); aLayeriter.Next())
{
theDI << aLayeriter.Value() << " ";
}
theDI << "\n";
}
else if (anArg == "-name")
{
if (aLayerId == Graphic3d_ZLayerId_UNKNOWN)
{
std::cout << "Syntax error: id of Z layer is missing\n";
return 1;
}
if (++anArgIter >= theArgNb)
{
std::cout << "Syntax error: name is missing\n";
return 1;
}
Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayerId);
aSettings.SetName (theArgVec[anArgIter]);
aViewer->SetZLayerSettings (aLayerId, aSettings);
}
else if (anArg == "-origin")
{
if (aLayerId == Graphic3d_ZLayerId_UNKNOWN)
{
std::cout << "Syntax error: id of Z layer is missing\n";
return 1;
}
if (anArgIter + 2 >= theArgNb)
{
std::cout << "Syntax error: origin coordinates are missing\n";
return 1;
}
Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayerId);
gp_XYZ anOrigin;
anOrigin.SetX (Draw::Atof (theArgVec[anArgIter + 1]));
anOrigin.SetY (Draw::Atof (theArgVec[anArgIter + 2]));
anOrigin.SetZ (0.0);
if (anArgIter + 3 < theArgNb)
{
anOrigin.SetZ (Draw::Atof (theArgVec[anArgIter + 3]));
anArgIter += 3;
}
else
{
anArgIter += 2;
}
aSettings.SetOrigin (anOrigin);
aViewer->SetZLayerSettings (aLayerId, aSettings);
}
else if (anArg == "-settings"
|| anArg == "settings")
{
if (aLayerId == Graphic3d_ZLayerId_UNKNOWN)
{
if (++anArgIter >= theArgNb)
{
std::cout << "Syntax error: id of Z layer is missing\n";
return 1;
}
aLayerId = Draw::Atoi (theArgVec[anArgIter]);
}
Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayerId);
printZLayerInfo (theDI, aSettings);
}
else if (anArg == "-enable"
|| anArg == "enable"
|| anArg == "-disable"
|| anArg == "disable")
{
const Standard_Boolean toEnable = anArg == "-enable"
|| anArg == "enable";
if (++anArgIter >= theArgNb)
{
std::cout << "Syntax error: option name is missing\n";
return 1;
}
TCollection_AsciiString aSubOp (theArgVec[anArgIter]);
aSubOp.LowerCase();
if (aLayerId == Graphic3d_ZLayerId_UNKNOWN)
{
if (++anArgIter >= theArgNb)
{
std::cout << "Syntax error: id of Z layer is missing\n";
return 1;
}
aLayerId = Draw::Atoi (theArgVec[anArgIter]);
}
Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayerId);
if (aSubOp == "depthtest"
|| aSubOp == "test")
{
aSettings.SetEnableDepthTest (toEnable);
}
else if (aSubOp == "depthwrite"
|| aSubOp == "write")
{
aSettings.SetEnableDepthWrite (toEnable);
}
else if (aSubOp == "depthclear"
|| aSubOp == "clear")
{
aSettings.SetClearDepth (toEnable);
}
else if (aSubOp == "depthoffset"
|| aSubOp == "offset")
{
Graphic3d_PolygonOffset aParams;
aParams.Mode = toEnable ? Aspect_POM_Fill : Aspect_POM_None;
if (toEnable)
{
if (anArgIter + 2 >= theArgNb)
{
std::cout << "Syntax error: factor and units values for depth offset are missing\n";
return 1;
}
aParams.Factor = static_cast<Standard_ShortReal> (Draw::Atof (theArgVec[++anArgIter]));
aParams.Units = static_cast<Standard_ShortReal> (Draw::Atof (theArgVec[++anArgIter]));
}
aSettings.SetPolygonOffset (aParams);
}
else if (aSubOp == "positiveoffset"
|| aSubOp == "poffset")
{
if (toEnable)
{
aSettings.SetDepthOffsetPositive();
}
else
{
aSettings.SetPolygonOffset (Graphic3d_PolygonOffset());
}
}
else if (aSubOp == "negativeoffset"
|| aSubOp == "noffset")
{
if (toEnable)
{
aSettings.SetDepthOffsetNegative();
}
else
{
aSettings.SetPolygonOffset(Graphic3d_PolygonOffset());
}
}
else if (aSubOp == "textureenv")
{
aSettings.SetEnvironmentTexture (toEnable);
}
aViewer->SetZLayerSettings (aLayerId, aSettings);
}
else
{
std::cout << "Syntax error: unknown option " << theArgVec[anArgIter] << "\n";
return 1;
}
}
return 0;
@ -9364,22 +9531,17 @@ void ViewerTest::ViewerCommands(Draw_Interpretor& theCommands)
"\n\t\t: -upperLeft tile offset as upper left corner",
__FILE__, VTile, group);
theCommands.Add("vzlayer",
"vzlayer add/del/get/settings/enable/disable [id]\n"
" add - add new z layer to viewer and print its id\n"
" del - del z layer by its id\n"
" get - print sequence of z layers in increasing order of their overlay level\n"
" settings - print status of z layer settings\n"
" enable ([depth]test/[depth]write/[depth]clear/[depth]offset) \n enables given setting for the z layer\n"
" enable (p[ositive]offset/n[egative]offset) \n enables given setting for the z layer\n"
" enable textureenv \n enables environment texture mapping\n"
" disable ([depth]test/[depth]write/[depth]clear/[depth]offset) \n disables given setting for the z layer\n"
" disable textureenv \n disables environment texture mapping\n"
"\nWhere id is the layer identificator\n"
"\nExamples:\n"
" vzlayer add\n"
" vzlayer enable poffset 1\n"
" vzlayer disable depthtest 1\n"
" vzlayer del 1\n",
"vzlayer [layerId]"
"\n\t\t: [-add|-delete|-get|-settings]"
"\n\t\t: [-enable|-disable {depthTest|depthWrite|depthClear|depthoffset}]"
"\n\t\t: [-enable|-disable {positiveOffset|negativeOffset|textureenv}]"
"\n\t\t: ZLayer list management:"
"\n\t\t: -add add new z layer to viewer and print its id"
"\n\t\t: -delete delete z layer"
"\n\t\t: -get print sequence of z layers"
"\n\t\t: -settings print status of z layer settings"
"\n\t\t: -disable disables given setting"
"\n\t\t: -enable enables given setting",
__FILE__,VZLayer,group);
theCommands.Add("vlayerline",
"vlayerline : vlayerline x1 y1 x2 y2 [linewidth=0.5] [linetype=0] [transparency=1.0]",

View File

@ -11,11 +11,11 @@ vertex v 100 -300 0
vclear
vinit View1
catch { vzlayer del 1 }
vzlayer add 1
vzlayer enable 1 depthclear
set aLayerId [vzlayer add]
vzlayer ${aLayerId} -enable depthClear
vaxo
vdisplay -noupdate -dispMode 1 -highMode 1 b1
vdisplay -noupdate -dispMode 1 -highMode 1 -layer 1 b2
vdisplay -noupdate -dispMode 1 -highMode 1 -layer ${aLayerId} b2
vsetcolor -noupdate b1 RED
vsetcolor -noupdate b2 GREEN
vfit

View File

@ -0,0 +1,54 @@
puts "========"
puts "0024393: Visualization - objects position with enchanced precision"
puts "========"
pload MODELING VISUALIZATION
vclear
vinit View1
vaxo
vzbufftrihedron
circle c 0 0 0 0.001
mkedge e c
wire w e
plane s
mkface f0 s w
mkface f1000 s w
ttranslate f1000 1000 0 0
# Display object with pre-applied transformation.
# Result presentation is already corrupted
# AND it jumps while rotating the camera.
vpoint v1000 1000 0 0.001
vdisplay -dispMode 1 f1000
vfit
# Display object with external transformation.
# Result presentation jumps while rotating the camera.
vdisplay -dispMode 1 f0
vsetlocation f0 1000 0 0
# Display object with external transformation
# in Z-layer with translated Origin.
# Result presentation does not jump while rotating the camera.
vzlayer top -origin 1000 0 0
vdisplay -dispMode 1 -top f0
# check transformation persistence
vtrihedron tt
vdisplay -top -trihedron topLeft 100 100 tt
box zp 40 50 30
vdisplay -top -dispMode 1 -trsfPers zoom -trsfPersPos 1000 0 0 zp
# check clippling planes
vclipplane pln -equation -1 0 0 1000 -set
# check positional lights
vlight add positional pos 1000 0 0.001 color RED1 headlight 0
vremove f1000
vmoveto 220 220
vdrawtext text Text -pos 0 0 0
vdisplay -top text -trsfPers zoomRotate -trsfPersPos 1000 0 0.001
vdump $::imagedir/${::casename}.png

View File

@ -26,40 +26,40 @@ vrotate 0.5 0 0
vzbufftrihedron
catch { vzlayer del 1 }
vzlayer add 1
vzlayer enable 1 depthclear
set aLayerId [vzlayer add]
vzlayer $aLayerId -enable depthClear
vtrihedron trh
vdisplay -noupdate trh -layer 1 -trihedron topRight 100 100
vdisplay -noupdate trh -layer $aLayerId -trihedron topRight 100 100
text2brep tcc "Center" -font $aLabelFont -height 30 -pos -40 0 0
vdisplay -noupdate tcc -2d center -layer 1 -dispMode 1
vdisplay -noupdate tcc -2d center -layer $aLayerId -dispMode 1
polyline lcc -50 -50 0 -50 50 0 50 50 0 50 0 0 0 -50 0 -50 -50 0
vdisplay -noupdate lcc -2d center -layer 1
vdisplay -noupdate lcc -2d center -layer $aLayerId
vsetwidth -noupdate lcc 2
text2brep tbl "Bottom-Left" -font $aLabelFont -height 30 -pos 0 3 5
vdisplay -noupdate tbl -2d bottomLeft -layer 1 -dispMode 1
vdisplay -noupdate tbl -2d bottomLeft -layer $aLayerId -dispMode 1
polyline lbl 0 0 0 0 100 0 100 100 0 100 50 0 50 0 0 0 0 0
vdisplay -noupdate lbl -2d bottomLeft -layer 1
vdisplay -noupdate lbl -2d bottomLeft -layer $aLayerId
vsetwidth -noupdate lbl 2
text2brep ttl "Top-Left" -font $aLabelFont -height 30 -pos 0 -30 0
vdisplay -noupdate ttl -2d topLeft -layer 1 -dispMode 1
vdisplay -noupdate ttl -2d topLeft -layer $aLayerId -dispMode 1
polyline ltl 0 -100 0 0 0 0 100 0 0 100 -50 0 50 -100 0 0 -100 0
vdisplay -noupdate ltl -2d topLeft -layer 1
vdisplay -noupdate ltl -2d topLeft -layer $aLayerId
vsetwidth -noupdate ltl 2
text2brep ttr "Top-Right" -font $aLabelFont -height 30 -pos -130 -30 0
vdisplay -noupdate ttr -2d topRight -layer 1 -dispMode 1
vdisplay -noupdate ttr -2d topRight -layer $aLayerId -dispMode 1
polyline ltr -100 -100 0 -100 0 0 0 0 0 0 -50 0 -50 -100 0 -100 -100 0
vdisplay -noupdate ltr -2d topRight -layer 1
vdisplay -noupdate ltr -2d topRight -layer $aLayerId
vsetwidth -noupdate ltr 2
text2brep tbr "Bottom-Right" -font $aLabelFont -height 30 -pos -180 3 0
vdisplay -noupdate tbr -2d bottomRight -layer 1 -dispMode 1
vdisplay -noupdate tbr -2d bottomRight -layer $aLayerId -dispMode 1
polyline lbr -100 0 0 -100 100 0 0 100 0 0 50 0 -50 0 0 -100 0 0
vdisplay -noupdate lbr -2d bottomRight -layer 1
vdisplay -noupdate lbr -2d bottomRight -layer $aLayerId
vsetwidth -noupdate lbr 2
vdrawtext t2 "Label" -pos 1 0 1 -font $aLabelFont