You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
nmWTAI-Platform/3rd/VTK7.1/include/vtkHardwareSelector.h

414 lines
12 KiB
C++

/*=========================================================================
Program: Visualization Toolkit
Module: vtkHardwareSelector.h
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notice for more information.
=========================================================================*/
/**
* @class vtkHardwareSelector
* @brief manager for OpenGL-based selection.
*
* vtkHardwareSelector is a helper that orchestrates color buffer based
* selection. This relies on OpenGL.
* vtkHardwareSelector can be used to select visible cells or points within a
* given rectangle of the RenderWindow.
* To use it, call in order:
* \li SetRenderer() - to select the renderer in which we
* want to select the cells/points.
* \li SetArea() - to set the rectangular region in the render window to select
* in.
* \li SetFieldAssociation() - to select the attribute to select i.e.
* cells/points etc.
* \li Finally, call Select().
* Select will cause the attached vtkRenderer to render in a special color mode,
* where each cell/point is given it own color so that later inspection of the
* Rendered Pixels can determine what cells are visible. Select() returns a new
* vtkSelection instance with the cells/points selected.
*
* Limitations:
* Antialiasing will break this class. If your graphics card settings force
* their use this class will return invalid results.
*
* Currently only cells from PolyDataMappers can be selected from. When
* vtkRenderer::Selector is non-null vtkPainterPolyDataMapper uses the
* vtkHardwareSelectionPolyDataPainter which make appropriate calls to
* BeginRenderProp(), EndRenderProp(), RenderProcessId(),
* RenderAttributeId() to render colors
* correctly. Until alternatives to vtkHardwareSelectionPolyDataPainter
* exist that can do a similar coloration of other vtkDataSet types, only
* polygonal data can be selected. If you need to select other data types,
* consider using vtkDataSetMapper and turning on it's PassThroughCellIds
* feature, or using vtkFrustumExtractor.
*
* Only Opaque geometry in Actors is selected from. Assemblies and LODMappers
* are not currently supported.
*
* During selection, visible datasets that can not be selected from are
* temporarily hidden so as not to produce invalid indices from their colors.
*
* @sa
* vtkIdentColoredPainter
*/
#ifndef vtkHardwareSelector_h
#define vtkHardwareSelector_h
#include "vtkRenderingCoreModule.h" // For export macro
#include "vtkObject.h"
#include <string> // for std::string
class vtkRenderer;
class vtkRenderWindow;
class vtkSelection;
class vtkProp;
class vtkTextureObject;
class VTKRENDERINGCORE_EXPORT vtkHardwareSelector : public vtkObject
{
public:
//@{
/**
* Struct used to return information about a pixel location.
*/
struct PixelInformation
{
bool Valid;
int ProcessID;
int PropID;
vtkProp* Prop;
unsigned int CompositeID;
vtkIdType AttributeID;
PixelInformation():
Valid(false),
ProcessID(-1),
Prop(NULL),
CompositeID(0),
AttributeID(-1) {}
};
//@}
public:
static vtkHardwareSelector* New();
vtkTypeMacro(vtkHardwareSelector, vtkObject);
void PrintSelf(ostream& os, vtkIndent indent);
//@{
/**
* Get/Set the renderer to perform the selection on.
*/
virtual void SetRenderer(vtkRenderer*);
vtkGetObjectMacro(Renderer, vtkRenderer);
//@}
//@{
/**
* Get/Set the area to select as (xmin, ymin, xmax, ymax).
*/
vtkSetVector4Macro(Area, unsigned int);
vtkGetVector4Macro(Area, unsigned int);
//@}
//@{
/**
* Set the field type to select. Valid values are
* \li vtkDataObject::FIELD_ASSOCIATION_POINTS
* \li vtkDataObject::FIELD_ASSOCIATION_CELLS
* \li vtkDataObject::FIELD_ASSOCIATION_VERTICES
* \li vtkDataObject::FIELD_ASSOCIATION_EDGES
* \li vtkDataObject::FIELD_ASSOCIATION_ROWS
* Currently only FIELD_ASSOCIATION_POINTS and FIELD_ASSOCIATION_CELLS are
* supported.
*/
vtkSetMacro(FieldAssociation, int);
vtkGetMacro(FieldAssociation, int);
//@}
//@{
/**
* In some parallel rendering setups, the process id for elements must be
* obtained from the data itself, rather than the rendering process' id. In
* that case, set this flag to ON (default OFF).
*/
vtkSetMacro(UseProcessIdFromData, bool);
vtkGetMacro(UseProcessIdFromData, bool);
//@}
/**
* Perform the selection. Returns a new instance of vtkSelection containing
* the selection on success.
*/
vtkSelection* Select();
//@{
/**
* It is possible to use the vtkHardwareSelector for a custom picking. (Look
* at vtkScenePicker). In that case instead of Select() on can use
* CaptureBuffers() to render the selection buffers and then get information
* about pixel locations suing GetPixelInformation(). Use ClearBuffers() to
* clear buffers after one's done with the scene.
* The optional final parameter maxDist will look for a cell within the specified
* number of pixels from display_position. When using the overload with the
* optional \c selected_position argument, selected_position is filled with
* the position for which the PixelInformation is being returned. This is
* useful when maxDist > 0 to determine which position's pixel information is
* was returned.
*/
virtual bool CaptureBuffers();
PixelInformation GetPixelInformation(const unsigned int display_position[2])
{ return this->GetPixelInformation(display_position, 0); }
PixelInformation GetPixelInformation(const unsigned int display_position[2], int maxDist)
{ unsigned int temp[2]; return this->GetPixelInformation(display_position, maxDist, temp); }
PixelInformation GetPixelInformation(const unsigned int display_position[2],
int maxDist, unsigned int selected_position[2]);
void ClearBuffers()
{ this->ReleasePixBuffers(); }
//@}
/**
* Called by any vtkMapper or vtkProp subclass to render a composite-index.
* Currently indices >= 0xffffff are not supported.
*/
virtual void RenderCompositeIndex(unsigned int index);
/**
* Called by any vtkMapper or vtkProp subclass to render an attribute's id.
*/
virtual void RenderAttributeId(vtkIdType attribid);
/**
* Called by any vtkMapper or subclass to render process id. This has any
* effect when this->UseProcessIdFromData is true.
*/
virtual void RenderProcessId(unsigned int processid);
/**
* Called by vtkRenderer to render the selection pass.
* Returns the number of props rendered.
*/
int Render(vtkRenderer* renderer, vtkProp** propArray, int propArrayCount);
//@{
/**
* Called by the mapper (vtkHardwareSelectionPolyDataPainter) before and after
* rendering each prop.
*/
virtual void BeginRenderProp();
virtual void EndRenderProp();
//@}
//@{
/**
* Get/Set the process id. If process id < 0 (default -1), then the
* PROCESS_PASS is not rendered.
*/
vtkSetMacro(ProcessID, int);
vtkGetMacro(ProcessID, int);
//@}
//@{
/**
* Get/Set the color to be used by the prop when drawing
*/
vtkGetVector3Macro(PropColorValue,float);
vtkSetVector3Macro(PropColorValue,float);
//@}
//@{
/**
* Get the current pass number.
*/
vtkGetMacro(CurrentPass, int);
//@}
/**
* Generates the vtkSelection from pixel buffers.
* Requires that CaptureBuffers() has already been called.
* Optionally you may pass a screen region (xmin, ymin, xmax, ymax)
* to generate a selection from. The region must be a subregion
* of the region specified by SetArea(), otherwise it will be
* clipped to that region.
*/
virtual vtkSelection* GenerateSelection()
{ return GenerateSelection(this->Area); }
virtual vtkSelection* GenerateSelection(unsigned int r[4])
{ return GenerateSelection(r[0], r[1], r[2], r[3]); }
virtual vtkSelection* GenerateSelection(
unsigned int x1, unsigned int y1,
unsigned int x2, unsigned int y2);
/**
* Generates the vtkSelection from pixel buffers.
* Same as GenerateSelection, except this one use a polygon, instead
* of a rectangle region, and select elements inside the polygon.
* NOTE: The CaptureBuffers() needs to be called first.
*/
virtual vtkSelection* GeneratePolygonSelection(
int* polygonPoints, vtkIdType count);
/**
* returns the prop associated with a ID. This is valid only until
* ReleasePixBuffers() gets called.
*/
vtkProp* GetPropFromID(int id);
enum PassTypes
{
PROCESS_PASS,
ACTOR_PASS,
COMPOSITE_INDEX_PASS,
ID_LOW24,
ID_MID24,
ID_HIGH16,
MAX_KNOWN_PASS = ID_HIGH16,
MIN_KNOWN_PASS = PROCESS_PASS
};
/**
* Convert a PassTypes enum value to a human readable string.
*/
std::string PassTypeToString(PassTypes type);
static void Convert(int id, float tcoord[3])
{
tcoord[0] = static_cast<float>((id & 0xff)/255.0);
tcoord[1] = static_cast<float>(((id & 0xff00) >> 8)/255.0);
tcoord[2] = static_cast<float>(((id & 0xff0000) >> 16)/255.0);
}
protected:
vtkHardwareSelector();
~vtkHardwareSelector();
// Used to notify subclasses when a capture pass is occuring.
virtual void PreCapturePass(int pass) { (void)pass; }
virtual void PostCapturePass(int pass) { (void)pass; }
// Called internally before and after each prop is rendered
// for device specific configuration/preparation etc.
virtual void BeginRenderProp(vtkRenderWindow *) = 0;
virtual void EndRenderProp(vtkRenderWindow *) = 0;
int Convert(unsigned long offset, unsigned char* pb)
{
if (!pb)
{
return 0;
}
offset = offset * 3;
unsigned char rgb[3];
rgb[0] = pb[offset];
rgb[1] = pb[offset+1];
rgb[2] = pb[offset+2];
int val = 0;
val |= rgb[2];
val = val << 8;
val |= rgb[1];
val = val << 8;
val |= rgb[0];
return val;
}
//@{
/**
* \c pos must be relative to the lower-left corner of this->Area.
*/
int Convert(unsigned int pos[2], unsigned char* pb)
{ return this->Convert(pos[0], pos[1], pb); }
int Convert(int xx, int yy, unsigned char* pb)
{
if (!pb)
{
return 0;
}
int offset = (yy * static_cast<int>(this->Area[2]-this->Area[0]+1) + xx) * 3;
unsigned char rgb[3];
rgb[0] = pb[offset];
rgb[1] = pb[offset+1];
rgb[2] = pb[offset+2];
int val = 0;
val |= rgb[2];
val = val << 8;
val |= rgb[1];
val = val << 8;
val |= rgb[0];
return val;
}
//@}
vtkIdType GetID(int low24, int mid24, int high16)
{
vtkIdType val = 0;
val |= high16;
val = val << 24;
val |= mid24;
val = val << 24;
val |= low24;
return val;
}
/**
* Returns is the pass indicated is needed.
*/
virtual bool PassRequired(int pass);
/**
* After the ACTOR_PASS this return true or false depending upon whether the
* prop was hit in the ACTOR_PASS. This makes it possible to skip props that
* are not involved in the selection after the first pass.
*/
bool IsPropHit(int propid);
/**
* Return a unique ID for the prop.
*/
virtual int GetPropID(int idx, vtkProp* vtkNotUsed(prop))
{ return idx; }
virtual void BeginSelection();
virtual void EndSelection();
virtual void SavePixelBuffer(int passNo);
void BuildPropHitList(unsigned char* rgbData);
//@{
/**
* Clears all pixel buffers.
*/
void ReleasePixBuffers();
vtkRenderer* Renderer;
unsigned int Area[4];
int FieldAssociation;
bool UseProcessIdFromData;
vtkIdType MaxAttributeId;
//@}
// At most 10 passes.
unsigned char* PixBuffer[10];
int ProcessID;
int CurrentPass;
int InPropRender;
int PropID;
float PropColorValue[3];
private:
vtkHardwareSelector(const vtkHardwareSelector&) VTK_DELETE_FUNCTION;
void operator=(const vtkHardwareSelector&) VTK_DELETE_FUNCTION;
class vtkInternals;
vtkInternals* Internals;
};
#endif