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