From: kgv Date: Mon, 8 Apr 2019 13:22:20 +0000 (+0300) Subject: 0030635: Visualization - move OpenGl_Layer to Graphic3d_Layer X-Git-Tag: V7_4_0_beta~181 X-Git-Url: http://git.dev.opencascade.org/gitweb/?p=occt.git;a=commitdiff_plain;h=d325cb7f570c25d36b64c5ac45be72d0371b7f6b 0030635: Visualization - move OpenGl_Layer to Graphic3d_Layer Renamed classes (moved from TKOpenGl to TKV3d): - OpenGl_Layer -> Graphic3d_Layer; - OpenGl_BVHClipPrimitiveSet -> Graphic3d_BvhCStructureSet; - OpenGl_BVHClipPrimitiveTrsfPersSet -> Graphic3d_BvhCStructureSetTrsfPers; - OpenGl_BVHTreeSelector -> Graphic3d_CullingTool. Method OpenGl_Layer::Render() has been moved to OpenGl_LayerList::renderLayer(). Standard Z-layers list definition has been moved from OpenGl_GraphicDriver to base class Graphic3d_GraphicDriver. --- diff --git a/src/Graphic3d/FILES b/src/Graphic3d/FILES index 1c78cae641..2e0b1fa60d 100755 --- a/src/Graphic3d/FILES +++ b/src/Graphic3d/FILES @@ -33,6 +33,10 @@ Graphic3d_Buffer.cxx Graphic3d_Buffer.hxx Graphic3d_BufferRange.hxx Graphic3d_BufferType.hxx +Graphic3d_BvhCStructureSet.cxx +Graphic3d_BvhCStructureSet.hxx +Graphic3d_BvhCStructureSetTrsfPers.cxx +Graphic3d_BvhCStructureSetTrsfPers.hxx Graphic3d_Camera.cxx Graphic3d_Camera.hxx Graphic3d_CameraTile.hxx @@ -44,6 +48,8 @@ Graphic3d_ClipPlane.hxx Graphic3d_CStructure.cxx Graphic3d_CStructure.hxx Graphic3d_CTexture.hxx +Graphic3d_CullingTool.cxx +Graphic3d_CullingTool.hxx Graphic3d_CView.cxx Graphic3d_CView.hxx Graphic3d_DataStructureManager.cxx @@ -78,6 +84,7 @@ Graphic3d_MapOfAspectsToAspects.hxx Graphic3d_MapIteratorOfMapOfStructure.hxx Graphic3d_MapOfObject.hxx Graphic3d_MapOfStructure.hxx +Graphic3d_MapOfZLayerSettings.hxx Graphic3d_MarkerImage.cxx Graphic3d_MarkerImage.hxx Graphic3d_Mat4.hxx @@ -173,5 +180,7 @@ Graphic3d_VerticalTextAlignment.hxx Graphic3d_ViewAffinity.cxx Graphic3d_ViewAffinity.hxx Graphic3d_WorldViewProjState.hxx +Graphic3d_Layer.cxx +Graphic3d_Layer.hxx Graphic3d_ZLayerId.hxx Graphic3d_ZLayerSettings.hxx diff --git a/src/Graphic3d/Graphic3d_BvhCStructureSet.cxx b/src/Graphic3d/Graphic3d_BvhCStructureSet.cxx new file mode 100644 index 0000000000..bff09f3a82 --- /dev/null +++ b/src/Graphic3d/Graphic3d_BvhCStructureSet.cxx @@ -0,0 +1,130 @@ +// Created on: 2013-12-25 +// Created by: Varvara POSKONINA +// Copyright (c) 1999-2014 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#include + +#include +#include + +IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_BvhCStructureSet, BVH_PrimitiveSet3d) + +// ======================================================================= +// function : Graphic3d_BvhCStructureSet +// purpose : +// ======================================================================= +Graphic3d_BvhCStructureSet::Graphic3d_BvhCStructureSet() +{ + myBuilder = new BVH_BinnedBuilder (BVH_Constants_LeafNodeSizeSingle, BVH_Constants_MaxTreeDepth); +} + +// ======================================================================= +// function : Size +// purpose : +// ======================================================================= +Standard_Integer Graphic3d_BvhCStructureSet::Size() const +{ + return myStructs.Size(); +} + +// ======================================================================= +// function : Box +// purpose : +// ======================================================================= +Graphic3d_BndBox3d Graphic3d_BvhCStructureSet::Box (const Standard_Integer theIdx) const +{ + return myStructs.FindKey (theIdx + 1)->BoundingBox(); +} + +// ======================================================================= +// function : Center +// purpose : +// ======================================================================= +Standard_Real Graphic3d_BvhCStructureSet::Center (const Standard_Integer theIdx, + const Standard_Integer theAxis) const +{ + Graphic3d_BndBox3d aBndBox = myStructs.FindKey (theIdx + 1)->BoundingBox(); + + const Standard_Real aMin = aBndBox.CornerMin()[theAxis]; + const Standard_Real aMax = aBndBox.CornerMax()[theAxis]; + const Standard_Real aCenter = (aMin + aMax) * 0.5; + return aCenter; +} + +// ======================================================================= +// function : Swap +// purpose : +// ======================================================================= +void Graphic3d_BvhCStructureSet::Swap (const Standard_Integer theIdx1, + const Standard_Integer theIdx2) +{ + myStructs.Swap (theIdx1 + 1, theIdx2 + 1); +} + +// ======================================================================= +// function : Add +// purpose : +// ======================================================================= +Standard_Boolean Graphic3d_BvhCStructureSet::Add (const Graphic3d_CStructure* theStruct) +{ + const Standard_Integer aSize = myStructs.Size(); + + if (myStructs.Add (theStruct) > aSize) // new structure? + { + MarkDirty(); + + return Standard_True; + } + + return Standard_False; +} + +// ======================================================================= +// function : Remove +// purpose : +// ======================================================================= +Standard_Boolean Graphic3d_BvhCStructureSet::Remove (const Graphic3d_CStructure* theStruct) +{ + const Standard_Integer anIndex = myStructs.FindIndex (theStruct); + + if (anIndex != 0) + { + myStructs.Swap (Size(), anIndex); + myStructs.RemoveLast(); + MarkDirty(); + + return Standard_True; + } + + return Standard_False; +} + +// ======================================================================= +// function : Clear +// purpose : +// ======================================================================= +void Graphic3d_BvhCStructureSet::Clear() +{ + myStructs.Clear(); + MarkDirty(); +} + +// ======================================================================= +// function : GetStructureById +// purpose : +// ======================================================================= +const Graphic3d_CStructure* Graphic3d_BvhCStructureSet::GetStructureById (Standard_Integer theId) +{ + return myStructs.FindKey (theId + 1); +} diff --git a/src/Graphic3d/Graphic3d_BvhCStructureSet.hxx b/src/Graphic3d/Graphic3d_BvhCStructureSet.hxx new file mode 100644 index 0000000000..a46145717a --- /dev/null +++ b/src/Graphic3d/Graphic3d_BvhCStructureSet.hxx @@ -0,0 +1,75 @@ +// Created on: 2013-12-25 +// Created by: Varvara POSKONINA +// Copyright (c) 1999-2014 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _Graphic3d_BvhCStructureSet_HeaderFile +#define _Graphic3d_BvhCStructureSet_HeaderFile + +#include +#include +#include + +class Graphic3d_CStructure; + +//! Set of OpenGl_Structures for building BVH tree. +class Graphic3d_BvhCStructureSet : public BVH_PrimitiveSet3d +{ + DEFINE_STANDARD_RTTIEXT(Graphic3d_BvhCStructureSet, BVH_PrimitiveSet3d) +protected: + + using BVH_PrimitiveSet3d::Box; + +public: + + //! Creates an empty primitive set for BVH clipping. + Graphic3d_BvhCStructureSet(); + + //! Returns total number of structures. + virtual Standard_Integer Size() const Standard_OVERRIDE; + + //! Returns AABB of the structure. + virtual Graphic3d_BndBox3d Box (const Standard_Integer theIdx) const Standard_OVERRIDE; + + //! Calculates center of the AABB along given axis. + 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, + const Standard_Integer theIdx2) Standard_OVERRIDE; + + //! Adds structure to the set. + //! @return true if structure added, otherwise returns false (structure already in the set). + Standard_Boolean Add (const Graphic3d_CStructure* theStruct); + + //! Removes the given structure from the set. + //! @return true if structure removed, otherwise returns false (structure is not in the set). + Standard_Boolean Remove (const Graphic3d_CStructure* theStruct); + + //! Cleans the whole primitive set. + void Clear(); + + //! Returns the structure corresponding to the given ID. + const Graphic3d_CStructure* GetStructureById (Standard_Integer theId); + + //! Access directly a collection of structures. + const NCollection_IndexedMap& Structures() const { return myStructs; } + +private: + + NCollection_IndexedMap myStructs; //!< Indexed map of structures. + +}; + +#endif // _Graphic3d_BvhCStructureSet_HeaderFile diff --git a/src/Graphic3d/Graphic3d_BvhCStructureSetTrsfPers.cxx b/src/Graphic3d/Graphic3d_BvhCStructureSetTrsfPers.cxx new file mode 100644 index 0000000000..95b0ff7322 --- /dev/null +++ b/src/Graphic3d/Graphic3d_BvhCStructureSetTrsfPers.cxx @@ -0,0 +1,173 @@ +// Created on: 2015-06-30 +// Created by: Anton POLETAEV +// Copyright (c) 2015 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#include + +#include + +// ======================================================================= +// function : Graphic3d_BvhCStructureSetTrsfPers +// purpose : +// ======================================================================= +Graphic3d_BvhCStructureSetTrsfPers::Graphic3d_BvhCStructureSetTrsfPers (const Handle(Select3D_BVHBuilder3d)& theBuilder) +: myIsDirty (Standard_False), + myBVH (new BVH_Tree()), + myBuilder (theBuilder) +{ + // +} + +// ======================================================================= +// function : Size +// purpose : +// ======================================================================= +Standard_Integer Graphic3d_BvhCStructureSetTrsfPers::Size() const +{ + return myStructs.Size(); +} + +// ======================================================================= +// function : Box +// purpose : +// ======================================================================= +Graphic3d_BndBox3d Graphic3d_BvhCStructureSetTrsfPers::Box (const Standard_Integer theIdx) const +{ + return *myStructBoxes (theIdx + 1); +} + +// ======================================================================= +// function : Center +// purpose : +// ======================================================================= +Standard_Real Graphic3d_BvhCStructureSetTrsfPers::Center (const Standard_Integer theIdx, + const Standard_Integer theAxis) const +{ + const Graphic3d_BndBox3d& aBndBox = *myStructBoxes (theIdx + 1); + return (aBndBox.CornerMin()[theAxis] + aBndBox.CornerMax()[theAxis]) * 0.5; +} + +// ======================================================================= +// function : Swap +// purpose : +// ======================================================================= +void Graphic3d_BvhCStructureSetTrsfPers::Swap (const Standard_Integer theIdx1, + const Standard_Integer theIdx2) +{ + const Standard_Integer aStructIdx1 = theIdx1 + 1; + const Standard_Integer aStructIdx2 = theIdx2 + 1; + + myStructs .Swap (aStructIdx1, aStructIdx2); + myStructBoxes.Swap (aStructIdx1, aStructIdx2); +} + +// ======================================================================= +// function : Add +// purpose : +// ======================================================================= +Standard_Boolean Graphic3d_BvhCStructureSetTrsfPers::Add (const Graphic3d_CStructure* theStruct) +{ + const Standard_Integer aSize = myStructs.Size(); + + if (myStructs.Add (theStruct) > aSize) // new structure? + { + MarkDirty(); + + return Standard_True; + } + + return Standard_False; +} + +// ======================================================================= +// function : Remove +// purpose : +// ======================================================================= +Standard_Boolean Graphic3d_BvhCStructureSetTrsfPers::Remove (const Graphic3d_CStructure* theStruct) +{ + const Standard_Integer anIndex = myStructs.FindIndex (theStruct); + + if (anIndex != 0) + { + myStructs.Swap (Size(), anIndex); + myStructs.RemoveLast(); + MarkDirty(); + + return Standard_True; + } + + return Standard_False; +} + +// ======================================================================= +// function : Clear +// purpose : +// ======================================================================= +void Graphic3d_BvhCStructureSetTrsfPers::Clear() +{ + myStructs.Clear(); + MarkDirty(); +} + +// ======================================================================= +// function : GetStructureById +// purpose : +// ======================================================================= +const Graphic3d_CStructure* Graphic3d_BvhCStructureSetTrsfPers::GetStructureById (Standard_Integer theId) +{ + return myStructs.FindKey (theId + 1); +} + +//======================================================================= +// function : BVH +// purpose : +//======================================================================= +const opencascade::handle >& Graphic3d_BvhCStructureSetTrsfPers::BVH (const Handle(Graphic3d_Camera)& theCamera, + const Graphic3d_Mat4d& theProjectionMatrix, + const Graphic3d_Mat4d& theWorldViewMatrix, + const Standard_Integer theViewportWidth, + const Standard_Integer theViewportHeight, + const Graphic3d_WorldViewProjState& theWVPState) +{ + if (!myIsDirty + && (myStructBoxesState.IsValid() + && !myStructBoxesState.IsChanged (theWVPState))) + { + return myBVH; + } + + myStructBoxes.ReSize (myStructs.Size()); + + for (Standard_Integer aStructIdx = 1; aStructIdx <= myStructs.Size(); ++aStructIdx) + { + const Graphic3d_CStructure* aStructure = myStructs (aStructIdx); + + Handle(HBndBox3d) aBoundingBox = new HBndBox3d(); + *aBoundingBox = aStructure->BoundingBox(); + if (!aStructure->TransformPersistence().IsNull()) + { + aStructure->TransformPersistence()->Apply (theCamera, theProjectionMatrix, theWorldViewMatrix, theViewportWidth, theViewportHeight, *aBoundingBox); + } + + myStructBoxes.Add (aBoundingBox); + } + + myBuilder->Build (this, myBVH.operator->(), BVH_Set::Box()); + + myStructBoxesState = theWVPState; + myStructBoxes.Clear(); + myIsDirty = Standard_False; + + return myBVH; +} diff --git a/src/Graphic3d/Graphic3d_BvhCStructureSetTrsfPers.hxx b/src/Graphic3d/Graphic3d_BvhCStructureSetTrsfPers.hxx new file mode 100644 index 0000000000..a7b9919794 --- /dev/null +++ b/src/Graphic3d/Graphic3d_BvhCStructureSetTrsfPers.hxx @@ -0,0 +1,120 @@ +// Created on: 2015-06-30 +// Created by: Anton POLETAEV +// Copyright (c) 2015 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _Graphic3d_BvhCStructureSetTrsfPers_HeaderFile +#define _Graphic3d_BvhCStructureSetTrsfPers_HeaderFile + +#include +#include +#include +#include +#include +#include +#include +#include + +class Graphic3d_Camera; +class Graphic3d_CStructure; + +//! Set of transformation persistent OpenGl_Structure for building BVH tree. +//! Provides built-in mechanism to invalidate tree when world view projection state changes. +//! Due to frequent invalidation of BVH tree the choice of BVH tree builder is made +//! in favor of BVH linear builder (quick rebuild). +class Graphic3d_BvhCStructureSetTrsfPers : public BVH_Set +{ +private: + + typedef NCollection_Shared HBndBox3d; + +public: + + //! Creates an empty primitive set for BVH clipping. + Graphic3d_BvhCStructureSetTrsfPers (const Handle(Select3D_BVHBuilder3d)& theBuilder); + + //! Returns total number of structures. + virtual Standard_Integer Size() const Standard_OVERRIDE; + + //! Returns AABB of the structure. + virtual Graphic3d_BndBox3d Box (const Standard_Integer theIdx) const Standard_OVERRIDE; + + //! Calculates center of the AABB along given axis. + 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, + const Standard_Integer theIdx2) Standard_OVERRIDE; + + //! Adds structure to the set. + //! @return true if structure added, otherwise returns false (structure already in the set). + Standard_Boolean Add (const Graphic3d_CStructure* theStruct); + + //! Removes the given structure from the set. + //! @return true if structure removed, otherwise returns false (structure is not in the set). + Standard_Boolean Remove (const Graphic3d_CStructure* theStruct); + + //! Cleans the whole primitive set. + void Clear(); + + //! Returns the structure corresponding to the given ID. + const Graphic3d_CStructure* GetStructureById (Standard_Integer theId); + + //! Access directly a collection of structures. + const NCollection_IndexedMap& Structures() const { return myStructs; } + + //! Marks object state as outdated (needs BVH rebuilding). + void MarkDirty() + { + myIsDirty = Standard_True; + } + + //! Returns BVH tree for the given world view projection (builds it if necessary). + const opencascade::handle >& BVH (const Handle(Graphic3d_Camera)& theCamera, + const Graphic3d_Mat4d& theProjectionMatrix, + const Graphic3d_Mat4d& theWorldViewMatrix, + const Standard_Integer theViewportWidth, + const Standard_Integer theViewportHeight, + const Graphic3d_WorldViewProjState& theWVPState); + + //! Returns builder for bottom-level BVH. + const Handle(Select3D_BVHBuilder3d)& Builder() const { return myBuilder; } + + //! Assigns builder for bottom-level BVH. + void SetBuilder (const Handle(Select3D_BVHBuilder3d)& theBuilder) { myBuilder = theBuilder; } + +private: + + //! Marks internal object state as outdated. + Standard_Boolean myIsDirty; + + //! Constructed bottom-level BVH. + opencascade::handle > myBVH; + + //! Builder for bottom-level BVH. + Handle(Select3D_BVHBuilder3d) myBuilder; + + //! Indexed map of structures. + NCollection_IndexedMap myStructs; + + //! Cached set of bounding boxes precomputed for transformation persistent selectable objects. + //! Cache exists only during computation of BVH Tree. Bounding boxes are world view projection + //! dependent and should by synchronized. + NCollection_IndexedMap myStructBoxes; + + //! State of world view projection used for generation of transformation persistence bounding boxes. + Graphic3d_WorldViewProjState myStructBoxesState; +}; + +#endif // _Graphic3d_BvhCStructureSetTrsfPers_HeaderFile diff --git a/src/Graphic3d/Graphic3d_CStructure.cxx b/src/Graphic3d/Graphic3d_CStructure.cxx index ecc6e8d23f..7168413023 100644 --- a/src/Graphic3d/Graphic3d_CStructure.cxx +++ b/src/Graphic3d/Graphic3d_CStructure.cxx @@ -19,7 +19,6 @@ #include #include - IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_CStructure,Standard_Transient) //============================================================================= @@ -39,7 +38,8 @@ Graphic3d_CStructure::Graphic3d_CStructure (const Handle(Graphic3d_StructureMana IsForHighlight (Standard_False), IsMutable (Standard_False), Is2dText (Standard_False), - myGraphicDriver (theManager->GraphicDriver()) + myGraphicDriver (theManager->GraphicDriver()), + myIsCulled (Standard_True) { Id = myGraphicDriver->NewIdentification(); } diff --git a/src/Graphic3d/Graphic3d_CStructure.hxx b/src/Graphic3d/Graphic3d_CStructure.hxx index 32a773e169..adfcbbe9ee 100644 --- a/src/Graphic3d/Graphic3d_CStructure.hxx +++ b/src/Graphic3d/Graphic3d_CStructure.hxx @@ -26,6 +26,7 @@ #include #include #include +#include class Graphic3d_GraphicDriver; class Graphic3d_StructureManager; @@ -33,6 +34,35 @@ class Graphic3d_StructureManager; //! Low-level graphic structure interface class Graphic3d_CStructure : public Standard_Transient { +protected: + + //! Auxiliary wrapper to iterate through structure list. + template + class SubclassStructIterator + { + public: + SubclassStructIterator (const NCollection_IndexedMap& theStructs) : myIter (theStructs) {} + Standard_Boolean More() const { return myIter.More(); } + void Next() { myIter.Next(); } + const Struct_t* Value() const { return (const Struct_t* )(myIter.Value()); } + Struct_t* ChangeValue() { return (Struct_t* )(myIter.Value()); } + private: + NCollection_IndexedMap::Iterator myIter; + }; + + //! Auxiliary wrapper to iterate through group sequence. + template + class SubclassGroupIterator + { + public: + SubclassGroupIterator (const Graphic3d_SequenceOfGroup& theGroups) : myIter (theGroups) {} + Standard_Boolean More() const { return myIter.More(); } + void Next() { myIter.Next(); } + const Group_t* Value() const { return (const Group_t* )(myIter.Value().get()); } + Group_t* ChangeValue() { return (Group_t* )(myIter.ChangeValue().get()); } + private: + Graphic3d_SequenceOfGroup::Iterator myIter; + }; public: @@ -103,6 +133,28 @@ public: //! highlight flag is set to true const Handle(Graphic3d_PresentationAttributes)& HighlightStyle() const { return myHighlightStyle; } +public: + + //! Returns FALSE if the structure hits the current view volume, otherwise returns TRUE. + Standard_Boolean IsCulled() const { return myIsCulled; } + + //! Marks structure as culled/not culled - note that IsAlwaysRendered() is ignored here! + void SetCulled (Standard_Boolean theIsCulled) const { myIsCulled = theIsCulled; } + + //! Marks structure as overlapping the current view volume one. + //! The method is called during traverse of BVH tree. + void MarkAsNotCulled() const { myIsCulled = Standard_False; } + + //! Checks if the structure should be included into BVH tree or not. + Standard_Boolean IsAlwaysRendered() const + { + return IsInfinite + || IsForHighlight + || IsMutable + || Is2dText + || (!myTrsfPers.IsNull() && myTrsfPers->IsTrihedronOr2d()); + } + public: //! Update structure visibility state @@ -133,6 +185,9 @@ public: //! Remove group from this structure virtual void RemoveGroup (const Handle(Graphic3d_Group)& theGroup) = 0; + //! Update render transformation matrix. + virtual void updateLayerTransformation() {} + public: int Id; @@ -168,6 +223,8 @@ protected: Handle(Graphic3d_SequenceOfHClipPlane) myClipPlanes; Handle(Graphic3d_PresentationAttributes) myHighlightStyle; //! Current highlight style; is set only if highlight flag is true + mutable Standard_Boolean myIsCulled; //!< A status specifying is structure needs to be rendered after BVH tree traverse + public: DEFINE_STANDARD_RTTIEXT(Graphic3d_CStructure,Standard_Transient) // Type definition diff --git a/src/Graphic3d/Graphic3d_CView.cxx b/src/Graphic3d/Graphic3d_CView.cxx index e88505feb4..d5dac3a0e0 100644 --- a/src/Graphic3d/Graphic3d_CView.cxx +++ b/src/Graphic3d/Graphic3d_CView.cxx @@ -33,7 +33,9 @@ namespace //purpose : //======================================================================= Graphic3d_CView::Graphic3d_CView (const Handle(Graphic3d_StructureManager)& theMgr) -: myStructureManager (theMgr), +: myBgColor (Quantity_NOC_BLACK), + myStructureManager (theMgr), + myCamera (new Graphic3d_Camera()), myHiddenObjects (new Graphic3d_NMapOfTransient()), myIsInComputedMode (Standard_False), myIsActive (Standard_False), diff --git a/src/Graphic3d/Graphic3d_CView.hxx b/src/Graphic3d/Graphic3d_CView.hxx index 761e791c80..e409c5e5bf 100644 --- a/src/Graphic3d/Graphic3d_CView.hxx +++ b/src/Graphic3d/Graphic3d_CView.hxx @@ -87,6 +87,12 @@ public: //! Returns true if the view was removed. Standard_Boolean IsRemoved() const { return myIsRemoved; } + //! Returns camera object of the view. + virtual const Handle(Graphic3d_Camera)& Camera() const { return myCamera; } + + //! Sets camera used by the view. + virtual void SetCamera (const Handle(Graphic3d_Camera)& theCamera) { myCamera = theCamera; } + public: //! Returns default Shading Model of the view; Graphic3d_TOSM_FRAGMENT by default. @@ -252,20 +258,6 @@ public: //! Returns True if the window associated to the view is defined. virtual Standard_Boolean IsDefined() const = 0; - //! Returns data of a graduated trihedron - virtual const Graphic3d_GraduatedTrihedron& GetGraduatedTrihedron() = 0; - - //! Displays Graduated Trihedron. - virtual void GraduatedTrihedronDisplay (const Graphic3d_GraduatedTrihedron& theTrihedronData) = 0; - - //! Erases Graduated Trihedron. - virtual void GraduatedTrihedronErase() = 0; - - //! Sets minimum and maximum points of scene bounding box for Graduated Trihedron stored in graphic view object. - //! @param theMin [in] the minimum point of scene. - //! @param theMax [in] the maximum point of scene. - virtual void GraduatedTrihedronMinMaxValues (const Graphic3d_Vec3 theMin, const Graphic3d_Vec3 theMax) = 0; - //! Dump active rendering buffer into specified memory buffer. virtual Standard_Boolean BufferDump (Image_PixMap& theImage, const Graphic3d_BufferType& theBufferType) = 0; @@ -352,10 +344,10 @@ public: Graphic3d_RenderingParams& ChangeRenderingParams() { return myRenderParams; } //! Returns background fill color. - virtual Aspect_Background Background() const = 0; + virtual Aspect_Background Background() const { return Aspect_Background (myBgColor.GetRGB()); } //! Sets background fill color. - virtual void SetBackground (const Aspect_Background& theBackground) = 0; + virtual void SetBackground (const Aspect_Background& theBackground) { myBgColor.SetRGB (theBackground.Color()); } //! Returns gradient background fill colors. virtual Aspect_GradientBackground GradientBackground() const = 0; @@ -387,12 +379,6 @@ public: //! Sets backfacing model for the view. virtual void SetBackfacingModel (const Graphic3d_TypeOfBackfacingModel theModel) = 0; - //! Returns camera object of the view. - virtual const Handle(Graphic3d_Camera)& Camera() const = 0; - - //! Sets camera used by the view. - virtual void SetCamera (const Handle(Graphic3d_Camera)& theCamera) = 0; - //! Returns list of lights of the view. virtual const Handle(Graphic3d_LightSet)& Lights() const = 0; @@ -421,6 +407,26 @@ public: //! Fills in the dictionary with statistic performance info. virtual void StatisticInformation (TColStd_IndexedDataMapOfStringString& theDict) const = 0; +public: //! @name obsolete Graduated Trihedron functionality + + //! Returns data of a graduated trihedron + virtual const Graphic3d_GraduatedTrihedron& GetGraduatedTrihedron() { return myGTrihedronData; } + + //! Displays Graduated Trihedron. + virtual void GraduatedTrihedronDisplay (const Graphic3d_GraduatedTrihedron& theTrihedronData) { (void )theTrihedronData; } + + //! Erases Graduated Trihedron. + virtual void GraduatedTrihedronErase() {} + + //! Sets minimum and maximum points of scene bounding box for Graduated Trihedron stored in graphic view object. + //! @param theMin [in] the minimum point of scene. + //! @param theMax [in] the maximum point of scene. + virtual void GraduatedTrihedronMinMaxValues (const Graphic3d_Vec3 theMin, const Graphic3d_Vec3 theMax) + { + (void )theMin; + (void )theMax; + } + private: //! Adds the structure to display lists of the view. @@ -448,7 +454,9 @@ protected: Standard_Integer myId; Graphic3d_RenderingParams myRenderParams; + Quantity_ColorRGBA myBgColor; Handle(Graphic3d_StructureManager) myStructureManager; + Handle(Graphic3d_Camera) myCamera; Graphic3d_SequenceOfStructure myStructsToCompute; Graphic3d_SequenceOfStructure myStructsComputed; Graphic3d_MapOfStructure myStructsDisplayed; @@ -459,6 +467,10 @@ protected: Graphic3d_TypeOfShadingModel myShadingModel; Graphic3d_TypeOfVisualization myVisualization; +protected: + + Graphic3d_GraduatedTrihedron myGTrihedronData; + }; #endif // _Graphic3d_CView_HeaderFile diff --git a/src/Graphic3d/Graphic3d_CullingTool.cxx b/src/Graphic3d/Graphic3d_CullingTool.cxx new file mode 100644 index 0000000000..c2a11be66a --- /dev/null +++ b/src/Graphic3d/Graphic3d_CullingTool.cxx @@ -0,0 +1,198 @@ +// Created on: 2013-12-25 +// Created by: Varvara POSKONINA +// Copyright (c) 1999-2014 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#include + +#include + +#include + +// ======================================================================= +// function : Graphic3d_CullingTool +// purpose : +// ======================================================================= +Graphic3d_CullingTool::Graphic3d_CullingTool() +: myClipVerts (0, Graphic3d_Camera::FrustumVerticesNB), + myIsProjectionParallel (Standard_True), + myCamScale (1.0), + myPixelSize (1.0) +{ + // +} + +// ======================================================================= +// function : SetViewVolume +// purpose : Retrieves view volume's planes equations and its vertices from projection and world-view matrices. +// ======================================================================= +void Graphic3d_CullingTool::SetViewVolume (const Handle(Graphic3d_Camera)& theCamera) +{ + if (!myWorldViewProjState.IsChanged (theCamera->WorldViewProjState())) + return; + + myIsProjectionParallel = theCamera->IsOrthographic(); + const gp_Dir aCamDir = theCamera->Direction(); + + myCamera = theCamera; + myProjectionMat = theCamera->ProjectionMatrix(); + myWorldViewMat = theCamera->OrientationMatrix(); + myWorldViewProjState = theCamera->WorldViewProjState(); + myCamEye.SetValues (theCamera->Eye().X(), theCamera->Eye().Y(), theCamera->Eye().Z()); + myCamDir.SetValues (aCamDir.X(), aCamDir.Y(), aCamDir.Z()); + myCamScale = theCamera->IsOrthographic() + ? theCamera->Scale() + : 2.0 * Tan (theCamera->FOVy() * M_PI / 360.0); // same as theCamera->Scale()/theCamera->Distance() + + // Compute frustum points + theCamera->FrustumPoints (myClipVerts); + + // Compute frustum planes + // Vertices go in order: + // 0, 2, 1 + const Standard_Integer aLookup1[] = { 0, 1, 0 }; + const Standard_Integer aLookup2[] = { 0, 0, 1 }; + Standard_Integer aShifts[] = { 0, 0, 0 }; + + // Planes go in order: + // LEFT, RIGHT, BOTTOM, TOP, NEAR, FAR + for (Standard_Integer aFaceIdx = 0; aFaceIdx < 3; ++aFaceIdx) + { + for (Standard_Integer i = 0; i < 2; ++i) + { + Graphic3d_Vec3d aPlanePnts[3]; + for (Standard_Integer aPntIter = 0; aPntIter < 3; ++aPntIter) + { + aShifts[aFaceIdx] = i; + aShifts[(aFaceIdx + 1) % 3] = aLookup1[aPntIter]; + aShifts[(aFaceIdx + 2) % 3] = aLookup2[aPntIter]; + + aPlanePnts[aPntIter] = myClipVerts[aShifts[0] * 2 * 2 + aShifts[1] * 2 + aShifts[2]]; + } + + myClipPlanes[aFaceIdx * 2 + i].Origin = aPlanePnts[0]; + myClipPlanes[aFaceIdx * 2 + i].Normal = + Graphic3d_Vec3d::Cross (aPlanePnts[1] - aPlanePnts[0], + aPlanePnts[2] - aPlanePnts[0]).Normalized() * (i == 0 ? -1.f : 1.f); + } + } +} + +// ======================================================================= +// function : SetViewportSize +// purpose : +// ======================================================================= +void Graphic3d_CullingTool::SetViewportSize (Standard_Integer theViewportWidth, + Standard_Integer theViewportHeight, + Standard_Real theResolutionRatio) +{ + myViewportHeight = theViewportHeight > 0 ? theViewportHeight : 1; + myViewportWidth = theViewportWidth > 0 ? theViewportWidth : 1; + myPixelSize = Max (theResolutionRatio / myViewportHeight, + theResolutionRatio / myViewportWidth); +} + +// ======================================================================= +// function : SignedPlanePointDistance +// purpose : +// ======================================================================= +Standard_Real Graphic3d_CullingTool::SignedPlanePointDistance (const Graphic3d_Vec4d& theNormal, + const Graphic3d_Vec4d& thePnt) +{ + const Standard_Real aNormLength = std::sqrt (theNormal.x() * theNormal.x() + + theNormal.y() * theNormal.y() + + theNormal.z() * theNormal.z()); + + if (aNormLength < gp::Resolution()) + return 0.0; + + 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()); +} + +// ======================================================================= +// function : SetCullingDistance +// purpose : +// ======================================================================= +void Graphic3d_CullingTool::SetCullingDistance (CullingContext& theCtx, + Standard_Real theDistance) const +{ + theCtx.DistCull = -1.0; + if (!myIsProjectionParallel) + { + theCtx.DistCull = theDistance > 0.0 && !Precision::IsInfinite (theDistance) + ? theDistance + : -1.0; + } +} + +// ======================================================================= +// function : SetCullingSize +// purpose : +// ======================================================================= +void Graphic3d_CullingTool::SetCullingSize (CullingContext& theCtx, + Standard_Real theSize) const +{ + theCtx.SizeCull2 = -1.0; + if (theSize > 0.0 && !Precision::IsInfinite (theSize)) + { + theCtx.SizeCull2 = myPixelSize * theSize; + theCtx.SizeCull2 *= myCamScale; + theCtx.SizeCull2 *= theCtx.SizeCull2; + } +} + +// ======================================================================= +// function : CacheClipPtsProjections +// purpose : +// ======================================================================= +void Graphic3d_CullingTool::CacheClipPtsProjections() +{ + // project frustum onto its own normals + const Standard_Integer anIncFactor = myIsProjectionParallel ? 2 : 1; + for (Standard_Integer aPlaneIter = 0; aPlaneIter < PlanesNB - 1; aPlaneIter += anIncFactor) + { + Standard_Real aMaxProj = -std::numeric_limits::max(); + Standard_Real aMinProj = std::numeric_limits::max(); + for (Standard_Integer aCornerIter = 0; aCornerIter < Graphic3d_Camera::FrustumVerticesNB; ++aCornerIter) + { + Standard_Real aProjection = myClipVerts[aCornerIter].Dot (myClipPlanes[aPlaneIter].Normal); + aMaxProj = Max (aProjection, aMaxProj); + aMinProj = Min (aProjection, aMinProj); + } + myMaxClipProjectionPts[aPlaneIter] = aMaxProj; + myMinClipProjectionPts[aPlaneIter] = aMinProj; + } + + // project frustum onto main axes + Graphic3d_Vec3d anAxes[] = { Graphic3d_Vec3d (1.0, 0.0, 0.0), + Graphic3d_Vec3d (0.0, 1.0, 0.0), + Graphic3d_Vec3d (0.0, 0.0, 1.0) }; + for (Standard_Integer aDim = 0; aDim < 3; ++aDim) + { + Standard_Real aMaxProj = -std::numeric_limits::max(); + Standard_Real aMinProj = std::numeric_limits::max(); + for (Standard_Integer aCornerIter = 0; aCornerIter < Graphic3d_Camera::FrustumVerticesNB; ++aCornerIter) + { + Standard_Real aProjection = myClipVerts[aCornerIter].Dot (anAxes[aDim]); + aMaxProj = Max (aProjection, aMaxProj); + aMinProj = Min (aProjection, aMinProj); + } + myMaxOrthoProjectionPts[aDim] = aMaxProj; + myMinOrthoProjectionPts[aDim] = aMinProj; + } +} diff --git a/src/Graphic3d/Graphic3d_CullingTool.hxx b/src/Graphic3d/Graphic3d_CullingTool.hxx new file mode 100644 index 0000000000..f76a72b9a6 --- /dev/null +++ b/src/Graphic3d/Graphic3d_CullingTool.hxx @@ -0,0 +1,287 @@ +// Created on: 2013-12-25 +// Created by: Varvara POSKONINA +// Copyright (c) 1999-2014 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _Graphic3d_CullingTool_HeaderFile +#define _Graphic3d_CullingTool_HeaderFile + +#include +#include +#include + +//! Graphic3d_CullingTool class provides a possibility to store parameters of view volume, +//! such as its vertices and equations, and contains methods detecting if given AABB overlaps view volume. +class Graphic3d_CullingTool +{ +public: + //! Auxiliary structure holding non-persistent culling options. + struct CullingContext + { + Standard_Real DistCull; //!< culling distance + Standard_Real SizeCull2; //!< squared culling size + + //! Empty constructor. + CullingContext() : DistCull (-1.0), SizeCull2 (-1.0) {} + }; + + //! Auxiliary structure representing 3D plane. + struct Plane + { + //! Creates default plane. + Plane() + : Origin (0.0, 0.0, 0.0), + Normal (0.0, 0.0, 1.0) {} + + //! Creates plane with specific parameters. + Plane (const Graphic3d_Vec3d& theOrigin, + const Graphic3d_Vec3d& theNormal) + : Origin (theOrigin), + Normal (theNormal) {} + + Graphic3d_Vec3d Origin; + Graphic3d_Vec3d Normal; + }; + +public: + + //! Creates an empty selector object with parallel projection type by default. + Standard_EXPORT Graphic3d_CullingTool(); + + //! Retrieves view volume's planes equations and its vertices from projection and world-view matrices. + Standard_EXPORT void SetViewVolume (const Handle(Graphic3d_Camera)& theCamera); + + Standard_EXPORT void SetViewportSize (Standard_Integer theViewportWidth, + Standard_Integer theViewportHeight, + Standard_Real theResolutionRatio); + + //! Setup distance culling. + Standard_EXPORT void SetCullingDistance (CullingContext& theCtx, + Standard_Real theDistance) const; + + //! Setup size culling. + Standard_EXPORT void SetCullingSize (CullingContext& theCtx, + Standard_Real theSize) 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. + Standard_EXPORT void CacheClipPtsProjections(); + + //! Checks whether given AABB should be entirely culled or not. + //! @param theCtx [in] culling properties + //! @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 + bool IsCulled (const CullingContext& theCtx, + const Graphic3d_Vec3d& theMinPt, + const Graphic3d_Vec3d& theMaxPt) const + { + return isFullOut (theMinPt, theMaxPt) + || isTooDistant(theCtx, theMinPt, theMaxPt) + || isTooSmall (theCtx, theMinPt, theMaxPt); + } + + //! Return the camera definition. + const Handle(Graphic3d_Camera)& Camera() const { return myCamera; } + + //! Returns current projection matrix. + const Graphic3d_Mat4d& ProjectionMatrix() const + { + return myProjectionMat; + } + + //! Returns current world view transformation matrix. + const Graphic3d_Mat4d& WorldViewMatrix() const + { + return myWorldViewMat; + } + + Standard_Integer ViewportWidth() const + { + return myViewportWidth; + } + + Standard_Integer ViewportHeight() const + { + return myViewportHeight; + } + + //! Returns state of current world view projection transformation matrices. + const Graphic3d_WorldViewProjState& WorldViewProjState() const + { + return myWorldViewProjState; + } + +protected: + + //! Calculates signed distance from plane to point. + //! @param theNormal [in] the plane's normal. + //! @param thePnt [in] + Standard_EXPORT Standard_Real SignedPlanePointDistance (const Graphic3d_Vec4d& theNormal, + const Graphic3d_Vec4d& thePnt); + + //! Detects if AABB overlaps view volume using separating axis theorem (SAT). + //! @param theMinPt [in] maximum point of AABB. + //! @param theMaxPt [in] minimum point of AABB. + //! @return FALSE, if AABB is in viewing area, TRUE otherwise. + bool isFullOut (const Graphic3d_Vec3d& theMinPt, + const Graphic3d_Vec3d& theMaxPt) const + { + // E1 + // |_ E0 + // / + // E2 + + // E0 test (x axis) + if (theMinPt.x() > myMaxOrthoProjectionPts[0] + || theMaxPt.x() < myMinOrthoProjectionPts[0]) + { + return true; + } + + // E1 test (y axis) + if (theMinPt.y() > myMaxOrthoProjectionPts[1] + || theMaxPt.y() < myMinOrthoProjectionPts[1]) + { + return true; + } + + // E2 test (z axis) + if (theMinPt.z() > myMaxOrthoProjectionPts[2] + || theMaxPt.z() < myMinOrthoProjectionPts[2]) + { + return true; + } + + const Standard_Integer anIncFactor = myIsProjectionParallel ? 2 : 1; + for (Standard_Integer aPlaneIter = 0; aPlaneIter < PlanesNB - 1; aPlaneIter += anIncFactor) + { + // frustum normals + const Graphic3d_Vec3d anAxis = myClipPlanes[aPlaneIter].Normal; + + const Graphic3d_Vec3d aPVertex (anAxis.x() > 0.0 ? theMaxPt.x() : theMinPt.x(), + anAxis.y() > 0.0 ? theMaxPt.y() : theMinPt.y(), + anAxis.z() > 0.0 ? theMaxPt.z() : theMinPt.z()); + Standard_Real aPnt0 = aPVertex.Dot (anAxis); + + if (aPnt0 >= myMinClipProjectionPts[aPlaneIter] + && aPnt0 <= myMaxClipProjectionPts[aPlaneIter]) + { + continue; + } + + const Graphic3d_Vec3d aNVertex (anAxis.x() > 0.0 ? theMinPt.x() : theMaxPt.x(), + anAxis.y() > 0.0 ? theMinPt.y() : theMaxPt.y(), + anAxis.z() > 0.0 ? theMinPt.z() : theMaxPt.z()); + Standard_Real aPnt1 = aNVertex.Dot (anAxis); + + const Standard_Real aMin = aPnt0 < aPnt1 ? aPnt0 : aPnt1; + const Standard_Real aMax = aPnt0 > aPnt1 ? aPnt0 : aPnt1; + + if (aMin > myMaxClipProjectionPts[aPlaneIter] + || aMax < myMinClipProjectionPts[aPlaneIter]) + { + return true; + } + } + return false; + } + + //! Returns TRUE if given AABB should be discarded by distance culling criterion. + bool isTooDistant (const CullingContext& theCtx, + const Graphic3d_Vec3d& theMinPt, + const Graphic3d_Vec3d& theMaxPt) const + { + if (theCtx.DistCull <= 0.0) + { + return false; + } + + // check distance to the bounding sphere as fast approximation + const Graphic3d_Vec3d aSphereCenter = (theMinPt + theMaxPt) * 0.5; + const Standard_Real aSphereRadius = (theMaxPt - theMinPt).maxComp() * 0.5; + return (aSphereCenter - myCamEye).Modulus() - aSphereRadius > theCtx.DistCull; + } + + //! Returns TRUE if given AABB should be discarded by size culling criterion. + bool isTooSmall (const CullingContext& theCtx, + const Graphic3d_Vec3d& theMinPt, + const Graphic3d_Vec3d& theMaxPt) const + { + if (theCtx.SizeCull2 <= 0.0) + { + return false; + } + + const Standard_Real aBoxDiag2 = (theMaxPt - theMinPt).SquareModulus(); + if (myIsProjectionParallel) + { + return aBoxDiag2 < theCtx.SizeCull2; + } + + // note that distances behind the Eye (aBndDist < 0) are not scaled correctly here, + // but majority of such objects should be culled by frustum + const Graphic3d_Vec3d aBndCenter = (theMinPt + theMaxPt) * 0.5; + const Standard_Real aBndDist = (aBndCenter - myCamEye).Dot (myCamDir); + return aBoxDiag2 < theCtx.SizeCull2 * aBndDist * aBndDist; + } + +protected: + + //! Enumerates planes of view volume. + enum + { + Plane_Left, + Plane_Right, + Plane_Bottom, + Plane_Top, + Plane_Near, + Plane_Far, + PlanesNB + }; + +protected: + + Plane myClipPlanes[PlanesNB]; //!< Planes + NCollection_Array1 myClipVerts; //!< Vertices + + Handle(Graphic3d_Camera) myCamera; //!< camera definition + + // for caching clip points projections onto viewing area normals once per traverse + // ORDER: LEFT, RIGHT, BOTTOM, TOP, NEAR, FAR + 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_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; + + Graphic3d_Mat4d myProjectionMat; + Graphic3d_Mat4d myWorldViewMat; + + Standard_Integer myViewportWidth; + Standard_Integer myViewportHeight; + + Graphic3d_WorldViewProjState myWorldViewProjState; //!< State of world view projection matrices. + + Graphic3d_Vec3d myCamEye; //!< camera eye position for distance culling + Graphic3d_Vec3d myCamDir; //!< camera direction for size culling + Standard_Real myCamScale; //!< camera scale for size culling + Standard_Real myPixelSize; //!< pixel size for size culling + +}; + +#endif // _Graphic3d_CullingTool_HeaderFile diff --git a/src/Graphic3d/Graphic3d_GraphicDriver.cxx b/src/Graphic3d/Graphic3d_GraphicDriver.cxx index 773f49dcff..84213193a9 100644 --- a/src/Graphic3d/Graphic3d_GraphicDriver.cxx +++ b/src/Graphic3d/Graphic3d_GraphicDriver.cxx @@ -25,7 +25,71 @@ IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_GraphicDriver,Standard_Transient) Graphic3d_GraphicDriver::Graphic3d_GraphicDriver (const Handle(Aspect_DisplayConnection)& theDisp) : myDisplayConnection (theDisp) { - // + // default layers are always presented in display layer sequence it can not be removed + { + 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 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 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 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 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); + } } // ======================================================================= @@ -53,4 +117,83 @@ Standard_Integer Graphic3d_GraphicDriver::NewIdentification() void Graphic3d_GraphicDriver::RemoveIdentification(const Standard_Integer theId) { myStructGenId.Free(theId); -} \ No newline at end of file +} + +//======================================================================= +//function : ZLayerSettings +//purpose : +//======================================================================= +const Graphic3d_ZLayerSettings& Graphic3d_GraphicDriver::ZLayerSettings (const Graphic3d_ZLayerId theLayerId) const +{ + Standard_ASSERT_RAISE (myLayerIds.Contains (theLayerId), "Graphic3d_GraphicDriver::ZLayerSettings, Layer with theLayerId does not exist"); + return myMapOfZLayerSettings.Find (theLayerId); +} + +//======================================================================= +//function : addZLayerIndex +//purpose : +//======================================================================= +void Graphic3d_GraphicDriver::addZLayerIndex (const Graphic3d_ZLayerId theLayerId) +{ + // remove index + for (TColStd_SequenceOfInteger::Iterator aLayerIt (myLayerSeq); aLayerIt.More(); aLayerIt.Next()) + { + if (aLayerIt.Value() == theLayerId) + { + myLayerSeq.Remove (aLayerIt); + break; + } + } + + if (myMapOfZLayerSettings.Find (theLayerId).IsImmediate()) + { + myLayerSeq.Append (theLayerId); + return; + } + + for (TColStd_SequenceOfInteger::Iterator aLayerIt (myLayerSeq); aLayerIt.More(); aLayerIt.Next()) + { + const Graphic3d_ZLayerSettings& aSettings = myMapOfZLayerSettings.Find (aLayerIt.Value()); + if (aSettings.IsImmediate()) + { + aLayerIt.Previous(); + if (aLayerIt.More()) + { + myLayerSeq.InsertAfter (aLayerIt, theLayerId); + return; + } + + // first non-immediate layer + myLayerSeq.Prepend (theLayerId); + return; + } + } + + // no immediate layers + myLayerSeq.Append (theLayerId); +} + +//======================================================================= +//function : SetZLayerSettings +//purpose : +//======================================================================= +void Graphic3d_GraphicDriver::SetZLayerSettings (const Graphic3d_ZLayerId theLayerId, + const Graphic3d_ZLayerSettings& theSettings) +{ + Graphic3d_ZLayerSettings* aSettings = myMapOfZLayerSettings.ChangeSeek (theLayerId); + if (aSettings != NULL) + { + const bool isChanged = (aSettings->IsImmediate() != theSettings.IsImmediate()); + *aSettings = theSettings; + if (isChanged) + { + addZLayerIndex (theLayerId); + } + } + else + { + // abnormal case + myMapOfZLayerSettings.Bind (theLayerId, theSettings); + addZLayerIndex (theLayerId); + } +} diff --git a/src/Graphic3d/Graphic3d_GraphicDriver.hxx b/src/Graphic3d/Graphic3d_GraphicDriver.hxx index 5880b000ed..dd4fd3e040 100644 --- a/src/Graphic3d/Graphic3d_GraphicDriver.hxx +++ b/src/Graphic3d/Graphic3d_GraphicDriver.hxx @@ -42,9 +42,11 @@ #include #include #include +#include #include #include #include +#include #include class Aspect_DisplayConnection; @@ -122,13 +124,16 @@ public: virtual void RemoveZLayer (const Graphic3d_ZLayerId theLayerId) = 0; //! Returns list of Z layers defined for the graphical driver. - virtual void ZLayers (TColStd_SequenceOfInteger& theLayerSeq) const = 0; + virtual void ZLayers (TColStd_SequenceOfInteger& theLayerSeq) const + { + theLayerSeq.Assign (myLayerSeq); + } //! Sets the settings for a single Z layer. - virtual void SetZLayerSettings (const Graphic3d_ZLayerId theLayerId, const Graphic3d_ZLayerSettings& theSettings) = 0; + Standard_EXPORT virtual void SetZLayerSettings (const Graphic3d_ZLayerId theLayerId, const Graphic3d_ZLayerSettings& theSettings) = 0; //! Returns the settings of a single Z layer. - virtual const Graphic3d_ZLayerSettings& ZLayerSettings (const Graphic3d_ZLayerId theLayerId) const = 0; + Standard_EXPORT virtual const Graphic3d_ZLayerSettings& ZLayerSettings (const Graphic3d_ZLayerId theLayerId) const; //! Returns view associated with the window if it is exists and is activated. //! Returns Standard_True if the view associated to the window exists. @@ -150,10 +155,16 @@ protected: //! Initializes the Driver Standard_EXPORT Graphic3d_GraphicDriver(const Handle(Aspect_DisplayConnection)& theDisp); + //! Insert index layer at proper position. + Standard_EXPORT void addZLayerIndex (const Graphic3d_ZLayerId theLayerId); + protected: Handle(Aspect_DisplayConnection) myDisplayConnection; Aspect_GenId myStructGenId; + TColStd_MapOfInteger myLayerIds; + TColStd_SequenceOfInteger myLayerSeq; + Graphic3d_MapOfZLayerSettings myMapOfZLayerSettings; }; diff --git a/src/Graphic3d/Graphic3d_Layer.cxx b/src/Graphic3d/Graphic3d_Layer.cxx new file mode 100644 index 0000000000..fad60a392a --- /dev/null +++ b/src/Graphic3d/Graphic3d_Layer.cxx @@ -0,0 +1,626 @@ +// Copyright (c) 2011-2019 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#include + +#include +#include + +IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_Layer, Standard_Transient) + +// ======================================================================= +// function : Graphic3d_Layer +// purpose : +// ======================================================================= +Graphic3d_Layer::Graphic3d_Layer (Standard_Integer theNbPriorities, + const Handle(Select3D_BVHBuilder3d)& theBuilder) +: myArray (0, theNbPriorities - 1), + myNbStructures (0), + myNbStructuresNotCulled (0), + myBVHPrimitivesTrsfPers (theBuilder), + myBVHIsLeftChildQueuedFirst (Standard_True), + myIsBVHPrimitivesNeedsReset (Standard_False) +{ + myIsBoundingBoxNeedsReset[0] = myIsBoundingBoxNeedsReset[1] = true; +} + +// ======================================================================= +// function : ~Graphic3d_Layer +// purpose : +// ======================================================================= +Graphic3d_Layer::~Graphic3d_Layer() +{ + // +} + +// ======================================================================= +// function : Add +// purpose : +// ======================================================================= +void Graphic3d_Layer::Add (const Graphic3d_CStructure* theStruct, + Standard_Integer thePriority, + Standard_Boolean isForChangePriority) +{ + const Standard_Integer anIndex = Min (Max (thePriority, 0), myArray.Length() - 1); + if (theStruct == NULL) + { + return; + } + + myArray (anIndex).Add (theStruct); + if (theStruct->IsAlwaysRendered()) + { + theStruct->MarkAsNotCulled(); + if (!isForChangePriority) + { + myAlwaysRenderedMap.Add (theStruct); + } + } + else if (!isForChangePriority) + { + if (theStruct->TransformPersistence().IsNull()) + { + myBVHPrimitives.Add (theStruct); + } + else + { + myBVHPrimitivesTrsfPers.Add (theStruct); + } + } + ++myNbStructures; +} + +// ======================================================================= +// function : Remove +// purpose : +// ======================================================================= +bool Graphic3d_Layer::Remove (const Graphic3d_CStructure* theStruct, + Standard_Integer& thePriority, + Standard_Boolean isForChangePriority) +{ + if (theStruct == NULL) + { + thePriority = -1; + return false; + } + + const Standard_Integer aNbPriorities = myArray.Length(); + for (Standard_Integer aPriorityIter = 0; aPriorityIter < aNbPriorities; ++aPriorityIter) + { + Graphic3d_IndexedMapOfStructure& aStructures = myArray (aPriorityIter); + const Standard_Integer anIndex = aStructures.FindIndex (theStruct); + if (anIndex == 0) + { + continue; + } + + aStructures.Swap (anIndex, aStructures.Size()); + aStructures.RemoveLast(); + + if (!isForChangePriority) + { + Standard_Boolean isAlwaysRend = theStruct->IsAlwaysRendered(); + if (!isAlwaysRend) + { + if (!myBVHPrimitives.Remove (theStruct)) + { + if (!myBVHPrimitivesTrsfPers.Remove (theStruct)) + { + isAlwaysRend = Standard_True; + } + } + } + if (isAlwaysRend) + { + const Standard_Integer anIndex2 = myAlwaysRenderedMap.FindIndex (theStruct); + if (anIndex2 != 0) + { + myAlwaysRenderedMap.Swap (myAlwaysRenderedMap.Size(), anIndex2); + myAlwaysRenderedMap.RemoveLast(); + } + } + } + --myNbStructures; + thePriority = aPriorityIter; + return true; + } + + thePriority = -1; + return false; +} + +// ======================================================================= +// function : InvalidateBVHData +// purpose : +// ======================================================================= +void Graphic3d_Layer::InvalidateBVHData() +{ + myIsBVHPrimitivesNeedsReset = Standard_True; +} + +//! Calculate a finite bounding box of infinite object as its middle point. +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_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_BndBox3d& theBndBox) +{ + return Abs (theBndBox.CornerMax().x()) >= ShortRealLast() + || Abs (theBndBox.CornerMax().y()) >= ShortRealLast() + || Abs (theBndBox.CornerMax().z()) >= ShortRealLast() + || Abs (theBndBox.CornerMin().x()) >= ShortRealLast() + || Abs (theBndBox.CornerMin().y()) >= ShortRealLast() + || Abs (theBndBox.CornerMin().z()) >= ShortRealLast(); +} + +// ======================================================================= +// function : BoundingBox +// purpose : +// ======================================================================= +Bnd_Box Graphic3d_Layer::BoundingBox (Standard_Integer theViewId, + const Handle(Graphic3d_Camera)& theCamera, + Standard_Integer theWindowWidth, + Standard_Integer theWindowHeight, + Standard_Boolean theToIncludeAuxiliary) const +{ + updateBVH(); + + const Standard_Integer aBoxId = !theToIncludeAuxiliary ? 0 : 1; + const Graphic3d_Mat4d& aProjectionMat = theCamera->ProjectionMatrix(); + const Graphic3d_Mat4d& aWorldViewMat = theCamera->OrientationMatrix(); + if (myIsBoundingBoxNeedsReset[aBoxId]) + { + // Recompute layer bounding box + myBoundingBox[aBoxId].SetVoid(); + + for (Graphic3d_ArrayOfIndexedMapOfStructure::Iterator aMapIter (myArray); aMapIter.More(); aMapIter.Next()) + { + const Graphic3d_IndexedMapOfStructure& aStructures = aMapIter.Value(); + for (Graphic3d_IndexedMapOfStructure::Iterator aStructIter (aStructures); aStructIter.More(); aStructIter.Next()) + { + const Graphic3d_CStructure* aStructure = aStructIter.Value(); + if (!aStructure->IsVisible (theViewId)) + { + continue; + } + + // "FitAll" operation ignores object with transform persistence parameter + // but adds transform persistence point in a bounding box of layer (only zoom pers. objects). + if (!aStructure->TransformPersistence().IsNull()) + { + if (!theToIncludeAuxiliary + && aStructure->TransformPersistence()->IsZoomOrRotate()) + { + const gp_Pnt anAnchor = aStructure->TransformPersistence()->AnchorPoint(); + myBoundingBox[aBoxId].Add (anAnchor); + continue; + } + // Panning and 2d persistence apply changes to projection or/and its translation components. + // It makes them incompatible with z-fitting algorithm. Ignored by now. + else if (!theToIncludeAuxiliary + || aStructure->TransformPersistence()->IsTrihedronOr2d()) + { + continue; + } + } + + Graphic3d_BndBox3d aBox = aStructure->BoundingBox(); + if (!aBox.IsValid()) + { + continue; + } + + if (aStructure->IsInfinite + && !theToIncludeAuxiliary) + { + // include center of infinite object + aBox = centerOfinfiniteBndBox (aBox); + } + + if (!aStructure->TransformPersistence().IsNull()) + { + aStructure->TransformPersistence()->Apply (theCamera, aProjectionMat, aWorldViewMat, theWindowWidth, theWindowHeight, aBox); + } + + // skip too big boxes to prevent float overflow at camera parameters calculation + if (aBox.IsValid() + && !isInfiniteBndBox (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())); + } + } + } + + myIsBoundingBoxNeedsReset[aBoxId] = false; + } + + Bnd_Box aResBox = myBoundingBox[aBoxId]; + if (!theToIncludeAuxiliary + || myAlwaysRenderedMap.IsEmpty()) + { + return aResBox; + } + + // add transformation-persistent objects which depend on camera position (and thus can not be cached) for operations like Z-fit + for (NCollection_IndexedMap::Iterator aStructIter (myAlwaysRenderedMap); aStructIter.More(); aStructIter.Next()) + { + const Graphic3d_CStructure* aStructure = aStructIter.Value(); + if (!aStructure->IsVisible (theViewId)) + { + continue; + } + else if (aStructure->TransformPersistence().IsNull() + || !aStructure->TransformPersistence()->IsTrihedronOr2d()) + { + continue; + } + + Graphic3d_BndBox3d aBox = aStructure->BoundingBox(); + if (!aBox.IsValid()) + { + continue; + } + + aStructure->TransformPersistence()->Apply (theCamera, aProjectionMat, aWorldViewMat, theWindowWidth, theWindowHeight, aBox); + if (aBox.IsValid() + && !isInfiniteBndBox (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())); + } + } + + return aResBox; +} + +// ======================================================================= +// function : considerZoomPersistenceObjects +// purpose : +// ======================================================================= +Standard_Real Graphic3d_Layer::considerZoomPersistenceObjects (Standard_Integer theViewId, + const Handle(Graphic3d_Camera)& theCamera, + Standard_Integer theWindowWidth, + Standard_Integer theWindowHeight) const +{ + if (NbOfTransformPersistenceObjects() == 0) + { + return 1.0; + } + + const Graphic3d_Mat4d& aProjectionMat = theCamera->ProjectionMatrix(); + const Graphic3d_Mat4d& aWorldViewMat = theCamera->OrientationMatrix(); + Standard_Real aMaxCoef = -std::numeric_limits::max(); + + for (Graphic3d_ArrayOfIndexedMapOfStructure::Iterator aMapIter (myArray); aMapIter.More(); aMapIter.Next()) + { + const Graphic3d_IndexedMapOfStructure& aStructures = aMapIter.Value(); + for (Graphic3d_IndexedMapOfStructure::Iterator aStructIter (aStructures); aStructIter.More(); aStructIter.Next()) + { + const Graphic3d_CStructure* aStructure = aStructIter.Value(); + if (!aStructure->IsVisible (theViewId) + || aStructure->TransformPersistence().IsNull() + || !aStructure->TransformPersistence()->IsZoomOrRotate()) + { + continue; + } + + Graphic3d_BndBox3d aBox = aStructure->BoundingBox(); + if (!aBox.IsValid()) + { + continue; + } + + aStructure->TransformPersistence()->Apply (theCamera, aProjectionMat, aWorldViewMat, theWindowWidth, theWindowHeight, aBox); + + 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()), + gp_Pnt (aCornerMin.x(), aCornerMax.y(), aCornerMin.z()), + gp_Pnt (aCornerMin.x(), aCornerMax.y(), aCornerMax.z()), + gp_Pnt (aCornerMax.x(), aCornerMin.y(), aCornerMin.z()), + gp_Pnt (aCornerMax.x(), aCornerMin.y(), aCornerMax.z()), + gp_Pnt (aCornerMax.x(), aCornerMax.y(), aCornerMin.z()), + gp_Pnt (aCornerMax.x(), aCornerMax.y(), aCornerMax.z()) }; + gp_Pnt aConvertedPoints[aNbOfPoints]; + Standard_Real aConvertedMinX = std::numeric_limits::max(); + Standard_Real aConvertedMaxX = -std::numeric_limits::max(); + Standard_Real aConvertedMinY = std::numeric_limits::max(); + Standard_Real aConvertedMaxY = -std::numeric_limits::max(); + for (Standard_Integer anIdx = 0; anIdx < aNbOfPoints; ++anIdx) + { + aConvertedPoints[anIdx] = theCamera->Project (aPoints[anIdx]); + + aConvertedMinX = Min (aConvertedMinX, aConvertedPoints[anIdx].X()); + aConvertedMaxX = Max (aConvertedMaxX, aConvertedPoints[anIdx].X()); + + aConvertedMinY = Min (aConvertedMinY, aConvertedPoints[anIdx].Y()); + aConvertedMaxY = Max (aConvertedMaxY, aConvertedPoints[anIdx].Y()); + } + + const Standard_Boolean isBigObject = (Abs (aConvertedMaxX - aConvertedMinX) > 2.0) // width of zoom pers. object greater than width of window + || (Abs (aConvertedMaxY - aConvertedMinY) > 2.0); // height of zoom pers. object greater than height of window + const Standard_Boolean isAlreadyInScreen = (aConvertedMinX > -1.0 && aConvertedMinX < 1.0) + && (aConvertedMaxX > -1.0 && aConvertedMaxX < 1.0) + && (aConvertedMinY > -1.0 && aConvertedMinY < 1.0) + && (aConvertedMaxY > -1.0 && aConvertedMaxY < 1.0); + if (isBigObject || isAlreadyInScreen) + { + continue; + } + + const gp_Pnt aTPPoint = aStructure->TransformPersistence()->AnchorPoint(); + gp_Pnt aConvertedTPPoint = theCamera->Project (aTPPoint); + aConvertedTPPoint.SetZ (0.0); + + if (aConvertedTPPoint.Coord().Modulus() < Precision::Confusion()) + { + continue; + } + + Standard_Real aShiftX = 0.0; + if (aConvertedMinX < -1.0) + { + aShiftX = ((aConvertedMaxX < -1.0) ? (-(1.0 + aConvertedMaxX) + (aConvertedMaxX - aConvertedMinX)) : -(1.0 + aConvertedMinX)); + } + else if (aConvertedMaxX > 1.0) + { + aShiftX = ((aConvertedMinX > 1.0) ? ((aConvertedMinX - 1.0) + (aConvertedMaxX - aConvertedMinX)) : (aConvertedMaxX - 1.0)); + } + + Standard_Real aShiftY = 0.0; + if (aConvertedMinY < -1.0) + { + aShiftY = ((aConvertedMaxY < -1.0) ? (-(1.0 + aConvertedMaxY) + (aConvertedMaxY - aConvertedMinY)) : -(1.0 + aConvertedMinY)); + } + else if (aConvertedMaxY > 1.0) + { + aShiftY = ((aConvertedMinY > 1.0) ? ((aConvertedMinY - 1.0) + (aConvertedMaxY - aConvertedMinY)) : (aConvertedMaxY - 1.0)); + } + + const Standard_Real aDifX = Abs (aConvertedTPPoint.X()) - aShiftX; + const Standard_Real aDifY = Abs (aConvertedTPPoint.Y()) - aShiftY; + if (aDifX > Precision::Confusion()) + { + aMaxCoef = Max (aMaxCoef, Abs (aConvertedTPPoint.X()) / aDifX); + } + if (aDifY > Precision::Confusion()) + { + aMaxCoef = Max (aMaxCoef, Abs (aConvertedTPPoint.Y()) / aDifY); + } + } + } + + return (aMaxCoef > 0.0) ? aMaxCoef : 1.0; +} + +// ======================================================================= +// function : updateBVH +// purpose : +// ======================================================================= +void Graphic3d_Layer::updateBVH() const +{ + if (!myIsBVHPrimitivesNeedsReset) + { + return; + } + + myBVHPrimitives.Clear(); + myBVHPrimitivesTrsfPers.Clear(); + myAlwaysRenderedMap.Clear(); + myIsBVHPrimitivesNeedsReset = Standard_False; + for (Graphic3d_ArrayOfIndexedMapOfStructure::Iterator aMapIter (myArray); aMapIter.More(); aMapIter.Next()) + { + const Graphic3d_IndexedMapOfStructure& aStructures = aMapIter.Value(); + for (Graphic3d_IndexedMapOfStructure::Iterator aStructIter (aStructures); aStructIter.More(); aStructIter.Next()) + { + const Graphic3d_CStructure* aStruct = aStructIter.Value(); + if (aStruct->IsAlwaysRendered()) + { + aStruct->MarkAsNotCulled(); + myAlwaysRenderedMap.Add (aStruct); + } + else if (aStruct->TransformPersistence().IsNull()) + { + myBVHPrimitives.Add (aStruct); + } + else + { + myBVHPrimitivesTrsfPers.Add (aStruct); + } + } + } +} + +// ======================================================================= +// function : UpdateCulling +// purpose : +// ======================================================================= +void Graphic3d_Layer::UpdateCulling (Standard_Integer theViewId, + const Graphic3d_CullingTool& theSelector, + const Graphic3d_RenderingParams::FrustumCulling theFrustumCullingState) +{ + updateBVH(); + + myNbStructuresNotCulled = myNbStructures; + if (theFrustumCullingState != Graphic3d_RenderingParams::FrustumCulling_NoUpdate) + { + Standard_Boolean toTraverse = (theFrustumCullingState == Graphic3d_RenderingParams::FrustumCulling_On); + for (Graphic3d_IndexedMapOfStructure::Iterator aStructIter (myBVHPrimitives.Structures()); aStructIter.More(); aStructIter.Next()) + { + const Graphic3d_CStructure* aStruct = aStructIter.Value(); + aStruct->SetCulled (toTraverse); + } + for (Graphic3d_IndexedMapOfStructure::Iterator aStructIter (myBVHPrimitivesTrsfPers.Structures()); aStructIter.More(); aStructIter.Next()) + { + const Graphic3d_CStructure* aStruct = aStructIter.Value(); + aStruct->SetCulled (toTraverse); + } + } + + if (theFrustumCullingState != Graphic3d_RenderingParams::FrustumCulling_On) + { + return; + } + if (myBVHPrimitives .Size() == 0 + && myBVHPrimitivesTrsfPers.Size() == 0) + { + return; + } + + myNbStructuresNotCulled = myAlwaysRenderedMap.Extent(); + Graphic3d_CullingTool::CullingContext aCullCtx; + theSelector.SetCullingDistance(aCullCtx, myLayerSettings.CullingDistance()); + theSelector.SetCullingSize (aCullCtx, myLayerSettings.CullingSize()); + for (Standard_Integer aBVHTreeIdx = 0; aBVHTreeIdx < 2; ++aBVHTreeIdx) + { + const Standard_Boolean isTrsfPers = aBVHTreeIdx == 1; + opencascade::handle > aBVHTree; + if (isTrsfPers) + { + if (myBVHPrimitivesTrsfPers.Size() == 0) + continue; + + const Graphic3d_Mat4d& aProjection = theSelector.ProjectionMatrix(); + const Graphic3d_Mat4d& aWorldView = theSelector.WorldViewMatrix(); + const Graphic3d_WorldViewProjState& aWVPState = theSelector.WorldViewProjState(); + const Standard_Integer aViewportWidth = theSelector.ViewportWidth(); + const Standard_Integer aViewportHeight = theSelector.ViewportHeight(); + + aBVHTree = myBVHPrimitivesTrsfPers.BVH (theSelector.Camera(), aProjection, aWorldView, aViewportWidth, aViewportHeight, aWVPState); + } + else + { + if (myBVHPrimitives.Size() == 0) + continue; + + aBVHTree = myBVHPrimitives.BVH(); + } + + if (theSelector.IsCulled (aCullCtx, aBVHTree->MinPoint (0), aBVHTree->MaxPoint (0))) + { + continue; + } + + Standard_Integer aStack[BVH_Constants_MaxTreeDepth]; + Standard_Integer aHead = -1; + Standard_Integer aNode = 0; // a root node + for (;;) + { + if (!aBVHTree->IsOuter (aNode)) + { + const Standard_Integer aLeftChildIdx = aBVHTree->Child<0> (aNode); + const Standard_Integer aRightChildIdx = aBVHTree->Child<1> (aNode); + const Standard_Boolean isLeftChildIn = !theSelector.IsCulled (aCullCtx, aBVHTree->MinPoint (aLeftChildIdx), aBVHTree->MaxPoint (aLeftChildIdx)); + const Standard_Boolean isRightChildIn = !theSelector.IsCulled (aCullCtx, aBVHTree->MinPoint (aRightChildIdx), aBVHTree->MaxPoint (aRightChildIdx)); + if (isLeftChildIn + && isRightChildIn) + { + aNode = myBVHIsLeftChildQueuedFirst ? aLeftChildIdx : aRightChildIdx; + aStack[++aHead] = myBVHIsLeftChildQueuedFirst ? aRightChildIdx : aLeftChildIdx; + myBVHIsLeftChildQueuedFirst = !myBVHIsLeftChildQueuedFirst; + } + else if (isLeftChildIn + || isRightChildIn) + { + aNode = isLeftChildIn ? aLeftChildIdx : aRightChildIdx; + } + else + { + if (aHead < 0) + { + break; + } + + aNode = aStack[aHead--]; + } + } + else + { + Standard_Integer aIdx = aBVHTree->BegPrimitive (aNode); + const Graphic3d_CStructure* aStruct = isTrsfPers + ? myBVHPrimitivesTrsfPers.GetStructureById (aIdx) + : myBVHPrimitives.GetStructureById (aIdx); + if (aStruct->IsVisible (theViewId)) + { + aStruct->MarkAsNotCulled(); + ++myNbStructuresNotCulled; + } + if (aHead < 0) + { + break; + } + + aNode = aStack[aHead--]; + } + } + } +} + +// ======================================================================= +// function : Append +// purpose : +// ======================================================================= +Standard_Boolean Graphic3d_Layer::Append (const Graphic3d_Layer& theOther) +{ + // the source priority list shouldn't have more priorities + const Standard_Integer aNbPriorities = theOther.NbPriorities(); + if (aNbPriorities > NbPriorities()) + { + return Standard_False; + } + + // add all structures to destination priority list + for (Standard_Integer aPriorityIter = 0; aPriorityIter < aNbPriorities; ++aPriorityIter) + { + const Graphic3d_IndexedMapOfStructure& aStructures = theOther.myArray (aPriorityIter); + for (Graphic3d_IndexedMapOfStructure::Iterator aStructIter (aStructures); aStructIter.More(); aStructIter.Next()) + { + Add (aStructIter.Value(), aPriorityIter); + } + } + + return Standard_True; +} + +//======================================================================= +//function : SetLayerSettings +//purpose : +//======================================================================= +void Graphic3d_Layer::SetLayerSettings (const Graphic3d_ZLayerSettings& theSettings) +{ + const Standard_Boolean toUpdateTrsf = !myLayerSettings.Origin().IsEqual (theSettings.Origin(), gp::Resolution()); + myLayerSettings = theSettings; + if (!toUpdateTrsf) + { + return; + } + + for (Graphic3d_ArrayOfIndexedMapOfStructure::Iterator aMapIter (myArray); aMapIter.More(); aMapIter.Next()) + { + Graphic3d_IndexedMapOfStructure& aStructures = aMapIter.ChangeValue(); + for (Graphic3d_IndexedMapOfStructure::Iterator aStructIter (aStructures); aStructIter.More(); aStructIter.Next()) + { + Graphic3d_CStructure* aStructure = const_cast(aStructIter.Value()); + aStructure->updateLayerTransformation(); + } + } +} diff --git a/src/Graphic3d/Graphic3d_Layer.hxx b/src/Graphic3d/Graphic3d_Layer.hxx new file mode 100644 index 0000000000..dc947bc462 --- /dev/null +++ b/src/Graphic3d/Graphic3d_Layer.hxx @@ -0,0 +1,184 @@ +// Copyright (c) 2011-2019 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_Layer_HeaderFile +#define _Graphic3d_Layer_HeaderFile + +#include +#include +#include +#include +#include +#include +#include +#include + +//! Defines index map of structures. +typedef NCollection_IndexedMap Graphic3d_IndexedMapOfStructure; + +//! Defines array of indexed maps of structures. +typedef NCollection_Array1 Graphic3d_ArrayOfIndexedMapOfStructure; + +class Graphic3d_CullingTool; + +//! Presentations list sorted within priorities. +class Graphic3d_Layer : public Standard_Transient +{ + DEFINE_STANDARD_RTTIEXT(Graphic3d_Layer, Standard_Transient) +public: + + //! Initializes associated priority list and layer properties + Standard_EXPORT Graphic3d_Layer (Standard_Integer theNbPriorities, + const Handle(Select3D_BVHBuilder3d)& theBuilder); + + //! Destructor. + Standard_EXPORT virtual ~Graphic3d_Layer(); + + //! Returns BVH tree builder for frustom culling. + const Handle(Select3D_BVHBuilder3d)& FrustumCullingBVHBuilder() const { return myBVHPrimitivesTrsfPers.Builder(); } + + //! Assigns BVH tree builder for frustom culling. + void SetFrustumCullingBVHBuilder (const Handle(Select3D_BVHBuilder3d)& theBuilder) { myBVHPrimitivesTrsfPers.SetBuilder (theBuilder); } + + //! 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. + Standard_EXPORT void SetLayerSettings (const Graphic3d_ZLayerSettings& theSettings); + + Standard_EXPORT void Add (const Graphic3d_CStructure* theStruct, + Standard_Integer thePriority, + Standard_Boolean isForChangePriority = Standard_False); + + //! Remove structure and returns its priority, if the structure is not found, method returns negative value + Standard_EXPORT bool Remove (const Graphic3d_CStructure* theStruct, + Standard_Integer& thePriority, + Standard_Boolean isForChangePriority = Standard_False); + + //! @return the number of structures + Standard_Integer NbStructures() const { return myNbStructures; } + + //! Number of NOT culled structures in the layer. + Standard_Integer NbStructuresNotCulled() const { return myNbStructuresNotCulled; } + + //! Returns the number of available priority levels + Standard_Integer NbPriorities() const { return myArray.Length(); } + + //! Append layer of acceptable type (with similar number of priorities or less). + //! Returns Standard_False if the list can not be accepted. + Standard_EXPORT Standard_Boolean Append (const Graphic3d_Layer& theOther); + + //! Returns array of structures. + const Graphic3d_ArrayOfIndexedMapOfStructure& ArrayOfStructures() const { return myArray; } + + //! Marks BVH tree for given priority list as dirty and + //! marks primitive set for rebuild. + Standard_EXPORT void InvalidateBVHData(); + + //! Marks cached bounding box as obsolete. + void InvalidateBoundingBox() const + { + myIsBoundingBoxNeedsReset[0] = myIsBoundingBoxNeedsReset[1] = true; + } + + //! Returns layer bounding box. + //! @param theViewId view index to consider View Affinity in structure + //! @param theCamera camera definition + //! @param theWindowWidth viewport width (for applying transformation-persistence) + //! @param theWindowHeight viewport height (for applying transformation-persistence) + //! @param theToIncludeAuxiliary consider also auxiliary presentations (with infinite flag or with trihedron transformation persistence) + //! @return computed bounding box + Standard_EXPORT Bnd_Box BoundingBox (Standard_Integer theViewId, + const Handle(Graphic3d_Camera)& theCamera, + Standard_Integer theWindowWidth, + Standard_Integer theWindowHeight, + Standard_Boolean theToIncludeAuxiliary) const; + + //! Returns zoom-scale factor. + Standard_EXPORT Standard_Real considerZoomPersistenceObjects (Standard_Integer theViewId, + const Handle(Graphic3d_Camera)& theCamera, + Standard_Integer theWindowWidth, + Standard_Integer theWindowHeight) const; + + //! Update culling state - should be called before rendering. + //! Traverses through BVH tree to determine which structures are in view volume. + Standard_EXPORT void UpdateCulling (Standard_Integer theViewId, + const Graphic3d_CullingTool& theSelector, + const Graphic3d_RenderingParams::FrustumCulling theFrustumCullingState); + + //! Returns TRUE if layer is empty or has been discarded entirely by culling test. + bool IsCulled() const { return myNbStructuresNotCulled == 0; } + + //! Returns number of transform persistence objects. + Standard_Integer NbOfTransformPersistenceObjects() const + { + return myBVHPrimitivesTrsfPers.Size(); + } + +public: + + //! Returns set of Graphic3d_CStructures structures for building BVH tree. + const Graphic3d_BvhCStructureSet& CullableStructuresBVH() const { return myBVHPrimitives; } + + //! Returns set of transform persistent Graphic3d_CStructures for building BVH tree. + const Graphic3d_BvhCStructureSetTrsfPers& CullableTrsfPersStructuresBVH() const { return myBVHPrimitivesTrsfPers; } + + //! Returns indexed map of always rendered structures. + const NCollection_IndexedMap& NonCullableStructures() const { return myAlwaysRenderedMap; } + +protected: + + //! Updates BVH trees if their state has been invalidated. + Standard_EXPORT void updateBVH() const; + +private: + + //! Array of Graphic3d_CStructures by priority rendered in layer. + Graphic3d_ArrayOfIndexedMapOfStructure myArray; + + //! Overall number of structures rendered in the layer. + Standard_Integer myNbStructures; + + //! Number of NOT culled structures in the layer. + Standard_Integer myNbStructuresNotCulled; + + //! Layer setting flags. + Graphic3d_ZLayerSettings myLayerSettings; + + //! Set of Graphic3d_CStructures structures for building BVH tree. + mutable Graphic3d_BvhCStructureSet myBVHPrimitives; + + //! Set of transform persistent Graphic3d_CStructures for building BVH tree. + mutable Graphic3d_BvhCStructureSetTrsfPers myBVHPrimitivesTrsfPers; + + //! Indexed map of always rendered structures. + mutable NCollection_IndexedMap myAlwaysRenderedMap; + + //! Is needed for implementation of stochastic order of BVH traverse. + Standard_Boolean myBVHIsLeftChildQueuedFirst; + + //! Defines if the primitive set for BVH is outdated. + mutable Standard_Boolean myIsBVHPrimitivesNeedsReset; + + //! Defines if the cached bounding box is outdated. + mutable bool myIsBoundingBoxNeedsReset[2]; + + //! Cached layer bounding box. + mutable Bnd_Box myBoundingBox[2]; + +}; + +#endif // _Graphic3d_Layer_HeaderFile diff --git a/src/Graphic3d/Graphic3d_MapOfZLayerSettings.hxx b/src/Graphic3d/Graphic3d_MapOfZLayerSettings.hxx new file mode 100644 index 0000000000..944d14aafd --- /dev/null +++ b/src/Graphic3d/Graphic3d_MapOfZLayerSettings.hxx @@ -0,0 +1,24 @@ +// Copyright (c) 2019 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 _Vulkan_MapOfZLayerSettings_HeaderFile +#define _Vulkan_MapOfZLayerSettings_HeaderFile + +#include +#include +#include +#include + +typedef NCollection_DataMap Graphic3d_MapOfZLayerSettings; + +#endif // _Vulkan_MapOfZLayerSettings_HeaderFile diff --git a/src/Graphic3d/Graphic3d_ZLayerSettings.hxx b/src/Graphic3d/Graphic3d_ZLayerSettings.hxx index c7eab89702..25ee49ef3a 100644 --- a/src/Graphic3d/Graphic3d_ZLayerSettings.hxx +++ b/src/Graphic3d/Graphic3d_ZLayerSettings.hxx @@ -18,6 +18,7 @@ #include #include #include +#include #include enum Graphic3d_ZLayerSetting diff --git a/src/OpenGl/FILES b/src/OpenGl/FILES index 99faeb209f..107ce004c4 100755 --- a/src/OpenGl/FILES +++ b/src/OpenGl/FILES @@ -39,7 +39,6 @@ OpenGl_View_Raytrace.cxx OpenGl_View_Redraw.cxx OpenGl_GraduatedTrihedron.hxx OpenGl_GraduatedTrihedron.cxx -OpenGl_MapOfZLayerSettings.hxx OpenGl_Material.hxx OpenGl_MaterialState.hxx OpenGl_Matrix.hxx @@ -63,12 +62,6 @@ OpenGl_Font.hxx OpenGl_Font.cxx OpenGl_BackgroundArray.cxx OpenGl_BackgroundArray.hxx -OpenGl_BVHClipPrimitiveSet.cxx -OpenGl_BVHClipPrimitiveSet.hxx -OpenGl_BVHClipPrimitiveTrsfPersSet.cxx -OpenGl_BVHClipPrimitiveTrsfPersSet.hxx -OpenGl_BVHTreeSelector.cxx -OpenGl_BVHTreeSelector.hxx OpenGl_CappingAlgo.cxx OpenGl_CappingAlgo.hxx OpenGl_CappingPlaneResource.cxx @@ -109,7 +102,6 @@ OpenGl_GraphicDriver.cxx OpenGl_GraphicDriver.hxx OpenGl_IndexBuffer.cxx OpenGl_IndexBuffer.hxx -OpenGl_Layer.cxx OpenGl_Layer.hxx OpenGl_RenderFilter.hxx OpenGl_Sampler.cxx diff --git a/src/OpenGl/OpenGl_BVHClipPrimitiveSet.cxx b/src/OpenGl/OpenGl_BVHClipPrimitiveSet.cxx deleted file mode 100644 index 1fe7c08cc7..0000000000 --- a/src/OpenGl/OpenGl_BVHClipPrimitiveSet.cxx +++ /dev/null @@ -1,130 +0,0 @@ -// Created on: 2013-12-25 -// Created by: Varvara POSKONINA -// Copyright (c) 1999-2014 OPEN CASCADE SAS -// -// This file is part of Open CASCADE Technology software library. -// -// This library is free software; you can redistribute it and/or modify it under -// the terms of the GNU Lesser General Public License version 2.1 as published -// by the Free Software Foundation, with special exception defined in the file -// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT -// distribution for complete text of the license and disclaimer of any warranty. -// -// Alternatively, this file may be used under the terms of Open CASCADE -// commercial license or contractual agreement. - -#include - -#include -#include - -IMPLEMENT_STANDARD_RTTIEXT(OpenGl_BVHClipPrimitiveSet, BVH_PrimitiveSet3d) - -// ======================================================================= -// function : OpenGl_BVHClipPrimitiveSet -// purpose : -// ======================================================================= -OpenGl_BVHClipPrimitiveSet::OpenGl_BVHClipPrimitiveSet() -{ - myBuilder = new BVH_BinnedBuilder (BVH_Constants_LeafNodeSizeSingle, BVH_Constants_MaxTreeDepth); -} - -// ======================================================================= -// function : Size -// purpose : -// ======================================================================= -Standard_Integer OpenGl_BVHClipPrimitiveSet::Size() const -{ - return myStructs.Size(); -} - -// ======================================================================= -// function : Box -// purpose : -// ======================================================================= -Graphic3d_BndBox3d OpenGl_BVHClipPrimitiveSet::Box (const Standard_Integer theIdx) const -{ - return myStructs.FindKey (theIdx + 1)->BoundingBox(); -} - -// ======================================================================= -// function : Center -// purpose : -// ======================================================================= -Standard_Real OpenGl_BVHClipPrimitiveSet::Center (const Standard_Integer theIdx, - const Standard_Integer theAxis) const -{ - Graphic3d_BndBox3d aBndBox = myStructs.FindKey (theIdx + 1)->BoundingBox(); - - const Standard_Real aMin = aBndBox.CornerMin()[theAxis]; - const Standard_Real aMax = aBndBox.CornerMax()[theAxis]; - const Standard_Real aCenter = (aMin + aMax) * 0.5; - return aCenter; -} - -// ======================================================================= -// function : Swap -// purpose : -// ======================================================================= -void OpenGl_BVHClipPrimitiveSet::Swap (const Standard_Integer theIdx1, - const Standard_Integer theIdx2) -{ - myStructs.Swap (theIdx1 + 1, theIdx2 + 1); -} - -// ======================================================================= -// function : Add -// purpose : -// ======================================================================= -Standard_Boolean OpenGl_BVHClipPrimitiveSet::Add (const OpenGl_Structure* theStruct) -{ - const Standard_Integer aSize = myStructs.Size(); - - if (myStructs.Add (theStruct) > aSize) // new structure? - { - MarkDirty(); - - return Standard_True; - } - - return Standard_False; -} - -// ======================================================================= -// function : Remove -// purpose : -// ======================================================================= -Standard_Boolean OpenGl_BVHClipPrimitiveSet::Remove (const OpenGl_Structure* theStruct) -{ - const Standard_Integer anIndex = myStructs.FindIndex (theStruct); - - if (anIndex != 0) - { - myStructs.Swap (Size(), anIndex); - myStructs.RemoveLast(); - MarkDirty(); - - return Standard_True; - } - - return Standard_False; -} - -// ======================================================================= -// function : Clear -// purpose : -// ======================================================================= -void OpenGl_BVHClipPrimitiveSet::Clear() -{ - myStructs.Clear(); - MarkDirty(); -} - -// ======================================================================= -// function : GetStructureById -// purpose : -// ======================================================================= -const OpenGl_Structure* OpenGl_BVHClipPrimitiveSet::GetStructureById (Standard_Integer theId) -{ - return myStructs.FindKey (theId + 1); -} diff --git a/src/OpenGl/OpenGl_BVHClipPrimitiveSet.hxx b/src/OpenGl/OpenGl_BVHClipPrimitiveSet.hxx deleted file mode 100644 index 902444c768..0000000000 --- a/src/OpenGl/OpenGl_BVHClipPrimitiveSet.hxx +++ /dev/null @@ -1,75 +0,0 @@ -// Created on: 2013-12-25 -// Created by: Varvara POSKONINA -// Copyright (c) 1999-2014 OPEN CASCADE SAS -// -// This file is part of Open CASCADE Technology software library. -// -// This library is free software; you can redistribute it and/or modify it under -// the terms of the GNU Lesser General Public License version 2.1 as published -// by the Free Software Foundation, with special exception defined in the file -// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT -// distribution for complete text of the license and disclaimer of any warranty. -// -// Alternatively, this file may be used under the terms of Open CASCADE -// commercial license or contractual agreement. - -#ifndef _OpenGl_BVHClipPrimitiveSet_HeaderFile -#define _OpenGl_BVHClipPrimitiveSet_HeaderFile - -#include -#include -#include - -#include - -//! Set of OpenGl_Structures for building BVH tree. -class OpenGl_BVHClipPrimitiveSet : public BVH_PrimitiveSet3d -{ - DEFINE_STANDARD_RTTIEXT(OpenGl_BVHClipPrimitiveSet, BVH_PrimitiveSet3d) -protected: - - using BVH_PrimitiveSet3d::Box; - -public: - - //! Creates an empty primitive set for BVH clipping. - OpenGl_BVHClipPrimitiveSet(); - - //! Returns total number of structures. - virtual Standard_Integer Size() const Standard_OVERRIDE; - - //! Returns AABB of the structure. - virtual Graphic3d_BndBox3d Box (const Standard_Integer theIdx) const Standard_OVERRIDE; - - //! Calculates center of the AABB along given axis. - 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, - const Standard_Integer theIdx2) Standard_OVERRIDE; - - //! Adds structure to the set. - //! @return true if structure added, otherwise returns false (structure already in the set). - Standard_Boolean Add (const OpenGl_Structure* theStruct); - - //! Removes the given structure from the set. - //! @return true if structure removed, otherwise returns false (structure is not in the set). - Standard_Boolean Remove (const OpenGl_Structure* theStruct); - - //! Cleans the whole primitive set. - void Clear(); - - //! Returns the structure corresponding to the given ID. - const OpenGl_Structure* GetStructureById (Standard_Integer theId); - - //! Access directly a collection of structures. - const NCollection_IndexedMap& Structures() const { return myStructs; } - -private: - - NCollection_IndexedMap myStructs; //!< Indexed map of structures. - -}; - -#endif // _OpenGl_BVHClipPrimitiveSet_HeaderFile diff --git a/src/OpenGl/OpenGl_BVHClipPrimitiveTrsfPersSet.cxx b/src/OpenGl/OpenGl_BVHClipPrimitiveTrsfPersSet.cxx deleted file mode 100644 index 82576bf861..0000000000 --- a/src/OpenGl/OpenGl_BVHClipPrimitiveTrsfPersSet.cxx +++ /dev/null @@ -1,172 +0,0 @@ -// Created on: 2015-06-30 -// Created by: Anton POLETAEV -// Copyright (c) 2015 OPEN CASCADE SAS -// -// This file is part of Open CASCADE Technology software library. -// -// This library is free software; you can redistribute it and/or modify it under -// the terms of the GNU Lesser General Public License version 2.1 as published -// by the Free Software Foundation, with special exception defined in the file -// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT -// distribution for complete text of the license and disclaimer of any warranty. -// -// Alternatively, this file may be used under the terms of Open CASCADE -// commercial license or contractual agreement. - -#include - -// ======================================================================= -// function : OpenGl_BVHClipPrimitiveTrsfPersSet -// purpose : -// ======================================================================= -OpenGl_BVHClipPrimitiveTrsfPersSet::OpenGl_BVHClipPrimitiveTrsfPersSet (const Handle(Select3D_BVHBuilder3d)& theBuilder) -: myIsDirty (Standard_False), - myBVH (new BVH_Tree()), - myBuilder (theBuilder) -{ - // -} - -// ======================================================================= -// function : Size -// purpose : -// ======================================================================= -Standard_Integer OpenGl_BVHClipPrimitiveTrsfPersSet::Size() const -{ - return myStructs.Size(); -} - -// ======================================================================= -// function : Box -// purpose : -// ======================================================================= -Graphic3d_BndBox3d OpenGl_BVHClipPrimitiveTrsfPersSet::Box (const Standard_Integer theIdx) const -{ - return *myStructBoxes (theIdx + 1); -} - -// ======================================================================= -// function : Center -// purpose : -// ======================================================================= -Standard_Real OpenGl_BVHClipPrimitiveTrsfPersSet::Center (const Standard_Integer theIdx, - const Standard_Integer theAxis) const -{ - const Graphic3d_BndBox3d& aBndBox = *myStructBoxes (theIdx + 1); - return (aBndBox.CornerMin()[theAxis] + aBndBox.CornerMax()[theAxis]) * 0.5; -} - -// ======================================================================= -// function : Swap -// purpose : -// ======================================================================= -void OpenGl_BVHClipPrimitiveTrsfPersSet::Swap (const Standard_Integer theIdx1, - const Standard_Integer theIdx2) -{ - const Standard_Integer aStructIdx1 = theIdx1 + 1; - const Standard_Integer aStructIdx2 = theIdx2 + 1; - - myStructs .Swap (aStructIdx1, aStructIdx2); - myStructBoxes.Swap (aStructIdx1, aStructIdx2); -} - -// ======================================================================= -// function : Add -// purpose : -// ======================================================================= -Standard_Boolean OpenGl_BVHClipPrimitiveTrsfPersSet::Add (const OpenGl_Structure* theStruct) -{ - const Standard_Integer aSize = myStructs.Size(); - - if (myStructs.Add (theStruct) > aSize) // new structure? - { - MarkDirty(); - - return Standard_True; - } - - return Standard_False; -} - -// ======================================================================= -// function : Remove -// purpose : -// ======================================================================= -Standard_Boolean OpenGl_BVHClipPrimitiveTrsfPersSet::Remove (const OpenGl_Structure* theStruct) -{ - const Standard_Integer anIndex = myStructs.FindIndex (theStruct); - - if (anIndex != 0) - { - myStructs.Swap (Size(), anIndex); - myStructs.RemoveLast(); - MarkDirty(); - - return Standard_True; - } - - return Standard_False; -} - -// ======================================================================= -// function : Clear -// purpose : -// ======================================================================= -void OpenGl_BVHClipPrimitiveTrsfPersSet::Clear() -{ - myStructs.Clear(); - MarkDirty(); -} - -// ======================================================================= -// function : GetStructureById -// purpose : -// ======================================================================= -const OpenGl_Structure* OpenGl_BVHClipPrimitiveTrsfPersSet::GetStructureById (Standard_Integer theId) -{ - return myStructs.FindKey (theId + 1); -} - -//======================================================================= -// function : BVH -// purpose : -//======================================================================= -const opencascade::handle >& - OpenGl_BVHClipPrimitiveTrsfPersSet::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) -{ - if (!myIsDirty - && (myStructBoxesState.IsValid() - && !myStructBoxesState.IsChanged (theWVPState))) - { - return myBVH; - } - - myStructBoxes.ReSize (myStructs.Size()); - - for (Standard_Integer aStructIdx = 1; aStructIdx <= myStructs.Size(); ++aStructIdx) - { - const OpenGl_Structure* aStructure = myStructs (aStructIdx); - - Handle(HBndBox3d) aBoundingBox = new HBndBox3d(); - *aBoundingBox = aStructure->BoundingBox(); - if (!aStructure->TransformPersistence().IsNull()) - { - aStructure->TransformPersistence()->Apply (theCamera, theProjectionMatrix, theWorldViewMatrix, theViewportWidth, theViewportHeight, *aBoundingBox); - } - - myStructBoxes.Add (aBoundingBox); - } - - myBuilder->Build (this, myBVH.operator->(), BVH_Set::Box()); - - myStructBoxesState = theWVPState; - myStructBoxes.Clear(); - myIsDirty = Standard_False; - - return myBVH; -} diff --git a/src/OpenGl/OpenGl_BVHClipPrimitiveTrsfPersSet.hxx b/src/OpenGl/OpenGl_BVHClipPrimitiveTrsfPersSet.hxx deleted file mode 100644 index 6eedd2b3f6..0000000000 --- a/src/OpenGl/OpenGl_BVHClipPrimitiveTrsfPersSet.hxx +++ /dev/null @@ -1,118 +0,0 @@ -// Created on: 2015-06-30 -// Created by: Anton POLETAEV -// Copyright (c) 2015 OPEN CASCADE SAS -// -// This file is part of Open CASCADE Technology software library. -// -// This library is free software; you can redistribute it and/or modify it under -// the terms of the GNU Lesser General Public License version 2.1 as published -// by the Free Software Foundation, with special exception defined in the file -// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT -// distribution for complete text of the license and disclaimer of any warranty. -// -// Alternatively, this file may be used under the terms of Open CASCADE -// commercial license or contractual agreement. - -#ifndef _OpenGl_BVHClipPrimitiveTrsfPersSet_HeaderFile -#define _OpenGl_BVHClipPrimitiveTrsfPersSet_HeaderFile - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -//! Set of transformation persistent OpenGl_Structure for building BVH tree. -//! Provides built-in mechanism to invalidate tree when world view projection state changes. -//! Due to frequent invalidation of BVH tree the choice of BVH tree builder is made -//! in favor of BVH linear builder (quick rebuild). -class OpenGl_BVHClipPrimitiveTrsfPersSet : public BVH_Set -{ -private: - - typedef NCollection_Shared HBndBox3d; - -public: - - //! Creates an empty primitive set for BVH clipping. - OpenGl_BVHClipPrimitiveTrsfPersSet (const Handle(Select3D_BVHBuilder3d)& theBuilder); - - //! Returns total number of structures. - virtual Standard_Integer Size() const Standard_OVERRIDE; - - //! Returns AABB of the structure. - virtual Graphic3d_BndBox3d Box (const Standard_Integer theIdx) const Standard_OVERRIDE; - - //! Calculates center of the AABB along given axis. - 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, - const Standard_Integer theIdx2) Standard_OVERRIDE; - - //! Adds structure to the set. - //! @return true if structure added, otherwise returns false (structure already in the set). - Standard_Boolean Add (const OpenGl_Structure* theStruct); - - //! Removes the given structure from the set. - //! @return true if structure removed, otherwise returns false (structure is not in the set). - Standard_Boolean Remove (const OpenGl_Structure* theStruct); - - //! Cleans the whole primitive set. - void Clear(); - - //! Returns the structure corresponding to the given ID. - const OpenGl_Structure* GetStructureById (Standard_Integer theId); - - //! Access directly a collection of structures. - const NCollection_IndexedMap& Structures() const { return myStructs; } - - //! Marks object state as outdated (needs BVH rebuilding). - void MarkDirty() - { - myIsDirty = Standard_True; - } - - //! Returns BVH tree for the given world view projection (builds it if necessary). - const opencascade::handle >& 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); - - //! Returns builder for bottom-level BVH. - const Handle(Select3D_BVHBuilder3d)& Builder() const { return myBuilder; } - - //! Assigns builder for bottom-level BVH. - void SetBuilder (const Handle(Select3D_BVHBuilder3d)& theBuilder) { myBuilder = theBuilder; } - -private: - - //! Marks internal object state as outdated. - Standard_Boolean myIsDirty; - - //! Constructed bottom-level BVH. - opencascade::handle > myBVH; - - //! Builder for bottom-level BVH. - Handle(Select3D_BVHBuilder3d) myBuilder; - - //! Indexed map of structures. - NCollection_IndexedMap myStructs; - - //! Cached set of bounding boxes precomputed for transformation persistent selectable objects. - //! Cache exists only during computation of BVH Tree. Bounding boxes are world view projection - //! dependent and should by synchronized. - NCollection_IndexedMap myStructBoxes; - - //! State of world view projection used for generation of transformation persistence bounding boxes. - Graphic3d_WorldViewProjState myStructBoxesState; -}; - -#endif // _OpenGl_BVHClipPrimitiveTrsfPersSet_HeaderFile diff --git a/src/OpenGl/OpenGl_BVHTreeSelector.cxx b/src/OpenGl/OpenGl_BVHTreeSelector.cxx deleted file mode 100644 index 95edcad41f..0000000000 --- a/src/OpenGl/OpenGl_BVHTreeSelector.cxx +++ /dev/null @@ -1,198 +0,0 @@ -// Created on: 2013-12-25 -// Created by: Varvara POSKONINA -// Copyright (c) 1999-2014 OPEN CASCADE SAS -// -// This file is part of Open CASCADE Technology software library. -// -// This library is free software; you can redistribute it and/or modify it under -// the terms of the GNU Lesser General Public License version 2.1 as published -// by the Free Software Foundation, with special exception defined in the file -// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT -// distribution for complete text of the license and disclaimer of any warranty. -// -// Alternatively, this file may be used under the terms of Open CASCADE -// commercial license or contractual agreement. - -#include - -#include -#include -#include - -// ======================================================================= -// function : OpenGl_BVHTreeSelector -// purpose : -// ======================================================================= -OpenGl_BVHTreeSelector::OpenGl_BVHTreeSelector() -: myClipVerts (0, Graphic3d_Camera::FrustumVerticesNB), - myIsProjectionParallel (Standard_True), - myCamScale (1.0), - myPixelSize (1.0) -{ - // -} - -// ======================================================================= -// function : SetViewVolume -// purpose : Retrieves view volume's planes equations and its vertices from projection and world-view matrices. -// ======================================================================= -void OpenGl_BVHTreeSelector::SetViewVolume (const Handle(Graphic3d_Camera)& theCamera) -{ - if (!myWorldViewProjState.IsChanged (theCamera->WorldViewProjState())) - return; - - myIsProjectionParallel = theCamera->IsOrthographic(); - const gp_Dir aCamDir = theCamera->Direction(); - - myCamera = theCamera; - myProjectionMat = theCamera->ProjectionMatrix(); - myWorldViewMat = theCamera->OrientationMatrix(); - myWorldViewProjState = theCamera->WorldViewProjState(); - myCamEye.SetValues (theCamera->Eye().X(), theCamera->Eye().Y(), theCamera->Eye().Z()); - myCamDir.SetValues (aCamDir.X(), aCamDir.Y(), aCamDir.Z()); - myCamScale = theCamera->IsOrthographic() - ? theCamera->Scale() - : 2.0 * Tan (theCamera->FOVy() * M_PI / 360.0); // same as theCamera->Scale()/theCamera->Distance() - - // Compute frustum points - theCamera->FrustumPoints (myClipVerts); - - // Compute frustum planes - // Vertices go in order: - // 0, 2, 1 - const Standard_Integer aLookup1[] = { 0, 1, 0 }; - const Standard_Integer aLookup2[] = { 0, 0, 1 }; - Standard_Integer aShifts[] = { 0, 0, 0 }; - - // Planes go in order: - // LEFT, RIGHT, BOTTOM, TOP, NEAR, FAR - for (Standard_Integer aFaceIdx = 0; aFaceIdx < 3; ++aFaceIdx) - { - for (Standard_Integer i = 0; i < 2; ++i) - { - OpenGl_Vec3d aPlanePnts[3]; - for (Standard_Integer aPntIter = 0; aPntIter < 3; ++aPntIter) - { - aShifts[aFaceIdx] = i; - aShifts[(aFaceIdx + 1) % 3] = aLookup1[aPntIter]; - aShifts[(aFaceIdx + 2) % 3] = aLookup2[aPntIter]; - - aPlanePnts[aPntIter] = myClipVerts[aShifts[0] * 2 * 2 + aShifts[1] * 2 + aShifts[2]]; - } - - myClipPlanes[aFaceIdx * 2 + i].Origin = aPlanePnts[0]; - myClipPlanes[aFaceIdx * 2 + i].Normal = - OpenGl_Vec3d::Cross (aPlanePnts[1] - aPlanePnts[0], - aPlanePnts[2] - aPlanePnts[0]).Normalized() * (i == 0 ? -1.f : 1.f); - } - } -} - -// ======================================================================= -// function : SetViewportSize -// purpose : -// ======================================================================= -void OpenGl_BVHTreeSelector::SetViewportSize (Standard_Integer theViewportWidth, - Standard_Integer theViewportHeight, - Standard_Real theResolutionRatio) -{ - myViewportHeight = theViewportHeight > 0 ? theViewportHeight : 1; - myViewportWidth = theViewportWidth > 0 ? theViewportWidth : 1; - myPixelSize = Max (theResolutionRatio / myViewportHeight, - theResolutionRatio / myViewportWidth); -} - -// ======================================================================= -// function : SignedPlanePointDistance -// purpose : -// ======================================================================= -Standard_Real OpenGl_BVHTreeSelector::SignedPlanePointDistance (const OpenGl_Vec4d& theNormal, - const OpenGl_Vec4d& thePnt) -{ - const Standard_Real aNormLength = std::sqrt (theNormal.x() * theNormal.x() - + theNormal.y() * theNormal.y() - + theNormal.z() * theNormal.z()); - - if (aNormLength < gp::Resolution()) - return 0.0; - - 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()); -} - -// ======================================================================= -// function : SetCullingDistance -// purpose : -// ======================================================================= -void OpenGl_BVHTreeSelector::SetCullingDistance (CullingContext& theCtx, - Standard_Real theDistance) const -{ - theCtx.DistCull = -1.0; - if (!myIsProjectionParallel) - { - theCtx.DistCull = theDistance > 0.0 && !Precision::IsInfinite (theDistance) - ? theDistance - : -1.0; - } -} - -// ======================================================================= -// function : SetCullingSize -// purpose : -// ======================================================================= -void OpenGl_BVHTreeSelector::SetCullingSize (CullingContext& theCtx, - Standard_Real theSize) const -{ - theCtx.SizeCull2 = -1.0; - if (theSize > 0.0 && !Precision::IsInfinite (theSize)) - { - theCtx.SizeCull2 = myPixelSize * theSize; - theCtx.SizeCull2 *= myCamScale; - theCtx.SizeCull2 *= theCtx.SizeCull2; - } -} - -// ======================================================================= -// function : CacheClipPtsProjections -// purpose : -// ======================================================================= -void OpenGl_BVHTreeSelector::CacheClipPtsProjections() -{ - // project frustum onto its own normals - const Standard_Integer anIncFactor = myIsProjectionParallel ? 2 : 1; - for (Standard_Integer aPlaneIter = 0; aPlaneIter < PlanesNB - 1; aPlaneIter += anIncFactor) - { - Standard_Real aMaxProj = -std::numeric_limits::max(); - Standard_Real aMinProj = std::numeric_limits::max(); - for (Standard_Integer aCornerIter = 0; aCornerIter < Graphic3d_Camera::FrustumVerticesNB; ++aCornerIter) - { - Standard_Real aProjection = myClipVerts[aCornerIter].Dot (myClipPlanes[aPlaneIter].Normal); - aMaxProj = Max (aProjection, aMaxProj); - aMinProj = Min (aProjection, aMinProj); - } - myMaxClipProjectionPts[aPlaneIter] = aMaxProj; - myMinClipProjectionPts[aPlaneIter] = aMinProj; - } - - // project frustum onto main axes - OpenGl_Vec3d anAxes[] = { OpenGl_Vec3d (1.0, 0.0, 0.0), - OpenGl_Vec3d (0.0, 1.0, 0.0), - OpenGl_Vec3d (0.0, 0.0, 1.0) }; - for (Standard_Integer aDim = 0; aDim < 3; ++aDim) - { - Standard_Real aMaxProj = -std::numeric_limits::max(); - Standard_Real aMinProj = std::numeric_limits::max(); - for (Standard_Integer aCornerIter = 0; aCornerIter < Graphic3d_Camera::FrustumVerticesNB; ++aCornerIter) - { - Standard_Real aProjection = myClipVerts[aCornerIter].Dot (anAxes[aDim]); - aMaxProj = Max (aProjection, aMaxProj); - aMinProj = Min (aProjection, aMinProj); - } - myMaxOrthoProjectionPts[aDim] = aMaxProj; - myMinOrthoProjectionPts[aDim] = aMinProj; - } -} diff --git a/src/OpenGl/OpenGl_BVHTreeSelector.hxx b/src/OpenGl/OpenGl_BVHTreeSelector.hxx deleted file mode 100644 index 6cf9cfe83e..0000000000 --- a/src/OpenGl/OpenGl_BVHTreeSelector.hxx +++ /dev/null @@ -1,288 +0,0 @@ -// Created on: 2013-12-25 -// Created by: Varvara POSKONINA -// Copyright (c) 1999-2014 OPEN CASCADE SAS -// -// This file is part of Open CASCADE Technology software library. -// -// This library is free software; you can redistribute it and/or modify it under -// the terms of the GNU Lesser General Public License version 2.1 as published -// by the Free Software Foundation, with special exception defined in the file -// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT -// distribution for complete text of the license and disclaimer of any warranty. -// -// Alternatively, this file may be used under the terms of Open CASCADE -// commercial license or contractual agreement. - -#ifndef _OpenGl_BVHTreeSelector_HeaderFile -#define _OpenGl_BVHTreeSelector_HeaderFile - -#include -#include -#include - -//! BVHTreeSelector class provides a possibility to store parameters of view volume, -//! such as its vertices and equations, and contains methods detecting if given AABB overlaps -//! view volume. -class OpenGl_BVHTreeSelector -{ -public: - //! Auxiliary structure holding non-persistent culling options. - struct CullingContext - { - Standard_Real DistCull; //!< culling distance - Standard_Real SizeCull2; //!< squared culling size - - //! Empty constructor. - CullingContext() : DistCull (-1.0), SizeCull2 (-1.0) {} - }; - - //! Auxiliary structure representing 3D plane. - struct Plane - { - //! Creates default plane. - Plane() - : Origin (0.0, 0.0, 0.0), - Normal (0.0, 0.0, 1.0) {} - - //! Creates plane with specific parameters. - Plane (const OpenGl_Vec3d& theOrigin, - const OpenGl_Vec3d& theNormal) - : Origin (theOrigin), - Normal (theNormal) {} - - OpenGl_Vec3d Origin; - OpenGl_Vec3d Normal; - }; - -public: - - //! Creates an empty selector object with parallel projection type by default. - Standard_EXPORT OpenGl_BVHTreeSelector(); - - //! Retrieves view volume's planes equations and its vertices from projection and world-view matrices. - Standard_EXPORT void SetViewVolume (const Handle(Graphic3d_Camera)& theCamera); - - Standard_EXPORT void SetViewportSize (Standard_Integer theViewportWidth, - Standard_Integer theViewportHeight, - Standard_Real theResolutionRatio); - - //! Setup distance culling. - Standard_EXPORT void SetCullingDistance (CullingContext& theCtx, - Standard_Real theDistance) const; - - //! Setup size culling. - Standard_EXPORT void SetCullingSize (CullingContext& theCtx, - Standard_Real theSize) 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. - Standard_EXPORT void CacheClipPtsProjections(); - - //! Checks whether given AABB should be entirely culled or not. - //! @param theCtx [in] culling properties - //! @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 - bool IsCulled (const CullingContext& theCtx, - const OpenGl_Vec3d& theMinPt, - const OpenGl_Vec3d& theMaxPt) const - { - return isFullOut (theMinPt, theMaxPt) - || isTooDistant(theCtx, theMinPt, theMaxPt) - || isTooSmall (theCtx, theMinPt, theMaxPt); - } - - //! Return the camera definition. - const Handle(Graphic3d_Camera)& Camera() const { return myCamera; } - - //! Returns current projection matrix. - const OpenGl_Mat4d& ProjectionMatrix() const - { - return myProjectionMat; - } - - //! Returns current world view transformation matrix. - const OpenGl_Mat4d& WorldViewMatrix() const - { - return myWorldViewMat; - } - - Standard_Integer ViewportWidth() const - { - return myViewportWidth; - } - - Standard_Integer ViewportHeight() const - { - return myViewportHeight; - } - - //! Returns state of current world view projection transformation matrices. - const Graphic3d_WorldViewProjState& WorldViewProjState() const - { - return myWorldViewProjState; - } - -protected: - - //! Calculates signed distance from plane to point. - //! @param theNormal [in] the plane's normal. - //! @param thePnt [in] - Standard_EXPORT Standard_Real SignedPlanePointDistance (const OpenGl_Vec4d& theNormal, - const OpenGl_Vec4d& thePnt); - - //! Detects if AABB overlaps view volume using separating axis theorem (SAT). - //! @param theMinPt [in] maximum point of AABB. - //! @param theMaxPt [in] minimum point of AABB. - //! @return FALSE, if AABB is in viewing area, TRUE otherwise. - bool isFullOut (const OpenGl_Vec3d& theMinPt, - const OpenGl_Vec3d& theMaxPt) const - { - // E1 - // |_ E0 - // / - // E2 - - // E0 test (x axis) - if (theMinPt.x() > myMaxOrthoProjectionPts[0] - || theMaxPt.x() < myMinOrthoProjectionPts[0]) - { - return true; - } - - // E1 test (y axis) - if (theMinPt.y() > myMaxOrthoProjectionPts[1] - || theMaxPt.y() < myMinOrthoProjectionPts[1]) - { - return true; - } - - // E2 test (z axis) - if (theMinPt.z() > myMaxOrthoProjectionPts[2] - || theMaxPt.z() < myMinOrthoProjectionPts[2]) - { - return true; - } - - const Standard_Integer anIncFactor = myIsProjectionParallel ? 2 : 1; - for (Standard_Integer aPlaneIter = 0; aPlaneIter < PlanesNB - 1; aPlaneIter += anIncFactor) - { - // frustum normals - const OpenGl_Vec3d anAxis = myClipPlanes[aPlaneIter].Normal; - - const OpenGl_Vec3d aPVertex (anAxis.x() > 0.0 ? theMaxPt.x() : theMinPt.x(), - anAxis.y() > 0.0 ? theMaxPt.y() : theMinPt.y(), - anAxis.z() > 0.0 ? theMaxPt.z() : theMinPt.z()); - Standard_Real aPnt0 = aPVertex.Dot (anAxis); - - if (aPnt0 >= myMinClipProjectionPts[aPlaneIter] - && aPnt0 <= myMaxClipProjectionPts[aPlaneIter]) - { - continue; - } - - const OpenGl_Vec3d aNVertex (anAxis.x() > 0.0 ? theMinPt.x() : theMaxPt.x(), - anAxis.y() > 0.0 ? theMinPt.y() : theMaxPt.y(), - anAxis.z() > 0.0 ? theMinPt.z() : theMaxPt.z()); - Standard_Real aPnt1 = aNVertex.Dot (anAxis); - - const Standard_Real aMin = aPnt0 < aPnt1 ? aPnt0 : aPnt1; - const Standard_Real aMax = aPnt0 > aPnt1 ? aPnt0 : aPnt1; - - if (aMin > myMaxClipProjectionPts[aPlaneIter] - || aMax < myMinClipProjectionPts[aPlaneIter]) - { - return true; - } - } - return false; - } - - //! Returns TRUE if given AABB should be discarded by distance culling criterion. - bool isTooDistant (const CullingContext& theCtx, - const OpenGl_Vec3d& theMinPt, - const OpenGl_Vec3d& theMaxPt) const - { - if (theCtx.DistCull <= 0.0) - { - return false; - } - - // check distance to the bounding sphere as fast approximation - const Graphic3d_Vec3d aSphereCenter = (theMinPt + theMaxPt) * 0.5; - const Standard_Real aSphereRadius = (theMaxPt - theMinPt).maxComp() * 0.5; - return (aSphereCenter - myCamEye).Modulus() - aSphereRadius > theCtx.DistCull; - } - - //! Returns TRUE if given AABB should be discarded by size culling criterion. - bool isTooSmall (const CullingContext& theCtx, - const OpenGl_Vec3d& theMinPt, - const OpenGl_Vec3d& theMaxPt) const - { - if (theCtx.SizeCull2 <= 0.0) - { - return false; - } - - const Standard_Real aBoxDiag2 = (theMaxPt - theMinPt).SquareModulus(); - if (myIsProjectionParallel) - { - return aBoxDiag2 < theCtx.SizeCull2; - } - - // note that distances behind the Eye (aBndDist < 0) are not scaled correctly here, - // but majority of such objects should be culled by frustum - const OpenGl_Vec3d aBndCenter = (theMinPt + theMaxPt) * 0.5; - const Standard_Real aBndDist = (aBndCenter - myCamEye).Dot (myCamDir); - return aBoxDiag2 < theCtx.SizeCull2 * aBndDist * aBndDist; - } - -protected: - - //! Enumerates planes of view volume. - enum - { - Plane_Left, - Plane_Right, - Plane_Bottom, - Plane_Top, - Plane_Near, - Plane_Far, - PlanesNB - }; - -protected: - - Plane myClipPlanes[PlanesNB]; //!< Planes - NCollection_Array1 myClipVerts; //!< Vertices - - Handle(Graphic3d_Camera) myCamera; //!< camera definition - - // for caching clip points projections onto viewing area normals once per traverse - // ORDER: LEFT, RIGHT, BOTTOM, TOP, NEAR, FAR - 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_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_Mat4d myProjectionMat; - OpenGl_Mat4d myWorldViewMat; - - Standard_Integer myViewportWidth; - Standard_Integer myViewportHeight; - - Graphic3d_WorldViewProjState myWorldViewProjState; //!< State of world view projection matrices. - - Graphic3d_Vec3d myCamEye; //!< camera eye position for distance culling - Graphic3d_Vec3d myCamDir; //!< camera direction for size culling - Standard_Real myCamScale; //!< camera scale for size culling - Standard_Real myPixelSize; //!< pixel size for size culling - -}; - -#endif // _OpenGl_BVHTreeSelector_HeaderFile diff --git a/src/OpenGl/OpenGl_Caps.hxx b/src/OpenGl/OpenGl_Caps.hxx index 548a8bea70..6bdc98e92e 100755 --- a/src/OpenGl/OpenGl_Caps.hxx +++ b/src/OpenGl/OpenGl_Caps.hxx @@ -60,7 +60,7 @@ public: //! @name context creation parameters * (see OpenGl_Context - messages will be printed to standard output). * Affects performance - thus should not be turned on by products in released state. * - * OFF by default. Currently implemented only for Windows (WGL). + * OFF by default. */ Standard_Boolean contextDebug; diff --git a/src/OpenGl/OpenGl_FrameStats.cxx b/src/OpenGl/OpenGl_FrameStats.cxx index c43b16cce8..ff55ab0c94 100644 --- a/src/OpenGl/OpenGl_FrameStats.cxx +++ b/src/OpenGl/OpenGl_FrameStats.cxx @@ -186,12 +186,12 @@ void OpenGl_FrameStats::updateStatistics (const Handle(Graphic3d_CView)& theView // purpose : // ======================================================================= void OpenGl_FrameStats::updateStructures (Standard_Integer theViewId, - const OpenGl_IndexedMapOfStructure& theStructures, + const NCollection_IndexedMap& theStructures, Standard_Boolean theToCountElems, Standard_Boolean theToCountTris, Standard_Boolean theToCountMem) { - for (OpenGl_IndexedMapOfStructure::Iterator aStructIter (theStructures); aStructIter.More(); aStructIter.Next()) + for (OpenGl_Structure::StructIterator aStructIter (theStructures); aStructIter.More(); aStructIter.Next()) { const OpenGl_Structure* aStruct = aStructIter.Value(); const bool isStructHidden = aStruct->IsCulled() diff --git a/src/OpenGl/OpenGl_FrameStats.hxx b/src/OpenGl/OpenGl_FrameStats.hxx index 364d5738fd..ef1f58bec8 100644 --- a/src/OpenGl/OpenGl_FrameStats.hxx +++ b/src/OpenGl/OpenGl_FrameStats.hxx @@ -17,9 +17,7 @@ #include #include -class OpenGl_Workspace; -class OpenGl_Structure; -typedef NCollection_IndexedMap OpenGl_IndexedMapOfStructure; +class Graphic3d_CStructure; //! Class storing the frame statistics. class OpenGl_FrameStats : public Graphic3d_FrameStats @@ -48,7 +46,7 @@ protected: //! Updates counters for structures. Standard_EXPORT virtual void updateStructures (Standard_Integer theViewId, - const OpenGl_IndexedMapOfStructure& theStructures, + const NCollection_IndexedMap& theStructures, Standard_Boolean theToCountElems, Standard_Boolean theToCountTris, Standard_Boolean theToCountMem); diff --git a/src/OpenGl/OpenGl_GraphicDriver.cxx b/src/OpenGl/OpenGl_GraphicDriver.cxx index 35b0e61aca..03f02a636e 100644 --- a/src/OpenGl/OpenGl_GraphicDriver.cxx +++ b/src/OpenGl/OpenGl_GraphicDriver.cxx @@ -139,72 +139,6 @@ OpenGl_GraphicDriver::OpenGl_GraphicDriver (const Handle(Aspect_DisplayConnectio { throw Aspect_GraphicDeviceDefinitionError("OpenGl_GraphicDriver: default context can not be initialized!"); } - - // default layers are always presented in display layer sequence it can not be removed - { - 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 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 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 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 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); - } } // ======================================================================= @@ -570,50 +504,6 @@ void OpenGl_GraphicDriver::TextSize (const Handle(Graphic3d_CView)& theView, OpenGl_Text::StringSize(aCtx, aText, aTextAspect, aTextParam, theView->RenderingParams().Resolution, theWidth, theAscent, theDescent); } -//======================================================================= -//function : addZLayerIndex -//purpose : -//======================================================================= -void OpenGl_GraphicDriver::addZLayerIndex (const Graphic3d_ZLayerId theLayerId) -{ - // remove index - for (TColStd_SequenceOfInteger::Iterator aLayerIt (myLayerSeq); aLayerIt.More(); aLayerIt.Next()) - { - if (aLayerIt.Value() == theLayerId) - { - myLayerSeq.Remove (aLayerIt); - break; - } - } - - if (myMapOfZLayerSettings.Find (theLayerId).IsImmediate()) - { - myLayerSeq.Append (theLayerId); - return; - } - - for (TColStd_SequenceOfInteger::Iterator aLayerIt (myLayerSeq); aLayerIt.More(); aLayerIt.Next()) - { - const Graphic3d_ZLayerSettings& aSettings = myMapOfZLayerSettings.Find (aLayerIt.Value()); - if (aSettings.IsImmediate()) - { - aLayerIt.Previous(); - if (aLayerIt.More()) - { - myLayerSeq.InsertAfter (aLayerIt, theLayerId); - return; - } - - // first non-immediate layer - myLayerSeq.Prepend (theLayerId); - return; - } - } - - // no immediate layers - myLayerSeq.Append (theLayerId); -} - //======================================================================= //function : AddZLayer //purpose : @@ -686,15 +576,6 @@ void OpenGl_GraphicDriver::RemoveZLayer (const Graphic3d_ZLayerId theLayerId) myLayerIds.Remove (theLayerId); } -//======================================================================= -//function : ZLayers -//purpose : -//======================================================================= -void OpenGl_GraphicDriver::ZLayers (TColStd_SequenceOfInteger& theLayerSeq) const -{ - theLayerSeq.Assign (myLayerSeq); -} - //======================================================================= //function : SetZLayerSettings //purpose : @@ -702,22 +583,7 @@ void OpenGl_GraphicDriver::ZLayers (TColStd_SequenceOfInteger& theLayerSeq) cons void OpenGl_GraphicDriver::SetZLayerSettings (const Graphic3d_ZLayerId theLayerId, const Graphic3d_ZLayerSettings& theSettings) { - Graphic3d_ZLayerSettings* aSettings = myMapOfZLayerSettings.ChangeSeek (theLayerId); - if (aSettings != NULL) - { - const bool isChanged = (aSettings->IsImmediate() != theSettings.IsImmediate()); - *aSettings = theSettings; - if (isChanged) - { - addZLayerIndex (theLayerId); - } - } - else - { - // abnormal case - myMapOfZLayerSettings.Bind (theLayerId, theSettings); - addZLayerIndex (theLayerId); - } + base_type::SetZLayerSettings (theLayerId, theSettings); // Change Z layer settings in all managed views for (NCollection_Map::Iterator aViewIt (myMapOfView); aViewIt.More(); aViewIt.Next()) @@ -726,19 +592,6 @@ void OpenGl_GraphicDriver::SetZLayerSettings (const Graphic3d_ZLayerId theLayerI } } -//======================================================================= -//function : ZLayerSettings -//purpose : -//======================================================================= -const Graphic3d_ZLayerSettings& OpenGl_GraphicDriver::ZLayerSettings (const Graphic3d_ZLayerId theLayerId) const -{ - Standard_ASSERT_RAISE (myLayerIds.Contains (theLayerId), - "OpenGl_GraphicDriver::ZLayerSettings, " - "Layer with theLayerId does not exist"); - - return myMapOfZLayerSettings.Find (theLayerId); -} - // ======================================================================= // function : Structure // purpose : diff --git a/src/OpenGl/OpenGl_GraphicDriver.hxx b/src/OpenGl/OpenGl_GraphicDriver.hxx index af313e740c..4cdba035dd 100644 --- a/src/OpenGl/OpenGl_GraphicDriver.hxx +++ b/src/OpenGl/OpenGl_GraphicDriver.hxx @@ -20,39 +20,15 @@ #include #include -#include -#include -#include -#include #include -#include #include #include -#include -#include -#include -#include -#include -#include #include #include -#include -#include -#include -#include -#include -#include -#include -#include class Aspect_Window; class Quantity_Color; -class Graphic3d_Vertex; -class TCollection_ExtendedString; -class Image_PixMap; -class OpenGl_Element; class OpenGl_Structure; -class OpenGl_Text; class OpenGl_View; class OpenGl_Window; @@ -143,15 +119,9 @@ public: //! (reserved for default layers that can not be removed). Standard_EXPORT void RemoveZLayer (const Graphic3d_ZLayerId theLayerId) Standard_OVERRIDE; - //! Returns list of Z layers defined for the graphical driver. - Standard_EXPORT void ZLayers (TColStd_SequenceOfInteger& theLayerSeq) const Standard_OVERRIDE; - //! Sets the settings for a single Z layer. 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 const Graphic3d_ZLayerSettings& ZLayerSettings (const Graphic3d_ZLayerId theLayerId) const Standard_OVERRIDE; - public: //! @return the visualization options @@ -191,9 +161,6 @@ public: void* getRawGlConfig() const { return myEglConfig; } #endif - //! Insert index layer at proper position. - Standard_EXPORT void addZLayerIndex (const Graphic3d_ZLayerId theLayerId); - //! Set device lost flag for redrawn views. Standard_EXPORT void setDeviceLost(); @@ -218,10 +185,6 @@ protected: NCollection_Map myMapOfView; NCollection_DataMap myMapOfStructure; - TColStd_MapOfInteger myLayerIds; - TColStd_SequenceOfInteger myLayerSeq; - OpenGl_MapOfZLayerSettings myMapOfZLayerSettings; - mutable OpenGl_StateCounter myStateCounter; //!< State counter for OpenGl structures. mutable OpenGl_StateCounter myUIDGenerator; //!< Unique ID counter for primitive arrays. diff --git a/src/OpenGl/OpenGl_Layer.cxx b/src/OpenGl/OpenGl_Layer.cxx deleted file mode 100644 index 53d0b5cea6..0000000000 --- a/src/OpenGl/OpenGl_Layer.cxx +++ /dev/null @@ -1,773 +0,0 @@ -// Created on: 2014-03-31 -// Created by: Danila ULYANOV -// Copyright (c) 2014 OPEN CASCADE SAS -// -// This file is part of Open CASCADE Technology software library. -// -// This library is free software; you can redistribute it and/or modify it under -// the terms of the GNU Lesser General Public License version 2.1 as published -// by the Free Software Foundation, with special exception defined in the file -// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT -// distribution for complete text of the license and disclaimer of any warranty. -// -// Alternatively, this file may be used under the terms of Open CASCADE -// commercial license or contractual agreement. - -#include - -#include -#include -#include -#include -#include -#include - -IMPLEMENT_STANDARD_RTTIEXT(OpenGl_Layer, Standard_Transient) - -// ======================================================================= -// function : OpenGl_Layer -// purpose : -// ======================================================================= -OpenGl_Layer::OpenGl_Layer (const Standard_Integer theNbPriorities, - const Handle(Select3D_BVHBuilder3d)& theBuilder) -: myArray (0, theNbPriorities - 1), - myNbStructures (0), - myNbStructuresNotCulled (0), - myBVHPrimitivesTrsfPers (theBuilder), - myBVHIsLeftChildQueuedFirst (Standard_True), - myIsBVHPrimitivesNeedsReset (Standard_False) -{ - myIsBoundingBoxNeedsReset[0] = myIsBoundingBoxNeedsReset[1] = true; -} - -// ======================================================================= -// function : ~OpenGl_Layer -// purpose : -// ======================================================================= -OpenGl_Layer::~OpenGl_Layer() -{ - // -} - -// ======================================================================= -// function : Add -// purpose : -// ======================================================================= -void OpenGl_Layer::Add (const OpenGl_Structure* theStruct, - const Standard_Integer thePriority, - Standard_Boolean isForChangePriority) -{ - const Standard_Integer anIndex = Min (Max (thePriority, 0), myArray.Length() - 1); - if (theStruct == NULL) - { - return; - } - - myArray (anIndex).Add (theStruct); - if (theStruct->IsAlwaysRendered()) - { - theStruct->MarkAsNotCulled(); - if (!isForChangePriority) - { - myAlwaysRenderedMap.Add (theStruct); - } - } - else if (!isForChangePriority) - { - if (theStruct->TransformPersistence().IsNull()) - { - myBVHPrimitives.Add (theStruct); - } - else - { - myBVHPrimitivesTrsfPers.Add (theStruct); - } - } - ++myNbStructures; -} - -// ======================================================================= -// function : Remove -// purpose : -// ======================================================================= -bool OpenGl_Layer::Remove (const OpenGl_Structure* theStruct, - Standard_Integer& thePriority, - Standard_Boolean isForChangePriority) -{ - if (theStruct == NULL) - { - thePriority = -1; - return false; - } - - const Standard_Integer aNbPriorities = myArray.Length(); - for (Standard_Integer aPriorityIter = 0; aPriorityIter < aNbPriorities; ++aPriorityIter) - { - OpenGl_IndexedMapOfStructure& aStructures = myArray (aPriorityIter); - - const Standard_Integer anIndex = aStructures.FindIndex (theStruct); - if (anIndex != 0) - { - aStructures.Swap (anIndex, aStructures.Size()); - aStructures.RemoveLast(); - - if (!isForChangePriority) - { - Standard_Boolean isAlwaysRend = theStruct->IsAlwaysRendered(); - if (!isAlwaysRend) - { - if (!myBVHPrimitives.Remove (theStruct)) - { - if (!myBVHPrimitivesTrsfPers.Remove (theStruct)) - { - isAlwaysRend = Standard_True; - } - } - } - if (isAlwaysRend) - { - const Standard_Integer anIndex2 = myAlwaysRenderedMap.FindIndex (theStruct); - if (anIndex2 != 0) - { - myAlwaysRenderedMap.Swap (myAlwaysRenderedMap.Size(), anIndex2); - myAlwaysRenderedMap.RemoveLast(); - } - } - } - --myNbStructures; - thePriority = aPriorityIter; - return true; - } - } - - thePriority = -1; - return false; -} - -// ======================================================================= -// function : InvalidateBVHData -// purpose : -// ======================================================================= -void OpenGl_Layer::InvalidateBVHData() -{ - myIsBVHPrimitivesNeedsReset = Standard_True; -} - -//! Calculate a finite bounding box of infinite object as its middle point. -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_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_BndBox3d& theBndBox) -{ - return Abs (theBndBox.CornerMax().x()) >= ShortRealLast() - || Abs (theBndBox.CornerMax().y()) >= ShortRealLast() - || Abs (theBndBox.CornerMax().z()) >= ShortRealLast() - || Abs (theBndBox.CornerMin().x()) >= ShortRealLast() - || Abs (theBndBox.CornerMin().y()) >= ShortRealLast() - || Abs (theBndBox.CornerMin().z()) >= ShortRealLast(); -} - -// ======================================================================= -// function : BoundingBox -// purpose : -// ======================================================================= -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_Mat4d& aProjectionMat = theCamera->ProjectionMatrix(); - const Graphic3d_Mat4d& aWorldViewMat = theCamera->OrientationMatrix(); - if (myIsBoundingBoxNeedsReset[aBoxId]) - { - // Recompute layer bounding box - myBoundingBox[aBoxId].SetVoid(); - - for (OpenGl_ArrayOfIndexedMapOfStructure::Iterator aMapIter (myArray); aMapIter.More(); aMapIter.Next()) - { - const OpenGl_IndexedMapOfStructure& aStructures = aMapIter.Value(); - for (OpenGl_IndexedMapOfStructure::Iterator aStructIter (aStructures); aStructIter.More(); aStructIter.Next()) - { - const OpenGl_Structure* aStructure = aStructIter.Value(); - if (!aStructure->IsVisible (theViewId)) - { - continue; - } - - // "FitAll" operation ignores object with transform persistence parameter - // but adds transform persistence point in a bounding box of layer (only zoom pers. objects). - if (!aStructure->TransformPersistence().IsNull()) - { - if (!theToIncludeAuxiliary - && aStructure->TransformPersistence()->IsZoomOrRotate()) - { - const gp_Pnt anAnchor = aStructure->TransformPersistence()->AnchorPoint(); - myBoundingBox[aBoxId].Add (anAnchor); - continue; - } - // Panning and 2d persistence apply changes to projection or/and its translation components. - // It makes them incompatible with z-fitting algorithm. Ignored by now. - else if (!theToIncludeAuxiliary - || aStructure->TransformPersistence()->IsTrihedronOr2d()) - { - continue; - } - } - - Graphic3d_BndBox3d aBox = aStructure->BoundingBox(); - if (!aBox.IsValid()) - { - continue; - } - - if (aStructure->IsInfinite - && !theToIncludeAuxiliary) - { - // include center of infinite object - aBox = centerOfinfiniteBndBox (aBox); - } - - if (!aStructure->TransformPersistence().IsNull()) - { - aStructure->TransformPersistence()->Apply (theCamera, aProjectionMat, aWorldViewMat, theWindowWidth, theWindowHeight, aBox); - } - - // skip too big boxes to prevent float overflow at camera parameters calculation - if (aBox.IsValid() - && !isInfiniteBndBox (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())); - } - } - } - - myIsBoundingBoxNeedsReset[aBoxId] = false; - } - - Bnd_Box aResBox = myBoundingBox[aBoxId]; - if (!theToIncludeAuxiliary - || myAlwaysRenderedMap.IsEmpty()) - { - return aResBox; - } - - // add transformation-persistent objects which depend on camera position (and thus can not be cached) for operations like Z-fit - for (NCollection_IndexedMap::Iterator aStructIter (myAlwaysRenderedMap); aStructIter.More(); aStructIter.Next()) - { - const OpenGl_Structure* aStructure = aStructIter.Value(); - if (!aStructure->IsVisible (theViewId)) - { - continue; - } - else if (aStructure->TransformPersistence().IsNull() - || !aStructure->TransformPersistence()->IsTrihedronOr2d()) - { - continue; - } - - Graphic3d_BndBox3d aBox = aStructure->BoundingBox(); - if (!aBox.IsValid()) - { - continue; - } - - aStructure->TransformPersistence()->Apply (theCamera, aProjectionMat, aWorldViewMat, theWindowWidth, theWindowHeight, aBox); - if (aBox.IsValid() - && !isInfiniteBndBox (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())); - } - } - - return aResBox; -} - -// ======================================================================= -// function : considerZoomPersistenceObjects -// purpose : -// ======================================================================= -Standard_Real OpenGl_Layer::considerZoomPersistenceObjects (const Standard_Integer theViewId, - const Handle(Graphic3d_Camera)& theCamera, - Standard_Integer theWindowWidth, - Standard_Integer theWindowHeight) const -{ - if (NbOfTransformPersistenceObjects() == 0) - { - return 1.0; - } - - const Graphic3d_Mat4d& aProjectionMat = theCamera->ProjectionMatrix(); - const Graphic3d_Mat4d& aWorldViewMat = theCamera->OrientationMatrix(); - Standard_Real aMaxCoef = -std::numeric_limits::max(); - - for (OpenGl_ArrayOfIndexedMapOfStructure::Iterator aMapIter (myArray); aMapIter.More(); aMapIter.Next()) - { - const OpenGl_IndexedMapOfStructure& aStructures = aMapIter.Value(); - for (OpenGl_IndexedMapOfStructure::Iterator aStructIter (aStructures); aStructIter.More(); aStructIter.Next()) - { - const OpenGl_Structure* aStructure = aStructIter.Value(); - if (!aStructure->IsVisible (theViewId) - || aStructure->TransformPersistence().IsNull() - || !aStructure->TransformPersistence()->IsZoomOrRotate()) - { - continue; - } - - Graphic3d_BndBox3d aBox = aStructure->BoundingBox(); - if (!aBox.IsValid()) - { - continue; - } - - aStructure->TransformPersistence()->Apply (theCamera, aProjectionMat, aWorldViewMat, theWindowWidth, theWindowHeight, aBox); - - 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()), - gp_Pnt (aCornerMin.x(), aCornerMax.y(), aCornerMin.z()), - gp_Pnt (aCornerMin.x(), aCornerMax.y(), aCornerMax.z()), - gp_Pnt (aCornerMax.x(), aCornerMin.y(), aCornerMin.z()), - gp_Pnt (aCornerMax.x(), aCornerMin.y(), aCornerMax.z()), - gp_Pnt (aCornerMax.x(), aCornerMax.y(), aCornerMin.z()), - gp_Pnt (aCornerMax.x(), aCornerMax.y(), aCornerMax.z()) }; - gp_Pnt aConvertedPoints[aNbOfPoints]; - Standard_Real aConvertedMinX = std::numeric_limits::max(); - Standard_Real aConvertedMaxX = -std::numeric_limits::max(); - Standard_Real aConvertedMinY = std::numeric_limits::max(); - Standard_Real aConvertedMaxY = -std::numeric_limits::max(); - for (Standard_Integer anIdx = 0; anIdx < aNbOfPoints; ++anIdx) - { - aConvertedPoints[anIdx] = theCamera->Project (aPoints[anIdx]); - - aConvertedMinX = Min (aConvertedMinX, aConvertedPoints[anIdx].X()); - aConvertedMaxX = Max (aConvertedMaxX, aConvertedPoints[anIdx].X()); - - aConvertedMinY = Min (aConvertedMinY, aConvertedPoints[anIdx].Y()); - aConvertedMaxY = Max (aConvertedMaxY, aConvertedPoints[anIdx].Y()); - } - - const Standard_Boolean isBigObject = (Abs (aConvertedMaxX - aConvertedMinX) > 2.0) // width of zoom pers. object greater than width of window - || (Abs (aConvertedMaxY - aConvertedMinY) > 2.0); // height of zoom pers. object greater than height of window - const Standard_Boolean isAlreadyInScreen = (aConvertedMinX > -1.0 && aConvertedMinX < 1.0) - && (aConvertedMaxX > -1.0 && aConvertedMaxX < 1.0) - && (aConvertedMinY > -1.0 && aConvertedMinY < 1.0) - && (aConvertedMaxY > -1.0 && aConvertedMaxY < 1.0); - if (isBigObject || isAlreadyInScreen) - { - continue; - } - - const gp_Pnt aTPPoint = aStructure->TransformPersistence()->AnchorPoint(); - gp_Pnt aConvertedTPPoint = theCamera->Project (aTPPoint); - aConvertedTPPoint.SetZ (0.0); - - if (aConvertedTPPoint.Coord().Modulus() < Precision::Confusion()) - { - continue; - } - - Standard_Real aShiftX = 0.0; - if (aConvertedMinX < -1.0) - { - aShiftX = ((aConvertedMaxX < -1.0) ? (-(1.0 + aConvertedMaxX) + (aConvertedMaxX - aConvertedMinX)) : -(1.0 + aConvertedMinX)); - } - else if (aConvertedMaxX > 1.0) - { - aShiftX = ((aConvertedMinX > 1.0) ? ((aConvertedMinX - 1.0) + (aConvertedMaxX - aConvertedMinX)) : (aConvertedMaxX - 1.0)); - } - - Standard_Real aShiftY = 0.0; - if (aConvertedMinY < -1.0) - { - aShiftY = ((aConvertedMaxY < -1.0) ? (-(1.0 + aConvertedMaxY) + (aConvertedMaxY - aConvertedMinY)) : -(1.0 + aConvertedMinY)); - } - else if (aConvertedMaxY > 1.0) - { - aShiftY = ((aConvertedMinY > 1.0) ? ((aConvertedMinY - 1.0) + (aConvertedMaxY - aConvertedMinY)) : (aConvertedMaxY - 1.0)); - } - - const Standard_Real aDifX = Abs (aConvertedTPPoint.X()) - aShiftX; - const Standard_Real aDifY = Abs (aConvertedTPPoint.Y()) - aShiftY; - if (aDifX > Precision::Confusion()) - { - aMaxCoef = Max (aMaxCoef, Abs (aConvertedTPPoint.X()) / aDifX); - } - if (aDifY > Precision::Confusion()) - { - aMaxCoef = Max (aMaxCoef, Abs (aConvertedTPPoint.Y()) / aDifY); - } - } - } - - return (aMaxCoef > 0.0) ? aMaxCoef : 1.0; -} - -// ======================================================================= -// function : renderAll -// purpose : -// ======================================================================= -void OpenGl_Layer::renderAll (const Handle(OpenGl_Workspace)& theWorkspace) const -{ - const Standard_Integer aViewId = theWorkspace->View()->Identification(); - for (OpenGl_ArrayOfIndexedMapOfStructure::Iterator aMapIter (myArray); aMapIter.More(); aMapIter.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->IsCulled() - || !aStruct->IsVisible (aViewId)) - { - continue; - } - - aStruct->Render (theWorkspace); - } - } -} - -// ======================================================================= -// function : updateBVH -// purpose : -// ======================================================================= -void OpenGl_Layer::updateBVH() const -{ - if (!myIsBVHPrimitivesNeedsReset) - { - return; - } - - myBVHPrimitives.Clear(); - myBVHPrimitivesTrsfPers.Clear(); - myAlwaysRenderedMap.Clear(); - myIsBVHPrimitivesNeedsReset = Standard_False; - for (OpenGl_ArrayOfIndexedMapOfStructure::Iterator aMapIter (myArray); aMapIter.More(); aMapIter.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()) - { - aStruct->MarkAsNotCulled(); - myAlwaysRenderedMap.Add (aStruct); - } - else if (aStruct->TransformPersistence().IsNull()) - { - myBVHPrimitives.Add (aStruct); - } - else - { - myBVHPrimitivesTrsfPers.Add (aStruct); - } - } - } -} - -// ======================================================================= -// function : UpdateCulling -// purpose : -// ======================================================================= -void OpenGl_Layer::UpdateCulling (const Standard_Integer theViewId, - const OpenGl_BVHTreeSelector& theSelector, - const Graphic3d_RenderingParams::FrustumCulling theFrustumCullingState) -{ - updateBVH(); - - myNbStructuresNotCulled = myNbStructures; - if (theFrustumCullingState != Graphic3d_RenderingParams::FrustumCulling_NoUpdate) - { - Standard_Boolean toTraverse = - (theFrustumCullingState == Graphic3d_RenderingParams::FrustumCulling_On); - for (OpenGl_IndexedMapOfStructure::Iterator aStructIter (myBVHPrimitives.Structures()); aStructIter.More(); aStructIter.Next()) - { - const OpenGl_Structure* aStruct = aStructIter.Value(); - aStruct->SetCulled (toTraverse); - } - for (OpenGl_IndexedMapOfStructure::Iterator aStructIter (myBVHPrimitivesTrsfPers.Structures()); aStructIter.More(); aStructIter.Next()) - { - const OpenGl_Structure* aStruct = aStructIter.Value(); - aStruct->SetCulled (toTraverse); - } - } - - if (theFrustumCullingState != Graphic3d_RenderingParams::FrustumCulling_On) - { - return; - } - if (myBVHPrimitives .Size() == 0 - && myBVHPrimitivesTrsfPers.Size() == 0) - { - return; - } - - myNbStructuresNotCulled = myAlwaysRenderedMap.Extent(); - OpenGl_BVHTreeSelector::CullingContext aCullCtx; - theSelector.SetCullingDistance(aCullCtx, myLayerSettings.CullingDistance()); - theSelector.SetCullingSize (aCullCtx, myLayerSettings.CullingSize()); - for (Standard_Integer aBVHTreeIdx = 0; aBVHTreeIdx < 2; ++aBVHTreeIdx) - { - const Standard_Boolean isTrsfPers = aBVHTreeIdx == 1; - opencascade::handle > aBVHTree; - if (isTrsfPers) - { - if (myBVHPrimitivesTrsfPers.Size() == 0) - continue; - - 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(); - - aBVHTree = myBVHPrimitivesTrsfPers.BVH (theSelector.Camera(), aProjection, aWorldView, aViewportWidth, aViewportHeight, aWVPState); - } - else - { - if (myBVHPrimitives.Size() == 0) - continue; - - aBVHTree = myBVHPrimitives.BVH(); - } - - if (theSelector.IsCulled (aCullCtx, aBVHTree->MinPoint (0), aBVHTree->MaxPoint (0))) - { - continue; - } - - Standard_Integer aStack[BVH_Constants_MaxTreeDepth]; - Standard_Integer aHead = -1; - Standard_Integer aNode = 0; // a root node - for (;;) - { - if (!aBVHTree->IsOuter (aNode)) - { - const Standard_Integer aLeftChildIdx = aBVHTree->Child<0> (aNode); - const Standard_Integer aRightChildIdx = aBVHTree->Child<1> (aNode); - const Standard_Boolean isLeftChildIn = !theSelector.IsCulled (aCullCtx, aBVHTree->MinPoint (aLeftChildIdx), aBVHTree->MaxPoint (aLeftChildIdx)); - const Standard_Boolean isRightChildIn = !theSelector.IsCulled (aCullCtx, aBVHTree->MinPoint (aRightChildIdx), aBVHTree->MaxPoint (aRightChildIdx)); - if (isLeftChildIn - && isRightChildIn) - { - aNode = myBVHIsLeftChildQueuedFirst ? aLeftChildIdx : aRightChildIdx; - aStack[++aHead] = myBVHIsLeftChildQueuedFirst ? aRightChildIdx : aLeftChildIdx; - myBVHIsLeftChildQueuedFirst = !myBVHIsLeftChildQueuedFirst; - } - else if (isLeftChildIn - || isRightChildIn) - { - aNode = isLeftChildIn ? aLeftChildIdx : aRightChildIdx; - } - else - { - if (aHead < 0) - { - break; - } - - aNode = aStack[aHead--]; - } - } - else - { - Standard_Integer aIdx = aBVHTree->BegPrimitive (aNode); - const OpenGl_Structure* aStruct = isTrsfPers - ? myBVHPrimitivesTrsfPers.GetStructureById (aIdx) - : myBVHPrimitives.GetStructureById (aIdx); - if (aStruct->IsVisible (theViewId)) - { - aStruct->MarkAsNotCulled(); - ++myNbStructuresNotCulled; - } - if (aHead < 0) - { - break; - } - - aNode = aStack[aHead--]; - } - } - } -} - -// ======================================================================= -// function : Append -// purpose : -// ======================================================================= -Standard_Boolean OpenGl_Layer::Append (const OpenGl_Layer& theOther) -{ - // the source priority list shouldn't have more priorities - const Standard_Integer aNbPriorities = theOther.NbPriorities(); - if (aNbPriorities > NbPriorities()) - { - return Standard_False; - } - - // add all structures to destination priority list - for (Standard_Integer aPriorityIter = 0; aPriorityIter < aNbPriorities; ++aPriorityIter) - { - const OpenGl_IndexedMapOfStructure& aStructures = theOther.myArray (aPriorityIter); - for (OpenGl_IndexedMapOfStructure::Iterator aStructIter (aStructures); aStructIter.More(); aStructIter.Next()) - { - 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 (aStructIter.Value()); - aStructure->updateLayerTransformation(); - } - } - } -} - -//======================================================================= -//function : Render -//purpose : -//======================================================================= -void OpenGl_Layer::Render (const Handle(OpenGl_Workspace)& theWorkspace, - const OpenGl_GlobalLayerSettings& theDefaultSettings) const -{ - const Handle(OpenGl_Context)& aCtx = theWorkspace->GetGlContext(); - // myLayerSettings.ToClearDepth() is handled outside - - // handle depth test - if (myLayerSettings.ToEnableDepthTest()) - { - // assuming depth test is enabled by default - glDepthFunc (theDefaultSettings.DepthFunc); - } - else - { - glDepthFunc (GL_ALWAYS); - } - - // save environment texture - Handle(OpenGl_TextureSet) anEnvironmentTexture = theWorkspace->EnvironmentTexture(); - if (!myLayerSettings.UseEnvironmentTexture()) - { - theWorkspace->SetEnvironmentTexture (Handle(OpenGl_TextureSet)()); - } - - // handle depth offset - const Graphic3d_PolygonOffset anAppliedOffsetParams = theWorkspace->SetDefaultPolygonOffset (myLayerSettings.PolygonOffset()); - - // handle depth write - theWorkspace->UseDepthWrite() = myLayerSettings.ToEnableDepthWrite() && theDefaultSettings.DepthMask == GL_TRUE; - glDepthMask (theWorkspace->UseDepthWrite() ? GL_TRUE : GL_FALSE); - - const Standard_Boolean hasLocalCS = !myLayerSettings.OriginTransformation().IsNull(); - const Handle(OpenGl_ShaderManager)& aManager = aCtx->ShaderManager(); - Handle(Graphic3d_LightSet) aLightsBack = aManager->LightSourceState().LightSources(); - const bool hasOwnLights = aCtx->ColorMask() && !myLayerSettings.Lights().IsNull() && myLayerSettings.Lights() != aLightsBack; - if (hasOwnLights) - { - myLayerSettings.Lights()->UpdateRevision(); - aManager->UpdateLightSourceStateTo (myLayerSettings.Lights()); - } - - const Handle(Graphic3d_Camera)& aWorldCamera = theWorkspace->View()->Camera(); - 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 aWorldView = aWorldCamera->OrientationMatrix(); - Graphic3d_TransformUtils::Translate (aWorldView, myLayerSettings.Origin().X(), myLayerSettings.Origin().Y(), myLayerSettings.Origin().Z()); - - NCollection_Mat4 aWorldViewF; - aWorldViewF.ConvertFrom (aWorldView); - aCtx->WorldViewState.SetCurrent (aWorldViewF); - aCtx->ShaderManager()->UpdateClippingState(); - aCtx->ShaderManager()->UpdateLightSourceState(); - } - - // render priority list - renderAll (theWorkspace); - - if (hasOwnLights) - { - aManager->UpdateLightSourceStateTo (aLightsBack); - } - 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->SetDefaultPolygonOffset (anAppliedOffsetParams); - - // restore environment texture - if (!myLayerSettings.UseEnvironmentTexture()) - { - theWorkspace->SetEnvironmentTexture (anEnvironmentTexture); - } -} diff --git a/src/OpenGl/OpenGl_Layer.hxx b/src/OpenGl/OpenGl_Layer.hxx index 8fe3f46ec6..09a2e91538 100644 --- a/src/OpenGl/OpenGl_Layer.hxx +++ b/src/OpenGl/OpenGl_Layer.hxx @@ -16,185 +16,8 @@ #ifndef _OpenGl_Layer_Header #define _OpenGl_Layer_Header -#include -#include +#include -#include -#include -#include - -#include -#include -#include - - -struct OpenGl_GlobalLayerSettings -{ - GLint DepthFunc; - GLboolean DepthMask; -}; - -//! Defines index map of OpenGL structures. -typedef NCollection_IndexedMap OpenGl_IndexedMapOfStructure; - -//! Defines array of indexed maps of OpenGL structures. -typedef NCollection_Array1 OpenGl_ArrayOfIndexedMapOfStructure; - -//! Presentations list sorted within priorities. -class OpenGl_Layer : public Standard_Transient -{ - DEFINE_STANDARD_RTTIEXT(OpenGl_Layer, Standard_Transient) -public: - - //! Initializes associated priority list and layer properties - OpenGl_Layer (const Standard_Integer theNbPriorities, - const Handle(Select3D_BVHBuilder3d)& theBuilder); - - //! Destructor. - virtual ~OpenGl_Layer(); - - //! Returns BVH tree builder for frustom culling. - const Handle(Select3D_BVHBuilder3d)& FrustumCullingBVHBuilder() const { return myBVHPrimitivesTrsfPers.Builder(); } - - //! Assigns BVH tree builder for frustom culling. - void SetFrustumCullingBVHBuilder (const Handle(Select3D_BVHBuilder3d)& theBuilder) { myBVHPrimitivesTrsfPers.SetBuilder (theBuilder); } - - //! 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); - - void Add (const OpenGl_Structure* theStruct, - const Standard_Integer thePriority, - Standard_Boolean isForChangePriority = Standard_False); - - //! Remove structure and returns its priority, if the structure is not found, method returns negative value - bool Remove (const OpenGl_Structure* theStruct, - Standard_Integer& thePriority, - Standard_Boolean isForChangePriority = Standard_False); - - //! @return the number of structures - Standard_Integer NbStructures() const { return myNbStructures; } - - //! Number of NOT culled structures in the layer. - Standard_Integer NbStructuresNotCulled() const { return myNbStructuresNotCulled; } - - //! Returns the number of available priority levels - Standard_Integer NbPriorities() const { return myArray.Length(); } - - //! Append layer of acceptable type (with similar number of priorities or less). - //! Returns Standard_False if the list can not be accepted. - Standard_Boolean Append (const OpenGl_Layer& theOther); - - //! Returns array of OpenGL structures. - const OpenGl_ArrayOfIndexedMapOfStructure& ArrayOfStructures() const { return myArray; } - - //! Marks BVH tree for given priority list as dirty and - //! marks primitive set for rebuild. - void InvalidateBVHData(); - - //! Marks cached bounding box as obsolete. - void InvalidateBoundingBox() const - { - myIsBoundingBoxNeedsReset[0] = myIsBoundingBoxNeedsReset[1] = true; - } - - //! Returns layer bounding box. - //! @param theViewId view index to consider View Affinity in structure - //! @param theCamera camera definition - //! @param theWindowWidth viewport width (for applying transformation-persistence) - //! @param theWindowHeight viewport height (for applying transformation-persistence) - //! @param theToIncludeAuxiliary consider also auxiliary presentations (with infinite flag or with trihedron transformation persistence) - //! @return computed bounding box - 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, - const Handle(Graphic3d_Camera)& theCamera, - const Standard_Integer theWindowWidth, - const Standard_Integer theWindowHeight) const; - - //! Update culling state - should be called before rendering. - //! Traverses through BVH tree to determine which structures are in view volume. - void UpdateCulling (const Standard_Integer theViewId, - const OpenGl_BVHTreeSelector& theSelector, - const Graphic3d_RenderingParams::FrustumCulling theFrustumCullingState); - - //! Returns TRUE if layer is empty or has been discarded entirely by culling test. - bool IsCulled() const { return myNbStructuresNotCulled == 0; } - - // Render all structures. - void Render (const Handle(OpenGl_Workspace)& theWorkspace, - const OpenGl_GlobalLayerSettings& theDefaultSettings) const; - - //! Returns number of transform persistence objects. - Standard_Integer NbOfTransformPersistenceObjects() const - { - return myBVHPrimitivesTrsfPers.Size(); - } - -public: - - //! Returns set of OpenGl_Structures structures for building BVH tree. - const OpenGl_BVHClipPrimitiveSet& CullableStructuresBVH() const { return myBVHPrimitives; } - - //! Returns set of transform persistent OpenGl_Structures for building BVH tree. - const OpenGl_BVHClipPrimitiveTrsfPersSet& CullableTrsfPersStructuresBVH() const { return myBVHPrimitivesTrsfPers; } - - //! Returns indexed map of always rendered structures. - const NCollection_IndexedMap& NonCullableStructures() const { return myAlwaysRenderedMap; } - -protected: - - //! Updates BVH trees if their state has been invalidated. - Standard_EXPORT void updateBVH() const; - - //! Iterates through the hierarchical list of existing structures and renders them all. - Standard_EXPORT void renderAll (const Handle(OpenGl_Workspace)& theWorkspace) const; - -private: - - //! Array of OpenGl_Structures by priority rendered in layer. - OpenGl_ArrayOfIndexedMapOfStructure myArray; - - //! Overall number of structures rendered in the layer. - Standard_Integer myNbStructures; - - //! Number of NOT culled structures in the layer. - Standard_Integer myNbStructuresNotCulled; - - //! Layer setting flags. - Graphic3d_ZLayerSettings myLayerSettings; - - //! Set of OpenGl_Structures structures for building BVH tree. - mutable OpenGl_BVHClipPrimitiveSet myBVHPrimitives; - - //! Set of transform persistent OpenGl_Structures for building BVH tree. - mutable OpenGl_BVHClipPrimitiveTrsfPersSet myBVHPrimitivesTrsfPers; - - //! Indexed map of always rendered structures. - mutable NCollection_IndexedMap myAlwaysRenderedMap; - - //! Is needed for implementation of stochastic order of BVH traverse. - Standard_Boolean myBVHIsLeftChildQueuedFirst; - - //! Defines if the primitive set for BVH is outdated. - mutable Standard_Boolean myIsBVHPrimitivesNeedsReset; - - //! Defines if the cached bounding box is outdated. - mutable bool myIsBoundingBoxNeedsReset[2]; - - //! Cached layer bounding box. - mutable Bnd_Box myBoundingBox[2]; - -}; +typedef Graphic3d_Layer OpenGl_Layer; #endif //_OpenGl_Layer_Header diff --git a/src/OpenGl/OpenGl_LayerList.cxx b/src/OpenGl/OpenGl_LayerList.cxx index 2948219289..4aee97b5e0 100644 --- a/src/OpenGl/OpenGl_LayerList.cxx +++ b/src/OpenGl/OpenGl_LayerList.cxx @@ -137,6 +137,12 @@ namespace }; } +struct OpenGl_GlobalLayerSettings +{ + GLint DepthFunc; + GLboolean DepthMask; +}; + //======================================================================= //function : OpenGl_LayerList //purpose : Constructor @@ -519,7 +525,7 @@ void OpenGl_LayerList::UpdateCulling (const Handle(OpenGl_Workspace)& theWorkspa aTimer.Start(); const Standard_Integer aViewId = theWorkspace->View()->Identification(); - const OpenGl_BVHTreeSelector& aSelector = theWorkspace->View()->BVHTreeSelector(); + const Graphic3d_CullingTool& aSelector = theWorkspace->View()->BVHTreeSelector(); for (OpenGl_IndexedLayerIterator anIts (myLayers); anIts.More(); anIts.Next()) { OpenGl_Layer& aLayer = *anIts.ChangeValue(); @@ -535,6 +541,143 @@ void OpenGl_LayerList::UpdateCulling (const Handle(OpenGl_Workspace)& theWorkspa aStats->ActiveDataFrame()[Graphic3d_FrameStatsTimer_CpuCulling] = aTimer.UserTimeCPU(); } +//======================================================================= +//function : renderLayer +//purpose : +//======================================================================= +void OpenGl_LayerList::renderLayer (const Handle(OpenGl_Workspace)& theWorkspace, + const OpenGl_GlobalLayerSettings& theDefaultSettings, + const Graphic3d_Layer& theLayer) const +{ + const Handle(OpenGl_Context)& aCtx = theWorkspace->GetGlContext(); + + const Graphic3d_ZLayerSettings& aLayerSettings = theLayer.LayerSettings(); + // aLayerSettings.ToClearDepth() is handled outside + + // handle depth test + if (aLayerSettings.ToEnableDepthTest()) + { + // assuming depth test is enabled by default + glDepthFunc (theDefaultSettings.DepthFunc); + } + else + { + glDepthFunc (GL_ALWAYS); + } + + // save environment texture + Handle(OpenGl_TextureSet) anEnvironmentTexture = theWorkspace->EnvironmentTexture(); + if (!aLayerSettings.UseEnvironmentTexture()) + { + theWorkspace->SetEnvironmentTexture (Handle(OpenGl_TextureSet)()); + } + + // handle depth offset + const Graphic3d_PolygonOffset anAppliedOffsetParams = theWorkspace->SetDefaultPolygonOffset (aLayerSettings.PolygonOffset()); + + // handle depth write + theWorkspace->UseDepthWrite() = aLayerSettings.ToEnableDepthWrite() && theDefaultSettings.DepthMask == GL_TRUE; + glDepthMask (theWorkspace->UseDepthWrite() ? GL_TRUE : GL_FALSE); + + const Standard_Boolean hasLocalCS = !aLayerSettings.OriginTransformation().IsNull(); + const Handle(OpenGl_ShaderManager)& aManager = aCtx->ShaderManager(); + Handle(Graphic3d_LightSet) aLightsBack = aManager->LightSourceState().LightSources(); + const bool hasOwnLights = aCtx->ColorMask() && !aLayerSettings.Lights().IsNull() && aLayerSettings.Lights() != aLightsBack; + if (hasOwnLights) + { + aLayerSettings.Lights()->UpdateRevision(); + aManager->UpdateLightSourceStateTo (aLayerSettings.Lights()); + } + + const Handle(Graphic3d_Camera)& aWorldCamera = theWorkspace->View()->Camera(); + 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 (aLayerSettings.Origin()); + + NCollection_Mat4 aWorldView = aWorldCamera->OrientationMatrix(); + Graphic3d_TransformUtils::Translate (aWorldView, aLayerSettings.Origin().X(), aLayerSettings.Origin().Y(), aLayerSettings.Origin().Z()); + + NCollection_Mat4 aWorldViewF; + aWorldViewF.ConvertFrom (aWorldView); + aCtx->WorldViewState.SetCurrent (aWorldViewF); + aCtx->ShaderManager()->UpdateClippingState(); + aCtx->ShaderManager()->UpdateLightSourceState(); + } + + // render priority list + const Standard_Integer aViewId = theWorkspace->View()->Identification(); + for (Graphic3d_ArrayOfIndexedMapOfStructure::Iterator aMapIter (theLayer.ArrayOfStructures()); aMapIter.More(); aMapIter.Next()) + { + const Graphic3d_IndexedMapOfStructure& aStructures = aMapIter.Value(); + for (OpenGl_Structure::StructIterator aStructIter (aStructures); aStructIter.More(); aStructIter.Next()) + { + const OpenGl_Structure* aStruct = aStructIter.Value(); + if (aStruct->IsCulled() + || !aStruct->IsVisible (aViewId)) + { + continue; + } + + aStruct->Render (theWorkspace); + } + } + + if (hasOwnLights) + { + aManager->UpdateLightSourceStateTo (aLightsBack); + } + 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->SetDefaultPolygonOffset (anAppliedOffsetParams); + + // restore environment texture + if (!aLayerSettings.UseEnvironmentTexture()) + { + theWorkspace->SetEnvironmentTexture (anEnvironmentTexture); + } +} + //======================================================================= //function : Render //purpose : @@ -652,7 +795,7 @@ void OpenGl_LayerList::Render (const Handle(OpenGl_Workspace)& theWorkspace, // the transparency post-processing stack. theWorkspace->ResetSkippedCounter(); - aLayer.Render (theWorkspace, aDefaultSettings); + renderLayer (theWorkspace, aDefaultSettings, aLayer); if (aPassIter != 0 && theWorkspace->NbSkippedTransparentElements() > 0) @@ -751,7 +894,7 @@ void OpenGl_LayerList::renderTransparent (const Handle(OpenGl_Workspace)& theW for (; theLayerIter != myTransparentToProcess.Back(); ++theLayerIter) { - (*theLayerIter)->Render (theWorkspace, aGlobalSettings); + renderLayer (theWorkspace, aGlobalSettings, *(*theLayerIter)); } // Revert state of rendering. diff --git a/src/OpenGl/OpenGl_LayerList.hxx b/src/OpenGl/OpenGl_LayerList.hxx index 3701607734..813bc47807 100644 --- a/src/OpenGl/OpenGl_LayerList.hxx +++ b/src/OpenGl/OpenGl_LayerList.hxx @@ -19,12 +19,15 @@ #include #include +#include #include #include #include #include class OpenGl_Structure; +class OpenGl_Workspace; +struct OpenGl_GlobalLayerSettings; typedef NCollection_Sequence OpenGl_SequenceOfLayers; typedef NCollection_DataMap OpenGl_LayerSeqIds; @@ -124,14 +127,14 @@ protected: class OpenGl_LayerStack { public: - typedef NCollection_Array1::iterator iterator; + typedef NCollection_Array1::iterator iterator; //! Reallocate internal buffer of the stack. void Allocate (Standard_Integer theSize) { if (theSize > 0) { - myStackSpace = new NCollection_Array1 (1, theSize); + myStackSpace = new NCollection_Array1 (1, theSize); myStackSpace->Init (NULL); myBackPtr = myStackSpace->begin(); } @@ -185,6 +188,11 @@ protected: OpenGl_FrameBuffer* theReadDrawFbo, OpenGl_FrameBuffer* theOitAccumFbo) const; + // Render structures within specified layer. + void renderLayer (const Handle(OpenGl_Workspace)& theWorkspace, + const OpenGl_GlobalLayerSettings& theDefaultSettings, + const Graphic3d_Layer& theLayer) const; + protected: // number of structures temporary put to default layer diff --git a/src/OpenGl/OpenGl_MapOfZLayerSettings.hxx b/src/OpenGl/OpenGl_MapOfZLayerSettings.hxx deleted file mode 100644 index 09977a00e7..0000000000 --- a/src/OpenGl/OpenGl_MapOfZLayerSettings.hxx +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright (c) 2014 OPEN CASCADE SAS -// -// This file is part of Open CASCADE Technology software library. -// -// This library is free software; you can redistribute it and/or modify it under -// the terms of the GNU Lesser General Public License version 2.1 as published -// by the Free Software Foundation, with special exception defined in the file -// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT -// distribution for complete text of the license and disclaimer of any warranty. -// -// Alternatively, this file may be used under the terms of Open CASCADE -// commercial license or contractual agreement. - -#ifndef _OpenGl_MapOfZLayerSettings_HeaderFile -#define _OpenGl_MapOfZLayerSettings_HeaderFile - -#include -#include -#include -#include - -typedef NCollection_DataMap OpenGl_MapOfZLayerSettings; - -#endif // _OpenGl_MapOfZLayerSettings_HeaderFile diff --git a/src/OpenGl/OpenGl_Structure.cxx b/src/OpenGl/OpenGl_Structure.cxx index d31a32e1ef..e3188fef8f 100644 --- a/src/OpenGl/OpenGl_Structure.cxx +++ b/src/OpenGl/OpenGl_Structure.cxx @@ -107,7 +107,6 @@ OpenGl_Structure::OpenGl_Structure (const Handle(Graphic3d_StructureManager)& th myInstancedStructure (NULL), myIsRaytracable (Standard_False), myModificationState (0), - myIsCulled (Standard_True), myIsMirrored (Standard_False) { updateLayerTransformation(); diff --git a/src/OpenGl/OpenGl_Structure.hxx b/src/OpenGl/OpenGl_Structure.hxx index da00070e47..58c3a0e29f 100644 --- a/src/OpenGl/OpenGl_Structure.hxx +++ b/src/OpenGl/OpenGl_Structure.hxx @@ -29,33 +29,23 @@ #include -class OpenGl_Structure; class OpenGl_GraphicDriver; +DEFINE_STANDARD_HANDLE(OpenGl_Structure, Graphic3d_CStructure) typedef NCollection_List OpenGl_ListOfStructure; //! Implementation of low-level graphic structure. class OpenGl_Structure : public Graphic3d_CStructure { friend class OpenGl_Group; - + DEFINE_STANDARD_RTTIEXT(OpenGl_Structure, Graphic3d_CStructure) public: - //! Auxiliary wrapper to iterate OpenGl_Group sequence. - class GroupIterator - { - - public: - GroupIterator (const Graphic3d_SequenceOfGroup& theGroups) : myIter (theGroups) {} - Standard_Boolean More() const { return myIter.More(); } - void Next() { myIter.Next(); } - const OpenGl_Group* Value() const { return (const OpenGl_Group* )(myIter.Value().operator->()); } - OpenGl_Group* ChangeValue() { return (OpenGl_Group* )(myIter.ChangeValue().operator->()); } + //! Auxiliary wrapper to iterate OpenGl_Structure sequence. + typedef SubclassStructIterator StructIterator; - private: - Graphic3d_SequenceOfGroup::Iterator myIter; - - }; + //! Auxiliary wrapper to iterate OpenGl_Group sequence. + typedef SubclassGroupIterator GroupIterator; public: @@ -115,28 +105,6 @@ public: //! Releases structure resources. virtual void Release (const Handle(OpenGl_Context)& theGlCtx); - //! Marks structure as culled/not culled - note that IsAlwaysRendered() is ignored here! - void SetCulled (Standard_Boolean theIsCulled) const { myIsCulled = theIsCulled; } - - //! Marks structure as overlapping the current view volume one. - //! The method is called during traverse of BVH tree. - void MarkAsNotCulled() const { myIsCulled = Standard_False; } - - //! Returns Standard_False if the structure hits the current view volume, otherwise - //! returns Standard_True. The default value for all structures before each traverse - //! of BVH tree is Standard_True. - Standard_Boolean IsCulled() const { return myIsCulled; } - - //! Checks if the structure should be included into BVH tree or not. - Standard_Boolean IsAlwaysRendered() const - { - return IsInfinite - || IsForHighlight - || IsMutable - || Is2dText - || (!myTrsfPers.IsNull() && myTrsfPers->IsTrihedronOr2d()); - } - //! This method releases GL resources without actual elements destruction. //! As result structure could be correctly destroyed layer without GL context //! (after last window was closed for example). @@ -158,7 +126,7 @@ public: Standard_Boolean IsRaytracable() const; //! Update render transformation matrix. - Standard_EXPORT void updateLayerTransformation(); + Standard_EXPORT virtual void updateLayerTransformation() Standard_OVERRIDE; protected: @@ -184,16 +152,8 @@ protected: mutable Standard_Boolean myIsRaytracable; mutable Standard_Size myModificationState; - mutable Standard_Boolean myIsCulled; //!< A status specifying is structure needs to be rendered after BVH tree traverse. - Standard_Boolean myIsMirrored; //!< Used to tell OpenGl to interpret polygons in clockwise order. -public: - - DEFINE_STANDARD_RTTIEXT(OpenGl_Structure,Graphic3d_CStructure) // Type definition - }; -DEFINE_STANDARD_HANDLE(OpenGl_Structure, Graphic3d_CStructure) - #endif // OpenGl_Structure_Header diff --git a/src/OpenGl/OpenGl_View.cxx b/src/OpenGl/OpenGl_View.cxx index 14495041f5..a3a388b8f7 100644 --- a/src/OpenGl/OpenGl_View.cxx +++ b/src/OpenGl/OpenGl_View.cxx @@ -51,8 +51,6 @@ OpenGl_View::OpenGl_View (const Handle(Graphic3d_StructureManager)& theMgr, myCaps (theCaps), myWasRedrawnGL (Standard_False), myBackfacing (Graphic3d_TOBM_AUTOMATIC), - myBgColor (Quantity_NOC_BLACK), - myCamera (new Graphic3d_Camera()), myToShowGradTrihedron (false), myZLayers (Structure_MAX_PRIORITY - Structure_MIN_PRIORITY + 1), myStateCounter (theCounter), @@ -192,15 +190,6 @@ void OpenGl_View::Remove() Graphic3d_CView::Remove(); } -// ======================================================================= -// function : SetTextureEnv -// purpose : -// ======================================================================= -void OpenGl_View::SetCamera(const Handle(Graphic3d_Camera)& theCamera) -{ - myCamera = theCamera; -} - // ======================================================================= // function : SetLocalOrigin // purpose : @@ -420,24 +409,6 @@ Standard_Boolean OpenGl_View::BufferDump (Image_PixMap& theImage, const Graphic3 #endif } -// ======================================================================= -// function : Background -// purpose : -// ======================================================================= -Aspect_Background OpenGl_View::Background() const -{ - return Aspect_Background (myBgColor.GetRGB()); -} - -// ======================================================================= -// function : SetBackground -// purpose : -// ======================================================================= -void OpenGl_View::SetBackground (const Aspect_Background& theBackground) -{ - myBgColor.SetRGB (theBackground.Color()); -} - // ======================================================================= // function : GradientBackground // purpose : diff --git a/src/OpenGl/OpenGl_View.hxx b/src/OpenGl/OpenGl_View.hxx index 15a3b9e82c..44ead7cef8 100644 --- a/src/OpenGl/OpenGl_View.hxx +++ b/src/OpenGl/OpenGl_View.hxx @@ -28,6 +28,7 @@ #include #include +#include #include #include #include @@ -37,7 +38,6 @@ #include #include -#include #include #include #include @@ -127,21 +127,6 @@ public: //! Return true if view content cache has been invalidated. virtual Standard_Boolean IsInvalidated() Standard_OVERRIDE { return !myBackBufferRestored; } - //! Returns data of a graduated trihedron - const Graphic3d_GraduatedTrihedron& GetGraduatedTrihedron() Standard_OVERRIDE - { return myGTrihedronData; } - - //! Displays Graduated Trihedron. - Standard_EXPORT virtual void GraduatedTrihedronDisplay (const Graphic3d_GraduatedTrihedron& theTrihedronData) Standard_OVERRIDE; - - //! Erases Graduated Trihedron. - Standard_EXPORT virtual void GraduatedTrihedronErase() Standard_OVERRIDE; - - //! Sets minimum and maximum points of scene bounding box for Graduated Trihedron stored in graphic view object. - //! @param theMin [in] the minimum point of scene. - //! @param theMax [in] the maximum point of scene. - Standard_EXPORT virtual void GraduatedTrihedronMinMaxValues (const Graphic3d_Vec3 theMin, const Graphic3d_Vec3 theMax) Standard_OVERRIDE; - //! Dump active rendering buffer into specified memory buffer. //! In Ray-Tracing allow to get a raw HDR buffer using Graphic3d_BT_RGB_RayTraceHdrLeft buffer type, //! only Left view will be dumped ignoring stereoscopic parameter. @@ -211,12 +196,6 @@ public: public: - //! Returns background fill color. - Standard_EXPORT virtual Aspect_Background Background() const Standard_OVERRIDE; - - //! Sets background fill color. - Standard_EXPORT virtual void SetBackground (const Aspect_Background& theBackground) Standard_OVERRIDE; - //! Returns gradient background fill colors. Standard_EXPORT virtual Aspect_GradientBackground GradientBackground() const Standard_OVERRIDE; @@ -247,18 +226,12 @@ public: //! Sets backfacing model for the view. virtual void SetBackfacingModel (const Graphic3d_TypeOfBackfacingModel theModel) Standard_OVERRIDE { myBackfacing = theModel; } - //! 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. - Standard_EXPORT virtual void SetCamera (const Handle(Graphic3d_Camera)& theCamera) Standard_OVERRIDE; - //! Returns list of lights of the view. virtual const Handle(Graphic3d_LightSet)& Lights() const Standard_OVERRIDE { return myLights; } @@ -319,7 +292,7 @@ public: //! Returns selector for BVH tree, providing a possibility to store information //! about current view volume and to detect which objects are overlapping it. - const OpenGl_BVHTreeSelector& BVHTreeSelector() const { return myBVHSelector; } + const Graphic3d_CullingTool& BVHTreeSelector() const { return myBVHSelector; } //! Returns true if there are immediate structures to display bool HasImmediateStructures() const @@ -327,6 +300,19 @@ public: return myZLayers.NbImmediateStructures() != 0; } +public: //! @name obsolete Graduated Trihedron functionality + + //! Displays Graduated Trihedron. + Standard_EXPORT virtual void GraduatedTrihedronDisplay (const Graphic3d_GraduatedTrihedron& theTrihedronData) Standard_OVERRIDE; + + //! Erases Graduated Trihedron. + Standard_EXPORT virtual void GraduatedTrihedronErase() Standard_OVERRIDE; + + //! Sets minimum and maximum points of scene bounding box for Graduated Trihedron stored in graphic view object. + //! @param theMin [in] the minimum point of scene. + //! @param theMax [in] the maximum point of scene. + Standard_EXPORT virtual void GraduatedTrihedronMinMaxValues (const Graphic3d_Vec3 theMin, const Graphic3d_Vec3 theMax) Standard_OVERRIDE; + protected: //! @name Internal methods for managing GL resources //! Initializes OpenGl resource for environment texture. @@ -458,9 +444,7 @@ protected: Standard_Boolean myWasRedrawnGL; Graphic3d_TypeOfBackfacingModel myBackfacing; - Quantity_ColorRGBA myBgColor; Handle(Graphic3d_SequenceOfHClipPlane) myClipPlanes; - Handle(Graphic3d_Camera) myCamera; gp_XYZ myLocalOrigin; Handle(OpenGl_FrameBuffer) myFBO; Standard_Boolean myToShowGradTrihedron; @@ -484,7 +468,7 @@ protected: StateInfo myLastLightSourceState; //! Is needed for selection of overlapping objects and storage of the current view volume - OpenGl_BVHTreeSelector myBVHSelector; + Graphic3d_CullingTool myBVHSelector; OpenGl_GraduatedTrihedron myGraduatedTrihedron; OpenGl_FrameStatsPrs myFrameStatsPrs; diff --git a/src/OpenGl/OpenGl_View_Raytrace.cxx b/src/OpenGl/OpenGl_View_Raytrace.cxx index d0ee3b22b1..35013cd66d 100644 --- a/src/OpenGl/OpenGl_View_Raytrace.cxx +++ b/src/OpenGl/OpenGl_View_Raytrace.cxx @@ -111,11 +111,11 @@ Standard_Boolean OpenGl_View::updateRaytraceGeometry (const RaytraceUpdateMode if (aLayer.NbStructures() != 0) { - const OpenGl_ArrayOfIndexedMapOfStructure& aStructArray = aLayer.ArrayOfStructures(); + const Graphic3d_ArrayOfIndexedMapOfStructure& aStructArray = aLayer.ArrayOfStructures(); for (Standard_Integer anIndex = 0; anIndex < aStructArray.Length(); ++anIndex) { - for (OpenGl_IndexedMapOfStructure::Iterator aStructIt (aStructArray (anIndex)); aStructIt.More(); aStructIt.Next()) + for (OpenGl_Structure::StructIterator aStructIt (aStructArray.Value (anIndex)); aStructIt.More(); aStructIt.Next()) { const OpenGl_Structure* aStructure = aStructIt.Value();