0032978: Visualization - AIS_ViewController::PickPoint() includes objects invisible...
[occt.git] / src / SelectMgr / SelectMgr_ViewerSelector.hxx
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 <Graphic3d_SequenceOfStructure.hxx>
21 #include <NCollection_DataMap.hxx>
22 #include <OSD_Chronometer.hxx>
23 #include <Select3D_BVHBuilder3d.hxx>
24 #include <SelectMgr_BVHThreadPool.hxx>
25 #include <SelectMgr_IndexedDataMapOfOwnerCriterion.hxx>
26 #include <SelectMgr_SelectingVolumeManager.hxx>
27 #include <SelectMgr_Selection.hxx>
28 #include <SelectMgr_SelectableObject.hxx>
29 #include <SelectMgr_SelectableObjectSet.hxx>
30 #include <SelectMgr_StateOfSelection.hxx>
31 #include <SelectMgr_ToleranceMap.hxx>
32 #include <SelectMgr_TypeOfDepthTolerance.hxx>
33 #include <SelectMgr_ViewerSelector.hxx>
34 #include <Standard_OStream.hxx>
35 #include <Standard_Transient.hxx>
36 #include <StdSelect_TypeOfSelectionImage.hxx>
37 #include <TColStd_HArray1OfInteger.hxx>
38 #include <TColStd_SequenceOfInteger.hxx>
39
40 class SelectMgr_SensitiveEntitySet;
41 class SelectMgr_EntityOwner;
42 class Select3D_SensitiveEntity;
43 class V3d_View;
44
45 // resolve name collisions with X11 headers
46 #ifdef Status
47   #undef Status
48 #endif
49 typedef NCollection_DataMap<Handle(SelectMgr_SelectableObject), Handle(SelectMgr_SensitiveEntitySet) > SelectMgr_MapOfObjectSensitives;
50 typedef NCollection_DataMap<Handle(SelectMgr_SelectableObject), Handle(SelectMgr_SensitiveEntitySet) >::Iterator SelectMgr_MapOfObjectSensitivesIterator;
51
52 typedef NCollection_DataMap<Standard_Integer, SelectMgr_SelectingVolumeManager> SelectMgr_FrustumCache;
53
54 //! A framework to define finding, sorting the sensitive
55 //! primitives in a view. Services are also provided to
56 //! define the return of the owners of those primitives
57 //! selected. The primitives are sorted by criteria such
58 //! as priority of the primitive or its depth in the view
59 //! relative to that of other primitives.
60 //! Note that in 3D, the inheriting framework
61 //! StdSelect_ViewerSelector3d   is only to be used
62 //! if you do not want to use the services provided by
63 //! AIS.
64 //! Two tools are available to find and select objects
65 //! found at a given position in the view. If you want to
66 //! select the owners of all the objects detected at
67 //! point x,y,z you use the Init - More - Next - Picked
68 //! loop. If, on the other hand, you want to select only
69 //! one object detected at that point, you use the Init -
70 //! More - OnePicked loop. In this iteration, More is
71 //! used to see if an object was picked and
72 //! OnePicked, to get the object closest to the pick position.
73 //! Viewer selectors are driven by
74 //! SelectMgr_SelectionManager, and manipulate
75 //! the SelectMgr_Selection objects given to them by
76 //! the selection manager.
77 //!
78 //! Tolerances are applied to the entities in the following way:
79 //! 1. tolerance value stored in mytolerance will be used to calculate initial
80 //!    selecting frustum, which will be applied for intersection testing during
81 //!    BVH traverse;
82 //! 2. if tolerance of sensitive entity is less than mytolerance, the frustum for
83 //!    intersection detection will be resized according to its sensitivity.
84 class SelectMgr_ViewerSelector : public Standard_Transient
85 {
86   DEFINE_STANDARD_RTTIEXT(SelectMgr_ViewerSelector, Standard_Transient)
87   friend class SelectMgr_SelectionManager;
88 public:
89
90   //! Constructs an empty selector object.
91   Standard_EXPORT SelectMgr_ViewerSelector();
92
93   //! Returns custom pixel tolerance value.
94   Standard_Integer CustomPixelTolerance() const { return myTolerances.CustomTolerance(); }
95
96   //! Sets the pixel tolerance <theTolerance>.
97   Standard_EXPORT void SetPixelTolerance (const Standard_Integer theTolerance);
98
99   //! Returns the largest sensitivity of picking
100   Standard_Real Sensitivity() const { return myTolerances.Tolerance(); }
101
102   //! Returns the largest pixel tolerance.
103   Standard_Integer PixelTolerance() const { return myTolerances.Tolerance(); }
104
105   //! Sorts the detected entities by priority and distance.
106   Standard_EXPORT virtual void SortResult() const;
107
108   //! Returns the picked element with the highest priority,
109   //! and which is the closest to the last successful mouse position.
110   Handle(SelectMgr_EntityOwner) OnePicked() const
111   {
112     return mystored.IsEmpty()
113          ? Handle(SelectMgr_EntityOwner)()
114          : Picked (1);
115   }
116
117   //! Return the flag determining precedence of picked depth (distance from eye to entity) over entity priority in sorted results; TRUE by default.
118   //! When flag is TRUE, priority will be considered only if entities have the same depth  within the tolerance.
119   //! When flag is FALSE, entities with higher priority will be in front regardless of their depth (like x-ray).
120   bool ToPickClosest() const { return myToPreferClosest; }
121
122   //! Set flag determining precedence of picked depth over entity priority in sorted results.
123   void SetPickClosest (bool theToPreferClosest) { myToPreferClosest = theToPreferClosest; }
124
125   //! Return the type of tolerance for considering two entities having a similar depth (distance from eye to entity);
126   //! SelectMgr_TypeOfDepthTolerance_SensitivityFactor by default.
127   SelectMgr_TypeOfDepthTolerance DepthToleranceType() const { return myDepthTolType; }
128
129   //! Return the tolerance for considering two entities having a similar depth (distance from eye to entity).
130   Standard_Real DepthTolerance() const { return myDepthTolerance; }
131
132   //! Set the tolerance for considering two entities having a similar depth (distance from eye to entity).
133   //! @param theType [in] type of tolerance value
134   //! @param theTolerance [in] tolerance value in 3D scale (SelectMgr_TypeOfDepthTolerance_Uniform)
135   //!                          or in pixels (SelectMgr_TypeOfDepthTolerance_UniformPixels);
136   //!                          value is ignored in case of SelectMgr_TypeOfDepthTolerance_SensitivityFactor
137   void SetDepthTolerance (SelectMgr_TypeOfDepthTolerance theType,
138                           Standard_Real theTolerance)
139   {
140     myDepthTolType   = theType;
141     myDepthTolerance = theTolerance;
142   }
143
144   //! Returns the number of detected owners.
145   Standard_Integer NbPicked() const { return mystored.Extent(); }
146
147   //! Clears picking results.
148   Standard_EXPORT void ClearPicked();
149
150   //! Empties all the tables, removes all selections...
151   void Clear() { ClearPicked(); }
152
153   //! Returns the entity Owner for the object picked at specified position.
154   //! @param theRank rank of detected object within range 1...NbPicked()
155   Standard_EXPORT Handle(SelectMgr_EntityOwner) Picked (const Standard_Integer theRank) const;
156
157   //! Returns the Entity for the object picked at specified position.
158   //! @param theRank rank of detected object within range 1...NbPicked()
159   Standard_EXPORT const SelectMgr_SortCriterion& PickedData (const Standard_Integer theRank) const;
160
161   //! Returns the Entity for the object picked at specified position.
162   //! @param theRank rank of detected object within range 1...NbPicked()
163   const Handle(Select3D_SensitiveEntity)& PickedEntity (const Standard_Integer theRank) const { return PickedData (theRank).Entity; }
164
165   //! Returns the 3D point (intersection of picking axis with the object nearest to eye)
166   //! for the object picked at specified position.
167   //! @param theRank rank of detected object within range 1...NbPicked()
168   gp_Pnt PickedPoint (const Standard_Integer theRank) const { return PickedData (theRank).Point; }
169
170   //! Remove picked entities associated with specified object.
171   Standard_EXPORT Standard_Boolean RemovePicked (const Handle(SelectMgr_SelectableObject)& theObject);
172
173   Standard_EXPORT Standard_Boolean Contains (const Handle(SelectMgr_SelectableObject)& theObject) const;
174
175   //! Returns the default builder used to construct BVH of entity set.
176   const Handle(Select3D_BVHBuilder3d) EntitySetBuilder() { return myEntitySetBuilder; }
177
178   //! Sets the default builder used to construct BVH of entity set.
179   //! The new builder will be also assigned for already defined objects, but computed BVH trees will not be invalidated.
180   Standard_EXPORT void SetEntitySetBuilder (const Handle(Select3D_BVHBuilder3d)& theBuilder);
181
182   //! Returns the list of selection modes ModeList found in
183   //! this selector for the selectable object aSelectableObject.
184   //! Returns true if aSelectableObject is referenced inside
185   //! this selector; returns false if the object is not present
186   //! in this selector.
187   Standard_EXPORT Standard_Boolean Modes (const Handle(SelectMgr_SelectableObject)& theSelectableObject,
188                                           TColStd_ListOfInteger& theModeList,
189                                           const SelectMgr_StateOfSelection theWantedState = SelectMgr_SOS_Any) const;
190
191   //! Returns true if the selectable object
192   //! aSelectableObject having the selection mode aMode
193   //! is active in this selector.
194   Standard_EXPORT Standard_Boolean IsActive (const Handle(SelectMgr_SelectableObject)& theSelectableObject,
195                                              const Standard_Integer theMode) const;
196
197   //! Returns true if the selectable object
198   //! aSelectableObject having the selection mode aMode
199   //! is in this selector.
200   Standard_EXPORT Standard_Boolean IsInside (const Handle(SelectMgr_SelectableObject)& theSelectableObject,
201                                              const Standard_Integer theMode) const;
202
203   //! Returns the selection status Status of the selection aSelection.
204   Standard_EXPORT SelectMgr_StateOfSelection Status (const Handle(SelectMgr_Selection)& theSelection) const;
205
206   Standard_EXPORT TCollection_AsciiString Status (const Handle(SelectMgr_SelectableObject)& theSelectableObject) const;
207
208   //! Returns the list of active entity owners
209   Standard_EXPORT void ActiveOwners (NCollection_List<Handle(SelectMgr_EntityOwner)>& theOwners) const;
210
211   //! Adds new object to the map of selectable objects
212   Standard_EXPORT void AddSelectableObject (const Handle(SelectMgr_SelectableObject)& theObject);
213
214   //! Adds new selection to the object and builds its BVH tree
215   Standard_EXPORT void AddSelectionToObject (const Handle(SelectMgr_SelectableObject)& theObject,
216                                              const Handle(SelectMgr_Selection)& theSelection);
217
218   //! Moves existing object from set of not transform persistence objects
219   //! to set of transform persistence objects (or vice versa).
220   Standard_EXPORT void MoveSelectableObject (const Handle(SelectMgr_SelectableObject)& theObject);
221
222   //! Removes selectable object from map of selectable ones
223   Standard_EXPORT void RemoveSelectableObject (const Handle(SelectMgr_SelectableObject)& theObject);
224
225   //! Removes selection of the object and marks its BVH tree for rebuild
226   Standard_EXPORT void RemoveSelectionOfObject (const Handle(SelectMgr_SelectableObject)& theObject,
227                                                 const Handle(SelectMgr_Selection)& theSelection);
228
229   //! Marks BVH of selectable objects for rebuild. Parameter theIsForce set as true
230   //! guarantees that 1st level BVH for the viewer selector will be rebuilt during this call
231   Standard_EXPORT void RebuildObjectsTree (const Standard_Boolean theIsForce = Standard_False);
232
233   //! Marks BVH of sensitive entities of particular selectable object for rebuild. Parameter
234   //! theIsForce set as true guarantees that 2nd level BVH for the object given will be
235   //! rebuilt during this call
236   Standard_EXPORT void RebuildSensitivesTree (const Handle(SelectMgr_SelectableObject)& theObject,
237                                               const Standard_Boolean theIsForce = Standard_False);
238
239   //! Returns instance of selecting volume manager of the viewer selector
240   SelectMgr_SelectingVolumeManager& GetManager() { return mySelectingVolumeMgr; }
241
242   //! Return map of selectable objects.
243   const SelectMgr_SelectableObjectSet& SelectableObjects() const { return mySelectableObjects; }
244
245   //! Marks all added sensitive entities of all objects as non-selectable
246   Standard_EXPORT void ResetSelectionActivationStatus();
247
248   //! Is used for rectangular selection only
249   //! If theIsToAllow is false, only fully included sensitives will be detected, otherwise the algorithm will
250   //! mark both included and overlapped entities as matched
251   Standard_EXPORT void AllowOverlapDetection (const Standard_Boolean theIsToAllow);
252
253 public:
254
255   //! Picks the sensitive entity at the pixel coordinates of
256   //! the mouse <theXPix> and <theYPix>. The selector looks for touched areas and owners.
257   Standard_EXPORT void Pick (const Standard_Integer theXPix,
258                              const Standard_Integer theYPix,
259                              const Handle(V3d_View)& theView);
260
261   //! Picks the sensitive entity according to the minimum
262   //! and maximum pixel values <theXPMin>, <theYPMin>, <theXPMax>
263   //! and <theYPMax> defining a 2D area for selection in the 3D view aView.
264   Standard_EXPORT void Pick (const Standard_Integer theXPMin,
265                              const Standard_Integer theYPMin,
266                              const Standard_Integer theXPMax,
267                              const Standard_Integer theYPMax,
268                              const Handle(V3d_View)& theView);
269
270   //! pick action - input pixel values for polyline selection for selection.
271   Standard_EXPORT void Pick (const TColgp_Array1OfPnt2d& thePolyline,
272                              const Handle(V3d_View)& theView);
273
274   //! Picks the sensitive entity according to the input axis.
275   //! This is geometric intersection 3D objects by axis
276   //! (camera parameters are ignored and objects with transform persistance are skipped).
277   Standard_EXPORT void Pick (const gp_Ax1& theAxis,
278                              const Handle(V3d_View)& theView);
279
280   //! Dump of detection results into image.
281   //! This method performs axis picking for each pixel in the image
282   //! and generates a color depending on picking results and selection image type.
283   //! @param theImage       result image, should be initialized
284   //! @param theView        3D view defining camera position
285   //! @param theType        type of image to define
286   //! @param thePickedIndex index of picked entity (1 means topmost)
287   Standard_EXPORT Standard_Boolean ToPixMap (Image_PixMap&                        theImage,
288                                              const Handle(V3d_View)&              theView,
289                                              const StdSelect_TypeOfSelectionImage theType,
290                                              const Standard_Integer               thePickedIndex = 1);
291
292 public:
293
294   //! Displays sensitives in view <theView>.
295   Standard_EXPORT void DisplaySensitive (const Handle(V3d_View)& theView);
296
297   Standard_EXPORT void ClearSensitive (const Handle(V3d_View)& theView);
298
299   Standard_EXPORT void DisplaySensitive (const Handle(SelectMgr_Selection)& theSel,
300                                          const gp_Trsf& theTrsf,
301                                          const Handle(V3d_View)& theView,
302                                          const Standard_Boolean theToClearOthers = Standard_True);
303
304   //! Dumps the content of me into the stream
305   Standard_EXPORT void DumpJson (Standard_OStream& theOStream, Standard_Integer theDepth = -1) const;
306
307 public:
308
309   //! Enables/disables building BVH for sensitives in separate threads
310   Standard_EXPORT void SetToPrebuildBVH(Standard_Boolean theToPrebuild, Standard_Integer theThreadsNum = -1);
311
312   //! Queues a sensitive entity to build its BVH
313   Standard_EXPORT void QueueBVHBuild(const Handle(Select3D_SensitiveEntity)& theEntity);
314
315   //! Waits BVH threads finished building
316   Standard_EXPORT void WaitForBVHBuild();
317
318   //! Returns TRUE if building BVH for sensitives in separate threads is enabled
319   Standard_Boolean ToPrebuildBVH() const
320   {
321     return myToPrebuildBVH;
322   }
323
324 protected:
325
326   //! Traverses BVH containing all added selectable objects and
327   //! finds candidates for further search of overlap
328   Standard_EXPORT void TraverseSensitives (const Standard_Integer theViewId = -1);
329
330   //! Internal function that checks if there is possible overlap between some entity of selectable object theObject and
331   //! current selecting volume.
332   //! @param theObject [in] the selectable object for traversal.
333   //! @param theMgr [in] the (un)transformed copy of the selecting volume manager representing active selection frustum.
334   //! @param theCamera, theProjectionMat, theWorldViewMat [in] the source camera and matrices for theMgr given.
335   //! @param theViewportWidth, theViewportHeight [in] viewport (window) dimensions for evaluating 
336   //!        object's transformation persistence.
337   Standard_EXPORT void traverseObject (const Handle(SelectMgr_SelectableObject)& theObject,
338                                        const SelectMgr_SelectingVolumeManager& theMgr,
339                                        const Handle(Graphic3d_Camera)& theCamera,
340                                        const Graphic3d_Mat4d& theProjectionMat,
341                                        const Graphic3d_Mat4d& theWorldViewMat,
342                                        const Graphic3d_Vec2i& theWinSize);
343
344   //! Internal function that checks if a particular sensitive
345   //! entity theEntity overlaps current selecting volume precisely
346   Standard_EXPORT void checkOverlap (const Handle(Select3D_SensitiveEntity)& theEntity,
347                                      const gp_GTrsf& theInversedTrsf,
348                                      SelectMgr_SelectingVolumeManager& theMgr);
349
350   //! Update z-layers order map.
351   Standard_EXPORT void updateZLayers (const Handle(V3d_View)& theView);
352
353 private:
354
355   //! Checks if the entity given requires to scale current selecting frustum
356   Standard_Boolean isToScaleFrustum (const Handle(Select3D_SensitiveEntity)& theEntity);
357
358   //! In case if custom tolerance is set, this method will return sum of entity sensitivity and
359   //! custom tolerance. Otherwise, pure entity sensitivity factor will be returned.
360   Standard_Integer sensitivity (const Handle(Select3D_SensitiveEntity)& theEntity) const;
361
362   void Activate (const Handle(SelectMgr_Selection)& theSelection);
363
364   void Deactivate (const Handle(SelectMgr_Selection)& theSelection);
365
366   //! removes a Selection from the Selector
367   void Remove (const Handle(SelectMgr_Selection)& aSelection);
368
369   //! Internal function that checks if a current selecting frustum needs to be scaled and transformed for the entity and performs necessary calculations.
370   void computeFrustum (const Handle(Select3D_SensitiveEntity)& theEnt,
371                        const SelectMgr_SelectingVolumeManager& theMgrGlobal,
372                        const SelectMgr_SelectingVolumeManager& theMgrObject,
373                        const gp_GTrsf& theInvTrsf,
374                        SelectMgr_FrustumCache& theCachedMgrs,
375                        SelectMgr_SelectingVolumeManager& theResMgr);
376
377
378 private:
379
380   //! Compute 3d position for detected entity.
381   void updatePoint3d (SelectMgr_SortCriterion& theCriterion,
382                       const SelectBasics_PickResult& thePickResult,
383                       const Handle(Select3D_SensitiveEntity)& theEntity,
384                       const gp_GTrsf& theInversedTrsf,
385                       const SelectMgr_SelectingVolumeManager& theMgr) const;
386
387 protected:
388
389   Standard_Real                                 myDepthTolerance;
390   SelectMgr_TypeOfDepthTolerance                myDepthTolType;
391   Standard_Boolean                              myToPreferClosest;
392   SelectMgr_IndexedDataMapOfOwnerCriterion      mystored;
393   SelectMgr_SelectingVolumeManager              mySelectingVolumeMgr;
394   mutable SelectMgr_SelectableObjectSet         mySelectableObjects;
395   SelectMgr_ToleranceMap                        myTolerances;
396   NCollection_DataMap<Graphic3d_ZLayerId, Standard_Integer> myZLayerOrderMap;
397   Handle(Select3D_BVHBuilder3d)                 myEntitySetBuilder;
398   gp_Pnt                                        myCameraEye;
399   gp_Dir                                        myCameraDir;
400   Standard_Real                                 myCameraScale;
401
402   Standard_Boolean                              myToPrebuildBVH;
403   Handle(SelectMgr_BVHThreadPool)               myBVHThreadPool;
404
405   mutable TColStd_Array1OfInteger              myIndexes;
406   mutable Standard_Boolean                     myIsSorted;
407   Standard_Boolean                             myIsLeftChildQueuedFirst;
408   SelectMgr_MapOfObjectSensitives              myMapOfObjectSensitives;
409
410   Graphic3d_SequenceOfStructure                myStructs; //!< list of debug presentations
411
412 };
413
414 DEFINE_STANDARD_HANDLE(SelectMgr_ViewerSelector, Standard_Transient)
415
416 #endif