1 /*=========================================================================
2 
3   Program:   Visualization Toolkit
4   Module:    vtkConstrainedPointHandleRepresentation.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 /**
16  * @class   vtkConstrainedPointHandleRepresentation
17  * @brief   point representation constrained to a 2D plane
18  *
19  * This class is used to represent a vtkHandleWidget. It represents a
20  * position in 3D world coordinates that is constrained to a specified plane.
21  * The default look is to draw a white point when this widget is not selected
22  * or active, a thin green circle when it is highlighted, and a thicker cyan
23  * circle when it is active (being positioned). Defaults can be adjusted - but
24  * take care to define cursor geometry that makes sense for this widget.
25  * The geometry will be aligned on the constraining plane, with the plane
26  * normal aligned with the X axis of the geometry (similar behavior to
27  * vtkGlyph3D).
28  *
29  * TODO: still need to work on
30  * 1) translation when mouse is outside bounding planes
31  * 2) size of the widget
32  *
33  * @sa
34  * vtkHandleRepresentation vtkHandleWidget
35  */
36 
37 #ifndef vtkConstrainedPointHandleRepresentation_h
38 #define vtkConstrainedPointHandleRepresentation_h
39 
40 #include "vtkHandleRepresentation.h"
41 #include "vtkInteractionWidgetsModule.h" // For export macro
42 
43 class vtkProperty;
44 class vtkActor;
45 class vtkPolyDataMapper;
46 class vtkPolyData;
47 class vtkGlyph3D;
48 class vtkPoints;
49 class vtkPolyData;
50 class vtkPlane;
51 class vtkPlaneCollection;
52 class vtkPlanes;
53 class vtkRenderer;
54 
55 class VTKINTERACTIONWIDGETS_EXPORT vtkConstrainedPointHandleRepresentation
56   : public vtkHandleRepresentation
57 {
58 public:
59   /**
60    * Instantiate this class.
61    */
62   static vtkConstrainedPointHandleRepresentation* New();
63 
64   ///@{
65   /**
66    * Standard methods for instances of this class.
67    */
68   vtkTypeMacro(vtkConstrainedPointHandleRepresentation, vtkHandleRepresentation);
69   void PrintSelf(ostream& os, vtkIndent indent) override;
70   ///@}
71 
72   using vtkHandleRepresentation::Translate;
73 
74   ///@{
75   /**
76    * Specify the cursor shape. Keep in mind that the shape will be
77    * aligned with the constraining plane by orienting it such that
78    * the x axis of the geometry lies along the normal of the plane.
79    */
80   void SetCursorShape(vtkPolyData* cursorShape);
81   vtkPolyData* GetCursorShape();
82   ///@}
83 
84   ///@{
85   /**
86    * Specify the shape of the cursor (handle) when it is active.
87    * This is the geometry that will be used when the mouse is
88    * close to the handle or if the user is manipulating the handle.
89    */
90   void SetActiveCursorShape(vtkPolyData* activeShape);
91   vtkPolyData* GetActiveCursorShape();
92   ///@}
93 
94   ///@{
95   /**
96    * Set the projection normal to lie along the x, y, or z axis,
97    * or to be oblique. If it is oblique, then the plane is
98    * defined in the ObliquePlane ivar.
99    */
100   vtkSetClampMacro(ProjectionNormal, int, vtkConstrainedPointHandleRepresentation::XAxis,
101     vtkConstrainedPointHandleRepresentation::Oblique);
102   vtkGetMacro(ProjectionNormal, int);
103   ///@}
104 
SetProjectionNormalToXAxis()105   void SetProjectionNormalToXAxis()
106   {
107     this->SetProjectionNormal(vtkConstrainedPointHandleRepresentation::XAxis);
108   }
SetProjectionNormalToYAxis()109   void SetProjectionNormalToYAxis()
110   {
111     this->SetProjectionNormal(vtkConstrainedPointHandleRepresentation::YAxis);
112   }
SetProjectionNormalToZAxis()113   void SetProjectionNormalToZAxis()
114   {
115     this->SetProjectionNormal(vtkConstrainedPointHandleRepresentation::ZAxis);
116   }
SetProjectionNormalToOblique()117   void SetProjectionNormalToOblique()
118   {
119     this->SetProjectionNormal(vtkConstrainedPointHandleRepresentation::Oblique);
120   }
121 
122   ///@{
123   /**
124    * If the ProjectionNormal is set to Oblique, then this is the
125    * oblique plane used to constrain the handle position
126    */
127   void SetObliquePlane(vtkPlane*);
128   vtkGetObjectMacro(ObliquePlane, vtkPlane);
129   ///@}
130 
131   ///@{
132   /**
133    * The position of the bounding plane from the origin along the
134    * normal. The origin and normal are defined in the oblique plane
135    * when the ProjectionNormal is Oblique. For the X, Y, and Z
136    * axes projection normals, the normal is the axis direction, and
137    * the origin is (0,0,0).
138    */
139   void SetProjectionPosition(double position);
140   vtkGetMacro(ProjectionPosition, double);
141   ///@}
142 
143   ///@{
144   /**
145    * A collection of plane equations used to bound the position of the point.
146    * This is in addition to confining the point to a plane - these constraints
147    * are meant to, for example, keep a point within the extent of an image.
148    * Using a set of plane equations allows for more complex bounds (such as
149    * bounding a point to an oblique reliced image that has hexagonal shape)
150    * than a simple extent.
151    */
152   void AddBoundingPlane(vtkPlane* plane);
153   void RemoveBoundingPlane(vtkPlane* plane);
154   void RemoveAllBoundingPlanes();
155   virtual void SetBoundingPlanes(vtkPlaneCollection*);
156   vtkGetObjectMacro(BoundingPlanes, vtkPlaneCollection);
157   void SetBoundingPlanes(vtkPlanes* planes);
158   ///@}
159 
160   /**
161    * Overridden from the base class. It converts the display
162    * co-ordinates to world co-ordinates. It returns 1 if the point lies
163    * within the constrained region, otherwise return 0
164    */
165   int CheckConstraint(vtkRenderer* renderer, double pos[2]) override;
166 
167   ///@{
168   /**
169    * Set/Get the position of the point in display coordinates.  These are
170    * convenience methods that extend the superclasses' GetHandlePosition()
171    * method. Note that only the x-y coordinate values are used
172    */
173   void SetPosition(double x, double y, double z);
174   void SetPosition(double xyz[3]);
175   double* GetPosition();
176   void GetPosition(double xyz[3]);
177   ///@}
178 
179   ///@{
180   /**
181    * This is the property used when the handle is not active
182    * (the mouse is not near the handle)
183    */
184   vtkGetObjectMacro(Property, vtkProperty);
185   ///@}
186 
187   ///@{
188   /**
189    * This is the property used when the mouse is near the
190    * handle (but the user is not yet interacting with it)
191    */
192   vtkGetObjectMacro(SelectedProperty, vtkProperty);
193   ///@}
194 
195   ///@{
196   /**
197    * This is the property used when the user is interacting
198    * with the handle.
199    */
200   vtkGetObjectMacro(ActiveProperty, vtkProperty);
201   ///@}
202 
203   ///@{
204   /**
205    * Subclasses of vtkConstrainedPointHandleRepresentation must implement these methods. These
206    * are the methods that the widget and its representation use to
207    * communicate with each other.
208    */
209   void SetRenderer(vtkRenderer* ren) override;
210   void BuildRepresentation() override;
211   void StartWidgetInteraction(double eventPos[2]) override;
212   void WidgetInteraction(double eventPos[2]) override;
213   int ComputeInteractionState(int X, int Y, int modify) override;
214   ///@}
215 
216   /**
217    * Method overridden from Superclass. computes the world
218    * co-ordinates using GetIntersectionPosition()
219    */
220   void SetDisplayPosition(double pos[3]) override;
221 
222   ///@{
223   /**
224    * Methods to make this class behave as a vtkProp.
225    */
226   void GetActors(vtkPropCollection*) override;
227   void ReleaseGraphicsResources(vtkWindow*) override;
228   int RenderOverlay(vtkViewport* viewport) override;
229   int RenderOpaqueGeometry(vtkViewport* viewport) override;
230   int RenderTranslucentPolygonalGeometry(vtkViewport* viewport) override;
231   vtkTypeBool HasTranslucentPolygonalGeometry() override;
232   void ShallowCopy(vtkProp* prop) override;
233   ///@}
234 
235   enum
236   {
237     XAxis = 0,
238     YAxis,
239     ZAxis,
240     Oblique
241   };
242 
243   void Highlight(int highlight) override;
244 
245 protected:
246   vtkConstrainedPointHandleRepresentation();
247   ~vtkConstrainedPointHandleRepresentation() override;
248 
249   // Render the cursor
250   vtkActor* Actor;
251   vtkPolyDataMapper* Mapper;
252   vtkGlyph3D* Glypher;
253   vtkPolyData* CursorShape;
254   vtkPolyData* ActiveCursorShape;
255   vtkPolyData* FocalData;
256   vtkPoints* FocalPoint;
257 
258   // Support picking
259   double LastPickPosition[3];
260   double LastEventPosition[2];
261 
262   // Methods to manipulate the cursor
263   void Translate(const double* eventPos) override;
264   void Scale(const double* eventPos);
265 
266   // Properties used to control the appearance of selected objects and
267   // the manipulator in general.
268   vtkProperty* Property;
269   vtkProperty* SelectedProperty;
270   vtkProperty* ActiveProperty;
271   void CreateDefaultProperties();
272 
273   // Controlling vars
274   int ProjectionNormal;
275   double ProjectionPosition;
276   int ProjectToPlane;
277   vtkPlane* ObliquePlane;
278 
279   vtkPlaneCollection* BoundingPlanes;
280 
281   // Internal method for computing 3D location from 2D screen position
282   int GetIntersectionPosition(const double eventPos[2], double worldPos[3], double tolerance = 0.0,
283     vtkRenderer* renderer = nullptr);
284 
285   // Internal method for getting the project normal as a vector
286   void GetProjectionNormal(double normal[3]);
287 
288   // Internal method for getting the origin of the
289   // constraining plane as a 3-tuple
290   void GetProjectionOrigin(double origin[3]);
291 
292   // Distance between where the mouse event happens and where the
293   // widget is focused - maintain this distance during interaction.
294   double InteractionOffset[2];
295 
296 private:
297   vtkConstrainedPointHandleRepresentation(const vtkConstrainedPointHandleRepresentation&) = delete;
298   void operator=(const vtkConstrainedPointHandleRepresentation&) = delete;
299 };
300 
301 #endif
302