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.

289 lines
9.8 KiB
C++

/*=========================================================================
Program: Visualization Toolkit
Module: vtkContourWidget.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 vtkContourWidget
* @brief create a contour with a set of points
*
* The vtkContourWidget is used to select a set of points, and draw lines
* between these points. The contour may be opened or closed, depending on
* how the last point is added. The widget handles all processing of widget
* events (that are triggered by VTK events). The vtkContourRepresentation is
* responsible for all placement of the points, calculation of the lines, and
* contour manipulation. This is done through two main helper classes:
* vtkPointPlacer and vtkContourLineInterpolator. The representation is also
* responsible for drawing the points and lines.
*
* @par Event Bindings:
* By default, the widget responds to the following VTK events (i.e., it
* watches the vtkRenderWindowInteractor for these events):
* <pre>
* LeftButtonPressEvent - triggers a Select event
* RightButtonPressEvent - triggers a AddFinalPoint event
* MouseMoveEvent - triggers a Move event
* LeftButtonReleaseEvent - triggers an EndSelect event
* Delete key event - triggers a Delete event
* Shift + Delete key event - triggers a Reset event
* </pre>
*
* @par Event Bindings:
* Note that the event bindings described above can be changed using this
* class's vtkWidgetEventTranslator. This class translates VTK events
* into the vtkContourWidget's widget events:
* <pre>
* vtkWidgetEvent::Select
* widget state is:
* Start or
* Define: If we already have at least 2 nodes, test
* whether the current (X,Y) location is near an existing
* node. If so, close the contour and change to Manipulate
* state. Otherwise, attempt to add a node at this (X,Y)
* location.
* Manipulate: If this (X,Y) location activates a node, then
* set the current operation to Translate. Otherwise, if
* this location is near the contour, attempt to add a
* new node on the contour at this (X,Y) location.
*
* @par Event Bindings:
* vtkWidgetEvent::AddFinalPoint
* widget state is:
* Start: Do nothing.
* Define: If we already have at least 2 nodes, test
* whether the current (X,Y) location is near an existing
* node. If so, close the contour and change to Manipulate
* state. Otherwise, attempt to add a node at this (X,Y)
* location. If we do, then leave the contour open and
* change to Manipulate state.
* Manipulate: Do nothing.
*
* @par Event Bindings:
* vtkWidgetEvent::Move
* widget state is:
* Start or
* Define: Do nothing.
* Manipulate: If our operation is Translate, then invoke
* WidgetInteraction() on the representation. If our
* operation is Inactive, then just attempt to activate
* a node at this (X,Y) location.
*
* @par Event Bindings:
* vtkWidgetEvent::EndSelect
* widget state is:
* Start or
* Define: Do nothing.
* Manipulate: If our operation is not Inactive, set it to
* Inactive.
*
* @par Event Bindings:
* vtkWidgetEvent::Delete
* widget state is:
* Start: Do nothing.
* Define: Remove the last point on the contour.
* Manipulate: Attempt to activate a node at (X,Y). If
* we do activate a node, delete it. If we now
* have less than 3 nodes, go back to Define state.
*
* @par Event Bindings:
* vtkWidgetEvent::Reset
* widget state is:
* Start: Do nothing.
* Define: Remove all points and line segments of the contour.
* Essentially calls Initialize(nullptr)
* Manipulate: Do nothing.
* </pre>
*
* @par Event Bindings:
* This widget invokes the following VTK events on itself (which observers
* can listen for):
* <pre>
* vtkCommand::StartInteractionEvent (beginning to interact)
* vtkCommand::EndInteractionEvent (completing interaction)
* vtkCommand::InteractionEvent (moving after selecting something)
* vtkCommand::PlacePointEvent (after point is positioned;
* call data includes handle id (0,1))
* vtkCommand::WidgetValueChangedEvent (Invoked when the contour is closed
* for the first time. )
* </pre>
*
* @sa
* vtkHandleWidget
*/
#ifndef vtkContourWidget_h
#define vtkContourWidget_h
#include "vtkAbstractWidget.h"
#include "vtkInteractionWidgetsModule.h" // For export macro
class vtkContourRepresentation;
class vtkPolyData;
class vtkIdList;
class VTKINTERACTIONWIDGETS_EXPORT vtkContourWidget : public vtkAbstractWidget
{
public:
/**
* Instantiate this class.
*/
static vtkContourWidget* New();
//@{
/**
* Standard methods for a VTK class.
*/
vtkTypeMacro(vtkContourWidget, vtkAbstractWidget);
void PrintSelf(ostream& os, vtkIndent indent) override;
//@}
/**
* The method for activating and deactivating this widget. This method
* must be overridden because it is a composite widget and does more than
* its superclasses' vtkAbstractWidget::SetEnabled() method.
*/
void SetEnabled(int) override;
/**
* Specify an instance of vtkWidgetRepresentation used to represent this
* widget in the scene. Note that the representation is a subclass of vtkProp
* so it can be added to the renderer independent of the widget.
*/
void SetRepresentation(vtkContourRepresentation* r)
{
this->Superclass::SetWidgetRepresentation(reinterpret_cast<vtkWidgetRepresentation*>(r));
}
/**
* Return the representation as a vtkContourRepresentation.
*/
vtkContourRepresentation* GetContourRepresentation()
{
return reinterpret_cast<vtkContourRepresentation*>(this->WidgetRep);
}
/**
* Create the default widget representation if one is not set.
*/
void CreateDefaultRepresentation() override;
/**
* Convenient method to close the contour loop.
*/
void CloseLoop();
//@{
/**
* Convenient method to change what state the widget is in.
*/
vtkSetMacro(WidgetState, int);
//@}
//@{
/**
* Convenient method to determine the state of the method
*/
vtkGetMacro(WidgetState, int);
//@}
//@{
/**
* Set / Get the AllowNodePicking value. This ivar indicates whether the nodes
* and points between nodes can be picked/un-picked by Ctrl+Click on the node.
*/
void SetAllowNodePicking(vtkTypeBool);
vtkGetMacro(AllowNodePicking, vtkTypeBool);
vtkBooleanMacro(AllowNodePicking, vtkTypeBool);
//@}
//@{
/**
* Follow the cursor ? If this is ON, during definition, the last node of the
* contour will automatically follow the cursor, without waiting for the
* point to be dropped. This may be useful for some interpolators, such as the
* live-wire interpolator to see the shape of the contour that will be placed
* as you move the mouse cursor.
*/
vtkSetMacro(FollowCursor, vtkTypeBool);
vtkGetMacro(FollowCursor, vtkTypeBool);
vtkBooleanMacro(FollowCursor, vtkTypeBool);
//@}
//@{
/**
* Define a contour by continuously drawing with the mouse cursor.
* Press and hold the left mouse button down to continuously draw.
* Releasing the left mouse button switches into a snap drawing mode.
* Terminate the contour by pressing the right mouse button. If you
* do not want to see the nodes as they are added to the contour, set the
* opacity to 0 of the representation's property. If you do not want to
* see the last active node as it is being added, set the opacity to 0
* of the representation's active property.
*/
vtkSetMacro(ContinuousDraw, vtkTypeBool);
vtkGetMacro(ContinuousDraw, vtkTypeBool);
vtkBooleanMacro(ContinuousDraw, vtkTypeBool);
//@}
/**
* Initialize the contour widget from a user supplied set of points. The
* state of the widget decides if you are still defining the widget, or
* if you've finished defining (added the last point) are manipulating
* it. Note that if the polydata supplied is closed, the state will be
* set to manipulate.
* State: Define = 0, Manipulate = 1.
*/
virtual void Initialize(vtkPolyData* poly, int state = 1, vtkIdList* idList = nullptr);
virtual void Initialize() { this->Initialize(nullptr); }
// The state of the widget
enum
{
Start,
Define,
Manipulate
};
protected:
vtkContourWidget();
~vtkContourWidget() override;
int WidgetState;
int CurrentHandle;
vtkTypeBool AllowNodePicking;
vtkTypeBool FollowCursor;
vtkTypeBool ContinuousDraw;
int ContinuousActive;
// Callback interface to capture events when
// placing the widget.
static void SelectAction(vtkAbstractWidget*);
static void AddFinalPointAction(vtkAbstractWidget*);
static void MoveAction(vtkAbstractWidget*);
static void EndSelectAction(vtkAbstractWidget*);
static void DeleteAction(vtkAbstractWidget*);
static void TranslateContourAction(vtkAbstractWidget*);
static void ScaleContourAction(vtkAbstractWidget*);
static void ResetAction(vtkAbstractWidget*);
// Internal helper methods
void SelectNode();
void AddNode();
private:
vtkContourWidget(const vtkContourWidget&) = delete;
void operator=(const vtkContourWidget&) = delete;
};
#endif