VTK  9.3.0
vtkHardwareSelector.h
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
2 // SPDX-License-Identifier: BSD-3-Clause
3 /*
4  * @class vtkHardwareSelector
5  * @brief manager for OpenGL-based selection.
6  *
7  * vtkHardwareSelector is a helper that orchestrates color buffer based
8  * selection. This relies on OpenGL.
9  * vtkHardwareSelector can be used to select visible cells or points within a
10  * given rectangle of the RenderWindow.
11  * To use it, call in order:
12  * \li SetRenderer() - to select the renderer in which we
13  * want to select the cells/points.
14  * \li SetArea() - to set the rectangular region in the render window to select
15  * in.
16  * \li SetFieldAssociation() - to select the attribute to select i.e.
17  * cells/points etc.
18  * \li Finally, call Select().
19  * Select will cause the attached vtkRenderer to render in a special color mode,
20  * where each cell/point is given it own color so that later inspection of the
21  * Rendered Pixels can determine what cells are visible. Select() returns a new
22  * vtkSelection instance with the cells/points selected.
23  *
24  * Limitations:
25  * Antialiasing will break this class. If your graphics card settings force
26  * their use this class will return invalid results.
27  *
28  * Only Opaque geometry in Actors is selected from. Assemblies and LODMappers
29  * are not currently supported.
30  *
31  * During selection, visible datasets that can not be selected from are
32  * temporarily hidden so as not to produce invalid indices from their colors.
33  *
34  *
35  * The basic approach this class uses is to invoke render multiple times
36  * (passes) and have the mappers render pass specific information into
37  * the color buffer. For example during the ACTOR_PASS a mapper is
38  * supposed to render it's actor's id into the color buffer as a RGB
39  * value where R is the lower 8 bits, G is the next 8, etc. Giving us 24
40  * bits of unsigned int range.
41  *
42  * The same concept applies to the COMPOSITE_INDEX_PASS and the point and
43  * cell ID passes. As points and cells can easily exceed the 24 bit range
44  * of the color buffer we break them into two 24 bit passes for a total
45  * of 48 bits of range.
46  *
47  * During each pass the mappers render their data into the color buffer,
48  * the hardware selector grabs that buffer and then invokes
49  * ProcessSelectorPixelBuffer on all of the hit props. Giving them, and
50  * their mappers, a chance to modify the pixel buffer.
51  *
52  * Most mappers use this ProcessSelectorPixelBuffers pass to take when
53  * they rendered into the color buffer and convert it into what the
54  * hardware selector is expecting. This is because in some cases it is
55  * far easier and faster to render something else, such as
56  * gl_PrimitiveID or gl_VertexID and then in the processing convert those
57  * values to the appropriate VTK values.
58  *
59  * NOTE: The goal is for mappers to support hardware selection without
60  * having to rebuild any of their VBO/IBOs to maintain fast picking
61  * performance.
62  *
63  * NOTE: This class has a complex interaction with parallel compositing
64  * techniques such as IceT that are used on supercomputers. In those
65  * cases the local nodes render each pass, process it, send it to icet
66  * which composites it, and then must copy the result back to the hardware
67  * selector. Be aware of these interactions if you work on this class.
68  *
69  * NOTE: many mappers support remapping arrays from their local value to
70  * some other provided value. For example ParaView when creating a
71  * polydata from an unstructured grid will create point and cell data
72  * arrays on the polydata that may the polydata point and cell IDs back
73  * to the original unstructured grid's point and cell IDs. The hardware
74  * selection process honors those arrays and will provide the original
75  * unstructured grid point and cell ID when a selection is made.
76  * Likewise there are process and composite arrays that most mappers
77  * support that allow for parallel data generation, delivery, and local
78  * rendering while preserving the original process and composite values
79  * from when the data was distributed. Be aware the process array is a
80  * point data while the composite array is a cell data.
81  *
82  * TODO: This whole selection process could be nicely encapsulated as a
83  * RenderPass that internally renders multiple times with different
84  * settings. That would be my suggestion for the future.
85  *
86  * TODO: The pick method build into renderer could use the ACTOR pass of
87  * this class to do it's work eliminating some confusion and duplicate
88  * code paths.
89  *
90  * TODO: I am not sure where the composite array indirection is used.
91  *
92  *
93  * @sa
94  * vtkOpenGLHardwareSelector
95 
96  @par Online Examples:
97 
98  @htmlonly
99 
100  <div class="examplegrid">
101  </div>
102 
103  @endhtmlonly
104 
105  @par Tests:
106  @ref c2_vtk_t_vtkHardwareSelector "vtkHardwareSelector (Tests)"
107  */
108 
109 #ifndef vtkHardwareSelector_h
110 #define vtkHardwareSelector_h
111 
112 #include "vtkObject.h"
113 #include "vtkRenderingCoreModule.h" // For export macro
114 
115 #include <string> // for std::string
116 
117 VTK_ABI_NAMESPACE_BEGIN
118 class vtkRenderer;
119 class vtkRenderWindow;
120 class vtkSelection;
121 class vtkProp;
122 class vtkTextureObject;
123 
124 class VTKRENDERINGCORE_EXPORT vtkHardwareSelector : public vtkObject
125 {
126 public:
128 
132  {
133  bool Valid;
135  int PropID;
137  unsigned int CompositeID;
140  : Valid(false)
141  , ProcessID(-1)
142  , PropID(-1)
143  , Prop(nullptr)
144  , CompositeID(0)
145  , AttributeID(-1)
146  {
147  }
148  };
150 
153  void PrintSelf(ostream& os, vtkIndent indent) override;
154 
156 
159  virtual void SetRenderer(vtkRenderer*);
160  vtkGetObjectMacro(Renderer, vtkRenderer);
162 
164 
167  vtkSetVector4Macro(Area, unsigned int);
168  vtkGetVector4Macro(Area, unsigned int);
170 
172 
182  vtkSetMacro(FieldAssociation, int);
183  vtkGetMacro(FieldAssociation, int);
185 
187 
192  vtkSetMacro(UseProcessIdFromData, bool);
193  vtkGetMacro(UseProcessIdFromData, bool);
195 
201 
203 
216  virtual bool CaptureBuffers();
217  PixelInformation GetPixelInformation(const unsigned int display_position[2])
218  {
219  return this->GetPixelInformation(display_position, 0);
220  }
221  PixelInformation GetPixelInformation(const unsigned int display_position[2], int maxDist)
222  {
223  unsigned int temp[2];
224  return this->GetPixelInformation(display_position, maxDist, temp);
225  }
227  const unsigned int display_position[2], int maxDist, unsigned int selected_position[2]);
228  void ClearBuffers() { this->ReleasePixBuffers(); }
229  // raw is before processing
230  unsigned char* GetRawPixelBuffer(int passNo) { return this->RawPixBuffer[passNo]; }
231  unsigned char* GetPixelBuffer(int passNo) { return this->PixBuffer[passNo]; }
233 
238  virtual void RenderCompositeIndex(unsigned int index);
239 
241 
247  virtual void UpdateMaximumCellId(vtkIdType attribid);
248  virtual void UpdateMaximumPointId(vtkIdType attribid);
250 
255  virtual void RenderProcessId(unsigned int processid);
256 
261  int Render(vtkRenderer* renderer, vtkProp** propArray, int propArrayCount);
262 
264 
268  vtkGetMacro(ActorPassOnly, bool);
269  vtkSetMacro(ActorPassOnly, bool);
271 
273 
279  vtkGetMacro(CaptureZValues, bool);
280  vtkSetMacro(CaptureZValues, bool);
282 
284 
287  virtual void BeginRenderProp();
288  virtual void EndRenderProp();
290 
292 
296  vtkSetMacro(ProcessID, int);
297  vtkGetMacro(ProcessID, int);
299 
301 
304  vtkGetVector3Macro(PropColorValue, float);
305  vtkSetVector3Macro(PropColorValue, float);
308 
310 
313  vtkGetMacro(CurrentPass, int);
315 
324  virtual vtkSelection* GenerateSelection() { return GenerateSelection(this->Area); }
325  virtual vtkSelection* GenerateSelection(unsigned int r[4])
326  {
327  return GenerateSelection(r[0], r[1], r[2], r[3]);
328  }
330  unsigned int x1, unsigned int y1, unsigned int x2, unsigned int y2);
331 
338  virtual vtkSelection* GeneratePolygonSelection(int* polygonPoints, vtkIdType count);
339 
345 
346  // it is very critical that these passes happen in the right order
347  // this is because of two complexities
348  //
349  // Compositing engines such as iceT send each pass as it
350  // renders. This means
351  //
352  // Mappers use point Ids or cell Id to update the process
353  // and composite ids. So the point and cell id passes
354  // have to happen before the last process and compoite
355  // passes respectively
356  //
357  //
359  {
360  // always must be first so that the prop IDs are set
362  // must always be second for composite mapper
364 
366  POINT_ID_HIGH24, // if needed
367  PROCESS_PASS, // must be after point id pass
368 
370  CELL_ID_HIGH24, // if needed
371 
372  MAX_KNOWN_PASS = CELL_ID_HIGH24,
373  MIN_KNOWN_PASS = ACTOR_PASS
374  };
375 
380 
381  static void Convert(vtkIdType id, float tcoord[3])
382  {
383  tcoord[0] = static_cast<float>((id & 0xff) / 255.0);
384  tcoord[1] = static_cast<float>(((id & 0xff00) >> 8) / 255.0);
385  tcoord[2] = static_cast<float>(((id & 0xff0000) >> 16) / 255.0);
386  }
387 
388  // grab the pixel buffer and save it
389  // typically called internally
390  virtual void SavePixelBuffer(int passNo);
391 
392  // does the selection process have high cell data
393  // requiring a high24 pass
395 
396  // does the selection process have high point data
397  // requiring a high24 pass
399 
400 protected:
403 
404  // Used to notify subclasses when a capture pass is occurring.
405  virtual void PreCapturePass(int pass) { (void)pass; }
406  virtual void PostCapturePass(int pass) { (void)pass; }
407 
408  // Called internally before and after each prop is rendered
409  // for device specific configuration/preparation etc.
410  virtual void BeginRenderProp(vtkRenderWindow*) = 0;
411  virtual void EndRenderProp(vtkRenderWindow*) = 0;
412 
413  double GetZValue(int propid);
414 
415  int Convert(unsigned long offset, unsigned char* pb)
416  {
417  if (!pb)
418  {
419  return 0;
420  }
421  offset = offset * 3;
422  unsigned char rgb[3];
423  rgb[0] = pb[offset];
424  rgb[1] = pb[offset + 1];
425  rgb[2] = pb[offset + 2];
426  int val = 0;
427  val |= rgb[2];
428  val = val << 8;
429  val |= rgb[1];
430  val = val << 8;
431  val |= rgb[0];
432  return val;
433  }
434 
436 
439  int Convert(unsigned int pos[2], unsigned char* pb) { return this->Convert(pos[0], pos[1], pb); }
440  int Convert(int xx, int yy, unsigned char* pb)
441  {
442  if (!pb)
443  {
444  return 0;
445  }
446  int offset = (yy * static_cast<int>(this->Area[2] - this->Area[0] + 1) + xx) * 3;
447  unsigned char rgb[3];
448  rgb[0] = pb[offset];
449  rgb[1] = pb[offset + 1];
450  rgb[2] = pb[offset + 2];
451  int val = 0;
452  val |= rgb[2];
453  val = val << 8;
454  val |= rgb[1];
455  val = val << 8;
456  val |= rgb[0];
457  return val;
458  }
460 
461  vtkIdType GetID(int low24, int mid24, int high16)
462  {
463  vtkIdType val = 0;
464  val |= high16;
465  val = val << 24;
466  val |= mid24;
467  val = val << 24;
468  val |= low24;
469  return val;
470  }
471 
475  virtual bool PassRequired(int pass);
476 
482  bool IsPropHit(int propid);
483 
487  virtual int GetPropID(int idx, vtkProp* vtkNotUsed(prop)) { return idx; }
488 
489  virtual void BeginSelection();
490  virtual void EndSelection();
491 
492  virtual void ProcessPixelBuffers();
493  void BuildPropHitList(unsigned char* rgbData);
494 
496 
501  unsigned int Area[4];
507 
508  // At most 10 passes.
509  unsigned char* PixBuffer[10];
510  unsigned char* RawPixBuffer[10];
515  int PropID;
516  float PropColorValue[3];
517 
519 
521 
522 private:
523  vtkHardwareSelector(const vtkHardwareSelector&) = delete;
524  void operator=(const vtkHardwareSelector&) = delete;
525 
526  class vtkInternals;
527  vtkInternals* Internals;
528 };
529 
530 VTK_ABI_NAMESPACE_END
531 #endif
static vtkHardwareSelector * New()
int Convert(unsigned long offset, unsigned char *pb)
vtkIdType MaximumCellId
Clears all pixel buffers.
virtual void BeginRenderProp()
Called by the mapper before and after rendering each prop.
virtual void UpdateMaximumPointId(vtkIdType attribid)
Called by any vtkMapper or vtkProp subclass to indicate the maximum cell or point attribute ID it use...
virtual void SavePixelBuffer(int passNo)
virtual void EndRenderProp(vtkRenderWindow *)=0
vtkRenderer * Renderer
Clears all pixel buffers.
virtual void EndRenderProp()
Called by the mapper before and after rendering each prop.
unsigned char * GetRawPixelBuffer(int passNo)
It is possible to use the vtkHardwareSelector for a custom picking.
virtual void SetRenderer(vtkRenderer *)
Get/Set the renderer to perform the selection on.
virtual vtkSelection * GenerateSelection(unsigned int r[4])
PixelInformation GetPixelInformation(const unsigned int display_position[2], int maxDist)
It is possible to use the vtkHardwareSelector for a custom picking.
vtkIdType GetID(int low24, int mid24, int high16)
virtual vtkSelection * GenerateSelection(unsigned int x1, unsigned int y1, unsigned int x2, unsigned int y2)
virtual PixelInformation GetPixelInformation(const unsigned int display_position[2], int maxDist, unsigned int selected_position[2])
It is possible to use the vtkHardwareSelector for a custom picking.
virtual void ProcessPixelBuffers()
vtkProp * GetPropFromID(int id)
returns the prop associated with a ID.
vtkIdType MaximumPointId
Clears all pixel buffers.
int FieldAssociation
Clears all pixel buffers.
~vtkHardwareSelector() override
void ReleasePixBuffers()
Clears all pixel buffers.
virtual void BeginSelection()
virtual void UpdateMaximumCellId(vtkIdType attribid)
Called by any vtkMapper or vtkProp subclass to indicate the maximum cell or point attribute ID it use...
virtual void PreCapturePass(int pass)
virtual bool PassRequired(int pass)
Returns is the pass indicated is needed.
int Convert(int xx, int yy, unsigned char *pb)
pos must be relative to the lower-left corner of this->Area.
virtual void PostCapturePass(int pass)
bool UseProcessIdFromData
Clears all pixel buffers.
bool IsPropHit(int propid)
After the ACTOR_PASS this return true or false depending upon whether the prop was hit in the ACTOR_P...
void SetPropColorValue(vtkIdType val)
Get/Set the color to be used by the prop when drawing.
std::string PassTypeToString(PassTypes type)
Convert a PassTypes enum value to a human readable string.
virtual int GetPropID(int idx, vtkProp *vtkNotUsed(prop))
Return a unique ID for the prop.
int Render(vtkRenderer *renderer, vtkProp **propArray, int propArrayCount)
Called by vtkRenderer to render the selection pass.
void BuildPropHitList(unsigned char *rgbData)
static void Convert(vtkIdType id, float tcoord[3])
int Convert(unsigned int pos[2], unsigned char *pb)
pos must be relative to the lower-left corner of this->Area.
PixelInformation GetPixelInformation(const unsigned int display_position[2])
It is possible to use the vtkHardwareSelector for a custom picking.
virtual void RenderCompositeIndex(unsigned int index)
Called by any vtkMapper or vtkProp subclass to render a composite-index.
virtual void EndSelection()
virtual vtkSelection * GeneratePolygonSelection(int *polygonPoints, vtkIdType count)
Generates the vtkSelection from pixel buffers.
virtual void BeginRenderProp(vtkRenderWindow *)=0
double GetZValue(int propid)
void ClearBuffers()
It is possible to use the vtkHardwareSelector for a custom picking.
vtkSelection * Select()
Perform the selection.
void PrintSelf(ostream &os, vtkIndent indent) override
Methods invoked by print to print information about the object including superclasses.
virtual bool CaptureBuffers()
It is possible to use the vtkHardwareSelector for a custom picking.
virtual vtkSelection * GenerateSelection()
Generates the vtkSelection from pixel buffers.
unsigned char * GetPixelBuffer(int passNo)
It is possible to use the vtkHardwareSelector for a custom picking.
virtual void RenderProcessId(unsigned int processid)
Called by any vtkMapper or subclass to render process id.
a simple class to control print indentation
Definition: vtkIndent.h:38
abstract base class for most VTK objects
Definition: vtkObject.h:61
abstract superclass for all actors, volumes and annotations
Definition: vtkProp.h:55
create a window for renderers to draw into
abstract specification for renderers
Definition: vtkRenderer.h:71
data object that represents a "selection" in VTK.
Definition: vtkSelection.h:59
abstracts an OpenGL texture object.
@ type
Definition: vtkX3D.h:516
@ index
Definition: vtkX3D.h:246
@ offset
Definition: vtkX3D.h:438
@ string
Definition: vtkX3D.h:490
Struct used to return information about a pixel location.
int vtkIdType
Definition: vtkType.h:315
#define VTK_NEWINSTANCE