Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
QmlMitkImageNavigator.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 
17 #include "QmlMitkImageNavigator.h"
18 
19 #include <QmlMitkStdMultiItem.h>
20 #include <QmitkStepperAdapter.h>
21 
23 
25 : m_AxialStepper(0)
26 , m_SagittalStepper(0)
27 , m_FrontalStepper(0)
28 , m_TimeStepper(0)
29 {
30  instance = this;
31 }
32 
34 {
35 }
36 
38 {
39  this->m_NavigatorAxial = item;
40 }
41 
43 {
44  this->m_NavigatorSagittal = item;
45 }
46 
48 {
49  this->m_NavigatorCoronal = item;
50 }
51 
53 {
54  this->m_NavigatorTime = item;
55 }
56 
58 {
59  return this->m_NavigatorAxial;
60 }
61 
63 {
64  return this->m_NavigatorSagittal;
65 }
66 
68 {
69  return this->m_NavigatorCoronal;
70 }
71 
73 {
74  return this->m_NavigatorTime;
75 }
76 
78 {
79  this->m_WorldCoordinateX = coordinate;
81 }
82 
84 {
85  this->m_WorldCoordinateY = coordinate;
87 }
88 
90 {
91  this->m_WorldCoordinateZ = coordinate;
93 }
94 
96 {
97  this->m_WorldCoordinateXMin = coordinate;
98 }
99 
101 {
102  this->m_WorldCoordinateYMin = coordinate;
103 }
104 
106 {
107  this->m_WorldCoordinateZMin = coordinate;
108 }
109 
111 {
112  this->m_WorldCoordinateXMax = coordinate;
113 }
114 
116 {
117  this->m_WorldCoordinateYMax = coordinate;
118 }
119 
121 {
122  this->m_WorldCoordinateZMax = coordinate;
123 }
124 
126 {
127  return this->m_WorldCoordinateX;
128 }
129 
131 {
132  return this->m_WorldCoordinateY;
133 }
134 
136 {
137  return this->m_WorldCoordinateZ;
138 }
139 
141 {
142  return this->m_WorldCoordinateXMin;
143 }
144 
146 {
147  return this->m_WorldCoordinateYMin;
148 }
149 
151 {
152  return this->m_WorldCoordinateZMin;
153 }
154 
156 {
157  return this->m_WorldCoordinateXMax;
158 }
159 
161 {
162  return this->m_WorldCoordinateYMax;
163 }
164 
166 {
167  return this->m_WorldCoordinateZMax;
168 }
169 
171 {
173  return;
174 
176 
177  if (renderWindow)
178  {
179  if (m_AxialStepper) m_AxialStepper->deleteLater();
180  m_AxialStepper = new QmitkStepperAdapter(this->m_NavigatorAxial,
181  renderWindow->GetSliceNavigationController()->GetSlice(),
182  "sliceNavigatorAxialFromSimpleExample");
183 
184  connect(m_AxialStepper, SIGNAL(Refetch()), this, SLOT(OnRefetch()));
185  }
186  else
187  {
188  this->m_NavigatorAxial->setEnabled(false);
189  }
190 
192  if (renderWindow)
193  {
194  if (m_SagittalStepper) m_SagittalStepper->deleteLater();
195  m_SagittalStepper = new QmitkStepperAdapter(this->m_NavigatorSagittal,
196  renderWindow->GetSliceNavigationController()->GetSlice(),
197  "sliceNavigatorSagittalFromSimpleExample");
198  connect(m_SagittalStepper, SIGNAL(Refetch()), this, SLOT(OnRefetch()));
199  }
200  else
201  {
202  this->m_NavigatorSagittal->setEnabled(false);
203  }
204 
206  if (renderWindow)
207  {
208  if (m_FrontalStepper) m_FrontalStepper->deleteLater();
209  m_FrontalStepper = new QmitkStepperAdapter(this->m_NavigatorCoronal,
210  renderWindow->GetSliceNavigationController()->GetSlice(),
211  "sliceNavigatorFrontalFromSimpleExample");
212  connect(m_FrontalStepper, SIGNAL(Refetch()), this, SLOT(OnRefetch()));
213  }
214  else
215  {
216  this->m_NavigatorCoronal->setEnabled(false);
217  }
218 
220  if (timeController)
221  {
222  if (m_TimeStepper) m_TimeStepper->deleteLater();
223  m_TimeStepper = new QmitkStepperAdapter(this->m_NavigatorTime,
224  timeController->GetTime(),
225  "sliceNavigatorTimeFromSimpleExample");
226  }
227  else
228  {
229  this->m_NavigatorTime->setEnabled(false);
230  }
231 }
232 
234 {
235  // cos(theta) = normal . axis
236  // cos(theta) = (a, b, c) . (d, e, f)
237  // cos(theta) = (a, b, c) . (1, 0, 0) = a
238  // cos(theta) = (a, b, c) . (0, 1, 0) = b
239  // cos(theta) = (a, b, c) . (0, 0, 1) = c
240  double absCosThetaWithAxis[3];
241 
242  for (int i = 0; i < 3; i++)
243  {
244  absCosThetaWithAxis[i] = fabs(normal[i]);
245  }
246  int largestIndex = 0;
247  double largestValue = absCosThetaWithAxis[0];
248  for (int i = 1; i < 3; i++)
249  {
250  if (absCosThetaWithAxis[i] > largestValue)
251  {
252  largestValue = absCosThetaWithAxis[i];
253  largestIndex = i;
254  }
255  }
256  return largestIndex;
257 }
258 
260 {
261  this->SetStepSize(0);
262  this->SetStepSize(1);
263  this->SetStepSize(2);
264 }
265 
267 {
269 
270  if (geometry.IsNotNull())
271  {
272  mitk::Point3D crossPositionInIndexCoordinates;
273  mitk::Point3D crossPositionInIndexCoordinatesPlus1;
274  mitk::Point3D crossPositionInMillimetresPlus1;
275  mitk::Vector3D transformedAxisDirection;
276 
277  mitk::Point3D crossPositionInMillimetres = QmlMitkStdMultiItem::instance->getCrossPosition();
278  geometry->WorldToIndex(crossPositionInMillimetres, crossPositionInIndexCoordinates);
279 
280  crossPositionInIndexCoordinatesPlus1 = crossPositionInIndexCoordinates;
281  crossPositionInIndexCoordinatesPlus1[axis] += 1;
282 
283  geometry->IndexToWorld(crossPositionInIndexCoordinatesPlus1, crossPositionInMillimetresPlus1);
284 
285  transformedAxisDirection = crossPositionInMillimetresPlus1 - crossPositionInMillimetres;
286 
287  int closestAxisInMillimetreSpace = this->GetClosestAxisIndex(transformedAxisDirection);
288  double stepSize = transformedAxisDirection.GetNorm();
289  this->SetStepSize(closestAxisInMillimetreSpace, stepSize);
290  }
291 }
292 
293 void QmlMitkImageNavigator::SetStepSize(int axis, double stepSize)
294 {
295  if (axis == 0)
296  {
297  //m_Controls.m_XWorldCoordinateSpinBox->setSingleStep(stepSize);
298  }
299  else if (axis == 1)
300  {
301  //m_Controls.m_YWorldCoordinateSpinBox->setSingleStep(stepSize);
302  }
303  else if (axis == 2)
304  {
305  //m_Controls.m_ZWorldCoordinateSpinBox->setSingleStep(stepSize);
306  }
307 }
308 
309 
311 {
313 
314  if (geometry.IsNotNull())
315  {
316  mitk::Point3D positionInWorldCoordinates;
317  positionInWorldCoordinates[0] = this->m_WorldCoordinateX;
318  positionInWorldCoordinates[1] = this->m_WorldCoordinateY;
319  positionInWorldCoordinates[2] = this->m_WorldCoordinateZ;
320 
321  QmlMitkStdMultiItem::instance->moveCrossToPosition(positionInWorldCoordinates);
322  }
323 }
324 
325 
327 {
330 
331  if (geometry.IsNull() && timeGeometry.IsNotNull())
332  {
334  geometry = timeGeometry->GetGeometryForTimeStep(timeStep);
335  }
336 
337  if (geometry.IsNotNull())
338  {
339  mitk::BoundingBox::BoundsArrayType bounds = geometry->GetBounds();
340 
341  mitk::Point3D cornerPoint1InIndexCoordinates;
342  cornerPoint1InIndexCoordinates[0] = bounds[0];
343  cornerPoint1InIndexCoordinates[1] = bounds[2];
344  cornerPoint1InIndexCoordinates[2] = bounds[4];
345 
346  mitk::Point3D cornerPoint2InIndexCoordinates;
347  cornerPoint2InIndexCoordinates[0] = bounds[1];
348  cornerPoint2InIndexCoordinates[1] = bounds[3];
349  cornerPoint2InIndexCoordinates[2] = bounds[5];
350 
351  if (!geometry->GetImageGeometry())
352  {
353  cornerPoint1InIndexCoordinates[0] += 0.5;
354  cornerPoint1InIndexCoordinates[1] += 0.5;
355  cornerPoint1InIndexCoordinates[2] += 0.5;
356  cornerPoint2InIndexCoordinates[0] -= 0.5;
357  cornerPoint2InIndexCoordinates[1] -= 0.5;
358  cornerPoint2InIndexCoordinates[2] -= 0.5;
359  }
360 
361  mitk::Point3D crossPositionInWorldCoordinates = QmlMitkStdMultiItem::instance->getCrossPosition();
362 
363  mitk::Point3D cornerPoint1InWorldCoordinates;
364  mitk::Point3D cornerPoint2InWorldCoordinates;
365 
366  geometry->IndexToWorld(cornerPoint1InIndexCoordinates, cornerPoint1InWorldCoordinates);
367  geometry->IndexToWorld(cornerPoint2InIndexCoordinates, cornerPoint2InWorldCoordinates);
368 
369  this->m_WorldCoordinateXMin = std::min(cornerPoint1InWorldCoordinates[0], cornerPoint2InWorldCoordinates[0]);
370  this->m_WorldCoordinateYMin = std::min(cornerPoint1InWorldCoordinates[1], cornerPoint2InWorldCoordinates[1]);
371  this->m_WorldCoordinateZMin = std::min(cornerPoint1InWorldCoordinates[2], cornerPoint2InWorldCoordinates[2]);
372 
373  this->m_WorldCoordinateXMax = std::max(cornerPoint1InWorldCoordinates[0], cornerPoint2InWorldCoordinates[0]);
374  this->m_WorldCoordinateYMax = std::max(cornerPoint1InWorldCoordinates[1], cornerPoint2InWorldCoordinates[1]);
375  this->m_WorldCoordinateZMax = std::max(cornerPoint1InWorldCoordinates[2], cornerPoint2InWorldCoordinates[2]);
376 
377  this->m_WorldCoordinateX = crossPositionInWorldCoordinates[0];
378  this->m_WorldCoordinateY = crossPositionInWorldCoordinates[1];
379  this->m_WorldCoordinateZ = crossPositionInWorldCoordinates[2];
380 
381  emit this->sync();
382  }
383 }
384 
385 void QmlMitkImageNavigator::create(QQmlEngine &engine)
386 {
388 
389  qmlRegisterType<QmlMitkImageNavigator>("Mitk.Views", 1, 0, "ImageNavigator");
390  QQmlComponent component(&engine, QUrl("qrc:/MitkImageNavigator.qml"));
391 }
QmlMitkRenderWindowItem * getViewerAxial()
mitk::Stepper * GetSlice()
Get the Stepper through the slices.
void setWorldCoordinateY(double coordinate)
QmitkStepperAdapter * m_AxialStepper
const SliceNavigationController * GetTimeNavigationController() const
void setWorldCoordinateZMax(double coordinate)
static QmlMitkImageNavigator * instance
QmlMitkRenderWindowItem * getViewerSagittal()
void setWorldCoordinateZ(double coordinate)
void setWorldCoordinateZMin(double coordinate)
Controls the selection of the slice the associated BaseRenderer will display.
QmlMitkSliderNavigatorItem * getNavigatorCoronal()
QmitkStepperAdapter * m_FrontalStepper
void moveCrossToPosition(const mitk::Point3D &newPosition)
void setNavigatorCoronal(QmlMitkSliderNavigatorItem *item)
const mitk::Point3D getCrossPosition() const
QmlMitkRenderWindowItem * getViewerCoronal()
Helper class to connect Qt-based navigators to instances of Stepper.
int GetClosestAxisIndex(mitk::Vector3D normal)
void setWorldCoordinateX(double coordinate)
void setWorldCoordinateXMax(double coordinate)
void sync()
GetDecorationColorOfGeometry helper method to get the color of a helper geometry node.
static RenderingManager * GetInstance()
QmitkStepperAdapter * m_TimeStepper
QmlMitkSliderNavigatorItem * getNavigatorTime()
virtual unsigned int GetPos() const
std::vcl_size_t TimeStepType
static T max(T x, T y)
Definition: svm.cpp:70
void setNavigatorTime(QmlMitkSliderNavigatorItem *item)
static QmlMitkStdMultiItem * instance
void setWorldCoordinateYMin(double coordinate)
static T min(T x, T y)
Definition: svm.cpp:67
void setWorldCoordinateYMax(double coordinate)
Provides a means to scan quickly through a dataset via Axial, Coronal and Sagittal sliders...
QmlMitkSliderNavigatorItem * getNavigatorSagittal()
virtual const mitk::BaseGeometry * GetInputWorldGeometry3D()
virtual mitk::SliceNavigationController * GetSliceNavigationController()
mitk::Stepper * GetTime()
Get the Stepper through the time.
QmlMitkSliderNavigatorItem * getNavigatorAxial()
static void create(QQmlEngine &engine)
void setWorldCoordinateXMin(double coordinate)
void setNavigatorSagittal(QmlMitkSliderNavigatorItem *item)
QmitkStepperAdapter * m_SagittalStepper
void setNavigatorAxial(QmlMitkSliderNavigatorItem *item)
BoundingBoxType::BoundsArrayType BoundsArrayType
virtual const mitk::TimeGeometry * GetInputWorldTimeGeometry()