Medical Imaging Interaction Toolkit  2018.4.99-3e3f1a6e
Medical Imaging Interaction Toolkit
QmitkInteractiveTransformationWidget.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 (DKFZ)
6 All rights reserved.
7 
8 Use of this source code is governed by a 3-clause BSD license that can be
9 found in the LICENSE file.
10 
11 ============================================================================*/
12 
14 
15 // mitk includes
16 #include "mitkRenderingManager.h"
17 #include "mitkBaseRenderer.h"
18 #include "mitkNavigationData.h"
19 
20 // vtk includes
21 #include "vtkMatrix4x4.h"
22 #include "vtkLinearTransform.h"
23 
24 const std::string QmitkInteractiveTransformationWidget::VIEW_ID = "org.mitk.views.interactivetransformationwidget";
25 
27  : QDialog(parent, f), m_Controls(nullptr), m_Geometry(nullptr)
28 {
29  CreateQtPartControl(this);
31 
33 
34 
35  this->setWindowTitle("Edit Tool Tip and Tool Orientation");
36 }
37 
39 {
40 }
41 
43 {
44  if (!m_Controls)
45  {
46  // create GUI widgets
47  m_Controls = new Ui::QmitkInteractiveTransformationWidgetControls;
48  m_Controls->setupUi(parent);
49  }
50 }
51 
53 {
54  if (m_Controls)
55  {
56  // translations
57  connect(m_Controls->m_XTransSpinBox, static_cast<void(QDoubleSpinBox::*)(double)>(&QDoubleSpinBox::valueChanged), this, &QmitkInteractiveTransformationWidget::OnXTranslationValueChanged);
58  connect(m_Controls->m_XTransSlider, &QSlider::valueChanged, this, &QmitkInteractiveTransformationWidget::OnXTranslationValueChanged);
59 
60  connect(m_Controls->m_YTransSpinBox, static_cast<void(QDoubleSpinBox::*)(double)>(&QDoubleSpinBox::valueChanged), this, &QmitkInteractiveTransformationWidget::OnYTranslationValueChanged);
61  connect(m_Controls->m_YTransSlider, &QSlider::valueChanged, this, &QmitkInteractiveTransformationWidget::OnYTranslationValueChanged);
62 
63  connect(m_Controls->m_ZTransSpinBox, static_cast<void(QDoubleSpinBox::*)(double)>(&QDoubleSpinBox::valueChanged), this, &QmitkInteractiveTransformationWidget::OnZTranslationValueChanged);
64  connect(m_Controls->m_ZTransSlider, &QSlider::valueChanged, this, &QmitkInteractiveTransformationWidget::OnZTranslationValueChanged);
65 
66  // rotations
67  connect(m_Controls->m_XRotSpinBox, static_cast<void(QDoubleSpinBox::*)(double)>(&QDoubleSpinBox::valueChanged), this, &QmitkInteractiveTransformationWidget::OnXRotationValueChanged);
68  connect(m_Controls->m_XRotSlider, &QSlider::valueChanged, this, &QmitkInteractiveTransformationWidget::OnXRotationValueChanged);
69 
70  connect(m_Controls->m_YRotSpinBox, static_cast<void(QDoubleSpinBox::*)(double)>(&QDoubleSpinBox::valueChanged), this, &QmitkInteractiveTransformationWidget::OnYRotationValueChanged);
71  connect(m_Controls->m_YRotSlider, &QSlider::valueChanged, this, &QmitkInteractiveTransformationWidget::OnYRotationValueChanged);
72 
73  connect(m_Controls->m_ZRotSpinBox, static_cast<void(QDoubleSpinBox::*)(double)>(&QDoubleSpinBox::valueChanged), this, &QmitkInteractiveTransformationWidget::OnZRotationValueChanged);
74  connect(m_Controls->m_ZRotSlider, &QSlider::valueChanged, this, &QmitkInteractiveTransformationWidget::OnZRotationValueChanged);
75 
76  connect((QObject*)(m_Controls->m_ResetPB), SIGNAL(clicked()), this, SLOT(OnResetGeometryToIdentity()));
77  connect((QObject*)(m_Controls->m_RevertChanges), SIGNAL(clicked()), this, SLOT(OnRevertChanges()));
78  connect((QObject*)(m_Controls->m_UseManipulatedToolTipPB), SIGNAL(clicked()), this, SLOT(OnApplyManipulatedToolTip()));
79  connect((QObject*)(m_Controls->m_Cancel), SIGNAL(clicked()), this, SLOT(OnCancel()));
80  }
81 }
82 
83 void QmitkInteractiveTransformationWidget::SetToolToEdit(const mitk::NavigationTool::Pointer _tool)
84 {
85  //If there is already a tool, remove it's node first.
86  if (m_ToolToEdit)
88  ->Remove(m_ToolToEdit->GetDataNode());
89 
90  m_ToolToEdit = _tool->Clone();
92  ->Add(m_ToolToEdit->GetDataNode());
93  m_ToolToEdit->GetDataNode()->SetName("Tool Tip to be edited");
94 
95  //change color to red
96  m_ToolToEdit->GetDataNode()->SetProperty("color", mitk::ColorProperty::New(1, 0, 0));
97 
98  //use the set-function via vtk matrix, 'cause this guarantees a deep copy and not just sharing a pointer.
99  m_Geometry = m_ToolToEdit->GetDataNode()->GetData()->GetGeometry();
100  m_ResetGeometry->SetIndexToWorldTransformByVtkMatrix(m_Geometry->GetVtkMatrix()); //Remember the original values to be able to reset and abort everything
101 }
102 
104 {
105  m_Geometry->SetOrigin(_defaultValues);
106  m_ResetGeometry->SetOrigin(_defaultValues); //Remember the original values to be able to reset and abort everything
107  SetValuesToGUI(m_Geometry->GetIndexToWorldTransform());
108 }
109 
111 {
112  // Conversion to navigation data / transform
113  mitk::NavigationData::Pointer rotationTransform = mitk::NavigationData::New(m_Geometry->GetIndexToWorldTransform());
114  rotationTransform->SetOrientation(_defaultValues);
115  m_Geometry->SetIndexToWorldTransform(rotationTransform->GetAffineTransform3D());
116 
117  //For ResetGeometry, use the set-function via vtk matrix, 'cause this guarantees a deep copy and not just sharing a pointer.
118  m_ResetGeometry->SetIndexToWorldTransformByVtkMatrix(m_Geometry->GetVtkMatrix()); //Remember the original values to be able to reset and abort everything
119  SetValuesToGUI(m_Geometry->GetIndexToWorldTransform());
120 }
121 
122 void QmitkInteractiveTransformationWidget::SetValuesToGUI(const mitk::AffineTransform3D::Pointer _defaultValues)
123 {
124 
125  //Set toolTip values in gui
126  m_Controls->m_XTransSlider->setValue(_defaultValues->GetOffset()[0]);
127  m_Controls->m_YTransSlider->setValue(_defaultValues->GetOffset()[1]);
128  m_Controls->m_ZTransSlider->setValue(_defaultValues->GetOffset()[2]);
129 
130  //first: some conversion
131  mitk::NavigationData::Pointer transformConversionHelper = mitk::NavigationData::New(_defaultValues);
132  double eulerAlphaDegrees = transformConversionHelper->GetOrientation().rotation_euler_angles()[0] / vnl_math::pi * 180;
133  double eulerBetaDegrees = transformConversionHelper->GetOrientation().rotation_euler_angles()[1] / vnl_math::pi * 180;
134  double eulerGammaDegrees = transformConversionHelper->GetOrientation().rotation_euler_angles()[2] / vnl_math::pi * 180;
135 
136  m_Controls->m_XRotSpinBox->setValue(eulerAlphaDegrees);
137  m_Controls->m_YRotSpinBox->setValue(eulerBetaDegrees);
138  m_Controls->m_ZRotSpinBox->setValue(eulerGammaDegrees);
139 
140  //Update view
142 }
143 
144 void QmitkInteractiveTransformationWidget::SetSynchronizedValuesToSliderAndSpinbox(QDoubleSpinBox* _spinbox, QSlider* _slider, double _value)
145 {
146 //block signals to avoid loop between slider and spinbox. Unblock at the end of the function!
147  _spinbox->blockSignals(true);
148  _slider->blockSignals(true);
149  _spinbox->setValue(_value);
150  _slider->setValue(_value);
151 //unblock signals. See above, don't remove this line. Unblock at the end of the function!
152  _spinbox->blockSignals(false);//
153  _slider->blockSignals(false);//
154 }
155 
157 {
158  //Set values to member variable
159  mitk::Point3D translationParams = m_Geometry->GetOrigin();
160  translationParams[0] = v;
161  m_Geometry->SetOrigin(translationParams);
162 
163  SetSynchronizedValuesToSliderAndSpinbox(m_Controls->m_XTransSpinBox, m_Controls->m_XTransSlider, v);
164 
165  //Update view
167 
168 }
169 
171 {
172  //Set values to member variable
173  mitk::Point3D translationParams = m_Geometry->GetOrigin();
174  translationParams[1] = v;
175  m_Geometry->SetOrigin(translationParams);
176 
177  SetSynchronizedValuesToSliderAndSpinbox(m_Controls->m_YTransSpinBox, m_Controls->m_YTransSlider, v);
178 
179  //Update view
181 }
182 
184 {
185  //Set values to member variable
186  mitk::Point3D translationParams = m_Geometry->GetOrigin();
187  translationParams[2] = v;
188  m_Geometry->SetOrigin(translationParams);
189 
190  SetSynchronizedValuesToSliderAndSpinbox(m_Controls->m_ZTransSpinBox, m_Controls->m_ZTransSlider, v);
191 
192  //Update view
194 }
195 
197 {
198  mitk::Vector3D rotationParams;
199  rotationParams[0] = v;
200  rotationParams[1] = m_Controls->m_YRotSpinBox->value();
201  rotationParams[2] = m_Controls->m_ZRotSpinBox->value();
202 
203  SetSynchronizedValuesToSliderAndSpinbox(m_Controls->m_XRotSpinBox, m_Controls->m_XRotSlider, v);
204 
205  this->Rotate(rotationParams);
206 }
207 
209 {
210  mitk::Vector3D rotationParams;
211  rotationParams[0] = m_Controls->m_XRotSpinBox->value();
212  rotationParams[1] = v;
213  rotationParams[2] = m_Controls->m_ZRotSpinBox->value();
214 
215  SetSynchronizedValuesToSliderAndSpinbox(m_Controls->m_YRotSpinBox, m_Controls->m_YRotSlider, v);
216 
217  this->Rotate(rotationParams);
218 }
219 
221 {
222  mitk::Vector3D rotationParams;
223  rotationParams[0] = m_Controls->m_XRotSpinBox->value();
224  rotationParams[1] = m_Controls->m_YRotSpinBox->value();
225  rotationParams[2] = v;
226 
227  SetSynchronizedValuesToSliderAndSpinbox(m_Controls->m_ZRotSpinBox, m_Controls->m_ZRotSlider, v);
228 
229  this->Rotate(rotationParams);
230 }
231 
233 {
234  //0: from degrees to radians
235  double radianX = rotateVector[0] * vnl_math::pi / 180;
236  double radianY = rotateVector[1] * vnl_math::pi / 180;
237  double radianZ = rotateVector[2] * vnl_math::pi / 180;
238 
239  //1: from euler angles to quaternion
240  mitk::Quaternion rotation(radianX, radianY, radianZ);
241 
242  //2: Conversion to navigation data / transform
243  mitk::NavigationData::Pointer rotationTransform = mitk::NavigationData::New(m_Geometry->GetIndexToWorldTransform());
244  rotationTransform->SetOrientation(rotation);
245 
246  m_Geometry->SetIndexToWorldTransform(rotationTransform->GetAffineTransform3D());
247 
249 }
250 
252 {
253  // reset the input to its initial state.
254  m_Geometry->SetIdentity();
255 
256  //Update Sliders
257  this->SetValuesToGUI(m_Geometry->GetIndexToWorldTransform());
258  //Refresh view
260 }
261 
263 {
264  // reset the input to its initial state.
265  m_Geometry->SetIndexToWorldTransformByVtkMatrix(m_ResetGeometry->GetVtkMatrix());
266 
267  //Update Sliders
268  this->SetValuesToGUI(m_Geometry->GetIndexToWorldTransform());
269  //Refresh view
271 }
272 
274 {
276  ->Remove(m_ToolToEdit->GetDataNode());
277 
278  mitk::AffineTransform3D::Pointer toolTip = m_Geometry->GetIndexToWorldTransform();
279  emit EditToolTipFinished(toolTip);
280  this->close();
281 }
282 
284 {
285  OnCancel();
286 }
287 
289 {
290  QDialog::reject();
291 
293  ->Remove(m_ToolToEdit->GetDataNode());
294 
295  emit EditToolTipFinished(nullptr);
296 }
static Pointer New()
void EditToolTipFinished(mitk::AffineTransform3D::Pointer toolTip)
static BaseRenderer * GetInstance(vtkRenderWindow *renWin)
static vtkRenderWindow * GetRenderWindowByName(const std::string &name)
void SetDefaultOffset(const mitk::Point3D _defaultValues)
static Pointer New()
mitk::BaseGeometry::Pointer m_Geometry
The geometry that is manipulated.
void SetDefaultRotation(const mitk::Quaternion _defaultValues)
static Pointer New()
static Matrix3D rotation
mitk::NavigationTool::Pointer m_ToolToEdit
this member holds a copy of the tool that should be edited for visualization
void Rotate(mitk::Vector3D rotateVector)
Method performs the rotation. rotateVector New rotation to be combined with geometry.
QmitkInteractiveTransformationWidget(QWidget *parent=nullptr, Qt::WindowFlags f=nullptr)
static RenderingManager * GetInstance()
void SetToolToEdit(const mitk::NavigationTool::Pointer _tool)
vnl_quaternion< ScalarType > Quaternion
mitk::BaseGeometry::Pointer m_ResetGeometry
Lifeline to reset to the original geometry.
Ui::QmitkInteractiveTransformationWidgetControls * m_Controls
virtual DataStorage::Pointer GetDataStorage() const
void RequestUpdateAll(RequestType type=REQUEST_UPDATE_ALL)