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 <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>
40 class SelectMgr_SensitiveEntitySet;
41 class SelectMgr_EntityOwner;
42 class Select3D_SensitiveEntity;
45 // resolve name collisions with X11 headers
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;
52 typedef NCollection_DataMap<Standard_Integer, SelectMgr_SelectingVolumeManager> SelectMgr_FrustumCache;
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
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.
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
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
86 DEFINE_STANDARD_RTTIEXT(SelectMgr_ViewerSelector, Standard_Transient)
87 friend class SelectMgr_SelectionManager;
90 //! Constructs an empty selector object.
91 Standard_EXPORT SelectMgr_ViewerSelector();
93 //! Returns custom pixel tolerance value.
94 Standard_Integer CustomPixelTolerance() const { return myTolerances.CustomTolerance(); }
96 //! Sets the pixel tolerance <theTolerance>.
97 Standard_EXPORT void SetPixelTolerance (const Standard_Integer theTolerance);
99 //! Returns the largest sensitivity of picking
100 Standard_Real Sensitivity() const { return myTolerances.Tolerance(); }
102 //! Returns the largest pixel tolerance.
103 Standard_Integer PixelTolerance() const { return myTolerances.Tolerance(); }
105 //! Sorts the detected entities by priority and distance.
106 Standard_EXPORT virtual void SortResult() const;
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
112 return mystored.IsEmpty()
113 ? Handle(SelectMgr_EntityOwner)()
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; }
122 //! Set flag determining precedence of picked depth over entity priority in sorted results.
123 void SetPickClosest (bool theToPreferClosest) { myToPreferClosest = theToPreferClosest; }
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; }
129 //! Return the tolerance for considering two entities having a similar depth (distance from eye to entity).
130 Standard_Real DepthTolerance() const { return myDepthTolerance; }
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)
140 myDepthTolType = theType;
141 myDepthTolerance = theTolerance;
144 //! Returns the number of detected owners.
145 Standard_Integer NbPicked() const { return mystored.Extent(); }
147 //! Clears picking results.
148 Standard_EXPORT void ClearPicked();
150 //! Empties all the tables, removes all selections...
151 void Clear() { ClearPicked(); }
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;
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;
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; }
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; }
170 //! Remove picked entities associated with specified object.
171 Standard_EXPORT Standard_Boolean RemovePicked (const Handle(SelectMgr_SelectableObject)& theObject);
173 Standard_EXPORT Standard_Boolean Contains (const Handle(SelectMgr_SelectableObject)& theObject) const;
175 //! Returns the default builder used to construct BVH of entity set.
176 const Handle(Select3D_BVHBuilder3d) EntitySetBuilder() { return myEntitySetBuilder; }
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);
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;
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;
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;
203 //! Returns the selection status Status of the selection aSelection.
204 Standard_EXPORT SelectMgr_StateOfSelection Status (const Handle(SelectMgr_Selection)& theSelection) const;
206 Standard_EXPORT TCollection_AsciiString Status (const Handle(SelectMgr_SelectableObject)& theSelectableObject) const;
208 //! Returns the list of active entity owners
209 Standard_EXPORT void ActiveOwners (NCollection_List<Handle(SelectMgr_EntityOwner)>& theOwners) const;
211 //! Adds new object to the map of selectable objects
212 Standard_EXPORT void AddSelectableObject (const Handle(SelectMgr_SelectableObject)& theObject);
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);
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);
222 //! Removes selectable object from map of selectable ones
223 Standard_EXPORT void RemoveSelectableObject (const Handle(SelectMgr_SelectableObject)& theObject);
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);
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);
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);
239 //! Returns instance of selecting volume manager of the viewer selector
240 SelectMgr_SelectingVolumeManager& GetManager() { return mySelectingVolumeMgr; }
242 //! Return map of selectable objects.
243 const SelectMgr_SelectableObjectSet& SelectableObjects() const { return mySelectableObjects; }
245 //! Marks all added sensitive entities of all objects as non-selectable
246 Standard_EXPORT void ResetSelectionActivationStatus();
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);
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);
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);
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);
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);
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);
294 //! Displays sensitives in view <theView>.
295 Standard_EXPORT void DisplaySensitive (const Handle(V3d_View)& theView);
297 Standard_EXPORT void ClearSensitive (const Handle(V3d_View)& theView);
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);
304 //! Dumps the content of me into the stream
305 Standard_EXPORT void DumpJson (Standard_OStream& theOStream, Standard_Integer theDepth = -1) const;
309 //! Enables/disables building BVH for sensitives in separate threads
310 Standard_EXPORT void SetToPrebuildBVH(Standard_Boolean theToPrebuild, Standard_Integer theThreadsNum = -1);
312 //! Queues a sensitive entity to build its BVH
313 Standard_EXPORT void QueueBVHBuild(const Handle(Select3D_SensitiveEntity)& theEntity);
315 //! Waits BVH threads finished building
316 Standard_EXPORT void WaitForBVHBuild();
318 //! Returns TRUE if building BVH for sensitives in separate threads is enabled
319 Standard_Boolean ToPrebuildBVH() const
321 return myToPrebuildBVH;
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);
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);
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);
350 //! Update z-layers order map.
351 Standard_EXPORT void updateZLayers (const Handle(V3d_View)& theView);
355 //! Checks if the entity given requires to scale current selecting frustum
356 Standard_Boolean isToScaleFrustum (const Handle(Select3D_SensitiveEntity)& theEntity);
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;
362 void Activate (const Handle(SelectMgr_Selection)& theSelection);
364 void Deactivate (const Handle(SelectMgr_Selection)& theSelection);
366 //! removes a Selection from the Selector
367 void Remove (const Handle(SelectMgr_Selection)& aSelection);
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);
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;
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;
400 Standard_Real myCameraScale;
402 Standard_Boolean myToPrebuildBVH;
403 Handle(SelectMgr_BVHThreadPool) myBVHThreadPool;
405 mutable TColStd_Array1OfInteger myIndexes;
406 mutable Standard_Boolean myIsSorted;
407 Standard_Boolean myIsLeftChildQueuedFirst;
408 SelectMgr_MapOfObjectSensitives myMapOfObjectSensitives;
410 Graphic3d_SequenceOfStructure myStructs; //!< list of debug presentations
414 DEFINE_STANDARD_HANDLE(SelectMgr_ViewerSelector, Standard_Transient)