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