From: vpa Date: Fri, 1 Apr 2016 16:26:57 +0000 (+0300) Subject: Added proper cleaning of LOD groups: X-Git-Url: http://git.dev.opencascade.org/gitweb/?a=commitdiff_plain;h=5efc1678e34d3403acc6113fd4a0d7caa9b2c3f4;p=occt-copy.git Added proper cleaning of LOD groups: - Graphic3d_Structure's Remove and GraphicClear now take into account LOD structures; - LOD graphic resources are cleaned up properly in OpenGl_Structure; Correction of warnings. TODO: There are a lot of places in OpenGl_Structure where the structure tries to iterate through its own graphic groups. In case of objects represented as LODs, such loops are useless and likely will affect the performance. --- diff --git a/src/Graphic3d/Graphic3d_LOD.cxx b/src/Graphic3d/Graphic3d_LOD.cxx index badb32bcdd..a78f9975b9 100644 --- a/src/Graphic3d/Graphic3d_LOD.cxx +++ b/src/Graphic3d/Graphic3d_LOD.cxx @@ -23,6 +23,7 @@ IMPLEMENT_STANDARD_RTTIEXT (Graphic3d_LOD, Standard_Transient) //======================================================================= Graphic3d_LOD::~Graphic3d_LOD() { + Clear (Standard_True); myGroups.Clear(); } @@ -37,3 +38,26 @@ void Graphic3d_LOD::SetRange (const Standard_Real theFrom, const Standard_Real t myRange = Graphic3d_RangeOfLOD (theFrom, theTo); } + +//======================================================================= +// function : Clear +// purpose : +//======================================================================= +void Graphic3d_LOD::Clear (const Standard_Boolean theWithDestruction) +{ + for (Graphic3d_SequenceOfGroup::Iterator aGroupIter (myGroups); aGroupIter.More(); aGroupIter.Next()) + { + aGroupIter.ChangeValue()->Clear(); + } + + if (!theWithDestruction) + { + return; + } + + while (!myGroups.IsEmpty()) + { + Handle(Graphic3d_Group) aGroup = myGroups.First(); + aGroup->Remove(); + } +} diff --git a/src/Graphic3d/Graphic3d_LOD.hxx b/src/Graphic3d/Graphic3d_LOD.hxx index d86bf8d5b0..1e01889868 100644 --- a/src/Graphic3d/Graphic3d_LOD.hxx +++ b/src/Graphic3d/Graphic3d_LOD.hxx @@ -81,6 +81,8 @@ public: return myGroups; } + Standard_EXPORT virtual void Clear (const Standard_Boolean theWithDestruction); + DEFINE_STANDARD_RTTIEXT (Graphic3d_LOD, Standard_Transient) protected: diff --git a/src/Graphic3d/Graphic3d_LODManager.cxx b/src/Graphic3d/Graphic3d_LODManager.cxx index f7d8d5e0aa..979bb8cd3b 100644 --- a/src/Graphic3d/Graphic3d_LODManager.cxx +++ b/src/Graphic3d/Graphic3d_LODManager.cxx @@ -115,3 +115,27 @@ Standard_Boolean Graphic3d_LODManager::IsEmpty() const return Standard_True; } + +//======================================================================= +// function : Clear +// purpose : +//======================================================================= +void Graphic3d_LODManager::Clear (const Standard_Boolean theWithDestruction) +{ + for (Standard_Integer aLodIdx = 0; aLodIdx < myLODs.Size(); ++aLodIdx) + { + myLODs.Value (aLodIdx)->Clear (theWithDestruction); + } +} + +//======================================================================= +// function : GetLodById +// purpose : +//======================================================================= +const Handle(Graphic3d_LOD)& Graphic3d_LODManager::GetLodById (const Standard_Integer theLodIdx) +{ + Standard_ASSERT_RAISE (theLodIdx >= 0 || theLodIdx < myLODs.Size(), + "Index of LOD is out of range"); + + return myLODs.Value (theLodIdx); +} diff --git a/src/Graphic3d/Graphic3d_LODManager.hxx b/src/Graphic3d/Graphic3d_LODManager.hxx index ab5299ce1d..fa9a8ce567 100644 --- a/src/Graphic3d/Graphic3d_LODManager.hxx +++ b/src/Graphic3d/Graphic3d_LODManager.hxx @@ -58,6 +58,10 @@ public: //! Returns false if at least one of LODs has non-empty sequence of Graphic3d_Groups Standard_EXPORT Standard_Boolean IsEmpty() const; + Standard_EXPORT void Clear (const Standard_Boolean theWithDestruction); + + Standard_EXPORT const Handle(Graphic3d_LOD)& GetLodById (const Standard_Integer theLodIdx); + DEFINE_STANDARD_RTTIEXT (Graphic3d_LODManager, Standard_Transient) protected: diff --git a/src/Graphic3d/Graphic3d_Structure.cxx b/src/Graphic3d/Graphic3d_Structure.cxx index cba7c821fb..1198ec1c66 100644 --- a/src/Graphic3d/Graphic3d_Structure.cxx +++ b/src/Graphic3d/Graphic3d_Structure.cxx @@ -187,6 +187,12 @@ void Graphic3d_Structure::Remove() ((Graphic3d_Structure *)myAncestors.FindKey (aStructIdx))->Remove (APtr, Graphic3d_TOC_DESCENDANT); } + // Clear LODs graphic groups if there are any + if (!myCStructure->GetLodManager().IsNull()) + { + myCStructure->GetLodManager()->Clear (Standard_False); + } + // Destruction of me in the graphic library const Standard_Integer aStructId = myCStructure->Id; myCStructure->GraphicDriver()->RemoveStructure (myCStructure); @@ -643,6 +649,13 @@ void Graphic3d_Structure::GraphicClear (const Standard_Boolean theWithDestructio return; } + if (!myCStructure->GetLodManager().IsNull()) + { + myCStructure->GetLodManager()->Clear (theWithDestruction); + if (theWithDestruction) + myCStructure->Clear(); + } + // clean and empty each group for (Graphic3d_SequenceOfGroup::Iterator aGroupIter (myCStructure->Groups()); aGroupIter.More(); aGroupIter.Next()) { @@ -1777,8 +1790,7 @@ Handle(Graphic3d_StructureManager) Graphic3d_Structure::StructureManager() const Graphic3d_BndBox4f Graphic3d_Structure::minMaxCoord() const { Graphic3d_BndBox4f aBnd; - const Handle(Graphic3d_LODManager)& aLodMgr = myCStructure->GetLodManager(); - if (aLodMgr.IsNull()) + if (myCStructure->GetLodManager().IsNull()) { for (Graphic3d_SequenceOfGroup::Iterator aGroupIter (myCStructure->Groups()); aGroupIter.More(); aGroupIter.Next()) { @@ -1787,7 +1799,7 @@ Graphic3d_BndBox4f Graphic3d_Structure::minMaxCoord() const } else { - aLodMgr->GetCombinedBndBox (aBnd); + myCStructure->GetLodManager()->GetCombinedBndBox (aBnd); } return aBnd; } diff --git a/src/MeshVS/MeshVS_Mesh.cxx b/src/MeshVS/MeshVS_Mesh.cxx index 4727e48f2d..e1ebb90c32 100644 --- a/src/MeshVS/MeshVS_Mesh.cxx +++ b/src/MeshVS/MeshVS_Mesh.cxx @@ -155,15 +155,17 @@ void MeshVS_Mesh::ComputeLods (const Handle(PrsMgr_PresentationManager3d)& thePr const Handle(Prs3d_Presentation)& thePrs, const Standard_Integer theMode) { + TColStd_PackedMapOfInteger aDummy; for (Standard_Integer aLodBldrIdx = 1; aLodBldrIdx <= myBuilders.Length(); ++aLodBldrIdx) { const Handle(MeshVS_LODBuilder) aLodBldr = Handle(MeshVS_LODBuilder)::DownCast (myBuilders.Value (aLodBldrIdx)); if (aLodBldr.IsNull()) continue; + aLodBldr->SetPresentationManager (thePrsMgr); const TColStd_PackedMapOfInteger aTrgIdxs = aLodBldr->GetDataSource()->GetAllElements(); if (!aTrgIdxs.IsEmpty()) - aLodBldr->Build (thePrs, aTrgIdxs, TColStd_PackedMapOfInteger(), Standard_True, theMode); + aLodBldr->Build (thePrs, aTrgIdxs, aDummy, Standard_True, theMode); } } diff --git a/src/OpenGl/OpenGl_LOD.cxx b/src/OpenGl/OpenGl_LOD.cxx index 1e7aea9164..53ceaf4c04 100644 --- a/src/OpenGl/OpenGl_LOD.cxx +++ b/src/OpenGl/OpenGl_LOD.cxx @@ -27,3 +27,15 @@ Handle(Graphic3d_Group) OpenGl_LOD::NewGroup (const Handle(Graphic3d_Structure)& myGroups.Append (aGroup); return aGroup; } + +//======================================================================= +// function : ReleaseGraphicResources +// purpose : +//======================================================================= +void OpenGl_LOD::ReleaseGraphicResources (const Handle(OpenGl_Context)& theGlCtx) +{ + for (OpenGl_Structure::GroupIterator aGroupIter (myGroups); aGroupIter.More(); aGroupIter.Next()) + { + aGroupIter.ChangeValue()->Release (theGlCtx); + } +} diff --git a/src/OpenGl/OpenGl_LOD.hxx b/src/OpenGl/OpenGl_LOD.hxx index fccafd4a70..f81da210f9 100644 --- a/src/OpenGl/OpenGl_LOD.hxx +++ b/src/OpenGl/OpenGl_LOD.hxx @@ -30,6 +30,8 @@ public: Standard_EXPORT virtual Handle(Graphic3d_Group) NewGroup (const Handle(Graphic3d_Structure)& theParentStruct) Standard_OVERRIDE; + void ReleaseGraphicResources (const Handle(OpenGl_Context)& theGlCtx); + DEFINE_STANDARD_RTTIEXT (OpenGl_LOD, Graphic3d_LOD) }; diff --git a/src/OpenGl/OpenGl_Structure.cxx b/src/OpenGl/OpenGl_Structure.cxx index 70504e8da1..2729997927 100644 --- a/src/OpenGl/OpenGl_Structure.cxx +++ b/src/OpenGl/OpenGl_Structure.cxx @@ -753,6 +753,14 @@ void OpenGl_Structure::ReleaseGlResources (const Handle(OpenGl_Context)& theGlCt { aGroupIter.ChangeValue()->Release (theGlCtx); } + if (!myLODManager.IsNull()) + { + for (Standard_Integer aLodIdx = 0; aLodIdx < myLODManager->NbOfDetailLevels(); ++aLodIdx) + { + Handle(OpenGl_LOD) aLod = Handle(OpenGl_LOD)::DownCast (myLODManager->GetLodById (aLodIdx)); + aLod->ReleaseGraphicResources (theGlCtx); + } + } if (myAspectLine != NULL) { myAspectLine->Release (theGlCtx.operator->());