VTK  9.0.20201130
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, // 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 
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  // does the selection process have high cell data
393  // requiring a high24 pass
394  bool HasHighCellIds();
395 
396  // does the selection process have high point data
397  // requiring a high24 pass
398  bool HasHighPointIds();
399 
400 protected:
402  ~vtkHardwareSelector() override;
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 
499  void ReleasePixBuffers();
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 #endif
vtkHardwareSelector::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:415
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:439
vtkHardwareSelector::PixelInformation::Prop
vtkProp * Prop
Definition: vtkHardwareSelector.h:135
vtkX3D::type
Definition: vtkX3D.h:522
vtkIdType
int vtkIdType
Definition: vtkType.h:330
vtkHardwareSelector::MaximumCellId
vtkIdType MaximumCellId
Definition: vtkHardwareSelector.h:505
vtkHardwareSelector::GetPixelBuffer
unsigned char * GetPixelBuffer(int passNo)
Definition: vtkHardwareSelector.h:231
vtkHardwareSelector::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:512
vtkObject
abstract base class for most VTK objects
Definition: vtkObject.h:62
vtkHardwareSelector::ProcessID
int ProcessID
Definition: vtkHardwareSelector.h:511
vtkHardwareSelector::Iteration
int Iteration
Definition: vtkHardwareSelector.h:513
vtkHardwareSelector::GetPropID
virtual int GetPropID(int idx, vtkProp *vtkNotUsed(prop))
Return a unique ID for the prop.
Definition: vtkHardwareSelector.h:487
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
Definition: vtkHardwareSelector.h:361
vtkHardwareSelector::FieldAssociation
int FieldAssociation
Definition: vtkHardwareSelector.h:502
vtkHardwareSelector::POINT_ID_LOW24
Definition: vtkHardwareSelector.h:365
vtkHardwareSelector::MaximumPointId
vtkIdType MaximumPointId
Definition: vtkHardwareSelector.h:504
vtkHardwareSelector::Renderer
vtkRenderer * Renderer
Definition: vtkHardwareSelector.h:500
vtkHardwareSelector::PixelInformation::PixelInformation
PixelInformation()
Definition: vtkHardwareSelector.h:138
vtkX3D::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:515
vtkHardwareSelector::GetID
vtkIdType GetID(int low24, int mid24, int high16)
Definition: vtkHardwareSelector.h:461
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:520
vtkHardwareSelector::COMPOSITE_INDEX_PASS
Definition: vtkHardwareSelector.h:363
vtkHardwareSelector::PreCapturePass
virtual void PreCapturePass(int pass)
Definition: vtkHardwareSelector.h:405
vtkHardwareSelector::ActorPassOnly
bool ActorPassOnly
Definition: vtkHardwareSelector.h:518
vtkObject.h
vtkHardwareSelector::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:56
vtkX3D::string
Definition: vtkX3D.h:496
vtkHardwareSelector::Convert
int Convert(int xx, int yy, unsigned char *pb)
Definition: vtkHardwareSelector.h:440
vtkHardwareSelector::GetRawPixelBuffer
unsigned char * GetRawPixelBuffer(int passNo)
Definition: vtkHardwareSelector.h:230
vtkHardwareSelector::InPropRender
int InPropRender
Definition: vtkHardwareSelector.h:514
vtkRenderer
abstract specification for renderers
Definition: vtkRenderer.h:67
vtkHardwareSelector::UseProcessIdFromData
bool UseProcessIdFromData
Definition: vtkHardwareSelector.h:503
vtkHardwareSelector::PixelInformation::ProcessID
int ProcessID
Definition: vtkHardwareSelector.h:133
vtkHardwareSelector::CELL_ID_LOW24
Definition: vtkHardwareSelector.h:369
vtkRenderWindow
create a window for renderers to draw into
Definition: vtkRenderWindow.h:95
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
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:406