Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-06-03 08:36:44

0001 // Created on: 1995-02-15
0002 // Created by: Roberc Coublanc
0003 // Copyright (c) 1995-1999 Matra Datavision
0004 // Copyright (c) 1999-2014 OPEN CASCADE SAS
0005 //
0006 // This file is part of Open CASCADE Technology software library.
0007 //
0008 // This library is free software; you can redistribute it and/or modify it under
0009 // the terms of the GNU Lesser General Public License version 2.1 as published
0010 // by the Free Software Foundation, with special exception defined in the file
0011 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
0012 // distribution for complete text of the license and disclaimer of any warranty.
0013 //
0014 // Alternatively, this file may be used under the terms of Open CASCADE
0015 // commercial license or contractual agreement.
0016 
0017 #ifndef _SelectMgr_ViewerSelector_HeaderFile
0018 #define _SelectMgr_ViewerSelector_HeaderFile
0019 
0020 #include <OSD_Chronometer.hxx>
0021 #include <SelectMgr_BVHThreadPool.hxx>
0022 #include <SelectMgr_IndexedDataMapOfOwnerCriterion.hxx>
0023 #include <SelectMgr_SelectingVolumeManager.hxx>
0024 #include <SelectMgr_Selection.hxx>
0025 #include <SelectMgr_SelectableObject.hxx>
0026 #include <SelectMgr_SelectableObjectSet.hxx>
0027 #include <SelectMgr_StateOfSelection.hxx>
0028 #include <SelectMgr_ToleranceMap.hxx>
0029 #include <SelectMgr_TypeOfDepthTolerance.hxx>
0030 #include <SelectMgr_ViewerSelector.hxx>
0031 #include <Standard_OStream.hxx>
0032 #include <Standard_Transient.hxx>
0033 #include <StdSelect_TypeOfSelectionImage.hxx>
0034 #include <TColStd_HArray1OfInteger.hxx>
0035 
0036 class SelectMgr_SensitiveEntitySet;
0037 class SelectMgr_EntityOwner;
0038 class Select3D_SensitiveEntity;
0039 class V3d_View;
0040 
0041 // resolve name collisions with X11 headers
0042 #ifdef Status
0043   #undef Status
0044 #endif
0045 typedef NCollection_DataMap<Handle(SelectMgr_SelectableObject),
0046                             Handle(SelectMgr_SensitiveEntitySet)>
0047   SelectMgr_MapOfObjectSensitives;
0048 typedef NCollection_DataMap<Handle(SelectMgr_SelectableObject),
0049                             Handle(SelectMgr_SensitiveEntitySet)>::Iterator
0050   SelectMgr_MapOfObjectSensitivesIterator;
0051 
0052 typedef NCollection_DataMap<Standard_Integer, SelectMgr_SelectingVolumeManager>
0053   SelectMgr_FrustumCache;
0054 
0055 //! A framework to define finding, sorting the sensitive
0056 //! primitives in a view. Services are also provided to
0057 //! define the return of the owners of those primitives
0058 //! selected. The primitives are sorted by criteria such
0059 //! as priority of the primitive or its depth in the view
0060 //! relative to that of other primitives.
0061 //! Note that in 3D, the inheriting framework
0062 //! StdSelect_ViewerSelector3d   is only to be used
0063 //! if you do not want to use the services provided by
0064 //! AIS.
0065 //! Two tools are available to find and select objects
0066 //! found at a given position in the view. If you want to
0067 //! select the owners of all the objects detected at
0068 //! point x,y,z you use the Init - More - Next - Picked
0069 //! loop. If, on the other hand, you want to select only
0070 //! one object detected at that point, you use the Init -
0071 //! More - OnePicked loop. In this iteration, More is
0072 //! used to see if an object was picked and
0073 //! OnePicked, to get the object closest to the pick position.
0074 //! Viewer selectors are driven by
0075 //! SelectMgr_SelectionManager, and manipulate
0076 //! the SelectMgr_Selection objects given to them by
0077 //! the selection manager.
0078 //!
0079 //! Tolerances are applied to the entities in the following way:
0080 //! 1. tolerance value stored in mytolerance will be used to calculate initial
0081 //!    selecting frustum, which will be applied for intersection testing during
0082 //!    BVH traverse;
0083 //! 2. if tolerance of sensitive entity is less than mytolerance, the frustum for
0084 //!    intersection detection will be resized according to its sensitivity.
0085 class SelectMgr_ViewerSelector : public Standard_Transient
0086 {
0087   DEFINE_STANDARD_RTTIEXT(SelectMgr_ViewerSelector, Standard_Transient)
0088   friend class SelectMgr_SelectionManager;
0089 
0090 public:
0091   //! Constructs an empty selector object.
0092   Standard_EXPORT SelectMgr_ViewerSelector();
0093 
0094   //! Returns custom pixel tolerance value.
0095   Standard_Integer CustomPixelTolerance() const { return myTolerances.CustomTolerance(); }
0096 
0097   //! Sets the pixel tolerance <theTolerance>.
0098   Standard_EXPORT void SetPixelTolerance(const Standard_Integer theTolerance);
0099 
0100   //! Returns the largest sensitivity of picking
0101   Standard_Real Sensitivity() const { return myTolerances.Tolerance(); }
0102 
0103   //! Returns the largest pixel tolerance.
0104   Standard_Integer PixelTolerance() const { return myTolerances.Tolerance(); }
0105 
0106   //! Sorts the detected entities by priority and distance.
0107   Standard_EXPORT virtual void SortResult() const;
0108 
0109   //! Returns the picked element with the highest priority,
0110   //! and which is the closest to the last successful mouse position.
0111   Handle(SelectMgr_EntityOwner) OnePicked() const
0112   {
0113     return mystored.IsEmpty() ? Handle(SelectMgr_EntityOwner)() : Picked(1);
0114   }
0115 
0116   //! Return the flag determining precedence of picked depth (distance from eye to entity) over
0117   //! entity priority in sorted results; TRUE by default. When flag is TRUE, priority will be
0118   //! considered only if entities have the same depth  within the tolerance. When flag is FALSE,
0119   //! entities with higher priority will be in front regardless of their depth (like x-ray).
0120   bool ToPickClosest() const { return myToPreferClosest; }
0121 
0122   //! Set flag determining precedence of picked depth over entity priority in sorted results.
0123   void SetPickClosest(bool theToPreferClosest) { myToPreferClosest = theToPreferClosest; }
0124 
0125   //! Return the type of tolerance for considering two entities having a similar depth (distance
0126   //! from eye to entity); SelectMgr_TypeOfDepthTolerance_SensitivityFactor by default.
0127   SelectMgr_TypeOfDepthTolerance DepthToleranceType() const { return myDepthTolType; }
0128 
0129   //! Return the tolerance for considering two entities having a similar depth (distance from eye to
0130   //! entity).
0131   Standard_Real DepthTolerance() const { return myDepthTolerance; }
0132 
0133   //! Set the tolerance for considering two entities having a similar depth (distance from eye to
0134   //! entity).
0135   //! @param[in] theType  type of tolerance value
0136   //! @param[in] theTolerance  tolerance value in 3D scale (SelectMgr_TypeOfDepthTolerance_Uniform)
0137   //!                          or in pixels (SelectMgr_TypeOfDepthTolerance_UniformPixels);
0138   //!                          value is ignored in case of
0139   //!                          SelectMgr_TypeOfDepthTolerance_SensitivityFactor
0140   void SetDepthTolerance(SelectMgr_TypeOfDepthTolerance theType, Standard_Real theTolerance)
0141   {
0142     myDepthTolType   = theType;
0143     myDepthTolerance = theTolerance;
0144   }
0145 
0146   //! Returns the number of detected owners.
0147   Standard_Integer NbPicked() const { return mystored.Extent(); }
0148 
0149   //! Clears picking results.
0150   Standard_EXPORT void ClearPicked();
0151 
0152   //! Empties all the tables, removes all selections...
0153   void Clear() { ClearPicked(); }
0154 
0155   //! Returns the entity Owner for the object picked at specified position.
0156   //! @param theRank rank of detected object within range 1...NbPicked()
0157   Standard_EXPORT Handle(SelectMgr_EntityOwner) Picked(const Standard_Integer theRank) const;
0158 
0159   //! Returns the Entity for the object picked at specified position.
0160   //! @param theRank rank of detected object within range 1...NbPicked()
0161   Standard_EXPORT const SelectMgr_SortCriterion& PickedData(const Standard_Integer theRank) const;
0162 
0163   //! Returns the Entity for the object picked at specified position.
0164   //! @param theRank rank of detected object within range 1...NbPicked()
0165   const Handle(Select3D_SensitiveEntity)& PickedEntity(const Standard_Integer theRank) const
0166   {
0167     return PickedData(theRank).Entity;
0168   }
0169 
0170   //! Returns the 3D point (intersection of picking axis with the object nearest to eye)
0171   //! for the object picked at specified position.
0172   //! @param theRank rank of detected object within range 1...NbPicked()
0173   gp_Pnt PickedPoint(const Standard_Integer theRank) const { return PickedData(theRank).Point; }
0174 
0175   //! Remove picked entities associated with specified object.
0176   Standard_EXPORT Standard_Boolean
0177     RemovePicked(const Handle(SelectMgr_SelectableObject)& theObject);
0178 
0179   Standard_EXPORT Standard_Boolean
0180     Contains(const Handle(SelectMgr_SelectableObject)& theObject) const;
0181 
0182   //! Returns the default builder used to construct BVH of entity set.
0183   const Handle(Select3D_BVHBuilder3d) EntitySetBuilder() { return myEntitySetBuilder; }
0184 
0185   //! Sets the default builder used to construct BVH of entity set.
0186   //! The new builder will be also assigned for already defined objects, but computed BVH trees will
0187   //! not be invalidated.
0188   Standard_EXPORT void SetEntitySetBuilder(const Handle(Select3D_BVHBuilder3d)& theBuilder);
0189 
0190   //! Returns the list of selection modes ModeList found in
0191   //! this selector for the selectable object aSelectableObject.
0192   //! Returns true if aSelectableObject is referenced inside
0193   //! this selector; returns false if the object is not present
0194   //! in this selector.
0195   Standard_EXPORT Standard_Boolean
0196     Modes(const Handle(SelectMgr_SelectableObject)& theSelectableObject,
0197           TColStd_ListOfInteger&                    theModeList,
0198           const SelectMgr_StateOfSelection          theWantedState = SelectMgr_SOS_Any) const;
0199 
0200   //! Returns true if the selectable object
0201   //! aSelectableObject having the selection mode aMode
0202   //! is active in this selector.
0203   Standard_EXPORT Standard_Boolean
0204     IsActive(const Handle(SelectMgr_SelectableObject)& theSelectableObject,
0205              const Standard_Integer                    theMode) const;
0206 
0207   //! Returns true if the selectable object
0208   //! aSelectableObject having the selection mode aMode
0209   //! is in this selector.
0210   Standard_EXPORT Standard_Boolean
0211     IsInside(const Handle(SelectMgr_SelectableObject)& theSelectableObject,
0212              const Standard_Integer                    theMode) const;
0213 
0214   //! Returns the selection status Status of the selection aSelection.
0215   Standard_EXPORT SelectMgr_StateOfSelection
0216     Status(const Handle(SelectMgr_Selection)& theSelection) const;
0217 
0218   Standard_EXPORT TCollection_AsciiString
0219     Status(const Handle(SelectMgr_SelectableObject)& theSelectableObject) const;
0220 
0221   //! Returns the list of active entity owners
0222   Standard_EXPORT void ActiveOwners(
0223     NCollection_List<Handle(SelectMgr_EntityOwner)>& theOwners) const;
0224 
0225   //! Adds new object to the map of selectable objects
0226   Standard_EXPORT void AddSelectableObject(const Handle(SelectMgr_SelectableObject)& theObject);
0227 
0228   //! Adds new selection to the object and builds its BVH tree
0229   Standard_EXPORT void AddSelectionToObject(const Handle(SelectMgr_SelectableObject)& theObject,
0230                                             const Handle(SelectMgr_Selection)&        theSelection);
0231 
0232   //! Moves existing object from set of not transform persistence objects
0233   //! to set of transform persistence objects (or vice versa).
0234   Standard_EXPORT void MoveSelectableObject(const Handle(SelectMgr_SelectableObject)& theObject);
0235 
0236   //! Removes selectable object from map of selectable ones
0237   Standard_EXPORT void RemoveSelectableObject(const Handle(SelectMgr_SelectableObject)& theObject);
0238 
0239   //! Removes selection of the object and marks its BVH tree for rebuild
0240   Standard_EXPORT void RemoveSelectionOfObject(const Handle(SelectMgr_SelectableObject)& theObject,
0241                                                const Handle(SelectMgr_Selection)& theSelection);
0242 
0243   //! Marks BVH of selectable objects for rebuild. Parameter theIsForce set as true
0244   //! guarantees that 1st level BVH for the viewer selector will be rebuilt during this call
0245   Standard_EXPORT void RebuildObjectsTree(const Standard_Boolean theIsForce = Standard_False);
0246 
0247   //! Marks BVH of sensitive entities of particular selectable object for rebuild. Parameter
0248   //! theIsForce set as true guarantees that 2nd level BVH for the object given will be
0249   //! rebuilt during this call
0250   Standard_EXPORT void RebuildSensitivesTree(const Handle(SelectMgr_SelectableObject)& theObject,
0251                                              const Standard_Boolean theIsForce = Standard_False);
0252 
0253   //! Returns instance of selecting volume manager of the viewer selector
0254   SelectMgr_SelectingVolumeManager& GetManager() { return mySelectingVolumeMgr; }
0255 
0256   //! Return map of selectable objects.
0257   const SelectMgr_SelectableObjectSet& SelectableObjects() const { return mySelectableObjects; }
0258 
0259   //! Marks all added sensitive entities of all objects as non-selectable
0260   Standard_EXPORT void ResetSelectionActivationStatus();
0261 
0262   //! Is used for rectangular selection only
0263   //! If theIsToAllow is false, only fully included sensitives will be detected, otherwise the
0264   //! algorithm will mark both included and overlapped entities as matched
0265   Standard_EXPORT void AllowOverlapDetection(const Standard_Boolean theIsToAllow);
0266 
0267 public:
0268   //! Picks the sensitive entity at the pixel coordinates of
0269   //! the mouse <theXPix> and <theYPix>. The selector looks for touched areas and owners.
0270   Standard_EXPORT void Pick(const Standard_Integer  theXPix,
0271                             const Standard_Integer  theYPix,
0272                             const Handle(V3d_View)& theView);
0273 
0274   //! Picks the sensitive entity according to the minimum
0275   //! and maximum pixel values <theXPMin>, <theYPMin>, <theXPMax>
0276   //! and <theYPMax> defining a 2D area for selection in the 3D view aView.
0277   Standard_EXPORT void Pick(const Standard_Integer  theXPMin,
0278                             const Standard_Integer  theYPMin,
0279                             const Standard_Integer  theXPMax,
0280                             const Standard_Integer  theYPMax,
0281                             const Handle(V3d_View)& theView);
0282 
0283   //! pick action - input pixel values for polyline selection for selection.
0284   Standard_EXPORT void Pick(const TColgp_Array1OfPnt2d& thePolyline,
0285                             const Handle(V3d_View)&     theView);
0286 
0287   //! Picks the sensitive entity according to the input axis.
0288   //! This is geometric intersection 3D objects by axis
0289   //! (camera parameters are ignored and objects with transform persistence are skipped).
0290   Standard_EXPORT void Pick(const gp_Ax1& theAxis, const Handle(V3d_View)& theView);
0291 
0292   //! Dump of detection results into image.
0293   //! This method performs axis picking for each pixel in the image
0294   //! and generates a color depending on picking results and selection image type.
0295   //! @param theImage       result image, should be initialized
0296   //! @param theView        3D view defining camera position
0297   //! @param theType        type of image to define
0298   //! @param thePickedIndex index of picked entity (1 means topmost)
0299   Standard_EXPORT Standard_Boolean ToPixMap(Image_PixMap&                        theImage,
0300                                             const Handle(V3d_View)&              theView,
0301                                             const StdSelect_TypeOfSelectionImage theType,
0302                                             const Standard_Integer thePickedIndex = 1);
0303 
0304 public:
0305   //! Displays sensitives in view <theView>.
0306   Standard_EXPORT void DisplaySensitive(const Handle(V3d_View)& theView);
0307 
0308   Standard_EXPORT void ClearSensitive(const Handle(V3d_View)& theView);
0309 
0310   Standard_EXPORT void DisplaySensitive(const Handle(SelectMgr_Selection)& theSel,
0311                                         const gp_Trsf&                     theTrsf,
0312                                         const Handle(V3d_View)&            theView,
0313                                         const Standard_Boolean theToClearOthers = Standard_True);
0314 
0315   //! Dumps the content of me into the stream
0316   Standard_EXPORT void DumpJson(Standard_OStream& theOStream, Standard_Integer theDepth = -1) const;
0317 
0318 public:
0319   //! Enables/disables building BVH for sensitives in separate threads
0320   Standard_EXPORT void SetToPrebuildBVH(Standard_Boolean theToPrebuild,
0321                                         Standard_Integer theThreadsNum = -1);
0322 
0323   //! Queues a sensitive entity to build its BVH
0324   Standard_EXPORT void QueueBVHBuild(const Handle(Select3D_SensitiveEntity)& theEntity);
0325 
0326   //! Waits BVH threads finished building
0327   Standard_EXPORT void WaitForBVHBuild();
0328 
0329   //! Returns TRUE if building BVH for sensitives in separate threads is enabled
0330   Standard_Boolean ToPrebuildBVH() const { return myToPrebuildBVH; }
0331 
0332 protected:
0333   //! Traverses BVH containing all added selectable objects and
0334   //! finds candidates for further search of overlap
0335   Standard_EXPORT void TraverseSensitives(const Standard_Integer theViewId = -1);
0336 
0337   //! Internal function that checks if there is possible overlap between some entity of selectable
0338   //! object theObject and current selecting volume.
0339   //! @param[in] theObject  the selectable object for traversal.
0340   //! @param[in] theMgr  the (un)transformed copy of the selecting volume manager representing
0341   //! active selection frustum.
0342   //! @param theCamera, theProjectionMat, theWorldViewMat[in]  the source camera and matrices for
0343   //! theMgr given.
0344   //! @param[in] theWinSize  viewport (window) dimensions for evaluating
0345   //!        object's transformation persistence.
0346   Standard_EXPORT void traverseObject(const Handle(SelectMgr_SelectableObject)& theObject,
0347                                       const SelectMgr_SelectingVolumeManager&   theMgr,
0348                                       const Handle(Graphic3d_Camera)&           theCamera,
0349                                       const Graphic3d_Mat4d&                    theProjectionMat,
0350                                       const Graphic3d_Mat4d&                    theWorldViewMat,
0351                                       const Graphic3d_Vec2i&                    theWinSize);
0352 
0353   //! Internal function that checks if a particular sensitive
0354   //! entity theEntity overlaps current selecting volume precisely
0355   Standard_EXPORT void checkOverlap(const Handle(Select3D_SensitiveEntity)& theEntity,
0356                                     const gp_GTrsf&                         theInversedTrsf,
0357                                     SelectMgr_SelectingVolumeManager&       theMgr);
0358 
0359   //! Update z-layers order map.
0360   Standard_EXPORT void updateZLayers(const Handle(V3d_View)& theView);
0361 
0362 private:
0363   //! Checks if the entity given requires to scale current selecting frustum
0364   Standard_Boolean isToScaleFrustum(const Handle(Select3D_SensitiveEntity)& theEntity);
0365 
0366   //! In case if custom tolerance is set, this method will return sum of entity sensitivity and
0367   //! custom tolerance. Otherwise, pure entity sensitivity factor will be returned.
0368   Standard_Integer sensitivity(const Handle(Select3D_SensitiveEntity)& theEntity) const;
0369 
0370   void Activate(const Handle(SelectMgr_Selection)& theSelection);
0371 
0372   void Deactivate(const Handle(SelectMgr_Selection)& theSelection);
0373 
0374   //! removes a Selection from the Selector
0375   void Remove(const Handle(SelectMgr_Selection)& aSelection);
0376 
0377   //! Internal function that checks if a current selecting frustum needs to be scaled and
0378   //! transformed for the entity and performs necessary calculations.
0379   void computeFrustum(const Handle(Select3D_SensitiveEntity)& theEnt,
0380                       const SelectMgr_SelectingVolumeManager& theMgrGlobal,
0381                       const SelectMgr_SelectingVolumeManager& theMgrObject,
0382                       const gp_GTrsf&                         theInvTrsf,
0383                       SelectMgr_FrustumCache&                 theCachedMgrs,
0384                       SelectMgr_SelectingVolumeManager&       theResMgr);
0385 
0386 private:
0387   //! Compute 3d position for detected entity.
0388   void updatePoint3d(SelectMgr_SortCriterion&                theCriterion,
0389                      const SelectBasics_PickResult&          thePickResult,
0390                      const Handle(Select3D_SensitiveEntity)& theEntity,
0391                      const gp_GTrsf&                         theInversedTrsf,
0392                      const SelectMgr_SelectingVolumeManager& theMgr) const;
0393 
0394 protected:
0395   Standard_Real                                             myDepthTolerance;
0396   SelectMgr_TypeOfDepthTolerance                            myDepthTolType;
0397   Standard_Boolean                                          myToPreferClosest;
0398   SelectMgr_IndexedDataMapOfOwnerCriterion                  mystored;
0399   SelectMgr_SelectingVolumeManager                          mySelectingVolumeMgr;
0400   mutable SelectMgr_SelectableObjectSet                     mySelectableObjects;
0401   SelectMgr_ToleranceMap                                    myTolerances;
0402   NCollection_DataMap<Graphic3d_ZLayerId, Standard_Integer> myZLayerOrderMap;
0403   Handle(Select3D_BVHBuilder3d)                             myEntitySetBuilder;
0404   gp_Pnt                                                    myCameraEye;
0405   gp_Dir                                                    myCameraDir;
0406   Standard_Real                                             myCameraScale;
0407 
0408   Standard_Boolean                myToPrebuildBVH;
0409   Handle(SelectMgr_BVHThreadPool) myBVHThreadPool;
0410 
0411   mutable TColStd_Array1OfInteger myIndexes;
0412   mutable Standard_Boolean        myIsSorted;
0413   Standard_Boolean                myIsLeftChildQueuedFirst;
0414   SelectMgr_MapOfObjectSensitives myMapOfObjectSensitives;
0415 
0416   Graphic3d_SequenceOfStructure myStructs; //!< list of debug presentations
0417 };
0418 
0419 DEFINE_STANDARD_HANDLE(SelectMgr_ViewerSelector, Standard_Transient)
0420 
0421 #endif