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.
528 lines
15 KiB
C++
528 lines
15 KiB
C++
/*=========================================================================
|
|
|
|
Program: Visualization Toolkit
|
|
Module: vtkControlPointsItem.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 vtkControlPointsItem
|
|
* @brief Abstract class for control points items.
|
|
*
|
|
* vtkControlPointsItem provides control point painting and management for
|
|
* subclasses that provide points (typically control points of a transfer
|
|
* function)
|
|
* @sa
|
|
* vtkScalarsToColorsItem
|
|
* vtkPiecewiseControlPointsItem
|
|
*/
|
|
|
|
#ifndef vtkControlPointsItem_h
|
|
#define vtkControlPointsItem_h
|
|
|
|
#include "vtkChartsCoreModule.h" // For export macro
|
|
#include "vtkCommand.h" // For vtkCommand enum
|
|
#include "vtkPlot.h"
|
|
#include "vtkSmartPointer.h" // for SmartPointer
|
|
#include "vtkVector.h" // For vtkVector2f
|
|
|
|
class vtkCallbackCommand;
|
|
class vtkContext2D;
|
|
class vtkControlPointsAddPointItem;
|
|
class vtkPiecewisePointHandleItem;
|
|
class vtkPoints2D;
|
|
class vtkTransform2D;
|
|
|
|
class VTKCHARTSCORE_EXPORT vtkControlPointsItem : public vtkPlot
|
|
{
|
|
public:
|
|
vtkTypeMacro(vtkControlPointsItem, vtkPlot);
|
|
void PrintSelf(ostream& os, vtkIndent indent) override;
|
|
|
|
// Events fires by this class (and subclasses).
|
|
// \li CurrentPointChangedEvent is fired when the current point index is changed.
|
|
// \li CurrentPointEditEvent is fired to request the application to show UI to
|
|
// edit the current point.
|
|
// \li vtkCommand::StartEvent and vtkCommand::EndEvent is fired
|
|
// to mark groups of changes to control points.
|
|
enum
|
|
{
|
|
CurrentPointChangedEvent = vtkCommand::UserEvent,
|
|
CurrentPointEditEvent
|
|
};
|
|
|
|
/**
|
|
* Bounds of the item, typically the bound of all the control points
|
|
* except if custom bounds have been set \sa SetUserBounds.
|
|
*/
|
|
void GetBounds(double bounds[4]) override;
|
|
|
|
//@{
|
|
/**
|
|
* Set custom bounds, except if bounds are invalid, bounds will be
|
|
* automatically computed based on the range of the control points
|
|
* Invalid bounds by default.
|
|
*/
|
|
vtkSetVector4Macro(UserBounds, double);
|
|
vtkGetVector4Macro(UserBounds, double);
|
|
//@}
|
|
|
|
//@{
|
|
/**
|
|
* Controls the valid range for the values.
|
|
* An invalid value (0, -1, 0., -1, 0, -1.) indicates that the valid
|
|
* range is the current bounds. It is the default behavior.
|
|
*/
|
|
vtkSetVector4Macro(ValidBounds, double);
|
|
vtkGetVector4Macro(ValidBounds, double);
|
|
//@}
|
|
|
|
//@{
|
|
/**
|
|
* Get/set the radius for screen points.
|
|
* Default is 6.f
|
|
*/
|
|
vtkGetMacro(ScreenPointRadius, float);
|
|
vtkSetMacro(ScreenPointRadius, float);
|
|
//@}
|
|
|
|
/**
|
|
* Paint the points with a fixed size (cosmetic) which doesn't depend
|
|
* on the scene zoom factor. Selected and unselected points are drawn
|
|
* with a different color.
|
|
*/
|
|
bool Paint(vtkContext2D* painter) override;
|
|
|
|
/**
|
|
* Select a point by its ID
|
|
*/
|
|
void SelectPoint(vtkIdType pointId);
|
|
|
|
/**
|
|
* Utility function that selects a point providing its coordinates.
|
|
* To be found, the position of the point must be no further away than its
|
|
* painted point size
|
|
*/
|
|
void SelectPoint(double* currentPoint);
|
|
|
|
/**
|
|
* Select all the points
|
|
*/
|
|
void SelectAllPoints();
|
|
|
|
/**
|
|
* Unselect a point by its ID
|
|
*/
|
|
void DeselectPoint(vtkIdType pointId);
|
|
|
|
/**
|
|
* Utility function that unselects a point providing its coordinates.
|
|
* To be found, the position of the point must be no further away than its
|
|
* painted point size
|
|
*/
|
|
void DeselectPoint(double* currentPoint);
|
|
|
|
/**
|
|
* Unselect all the previously selected points
|
|
*/
|
|
void DeselectAllPoints();
|
|
|
|
/**
|
|
* Toggle the selection of a point by its ID. If the point was selected then
|
|
* unselect it, otherwise select it.
|
|
*/
|
|
void ToggleSelectPoint(vtkIdType pointId);
|
|
|
|
/**
|
|
* Utility function that toggles the selection a point providing its
|
|
* coordinates. To be found, the position of the point must be no further
|
|
* away than its painted point size
|
|
*/
|
|
void ToggleSelectPoint(double* currentPoint);
|
|
|
|
/**
|
|
* Select all points in the specified rectangle.
|
|
*/
|
|
bool SelectPoints(const vtkVector2f& min, const vtkVector2f& max) override;
|
|
|
|
/**
|
|
* Return the number of selected points.
|
|
*/
|
|
vtkIdType GetNumberOfSelectedPoints() const;
|
|
|
|
/**
|
|
* Returns the vtkIdType of the point given its coordinates and a tolerance
|
|
* based on the screen point size.
|
|
*/
|
|
vtkIdType FindPoint(double* pos);
|
|
|
|
/**
|
|
* Returns true if pos is above the pointId point, false otherwise.
|
|
* It uses the size of the drawn point. To search what point is under the pos,
|
|
* use the more efficient \sa FindPoint() instead.
|
|
*/
|
|
bool IsOverPoint(double* pos, vtkIdType pointId);
|
|
|
|
/**
|
|
* Returns the id of the control point exactly matching pos, -1 if not found.
|
|
*/
|
|
vtkIdType GetControlPointId(double* pos);
|
|
|
|
/**
|
|
* Utility function that returns an array of all the control points IDs
|
|
* Typically: [0, 1, 2, ... n -1] where n is the point count
|
|
* Can exclude the first and last point ids from the array.
|
|
*/
|
|
void GetControlPointsIds(vtkIdTypeArray* ids, bool excludeFirstAndLast = false) const;
|
|
|
|
//@{
|
|
/**
|
|
* Controls whether or not control points are drawn (true) or clicked and
|
|
* moved (false).
|
|
* False by default.
|
|
*/
|
|
vtkGetMacro(StrokeMode, bool);
|
|
//@}
|
|
|
|
//@{
|
|
/**
|
|
* If DrawPoints is false, SwitchPoints controls the behavior when a control
|
|
* point is dragged past another point. The crossed point becomes current
|
|
* (true) or the current point is blocked/stopped (false).
|
|
* False by default.
|
|
*/
|
|
vtkSetMacro(SwitchPointsMode, bool);
|
|
vtkGetMacro(SwitchPointsMode, bool);
|
|
//@}
|
|
|
|
//@{
|
|
/**
|
|
* If EndPointsMovable is false, the two end points will not
|
|
* be moved. True by default.
|
|
*/
|
|
vtkSetMacro(EndPointsXMovable, bool);
|
|
vtkGetMacro(EndPointsXMovable, bool);
|
|
vtkSetMacro(EndPointsYMovable, bool);
|
|
vtkGetMacro(EndPointsYMovable, bool);
|
|
virtual bool GetEndPointsMovable();
|
|
//@}
|
|
|
|
//@{
|
|
/**
|
|
* If EndPointsRemovable is false, the two end points will not
|
|
* be removed. True by default.
|
|
*/
|
|
vtkSetMacro(EndPointsRemovable, bool);
|
|
vtkGetMacro(EndPointsRemovable, bool);
|
|
//@}
|
|
|
|
//@{
|
|
/**
|
|
* When set to true, labels are shown on the current control point and the end
|
|
* points. Default is false.
|
|
*/
|
|
vtkSetMacro(ShowLabels, bool);
|
|
vtkGetMacro(ShowLabels, bool);
|
|
//@}
|
|
|
|
//@{
|
|
/**
|
|
* Get/Set the label format. Default is "%.4f, %.4f".
|
|
*/
|
|
vtkSetStringMacro(LabelFormat);
|
|
vtkGetStringMacro(LabelFormat);
|
|
//@}
|
|
|
|
/**
|
|
* Add a point to the function. Returns the index of the point (0 based),
|
|
* or -1 on error.
|
|
* Subclasses should reimplement this function to do the actual work.
|
|
*/
|
|
virtual vtkIdType AddPoint(double* newPos) = 0;
|
|
|
|
/**
|
|
* Remove a point of the function. Returns the index of the point (0 based),
|
|
* or -1 on error.
|
|
* Subclasses should reimplement this function to do the actual work.
|
|
*/
|
|
virtual vtkIdType RemovePoint(double* pos) = 0;
|
|
|
|
/**
|
|
* Remove a point give its id. It is a utility function that internally call
|
|
* the virtual method RemovePoint(double*) and return its result.
|
|
*/
|
|
vtkIdType RemovePoint(vtkIdType pointId);
|
|
|
|
/**
|
|
* Remove the current point.
|
|
*/
|
|
inline void RemoveCurrentPoint();
|
|
|
|
/**
|
|
* Returns the total number of points
|
|
*/
|
|
virtual vtkIdType GetNumberOfPoints() const = 0;
|
|
|
|
/**
|
|
* Returns the x and y coordinates as well as the midpoint and sharpness
|
|
* of the control point corresponding to the index.
|
|
* point must be a double array of size 4.
|
|
*/
|
|
virtual void GetControlPoint(vtkIdType index, double* point) const = 0;
|
|
|
|
/**
|
|
* Sets the x and y coordinates as well as the midpoint and sharpness
|
|
* of the control point corresponding to the index.
|
|
*/
|
|
virtual void SetControlPoint(vtkIdType index, double* point) = 0;
|
|
|
|
/**
|
|
* Move the points referred by pointIds by a given translation.
|
|
* The new positions won't be outside the bounds.
|
|
* MovePoints is typically called with GetControlPointsIds() or GetSelection().
|
|
* Warning: if you pass this->GetSelection(), the array is deleted after
|
|
* each individual point move. Increase the reference count of the array.
|
|
* See also MoveAllPoints()
|
|
*/
|
|
void MovePoints(const vtkVector2f& translation, vtkIdTypeArray* pointIds);
|
|
|
|
/**
|
|
* Utility function to move all the control points of the given translation
|
|
* If dontMoveFirstAndLast is true, then the first and last points won't be
|
|
* moved.
|
|
*/
|
|
void MovePoints(const vtkVector2f& translation, bool dontMoveFirstAndLast = false);
|
|
|
|
/**
|
|
* Spread the points referred by pointIds
|
|
* If factor > 0, points are moved away from each other.
|
|
* If factor < 0, points are moved closer to each other
|
|
* SpreadPoints is typically called with GetControlPointsIds() or GetSelection().
|
|
* Warning: if you pass this->GetSelection(), the array is deleted after
|
|
* each individual point move. Increase the reference count of the array.
|
|
*/
|
|
void SpreadPoints(float factor, vtkIdTypeArray* pointIds);
|
|
|
|
/**
|
|
* Utility function to spread all the control points of a given factor
|
|
* If dontSpreadFirstAndLast is true, then the first and last points won't be
|
|
* spread.
|
|
*/
|
|
void SpreadPoints(float factor, bool dontSpreadFirstAndLast = false);
|
|
|
|
/**
|
|
* Returns the current point ID selected or -1 if there is no point current.
|
|
* No current point by default.
|
|
*/
|
|
vtkIdType GetCurrentPoint() const;
|
|
|
|
/**
|
|
* Sets the current point selected.
|
|
*/
|
|
void SetCurrentPoint(vtkIdType index);
|
|
|
|
//@{
|
|
/**
|
|
* Gets the selected point pen and brush.
|
|
*/
|
|
vtkGetObjectMacro(SelectedPointPen, vtkPen);
|
|
//@}
|
|
|
|
//@{
|
|
/**
|
|
* Depending on the control points item, the brush might not be taken into
|
|
* account.
|
|
*/
|
|
vtkGetObjectMacro(SelectedPointBrush, vtkBrush);
|
|
//@}
|
|
|
|
//@{
|
|
/**
|
|
* When enabled, a dedicated item is used to determine if a point should
|
|
* be added when clicking anywhere.
|
|
* This item can be recovered with GetAddPointItem and can this be placed
|
|
* below all other items. False by default.
|
|
*/
|
|
vtkGetMacro(UseAddPointItem, bool);
|
|
vtkSetMacro(UseAddPointItem, bool);
|
|
vtkBooleanMacro(UseAddPointItem, bool);
|
|
//@}
|
|
|
|
/**
|
|
* Item dedicated to add point, to be added below all other items.
|
|
* Used only if UseAddPointItem is set to true.
|
|
*/
|
|
vtkPlot* GetAddPointItem();
|
|
|
|
/**
|
|
* Recompute the bounds next time they are requested.
|
|
* You shouldn't have to call it but it is provided for rare cases.
|
|
*/
|
|
void ResetBounds();
|
|
|
|
//@{
|
|
/**
|
|
* Mouse and key events.
|
|
*/
|
|
bool MouseButtonPressEvent(const vtkContextMouseEvent& mouse) override;
|
|
bool MouseDoubleClickEvent(const vtkContextMouseEvent& mouse) override;
|
|
bool MouseButtonReleaseEvent(const vtkContextMouseEvent& mouse) override;
|
|
bool MouseMoveEvent(const vtkContextMouseEvent& mouse) override;
|
|
bool KeyPressEvent(const vtkContextKeyEvent& key) override;
|
|
bool KeyReleaseEvent(const vtkContextKeyEvent& key) override;
|
|
//@}
|
|
|
|
protected:
|
|
vtkControlPointsItem();
|
|
~vtkControlPointsItem() override;
|
|
|
|
friend class vtkPiecewisePointHandleItem;
|
|
|
|
void StartChanges();
|
|
void EndChanges();
|
|
void StartInteraction();
|
|
void StartInteractionIfNotStarted();
|
|
void Interaction();
|
|
void EndInteraction();
|
|
int GetInteractionsCount() const;
|
|
virtual void emitEvent(unsigned long event, void* params = nullptr) = 0;
|
|
|
|
static void CallComputePoints(
|
|
vtkObject* sender, unsigned long event, void* receiver, void* params);
|
|
|
|
//@{
|
|
/**
|
|
* Must be reimplemented by subclasses to calculate the points to draw.
|
|
* It's subclass responsibility to call ComputePoints() via the callback
|
|
*/
|
|
virtual void ComputePoints();
|
|
virtual vtkMTimeType GetControlPointsMTime() = 0;
|
|
//@}
|
|
|
|
/**
|
|
* Returns true if the supplied x, y are within the bounds or on a control point.
|
|
* If UseAddPointItem is true,
|
|
* returns true only if the supplied x, y are on a control point.
|
|
*/
|
|
bool Hit(const vtkContextMouseEvent& mouse) override;
|
|
|
|
//@{
|
|
/**
|
|
* Clamp the given 2D pos into the bounds of the function.
|
|
* Return true if the pos has been clamped, false otherwise.
|
|
*/
|
|
bool ClampValidDataPos(double pos[2]);
|
|
bool ClampValidScreenPos(double pos[2]);
|
|
//@}
|
|
|
|
//@{
|
|
/**
|
|
* Internal function that paints a collection of points and optionally
|
|
* excludes some.
|
|
*/
|
|
void DrawUnselectedPoints(vtkContext2D* painter);
|
|
void DrawSelectedPoints(vtkContext2D* painter);
|
|
virtual void DrawPoint(vtkContext2D* painter, vtkIdType index);
|
|
//@}
|
|
|
|
void SetCurrentPointPos(const vtkVector2f& newPos);
|
|
vtkIdType SetPointPos(vtkIdType point, const vtkVector2f& newPos);
|
|
void MoveCurrentPoint(const vtkVector2f& translation);
|
|
vtkIdType MovePoint(vtkIdType point, const vtkVector2f& translation);
|
|
|
|
inline vtkVector2f GetSelectionCenterOfMass() const;
|
|
vtkVector2f GetCenterOfMass(vtkIdTypeArray* pointIDs) const;
|
|
|
|
void Stroke(const vtkVector2f& newPos);
|
|
virtual void EditPoint(float vtkNotUsed(tX), float vtkNotUsed(tY));
|
|
|
|
/**
|
|
* Generate label for a control point.
|
|
*/
|
|
virtual vtkStdString GetControlPointLabel(vtkIdType index);
|
|
|
|
void AddPointId(vtkIdType addedPointId);
|
|
|
|
/**
|
|
* Return true if any of the end points is current point
|
|
* or part of the selection
|
|
*/
|
|
bool IsEndPointPicked();
|
|
|
|
/**
|
|
* Return true if the point is removable
|
|
*/
|
|
bool IsPointRemovable(vtkIdType pointId);
|
|
|
|
/**
|
|
* Compute the bounds for this item. Typically, the bounds should be aligned
|
|
* to the range of the vtkScalarsToColors or vtkPiecewiseFunction that is
|
|
* being controlled by the subclasses.
|
|
* Default implementation uses the range of the control points themselves.
|
|
*/
|
|
virtual void ComputeBounds(double* bounds);
|
|
|
|
vtkCallbackCommand* Callback;
|
|
vtkPen* SelectedPointPen;
|
|
vtkBrush* SelectedPointBrush;
|
|
int BlockUpdates;
|
|
int StartedInteractions;
|
|
int StartedChanges;
|
|
vtkIdType CurrentPoint;
|
|
|
|
double Bounds[4];
|
|
double UserBounds[4];
|
|
double ValidBounds[4];
|
|
|
|
vtkTransform2D* Transform;
|
|
float ScreenPointRadius;
|
|
|
|
bool StrokeMode;
|
|
bool SwitchPointsMode;
|
|
bool MouseMoved;
|
|
bool EnforceValidFunction;
|
|
vtkIdType PointToDelete;
|
|
bool PointAboutToBeDeleted;
|
|
vtkIdType PointToToggle;
|
|
bool PointAboutToBeToggled;
|
|
bool InvertShadow;
|
|
bool EndPointsXMovable;
|
|
bool EndPointsYMovable;
|
|
bool EndPointsRemovable;
|
|
bool ShowLabels;
|
|
char* LabelFormat;
|
|
|
|
private:
|
|
vtkControlPointsItem(const vtkControlPointsItem&) = delete;
|
|
void operator=(const vtkControlPointsItem&) = delete;
|
|
|
|
void ComputeBounds();
|
|
|
|
vtkIdType RemovePointId(vtkIdType removedPointId);
|
|
|
|
bool UseAddPointItem = false;
|
|
vtkNew<vtkControlPointsAddPointItem> AddPointItem;
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void vtkControlPointsItem::RemoveCurrentPoint()
|
|
{
|
|
this->RemovePoint(this->GetCurrentPoint());
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
vtkVector2f vtkControlPointsItem::GetSelectionCenterOfMass() const
|
|
{
|
|
return this->GetCenterOfMass(this->Selection);
|
|
}
|
|
|
|
#endif
|