1 /*========================================================================= 2 3 Program: Visualization Toolkit 4 Module: vtkImplicitPlaneWidget.h 5 6 Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen 7 All rights reserved. 8 See Copyright.txt or http://www.kitware.com/Copyright.htm for details. 9 10 This software is distributed WITHOUT ANY WARRANTY; without even 11 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 12 PURPOSE. See the above copyright notice for more information. 13 14 =========================================================================*/ 15 // .NAME vtkImplicitPlaneWidget - 3D widget for manipulating an infinite plane 16 // .SECTION Description 17 // This 3D widget defines an infinite plane that can be interactively placed 18 // in a scene. The widget is represented by a plane with a normal vector; the 19 // plane is contained by a bounding box, and where the plane intersects the 20 // bounding box the edges are shown (possibly tubed). The normal can be 21 // selected and moved to rotate the plane; the plane itself can be selected 22 // and translated in various directions. As the plane is moved, the implicit 23 // plane function and polygon (representing the plane cut against the bounding 24 // box) is updated. 25 // 26 // To use this object, just invoke SetInteractor() with the argument of the 27 // method a vtkRenderWindowInteractor. You may also wish to invoke 28 // "PlaceWidget()" to initially position the widget. If the "i" key (for 29 // "interactor") is pressed, the vtkImplicitPlaneWidget will appear. (See 30 // superclass documentation for information about changing this behavior.) 31 // If you select the normal vector, the plane can be arbitrarily rotated. The 32 // plane can be translated along the normal by selecting the plane and moving 33 // it. The plane (the plane origin) can also be arbitrary moved by selecting 34 // the plane with the middle mouse button. The right mouse button can be used 35 // to uniformly scale the bounding box (moving "up" the box scales larger; 36 // moving "down" the box scales smaller). Events that occur outside of the 37 // widget (i.e., no part of the widget is picked) are propagated to any other 38 // registered obsevers (such as the interaction style). Turn off the widget 39 // by pressing the "i" key again (or invoke the Off() method). 40 // 41 // The vtkImplicitPlaneWidget has several methods that can be used in 42 // conjunction with other VTK objects. The GetPolyData() method can be used 43 // to get a polygonal representation (the single polygon clipped by the 44 // bounding box). Typical usage of the widget is to make use of the 45 // StartInteractionEvent, InteractionEvent, and EndInteractionEvent 46 // events. The InteractionEvent is called on mouse motion; the other two 47 // events are called on button down and button up (either left or right 48 // button). (Note: there is also a PlaceWidgetEvent that is invoked when 49 // the widget is placed with PlaceWidget().) 50 // 51 // Some additional features of this class include the ability to control the 52 // properties of the widget. You do this by setting property values on the 53 // normal vector (selected and unselected properties); the plane (selected 54 // and unselected properties); the outline (selected and unselected 55 // properties); and the edges. The edges may also be tubed or not. 56 57 // .SECTION See Also 58 // vtk3DWidget vtkBoxWidget vtkPlaneWidget vtkLineWidget vtkPointWidget 59 // vtkSphereWidget vtkImagePlaneWidget 60 61 #ifndef vtkImplicitPlaneWidget_h 62 #define vtkImplicitPlaneWidget_h 63 64 #include "vtkInteractionWidgetsModule.h" // For export macro 65 #include "vtkPolyDataSourceWidget.h" 66 67 class vtkActor; 68 class vtkPolyDataMapper; 69 class vtkCellPicker; 70 class vtkConeSource; 71 class vtkLineSource; 72 class vtkSphereSource; 73 class vtkTubeFilter; 74 class vtkPlane; 75 class vtkCutter; 76 class vtkProperty; 77 class vtkImageData; 78 class vtkOutlineFilter; 79 class vtkFeatureEdges; 80 class vtkPolyData; 81 class vtkTransform; 82 83 class VTKINTERACTIONWIDGETS_EXPORT vtkImplicitPlaneWidget : public vtkPolyDataSourceWidget 84 { 85 public: 86 // Description: 87 // Instantiate the object. 88 static vtkImplicitPlaneWidget *New(); 89 90 vtkTypeMacro(vtkImplicitPlaneWidget,vtkPolyDataSourceWidget); 91 void PrintSelf(ostream& os, vtkIndent indent); 92 93 // Description: 94 // Methods that satisfy the superclass' API. 95 virtual void SetEnabled(int); 96 virtual void PlaceWidget(double bounds[6]); PlaceWidget()97 void PlaceWidget() 98 {this->Superclass::PlaceWidget();} PlaceWidget(double xmin,double xmax,double ymin,double ymax,double zmin,double zmax)99 void PlaceWidget(double xmin, double xmax, double ymin, double ymax, 100 double zmin, double zmax) 101 {this->Superclass::PlaceWidget(xmin,xmax,ymin,ymax,zmin,zmax);} 102 103 // Description: 104 // Get the origin of the plane. 105 virtual void SetOrigin(double x, double y, double z); 106 virtual void SetOrigin(double x[3]); 107 double* GetOrigin(); 108 void GetOrigin(double xyz[3]); 109 110 // Description: 111 // Get the normal to the plane. 112 void SetNormal(double x, double y, double z); 113 void SetNormal(double x[3]); 114 double* GetNormal(); 115 void GetNormal(double xyz[3]); 116 117 // Description: 118 // Force the plane widget to be aligned with one of the x-y-z axes. 119 // If one axis is set on, the other two will be set off. 120 // Remember that when the state changes, a ModifiedEvent is invoked. 121 // This can be used to snap the plane to the axes if it is originally 122 // not aligned. 123 void SetNormalToXAxis(int); 124 vtkGetMacro(NormalToXAxis,int); 125 vtkBooleanMacro(NormalToXAxis,int); 126 void SetNormalToYAxis(int); 127 vtkGetMacro(NormalToYAxis,int); 128 vtkBooleanMacro(NormalToYAxis,int); 129 void SetNormalToZAxis(int); 130 vtkGetMacro(NormalToZAxis,int); 131 vtkBooleanMacro(NormalToZAxis,int); 132 133 // Description: 134 // Turn on/off tubing of the wire outline of the plane. The tube thickens 135 // the line by wrapping with a vtkTubeFilter. 136 vtkSetMacro(Tubing,int); 137 vtkGetMacro(Tubing,int); 138 vtkBooleanMacro(Tubing,int); 139 140 // Description: 141 // Enable/disable the drawing of the plane. In some cases the plane 142 // interferes with the object that it is operating on (i.e., the 143 // plane interferes with the cut surface it produces producing 144 // z-buffer artifacts.) 145 void SetDrawPlane(int plane); 146 vtkGetMacro(DrawPlane,int); 147 vtkBooleanMacro(DrawPlane,int); 148 149 // Description: 150 // Turn on/off the ability to translate the bounding box by grabbing it 151 // with the left mouse button. 152 vtkSetMacro(OutlineTranslation,int); 153 vtkGetMacro(OutlineTranslation,int); 154 vtkBooleanMacro(OutlineTranslation,int); 155 156 // Description: 157 // Turn on/off the ability to move the widget outside of the input's bound 158 vtkSetMacro(OutsideBounds,int); 159 vtkGetMacro(OutsideBounds,int); 160 vtkBooleanMacro(OutsideBounds,int); 161 162 // Description: 163 // Turn on/off the ability to scale with the mouse 164 vtkSetMacro(ScaleEnabled,int); 165 vtkGetMacro(ScaleEnabled,int); 166 vtkBooleanMacro(ScaleEnabled,int); 167 168 // Description: 169 // Turn on/off the ability to translate the origin (sphere) 170 // with the left mouse button. 171 vtkSetMacro(OriginTranslation,int); 172 vtkGetMacro(OriginTranslation,int); 173 vtkBooleanMacro(OriginTranslation,int); 174 175 // Description: 176 // By default the arrow is 30% of the diagonal length. DiagonalRatio control 177 // this ratio in the interval [0-2] 178 vtkSetClampMacro(DiagonalRatio,double,0,2); 179 vtkGetMacro(DiagonalRatio,double); 180 181 // Description: 182 // Grab the polydata that defines the plane. The polydata contains a single 183 // polygon that is clipped by the bounding box. 184 void GetPolyData(vtkPolyData *pd); 185 186 // Description: 187 // Satisfies superclass API. This returns a pointer to the underlying 188 // PolyData (which represents the plane). 189 vtkPolyDataAlgorithm* GetPolyDataAlgorithm(); 190 191 // Description: 192 // Get the implicit function for the plane. The user must provide the 193 // instance of the class vtkPlane. Note that vtkPlane is a subclass of 194 // vtkImplicitFunction, meaning that it can be used by a variety of filters 195 // to perform clipping, cutting, and selection of data. 196 void GetPlane(vtkPlane *plane); 197 198 // Description: 199 // Satisfies the superclass API. This will change the state of the widget 200 // to match changes that have been made to the underlying PolyDataSource 201 void UpdatePlacement(); 202 203 // Description: 204 // Control widget appearance 205 virtual void SizeHandles(); 206 207 // Description: 208 // Get the properties on the normal (line and cone). 209 vtkGetObjectMacro(NormalProperty,vtkProperty); 210 vtkGetObjectMacro(SelectedNormalProperty,vtkProperty); 211 212 // Description: 213 // Get the plane properties. The properties of the plane when selected 214 // and unselected can be manipulated. 215 vtkGetObjectMacro(PlaneProperty,vtkProperty); 216 vtkGetObjectMacro(SelectedPlaneProperty,vtkProperty); 217 218 // Description: 219 // Get the property of the outline. 220 vtkGetObjectMacro(OutlineProperty,vtkProperty); 221 vtkGetObjectMacro(SelectedOutlineProperty,vtkProperty); 222 223 // Description: 224 // Get the property of the intersection edges. (This property also 225 // applies to the edges when tubed.) 226 vtkGetObjectMacro(EdgesProperty,vtkProperty); 227 228 protected: 229 vtkImplicitPlaneWidget(); 230 ~vtkImplicitPlaneWidget(); 231 232 //BTX - manage the state of the widget 233 int State; 234 enum WidgetState 235 { 236 Start=0, 237 MovingPlane, 238 MovingOutline, 239 MovingOrigin, 240 Scaling, 241 Pushing, 242 Rotating, 243 Outside 244 }; 245 //ETX 246 247 //handles the events 248 static void ProcessEvents(vtkObject* object, unsigned long event, 249 void* clientdata, void* calldata); 250 251 // ProcessEvents() dispatches to these methods. 252 void OnLeftButtonDown(); 253 void OnLeftButtonUp(); 254 void OnMiddleButtonDown(); 255 void OnMiddleButtonUp(); 256 void OnRightButtonDown(); 257 void OnRightButtonUp(); 258 void OnMouseMove(); 259 260 // Controlling ivars 261 int NormalToXAxis; 262 int NormalToYAxis; 263 int NormalToZAxis; 264 void UpdateRepresentation(); 265 266 // The actual plane which is being manipulated 267 vtkPlane *Plane; 268 269 // The bounding box is represented by a single voxel image data 270 vtkImageData *Box; 271 vtkOutlineFilter *Outline; 272 vtkPolyDataMapper *OutlineMapper; 273 vtkActor *OutlineActor; 274 void HighlightOutline(int highlight); 275 int OutlineTranslation; //whether the outline can be moved 276 int ScaleEnabled; //whether the widget can be scaled 277 int OutsideBounds; //whether the widget can be moved outside input's bounds 278 279 // The cut plane is produced with a vtkCutter 280 vtkCutter *Cutter; 281 vtkPolyDataMapper *CutMapper; 282 vtkActor *CutActor; 283 int DrawPlane; 284 virtual void HighlightPlane(int highlight); 285 286 // Optional tubes are represented by extracting boundary edges and tubing 287 vtkFeatureEdges *Edges; 288 vtkTubeFilter *EdgesTuber; 289 vtkPolyDataMapper *EdgesMapper; 290 vtkActor *EdgesActor; 291 int Tubing; //control whether tubing is on 292 293 // Control final length of the arrow: 294 double DiagonalRatio; 295 296 // The + normal cone 297 vtkConeSource *ConeSource; 298 vtkPolyDataMapper *ConeMapper; 299 vtkActor *ConeActor; 300 void HighlightNormal(int highlight); 301 302 // The + normal line 303 vtkLineSource *LineSource; 304 vtkPolyDataMapper *LineMapper; 305 vtkActor *LineActor; 306 307 // The - normal cone 308 vtkConeSource *ConeSource2; 309 vtkPolyDataMapper *ConeMapper2; 310 vtkActor *ConeActor2; 311 312 // The - normal line 313 vtkLineSource *LineSource2; 314 vtkPolyDataMapper *LineMapper2; 315 vtkActor *LineActor2; 316 317 // The origin positioning handle 318 vtkSphereSource *Sphere; 319 vtkPolyDataMapper *SphereMapper; 320 vtkActor *SphereActor; 321 int OriginTranslation; //whether the origin (sphere) can be moved 322 323 // Do the picking 324 vtkCellPicker *Picker; 325 326 // Register internal Pickers within PickingManager 327 virtual void RegisterPickers(); 328 329 // Transform the normal (used for rotation) 330 vtkTransform *Transform; 331 332 // Methods to manipulate the plane 333 void ConstrainOrigin(double x[3]); 334 void Rotate(int X, int Y, double *p1, double *p2, double *vpn); 335 void TranslatePlane(double *p1, double *p2); 336 void TranslateOutline(double *p1, double *p2); 337 void TranslateOrigin(double *p1, double *p2); 338 void Push(double *p1, double *p2); 339 void Scale(double *p1, double *p2, int X, int Y); 340 341 // Properties used to control the appearance of selected objects and 342 // the manipulator in general. 343 vtkProperty *NormalProperty; 344 vtkProperty *SelectedNormalProperty; 345 vtkProperty *PlaneProperty; 346 vtkProperty *SelectedPlaneProperty; 347 vtkProperty *OutlineProperty; 348 vtkProperty *SelectedOutlineProperty; 349 vtkProperty *EdgesProperty; 350 void CreateDefaultProperties(); 351 352 void GeneratePlane(); 353 354 private: 355 vtkImplicitPlaneWidget(const vtkImplicitPlaneWidget&); //Not implemented 356 void operator=(const vtkImplicitPlaneWidget&); //Not implemented 357 }; 358 359 #endif 360