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
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
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.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16 
17 #ifndef _SelectMgr_ViewerSelector_HeaderFile
18 #define _SelectMgr_ViewerSelector_HeaderFile
19 
20 #include <Standard_Transient.hxx>
21 #include <NCollection_DataMap.hxx>
22 #include <OSD_Chronometer.hxx>
23 #include <TColStd_SequenceOfInteger.hxx>
24 #include <TColStd_HArray1OfInteger.hxx>
25 #include <Select3D_BVHBuilder3d.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>
34 
35 class SelectMgr_SelectionManager;
36 class SelectMgr_SensitiveEntitySet;
37 class SelectMgr_EntityOwner;
38 class Select3D_SensitiveEntity;
39 
40 // resolve name collisions with X11 headers
41 #ifdef Status
42   #undef Status
43 #endif
44 typedef NCollection_DataMap<Handle(SelectMgr_SelectableObject), Handle(SelectMgr_SensitiveEntitySet) > SelectMgr_MapOfObjectSensitives;
45 typedef NCollection_DataMap<Handle(SelectMgr_SelectableObject), Handle(SelectMgr_SensitiveEntitySet) >::Iterator SelectMgr_MapOfObjectSensitivesIterator;
46 
47 typedef NCollection_DataMap<Standard_Integer, SelectMgr_SelectingVolumeManager> SelectMgr_FrustumCache;
48 
49 //! A framework to define finding, sorting the sensitive
50 //! primitives in a view. Services are also provided to
51 //! define the return of the owners of those primitives
52 //! selected. The primitives are sorted by criteria such
53 //! as priority of the primitive or its depth in the view
54 //! relative to that of other primitives.
55 //! Note that in 3D, the inheriting framework
56 //! StdSelect_ViewerSelector3d   is only to be used
57 //! if you do not want to use the services provided by
58 //! AIS.
59 //! Two tools are available to find and select objects
60 //! found at a given position in the view. If you want to
61 //! select the owners of all the objects detected at
62 //! point x,y,z you use the Init - More - Next - Picked
63 //! loop. If, on the other hand, you want to select only
64 //! one object detected at that point, you use the Init -
65 //! More - OnePicked loop. In this iteration, More is
66 //! used to see if an object was picked and
67 //! OnePicked, to get the object closest to the pick position.
68 //! Viewer selectors are driven by
69 //! SelectMgr_SelectionManager, and manipulate
70 //! the SelectMgr_Selection objects given to them by
71 //! the selection manager.
72 //!
73 //! Tolerances are applied to the entities in the following way:
74 //! 1. tolerance value stored in mytolerance will be used to calculate initial
75 //!    selecting frustum, which will be applied for intersection testing during
76 //!    BVH traverse;
77 //! 2. if tolerance of sensitive entity is less than mytolerance, the frustum for
78 //!    intersection detection will be resized according to its sensitivity.
79 class SelectMgr_ViewerSelector : public Standard_Transient
80 {
81   DEFINE_STANDARD_RTTIEXT(SelectMgr_ViewerSelector, Standard_Transient)
82   friend class SelectMgr_SelectionManager;
83 public:
84 
85   //! Empties all the tables, removes all selections...
86   Standard_EXPORT void Clear();
87 
88   //! returns the Sensitivity of picking
Sensitivity() const89   Standard_Real Sensitivity() const { return myTolerances.Tolerance(); }
90 
91   //! Sorts the detected entites by priority and distance.
92   //!          to be redefined if other criterion are used...
93   Standard_EXPORT void SortResult();
94 
95   //! Returns the picked element with the highest priority,
96   //! and which is the closest to the last successful mouse position.
OnePicked() const97   Handle(SelectMgr_EntityOwner) OnePicked() const
98   {
99     return mystored.IsEmpty()
100          ? Handle(SelectMgr_EntityOwner)()
101          : Picked (1);
102   }
103 
104   //! Set preference of selecting one object for OnePicked() method:
105   //! - If True, objects with less depth (distance fron the view plane) are
106   //!   preferred regardless of priority (priority is used then to choose among
107   //!   objects with similar depth),
108   //! - If False, objects with higher priority are preferred regardless of the
109   //!   depth which is used to choose among objects of the same priority.
SetPickClosest(const Standard_Boolean theToPreferClosest)110   void SetPickClosest (const Standard_Boolean theToPreferClosest) { preferclosest = theToPreferClosest; }
111 
112   //! Returns the number of detected owners.
NbPicked() const113   Standard_Integer NbPicked() const { return mystored.Extent(); }
114 
115   //! Clears picking results.
116   Standard_EXPORT void ClearPicked();
117 
118   //! Returns the entity Owner for the object picked at specified position.
119   //! @param theRank rank of detected object within range 1...NbPicked()
120   Standard_EXPORT Handle(SelectMgr_EntityOwner) Picked (const Standard_Integer theRank) const;
121 
122   //! Returns the Entity for the object picked at specified position.
123   //! @param theRank rank of detected object within range 1...NbPicked()
124   Standard_EXPORT const SelectMgr_SortCriterion& PickedData (const Standard_Integer theRank) const;
125 
126   //! Returns the Entity for the object picked at specified position.
127   //! @param theRank rank of detected object within range 1...NbPicked()
Handle(Select3D_SensitiveEntity)128   const Handle(Select3D_SensitiveEntity)& PickedEntity (const Standard_Integer theRank) const { return PickedData (theRank).Entity; }
129 
130   //! Returns the 3D point (intersection of picking axis with the object nearest to eye)
131   //! for the object picked at specified position.
132   //! @param theRank rank of detected object within range 1...NbPicked()
PickedPoint(const Standard_Integer theRank) const133   gp_Pnt PickedPoint (const Standard_Integer theRank) const { return PickedData (theRank).Point; }
134 
135   Standard_EXPORT Standard_Boolean Contains (const Handle(SelectMgr_SelectableObject)& theObject) const;
136 
137   //! Returns the default builder used to construct BVH of entity set.
Handle(Select3D_BVHBuilder3d)138   const Handle(Select3D_BVHBuilder3d) EntitySetBuilder() { return myEntitySetBuilder; }
139 
140   //! Sets the default builder used to construct BVH of entity set.
141   //! The new builder will be also assigned for already defined objects, but computed BVH trees will not be invalidated.
142   Standard_EXPORT void SetEntitySetBuilder (const Handle(Select3D_BVHBuilder3d)& theBuilder);
143 
144   //! Returns the list of selection modes ModeList found in
145   //! this selector for the selectable object aSelectableObject.
146   //! Returns true if aSelectableObject is referenced inside
147   //! this selector; returns false if the object is not present
148   //! in this selector.
149   Standard_EXPORT Standard_Boolean Modes (const Handle(SelectMgr_SelectableObject)& theSelectableObject,
150                                           TColStd_ListOfInteger& theModeList,
151                                           const SelectMgr_StateOfSelection theWantedState = SelectMgr_SOS_Any) const;
152 
153   //! Returns true if the selectable object
154   //! aSelectableObject having the selection mode aMode
155   //! is active in this selector.
156   Standard_EXPORT Standard_Boolean IsActive (const Handle(SelectMgr_SelectableObject)& theSelectableObject,
157                                              const Standard_Integer theMode) const;
158 
159   //! Returns true if the selectable object
160   //! aSelectableObject having the selection mode aMode
161   //! is in this selector.
162   Standard_EXPORT Standard_Boolean IsInside (const Handle(SelectMgr_SelectableObject)& theSelectableObject,
163                                              const Standard_Integer theMode) const;
164 
165   //! Returns the selection status Status of the selection aSelection.
166   Standard_EXPORT SelectMgr_StateOfSelection Status (const Handle(SelectMgr_Selection)& theSelection) const;
167 
168   Standard_EXPORT TCollection_AsciiString Status (const Handle(SelectMgr_SelectableObject)& theSelectableObject) const;
169 
170   //! Returns the list of active entity owners
171   Standard_EXPORT void ActiveOwners (NCollection_List<Handle(SelectMgr_EntityOwner)>& theOwners) const;
172 
173   //! Adds new object to the map of selectable objects
174   Standard_EXPORT void AddSelectableObject (const Handle(SelectMgr_SelectableObject)& theObject);
175 
176   //! Adds new selection to the object and builds its BVH tree
177   Standard_EXPORT void AddSelectionToObject (const Handle(SelectMgr_SelectableObject)& theObject,
178                                              const Handle(SelectMgr_Selection)& theSelection);
179 
180   //! Moves existing object from set of not transform persistence objects
181   //! to set of transform persistence objects (or vice versa).
182   Standard_EXPORT void MoveSelectableObject (const Handle(SelectMgr_SelectableObject)& theObject);
183 
184   //! Removes selectable object from map of selectable ones
185   Standard_EXPORT void RemoveSelectableObject (const Handle(SelectMgr_SelectableObject)& theObject);
186 
187   //! Removes selection of the object and marks its BVH tree for rebuild
188   Standard_EXPORT void RemoveSelectionOfObject (const Handle(SelectMgr_SelectableObject)& theObject,
189                                                 const Handle(SelectMgr_Selection)& theSelection);
190 
191   //! Marks BVH of selectable objects for rebuild. Parameter theIsForce set as true
192   //! guarantees that 1st level BVH for the viewer selector will be rebuilt during this call
193   Standard_EXPORT void RebuildObjectsTree (const Standard_Boolean theIsForce = Standard_False);
194 
195   //! Marks BVH of sensitive entities of particular selectable object for rebuild. Parameter
196   //! theIsForce set as true guarantees that 2nd level BVH for the object given will be
197   //! rebuilt during this call
198   Standard_EXPORT void RebuildSensitivesTree (const Handle(SelectMgr_SelectableObject)& theObject,
199                                               const Standard_Boolean theIsForce = Standard_False);
200 
201   //! Returns instance of selecting volume manager of the viewer selector
GetManager()202   SelectMgr_SelectingVolumeManager& GetManager() { return mySelectingVolumeMgr; }
203 
204   //! Marks all added sensitive entities of all objects as non-selectable
205   Standard_EXPORT void ResetSelectionActivationStatus();
206 
207   //! Is used for rectangular selection only
208   //! If theIsToAllow is false, only fully included sensitives will be detected, otherwise the algorithm will
209   //! mark both included and overlapped entities as matched
210   Standard_EXPORT void AllowOverlapDetection (const Standard_Boolean theIsToAllow);
211 
212   //! Dumps the content of me into the stream
213   Standard_EXPORT void DumpJson (Standard_OStream& theOStream, const Standard_Integer theDepth = -1) const;
214 
215 public:
216 
217   //! Begins an iteration scanning for the owners detected at a position in the view.
218   Standard_DEPRECATED("Deprecated method Init()")
Init()219   void Init() { initPicked(); }
220 
221   //! Continues the interation scanning for the owners detected at a position in the view,
222   //! or continues the iteration scanning for the owner closest to the position in the view.
223   Standard_DEPRECATED("Deprecated method More()")
More()224   Standard_Boolean More() { return morePicked(); }
225 
226   //! Returns the next owner found in the iteration. This is
227   //! a scan for the owners detected at a position in the view.
228   Standard_DEPRECATED("Deprecated method Next()")
Next()229   void Next() { nextPicked(); }
230 
231   //! Returns the current selected entity detected by the selector;
232   Standard_DEPRECATED("Deprecated method Picked()")
233   Standard_EXPORT Handle(SelectMgr_EntityOwner) Picked() const;
234 
235   //! Initializes internal iterator for stored detected sensitive entities
236   Standard_DEPRECATED("Deprecated method InitDetected()")
InitDetected()237   void InitDetected() { initPicked(); }
238 
239   //! Makes a step along the map of detected sensitive entities and their owners
240   Standard_DEPRECATED("Deprecated method NextDetected()")
NextDetected()241   void NextDetected() { nextPicked(); }
242 
243   //! Returns true if iterator of map of detected sensitive entities has reached its end
244   Standard_DEPRECATED("Deprecated method MoreDetected()")
MoreDetected()245   Standard_Boolean MoreDetected() { return morePicked(); }
246 
247   //! Returns sensitive entity that was detected during the previous run of selection algorithm
248   Standard_DEPRECATED("Deprecated method DetectedEntity() should be replaced by DetectedEntity(int)")
249   Standard_EXPORT const Handle(Select3D_SensitiveEntity)& DetectedEntity() const;
250 
251 protected:
252 
253   Standard_EXPORT SelectMgr_ViewerSelector();
254 
255   //! Traverses BVH containing all added selectable objects and
256   //! finds candidates for further search of overlap
257   Standard_EXPORT void TraverseSensitives();
258 
259   //! Internal function that checks if there is possible overlap between some entity of selectable object theObject and
260   //! current selecting volume.
261   //! @param theObject [in] the selectable object for traversal.
262   //! @param theMgr [in] the (un)transformed copy of the selecting volume manager representing active selection frustum.
263   //! @param theCamera, theProjectionMat, theWorldViewMat [in] the source camera and matrices for theMgr given.
264   //! @param theViewportWidth, theViewportHeight [in] viewport (window) dimensions for evaluating
265   //!        object's transformation persistence.
266   Standard_EXPORT void traverseObject (const Handle(SelectMgr_SelectableObject)& theObject,
267                                        const SelectMgr_SelectingVolumeManager& theMgr,
268                                        const Handle(Graphic3d_Camera)& theCamera,
269                                        const Graphic3d_Mat4d& theProjectionMat,
270                                        const Graphic3d_Mat4d& theWorldViewMat,
271                                        const Standard_Integer theViewportWidth,
272                                        const Standard_Integer theViewportHeight);
273 
274   //! Internal function that checks if a particular sensitive
275   //! entity theEntity overlaps current selecting volume precisely
276   Standard_EXPORT void checkOverlap (const Handle(Select3D_SensitiveEntity)& theEntity,
277                                      const gp_GTrsf& theInversedTrsf,
278                                      SelectMgr_SelectingVolumeManager& theMgr);
279 
280 private:
281 
282   //! Checks if the entity given requires to scale current selecting frustum
283   Standard_Boolean isToScaleFrustum (const Handle(Select3D_SensitiveEntity)& theEntity);
284 
285   //! In case if custom tolerance is set, this method will return sum of entity sensitivity and
286   //! custom tolerance. Otherwise, pure entity sensitivity factor will be returned.
287   Standard_Integer sensitivity (const Handle(Select3D_SensitiveEntity)& theEntity) const;
288 
289   void Activate (const Handle(SelectMgr_Selection)& theSelection);
290 
291   void Deactivate (const Handle(SelectMgr_Selection)& theSelection);
292 
293   //! removes a Selection from the Selector
294   void Remove (const Handle(SelectMgr_Selection)& aSelection);
295 
296   //! Internal function that checks if a current selecting frustum needs to be scaled and transformed for the entity and performs necessary calculations.
297   void computeFrustum (const Handle(Select3D_SensitiveEntity)& theEnt,
298                        const SelectMgr_SelectingVolumeManager& theMgrGlobal,
299                        const SelectMgr_SelectingVolumeManager& theMgrObject,
300                        const gp_GTrsf& theInvTrsf,
301                        SelectMgr_FrustumCache& theCachedMgrs,
302                        SelectMgr_SelectingVolumeManager& theResMgr);
303 
304 
305 private: // implementation of deprecated methods
306 
307   //! Initializes internal iterator for stored detected sensitive entities
initPicked()308   void initPicked() { myCurRank = 1; }
309 
310   //! Makes a step along the map of detected sensitive entities and their owners
nextPicked()311   void nextPicked() { ++myCurRank; }
312 
313   //! Returns true if iterator of map of detected sensitive entities has reached its end
morePicked() const314   Standard_Boolean morePicked() const
315   {
316     if (mystored.Extent() == 0) return Standard_False;
317     if (myCurRank == 0) return Standard_False;
318     return myCurRank <= myIndexes->Length();
319   }
320 
321   //! Compute 3d position for detected entity.
322   void updatePoint3d (SelectMgr_SortCriterion& theCriterion,
323                       const SelectBasics_PickResult& thePickResult,
324                       const Handle(Select3D_SensitiveEntity)& theEntity,
325                       const gp_GTrsf& theInversedTrsf,
326                       const SelectMgr_SelectingVolumeManager& theMgr) const;
327 
328 protected:
329 
330   Standard_Boolean                              preferclosest;
331   Standard_Boolean                              myToUpdateTolerance;
332   SelectMgr_IndexedDataMapOfOwnerCriterion      mystored;
333   SelectMgr_SelectingVolumeManager              mySelectingVolumeMgr;
334   mutable SelectMgr_SelectableObjectSet         mySelectableObjects;
335   SelectMgr_ToleranceMap                        myTolerances;
336   NCollection_DataMap<Graphic3d_ZLayerId, Standard_Integer> myZLayerOrderMap;
337   Handle(Select3D_BVHBuilder3d)                 myEntitySetBuilder;
338   gp_Pnt                                        myCameraEye;
339   gp_Dir                                        myCameraDir;
340   Standard_Real                                 myCameraScale;
341 
342 private:
343 
344   Handle(TColStd_HArray1OfInteger)             myIndexes;
345   Standard_Integer                             myCurRank;
346   Standard_Boolean                             myIsLeftChildQueuedFirst;
347   Standard_Integer                             myEntityIdx;
348   SelectMgr_MapOfObjectSensitives              myMapOfObjectSensitives;
349 
350 };
351 
352 DEFINE_STANDARD_HANDLE(SelectMgr_ViewerSelector, Standard_Transient)
353 
354 #endif
355