1 // Created on: 1995-02-15
2 // Created by: Roberc Coublanc
3 // Copyright (c) 1995-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
6 // This file is part of Open CASCADE Technology software library.
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
17 #ifndef _SelectMgr_ViewerSelector_HeaderFile
18 #define _SelectMgr_ViewerSelector_HeaderFile
20 #include <MMgt_TShared.hxx>
21 #include <NCollection_Handle.hxx>
22 #include <NCollection_DataMap.hxx>
23 #include <OSD_Chronometer.hxx>
24 #include <TColStd_SequenceOfInteger.hxx>
25 #include <TColStd_HArray1OfInteger.hxx>
26 #include <SelectMgr_IndexedDataMapOfOwnerCriterion.hxx>
27 #include <SelectMgr_SelectingVolumeManager.hxx>
28 #include <SelectMgr_Selection.hxx>
29 #include <SelectMgr_SelectableObject.hxx>
30 #include <SelectMgr_SelectableObjectSet.hxx>
31 #include <SelectMgr_StateOfSelection.hxx>
32 #include <SelectMgr_ToleranceMap.hxx>
33 #include <Standard_OStream.hxx>
35 class SelectMgr_SelectionManager;
36 class SelectMgr_SensitiveEntitySet;
37 class SelectMgr_EntityOwner;
38 class SelectBasics_SensitiveEntity;
40 typedef NCollection_DataMap<Handle(SelectMgr_SelectableObject), NCollection_Handle<SelectMgr_SensitiveEntitySet> > SelectMgr_MapOfObjectSensitives;
41 typedef NCollection_DataMap<Handle(SelectMgr_SelectableObject), NCollection_Handle<SelectMgr_SensitiveEntitySet> >::Iterator SelectMgr_MapOfObjectSensitivesIterator;
43 typedef NCollection_DataMap<Standard_Integer, SelectMgr_SelectingVolumeManager> SelectMgr_FrustumCache;
45 //! A framework to define finding, sorting the sensitive
46 //! primitives in a view. Services are also provided to
47 //! define the return of the owners of those primitives
48 //! selected. The primitives are sorted by criteria such
49 //! as priority of the primitive or its depth in the view
50 //! relative to that of other primitives.
51 //! Note that in 3D, the inheriting framework
52 //! StdSelect_ViewerSelector3d is only to be used
53 //! if you do not want to use the services provided by
55 //! Two tools are available to find and select objects
56 //! found at a given position in the view. If you want to
57 //! select the owners of all the objects detected at
58 //! point x,y,z you use the Init - More - Next - Picked
59 //! loop. If, on the other hand, you want to select only
60 //! one object detected at that point, you use the Init -
61 //! More - OnePicked loop. In this iteration, More is
62 //! used to see if an object was picked and
63 //! OnePicked, to get the object closest to the pick position.
64 //! Viewer selectors are driven by
65 //! SelectMgr_SelectionManager, and manipulate
66 //! the SelectMgr_Selection objects given to them by
67 //! the selection manager.
69 //! Tolerances are applied to the entities in the following way:
70 //! 1. tolerance value stored in mytolerance will be used to calculate initial
71 //! selecting frustum, which will be applied for intersection testing during
73 //! 2. if tolerance of sensitive entity is less than mytolerance, the frustum for
74 //! intersection detection will be resized according to its sensitivity.
75 class SelectMgr_ViewerSelector : public MMgt_TShared
77 DEFINE_STANDARD_RTTIEXT(SelectMgr_ViewerSelector, MMgt_TShared)
78 friend class SelectMgr_SelectionManager;
81 //! Empties all the tables, removes all selections...
82 Standard_EXPORT void Clear();
84 //! returns the Sensitivity of picking
85 Standard_Real Sensitivity() const { return myTolerances.Tolerance(); }
87 //! Sorts the detected entites by priority and distance.
88 //! to be redefined if other criterion are used...
89 Standard_EXPORT void SortResult();
91 //! Returns the picked element with the highest priority,
92 //! and which is the closest to the last successful mouse position.
93 Handle(SelectMgr_EntityOwner) OnePicked() const
95 return mystored.IsEmpty()
96 ? Handle(SelectMgr_EntityOwner)()
100 //! Set preference of selecting one object for OnePicked() method:
101 //! - If True, objects with less depth (distance fron the view plane) are
102 //! preferred regardless of priority (priority is used then to choose among
103 //! objects with similar depth),
104 //! - If False, objects with higher priority are preferred regardless of the
105 //! depth which is used to choose among objects of the same priority.
106 void SetPickClosest (const Standard_Boolean theToPreferClosest) { preferclosest = theToPreferClosest; }
108 //! Returns the number of detected owners.
109 Standard_Integer NbPicked() const { return mystored.Extent(); }
111 //! Returns the entity Owner for the object picked at specified position.
112 //! @param theRank rank of detected object within range 1...NbPicked()
113 Standard_EXPORT Handle(SelectMgr_EntityOwner) Picked (const Standard_Integer theRank) const;
115 //! Returns the Entity for the object picked at specified position.
116 //! @param theRank rank of detected object within range 1...NbPicked()
117 Standard_EXPORT const SelectMgr_SortCriterion& PickedData (const Standard_Integer theRank) const;
119 //! Returns the Entity for the object picked at specified position.
120 //! @param theRank rank of detected object within range 1...NbPicked()
121 const Handle(SelectBasics_SensitiveEntity)& PickedEntity (const Standard_Integer theRank) const { return PickedData (theRank).Entity; }
123 //! Returns the 3D point (intersection of picking axis with the object nearest to eye)
124 //! for the object picked at specified position.
125 //! @param theRank rank of detected object within range 1...NbPicked()
126 gp_Pnt PickedPoint (const Standard_Integer theRank) const { return PickedData (theRank).Point; }
128 Standard_EXPORT Standard_Boolean Contains (const Handle(SelectMgr_SelectableObject)& theObject) const;
130 //! Returns the list of selection modes ModeList found in
131 //! this selector for the selectable object aSelectableObject.
132 //! Returns true if aSelectableObject is referenced inside
133 //! this selector; returns false if the object is not present
134 //! in this selector.
135 Standard_EXPORT Standard_Boolean Modes (const Handle(SelectMgr_SelectableObject)& theSelectableObject,
136 TColStd_ListOfInteger& theModeList,
137 const SelectMgr_StateOfSelection theWantedState = SelectMgr_SOS_Any) const;
139 //! Returns true if the selectable object
140 //! aSelectableObject having the selection mode aMode
141 //! is active in this selector.
142 Standard_EXPORT Standard_Boolean IsActive (const Handle(SelectMgr_SelectableObject)& theSelectableObject,
143 const Standard_Integer theMode) const;
145 //! Returns true if the selectable object
146 //! aSelectableObject having the selection mode aMode
147 //! is in this selector.
148 Standard_EXPORT Standard_Boolean IsInside (const Handle(SelectMgr_SelectableObject)& theSelectableObject,
149 const Standard_Integer theMode) const;
151 //! Returns the selection status Status of the selection aSelection.
152 Standard_EXPORT SelectMgr_StateOfSelection Status (const Handle(SelectMgr_Selection)& theSelection) const;
154 Standard_EXPORT TCollection_AsciiString Status (const Handle(SelectMgr_SelectableObject)& theSelectableObject) const;
156 //! Returns the list of active entity owners
157 Standard_EXPORT void ActiveOwners (NCollection_List<Handle(SelectBasics_EntityOwner)>& theOwners) const;
159 //! Adds new object to the map of selectable objects
160 Standard_EXPORT void AddSelectableObject (const Handle(SelectMgr_SelectableObject)& theObject);
162 //! Adds new selection to the object and builds its BVH tree
163 Standard_EXPORT void AddSelectionToObject (const Handle(SelectMgr_SelectableObject)& theObject,
164 const Handle(SelectMgr_Selection)& theSelection);
166 //! Moves existing object from set of not transform persistence objects
167 //! to set of transform persistence objects (or vice versa).
168 Standard_EXPORT void MoveSelectableObject (const Handle(SelectMgr_SelectableObject)& theObject);
170 //! Removes selectable object from map of selectable ones
171 Standard_EXPORT void RemoveSelectableObject (const Handle(SelectMgr_SelectableObject)& theObject);
173 //! Removes selection of the object and marks its BVH tree for rebuild
174 Standard_EXPORT void RemoveSelectionOfObject (const Handle(SelectMgr_SelectableObject)& theObject,
175 const Handle(SelectMgr_Selection)& theSelection);
177 //! Marks BVH of selectable objects for rebuild. Parameter theIsForce set as true
178 //! guarantees that 1st level BVH for the viewer selector will be rebuilt during this call
179 Standard_EXPORT void RebuildObjectsTree (const Standard_Boolean theIsForce = Standard_False);
181 //! Marks BVH of sensitive entities of particular selectable object for rebuild. Parameter
182 //! theIsForce set as true guarantees that 2nd level BVH for the object given will be
183 //! rebuilt during this call
184 Standard_EXPORT void RebuildSensitivesTree (const Handle(SelectMgr_SelectableObject)& theObject,
185 const Standard_Boolean theIsForce = Standard_False);
187 //! Returns instance of selecting volume manager of the viewer selector
188 SelectMgr_SelectingVolumeManager& GetManager() { return mySelectingVolumeMgr; }
190 //! Marks all added sensitive entities of all objects as non-selectable
191 Standard_EXPORT void ResetSelectionActivationStatus();
193 //! Is used for rectangular selection only
194 //! If theIsToAllow is false, only fully included sensitives will be detected, otherwise the algorithm will
195 //! mark both included and overlapped entities as matched
196 Standard_EXPORT void AllowOverlapDetection (const Standard_Boolean theIsToAllow);
200 //! Begins an iteration scanning for the owners detected at a position in the view.
201 Standard_DEPRECATED("Deprecated method Init()")
202 void Init() { initPicked(); }
204 //! Continues the interation scanning for the owners detected at a position in the view,
205 //! or continues the iteration scanning for the owner closest to the position in the view.
206 Standard_DEPRECATED("Deprecated method More()")
207 Standard_EXPORT Standard_Boolean More() { return morePicked(); }
209 //! Returns the next owner found in the iteration. This is
210 //! a scan for the owners detected at a position in the view.
211 Standard_DEPRECATED("Deprecated method Next()")
212 void Next() { nextPicked(); }
214 //! Returns the current selected entity detected by the selector;
215 Standard_DEPRECATED("Deprecated method Picked()")
216 Standard_EXPORT Handle(SelectMgr_EntityOwner) Picked() const;
218 //! Initializes internal iterator for stored detected sensitive entities
219 Standard_DEPRECATED("Deprecated method InitDetected()")
220 void InitDetected() { initPicked(); }
222 //! Makes a step along the map of detected sensitive entities and their owners
223 Standard_DEPRECATED("Deprecated method NextDetected()")
224 void NextDetected() { nextPicked(); }
226 //! Returns true if iterator of map of detected sensitive entities has reached its end
227 Standard_DEPRECATED("Deprecated method MoreDetected()")
228 Standard_Boolean MoreDetected() { return morePicked(); }
230 //! Returns sensitive entity that was detected during the previous run of selection algorithm
231 Standard_DEPRECATED("Deprecated method DetectedEntity() should be replaced by DetectedEntity(int)")
232 Standard_EXPORT const Handle(SelectBasics_SensitiveEntity)& DetectedEntity() const;
236 Standard_EXPORT SelectMgr_ViewerSelector();
238 //! Traverses BVH containing all added selectable objects and
239 //! finds candidates for further search of overlap
240 Standard_EXPORT void TraverseSensitives();
242 //! Returns True if the owner provides clipping by depth
243 //! for its sensitives. Override this method to tell the selector
244 //! to use the DepthClipping method for the owner.
245 //! Default implementation returns False for every owner.
246 //! @param theOwner [in] the onwer to check.
247 //! @return True if owner provides depth limits for sensitive clipping.
248 Standard_EXPORT virtual Standard_Boolean HasDepthClipping (const Handle(SelectMgr_EntityOwner)& theOwner) const;
250 //! Internal function that checks if there is possible overlap between some entity of selectable object theObject and
251 //! current selecting volume.
252 //! @param theObject [in] the selectable object for traversal.
253 //! @param theMgr [in] the (un)transformed copy of the selecting volume manager representing active selection frustum.
254 //! @param theCamera, theProjectionMat, theWorldViewMat [in] the source camera and matrices for theMgr given.
255 //! @param theViewportWidth, theViewportHeight [in] viewport (window) dimensions for evaluating
256 //! object's transformation persistence.
257 Standard_EXPORT void traverseObject (const Handle(SelectMgr_SelectableObject)& theObject,
258 const SelectMgr_SelectingVolumeManager& theMgr,
259 const Handle(Graphic3d_Camera)& theCamera,
260 const Graphic3d_Mat4d& theProjectionMat,
261 const Graphic3d_Mat4d& theWorldViewMat,
262 const Standard_Integer theViewportWidth,
263 const Standard_Integer theViewportHeight);
265 //! Internal function that checks if a particular sensitive
266 //! entity theEntity overlaps current selecting volume precisely
267 Standard_EXPORT void checkOverlap (const Handle(SelectBasics_SensitiveEntity)& theEntity,
268 const gp_GTrsf& theInversedTrsf,
269 SelectMgr_SelectingVolumeManager& theMgr);
273 //! Checks if the entity given requires to scale current selecting frustum
274 Standard_Boolean isToScaleFrustum (const Handle(SelectBasics_SensitiveEntity)& theEntity);
276 //! In case if custom tolerance is set, this method will return sum of entity sensitivity and
277 //! custom tolerance. Otherwise, pure entity sensitivity factor will be returned.
278 Standard_Integer sensitivity (const Handle(SelectBasics_SensitiveEntity)& theEntity) const;
280 void Activate (const Handle(SelectMgr_Selection)& theSelection);
282 void Deactivate (const Handle(SelectMgr_Selection)& theSelection);
284 //! removes a Selection from the Selector
285 void Remove (const Handle(SelectMgr_Selection)& aSelection);
287 //! Internal function that checks if a current selecting frustum
288 //! needs to be scaled and transformed for the entity and performs
289 //! necessary calculations
290 void computeFrustum (const Handle(SelectBasics_SensitiveEntity)& theEnt,
291 const SelectMgr_SelectingVolumeManager& theMgr,
292 const gp_GTrsf& theInvTrsf,
293 SelectMgr_FrustumCache& theCachedMgrs,
294 SelectMgr_SelectingVolumeManager& theResMgr);
297 private: // implementation of deprecated methods
299 //! Initializes internal iterator for stored detected sensitive entities
300 void initPicked() { myCurRank = 1; }
302 //! Makes a step along the map of detected sensitive entities and their owners
303 void nextPicked() { ++myCurRank; }
305 //! Returns true if iterator of map of detected sensitive entities has reached its end
306 Standard_Boolean morePicked() const
308 if (mystored.Extent() == 0) return Standard_False;
309 if (myCurRank == 0) return Standard_False;
310 return myCurRank <= myIndexes->Length();
315 Standard_Boolean preferclosest;
316 Standard_Boolean myToUpdateTolerance;
317 SelectMgr_IndexedDataMapOfOwnerCriterion mystored;
318 SelectMgr_SelectingVolumeManager mySelectingVolumeMgr;
319 mutable SelectMgr_SelectableObjectSet mySelectableObjects;
320 SelectMgr_ToleranceMap myTolerances;
321 NCollection_DataMap<Graphic3d_ZLayerId, Standard_Integer> myZLayerOrderMap;
325 Handle(TColStd_HArray1OfInteger) myIndexes;
326 Standard_Integer myCurRank;
327 Standard_Boolean myIsLeftChildQueuedFirst;
328 Standard_Integer myEntityIdx;
329 SelectMgr_MapOfObjectSensitives myMapOfObjectSensitives;
333 DEFINE_STANDARD_HANDLE(SelectMgr_ViewerSelector, MMgt_TShared)