Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
mitkAffineImageCropperInteractor.cpp
Go to the documentation of this file.
1 /*===================================================================
2 
3 The Medical Imaging Interaction Toolkit (MITK)
4 
5 Copyright (c) German Cancer Research Center,
6 Division of Medical and Biological Informatics.
7 All rights reserved.
8 
9 This software is distributed WITHOUT ANY WARRANTY; without
10 even the implied warranty of MERCHANTABILITY or FITNESS FOR
11 A PARTICULAR PURPOSE.
12 
13 See LICENSE.txt or http://www.mitk.org for details.
14 
15 ===================================================================*/
16 
18 
19 #include "mitkInteractionConst.h"
21 #include "mitkRotationOperation.h"
22 #include "mitkSurface.h"
23 #include "mitkVtkMapper.h"
24 
25 #include <mitkBoundingObject.h>
26 #include <mitkMouseWheelEvent.h>
27 #include <vtkCamera.h>
28 #include <vtkInteractorStyle.h>
29 #include <vtkMatrix4x4.h>
30 #include <vtkPointData.h>
31 #include <vtkPolyData.h>
32 #include <vtkRenderWindowInteractor.h>
33 
34 #include <mitkRotationOperation.h>
35 #include <mitkScaleOperation.h>
36 
38 {
39  m_OriginalGeometry = Geometry3D::New();
40 }
41 
43 {
44 }
45 
47 {
48  // **Conditions** that can be used in the state machine, to ensure that certain conditions are met, before actually
49  // executing an action
50  CONNECT_CONDITION("isOverObject", CheckOverObject);
51 
52  // **Function** in the statmachine patterns also referred to as **Actions**
53  CONNECT_FUNCTION("selectObject", SelectObject);
54  CONNECT_FUNCTION("deselectObject", DeselectObject);
55  CONNECT_FUNCTION("initTranslate", InitTranslate);
56  CONNECT_FUNCTION("initRotate", InitRotate);
57  CONNECT_FUNCTION("initDeformation", InitDeformation);
58  CONNECT_FUNCTION("translateObject", TranslateObject);
59  CONNECT_FUNCTION("rotateObject", RotateObject);
60  CONNECT_FUNCTION("deformObject", DeformObject);
61  CONNECT_FUNCTION("scaleRadius", ScaleRadius);
62 }
63 
65 {
66 }
67 
69 {
70  mitk::DataNode::Pointer dn = this->GetDataNode();
71  if (dn.IsNull())
72  return false;
73  const InteractionPositionEvent *positionEvent = dynamic_cast<const InteractionPositionEvent *>(interactionEvent);
74  Point3D currentPickedPoint = positionEvent->GetPositionInWorld();
75  mitk::BoundingObject *object = dynamic_cast<mitk::BoundingObject *>(dn->GetData());
76  object->GetGeometry()->WorldToIndex(currentPickedPoint, currentPickedPoint);
77  return object && object->GetGeometry()->GetBoundingBox()->IsInside(currentPickedPoint);
78 }
79 
81 {
82  mitk::DataNode::Pointer dn = this->GetDataNode();
83 
84  if (dn.IsNull())
85  return;
86 
87  m_SelectedNode = dn;
88 
89  interactionEvent->GetSender()->GetRenderingManager()->RequestUpdateAll();
90 }
91 
92 void mitk::AffineImageCropperInteractor::Deselect()
93 {
94  mitk::DataNode::Pointer dn = this->GetDataNode();
95 
96  if (dn.IsNull())
97  return;
98 
99  m_SelectedNode = dn;
100 }
101 
103 {
104  Deselect();
105  interactionEvent->GetSender()->GetRenderingManager()->RequestUpdateAll();
106 }
107 
109 {
110  const MouseWheelEvent *wheelEvent = dynamic_cast<const MouseWheelEvent *>(interactionEvent);
111  if (wheelEvent == NULL)
112  return;
113 
114  if (m_SelectedNode.IsNull())
115  return;
116 
117  double scale = (double)(wheelEvent->GetWheelDelta()) / 64.0;
118  mitk::Point3D newScale;
119  newScale[0] = newScale[1] = newScale[2] = scale;
120 
121  mitk::Point3D anchorPoint = wheelEvent->GetPositionInWorld();
122  ScaleOperation *doOp = new mitk::ScaleOperation(OpSCALE, newScale, anchorPoint);
123  m_SelectedNode->GetData()->GetGeometry()->ExecuteOperation(doOp);
124 
125  interactionEvent->GetSender()->GetRenderingManager()->RequestUpdateAll();
126 }
127 
129 {
130  if (m_SelectedNode.IsNull())
131  return;
132  InteractionPositionEvent *positionEvent = dynamic_cast<InteractionPositionEvent *>(interactionEvent);
133  if (positionEvent == NULL)
134  return;
135 
136  m_InitialPickedPoint = positionEvent->GetPositionInWorld();
137  m_InitialPickedDisplayPoint = positionEvent->GetPointerPositionOnScreen();
138 
139  mitk::Surface::Pointer surface = dynamic_cast<mitk::Surface *>(m_SelectedNode->GetData());
140  mitk::BaseGeometry::Pointer surGeo = surface->GetGeometry();
141  m_InitialOrigin = surGeo->GetOrigin();
142 }
143 
145 {
146  InteractionPositionEvent *positionEvent = dynamic_cast<InteractionPositionEvent *>(interactionEvent);
147  if (positionEvent == NULL)
148  return;
149 
150  m_InitialPickedPoint = positionEvent->GetPositionInWorld();
151  m_InitialPickedDisplayPoint = positionEvent->GetPointerPositionOnScreen();
152 
153  mitk::Surface::Pointer surface = dynamic_cast<mitk::Surface *>(m_SelectedNode->GetData());
154  mitk::BaseGeometry::Pointer surGeo = surface->GetGeometry();
155  m_OriginalGeometry = dynamic_cast<mitk::Geometry3D *>(surGeo.GetPointer());
156 }
157 
159 {
160  InteractionPositionEvent *positionEvent = dynamic_cast<InteractionPositionEvent *>(interactionEvent);
161  if (positionEvent == NULL)
162  return;
163 
164  m_InitialPickedPoint = positionEvent->GetPositionInWorld();
165  m_InitialPickedDisplayPoint = positionEvent->GetPointerPositionOnScreen();
166 
167  mitk::Surface::Pointer surface = dynamic_cast<mitk::Surface *>(m_SelectedNode->GetData());
168  mitk::BaseGeometry::Pointer surGeo = surface->GetGeometry();
169  m_OriginalGeometry = dynamic_cast<mitk::Geometry3D *>(surGeo.GetPointer());
170 }
171 
173 {
174  InteractionPositionEvent *positionEvent = dynamic_cast<InteractionPositionEvent *>(interactionEvent);
175  if (positionEvent == NULL)
176  return;
177 
178  Point3D currentPickedPoint = positionEvent->GetPositionInWorld();
179 
180  Vector3D interactionMove;
181  interactionMove[0] = currentPickedPoint[0] - m_InitialPickedPoint[0];
182  interactionMove[1] = currentPickedPoint[1] - m_InitialPickedPoint[1];
183  interactionMove[2] = currentPickedPoint[2] - m_InitialPickedPoint[2];
184 
185  mitk::Surface::Pointer surface = dynamic_cast<mitk::Surface *>(m_SelectedNode->GetData());
186  mitk::BaseGeometry::Pointer surGeo = surface->GetGeometry();
187  surGeo->SetOrigin(m_InitialOrigin);
188  surGeo->Translate(interactionMove);
189 
190  interactionEvent->GetSender()->GetRenderingManager()->RequestUpdateAll();
191 }
192 
194 {
195  InteractionPositionEvent *positionEvent = dynamic_cast<InteractionPositionEvent *>(interactionEvent);
196  if (positionEvent == NULL)
197  return;
198 
199  Point3D currentPickedPoint = positionEvent->GetPositionInWorld();
200  Vector3D interactionMove = currentPickedPoint - m_InitialPickedPoint;
201 
202  mitk::Surface::Pointer surface = dynamic_cast<mitk::Surface *>(m_SelectedNode->GetData());
203  surface->SetGeometry(m_OriginalGeometry);
204  mitk::BaseGeometry::Pointer surGeo = surface->GetGeometry();
205 
206  surGeo->WorldToIndex(interactionMove, interactionMove);
207  Point3D scale;
208  for (int i = 0; i < 3; ++i)
209  {
210  scale[i] = (interactionMove[i] * surGeo->GetMatrixColumn(i).magnitude()) - 1;
211  }
212 
213  mitk::Point3D anchorPoint = surGeo->GetCenter();
214 
215  ScaleOperation *doOp = new mitk::ScaleOperation(OpSCALE, scale, anchorPoint);
216  surGeo->ExecuteOperation(doOp);
217 
219 }
220 
222 {
223  InteractionPositionEvent *positionEvent = dynamic_cast<InteractionPositionEvent *>(interactionEvent);
224  if (positionEvent == NULL)
225  return;
226 
227  Point2D currentPickedDisplayPoint = positionEvent->GetPointerPositionOnScreen();
228  if (currentPickedDisplayPoint.EuclideanDistanceTo(m_InitialPickedDisplayPoint) < 1)
229  return;
230 
231  vtkRenderer *currentVtkRenderer = interactionEvent->GetSender()->GetVtkRenderer();
232 
233  if (currentVtkRenderer && currentVtkRenderer->GetActiveCamera())
234  {
235  double vpn[3];
236  currentVtkRenderer->GetActiveCamera()->GetViewPlaneNormal(vpn);
237 
238  Vector3D rotationAxis;
239  rotationAxis[0] = vpn[0];
240  rotationAxis[1] = vpn[1];
241  rotationAxis[2] = vpn[2];
242  rotationAxis.Normalize();
243 
244  Vector2D move = currentPickedDisplayPoint - m_InitialPickedDisplayPoint;
245 
246  double rotationAngle = -57.3 * atan(move[0] / move[1]);
247  if (move[1] < 0)
248  rotationAngle += 180;
249 
250  // Use center of data bounding box as center of rotation
251  Point3D rotationCenter = m_OriginalGeometry->GetCenter();
252  if (positionEvent->GetSender()->GetMapperID() == BaseRenderer::Standard2D)
253  rotationCenter = m_InitialPickedPoint;
254 
255  // Reset current Geometry3D to original state (pre-interaction) and
256  // apply rotation
257  RotationOperation op(OpROTATE, rotationCenter, rotationAxis, rotationAngle);
258  Geometry3D::Pointer newGeometry = static_cast<Geometry3D *>(m_OriginalGeometry->Clone().GetPointer());
259  newGeometry->ExecuteOperation(&op);
260  m_SelectedNode->GetData()->SetGeometry(newGeometry);
261 
262  interactionEvent->GetSender()->GetRenderingManager()->RequestUpdateAll();
263  }
264 }
Class for storing surfaces (vtkPolyData).
Definition: mitkSurface.h:32
Super class for all position events.
Standard implementation of BaseGeometry.
virtual bool CheckOverObject(const InteractionEvent *)
Checks if the mouse pointer is over the object.
BaseRenderer * GetSender() const
virtual void InitTranslate(StateMachineAction *, InteractionEvent *)
virtual void DeformObject(StateMachineAction *, InteractionEvent *)
virtual void InitRotate(StateMachineAction *, InteractionEvent *)
static Pointer New()
Constants for most interaction classes, due to the generic StateMachines.
virtual void ScaleRadius(StateMachineAction *, InteractionEvent *interactionEvent)
virtual void DeselectObject(StateMachineAction *, InteractionEvent *)
Called if the mouse pointer leaves the area of the object.
virtual void SelectObject(StateMachineAction *, InteractionEvent *)
Called if the mouse pointer is over the object indicated by a color change.
superclass of all bounding objects (cylinder, cuboid,...)
virtual mitk::RenderingManager * GetRenderingManager() const
Setter for the RenderingManager that handles this instance of BaseRenderer.
virtual void TranslateObject(StateMachineAction *, InteractionEvent *)
Performs a translation of the object relative to the mouse movement.
static RenderingManager * GetInstance()
Represents an action, that is executed after a certain event (in statemachine-mechanism) TODO: implem...
virtual MapperSlotId GetMapperID()
Get the MapperSlotId to use.
virtual void DeselectObject(StateMachineAction *, InteractionEvent *)
virtual bool CheckOverObject(const InteractionEvent *interactionEvent)
virtual void RotateObject(StateMachineAction *, InteractionEvent *interactionEvent)
#define CONNECT_CONDITION(a, f)
virtual void InitDeformation(StateMachineAction *, InteractionEvent *)
The ScaleOperation is an operation to scale any mitk::BaseGeometry.
virtual void SelectObject(StateMachineAction *, InteractionEvent *)
#define CONNECT_FUNCTION(a, f)
vtkRenderer * GetVtkRenderer() const
mitk::BaseGeometry * GetGeometry(int t=0) const
Return the geometry, which is a TimeGeometry, of the data as non-const pointer.
Definition: mitkBaseData.h:129
Operation, that holds everything necessary for an rotation operation on mitk::BaseData.
void RequestUpdateAll(RequestType type=REQUEST_UPDATE_ALL)
virtual void TranslateObject(StateMachineAction *, InteractionEvent *interactionEvent)
void WorldToIndex(const mitk::Point3D &pt_mm, mitk::Point3D &pt_units) const
Convert world coordinates (in mm) of a point to (continuous!) index coordinates.