Loading files
3d097a032This file is pinned to the selected release. Download the original to open it in your design tool.
// Created on: 1995-02-15
// Created by: Roberc Coublanc
// Copyright (c) 1995-1999 Matra Datavision
// Copyright (c) 1999-2014 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#ifndef _SelectMgr_ViewerSelector_HeaderFile
#define _SelectMgr_ViewerSelector_HeaderFile
#include <OSD_Chronometer.hxx>
#include <SelectMgr_BVHThreadPool.hxx>
#include <SelectMgr_EntityOwner.hxx>
#include <SelectMgr_SortCriterion.hxx>
#include <NCollection_IndexedDataMap.hxx>
#include <SelectMgr_SelectingVolumeManager.hxx>
#include <SelectMgr_Selection.hxx>
#include <SelectMgr_SelectableObject.hxx>
#include <SelectMgr_SelectableObjectSet.hxx>
#include <SelectMgr_StateOfSelection.hxx>
#include <SelectMgr_ToleranceMap.hxx>
#include <SelectMgr_TypeOfDepthTolerance.hxx>
#include <Standard_OStream.hxx>
#include <Standard_Transient.hxx>
#include <StdSelect_TypeOfSelectionImage.hxx>
#include <Standard_Integer.hxx>
#include <NCollection_Array1.hxx>
#include <NCollection_HArray1.hxx>
class SelectMgr_SensitiveEntitySet;
class SelectMgr_EntityOwner;
class Select3D_SensitiveEntity;
class V3d_View;
// resolve name collisions with X11 headers
#ifdef Status
#undef Status
#endif
//! A framework to define finding, sorting the sensitive
//! primitives in a view. Services are also provided to
//! define the return of the owners of those primitives
//! selected. The primitives are sorted by criteria such
//! as priority of the primitive or its depth in the view
//! relative to that of other primitives.
//! Note that in 3D, the inheriting framework
//! StdSelect_ViewerSelector3d is only to be used
//! if you do not want to use the services provided by
//! AIS.
//! Two tools are available to find and select objects
//! found at a given position in the view. If you want to
//! select the owners of all the objects detected at
//! point x,y,z you use the Init - More - Next - Picked
//! loop. If, on the other hand, you want to select only
//! one object detected at that point, you use the Init -
//! More - OnePicked loop. In this iteration, More is
//! used to see if an object was picked and
//! OnePicked, to get the object closest to the pick position.
//! Viewer selectors are driven by
//! SelectMgr_SelectionManager, and manipulate
//! the SelectMgr_Selection objects given to them by
//! the selection manager.
//!
//! Tolerances are applied to the entities in the following way:
//! 1. tolerance value stored in mytolerance will be used to calculate initial
//! selecting frustum, which will be applied for intersection testing during
//! BVH traverse;
//! 2. if tolerance of sensitive entity is less than mytolerance, the frustum for
//! intersection detection will be resized according to its sensitivity.
class SelectMgr_ViewerSelector : public Standard_Transient
{
DEFINE_STANDARD_RTTIEXT(SelectMgr_ViewerSelector, Standard_Transient)
friend class SelectMgr_SelectionManager;
public:
//! Constructs an empty selector object.
Standard_EXPORT SelectMgr_ViewerSelector();
//! Returns custom pixel tolerance value.
int CustomPixelTolerance() const { return myTolerances.CustomTolerance(); }
//! Sets the pixel tolerance <theTolerance>.
Standard_EXPORT void SetPixelTolerance(const int theTolerance);
//! Returns the largest sensitivity of picking
double Sensitivity() const { return myTolerances.Tolerance(); }
//! Returns the largest pixel tolerance.
int PixelTolerance() const { return myTolerances.Tolerance(); }
//! Sorts the detected entities by priority and distance.
Standard_EXPORT virtual void SortResult() const;
//! Returns the picked element with the highest priority,
//! and which is the closest to the last successful mouse position.
occ::handle<SelectMgr_EntityOwner> OnePicked() const
{
return mystored.IsEmpty() ? occ::handle<SelectMgr_EntityOwner>() : Picked(1);
}
//! Return the flag determining precedence of picked depth (distance from eye to entity) over
//! entity priority in sorted results; TRUE by default. When flag is TRUE, priority will be
//! considered only if entities have the same depth within the tolerance. When flag is FALSE,
//! entities with higher priority will be in front regardless of their depth (like x-ray).
bool ToPickClosest() const { return myToPreferClosest; }
//! Set flag determining precedence of picked depth over entity priority in sorted results.
void SetPickClosest(bool theToPreferClosest) { myToPreferClosest = theToPreferClosest; }
//! Return the type of tolerance for considering two entities having a similar depth (distance
//! from eye to entity); SelectMgr_TypeOfDepthTolerance_SensitivityFactor by default.
SelectMgr_TypeOfDepthTolerance DepthToleranceType() const { return myDepthTolType; }
//! Return the tolerance for considering two entities having a similar depth (distance from eye to
//! entity).
double DepthTolerance() const { return myDepthTolerance; }
//! Set the tolerance for considering two entities having a similar depth (distance from eye to
//! entity).
//! @param[in] theType type of tolerance value
//! @param[in] theTolerance tolerance value in 3D scale (SelectMgr_TypeOfDepthTolerance_Uniform)
//! or in pixels (SelectMgr_TypeOfDepthTolerance_UniformPixels);
//! value is ignored in case of
//! SelectMgr_TypeOfDepthTolerance_SensitivityFactor
void SetDepthTolerance(SelectMgr_TypeOfDepthTolerance theType, double theTolerance)
{
myDepthTolType = theType;
myDepthTolerance = theTolerance;
}
//! Returns the number of detected owners.
int NbPicked() const { return mystored.Extent(); }
//! Clears picking results.
Standard_EXPORT void ClearPicked();
//! Empties all the tables, removes all selections...
void Clear() { ClearPicked(); }
//! Returns the entity Owner for the object picked at specified position.
//! @param theRank rank of detected object within range 1...NbPicked()
Standard_EXPORT occ::handle<SelectMgr_EntityOwner> Picked(const int theRank) const;
//! Returns the Entity for the object picked at specified position.
//! @param theRank rank of detected object within range 1...NbPicked()
Standard_EXPORT const SelectMgr_SortCriterion& PickedData(const int theRank) const;
//! Returns the Entity for the object picked at specified position.
//! @param theRank rank of detected object within range 1...NbPicked()
const occ::handle<Select3D_SensitiveEntity>& PickedEntity(const int theRank) const
{
return PickedData(theRank).Entity;
}
//! Returns the 3D point (intersection of picking axis with the object nearest to eye)
//! for the object picked at specified position.
//! @param theRank rank of detected object within range 1...NbPicked()
gp_Pnt PickedPoint(const int theRank) const { return PickedData(theRank).Point; }
//! Remove picked entities associated with specified object.
Standard_EXPORT bool RemovePicked(const occ::handle<SelectMgr_SelectableObject>& theObject);
Standard_EXPORT bool Contains(const occ::handle<SelectMgr_SelectableObject>& theObject) const;
//! Returns the default builder used to construct BVH of entity set.
const occ::handle<Select3D_BVHBuilder3d> EntitySetBuilder() { return myEntitySetBuilder; }
//! Sets the default builder used to construct BVH of entity set.
//! The new builder will be also assigned for already defined objects, but computed BVH trees will
//! not be invalidated.
Standard_EXPORT void SetEntitySetBuilder(const occ::handle<Select3D_BVHBuilder3d>& theBuilder);
//! Returns the list of selection modes ModeList found in
//! this selector for the selectable object aSelectableObject.
//! Returns true if aSelectableObject is referenced inside
//! this selector; returns false if the object is not present
//! in this selector.
Standard_EXPORT bool Modes(
const occ::handle<SelectMgr_SelectableObject>& theSelectableObject,
NCollection_List<int>& theModeList,
const SelectMgr_StateOfSelection theWantedState = SelectMgr_SOS_Any) const;
//! Returns true if the selectable object
//! aSelectableObject having the selection mode aMode
//! is active in this selector.
Standard_EXPORT bool IsActive(const occ::handle<SelectMgr_SelectableObject>& theSelectableObject,
const int theMode) const;
//! Returns true if the selectable object
//! aSelectableObject having the selection mode aMode
//! is in this selector.
Standard_EXPORT bool IsInside(const occ::handle<SelectMgr_SelectableObject>& theSelectableObject,
const int theMode) const;
//! Returns the selection status Status of the selection aSelection.
Standard_EXPORT SelectMgr_StateOfSelection
Status(const occ::handle<SelectMgr_Selection>& theSelection) const;
Standard_EXPORT TCollection_AsciiString
Status(const occ::handle<SelectMgr_SelectableObject>& theSelectableObject) const;
//! Returns the list of active entity owners
Standard_EXPORT void ActiveOwners(
NCollection_List<occ::handle<SelectMgr_EntityOwner>>& theOwners) const;
//! Adds new object to the map of selectable objects
Standard_EXPORT void AddSelectableObject(
const occ::handle<SelectMgr_SelectableObject>& theObject);
//! Adds new selection to the object and builds its BVH tree
Standard_EXPORT void AddSelectionToObject(
const occ::handle<SelectMgr_SelectableObject>& theObject,
const occ::handle<SelectMgr_Selection>& theSelection);
//! Moves existing object from set of not transform persistence objects
//! to set of transform persistence objects (or vice versa).
Standard_EXPORT void MoveSelectableObject(
const occ::handle<SelectMgr_SelectableObject>& theObject);
//! Removes selectable object from map of selectable ones
Standard_EXPORT void RemoveSelectableObject(
const occ::handle<SelectMgr_SelectableObject>& theObject);
//! Removes selection of the object and marks its BVH tree for rebuild
Standard_EXPORT void RemoveSelectionOfObject(
const occ::handle<SelectMgr_SelectableObject>& theObject,
const occ::handle<SelectMgr_Selection>& theSelection);
//! Marks BVH of selectable objects for rebuild. Parameter theIsForce set as true
//! guarantees that 1st level BVH for the viewer selector will be rebuilt during this call
Standard_EXPORT void RebuildObjectsTree(const bool theIsForce = false);
//! Marks BVH of sensitive entities of particular selectable object for rebuild. Parameter
//! theIsForce set as true guarantees that 2nd level BVH for the object given will be
//! rebuilt during this call
Standard_EXPORT void RebuildSensitivesTree(
const occ::handle<SelectMgr_SelectableObject>& theObject,
const bool theIsForce = false);
//! Returns instance of selecting volume manager of the viewer selector
SelectMgr_SelectingVolumeManager& GetManager() { return mySelectingVolumeMgr; }
//! Return map of selectable objects.
const SelectMgr_SelectableObjectSet& SelectableObjects() const { return mySelectableObjects; }
//! Marks all added sensitive entities of all objects as non-selectable
Standard_EXPORT void ResetSelectionActivationStatus();
//! Is used for rectangular selection only
//! If theIsToAllow is false, only fully included sensitives will be detected, otherwise the
//! algorithm will mark both included and overlapped entities as matched
Standard_EXPORT void AllowOverlapDetection(const bool theIsToAllow);
public:
//! Picks the sensitive entity at the pixel coordinates of
//! the mouse <theXPix> and <theYPix>. The selector looks for touched areas and owners.
Standard_EXPORT void Pick(const int theXPix,
const int theYPix,
const occ::handle<V3d_View>& theView);
//! Picks the sensitive entity according to the minimum
//! and maximum pixel values <theXPMin>, <theYPMin>, <theXPMax>
//! and <theYPMax> defining a 2D area for selection in the 3D view aView.
Standard_EXPORT void Pick(const int theXPMin,
const int theYPMin,
const int theXPMax,
const int theYPMax,
const occ::handle<V3d_View>& theView);
//! pick action - input pixel values for polyline selection for selection.
Standard_EXPORT void Pick(const NCollection_Array1<gp_Pnt2d>& thePolyline,
const occ::handle<V3d_View>& theView);
//! Picks the sensitive entity according to the input axis.
//! This is geometric intersection 3D objects by axis
//! (camera parameters are ignored and objects with transform persistence are skipped).
Standard_EXPORT void Pick(const gp_Ax1& theAxis, const occ::handle<V3d_View>& theView);
//! Dump of detection results into image.
//! This method performs axis picking for each pixel in the image
//! and generates a color depending on picking results and selection image type.
//! @param theImage result image, should be initialized
//! @param theView 3D view defining camera position
//! @param theType type of image to define
//! @param thePickedIndex index of picked entity (1 means topmost)
Standard_EXPORT bool ToPixMap(Image_PixMap& theImage,
const occ::handle<V3d_View>& theView,
const StdSelect_TypeOfSelectionImage theType,
const int thePickedIndex = 1);
public:
//! Displays sensitives in view <theView>.
Standard_EXPORT void DisplaySensitive(const occ::handle<V3d_View>& theView);
Standard_EXPORT void ClearSensitive(const occ::handle<V3d_View>& theView);
Standard_EXPORT void DisplaySensitive(const occ::handle<SelectMgr_Selection>& theSel,
const gp_Trsf& theTrsf,
const occ::handle<V3d_View>& theView,
const bool theToClearOthers = true);
//! Dumps the content of me into the stream
Standard_EXPORT void DumpJson(Standard_OStream& theOStream, int theDepth = -1) const;
public:
//! Enables/disables building BVH for sensitives in separate threads
Standard_EXPORT void SetToPrebuildBVH(bool theToPrebuild, int theThreadsNum = -1);
//! Queues a sensitive entity to build its BVH
Standard_EXPORT void QueueBVHBuild(const occ::handle<Select3D_SensitiveEntity>& theEntity);
//! Waits BVH threads finished building
Standard_EXPORT void WaitForBVHBuild();
//! Returns TRUE if building BVH for sensitives in separate threads is enabled
bool ToPrebuildBVH() const { return myToPrebuildBVH; }
protected:
//! Traverses BVH containing all added selectable objects and
//! finds candidates for further search of overlap
Standard_EXPORT void TraverseSensitives(const int theViewId = -1);
//! Internal function that checks if there is possible overlap between some entity of selectable
//! object theObject and current selecting volume.
//! @param[in] theObject the selectable object for traversal.
//! @param[in] theMgr the (un)transformed copy of the selecting volume manager representing
//! active selection frustum.
//! @param theCamera, theProjectionMat, theWorldViewMat[in] the source camera and matrices for
//! theMgr given.
//! @param[in] theWinSize viewport (window) dimensions for evaluating
//! object's transformation persistence.
Standard_EXPORT void traverseObject(const occ::handle<SelectMgr_SelectableObject>& theObject,
const SelectMgr_SelectingVolumeManager& theMgr,
const occ::handle<Graphic3d_Camera>& theCamera,
const NCollection_Mat4<double>& theProjectionMat,
const NCollection_Mat4<double>& theWorldViewMat,
const NCollection_Vec2<int>& theWinSize);
//! Internal function that checks if a particular sensitive
//! entity theEntity overlaps current selecting volume precisely
Standard_EXPORT void checkOverlap(const occ::handle<Select3D_SensitiveEntity>& theEntity,
const gp_GTrsf& theInversedTrsf,
SelectMgr_SelectingVolumeManager& theMgr);
//! Update z-layers order map.
Standard_EXPORT void updateZLayers(const occ::handle<V3d_View>& theView);
private:
//! Checks if the entity given requires to scale current selecting frustum
bool isToScaleFrustum(const occ::handle<Select3D_SensitiveEntity>& theEntity);
//! In case if custom tolerance is set, this method will return sum of entity sensitivity and
//! custom tolerance. Otherwise, pure entity sensitivity factor will be returned.
int sensitivity(const occ::handle<Select3D_SensitiveEntity>& theEntity) const;
void Activate(const occ::handle<SelectMgr_Selection>& theSelection);
void Deactivate(const occ::handle<SelectMgr_Selection>& theSelection);
//! removes a Selection from the Selector
void Remove(const occ::handle<SelectMgr_Selection>& aSelection);
//! Internal function that checks if a current selecting frustum needs to be scaled and
//! transformed for the entity and performs necessary calculations.
void computeFrustum(const occ::handle<Select3D_SensitiveEntity>& theEnt,
const SelectMgr_SelectingVolumeManager& theMgrGlobal,
const SelectMgr_SelectingVolumeManager& theMgrObject,
const gp_GTrsf& theInvTrsf,
NCollection_DataMap<int, SelectMgr_SelectingVolumeManager>& theCachedMgrs,
SelectMgr_SelectingVolumeManager& theResMgr);
private:
//! Compute 3d position for detected entity.
void updatePoint3d(SelectMgr_SortCriterion& theCriterion,
const SelectBasics_PickResult& thePickResult,
const occ::handle<Select3D_SensitiveEntity>& theEntity,
const gp_GTrsf& theInversedTrsf,
const SelectMgr_SelectingVolumeManager& theMgr) const;
protected:
double myDepthTolerance;
SelectMgr_TypeOfDepthTolerance myDepthTolType;
bool myToPreferClosest;
NCollection_IndexedDataMap<occ::handle<SelectMgr_EntityOwner>, SelectMgr_SortCriterion> mystored;
SelectMgr_SelectingVolumeManager mySelectingVolumeMgr;
mutable SelectMgr_SelectableObjectSet mySelectableObjects;
SelectMgr_ToleranceMap myTolerances;
NCollection_DataMap<Graphic3d_ZLayerId, int> myZLayerOrderMap;
occ::handle<Select3D_BVHBuilder3d> myEntitySetBuilder;
gp_Pnt myCameraEye;
gp_Dir myCameraDir;
double myCameraScale;
bool myToPrebuildBVH;
occ::handle<SelectMgr_BVHThreadPool> myBVHThreadPool;
mutable NCollection_Array1<int> myIndexes;
mutable bool myIsSorted;
bool myIsLeftChildQueuedFirst;
NCollection_DataMap<occ::handle<SelectMgr_SelectableObject>,
occ::handle<SelectMgr_SensitiveEntitySet>>
myMapOfObjectSensitives;
NCollection_Sequence<occ::handle<Graphic3d_Structure>> myStructs; //!< list of debug presentations
};
#endif