VTK  9.0.1
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 
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 class vtkRenderer;
118 class vtkRenderWindow;
119 class vtkSelection;
120 class vtkProp;
121 class vtkTextureObject;
122 
123 class VTKRENDERINGCORE_EXPORT vtkHardwareSelector : public vtkObject
124 {
125 public:
127 
131  {
132  bool Valid;
134  int PropID;
136  unsigned int CompositeID;
139  : Valid(false)
140  , ProcessID(-1)
141  , PropID(-1)
142  , Prop(nullptr)
143  , CompositeID(0)
144  , AttributeID(-1)
145  {
146  }
147  };
149 
150 public:
151  static vtkHardwareSelector* New();
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 
200  vtkSelection* Select();
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  }
226  PixelInformation GetPixelInformation(
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);
306  void SetPropColorValue(vtkIdType val);
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  }
329  virtual vtkSelection* GenerateSelection(
330  unsigned int x1, unsigned int y1, unsigned int x2, unsigned int y2);
331 
338  virtual vtkSelection* GeneratePolygonSelection(int* polygonPoints, vtkIdType count);
339 
344  vtkProp* GetPropFromID(int id);
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, // best to 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 
379  std::string PassTypeToString(PassTypes type);
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 protected:
394  ~vtkHardwareSelector() override;
395 
396  // Used to notify subclasses when a capture pass is occurring.
397  virtual void PreCapturePass(int pass) { (void)pass; }
398  virtual void PostCapturePass(int pass) { (void)pass; }
399 
400  // Called internally before and after each prop is rendered
401  // for device specific configuration/preparation etc.
402  virtual void BeginRenderProp(vtkRenderWindow*) = 0;
403  virtual void EndRenderProp(vtkRenderWindow*) = 0;
404 
405  double GetZValue(int propid);
406 
407  int Convert(unsigned long offset, unsigned char* pb)
408  {
409  if (!pb)
410  {
411  return 0;
412  }
413  offset = offset * 3;
414  unsigned char rgb[3];
415  rgb[0] = pb[offset];
416  rgb[1] = pb[offset + 1];
417  rgb[2] = pb[offset + 2];
418  int val = 0;
419  val |= rgb[2];
420  val = val << 8;
421  val |= rgb[1];
422  val = val << 8;
423  val |= rgb[0];
424  return val;
425  }
426 
428 
431  int Convert(unsigned int pos[2], unsigned char* pb) { return this->Convert(pos[0], pos[1], pb); }
432  int Convert(int xx, int yy, unsigned char* pb)
433  {
434  if (!pb)
435  {
436  return 0;
437  }
438  int offset = (yy * static_cast<int>(this->Area[2] - this->Area[0] + 1) + xx) * 3;
439  unsigned char rgb[3];
440  rgb[0] = pb[offset];
441  rgb[1] = pb[offset + 1];
442  rgb[2] = pb[offset + 2];
443  int val = 0;
444  val |= rgb[2];
445  val = val << 8;
446  val |= rgb[1];
447  val = val << 8;
448  val |= rgb[0];
449  return val;
450  }
452 
453  vtkIdType GetID(int low24, int mid24, int high16)
454  {
455  vtkIdType val = 0;
456  val |= high16;
457  val = val << 24;
458  val |= mid24;
459  val = val << 24;
460  val |= low24;
461  return val;
462  }
463 
467  virtual bool PassRequired(int pass);
468 
474  bool IsPropHit(int propid);
475 
479  virtual int GetPropID(int idx, vtkProp* vtkNotUsed(prop)) { return idx; }
480 
481  virtual void BeginSelection();
482  virtual void EndSelection();
483 
484  virtual void ProcessPixelBuffers();
485  void BuildPropHitList(unsigned char* rgbData);
486 
488 
491  void ReleasePixBuffers();
493  unsigned int Area[4];
499 
500  // At most 10 passes.
501  unsigned char* PixBuffer[10];
502  unsigned char* RawPixBuffer[10];
507  int PropID;
508  float PropColorValue[3];
509 
511 
513 
514 private:
515  vtkHardwareSelector(const vtkHardwareSelector&) = delete;
516  void operator=(const vtkHardwareSelector&) = delete;
517 
518  class vtkInternals;
519  vtkInternals* Internals;
520 };
521 
522 #endif
vtkHardwareSelector::POINT_ID_HIGH24
@ POINT_ID_HIGH24
Definition: vtkHardwareSelector.h:366
vtkHardwareSelector::PixelInformation::Valid
bool Valid
Definition: vtkHardwareSelector.h:132
vtkHardwareSelector::Convert
int Convert(unsigned long offset, unsigned char *pb)
Definition: vtkHardwareSelector.h:407
vtkHardwareSelector::Convert
int Convert(unsigned int pos[2], unsigned char *pb)
pos must be relative to the lower-left corner of this->Area.
Definition: vtkHardwareSelector.h:431
vtkHardwareSelector::PixelInformation::Prop
vtkProp * Prop
Definition: vtkHardwareSelector.h:135
vtkX3D::type
@ type
Definition: vtkX3D.h:522
vtkIdType
int vtkIdType
Definition: vtkType.h:338
vtkHardwareSelector::MaximumCellId
vtkIdType MaximumCellId
Definition: vtkHardwareSelector.h:497
vtkHardwareSelector::GetPixelBuffer
unsigned char * GetPixelBuffer(int passNo)
Definition: vtkHardwareSelector.h:231
vtkHardwareSelector::PROCESS_PASS
@ PROCESS_PASS
Definition: vtkHardwareSelector.h:367
vtkObject::New
static vtkObject * New()
Create an object with Debug turned off, modified time initialized to zero, and reference counting on.
vtkHardwareSelector::CurrentPass
int CurrentPass
Definition: vtkHardwareSelector.h:504
vtkObject
abstract base class for most VTK objects
Definition: vtkObject.h:62
vtkHardwareSelector::ProcessID
int ProcessID
Definition: vtkHardwareSelector.h:503
vtkHardwareSelector::Iteration
int Iteration
Definition: vtkHardwareSelector.h:505
vtkHardwareSelector::GetPropID
virtual int GetPropID(int idx, vtkProp *vtkNotUsed(prop))
Return a unique ID for the prop.
Definition: vtkHardwareSelector.h:479
vtkSelection
data object that represents a "selection" in VTK.
Definition: vtkSelection.h:57
vtkHardwareSelector::GenerateSelection
virtual vtkSelection * GenerateSelection()
Generates the vtkSelection from pixel buffers.
Definition: vtkHardwareSelector.h:324
vtkHardwareSelector::PassTypes
PassTypes
Definition: vtkHardwareSelector.h:358
vtkHardwareSelector::ACTOR_PASS
@ ACTOR_PASS
Definition: vtkHardwareSelector.h:361
vtkHardwareSelector::FieldAssociation
int FieldAssociation
Definition: vtkHardwareSelector.h:494
vtkHardwareSelector::POINT_ID_LOW24
@ POINT_ID_LOW24
Definition: vtkHardwareSelector.h:365
vtkHardwareSelector::MaximumPointId
vtkIdType MaximumPointId
Definition: vtkHardwareSelector.h:496
vtkHardwareSelector::Renderer
vtkRenderer * Renderer
Definition: vtkHardwareSelector.h:492
vtkHardwareSelector::PixelInformation::PixelInformation
PixelInformation()
Definition: vtkHardwareSelector.h:138
vtkX3D::offset
@ offset
Definition: vtkX3D.h:444
vtkHardwareSelector::GetPixelInformation
PixelInformation GetPixelInformation(const unsigned int display_position[2])
Definition: vtkHardwareSelector.h:217
vtkHardwareSelector
Definition: vtkHardwareSelector.h:123
vtkHardwareSelector::PixelInformation::AttributeID
vtkIdType AttributeID
Definition: vtkHardwareSelector.h:137
vtkIndent
a simple class to control print indentation
Definition: vtkIndent.h:33
vtkTextureObject
abstracts an OpenGL texture object.
Definition: vtkTextureObject.h:40
vtkHardwareSelector::GenerateSelection
virtual vtkSelection * GenerateSelection(unsigned int r[4])
Definition: vtkHardwareSelector.h:325
vtkHardwareSelector::PropID
int PropID
Definition: vtkHardwareSelector.h:507
vtkHardwareSelector::GetID
vtkIdType GetID(int low24, int mid24, int high16)
Definition: vtkHardwareSelector.h:453
vtkObject::PrintSelf
void PrintSelf(ostream &os, vtkIndent indent) override
Methods invoked by print to print information about the object including superclasses.
vtkHardwareSelector::CaptureZValues
bool CaptureZValues
Definition: vtkHardwareSelector.h:512
vtkHardwareSelector::COMPOSITE_INDEX_PASS
@ COMPOSITE_INDEX_PASS
Definition: vtkHardwareSelector.h:363
vtkHardwareSelector::PreCapturePass
virtual void PreCapturePass(int pass)
Definition: vtkHardwareSelector.h:397
vtkHardwareSelector::ActorPassOnly
bool ActorPassOnly
Definition: vtkHardwareSelector.h:510
vtkObject.h
vtkHardwareSelector::CELL_ID_HIGH24
@ CELL_ID_HIGH24
Definition: vtkHardwareSelector.h:370
vtkHardwareSelector::PixelInformation::PropID
int PropID
Definition: vtkHardwareSelector.h:134
vtkProp
abstract superclass for all actors, volumes and annotations
Definition: vtkProp.h:53
vtkX3D::string
@ string
Definition: vtkX3D.h:496
vtkHardwareSelector::Convert
int Convert(int xx, int yy, unsigned char *pb)
Definition: vtkHardwareSelector.h:432
vtkHardwareSelector::GetRawPixelBuffer
unsigned char * GetRawPixelBuffer(int passNo)
Definition: vtkHardwareSelector.h:230
vtkHardwareSelector::InPropRender
int InPropRender
Definition: vtkHardwareSelector.h:506
vtkRenderer
abstract specification for renderers
Definition: vtkRenderer.h:67
vtkHardwareSelector::UseProcessIdFromData
bool UseProcessIdFromData
Definition: vtkHardwareSelector.h:495
vtkHardwareSelector::PixelInformation::ProcessID
int ProcessID
Definition: vtkHardwareSelector.h:133
vtkHardwareSelector::CELL_ID_LOW24
@ CELL_ID_LOW24
Definition: vtkHardwareSelector.h:369
vtkRenderWindow
create a window for renderers to draw into
Definition: vtkRenderWindow.h:93
vtkHardwareSelector::Convert
static void Convert(vtkIdType id, float tcoord[3])
Definition: vtkHardwareSelector.h:381
vtkHardwareSelector::PixelInformation::CompositeID
unsigned int CompositeID
Definition: vtkHardwareSelector.h:136
vtkHardwareSelector::ClearBuffers
void ClearBuffers()
Definition: vtkHardwareSelector.h:228
vtkX3D::index
@ index
Definition: vtkX3D.h:252
vtkHardwareSelector::PixelInformation
Struct used to return information about a pixel location.
Definition: vtkHardwareSelector.h:130
vtkHardwareSelector::GetPixelInformation
PixelInformation GetPixelInformation(const unsigned int display_position[2], int maxDist)
Definition: vtkHardwareSelector.h:221
vtkHardwareSelector::PostCapturePass
virtual void PostCapturePass(int pass)
Definition: vtkHardwareSelector.h:398