VTK  9.1.20211115
vtkHardwareSelector.h
Go to the documentation of this file.
1 /*=========================================================================
2 
3  Program: Visualization Toolkit
4  Module: vtkHardwareSelector.h
5 
6  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
7  All rights reserved.
8  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
9 
10  This software is distributed WITHOUT ANY WARRANTY; without even
11  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12  PURPOSE. See the above copyright notice for more information.
13 
14 =========================================================================*/
15 /*
16  * @class vtkHardwareSelector
17  * @brief manager for OpenGL-based selection.
18  *
19  * vtkHardwareSelector is a helper that orchestrates color buffer based
20  * selection. This relies on OpenGL.
21  * vtkHardwareSelector can be used to select visible cells or points within a
22  * given rectangle of the RenderWindow.
23  * To use it, call in order:
24  * \li SetRenderer() - to select the renderer in which we
25  * want to select the cells/points.
26  * \li SetArea() - to set the rectangular region in the render window to select
27  * in.
28  * \li SetFieldAssociation() - to select the attribute to select i.e.
29  * cells/points etc.
30  * \li Finally, call Select().
31  * Select will cause the attached vtkRenderer to render in a special color mode,
32  * where each cell/point is given it own color so that later inspection of the
33  * Rendered Pixels can determine what cells are visible. Select() returns a new
34  * vtkSelection instance with the cells/points selected.
35  *
36  * Limitations:
37  * Antialiasing will break this class. If your graphics card settings force
38  * their use this class will return invalid results.
39  *
40  * Only Opaque geometry in Actors is selected from. Assemblies and LODMappers
41  * are not currently supported.
42  *
43  * During selection, visible datasets that can not be selected from are
44  * temporarily hidden so as not to produce invalid indices from their colors.
45  *
46  *
47  * The basic approach this class uses is to invoke render multiple times
48  * (passes) and have the mappers render pass specific information into
49  * the color buffer. For example during the ACTOR_PASS a mapper is
50  * supposed to render it's actor's id into the color buffer as a RGB
51  * value where R is the lower 8 bits, G is the next 8, etc. Giving us 24
52  * bits of unsigned int range.
53  *
54  * The same concept applies to the COMPOSITE_INDEX_PASS and the point and
55  * cell ID passes. As points and cells can easily exceed the 24 bit range
56  * of the color buffer we break them into two 24 bit passes for a total
57  * of 48 bits of range.
58  *
59  * During each pass the mappers render their data into the color buffer,
60  * the hardware selector grabs that buffer and then invokes
61  * ProcessSelectorPixelBuffer on all of the hit props. Giving them, and
62  * their mappers, a chance to modify the pixel buffer.
63  *
64  * Most mappers use this ProcessSelectorPixelBuffers pass to take when
65  * they rendered into the color buffer and convert it into what the
66  * hardware selector is expecting. This is because in some cases it is
67  * far easier and faster to render something else, such as
68  * gl_PrimitiveID or gl_VertexID and then in the processing convert those
69  * values to the appropriate VTK values.
70  *
71  * NOTE: The goal is for mappers to support hardware selection without
72  * having to rebuild any of their VBO/IBOs to maintain fast picking
73  * performance.
74  *
75  * NOTE: This class has a complex interaction with parallel compositing
76  * techniques such as IceT that are used on supercomputers. In those
77  * cases the local nodes render each pass, process it, send it to icet
78  * which composits it, and then must copy the result back to the hardware
79  * selector. Be aware of these interactions if you work on this class.
80  *
81  * NOTE: many mappers support remapping arrays from their local value to
82  * some other provided value. For example ParaView when creating a
83  * polydata from an unstructured grid will create point and cell data
84  * arrays on the polydata that may the polydata point and cell IDs back
85  * to the original unstructured grid's point and cell IDs. The hardware
86  * selection process honors those arrays and will provide the original
87  * unstructured grid point and cell ID when a selection is made.
88  * Likewise there are process and composite arrays that most mappers
89  * support that allow for parallel data generation, delivery, and local
90  * rendering while preserving the original process and composite values
91  * from when the data was distributed. Be aware the process array is a
92  * point data while the composite array is a cell data.
93  *
94  * TODO: This whole selection process could be nicely encapsulated as a
95  * RenderPass that internally renders multiple times with different
96  * settings. That would be my suggestion for the future.
97  *
98  * TODO: The pick method build into renderer could use the ACTOR pass of
99  * this class to do it's work eliminating some confusion and duplicate
100  * code paths.
101  *
102  * TODO: I am not sure where the composite array indirection is used.
103  *
104  *
105  * @sa
106  * vtkOpenGLHardwareSelector
107 
108  @par Online Examples:
109 
110  @htmlonly
111 
112  <div class="examplegrid">
113 
114  <a href="https://kitware.github.io/vtk-examples/site/Cxx/Filtering/ExtractVisibleCells">
115  <div class="examplegrid_container">
116  <img src="https://raw.githubusercontent.com/Kitware/vtk-examples/gh-pages/src/Testing/Baseline//Cxx/Filtering/TestExtractVisibleCells.png">
117  <div class="examplegrid_overlay">
118  <div class="examplegrid_text">ExtractVisibleCells</div>
119  </div>
120  </div>
121  </a>
122 
123 
124  <a href="https://kitware.github.io/vtk-examples/site/Cxx/Graphs/SelectedVerticesAndEdges">
125  <div class="examplegrid_container">
126  <img src="https://raw.githubusercontent.com/Kitware/vtk-examples/gh-pages/src/Testing/Baseline//Cxx/Graphs/TestSelectedVerticesAndEdges.png">
127  <div class="examplegrid_overlay">
128  <div class="examplegrid_text">SelectedVerticesAndEdges</div>
129  </div>
130  </div>
131  </a>
132 
133  </div>
134 
135  @endhtmlonly
136  */
137 
138 #ifndef vtkHardwareSelector_h
139 #define vtkHardwareSelector_h
140 
141 #include "vtkObject.h"
142 #include "vtkRenderingCoreModule.h" // For export macro
143 
144 #include <string> // for std::string
145 
146 class vtkRenderer;
147 class vtkRenderWindow;
148 class vtkSelection;
149 class vtkProp;
150 class vtkTextureObject;
151 
152 class VTKRENDERINGCORE_EXPORT vtkHardwareSelector : public vtkObject
153 {
154 public:
156 
160  {
161  bool Valid;
163  int PropID;
165  unsigned int CompositeID;
168  : Valid(false)
169  , ProcessID(-1)
170  , PropID(-1)
171  , Prop(nullptr)
172  , CompositeID(0)
173  , AttributeID(-1)
174  {
175  }
176  };
178 
179 public:
182  void PrintSelf(ostream& os, vtkIndent indent) override;
183 
185 
188  virtual void SetRenderer(vtkRenderer*);
189  vtkGetObjectMacro(Renderer, vtkRenderer);
191 
193 
196  vtkSetVector4Macro(Area, unsigned int);
197  vtkGetVector4Macro(Area, unsigned int);
199 
201 
211  vtkSetMacro(FieldAssociation, int);
212  vtkGetMacro(FieldAssociation, int);
214 
216 
221  vtkSetMacro(UseProcessIdFromData, bool);
222  vtkGetMacro(UseProcessIdFromData, bool);
224 
230 
232 
245  virtual bool CaptureBuffers();
246  PixelInformation GetPixelInformation(const unsigned int display_position[2])
247  {
248  return this->GetPixelInformation(display_position, 0);
249  }
250  PixelInformation GetPixelInformation(const unsigned int display_position[2], int maxDist)
251  {
252  unsigned int temp[2];
253  return this->GetPixelInformation(display_position, maxDist, temp);
254  }
256  const unsigned int display_position[2], int maxDist, unsigned int selected_position[2]);
257  void ClearBuffers() { this->ReleasePixBuffers(); }
258  // raw is before processing
259  unsigned char* GetRawPixelBuffer(int passNo) { return this->RawPixBuffer[passNo]; }
260  unsigned char* GetPixelBuffer(int passNo) { return this->PixBuffer[passNo]; }
262 
267  virtual void RenderCompositeIndex(unsigned int index);
268 
270 
276  virtual void UpdateMaximumCellId(vtkIdType attribid);
277  virtual void UpdateMaximumPointId(vtkIdType attribid);
279 
284  virtual void RenderProcessId(unsigned int processid);
285 
290  int Render(vtkRenderer* renderer, vtkProp** propArray, int propArrayCount);
291 
293 
297  vtkGetMacro(ActorPassOnly, bool);
298  vtkSetMacro(ActorPassOnly, bool);
300 
302 
308  vtkGetMacro(CaptureZValues, bool);
309  vtkSetMacro(CaptureZValues, bool);
311 
313 
316  virtual void BeginRenderProp();
317  virtual void EndRenderProp();
319 
321 
325  vtkSetMacro(ProcessID, int);
326  vtkGetMacro(ProcessID, int);
328 
330 
333  vtkGetVector3Macro(PropColorValue, float);
334  vtkSetVector3Macro(PropColorValue, float);
337 
339 
342  vtkGetMacro(CurrentPass, int);
344 
353  virtual vtkSelection* GenerateSelection() { return GenerateSelection(this->Area); }
354  virtual vtkSelection* GenerateSelection(unsigned int r[4])
355  {
356  return GenerateSelection(r[0], r[1], r[2], r[3]);
357  }
359  unsigned int x1, unsigned int y1, unsigned int x2, unsigned int y2);
360 
367  virtual vtkSelection* GeneratePolygonSelection(int* polygonPoints, vtkIdType count);
368 
374 
375  // it is very critical that these passes happen in the right order
376  // this is because of two complexities
377  //
378  // Compositing engines such as iceT send each pass as it
379  // renders. This means
380  //
381  // Mappers use point Ids or cell Id to update the process
382  // and composite ids. So the point and cell id passes
383  // have to happen before the last process and compoite
384  // passes respectively
385  //
386  //
388  {
389  // always must be first so that the prop IDs are set
391  // must always be second for composite mapper
393 
395  POINT_ID_HIGH24, // if needed
396  PROCESS_PASS, // must be after point id pass
397 
399  CELL_ID_HIGH24, // if needed
400 
401  MAX_KNOWN_PASS = CELL_ID_HIGH24,
402  MIN_KNOWN_PASS = ACTOR_PASS
403  };
404 
409 
410  static void Convert(vtkIdType id, float tcoord[3])
411  {
412  tcoord[0] = static_cast<float>((id & 0xff) / 255.0);
413  tcoord[1] = static_cast<float>(((id & 0xff00) >> 8) / 255.0);
414  tcoord[2] = static_cast<float>(((id & 0xff0000) >> 16) / 255.0);
415  }
416 
417  // grab the pixel buffer and save it
418  // typically called internally
419  virtual void SavePixelBuffer(int passNo);
420 
421  // does the selection process have high cell data
422  // requiring a high24 pass
424 
425  // does the selection process have high point data
426  // requiring a high24 pass
428 
429 protected:
432 
433  // Used to notify subclasses when a capture pass is occurring.
434  virtual void PreCapturePass(int pass) { (void)pass; }
435  virtual void PostCapturePass(int pass) { (void)pass; }
436 
437  // Called internally before and after each prop is rendered
438  // for device specific configuration/preparation etc.
439  virtual void BeginRenderProp(vtkRenderWindow*) = 0;
440  virtual void EndRenderProp(vtkRenderWindow*) = 0;
441 
442  double GetZValue(int propid);
443 
444  int Convert(unsigned long offset, unsigned char* pb)
445  {
446  if (!pb)
447  {
448  return 0;
449  }
450  offset = offset * 3;
451  unsigned char rgb[3];
452  rgb[0] = pb[offset];
453  rgb[1] = pb[offset + 1];
454  rgb[2] = pb[offset + 2];
455  int val = 0;
456  val |= rgb[2];
457  val = val << 8;
458  val |= rgb[1];
459  val = val << 8;
460  val |= rgb[0];
461  return val;
462  }
463 
465 
468  int Convert(unsigned int pos[2], unsigned char* pb) { return this->Convert(pos[0], pos[1], pb); }
469  int Convert(int xx, int yy, unsigned char* pb)
470  {
471  if (!pb)
472  {
473  return 0;
474  }
475  int offset = (yy * static_cast<int>(this->Area[2] - this->Area[0] + 1) + xx) * 3;
476  unsigned char rgb[3];
477  rgb[0] = pb[offset];
478  rgb[1] = pb[offset + 1];
479  rgb[2] = pb[offset + 2];
480  int val = 0;
481  val |= rgb[2];
482  val = val << 8;
483  val |= rgb[1];
484  val = val << 8;
485  val |= rgb[0];
486  return val;
487  }
489 
490  vtkIdType GetID(int low24, int mid24, int high16)
491  {
492  vtkIdType val = 0;
493  val |= high16;
494  val = val << 24;
495  val |= mid24;
496  val = val << 24;
497  val |= low24;
498  return val;
499  }
500 
504  virtual bool PassRequired(int pass);
505 
511  bool IsPropHit(int propid);
512 
516  virtual int GetPropID(int idx, vtkProp* vtkNotUsed(prop)) { return idx; }
517 
518  virtual void BeginSelection();
519  virtual void EndSelection();
520 
521  virtual void ProcessPixelBuffers();
522  void BuildPropHitList(unsigned char* rgbData);
523 
525 
530  unsigned int Area[4];
536 
537  // At most 10 passes.
538  unsigned char* PixBuffer[10];
539  unsigned char* RawPixBuffer[10];
544  int PropID;
545  float PropColorValue[3];
546 
548 
550 
551 private:
552  vtkHardwareSelector(const vtkHardwareSelector&) = delete;
553  void operator=(const vtkHardwareSelector&) = delete;
554 
555  class vtkInternals;
556  vtkInternals* Internals;
557 };
558 
559 #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 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.
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.
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:113
abstract base class for most VTK objects
Definition: vtkObject.h:82
abstract superclass for all actors, volumes and annotations
Definition: vtkProp.h:76
create a window for renderers to draw into
abstract specification for renderers
Definition: vtkRenderer.h:182
data object that represents a "selection" in VTK.
Definition: vtkSelection.h:163
abstracts an OpenGL texture object.
@ type
Definition: vtkX3D.h:522
@ index
Definition: vtkX3D.h:252
@ offset
Definition: vtkX3D.h:444
@ string
Definition: vtkX3D.h:496
Struct used to return information about a pixel location.
int vtkIdType
Definition: vtkType.h:332
#define VTK_NEWINSTANCE