// Created on: 2014-08-15 // Created by: Varvara POSKONINA // Copyright (c) 2005-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 _SelectMgr_SelectableObjectSet_HeaderFile #define _SelectMgr_SelectableObjectSet_HeaderFile #include #include #include //! The purpose of this class is to organize all selectable objects into data structure, allowing to build //! set of BVH trees for each transformation persistence subclass of selectable objects. This allow to minify //! number of updates for BVH trees - for example 2D persistent object subclass depends only on camera's projection //! and the corresponding BVH tree needs to be updated when camera's projection parameters change, while another //! tree for non-persistent objects can be left unchanged in this case. class SelectMgr_SelectableObjectSet { public: //! This enumeration declares names for subsets of selectable objects. Each subset has independent BVH tree. //! The class maintains subsets of selectable objects by their persistence flag. This allows to restric //! rebuilding of the trees for particular subset when the camera change does not implicitly require it: //! - BVHSubset_3d refers to the subset of normal world-space 3D objects. Associated BVH tree does not depend //! on the camera's state at all. //! This subset uses binned BVH builder with 32 bins and 1 element per leaf. //! - BVHSubset_3dPersistent refers to the subset of 3D persistent selectable objects (rotate, pan, zoom persistence). //! Associated BVH tree needs to be updated when either the camera's projection and position change. //! This subset uses linear BVH builder with 32 levels of depth and 1 element per leaf. //! - BVHSubset_2dPersistent refers to the subset of 2D persistent selectable objects. Associated BVH tree //! needs to be updated only when camera's projection changes. Bounding volumes for this object subclass //! is represented directly in eye space coordinates. //! This subset uses linear BVH builder with 32 levels of depth and 1 element per leaf. //! - BVHSubset_ortho3dPersistent refers to the subset of 3D persistent selectable objects (rotate, pan, zoom persistence) //! that contains `Graphic3d_TMF_OrthoPers` persistence mode. //! Associated BVH tree needs to be updated when either the camera's projection and position change. //! This subset uses linear BVH builder with 32 levels of depth and 1 element per leaf. //! - BVHSubset_ortho2dPersistent refers to the subset of 2D persistent selectable objects //! that contains `Graphic3d_TMF_OrthoPers` persistence mode. Associated BVH tree //! needs to be updated only when camera's projection changes. Bounding volumes for this object subclass //! is represented directly in eye space coordinates. //! This subset uses linear BVH builder with 32 levels of depth and 1 element per leaf. enum BVHSubset { BVHSubset_3d, BVHSubset_3dPersistent, BVHSubset_2dPersistent, BVHSubset_ortho3dPersistent, BVHSubset_ortho2dPersistent, BVHSubsetNb }; public: //! Class to iterate sequentually over all objects from every subset. class Iterator { //! Short-cut definition of map iterator type typedef NCollection_IndexedMap::Iterator ObjectMapIterator; public: //! Default constructor without initialization. Iterator() : mySet (NULL), mySubsetIdx (BVHSubsetNb) {} //! Constructs and initializes the iterator. Iterator (const SelectMgr_SelectableObjectSet& theSet) { Init (theSet); } //! Initializes the iterator. void Init (const SelectMgr_SelectableObjectSet& theSet) { mySet = &theSet; mySubsetIdx = 0; mySubsetIt = ObjectMapIterator (theSet.myObjects[mySubsetIdx]); More(); } //! Returns false when there is no more objects to iterate over. Standard_Boolean More() { if (mySubsetIt.More()) { return Standard_True; } else if ((mySubsetIdx == BVHSubsetNb - 1) || mySet == NULL) { return Standard_False; } mySubsetIt = ObjectMapIterator (mySet->myObjects[++mySubsetIdx]); return More(); } //! Steps to next selectable object in the set. void Next() { mySubsetIt.Next(); } //! Returns current object. const Handle(SelectMgr_SelectableObject)& Value() const { return mySubsetIt.Value(); } private: const SelectMgr_SelectableObjectSet* mySet; Standard_Integer mySubsetIdx; ObjectMapIterator mySubsetIt; }; public: //! Creates new empty objects set and initializes BVH tree builders for each subset. Standard_EXPORT SelectMgr_SelectableObjectSet(); //! Releases resources of selectable object set. virtual ~SelectMgr_SelectableObjectSet() { } //! Adds the new selectable object to the set. The selectable object is placed into one of the //! predefined subsets depending on its persistence type. After adding an object, this method //! marks the corresponding BVH tree for rebuild. //! @return true if selectable object is added, otherwise returns false (selectable object is already in the set). Standard_EXPORT Standard_Boolean Append (const Handle(SelectMgr_SelectableObject)& theObject); //! Removes the selectable object from the set. The selectable object is removed from the subset //! it has been placed into. After removing an object, this method marks the corresponding //! BVH tree for rebuild. //! @return true if selectable object is removed, otherwise returns false (selectable object is not in the set). Standard_EXPORT Standard_Boolean Remove (const Handle(SelectMgr_SelectableObject)& theObject); //! Performs necessary updates when object's persistence types changes. //! This method should be called right after changing transformation persistence flags of the //! objects and before updating BVH tree - to provide up-to-date state of the object set. Standard_EXPORT void ChangeSubset (const Handle(SelectMgr_SelectableObject)& theObject); //! Updates outdated BVH trees and remembers the last state of the //! camera view-projection matrices and viewport (window) dimensions. Standard_EXPORT void UpdateBVH (const Handle(Graphic3d_Camera)& theCam, const Graphic3d_Vec2i& theWinSize); //! Marks every BVH subset for update. Standard_EXPORT void MarkDirty(); //! Returns true if this objects set contains theObject given. Standard_Boolean Contains (const Handle(SelectMgr_SelectableObject)& theObject) const { return myObjects[BVHSubset_3d].Contains (theObject) || myObjects[BVHSubset_3dPersistent].Contains (theObject) || myObjects[BVHSubset_2dPersistent].Contains (theObject) || myObjects[BVHSubset_ortho3dPersistent].Contains (theObject) || myObjects[BVHSubset_ortho2dPersistent].Contains (theObject); } //! Returns true if the object set does not contain any selectable objects. Standard_Boolean IsEmpty() const { return myObjects[BVHSubset_3d].IsEmpty() && myObjects[BVHSubset_3dPersistent].IsEmpty() && myObjects[BVHSubset_2dPersistent].IsEmpty() && myObjects[BVHSubset_ortho3dPersistent].IsEmpty() && myObjects[BVHSubset_ortho2dPersistent].IsEmpty(); } //! Returns true if the specified object subset is empty. Standard_Boolean IsEmpty (const BVHSubset theSubset) const { return myObjects[theSubset].IsEmpty(); } //! Returns object from subset theSubset by theIndex given. The method allows to get selectable object //! referred by the index of an element of the subset's BVH tree. const Handle(SelectMgr_SelectableObject)& GetObjectById (const BVHSubset theSubset, const Standard_Integer theIndex) const { return myObjects[theSubset].FindKey (theIndex + 1); } //! Returns computed BVH for the theSubset given. const opencascade::handle >& BVH(const BVHSubset theSubset) const { return myBVH[theSubset]; } //! Dumps the content of me into the stream Standard_EXPORT void DumpJson (Standard_OStream& theOStream, Standard_Integer theDepth = -1) const; private: //! Returns an appropriate subset of theObject given depending on its persistence type. Standard_Integer appropriateSubset (const Handle(SelectMgr_SelectableObject)& theObject) { if (theObject->TransformPersistence().IsNull()) { const PrsMgr_Presentations& aPresentations = theObject->Presentations(); for (PrsMgr_Presentations::Iterator aPrsIter (aPresentations); aPrsIter.More(); aPrsIter.Next()) { const Handle(PrsMgr_Presentation)& aPrs3d = aPrsIter.ChangeValue(); if (aPrs3d->CStructure()->HasGroupTransformPersistence()) { return SelectMgr_SelectableObjectSet::BVHSubset_3dPersistent; } } return SelectMgr_SelectableObjectSet::BVHSubset_3d; } else if ((theObject->TransformPersistence()->Mode() & Graphic3d_TMF_2d) != 0) { if (theObject->TransformPersistence()->IsOrthoPers()) { return SelectMgr_SelectableObjectSet::BVHSubset_ortho2dPersistent; } return SelectMgr_SelectableObjectSet::BVHSubset_2dPersistent; } else if (theObject->TransformPersistence()->IsOrthoPers()) { return SelectMgr_SelectableObjectSet::BVHSubset_ortho3dPersistent; } else { return SelectMgr_SelectableObjectSet::BVHSubset_3dPersistent; } } //! Returns current subset of theObject given. Standard_Integer currentSubset (const Handle(SelectMgr_SelectableObject)& theObject) { for (Standard_Integer aSubsetIdx = 0; aSubsetIdx < BVHSubsetNb; ++aSubsetIdx) { if (myObjects[aSubsetIdx].Contains (theObject)) { return aSubsetIdx; } } return -1; } private: NCollection_IndexedMap myObjects[BVHSubsetNb]; //!< Map of objects for each subset opencascade::handle > myBVH[BVHSubsetNb]; //!< BVH tree computed for each subset Handle(Select3D_BVHBuilder3d) myBuilder[BVHSubsetNb]; //!< Builder allocated for each subset Standard_Boolean myIsDirty[BVHSubsetNb]; //!< Dirty flag for each subset Graphic3d_WorldViewProjState myLastViewState; //!< Last view-projection state used for construction of BVH Graphic3d_Vec2i myLastWinSize; //!< Last viewport's (window's) width used for construction of BVH friend class Iterator; }; #endif // _SelectMgr_SelectableObjectSet_HeaderFile