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