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.

243 lines
8.4 KiB
C++

/*=========================================================================
Program: Visualization Toolkit
Module: vtkOrientationMarkerWidget.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 vtkOrientationMarkerWidget
* @brief 2D widget for manipulating a marker prop
*
* This class provides support for interactively manipulating the position,
* size, and apparent orientation of a prop that represents an orientation
* marker. This class works by adding its internal renderer to an external
* "parent" renderer on a different layer. The input orientation marker is
* rendered as an overlay on the parent renderer and, thus, appears superposed
* over all props in the parent's scene. The camera view of the orientation
* the marker is made to match that of the parent's by means of an observer
* mechanism, giving the illusion that the orientation of the marker reflects
* that of the prop(s) in the parent's scene.
*
* The widget listens to left mouse button and mouse movement events. It will
* change the cursor shape based on its location. If the cursor is over the
* overlay renderer, it will change the cursor shape to a SIZEALL shape
* or to a resize corner shape (e.g., SIZENW) if the cursor is near a corner.
* If the left mouse button is pressed and held down while moving, the overlay
* renderer, and hence, the orientation marker, is resized or moved. I the case
* of a resize operation, releasing the left mouse button causes the widget
* to enforce its renderer to be square. The diagonally opposite corner to the
* one moved is repositioned such that all edges of the renderer have the same
* length: the minimum.
*
* To use this object, there are two key steps: 1) invoke SetInteractor() with
* the argument of the method a vtkRenderWindowInteractor, and 2) invoke
* SetOrientationMarker with an instance of vtkProp (see caveats below).
* Specifically, vtkAxesActor and vtkAnnotatedCubeActor are two classes
* designed to work with this class. A composite orientation marker can be
* generated by adding instances of vtkAxesActor and vtkAnnotatedCubeActor to a
* vtkPropAssembly, which can then be set as the input orientation marker.
* The widget can be also be set up in a non-interactive fashion by setting
* Ineractive to Off and sizing/placing the overlay renderer in its parent
* renderer by calling the widget's SetViewport method.
*
* @par Thanks:
* This class was based originally on Paraview's vtkPVAxesWidget.
*
* @warning
* The input orientation marker prop should calculate its bounds as though they
* are symmetric about it's origin. This must currently be done to correctly
* implement the camera synchronization between the ivar renderer and the
* renderer associated with the set interactor. Importantly, the InteractorStyle
* associated with the interactor must be of the type vtkInteractorStyle*Camera.
* Where desirable, the parent renderer should be set by the SetDefaultRenderer
* method. The parent renderer's number of layers is modified to 2 where
* required.
*
* @sa
* vtkInteractorObserver vtkXYPlotWidget vtkScalarBarWidget vtkAxesActor
* vtkAnnotatedCubeActor
*/
#ifndef vtkOrientationMarkerWidget_h
#define vtkOrientationMarkerWidget_h
#include "vtkInteractionWidgetsModule.h" // For export macro
#include "vtkInteractorObserver.h"
class vtkActor2D;
class vtkPolyData;
class vtkProp;
class vtkOrientationMarkerWidgetObserver;
class vtkRenderer;
class VTKINTERACTIONWIDGETS_EXPORT vtkOrientationMarkerWidget : public vtkInteractorObserver
{
public:
static vtkOrientationMarkerWidget* New();
vtkTypeMacro(vtkOrientationMarkerWidget, vtkInteractorObserver);
void PrintSelf(ostream& os, vtkIndent indent) override;
//@{
/**
* Set/get the orientation marker to be displayed in this widget.
*/
virtual void SetOrientationMarker(vtkProp* prop);
vtkGetObjectMacro(OrientationMarker, vtkProp);
//@}
/**
* Enable/disable the widget. Default is 0 (disabled).
*/
void SetEnabled(int) override;
/**
* Callback to keep the camera for the orientation marker up to date with the
* camera in the parent renderer.
*/
void ExecuteCameraUpdateEvent(vtkObject* o, unsigned long event, void* calldata);
//@{
/**
* Set/get whether to allow this widget to be interactively moved/scaled.
* Default is On.
*/
void SetInteractive(vtkTypeBool state);
vtkGetMacro(Interactive, vtkTypeBool);
vtkBooleanMacro(Interactive, vtkTypeBool);
//@}
//@{
/**
* Set/get the color of the outline of this widget. The outline is visible
* when (in interactive mode) the cursor is over this widget.
* Default is white (1,1,1).
*/
void SetOutlineColor(double r, double g, double b);
double* GetOutlineColor() VTK_SIZEHINT(3);
//@}
//@{
/**
* Set/get the viewport to position/size this widget.
* Coordinates are expressed as (xmin,ymin,xmax,ymax), where each
* coordinate is 0 <= coordinate <= 1.0.
* Default is bottom left corner (0,0,0.2,0.2).
* Note that this viewport is scaled with respect to the viewport of the
* current renderer i.e. if the viewport of the current renderer is
* (0.5, 0.5, 0.75, 0.75) and Viewport is set to (0, 0, 1, 1), the orientation
* marker will be confined to a viewport of (0.5, 0.5, 0.75, 0.75) in the
* render window.
* \sa SetCurrentRenderer()
*/
vtkSetVector4Macro(Viewport, double);
vtkGetVector4Macro(Viewport, double);
//@}
//@{
/**
* The tolerance representing the distance to the widget (in pixels)
* in which the cursor is considered to be on the widget, or on a
* widget feature (e.g., a corner point or edge).
*/
vtkSetClampMacro(Tolerance, int, 1, 10);
vtkGetMacro(Tolerance, int);
//@}
//@{
/**
* Need to reimplement this->Modified() because of the
* vtkSetVector4Macro/vtkGetVector4Macro use
*/
void Modified() override;
//@}
protected:
vtkOrientationMarkerWidget();
~vtkOrientationMarkerWidget() override;
vtkRenderer* Renderer;
vtkProp* OrientationMarker;
vtkPolyData* Outline;
vtkActor2D* OutlineActor;
unsigned long StartEventObserverId;
static void ProcessEvents(
vtkObject* object, unsigned long event, void* clientdata, void* calldata);
// ProcessEvents() dispatches to these methods.
virtual void OnLeftButtonDown();
virtual void OnLeftButtonUp();
virtual void OnMouseMove();
// observer to update the renderer's camera
vtkOrientationMarkerWidgetObserver* Observer;
vtkTypeBool Interactive;
int Tolerance;
int Moving;
// viewport to position/size this widget
double Viewport[4];
// used to compute relative movements
int StartPosition[2];
// Manage the state of the widget
int State;
enum WidgetState
{
Outside = 0,
Inside,
Translating,
AdjustingP1,
AdjustingP2,
AdjustingP3,
AdjustingP4
};
// use to determine what state the mouse is over, edge1 p1, etc.
// returns a state from the WidgetState enum above
virtual int ComputeStateBasedOnPosition(int X, int Y, int* pos1, int* pos2);
// set the cursor to the correct shape based on State argument
virtual void SetCursor(int state);
// adjust the viewport depending on state
void MoveWidget(int X, int Y);
void ResizeTopLeft(int X, int Y);
void ResizeTopRight(int X, int Y);
void ResizeBottomLeft(int X, int Y);
void ResizeBottomRight(int X, int Y);
void SquareRenderer();
void UpdateOutline();
// Used to reverse compute the Viewport ivar with respect to the current
// renderer viewport
void UpdateViewport();
// Used to compute and set the viewport on the internal renderer based on the
// Viewport ivar. The computed viewport will be with respect to the whole
// render window
void UpdateInternalViewport();
private:
vtkOrientationMarkerWidget(const vtkOrientationMarkerWidget&) = delete;
void operator=(const vtkOrientationMarkerWidget&) = delete;
// set up the actors and observers created by this widget
void SetupWindowInteraction();
// tear down up the actors and observers created by this widget
void TearDownWindowInteraction();
};
#endif