0030640: Visualization, Graphic3d_Camera - add option creating Projection matrix...
[occt.git] / src / SelectMgr / SelectMgr_SelectableObjectSet.hxx
1 // Created on: 2014-08-15
2 // Created by: Varvara POSKONINA
3 // Copyright (c) 2005-2014 OPEN CASCADE SAS
4 //
5 // This file is part of Open CASCADE Technology software library.
6 //
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
12 //
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
15
16 #ifndef _SelectMgr_SelectableObjectSet_HeaderFile
17 #define _SelectMgr_SelectableObjectSet_HeaderFile
18
19 #include <BVH_Builder.hxx>
20 #include <BVH_Tree.hxx>
21 #include <Graphic3d_Mat4d.hxx>
22 #include <Graphic3d_WorldViewProjState.hxx>
23 #include <NCollection_Handle.hxx>
24 #include <NCollection_IndexedMap.hxx>
25 #include <Select3D_BVHBuilder3d.hxx>
26 #include <SelectMgr_SelectableObject.hxx>
27
28 //! The purpose of this class is to organize all selectable objects into data structure, allowing to build 
29 //! set of BVH trees for each transformation persistence subclass of selectable objects. This allow to minify
30 //! number of updates for BVH trees - for example 2D persistent object subclass depends only on camera's projection
31 //! and the corresponding BVH tree needs to be updated when camera's projection parameters change, while another
32 //! tree for non-persistent objects can be left unchanged in this case.
33 class SelectMgr_SelectableObjectSet
34 {
35 public:
36
37   //! This enumeration declares names for subsets of selectable objects. Each subset has independent BVH tree.
38   //! The class maintains subsets of selectable objects by their persistence flag. This allows to restric
39   //! rebuilding of the trees for particular subset when the camera change does not implicitly require it:
40   //! - BVHSubset_3d refers to the subset of normal world-space 3D objects. Associated BVH tree does not depend
41   //! on the camera's state at all.
42   //! This subset uses binned BVH builder with 32 bins and 1 element per leaf.
43   //! - BVHSubset_3dPersistent refers to the subset of 3D persistent selectable objects (rotate, pan, zoom persistence).
44   //! Associated BVH tree needs to be updated when either the camera's projection and position change.
45   //! This subset uses linear BVH builder with 32 levels of depth and 1 element per leaf.
46   //! - BVHSubset_2dPersistent refers to the subset of 2D persistent selectable objects. Associated BVH tree
47   //! needs to be updated only when camera's projection changes. Bounding volumes for this object subclass
48   //! is represented directly in eye space coordinates.
49   //! This subset uses linear BVH builder with 32 levels of depth and 1 element per leaf.
50   enum BVHSubset
51   {
52     BVHSubset_3d,
53     BVHSubset_3dPersistent,
54     BVHSubset_2dPersistent,
55     BVHSubsetNb
56   };
57
58 public:
59
60   //! Class to iterate sequentually over all objects from every subset.
61   class Iterator
62   {
63     //! Short-cut definition of map iterator type
64     typedef NCollection_IndexedMap<Handle(SelectMgr_SelectableObject)>::Iterator ObjectMapIterator;
65
66   public:
67
68     //! Default constructor without initialization.
69     Iterator() : mySet (NULL), mySubsetIdx (BVHSubsetNb) {}
70
71     //! Constructs and initializes the iterator.
72     Iterator (const SelectMgr_SelectableObjectSet& theSet) { Init (theSet); }
73
74     //! Initializes the iterator.
75     void Init (const SelectMgr_SelectableObjectSet& theSet)
76     {
77       mySet       = &theSet;
78       mySubsetIdx = 0;
79       mySubsetIt  = ObjectMapIterator (theSet.myObjects[mySubsetIdx]);
80       More();
81     }
82
83     //! Returns false when there is no more objects to iterate over.
84     Standard_Boolean More()
85     {
86       if (mySubsetIt.More())
87       {
88         return Standard_True;
89       }
90       else if ((mySubsetIdx == BVHSubsetNb - 1) || mySet == NULL)
91       {
92         return Standard_False;
93       }
94       mySubsetIt = ObjectMapIterator (mySet->myObjects[++mySubsetIdx]);
95       return More();
96     }
97
98     //! Steps to next selectable object in the set.
99     void Next() { mySubsetIt.Next(); }
100
101     //! Returns current object.
102     const Handle(SelectMgr_SelectableObject)& Value() const { return mySubsetIt.Value(); }
103
104   private:
105     const SelectMgr_SelectableObjectSet* mySet;
106     Standard_Integer mySubsetIdx;
107     ObjectMapIterator mySubsetIt;
108   };
109
110 public:
111
112   //! Creates new empty objects set and initializes BVH tree builders for each subset.
113   Standard_EXPORT SelectMgr_SelectableObjectSet();
114
115   //! Releases resources of selectable object set.
116   virtual ~SelectMgr_SelectableObjectSet() { }
117
118   //! Adds the new selectable object to the set. The selectable object is placed into one of the
119   //! predefined subsets depending on its persistence type. After adding an object, this method
120   //! marks the corresponding BVH tree for rebuild.
121   //! @return true if selectable object is added, otherwise returns false (selectable object is already in the set).
122   Standard_EXPORT Standard_Boolean Append (const Handle(SelectMgr_SelectableObject)& theObject);
123
124   //! Removes the selectable object from the set. The selectable object is removed from the subset
125   //! it has been placed into. After removing an object, this method marks the corresponding
126   //! BVH tree for rebuild.
127   //! @return true if selectable object is removed, otherwise returns false (selectable object is not in the set).
128   Standard_EXPORT Standard_Boolean Remove (const Handle(SelectMgr_SelectableObject)& theObject);
129
130   //! Performs necessary updates when object's persistence types changes.
131   //! This method should be called right after changing transformation persistence flags of the
132   //! objects and before updating BVH tree - to provide up-to-date state of the object set.
133   Standard_EXPORT void ChangeSubset (const Handle(SelectMgr_SelectableObject)& theObject);
134
135   //! Updates outdated BVH trees and remembers the last state of the
136   //! camera view-projection matrices and viewport (window) dimensions.
137   Standard_EXPORT void UpdateBVH (const Handle(Graphic3d_Camera)& theCamera,
138                                   const Graphic3d_Mat4d& theProjectionMat,
139                                   const Graphic3d_Mat4d& theWorldViewMat,
140                                   const Graphic3d_WorldViewProjState& theViewState,
141                                   const Standard_Integer theViewportWidth,
142                                   const Standard_Integer theViewportHeight);
143
144   //! Marks every BVH subset for update.
145   Standard_EXPORT void MarkDirty();
146
147   //! Returns true if this objects set contains theObject given.
148   Standard_Boolean Contains (const Handle(SelectMgr_SelectableObject)& theObject) const
149   {
150     return myObjects[BVHSubset_3d].Contains (theObject)
151         || myObjects[BVHSubset_3dPersistent].Contains (theObject)
152         || myObjects[BVHSubset_2dPersistent].Contains (theObject);
153   }
154
155   //! Returns true if the object set does not contain any selectable objects.
156   Standard_Boolean IsEmpty() const
157   {
158     return myObjects[BVHSubset_3d].IsEmpty()
159         && myObjects[BVHSubset_3dPersistent].IsEmpty()
160         && myObjects[BVHSubset_2dPersistent].IsEmpty();
161   }
162
163   //! Returns true if the specified object subset is empty.
164   Standard_Boolean IsEmpty (const BVHSubset theSubset) const
165   {
166     return myObjects[theSubset].IsEmpty();
167   }
168
169   //! Returns object from subset theSubset by theIndex given. The method allows to get selectable object
170   //! referred by the index of an element of the subset's BVH tree.
171   const Handle(SelectMgr_SelectableObject)& GetObjectById (const BVHSubset theSubset,
172                                                            const Standard_Integer theIndex) const
173   {
174     return myObjects[theSubset].FindKey (theIndex + 1);
175   }
176
177   //! Returns computed BVH for the theSubset given.
178   const opencascade::handle<BVH_Tree<Standard_Real, 3> >& BVH(const BVHSubset theSubset) const
179   {
180     return myBVH[theSubset];
181   }
182
183   //! Dumps the content of me into the stream
184   Standard_EXPORT void DumpJson (Standard_OStream& theOStream, Standard_Integer theDepth = -1) const;
185
186 private:
187
188   //! Returns an appropriate subset of theObject given depending on its persistence type.
189   Standard_Integer appropriateSubset (const Handle(SelectMgr_SelectableObject)& theObject)
190   {
191     if (theObject->TransformPersistence().IsNull())
192     {
193       return SelectMgr_SelectableObjectSet::BVHSubset_3d;
194     }
195     else if (theObject->TransformPersistence()->Mode() == Graphic3d_TMF_2d)
196     {
197       return SelectMgr_SelectableObjectSet::BVHSubset_2dPersistent;
198     }
199     else
200     {
201       return SelectMgr_SelectableObjectSet::BVHSubset_3dPersistent;
202     }
203   }
204
205   //! Returns current subset of theObject given.
206   Standard_Integer currentSubset (const Handle(SelectMgr_SelectableObject)& theObject)
207   {
208     for (Standard_Integer aSubsetIdx = 0; aSubsetIdx < BVHSubsetNb; ++aSubsetIdx)
209     {
210       if (myObjects[aSubsetIdx].Contains (theObject))
211       {
212         return aSubsetIdx;
213       }
214     }
215     return -1;
216   }
217
218 private:
219
220   NCollection_IndexedMap<Handle(SelectMgr_SelectableObject)> myObjects[BVHSubsetNb]; //!< Map of objects for each subset
221   opencascade::handle<BVH_Tree<Standard_Real, 3> >           myBVH[BVHSubsetNb];     //!< BVH tree computed for each subset
222   Handle(Select3D_BVHBuilder3d)                              myBuilder[BVHSubsetNb]; //!< Builder allocated for each subset
223   Standard_Boolean                                           myIsDirty[BVHSubsetNb]; //!< Dirty flag for each subset
224   Graphic3d_WorldViewProjState                               myLastViewState; //!< Last view-projection state used for construction of BVH
225   Standard_Integer                                           myLastWidth; //!< Last viewport's (window's) width used for construction of BVH
226   Standard_Integer                                           myLastHeight; //!< Last viewport's (window's) height used for construction of BVH
227   friend class Iterator;
228 };
229
230 #endif // _SelectMgr_SelectableObjectSet_HeaderFile