/*========================================================================= Program: Visualization Toolkit Module: $RCSfile: vtkBoxWidget.h,v $ 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. =========================================================================*/ // .NAME vtkBoxWidget - orthogonal hexahedron 3D widget // .SECTION Description // 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. // .SECTION Caveats // Note that handles can be picked even when they are "behind" other actors. // This is an intended feature and not a bug. // // 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! // .SECTION See Also // vtk3DWidget vtkPointWidget vtkLineWidget vtkPlaneWidget // vtkImplicitPlaneWidget vtkImagePlaneWidget #ifndef __vtkBoxWidget_h #define __vtkBoxWidget_h #include "vtk3DWidget.h" class vtkActor; class vtkCellPicker; class vtkPlanes; class vtkPoints; class vtkPolyData; class vtkPolyDataMapper; class vtkProp; class vtkProperty; class vtkSphereSource; class vtkTransform; class VTK_WIDGETS_EXPORT vtkBoxWidget : public vtk3DWidget { public: // Description: // Instantiate the object. static vtkBoxWidget *New(); vtkTypeRevisionMacro(vtkBoxWidget,vtk3DWidget); void PrintSelf(ostream& os, vtkIndent indent); // Description: // Methods that satisfy the superclass' API. virtual void SetEnabled(int); virtual void PlaceWidget(double bounds[6]); void PlaceWidget() {this->Superclass::PlaceWidget();} void PlaceWidget(double xmin, double xmax, double ymin, double ymax, double zmin, double zmax) {this->Superclass::PlaceWidget(xmin,xmax,ymin,ymax,zmin,zmax);} // Description: // 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); // Description: // 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,int); vtkGetMacro(InsideOut,int); vtkBooleanMacro(InsideOut,int); // Description: // 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., vtkTranformPolyData). virtual void GetTransform(vtkTransform *t); // Description: // 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); // Description: // 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); // Description: // 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); // Description: // Switches handles (the spheres) on or off by manipulating the actor // visibility. void HandlesOn(); void HandlesOff(); // Description: // 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); // Description: // 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); // Description: // 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);} // Description: // 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);} // Description: // Control the behavior of the widget. Translation, rotation, and // scaling can all be enabled and disabled. vtkSetMacro(TranslationEnabled,int); vtkGetMacro(TranslationEnabled,int); vtkBooleanMacro(TranslationEnabled,int); vtkSetMacro(ScalingEnabled,int); vtkGetMacro(ScalingEnabled,int); vtkBooleanMacro(ScalingEnabled,int); vtkSetMacro(RotationEnabled,int); vtkGetMacro(RotationEnabled,int); vtkBooleanMacro(RotationEnabled,int); protected: vtkBoxWidget(); ~vtkBoxWidget(); //BTX - manage the state of the widget int State; enum WidgetState { Start=0, Moving, Scaling, Outside }; //ETX // 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(); virtual void SizeHandles(); // wireframe outline vtkActor *HexOutline; vtkPolyDataMapper *OutlineMapper; vtkPolyData *OutlinePolyData; // Do the picking vtkCellPicker *HandlePicker; vtkCellPicker *HexPicker; vtkActor *CurrentHandle; int CurrentHexFace; // 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 int InsideOut; int OutlineFaceWires; int OutlineCursorWires; void GenerateOutline(); // Control whether scaling, rotation, and translation are supported int TranslationEnabled; int ScalingEnabled; int RotationEnabled; private: vtkBoxWidget(const vtkBoxWidget&); //Not implemented void operator=(const vtkBoxWidget&); //Not implemented }; #endif