1 /*========================================================================= 2 3 Program: Visualization Toolkit 4 Module: vtkImageTracerWidget.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 vtkImageTracerWidget - 3D widget for tracing on planar props. 16 // .SECTION Description 17 // vtkImageTracerWidget is different from other widgets in three distinct ways: 18 // 1) any sub-class of vtkProp can be input rather than just vtkProp3D, so that 19 // vtkImageActor can be set as the prop and then traced over, 2) the widget fires 20 // pick events at the input prop to decide where to move its handles, 3) the 21 // widget has 2D glyphs for handles instead of 3D spheres as is done in other 22 // sub-classes of vtk3DWidget. This widget is primarily designed for manually 23 // tracing over image data. 24 // The button actions and key modifiers are as follows for controlling the 25 // widget: 26 // 1) left button click over the image, hold and drag draws a free hand line. 27 // 2) left button click and release erases the widget line, 28 // if it exists, and repositions the first handle. 29 // 3) middle button click starts a snap drawn line. The line is terminated by 30 // clicking the middle button while depressing the ctrl key. 31 // 4) when tracing a continuous or snap drawn line, if the last cursor position 32 // is within a specified tolerance to the first handle, the widget line will form 33 // a closed loop. 34 // 5) right button clicking and holding on any handle that is part of a snap 35 // drawn line allows handle dragging: existing line segments are updated 36 // accordingly. If the path is open and AutoClose is set to On, the path can 37 // be closed by repositioning the first and last points over one another. 38 // 6) ctrl key + right button down on any handle will erase it: existing 39 // snap drawn line segments are updated accordingly. If the line was formed by 40 // continuous tracing, the line is deleted leaving one handle. 41 // 7) shift key + right button down on any snap drawn line segment will insert 42 // a handle at the cursor position. The line segment is split accordingly. 43 44 // .SECTION Caveats 45 // the input vtkDataSet should be vtkImageData. 46 47 // .SECTION See Also 48 // vtk3DWidget vtkBoxWidget vtkLineWidget vtkPointWidget vtkSphereWidget 49 // vtkImagePlaneWidget vtkImplicitPlaneWidget vtkPlaneWidget 50 51 #ifndef vtkImageTracerWidget_h 52 #define vtkImageTracerWidget_h 53 54 #include "vtkInteractionWidgetsModule.h" // For export macro 55 #include "vtk3DWidget.h" 56 57 class vtkAbstractPropPicker; 58 class vtkActor; 59 class vtkCellArray; 60 class vtkCellPicker; 61 class vtkFloatArray; 62 class vtkGlyphSource2D; 63 class vtkPoints; 64 class vtkPolyData; 65 class vtkProp; 66 class vtkProperty; 67 class vtkPropPicker; 68 class vtkTransform; 69 class vtkTransformPolyDataFilter; 70 71 #define VTK_ITW_PROJECTION_YZ 0 72 #define VTK_ITW_PROJECTION_XZ 1 73 #define VTK_ITW_PROJECTION_XY 2 74 #define VTK_ITW_SNAP_CELLS 0 75 #define VTK_ITW_SNAP_POINTS 1 76 77 class VTKINTERACTIONWIDGETS_EXPORT vtkImageTracerWidget : public vtk3DWidget 78 { 79 public: 80 // Description: 81 // Instantiate the object. 82 static vtkImageTracerWidget *New(); 83 84 vtkTypeMacro(vtkImageTracerWidget,vtk3DWidget); 85 void PrintSelf(ostream& os, vtkIndent indent); 86 87 // Description: 88 // Methods that satisfy the superclass' API. 89 virtual void SetEnabled(int); 90 virtual void PlaceWidget(double bounds[6]); PlaceWidget()91 void PlaceWidget() 92 {this->Superclass::PlaceWidget();} PlaceWidget(double xmin,double xmax,double ymin,double ymax,double zmin,double zmax)93 void PlaceWidget(double xmin, double xmax, double ymin, double ymax, 94 double zmin, double zmax) 95 {this->Superclass::PlaceWidget(xmin,xmax,ymin,ymax,zmin,zmax);} 96 97 // Description: 98 // Set/Get the handle properties (the 2D glyphs are the handles). The 99 // properties of the handles when selected and normal can be manipulated. 100 virtual void SetHandleProperty(vtkProperty*); 101 vtkGetObjectMacro(HandleProperty, vtkProperty); 102 virtual void SetSelectedHandleProperty(vtkProperty*); 103 vtkGetObjectMacro(SelectedHandleProperty, vtkProperty); 104 105 // Description: 106 // Set/Get the line properties. The properties of the line when selected 107 // and unselected can be manipulated. 108 virtual void SetLineProperty(vtkProperty*); 109 vtkGetObjectMacro(LineProperty, vtkProperty); 110 virtual void SetSelectedLineProperty(vtkProperty*); 111 vtkGetObjectMacro(SelectedLineProperty, vtkProperty); 112 113 // Description: 114 // Set the prop, usually a vtkImageActor, to trace over. 115 void SetViewProp(vtkProp* prop); 116 117 // Description: 118 // Force handles to be on a specific ortho plane. Default is Off. 119 vtkSetMacro(ProjectToPlane,int); 120 vtkGetMacro(ProjectToPlane,int); 121 vtkBooleanMacro(ProjectToPlane,int); 122 123 // Description: 124 // Set the projection normal. The normal in SetProjectionNormal is 0,1,2 125 // for YZ,XZ,XY planes respectively. Since the handles are 2D glyphs, it is 126 // necessary to specify a plane on which to generate them, even though 127 // ProjectToPlane may be turned off. 128 vtkSetClampMacro(ProjectionNormal,int,VTK_ITW_PROJECTION_YZ,VTK_ITW_PROJECTION_XY); 129 vtkGetMacro(ProjectionNormal,int); SetProjectionNormalToXAxes()130 void SetProjectionNormalToXAxes() 131 { this->SetProjectionNormal(0); } SetProjectionNormalToYAxes()132 void SetProjectionNormalToYAxes() 133 { this->SetProjectionNormal(1); } SetProjectionNormalToZAxes()134 void SetProjectionNormalToZAxes() 135 { this->SetProjectionNormal(2); } 136 137 // Description: 138 // Set the position of the widgets' handles in terms of a plane's position. 139 // e.g., if ProjectionNormal is 0, all of the x-coordinate values of the 140 // handles are set to ProjectionPosition. No attempt is made to ensure that 141 // the position is within the bounds of either the underlying image data or 142 // the prop on which tracing is performed. 143 void SetProjectionPosition(double position); 144 vtkGetMacro(ProjectionPosition,double); 145 146 // Description: 147 // Force snapping to image data while tracing. Default is Off. 148 void SetSnapToImage(int snap); 149 vtkGetMacro(SnapToImage,int); 150 vtkBooleanMacro(SnapToImage,int); 151 152 // Description: 153 // In concert with a CaptureRadius value, automatically 154 // form a closed path by connecting first to last path points. 155 // Default is Off. 156 vtkSetMacro(AutoClose,int); 157 vtkGetMacro(AutoClose,int); 158 vtkBooleanMacro(AutoClose,int); 159 160 // Description: 161 // Set/Get the capture radius for automatic path closing. For image 162 // data, capture radius should be half the distance between voxel/pixel 163 // centers. 164 // Default is 1.0 165 vtkSetMacro(CaptureRadius,double); 166 vtkGetMacro(CaptureRadius,double); 167 168 // Description: 169 // Grab the points and lines that define the traced path. These point values 170 // are guaranteed to be up-to-date when either the InteractionEvent or 171 // EndInteraction events are invoked. The user provides the vtkPolyData and 172 // the points and cells representing the line are added to it. 173 void GetPath(vtkPolyData *pd); 174 175 // Description: 176 // Get the handles' geometric representation via vtkGlyphSource2D. GetGlyphSource()177 vtkGlyphSource2D* GetGlyphSource() { return this->HandleGenerator; } 178 179 // Description: 180 // Set/Get the type of snapping to image data: center of a pixel/voxel or 181 // nearest point defining a pixel/voxel. 182 vtkSetClampMacro(ImageSnapType,int,VTK_ITW_SNAP_CELLS,VTK_ITW_SNAP_POINTS); 183 vtkGetMacro(ImageSnapType,int); 184 185 // Description: 186 // Set/Get the handle position in terms of a zero-based array of handles. 187 void SetHandlePosition(int handle, double xyz[3]); 188 void SetHandlePosition(int handle, double x, double y, double z); 189 void GetHandlePosition(int handle, double xyz[3]); 190 double* GetHandlePosition(int handle); 191 192 // Description: 193 // Get the number of handles. 194 vtkGetMacro(NumberOfHandles,int); 195 196 // Description: 197 // Enable/disable mouse interaction when the widget is visible. 198 void SetInteraction(int interact); 199 vtkGetMacro(Interaction,int); 200 vtkBooleanMacro(Interaction,int); 201 202 // Description: 203 // Initialize the widget with a set of points and generate 204 // lines between them. If AutoClose is on it will handle the 205 // case wherein the first and last points are congruent. 206 void InitializeHandles(vtkPoints*); 207 208 // Description: 209 // Is the path closed or open? 210 int IsClosed(); 211 212 // Description: 213 // Enable/Disable mouse button events 214 vtkSetMacro(HandleLeftMouseButton,int); 215 vtkGetMacro(HandleLeftMouseButton,int); 216 vtkBooleanMacro(HandleLeftMouseButton,int); 217 vtkSetMacro(HandleMiddleMouseButton,int); 218 vtkGetMacro(HandleMiddleMouseButton,int); 219 vtkBooleanMacro(HandleMiddleMouseButton,int); 220 vtkSetMacro(HandleRightMouseButton,int); 221 vtkGetMacro(HandleRightMouseButton,int); 222 vtkBooleanMacro(HandleRightMouseButton,int); 223 224 #ifdef VTK_WORKAROUND_WINDOWS_MANGLE 225 # define SetPropA SetProp 226 # define SetPropW SetProp 227 #endif 228 229 // Description: 230 // @deprecated Replaced by vtkImageTracerWidget::SetViewProp() as of VTK 5.0. 231 VTK_LEGACY(void SetProp(vtkProp* prop)); 232 233 #ifdef VTK_WORKAROUND_WINDOWS_MANGLE 234 # undef SetPropA 235 # undef SetPropW 236 //BTX 237 VTK_LEGACY(void SetPropA(vtkProp*)); 238 VTK_LEGACY(void SetPropW(vtkProp*)); 239 //ETX 240 #endif 241 242 protected: 243 vtkImageTracerWidget(); 244 ~vtkImageTracerWidget(); 245 246 //BTX - manage the state of the widget 247 int State; 248 enum WidgetState 249 { 250 Start=0, 251 Tracing, 252 Snapping, 253 Erasing, 254 Inserting, 255 Moving, 256 Translating, 257 Outside 258 }; 259 //ETX 260 261 //handles the events 262 static void ProcessEvents(vtkObject* object, 263 unsigned long event, 264 void* clientdata, 265 void* calldata); 266 267 // ProcessEvents() dispatches to these methods. 268 void OnLeftButtonDown(); 269 void OnLeftButtonUp(); 270 void OnMiddleButtonDown(); 271 void OnMiddleButtonUp(); 272 void OnRightButtonDown(); 273 void OnRightButtonUp(); 274 void OnMouseMove(); 275 276 void AddObservers(); 277 278 // Controlling ivars 279 int Interaction; 280 int ProjectionNormal; 281 double ProjectionPosition; 282 int ProjectToPlane; 283 int ImageSnapType; 284 int SnapToImage; 285 double CaptureRadius; // tolerance for auto path close 286 int AutoClose; 287 int IsSnapping; 288 int LastX; 289 int LastY; 290 291 void Trace(int , int ); 292 void Snap(double* ); 293 void MovePoint(const double* , const double* ); 294 void Translate(const double* , const double* ); 295 void ClosePath(); 296 297 // 2D glyphs representing hot spots (e.g., handles) 298 vtkActor **Handle; 299 vtkPolyData **HandleGeometry; 300 vtkGlyphSource2D *HandleGenerator; 301 302 // Transforms required as 2D glyphs are generated in the x-y plane 303 vtkTransformPolyDataFilter *TransformFilter; 304 vtkTransform *Transform; 305 vtkFloatArray *TemporaryHandlePoints; 306 307 void AppendHandles(double*); 308 void ResetHandles(); 309 void AllocateHandles(const int& ); 310 void AdjustHandlePosition(const int& , double*); 311 int HighlightHandle(vtkProp* ); // returns handle index or -1 on fail 312 void EraseHandle(const int& ); 313 virtual void SizeHandles(); 314 void InsertHandleOnLine(double* ); 315 316 int NumberOfHandles; 317 vtkActor *CurrentHandle; 318 int CurrentHandleIndex; 319 320 vtkProp *ViewProp; // the prop we want to pick on 321 vtkPropPicker *PropPicker; // the prop's picker 322 323 // Representation of the line 324 vtkPoints *LinePoints; 325 vtkCellArray *LineCells; 326 vtkActor *LineActor; 327 vtkPolyData *LineData; 328 vtkIdType CurrentPoints[2]; 329 330 void HighlightLine(const int& ); 331 void BuildLinesFromHandles(); 332 void ResetLine(double* ); 333 void AppendLine(double* ); 334 int PickCount; 335 336 // Do the picking of the handles and the lines 337 vtkCellPicker *HandlePicker; 338 vtkCellPicker *LinePicker; 339 vtkAbstractPropPicker* CurrentPicker; 340 341 // Register internal Pickers within PickingManager 342 virtual void RegisterPickers(); 343 344 // Properties used to control the appearance of selected objects and 345 // the manipulator in general. 346 vtkProperty *HandleProperty; 347 vtkProperty *SelectedHandleProperty; 348 vtkProperty *LineProperty; 349 vtkProperty *SelectedLineProperty; 350 void CreateDefaultProperties(); 351 352 // Enable/Disable mouse button events 353 int HandleLeftMouseButton; 354 int HandleMiddleMouseButton; 355 int HandleRightMouseButton; 356 357 private: 358 vtkImageTracerWidget(const vtkImageTracerWidget&); //Not implemented 359 void operator=(const vtkImageTracerWidget&); //Not implemented 360 }; 361 362 #endif 363