/*========================================================================= Program: Visualization Toolkit Module: $RCSfile: vtkImplicitPlaneWidget.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 vtkImplicitPlaneWidget - 3D widget for manipulating an infinite plane // .SECTION Description // This 3D widget defines an infinite plane that can be interactively placed // in a scene. The widget is represented by a plane with a normal vector; the // plane is contained by a bounding box, and where the plane intersects the // bounding box the edges are shown (possibly tubed). The normal can be // selected and moved to rotate the plane; the plane itself can be selected // and translated in various directions. As the plane is moved, the implicit // plane function and polygon (representing the plane cut against the bounding // box) is updated. // // 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. If the "i" key (for // "interactor") is pressed, the vtkImplicitPlaneWidget will appear. (See // superclass documentation for information about changing this behavior.) // If you select the normal vector, the plane can be arbitrarily rotated. The // plane can be translated along the normal by selecting the plane and moving // it. The plane (the plane origin) can also be arbitrary moved by selecting // the plane with the middle mouse button. The right mouse button can be used // to uniformly scale the bounding box (moving "up" the box scales larger; // moving "down" the box scales smaller). 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 (or invoke the Off() method). // // The vtkImplicitPlaneWidget has several methods that can be used in // conjunction with other VTK objects. The GetPolyData() method can be used // to get a polygonal representation (the single polygon clipped by the // bounding box). 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). (Note: there is also a PlaceWidgetEvent that is invoked when // the widget is placed with PlaceWidget().) // // Some additional features of this class include the ability to control the // properties of the widget. You do this by setting property values on the // normal vector (selected and unselected properties); the plane (selected // and unselected properties); the outline (selected and unselected // properties); and the edges. The edges may also be tubed or not. // .SECTION Caveats // Note that the widget can be picked even when it is "behind" // other actors. This is an intended feature and not a bug. // .SECTION See Also // vtk3DWidget vtkBoxWidget vtkPlaneWidget vtkLineWidget vtkPointWidget // vtkSphereWidget vtkImagePlaneWidget #ifndef __vtkImplicitPlaneWidget_h #define __vtkImplicitPlaneWidget_h #include "vtkPolyDataSourceWidget.h" class vtkActor; class vtkPolyDataMapper; class vtkCellPicker; class vtkConeSource; class vtkLineSource; class vtkSphereSource; class vtkTubeFilter; class vtkPlane; class vtkCutter; class vtkProperty; class vtkImageData; class vtkOutlineFilter; class vtkFeatureEdges; class vtkPolyData; class vtkTransform; class VTK_WIDGETS_EXPORT vtkImplicitPlaneWidget : public vtkPolyDataSourceWidget { public: // Description: // Instantiate the object. static vtkImplicitPlaneWidget *New(); vtkTypeRevisionMacro(vtkImplicitPlaneWidget,vtkPolyDataSourceWidget); 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 origin of the plane. virtual void SetOrigin(double x, double y, double z); virtual void SetOrigin(double x[3]); double* GetOrigin(); void GetOrigin(double xyz[3]); // Description: // Get the normal to the plane. void SetNormal(double x, double y, double z); void SetNormal(double x[3]); double* GetNormal(); void GetNormal(double xyz[3]); // Description: // Force the plane widget to be aligned with one of the x-y-z axes. // If one axis is set on, the other two will be set off. // Remember that when the state changes, a ModifiedEvent is invoked. // This can be used to snap the plane to the axes if it is orginally // not aligned. void SetNormalToXAxis(int); vtkGetMacro(NormalToXAxis,int); vtkBooleanMacro(NormalToXAxis,int); void SetNormalToYAxis(int); vtkGetMacro(NormalToYAxis,int); vtkBooleanMacro(NormalToYAxis,int); void SetNormalToZAxis(int); vtkGetMacro(NormalToZAxis,int); vtkBooleanMacro(NormalToZAxis,int); // Description: // Turn on/off tubing of the wire outline of the plane. The tube thickens // the line by wrapping with a vtkTubeFilter. vtkSetMacro(Tubing,int); vtkGetMacro(Tubing,int); vtkBooleanMacro(Tubing,int); // Description: // Enable/disable the drawing of the plane. In some cases the plane // interferes with the object that it is operating on (i.e., the // plane interferes with the cut surface it produces producing // z-buffer artifacts.) void SetDrawPlane(int plane); vtkGetMacro(DrawPlane,int); vtkBooleanMacro(DrawPlane,int); // Description: // Turn on/off the ability to translate the bounding box by grabbing it // with the left mouse button. vtkSetMacro(OutlineTranslation,int); vtkGetMacro(OutlineTranslation,int); vtkBooleanMacro(OutlineTranslation,int); // Description: // Turn on/off the ability to move the widget outside of the input's bound vtkSetMacro(OutsideBounds,int); vtkGetMacro(OutsideBounds,int); vtkBooleanMacro(OutsideBounds,int); // Description: // Turn on/off the ability to scale with the mouse vtkSetMacro(ScaleEnabled,int); vtkGetMacro(ScaleEnabled,int); vtkBooleanMacro(ScaleEnabled,int); // Description: // Turn on/off the ability to translate the origin (sphere) // with the left mouse button. vtkSetMacro(OriginTranslation,int); vtkGetMacro(OriginTranslation,int); vtkBooleanMacro(OriginTranslation,int); // Description: // By default the arrow is 30% of the diagonal length. DiagonalRatio control // this ratio in the interval [0-2] vtkSetClampMacro(DiagonalRatio,double,0,2); vtkGetMacro(DiagonalRatio,double); // Description: // Grab the polydata that defines the plane. The polydata contains a single // polygon that is clipped by the bounding box. void GetPolyData(vtkPolyData *pd); // Description: // Satisfies superclass API. This returns a pointer to the underlying // PolyData (which represents the plane). vtkPolyDataAlgorithm* GetPolyDataAlgorithm(); // Description: // Get the implicit function for the plane. The user must provide the // instance of the class vtkPlane. Note that vtkPlane is a subclass of // vtkImplicitFunction, meaning that it can be used by a variety of filters // to perform clipping, cutting, and selection of data. void GetPlane(vtkPlane *plane); // Description: // Satisfies the superclass API. This will change the state of the widget // to match changes that have been made to the underlying PolyDataSource void UpdatePlacement(); // Description: // Control widget appearance virtual void SizeHandles(); // Description: // Get the properties on the normal (line and cone). vtkGetObjectMacro(NormalProperty,vtkProperty); vtkGetObjectMacro(SelectedNormalProperty,vtkProperty); // Description: // Get the plane properties. The properties of the plane when selected // and unselected can be manipulated. vtkGetObjectMacro(PlaneProperty,vtkProperty); vtkGetObjectMacro(SelectedPlaneProperty,vtkProperty); // Description: // Get the property of the outline. vtkGetObjectMacro(OutlineProperty,vtkProperty); vtkGetObjectMacro(SelectedOutlineProperty,vtkProperty); // Description: // Get the property of the intersection edges. (This property also // applies to the edges when tubed.) vtkGetObjectMacro(EdgesProperty,vtkProperty); protected: vtkImplicitPlaneWidget(); ~vtkImplicitPlaneWidget(); //BTX - manage the state of the widget int State; enum WidgetState { Start=0, MovingPlane, MovingOutline, MovingOrigin, Scaling, Pushing, Rotating, Outside }; //ETX //handles the events static void ProcessEvents(vtkObject* object, unsigned long event, void* clientdata, void* calldata); // ProcessEvents() dispatches to these methods. void OnLeftButtonDown(); void OnLeftButtonUp(); void OnMiddleButtonDown(); void OnMiddleButtonUp(); void OnRightButtonDown(); void OnRightButtonUp(); void OnMouseMove(); // Controlling ivars int NormalToXAxis; int NormalToYAxis; int NormalToZAxis; void UpdateRepresentation(); // The actual plane which is being manipulated vtkPlane *Plane; // The bounding box is represented by a single voxel image data vtkImageData *Box; vtkOutlineFilter *Outline; vtkPolyDataMapper *OutlineMapper; vtkActor *OutlineActor; void HighlightOutline(int highlight); int OutlineTranslation; //whether the outline can be moved int ScaleEnabled; //whether the widget can be scaled int OutsideBounds; //whether the widget can be moved outside input's bounds // The cut plane is produced with a vtkCutter vtkCutter *Cutter; vtkPolyDataMapper *CutMapper; vtkActor *CutActor; int DrawPlane; virtual void HighlightPlane(int highlight); // Optional tubes are represented by extracting boundary edges and tubing vtkFeatureEdges *Edges; vtkTubeFilter *EdgesTuber; vtkPolyDataMapper *EdgesMapper; vtkActor *EdgesActor; int Tubing; //control whether tubing is on // Control final length of the arrow: double DiagonalRatio; // The + normal cone vtkConeSource *ConeSource; vtkPolyDataMapper *ConeMapper; vtkActor *ConeActor; void HighlightNormal(int highlight); // The + normal line vtkLineSource *LineSource; vtkPolyDataMapper *LineMapper; vtkActor *LineActor; // The - normal cone vtkConeSource *ConeSource2; vtkPolyDataMapper *ConeMapper2; vtkActor *ConeActor2; // The - normal line vtkLineSource *LineSource2; vtkPolyDataMapper *LineMapper2; vtkActor *LineActor2; // The origin positioning handle vtkSphereSource *Sphere; vtkPolyDataMapper *SphereMapper; vtkActor *SphereActor; int OriginTranslation; //whether the origin (sphere) can be moved // Do the picking vtkCellPicker *Picker; // Transform the normal (used for rotation) vtkTransform *Transform; // Methods to manipulate the plane void ConstrainOrigin(double x[3]); void Rotate(int X, int Y, double *p1, double *p2, double *vpn); void TranslatePlane(double *p1, double *p2); void TranslateOutline(double *p1, double *p2); void TranslateOrigin(double *p1, double *p2); void Push(double *p1, double *p2); void Scale(double *p1, double *p2, int X, int Y); // Properties used to control the appearance of selected objects and // the manipulator in general. vtkProperty *NormalProperty; vtkProperty *SelectedNormalProperty; vtkProperty *PlaneProperty; vtkProperty *SelectedPlaneProperty; vtkProperty *OutlineProperty; vtkProperty *SelectedOutlineProperty; vtkProperty *EdgesProperty; void CreateDefaultProperties(); void GeneratePlane(); private: vtkImplicitPlaneWidget(const vtkImplicitPlaneWidget&); //Not implemented void operator=(const vtkImplicitPlaneWidget&); //Not implemented }; #endif