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.

324 lines
13 KiB
C++

/*=========================================================================
Program: Visualization Toolkit
Module: vtkWidgetRepresentation.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 vtkWidgetRepresentation
* @brief abstract class defines interface between the widget and widget representation classes
*
* This class is used to define the API for, and partially implement, a
* representation for different types of widgets. Note that the widget
* representation (i.e., subclasses of vtkWidgetRepresentation) are a type of
* vtkProp; meaning that they can be associated with a vtkRenderer end
* embedded in a scene like any other vtkActor. However,
* vtkWidgetRepresentation also defines an API that enables it to be paired
* with a subclass vtkAbstractWidget, meaning that it can be driven by a
* widget, serving to represent the widget as the widget responds to
* registered events.
*
* The API defined here should be regarded as a guideline for implementing
* widgets and widget representations. Widget behavior is complex, as is the
* way the representation responds to the registered widget events, so the API
* may vary from widget to widget to reflect this complexity.
*
* @warning
* The separation of the widget event handling and representation enables
* users and developers to create new appearances for the widget. It also
* facilitates parallel processing, where the client application handles
* events, and remote representations of the widget are slaves to the
* client (and do not handle events).
*/
#ifndef vtkWidgetRepresentation_h
#define vtkWidgetRepresentation_h
#include "vtkInteractionWidgetsModule.h" // For export macro
#include "vtkNew.h" // for ivars
#include "vtkProp.h"
#include "vtkWeakPointer.h" // needed for vtkWeakPointer iVar.
class vtkAbstractPropPicker;
class vtkAbstractWidget;
class vtkMatrix4x4;
class vtkPickingManager;
class vtkProp3D;
class vtkRenderWindowInteractor;
class vtkRenderer;
class vtkTransform;
class VTKINTERACTIONWIDGETS_EXPORT vtkWidgetRepresentation : public vtkProp
{
public:
//@{
/**
* Standard methods for instances of this class.
*/
vtkTypeMacro(vtkWidgetRepresentation, vtkProp);
void PrintSelf(ostream& os, vtkIndent indent) override;
//@}
//@{
/**
* Enable/Disable the use of a manager to process the picking.
* Enabled by default.
*/
vtkBooleanMacro(PickingManaged, bool);
void SetPickingManaged(bool managed);
vtkGetMacro(PickingManaged, bool);
//@}
//@{
/**
* Subclasses of vtkWidgetRepresentation must implement these methods. This is
* considered the minimum API for a widget representation.
* <pre>
* SetRenderer() - the renderer in which the representations draws itself.
* Typically the renderer is set by the associated widget.
* Use the widget's SetCurrentRenderer() method in most cases;
* otherwise there is a risk of inconsistent behavior as events
* and drawing may be performed in different viewports.
* BuildRepresentation() - update the geometry of the widget based on its
* current state.
* </pre>
* WARNING: The renderer is NOT reference counted by the representation,
* in order to avoid reference loops. Be sure that the representation
* lifetime does not extend beyond the renderer lifetime.
*/
virtual void SetRenderer(vtkRenderer* ren);
virtual vtkRenderer* GetRenderer();
virtual void BuildRepresentation() = 0;
//@}
/**
* The following is a suggested API for widget representations. These methods
* define the communication between the widget and its representation. These
* methods are only suggestions because widgets take on so many different
* forms that a universal API is not deemed practical. However, these methods
* should be implemented when possible to insure that the VTK widget hierarchy
* remains self-consistent.
* <pre>
* PlaceWidget() - given a bounding box (xmin,xmax,ymin,ymax,zmin,zmax), place
* the widget inside of it. The current orientation of the widget
* is preserved, only scaling and translation is performed.
* StartWidgetInteraction() - generally corresponds to a initial event (e.g.,
* mouse down) that starts the interaction process
* with the widget.
* WidgetInteraction() - invoked when an event causes the widget to change
* appearance.
* EndWidgetInteraction() - generally corresponds to a final event (e.g., mouse up)
* and completes the interaction sequence.
* ComputeInteractionState() - given (X,Y) display coordinates in a renderer, with a
* possible flag that modifies the computation,
* what is the state of the widget?
* GetInteractionState() - return the current state of the widget. Note that the
* value of "0" typically refers to "outside". The
* interaction state is strictly a function of the
* representation, and the widget/represent must agree
* on what they mean.
* Highlight() - turn on or off any highlights associated with the widget.
* Highlights are generally turned on when the widget is selected.
* </pre>
* Note that subclasses may ignore some of these methods and implement their own
* depending on the specifics of the widget.
*/
virtual void PlaceWidget(double* vtkNotUsed(bounds[6])) {}
virtual void StartWidgetInteraction(double eventPos[2]) { (void)eventPos; }
virtual void WidgetInteraction(double newEventPos[2]) { (void)newEventPos; }
virtual void EndWidgetInteraction(double newEventPos[2]) { (void)newEventPos; }
virtual int ComputeInteractionState(int X, int Y, int modify = 0);
virtual int GetInteractionState() { return this->InteractionState; }
virtual void Highlight(int vtkNotUsed(highlightOn)) {}
//@{
// Widgets were originally designed to be driven by 2D mouse events
// With Virtual Reality and multitouch we get mnore complex events
// that may involve multiple pointers as well as 3D pointers and
// orientations. As such we provide pointers to the interactor
// widget and an event type so that representations can access the
// values they need.
virtual void StartComplexInteraction(
vtkRenderWindowInteractor*, vtkAbstractWidget*, unsigned long /* event */, void* /*callData*/)
{
}
virtual void ComplexInteraction(
vtkRenderWindowInteractor*, vtkAbstractWidget*, unsigned long /* event */, void* /* callData */)
{
}
virtual void EndComplexInteraction(
vtkRenderWindowInteractor*, vtkAbstractWidget*, unsigned long /* event */, void* /* callData */)
{
}
virtual int ComputeComplexInteractionState(vtkRenderWindowInteractor* iren,
vtkAbstractWidget* widget, unsigned long event, void* callData, int modify = 0);
//@}
//@{
/**
* Set/Get a factor representing the scaling of the widget upon placement
* (via the PlaceWidget() method). Normally the widget is placed so that
* it just fits within the bounding box defined in PlaceWidget(bounds).
* The PlaceFactor will make the widget larger (PlaceFactor > 1) or smaller
* (PlaceFactor < 1). By default, PlaceFactor is set to 0.5.
*/
vtkSetClampMacro(PlaceFactor, double, 0.01, VTK_DOUBLE_MAX);
vtkGetMacro(PlaceFactor, double);
//@}
//@{
/**
* Set/Get the factor that controls the size of the handles that appear as
* part of the widget (if any). These handles (like spheres, etc.) are
* used to manipulate the widget. The HandleSize data member allows you
* to change the relative size of the handles. Note that while the handle
* size is typically expressed in pixels, some subclasses may use a relative size
* with respect to the viewport. (As a corollary, the value of this ivar is often
* set by subclasses of this class during instance instantiation.)
*/
vtkSetClampMacro(HandleSize, double, 0.001, 1000);
vtkGetMacro(HandleSize, double);
//@}
//@{
/**
* Some subclasses use this data member to keep track of whether to render
* or not (i.e., to minimize the total number of renders).
*/
vtkGetMacro(NeedToRender, vtkTypeBool);
vtkSetClampMacro(NeedToRender, vtkTypeBool, 0, 1);
vtkBooleanMacro(NeedToRender, vtkTypeBool);
//@}
/**
* Methods to make this class behave as a vtkProp. They are repeated here (from the
* vtkProp superclass) as a reminder to the widget implementor. Failure to implement
* these methods properly may result in the representation not appearing in the scene
* (i.e., not implementing the Render() methods properly) or leaking graphics resources
* (i.e., not implementing ReleaseGraphicsResources() properly).
*/
double* GetBounds() VTK_SIZEHINT(6) override { return nullptr; }
void ShallowCopy(vtkProp* prop) override;
void GetActors(vtkPropCollection*) override {}
void GetActors2D(vtkPropCollection*) override {}
void GetVolumes(vtkPropCollection*) override {}
void ReleaseGraphicsResources(vtkWindow*) override {}
int RenderOverlay(vtkViewport* vtkNotUsed(viewport)) override { return 0; }
int RenderOpaqueGeometry(vtkViewport* vtkNotUsed(viewport)) override { return 0; }
int RenderTranslucentPolygonalGeometry(vtkViewport* vtkNotUsed(viewport)) override { return 0; }
int RenderVolumetricGeometry(vtkViewport* vtkNotUsed(viewport)) override { return 0; }
vtkTypeBool HasTranslucentPolygonalGeometry() override { return 0; }
/**
* Register internal Pickers in the Picking Manager.
* Must be reimplemented by concrete widget representations to register
* their pickers.
*/
virtual void RegisterPickers();
/**
* Unregister internal pickers from the Picking Manager.
*/
virtual void UnRegisterPickers();
//@{
/**
* Axis labels
*/
enum Axis
{
NONE = -1,
XAxis = 0,
YAxis = 1,
ZAxis = 2
};
//@}
protected:
vtkWidgetRepresentation();
~vtkWidgetRepresentation() override;
// The renderer in which this widget is placed
vtkWeakPointer<vtkRenderer> Renderer;
// The state of this representation based on a recent event
int InteractionState;
// These are used to track the beginning of interaction with the representation
// It's dimensioned [3] because some events re processed in 3D.
double StartEventPosition[3];
// Instance variable and members supporting suclasses
double PlaceFactor; // Used to control how widget is placed around bounding box
int Placed; // Indicate whether widget has been placed
void AdjustBounds(double bounds[6], double newBounds[6], double center[3]);
double InitialBounds[6]; // initial bounds on place widget (valid after PlaceWidget)
double InitialLength; // initial length on place widget
// Sizing handles is tricky because the procedure requires information
// relative to the last pick, as well as a live renderer to perform
// coordinate conversions. In some cases, a pick is never made so handle
// sizing has to follow a different path. The following ivars help with
// this process.
int ValidPick; // indicate when valid picks are made
// This variable controls whether the picking is managed by the Picking
// Manager or not. True by default.
bool PickingManaged;
/**
* Return the picking manager associated on the context on which the widget
* representation currently belong.
*/
vtkPickingManager* GetPickingManager();
/**
* Proceed to a pick, whether through the PickingManager if the picking is
* managed or directly using the registered picker, and return the assembly
* path.
*/
vtkAssemblyPath* GetAssemblyPath(double X, double Y, double Z, vtkAbstractPropPicker* picker);
vtkAssemblyPath* GetAssemblyPath3DPoint(double pos[3], vtkAbstractPropPicker* picker);
// Helper function to cull events if they are not near to the actual widget
// representation. This is needed typically in situations of extreme zoom
// for 3D widgets. The current event position, and 3D bounds of the widget
// are provided.
bool NearbyEvent(int X, int Y, double bounds[6]);
// Members use to control handle size. The two methods return a "radius"
// in world coordinates. Note that the HandleSize data member is used
// internal to the SizeHandles__() methods.
double HandleSize; // controlling relative size of widget handles
double SizeHandlesRelativeToViewport(double factor, double pos[3]);
double SizeHandlesInPixels(double factor, double pos[3]);
// Try and reduce multiple renders
vtkTypeBool NeedToRender;
// This is the time that the representation was built. This data member
// can be used to reduce the time spent building the widget.
vtkTimeStamp BuildTime;
// update the pose of a prop based on two sets of
// position, orientation vectors
void UpdatePropPose(vtkProp3D* prop, const double* pos1, const double* orient1,
const double* pos2, const double* orient2);
vtkNew<vtkTransform> TempTransform;
vtkNew<vtkMatrix4x4> TempMatrix;
private:
vtkWidgetRepresentation(const vtkWidgetRepresentation&) = delete;
void operator=(const vtkWidgetRepresentation&) = delete;
};
#endif