VTK  9.2.6
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 composites 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 </div>
114
115 @endhtmlonly
116
117 @par Tests:
118 @ref c2_vtk_t_vtkHardwareSelector "vtkHardwareSelector (Tests)"
119 */
120
121#ifndef vtkHardwareSelector_h
122#define vtkHardwareSelector_h
123
124#include "vtkObject.h"
125#include "vtkRenderingCoreModule.h" // For export macro
126
127#include <string> // for std::string
128
129class vtkRenderer;
130class vtkRenderWindow;
131class vtkSelection;
132class vtkProp;
133class vtkTextureObject;
134
135class VTKRENDERINGCORE_EXPORT vtkHardwareSelector : public vtkObject
136{
137public:
139
143 {
144 bool Valid;
148 unsigned int CompositeID;
151 : Valid(false)
152 , ProcessID(-1)
153 , PropID(-1)
154 , Prop(nullptr)
155 , CompositeID(0)
156 , AttributeID(-1)
157 {
158 }
159 };
161
162public:
165 void PrintSelf(ostream& os, vtkIndent indent) override;
166
168
171 virtual void SetRenderer(vtkRenderer*);
172 vtkGetObjectMacro(Renderer, vtkRenderer);
174
176
179 vtkSetVector4Macro(Area, unsigned int);
180 vtkGetVector4Macro(Area, unsigned int);
182
184
194 vtkSetMacro(FieldAssociation, int);
195 vtkGetMacro(FieldAssociation, int);
197
199
204 vtkSetMacro(UseProcessIdFromData, bool);
205 vtkGetMacro(UseProcessIdFromData, bool);
207
213
215
228 virtual bool CaptureBuffers();
229 PixelInformation GetPixelInformation(const unsigned int display_position[2])
230 {
231 return this->GetPixelInformation(display_position, 0);
232 }
233 PixelInformation GetPixelInformation(const unsigned int display_position[2], int maxDist)
234 {
235 unsigned int temp[2];
236 return this->GetPixelInformation(display_position, maxDist, temp);
237 }
239 const unsigned int display_position[2], int maxDist, unsigned int selected_position[2]);
240 void ClearBuffers() { this->ReleasePixBuffers(); }
241 // raw is before processing
242 unsigned char* GetRawPixelBuffer(int passNo) { return this->RawPixBuffer[passNo]; }
243 unsigned char* GetPixelBuffer(int passNo) { return this->PixBuffer[passNo]; }
245
250 virtual void RenderCompositeIndex(unsigned int index);
251
253
259 virtual void UpdateMaximumCellId(vtkIdType attribid);
260 virtual void UpdateMaximumPointId(vtkIdType attribid);
262
267 virtual void RenderProcessId(unsigned int processid);
268
273 int Render(vtkRenderer* renderer, vtkProp** propArray, int propArrayCount);
274
276
280 vtkGetMacro(ActorPassOnly, bool);
281 vtkSetMacro(ActorPassOnly, bool);
283
285
291 vtkGetMacro(CaptureZValues, bool);
292 vtkSetMacro(CaptureZValues, bool);
294
296
299 virtual void BeginRenderProp();
300 virtual void EndRenderProp();
302
304
308 vtkSetMacro(ProcessID, int);
309 vtkGetMacro(ProcessID, int);
311
313
316 vtkGetVector3Macro(PropColorValue, float);
317 vtkSetVector3Macro(PropColorValue, float);
320
322
325 vtkGetMacro(CurrentPass, int);
327
336 virtual vtkSelection* GenerateSelection() { return GenerateSelection(this->Area); }
337 virtual vtkSelection* GenerateSelection(unsigned int r[4])
338 {
339 return GenerateSelection(r[0], r[1], r[2], r[3]);
340 }
342 unsigned int x1, unsigned int y1, unsigned int x2, unsigned int y2);
343
350 virtual vtkSelection* GeneratePolygonSelection(int* polygonPoints, vtkIdType count);
351
357
358 // it is very critical that these passes happen in the right order
359 // this is because of two complexities
360 //
361 // Compositing engines such as iceT send each pass as it
362 // renders. This means
363 //
364 // Mappers use point Ids or cell Id to update the process
365 // and composite ids. So the point and cell id passes
366 // have to happen before the last process and compoite
367 // passes respectively
368 //
369 //
371 {
372 // always must be first so that the prop IDs are set
374 // must always be second for composite mapper
376
378 POINT_ID_HIGH24, // if needed
379 PROCESS_PASS, // must be after point id pass
380
382 CELL_ID_HIGH24, // if needed
383
384 MAX_KNOWN_PASS = CELL_ID_HIGH24,
385 MIN_KNOWN_PASS = ACTOR_PASS
386 };
387
391 std::string PassTypeToString(PassTypes type);
392
393 static void Convert(vtkIdType id, float tcoord[3])
394 {
395 tcoord[0] = static_cast<float>((id & 0xff) / 255.0);
396 tcoord[1] = static_cast<float>(((id & 0xff00) >> 8) / 255.0);
397 tcoord[2] = static_cast<float>(((id & 0xff0000) >> 16) / 255.0);
398 }
399
400 // grab the pixel buffer and save it
401 // typically called internally
402 virtual void SavePixelBuffer(int passNo);
403
404 // does the selection process have high cell data
405 // requiring a high24 pass
407
408 // does the selection process have high point data
409 // requiring a high24 pass
411
412protected:
415
416 // Used to notify subclasses when a capture pass is occurring.
417 virtual void PreCapturePass(int pass) { (void)pass; }
418 virtual void PostCapturePass(int pass) { (void)pass; }
419
420 // Called internally before and after each prop is rendered
421 // for device specific configuration/preparation etc.
423 virtual void EndRenderProp(vtkRenderWindow*) = 0;
424
425 double GetZValue(int propid);
426
427 int Convert(unsigned long offset, unsigned char* pb)
428 {
429 if (!pb)
430 {
431 return 0;
432 }
433 offset = offset * 3;
434 unsigned char rgb[3];
435 rgb[0] = pb[offset];
436 rgb[1] = pb[offset + 1];
437 rgb[2] = pb[offset + 2];
438 int val = 0;
439 val |= rgb[2];
440 val = val << 8;
441 val |= rgb[1];
442 val = val << 8;
443 val |= rgb[0];
444 return val;
445 }
446
448
451 int Convert(unsigned int pos[2], unsigned char* pb) { return this->Convert(pos[0], pos[1], pb); }
452 int Convert(int xx, int yy, unsigned char* pb)
453 {
454 if (!pb)
455 {
456 return 0;
457 }
458 int offset = (yy * static_cast<int>(this->Area[2] - this->Area[0] + 1) + xx) * 3;
459 unsigned char rgb[3];
460 rgb[0] = pb[offset];
461 rgb[1] = pb[offset + 1];
462 rgb[2] = pb[offset + 2];
463 int val = 0;
464 val |= rgb[2];
465 val = val << 8;
466 val |= rgb[1];
467 val = val << 8;
468 val |= rgb[0];
469 return val;
470 }
472
473 vtkIdType GetID(int low24, int mid24, int high16)
474 {
475 vtkIdType val = 0;
476 val |= high16;
477 val = val << 24;
478 val |= mid24;
479 val = val << 24;
480 val |= low24;
481 return val;
482 }
483
487 virtual bool PassRequired(int pass);
488
494 bool IsPropHit(int propid);
495
499 virtual int GetPropID(int idx, vtkProp* vtkNotUsed(prop)) { return idx; }
500
501 virtual void BeginSelection();
502 virtual void EndSelection();
503
504 virtual void ProcessPixelBuffers();
505 void BuildPropHitList(unsigned char* rgbData);
506
508
513 unsigned int Area[4];
519
520 // At most 10 passes.
521 unsigned char* PixBuffer[10];
522 unsigned char* RawPixBuffer[10];
528 float PropColorValue[3];
529
531
533
534private:
536 void operator=(const vtkHardwareSelector&) = delete;
537
538 class vtkInternals;
539 vtkInternals* Internals;
540};
541
542#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 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()
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 void BeginRenderProp(vtkRenderWindow *)=0
double GetZValue(int propid)
void ClearBuffers()
It is possible to use the vtkHardwareSelector for a custom picking.
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.
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:49
abstract base class for most VTK objects
Definition vtkObject.h:72
abstract superclass for all actors, volumes and annotations
Definition vtkProp.h:66
create a window for renderers to draw into
abstract specification for renderers
Definition vtkRenderer.h:82
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:332
#define VTK_NEWINSTANCE