/*========================================================================= Program: Visualization Toolkit Module: vtkBoxWidget.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 vtkBoxWidget * @brief orthogonal hexahedron 3D widget * * This 3D widget defines a region of interest that is represented by an * arbitrarily oriented hexahedron with interior face angles of 90 degrees * (orthogonal faces). The object creates 7 handles that can be moused on and * manipulated. The first six correspond to the six faces, the seventh is in * the center of the hexahedron. In addition, a bounding box outline is shown, * the "faces" of which can be selected for object rotation or scaling. A * nice feature of the object is that the vtkBoxWidget, like any 3D widget, * will work with the current interactor style. That is, if vtkBoxWidget does * not handle an event, then all other registered observers (including the * interactor style) have an opportunity to process the event. Otherwise, the * vtkBoxWidget will terminate the processing of the event that it handles. * * To use this object, just invoke SetInteractor() with the argument of the * method a vtkRenderWindowInteractor. You may also wish to invoke * "PlaceWidget()" to initially position the widget. The interactor will act * normally until the "i" key (for "interactor") is pressed, at which point the * vtkBoxWidget will appear. (See superclass documentation for information * about changing this behavior.) By grabbing the six face handles (use the * left mouse button), faces can be moved. By grabbing the center handle * (with the left mouse button), the entire hexahedron can be * translated. (Translation can also be employed by using the * "shift-left-mouse-button" combination inside of the widget.) Scaling is * achieved by using the right mouse button "up" the render window (makes the * widget bigger) or "down" the render window (makes the widget smaller). To * rotate vtkBoxWidget, pick a face (but not a face handle) and move the left * mouse. (Note: the mouse button must be held down during manipulation.) * Events that occur outside of the widget (i.e., no part of the widget is * picked) are propagated to any other registered obsevers (such as the * interaction style). Turn off the widget by pressing the "i" key again. * (See the superclass documentation on key press activiation.) * * The vtkBoxWidget is very flexible. It can be used to select, cut, clip, or * perform any other operation that depends on an implicit function (use the * GetPlanes() method); or it can be used to transform objects using a linear * transformation (use the GetTransform() method). Typical usage of the * widget is to make use of the StartInteractionEvent, InteractionEvent, and * EndInteractionEvent events. The InteractionEvent is called on mouse * motion; the other two events are called on button down and button up * (either left or right button). * * Some additional features of this class include the ability to control the * rendered properties of the widget. You can set the properties of the * selected and unselected representations of the parts of the widget. For * example, you can set the property for the handles, faces, and outline in * their normal and selected states. * * The box widget can be oriented by specifying a transformation matrix. * This transformation is applied to the initial bounding box as defined by * the PlaceWidget() method. DO NOT ASSUME that the transformation is applied * to a unit box centered at the origin; this is wrong! * * @sa * vtk3DWidget vtkPointWidget vtkLineWidget vtkPlaneWidget * vtkImplicitPlaneWidget vtkImagePlaneWidget */ #ifndef vtkBoxWidget_h #define vtkBoxWidget_h #include "vtk3DWidget.h" #include "vtkInteractionWidgetsModule.h" // For export macro class vtkActor; class vtkCellPicker; class vtkPlanes; class vtkPoints; class vtkPolyData; class vtkPolyDataMapper; class vtkProp; class vtkProperty; class vtkSphereSource; class vtkTransform; class VTKINTERACTIONWIDGETS_EXPORT vtkBoxWidget : public vtk3DWidget { public: /** * Instantiate the object. */ static vtkBoxWidget* New(); vtkTypeMacro(vtkBoxWidget, vtk3DWidget); void PrintSelf(ostream& os, vtkIndent indent) override; //@{ /** * Methods that satisfy the superclass' API. */ void SetEnabled(int) override; void PlaceWidget(double bounds[6]) override; void PlaceWidget() override { this->Superclass::PlaceWidget(); } void PlaceWidget( double xmin, double xmax, double ymin, double ymax, double zmin, double zmax) override { this->Superclass::PlaceWidget(xmin, xmax, ymin, ymax, zmin, zmax); } //@} /** * Get the planes describing the implicit function defined by the box * widget. The user must provide the instance of the class vtkPlanes. Note * that vtkPlanes is a subclass of vtkImplicitFunction, meaning that it can * be used by a variety of filters to perform clipping, cutting, and * selection of data. (The direction of the normals of the planes can be * reversed enabling the InsideOut flag.) */ void GetPlanes(vtkPlanes* planes); //@{ /** * Set/Get the InsideOut flag. When off, the normals point out of the * box. When on, the normals point into the hexahedron. InsideOut * is off by default. */ vtkSetMacro(InsideOut, vtkTypeBool); vtkGetMacro(InsideOut, vtkTypeBool); vtkBooleanMacro(InsideOut, vtkTypeBool); //@} /** * Retrieve a linear transform characterizing the transformation of the * box. Note that the transformation is relative to where PlaceWidget * was initially called. This method modifies the transform provided. The * transform can be used to control the position of vtkProp3D's, as well as * other transformation operations (e.g., vtkTransformPolyData). */ virtual void GetTransform(vtkTransform* t); /** * Set the position, scale and orientation of the box widget using the * transform specified. Note that the transformation is relative to * where PlaceWidget was initially called (i.e., the original bounding * box). */ virtual void SetTransform(vtkTransform* t); /** * Grab the polydata (including points) that define the box widget. The * polydata consists of 6 quadrilateral faces and 15 points. The first * eight points define the eight corner vertices; the next six define the * -x,+x, -y,+y, -z,+z face points; and the final point (the 15th out of 15 * points) defines the center of the hexahedron. These point values are * guaranteed to be up-to-date when either the InteractionEvent or * EndInteractionEvent events are invoked. The user provides the * vtkPolyData and the points and cells are added to it. */ void GetPolyData(vtkPolyData* pd); //@{ /** * Get the handle properties (the little balls are the handles). The * properties of the handles when selected and normal can be * set. */ vtkGetObjectMacro(HandleProperty, vtkProperty); vtkGetObjectMacro(SelectedHandleProperty, vtkProperty); //@} //@{ /** * Switches handles (the spheres) on or off by manipulating the actor * visibility. */ void HandlesOn(); void HandlesOff(); //@} //@{ /** * Get the face properties (the faces of the box). The * properties of the face when selected and normal can be * set. */ vtkGetObjectMacro(FaceProperty, vtkProperty); vtkGetObjectMacro(SelectedFaceProperty, vtkProperty); //@} //@{ /** * Get the outline properties (the outline of the box). The * properties of the outline when selected and normal can be * set. */ vtkGetObjectMacro(OutlineProperty, vtkProperty); vtkGetObjectMacro(SelectedOutlineProperty, vtkProperty); //@} //@{ /** * Control the representation of the outline. This flag enables * face wires. By default face wires are off. */ void SetOutlineFaceWires(int); vtkGetMacro(OutlineFaceWires, int); void OutlineFaceWiresOn() { this->SetOutlineFaceWires(1); } void OutlineFaceWiresOff() { this->SetOutlineFaceWires(0); } //@} //@{ /** * Control the representation of the outline. This flag enables * the cursor lines running between the handles. By default cursor * wires are on. */ void SetOutlineCursorWires(int); vtkGetMacro(OutlineCursorWires, int); void OutlineCursorWiresOn() { this->SetOutlineCursorWires(1); } void OutlineCursorWiresOff() { this->SetOutlineCursorWires(0); } //@} //@{ /** * Control the behavior of the widget. Translation, rotation, and * scaling can all be enabled and disabled. */ vtkSetMacro(TranslationEnabled, vtkTypeBool); vtkGetMacro(TranslationEnabled, vtkTypeBool); vtkBooleanMacro(TranslationEnabled, vtkTypeBool); vtkSetMacro(ScalingEnabled, vtkTypeBool); vtkGetMacro(ScalingEnabled, vtkTypeBool); vtkBooleanMacro(ScalingEnabled, vtkTypeBool); vtkSetMacro(RotationEnabled, vtkTypeBool); vtkGetMacro(RotationEnabled, vtkTypeBool); vtkBooleanMacro(RotationEnabled, vtkTypeBool); //@} protected: vtkBoxWidget(); ~vtkBoxWidget() override; // Manage the state of the widget int State; enum WidgetState { Start = 0, Moving, Scaling, Outside }; // Handles the events static void ProcessEvents( vtkObject* object, unsigned long event, void* clientdata, void* calldata); // ProcessEvents() dispatches to these methods. virtual void OnMouseMove(); virtual void OnLeftButtonDown(); virtual void OnLeftButtonUp(); virtual void OnMiddleButtonDown(); virtual void OnMiddleButtonUp(); virtual void OnRightButtonDown(); virtual void OnRightButtonUp(); // the hexahedron (6 faces) vtkActor* HexActor; vtkPolyDataMapper* HexMapper; vtkPolyData* HexPolyData; vtkPoints* Points; // used by others as well double N[6][3]; // the normals of the faces // A face of the hexahedron vtkActor* HexFace; vtkPolyDataMapper* HexFaceMapper; vtkPolyData* HexFacePolyData; // glyphs representing hot spots (e.g., handles) vtkActor** Handle; vtkPolyDataMapper** HandleMapper; vtkSphereSource** HandleGeometry; virtual void PositionHandles(); int HighlightHandle(vtkProp* prop); // returns cell id void HighlightFace(int cellId); void HighlightOutline(int highlight); void ComputeNormals(); void SizeHandles() override; // wireframe outline vtkActor* HexOutline; vtkPolyDataMapper* OutlineMapper; vtkPolyData* OutlinePolyData; // Do the picking vtkCellPicker* HandlePicker; vtkCellPicker* HexPicker; vtkActor* CurrentHandle; int CurrentHexFace; // Register internal Pickers within PickingManager void RegisterPickers() override; // Methods to manipulate the hexahedron. virtual void Translate(double* p1, double* p2); virtual void Scale(double* p1, double* p2, int X, int Y); virtual void Rotate(int X, int Y, double* p1, double* p2, double* vpn); void MovePlusXFace(double* p1, double* p2); void MoveMinusXFace(double* p1, double* p2); void MovePlusYFace(double* p1, double* p2); void MoveMinusYFace(double* p1, double* p2); void MovePlusZFace(double* p1, double* p2); void MoveMinusZFace(double* p1, double* p2); //"dir" is the direction in which the face can be moved i.e. the axis passing // through the center void MoveFace(double* p1, double* p2, double* dir, double* x1, double* x2, double* x3, double* x4, double* x5); // Helper method to obtain the direction in which the face is to be moved. // Handles special cases where some of the scale factors are 0. void GetDirection(const double Nx[3], const double Ny[3], const double Nz[3], double dir[3]); // Transform the hexahedral points (used for rotations) vtkTransform* Transform; // Properties used to control the appearance of selected objects and // the manipulator in general. vtkProperty* HandleProperty; vtkProperty* SelectedHandleProperty; vtkProperty* FaceProperty; vtkProperty* SelectedFaceProperty; vtkProperty* OutlineProperty; vtkProperty* SelectedOutlineProperty; void CreateDefaultProperties(); // Control the orientation of the normals vtkTypeBool InsideOut; int OutlineFaceWires; int OutlineCursorWires; void GenerateOutline(); // Control whether scaling, rotation, and translation are supported vtkTypeBool TranslationEnabled; vtkTypeBool ScalingEnabled; vtkTypeBool RotationEnabled; private: vtkBoxWidget(const vtkBoxWidget&) = delete; void operator=(const vtkBoxWidget&) = delete; }; #endif