VTK  9.4.20241013
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
102 <a href="https://examples.vtk.org/site/Cxx/Filtering/ExtractVisibleCells">
103 <div class="examplegrid_container">
104 <img src="https://raw.githubusercontent.com/Kitware/vtk-examples/gh-pages/src/Testing/Baseline//Cxx/Filtering/TestExtractVisibleCells.png">
105 <div class="examplegrid_overlay">
106 <div class="examplegrid_text">ExtractVisibleCells</div>
107 </div>
108 </div>
109 </a>
110
111 </div>
112
113 @endhtmlonly
114
115 @par Tests:
116 @ref c2_vtk_t_vtkHardwareSelector "vtkHardwareSelector (Tests)"
117 */
118
119#ifndef vtkHardwareSelector_h
120#define vtkHardwareSelector_h
121
122#include "vtkObject.h"
123#include "vtkRenderingCoreModule.h" // For export macro
124
125#include <string> // for std::string
126
127VTK_ABI_NAMESPACE_BEGIN
128class vtkRenderer;
129class vtkRenderWindow;
130class vtkSelection;
131class vtkProp;
132class vtkTextureObject;
133
134class VTKRENDERINGCORE_EXPORT vtkHardwareSelector : public vtkObject
135{
136public:
138
142 {
143 bool Valid;
147 unsigned int CompositeID;
153 : Valid(false)
154 , ProcessID(-1)
155 , PropID(-1)
156 , Prop(nullptr)
157 , CompositeID(0)
158 , AttributeID(-1)
159 , CellGridCellTypeID(-1)
160 , CellGridSourceSpecID(-1)
161 , CellGridTupleID(-1)
162 {
163 }
164 };
166
169 void PrintSelf(ostream& os, vtkIndent indent) override;
170
172
175 virtual void SetRenderer(vtkRenderer*);
176 vtkGetObjectMacro(Renderer, vtkRenderer);
178
180
183 vtkSetVector4Macro(Area, unsigned int);
184 vtkGetVector4Macro(Area, unsigned int);
186
188
198 vtkSetMacro(FieldAssociation, int);
199 vtkGetMacro(FieldAssociation, int);
201
203
208 vtkSetMacro(UseProcessIdFromData, bool);
209 vtkGetMacro(UseProcessIdFromData, bool);
211
217
219
232 virtual bool CaptureBuffers();
233 PixelInformation GetPixelInformation(const unsigned int display_position[2])
234 {
235 return this->GetPixelInformation(display_position, 0);
236 }
237 PixelInformation GetPixelInformation(const unsigned int display_position[2], int maxDist)
238 {
239 unsigned int temp[2];
240 return this->GetPixelInformation(display_position, maxDist, temp);
241 }
243 const unsigned int display_position[2], int maxDist, unsigned int selected_position[2]);
244 void ClearBuffers() { this->ReleasePixBuffers(); }
245 // raw is before processing
246 unsigned char* GetRawPixelBuffer(int passNo) { return this->RawPixBuffer[passNo]; }
247 unsigned char* GetPixelBuffer(int passNo) { return this->PixBuffer[passNo]; }
249
254 virtual void RenderCompositeIndex(unsigned int index);
255
257
263 virtual void UpdateMaximumCellId(vtkIdType attribid);
264 virtual void UpdateMaximumPointId(vtkIdType attribid);
267
272 virtual void RenderProcessId(unsigned int processid);
273
278 int Render(vtkRenderer* renderer, vtkProp** propArray, int propArrayCount);
279
281
285 vtkGetMacro(ActorPassOnly, bool);
286 vtkSetMacro(ActorPassOnly, bool);
288
290
296 vtkGetMacro(CaptureZValues, bool);
297 vtkSetMacro(CaptureZValues, bool);
299
301
304 virtual void BeginRenderProp();
305 virtual void EndRenderProp();
307
309
313 vtkSetMacro(ProcessID, int);
314 vtkGetMacro(ProcessID, int);
316
318
321 vtkGetVector3Macro(PropColorValue, float);
322 vtkSetVector3Macro(PropColorValue, float);
325
327
330 vtkGetMacro(CurrentPass, int);
332
341 virtual vtkSelection* GenerateSelection() { return GenerateSelection(this->Area); }
342 virtual vtkSelection* GenerateSelection(unsigned int r[4])
343 {
344 return GenerateSelection(r[0], r[1], r[2], r[3]);
345 }
347 unsigned int x1, unsigned int y1, unsigned int x2, unsigned int y2);
348
355 virtual vtkSelection* GeneratePolygonSelection(int* polygonPoints, vtkIdType count);
356
362
363 // it is very critical that these passes happen in the right order
364 // this is because of two complexities
365 //
366 // Compositing engines such as iceT send each pass as it
367 // renders. This means
368 //
369 // Mappers use point Ids or cell Id to update the process
370 // and composite ids. So the point and cell id passes
371 // have to happen before the last process and compoite
372 // passes respectively
373 //
374 //
376 {
377 // always must be first so that the prop IDs are set
379 // must always be second for composite mapper
381
383 POINT_ID_HIGH24, // if needed
384 PROCESS_PASS, // must be after point id pass
385
387 CELL_ID_HIGH24, // if needed
388
393
394 MAX_KNOWN_PASS = CELLGRID_TUPLE_ID_HIGH24,
395 MIN_KNOWN_PASS = ACTOR_PASS
396 };
397
401 std::string PassTypeToString(PassTypes type);
402
403 static void Convert(vtkIdType id, float tcoord[3])
404 {
405 tcoord[0] = static_cast<float>((id & 0xff) / 255.0);
406 tcoord[1] = static_cast<float>(((id & 0xff00) >> 8) / 255.0);
407 tcoord[2] = static_cast<float>(((id & 0xff0000) >> 16) / 255.0);
408 }
409
410 // grab the pixel buffer and save it
411 // typically called internally
412 virtual void SavePixelBuffer(int passNo);
413
414 // does the selection process have high cell data
415 // requiring a high24 pass
417
418 // does the selection process have high point data
419 // requiring a high24 pass
421
422 // deos the selection process have high cell grid tuple ids
423 // requiring a high24 pass
425
426protected:
429
430 // Used to notify subclasses when a capture pass is occurring.
431 virtual void PreCapturePass(int pass) { (void)pass; }
432 virtual void PostCapturePass(int pass) { (void)pass; }
433
434 // Called internally before and after each prop is rendered
435 // for device specific configuration/preparation etc.
437 virtual void EndRenderProp(vtkRenderWindow*) = 0;
438
439 double GetZValue(int propid);
440
441 int Convert(unsigned long offset, unsigned char* pb)
442 {
443 if (!pb)
444 {
445 return 0;
446 }
447 offset = offset * 3;
448 unsigned char rgb[3];
449 rgb[0] = pb[offset];
450 rgb[1] = pb[offset + 1];
451 rgb[2] = pb[offset + 2];
452 int val = 0;
453 val |= rgb[2];
454 val = val << 8;
455 val |= rgb[1];
456 val = val << 8;
457 val |= rgb[0];
458 return val;
459 }
460
462
465 int Convert(unsigned int pos[2], unsigned char* pb) { return this->Convert(pos[0], pos[1], pb); }
466 int Convert(int xx, int yy, unsigned char* pb)
467 {
468 if (!pb)
469 {
470 return 0;
471 }
472 int offset = (yy * static_cast<int>(this->Area[2] - this->Area[0] + 1) + xx) * 3;
473 unsigned char rgb[3];
474 rgb[0] = pb[offset];
475 rgb[1] = pb[offset + 1];
476 rgb[2] = pb[offset + 2];
477 int val = 0;
478 val |= rgb[2];
479 val = val << 8;
480 val |= rgb[1];
481 val = val << 8;
482 val |= rgb[0];
483 return val;
484 }
486
487 vtkIdType GetID(int low24, int mid24, int high16)
488 {
489 vtkIdType val = 0;
490 val |= high16;
491 val = val << 24;
492 val |= mid24;
493 val = val << 24;
494 val |= low24;
495 return val;
496 }
497
501 virtual bool PassRequired(int pass);
502
508 bool IsPropHit(int propid);
509
513 virtual int GetPropID(int idx, vtkProp* vtkNotUsed(prop)) { return idx; }
514
515 virtual void BeginSelection();
516 virtual void EndSelection();
517
518 virtual void ProcessPixelBuffers();
519 void BuildPropHitList(unsigned char* rgbData);
520
522
527 unsigned int Area[4];
534
535 // At most 11 passes.
536 unsigned char* PixBuffer[11];
537 unsigned char* RawPixBuffer[11];
543 float PropColorValue[3];
544
546
548
549private:
551 void operator=(const vtkHardwareSelector&) = delete;
552
553 class vtkInternals;
554 vtkInternals* Internals;
555};
556
557VTK_ABI_NAMESPACE_END
558#endif
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 vtkSelection * GenerateSelection(unsigned int x1, unsigned int y1, unsigned int x2, unsigned int y2)
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.
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 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 UpdateMaximumCellGridTupleId(vtkIdType attribid)
Called by any vtkMapper or vtkProp subclass to indicate the maximum cell or point attribute ID it use...
virtual void ProcessPixelBuffers()
vtkSelection * Select()
Perform the selection.
virtual vtkSelection * GenerateSelection()
Generates the vtkSelection from pixel buffers.
virtual vtkSelection * GenerateSelection(unsigned int r[4])
vtkIdType MaximumPointId
Clears all pixel buffers.
int FieldAssociation
Clears all pixel buffers.
static vtkHardwareSelector * New()
~vtkHardwareSelector() override
void ReleasePixBuffers()
Clears all pixel buffers.
virtual vtkSelection * GeneratePolygonSelection(int *polygonPoints, vtkIdType count)
Generates the vtkSelection from pixel buffers.
virtual void BeginSelection()
vtkIdType MaximumCellGridTupleId
Clears all pixel buffers.
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.
bool HasHighCellGridTupleIds()
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 void BeginRenderProp(vtkRenderWindow *)=0
double GetZValue(int propid)
void ClearBuffers()
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.
unsigned char * GetPixelBuffer(int passNo)
It is possible to use the vtkHardwareSelector for a custom picking.
vtkProp * GetPropFromID(int id)
returns the prop associated with a ID.
virtual bool CaptureBuffers()
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:108
abstract base class for most VTK objects
Definition vtkObject.h:162
abstract superclass for all actors, volumes and annotations
Definition vtkProp.h:66
create a window for renderers to draw into
abstract specification for renderers
data object that represents a "selection" in VTK.
abstracts an OpenGL texture object.
Struct used to return information about a pixel location.
int vtkIdType
Definition vtkType.h:315
#define VTK_NEWINSTANCE