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