1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264
|
/*=========================================================================
Program: Visualization Toolkit
Module: vtkHardwarePicker.h
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notice for more information.
=========================================================================*/
/**
* @class vtkHardwarePicker
* @brief pick a point or snap to point of an actor/prop using graphics hardware
*
* vtkHardwarePicker is used to pick point or snap to point of an actor/prop given a selection
* point (in display coordinates) and a renderer. This class uses graphics hardware/rendering
* system to pick rapidly (as compared to using ray casting as does vtkCellPicker and
* vtkPointPicker). This class determines the actor/prop pick position, and pick normal in world
* coordinates; pointId is determined if snapping is enabled, otherwise the cellId is determined.
* if no actor/prop is picked, pick position = camera focal point, and pick normal = camera plane
* normal.
*
* @warning This class supports only picking in a screen, and not in VR.
*
* @sa
* vtkPropPicker vtkPicker vtkWorldPointPicker vtkCellPicker vtkPointPicker
*/
#ifndef vtkHardwarePicker_h
#define vtkHardwarePicker_h
#include "vtkAbstractPropPicker.h"
#include "vtkNew.h" // For vtkNew
#include "vtkRenderingCoreModule.h" // For export macro
#include "vtkSmartPointer.h" // For vtkSmartPointer
VTK_ABI_NAMESPACE_BEGIN
class vtkAbstractMapper3D;
class vtkCell;
class vtkCompositeDataSet;
class vtkDataSet;
class vtkSelection;
class VTKRENDERINGCORE_EXPORT vtkHardwarePicker : public vtkAbstractPropPicker
{
public:
static vtkHardwarePicker* New();
vtkTypeMacro(vtkHardwarePicker, vtkAbstractPropPicker);
void PrintSelf(ostream& os, vtkIndent indent) override;
///@{
/**
* Set/Get if the picker will snap to the closest mesh point or get the actual intersected point.
* Default is off.
*/
vtkSetMacro(SnapToMeshPoint, bool);
vtkGetMacro(SnapToMeshPoint, bool);
vtkBooleanMacro(SnapToMeshPoint, bool);
///@}
///@{
/**
* When SnapToMeshPoint is on, this is the pixel tolerance to use when snapping.
* Default is 5.
*/
vtkSetMacro(PixelTolerance, int);
vtkGetMacro(PixelTolerance, int);
///@}
///@{
/**
* Return mapper that was picked (if any).
*
* Note: Use vtkWeakPointer. This is because the Mapper may be deleted.
*/
vtkGetObjectMacro(Mapper, vtkAbstractMapper3D);
///@}
///@{
/**
* Get a pointer to the dataset that was picked (if any). If nothing
* was picked then nullptr is returned.
*
* Note: Use vtkWeakPointer. This is because the DataSet may be deleted.
*/
vtkGetObjectMacro(DataSet, vtkDataSet);
///@}
///@{
/**
* Get a pointer to the composite dataset that was picked (if any). If nothing
* was picked or a non-composite data object was picked then nullptr is returned.
*
* Note: Use vtkWeakPointer. This is because the CompositeDataSet may be deleted.
*/
vtkGetObjectMacro(CompositeDataSet, vtkCompositeDataSet);
///@}
///@{
/**
* Get the flat block index of the vtkDataSet in the composite dataset
* that was picked (if any). If nothing was picked or a non-composite
* data object was picked then -1 is returned.
*/
vtkGetMacro(FlatBlockIndex, vtkIdType);
///@}
///@{
/**
* Get the id of the picked point.
*
* If a prop is picked:
*
* 1) if SnapOnMeshPoint is on, the pointId of the prop's dataset will be returned
* 2) If SnapOnMeshPoint is off, PointId = -1;
*
* If a prop is not picked, PointId = -1;
*/
vtkGetMacro(PointId, vtkIdType);
///@}
///@{
/**
* Get the id of the picked cell.
*
* If a prop is picked:
*
* 1) If SnapOnMeshPoint is on, CellId = -1.
* 2) If SnapOnMeshPoint is off, the cellId of the prop's dataset will be returned
*
* if a prop is not picked, CellId = -1.
*/
vtkGetMacro(CellId, vtkIdType);
///@}
///@{
/**
* Get the subId of the picked cell. This is useful, for example, if
* the data is made of triangle strips.
*
* If a prop is picked:
*
* 1) If SnapOnMeshPoint is on, SubId = -1.
* 2) If SnapOnMeshPoint is off and the picked cell is a triangle strip, the subId of the
* intersected triangle will be returned, otherwise SubId = -1.
*
* If a prop is not picked, SubId = -1.
*/
vtkGetMacro(SubId, int);
///@}
///@{
/**
* Get the parametric coordinates of the picked cell. PCoords can be used to compute the
* weights that are needed to interpolate data values within the cell.
*
* If a prop is picked:
*
* 1) If SnapOnMeshPoint is on, PCoords will be a vector of
* std::numeric_limits<double>::quiet_NaN().
* 2) If SnapOnMeshPoint is off, PCoords will be extracted and the intersection point of the cell.
*
* if a prop is not picked, PCoords will be a vector of std::numeric_limits<double>::quiet_NaN().
*/
vtkGetVector3Macro(PCoords, double);
///@}
///@{
/**
* Get the normal of the point at the PickPosition.
*
* If a prop is picked:
*
* 1) If SnapOnMeshPoint is on, the picked normal will be extracted from the PointData normals, if
* they exist, otherwise a vector of std::numeric_limits<double>::quiet_NaN() will be returned.
* 2) If SnapOnMeshPoint is off, the picked normal on the intersected cell will be extracted using
* ray intersection, if the ray intersections was successful, otherwise a vector of
* std::numeric_limits<double>::quiet_NaN() will be returned.
*
* if a prop is not picked, the camera plane normal will be returned will be returned.
*/
vtkGetVectorMacro(PickNormal, double, 3);
///@}
/**
* Get if normal is flipped.
*
* The normal will be flipped if point normals don't exist and the angle between the PickedNormal
* and the camera plane normal is more than pi / 2.
*/
vtkGetMacro(NormalFlipped, bool);
/**
* Perform the pick operation set the PickedProp.
*
* If something is picked, 1 is returned, and PickPosition, PickNormal, and the rest of the
* results variables) are extracted from intersection with the PickedProp.
*
* If something is not picked, 0 is returned, and PickPosition and PickNormal are extracted from
* the camera's focal plane.
*/
int Pick(double selectionX, double selectionY, double selectionZ, vtkRenderer* renderer) override;
protected:
vtkHardwarePicker();
~vtkHardwarePicker() override;
void Initialize() override;
// converts the propCandidate into a vtkAbstractMapper3D and returns its pickability
int TypeDecipher(vtkProp*, vtkAbstractMapper3D**);
/**
* Fix normal sign in case the orientation of the picked cell is wrong.
* When you cast a ray to a 3d object from a specific view angle (camera normal), the angle
* between the camera normal and the normal of the cell surface that the ray intersected,
* can have an angle up to pi / 2. This is true because you can't see surface objects
* with a greater angle than pi / 2, therefore, you can't pick them. In case an angle greater
* than pi / 2 is computed, we flip the picked normal.
*/
void FixNormalSign();
/**
* Compute the intersection normal either by interpolating the point normals at the
* intersected point, or by computing the plane normal for the 2D intersected face/cell.
*/
int ComputeSurfaceNormal(vtkDataSet* data, vtkCell* cell, double* weights);
/**
* Compute the intersection using provided dataset
*/
void ComputeIntersectionFromDataSet(vtkDataSet* ds);
bool SnapToMeshPoint; // if true, the pick position is snapped to the closest point on the mesh
int PixelTolerance; // tolerance for picking when snapping the closest point on the mesh
vtkNew<vtkPropCollection> PickableProps; // list of pickable props
vtkSmartPointer<vtkSelection> HardwareSelection; // result of the hardware selector
double NearRayPoint[3]; // near ray point
double FarRayPoint[3]; // far ray point
vtkAbstractMapper3D* Mapper; // selected mapper (if the prop has a mapper)
vtkDataSet* DataSet; // selected dataset (if there is one)
vtkCompositeDataSet* CompositeDataSet; // selected dataset (if there is one)
vtkIdType FlatBlockIndex; // flat block index, for a composite data set
vtkIdType PointId; // id of the picked point
vtkIdType CellId; // id of the picked cell
int SubId; // sub id of the picked cell
double PCoords[3]; // parametric coordinates of the picked point
double PickNormal[3]; // normal of the picked surface
bool NormalFlipped; // Flag to indicate if the normal has been flipped
private:
vtkHardwarePicker(const vtkHardwarePicker&) = delete;
void operator=(const vtkHardwarePicker&) = delete;
};
VTK_ABI_NAMESPACE_END
#endif
|