Medical Imaging Interaction Toolkit  2018.4.99-1bab67a2
Medical Imaging Interaction Toolkit
QmitkRegistrationManipulationWidget.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 
13 //Qmitk
15 
16 //MatchPoint
17 #include <mapRegistrationManipulator.h>
18 #include <mapPreCachedRegistrationKernel.h>
19 #include <mapCombinedRegistrationKernel.h>
20 #include <mapNullRegistrationKernel.h>
21 #include <mapRegistrationCombinator.h>
22 
23 #include <itkCompositeTransform.h>
24 
25 #include <boost/math/constants/constants.hpp>
26 
28  : QWidget(parent), m_CenterOfRotationIsRelativeToTarget(false), m_internalUpdate(false)
29 {
30  this->setupUi(this);
31 
32  connect(this->slideRotX, SIGNAL(valueChanged(int)), this, SLOT(OnRotXSlideChanged(int)));
33  connect(this->sbRotX, SIGNAL(valueChanged(double)), this, SLOT(OnRotXChanged(double)));
34  connect(this->slideRotY, SIGNAL(valueChanged(int)), this, SLOT(OnRotYSlideChanged(int)));
35  connect(this->sbRotY, SIGNAL(valueChanged(double)), this, SLOT(OnRotYChanged(double)));
36  connect(this->slideRotZ, SIGNAL(valueChanged(int)), this, SLOT(OnRotZSlideChanged(int)));
37  connect(this->sbRotZ, SIGNAL(valueChanged(double)), this, SLOT(OnRotZChanged(double)));
38 
39  connect(this->slideTransX, SIGNAL(valueChanged(int)), this, SLOT(OnTransXSlideChanged(int)));
40  connect(this->sbTransX, SIGNAL(valueChanged(double)), this, SLOT(OnTransXChanged(double)));
41  connect(this->slideTransY, SIGNAL(valueChanged(int)), this, SLOT(OnTransYSlideChanged(int)));
42  connect(this->sbTransY, SIGNAL(valueChanged(double)), this, SLOT(OnTransYChanged(double)));
43  connect(this->slideTransZ, SIGNAL(valueChanged(int)), this, SLOT(OnTransZSlideChanged(int)));
44  connect(this->sbTransZ, SIGNAL(valueChanged(double)), this, SLOT(OnTransZChanged(double)));
45 
46  this->groupScale->setVisible(false);
47 }
48 
50 = default;
51 
53 {
54  this->ResetTransforms();
55  this->InitControls();
56 };
57 
59 {
60  this->ResetTransforms();
61  this->m_PreRegistration = precedingRegistration;
62 
63  ::map::core::RegistrationManipulator<MAPRegistrationType> manipulator(m_CurrentRegistration);
64  ::map::core::PreCachedRegistrationKernel<3, 3>::Pointer kernel = ::map::core::PreCachedRegistrationKernel<3, 3>::New();
65 
66  const map::core::RegistrationKernel<3, 3>* preKernel = dynamic_cast<const map::core::RegistrationKernel<3, 3>*>(&this->m_PreRegistration->getInverseMapping());
67  itk::CompositeTransform < ::map::core::continuous::ScalarType, 3>::Pointer compTransform = itk::CompositeTransform < ::map::core::continuous::ScalarType, 3>::New();
68  compTransform->AddTransform(preKernel->getTransformModel()->Clone());
69  compTransform->AddTransform(this->m_InverseCurrentTransform);
70 
71  kernel->setTransformModel(compTransform);
72  manipulator.setInverseMapping(kernel);
73 
74  this->InitControls();
75 };
76 
77 void QmitkRegistrationManipulationWidget::Initialize(const mitk::Point3D& movingReference, const mitk::Point3D& targetReference)
78 {
79  this->ResetTransforms();
80 
81  auto offset = targetReference - movingReference;
82  m_DirectCurrentTransform->SetOffset(offset);
83  m_DirectCurrentTransform->GetInverse(m_InverseCurrentTransform);
84 
85  this->InitControls();
86 };
87 
88 void QmitkRegistrationManipulationWidget::ResetTransforms()
89 {
90  this->m_CenterOfRotation.Fill(0.0);
91  this->m_PreRegistration = nullptr;
92 
93 
94  this->m_InverseCurrentTransform = TransformType::New();
95  this->m_InverseCurrentTransform->SetIdentity();
96  this->m_DirectCurrentTransform = TransformType::New();
97  this->m_DirectCurrentTransform->SetIdentity();
98 
99  m_CurrentRegistration = MAPRegistrationType::New();
100 
101  ::map::core::RegistrationManipulator<MAPRegistrationType> manipulator(m_CurrentRegistration);
102  ::map::core::PreCachedRegistrationKernel<3, 3>::Pointer kernel = ::map::core::PreCachedRegistrationKernel<3, 3>::New();
103  kernel->setTransformModel(m_InverseCurrentTransform);
104  manipulator.setInverseMapping(kernel);
105 
106  manipulator.setDirectMapping(::map::core::NullRegistrationKernel < 3, 3 >::New());
107 };
108 
110 {
111  this->m_CenterOfRotation = center;
112  this->ConfigureTransformCenter();
113  this->UpdateTransformWidgets();
114 };
115 
118 {
119  this->m_CenterOfRotationIsRelativeToTarget = targetRelative;
120  this->ConfigureTransformCenter();
121  this->UpdateTransformWidgets();
122 };
123 
124 void QmitkRegistrationManipulationWidget::InitControls()
125 {
126  this->ConfigureTransformCenter();
127 
128  //set bounds of the translation slider widget to have sensible ranges
129  this->m_internalUpdate = true;
130  auto currenttrans = m_DirectCurrentTransform->GetTranslation();
131  this->slideTransX->setMinimum(currenttrans[0] - 250);
132  this->slideTransY->setMinimum(currenttrans[1] - 250);
133  this->slideTransZ->setMinimum(currenttrans[2] - 250);
134  this->slideTransX->setMaximum(currenttrans[0] + 250);
135  this->slideTransY->setMaximum(currenttrans[1] + 250);
136  this->slideTransZ->setMaximum(currenttrans[2] + 250);
137  this->m_internalUpdate = false;
138 
139  this->UpdateTransformWidgets();
140 };
141 
142 void QmitkRegistrationManipulationWidget::UpdateTransformWidgets()
143 {
144  this->m_internalUpdate = true;
145  this->sbTransX->setValue(this->m_DirectCurrentTransform->GetTranslation()[0]);
146  this->sbTransY->setValue(this->m_DirectCurrentTransform->GetTranslation()[1]);
147  this->sbTransZ->setValue(this->m_DirectCurrentTransform->GetTranslation()[2]);
148  this->slideTransX->setValue(this->m_DirectCurrentTransform->GetTranslation()[0]);
149  this->slideTransY->setValue(this->m_DirectCurrentTransform->GetTranslation()[1]);
150  this->slideTransZ->setValue(this->m_DirectCurrentTransform->GetTranslation()[2]);
151 
152  this->sbRotX->setValue(this->m_DirectCurrentTransform->GetAngleX()*(180 / boost::math::double_constants::pi));
153  this->sbRotY->setValue(this->m_DirectCurrentTransform->GetAngleY()*(180 / boost::math::double_constants::pi));
154  this->sbRotZ->setValue(this->m_DirectCurrentTransform->GetAngleZ()*(180 / boost::math::double_constants::pi));
155  this->slideRotX->setValue(this->m_DirectCurrentTransform->GetAngleX()*(180 / boost::math::double_constants::pi));
156  this->slideRotY->setValue(this->m_DirectCurrentTransform->GetAngleY()*(180 / boost::math::double_constants::pi));
157  this->slideRotZ->setValue(this->m_DirectCurrentTransform->GetAngleZ()*(180 / boost::math::double_constants::pi));
158  this->m_internalUpdate = false;
159 };
160 
161 void QmitkRegistrationManipulationWidget::UpdateTransform(bool updateRotation)
162 {
163  if (updateRotation)
164  {
165  if (this->m_CenterOfRotationIsRelativeToTarget)
166  {
167  ConfigureTransformCenter();
168  }
169 
170  this->m_DirectCurrentTransform->SetRotation(this->sbRotX->value()*(boost::math::double_constants::pi / 180),
171  this->sbRotY->value()*(boost::math::double_constants::pi / 180),
172  this->sbRotZ->value()*(boost::math::double_constants::pi / 180));
173  }
174  else
175  {
176  TransformType::OutputVectorType trans;
177  trans[0] = this->sbTransX->value();
178  trans[1] = this->sbTransY->value();
179  trans[2] = this->sbTransZ->value();
180 
181  this->m_DirectCurrentTransform->SetTranslation(trans);
182  }
183 
184  this->m_DirectCurrentTransform->GetInverse(this->m_InverseCurrentTransform);
185 
186  this->UpdateTransformWidgets();
187 
188  emit RegistrationChanged(this->m_CurrentRegistration);
189 };
190 
192 {
193  return this->m_CurrentRegistration.GetPointer();
194 };
195 
196 map::core::RegistrationBase::Pointer QmitkRegistrationManipulationWidget::GenerateRegistration() const
197 {
198  MAPRegistrationType::Pointer newReg = MAPRegistrationType::New();
199 
200  ::map::core::RegistrationManipulator<MAPRegistrationType> manipulator(newReg);
201 
202  ::map::core::PreCachedRegistrationKernel<3, 3>::Pointer kernel = ::map::core::PreCachedRegistrationKernel<3, 3>::New();
203  kernel->setTransformModel(m_InverseCurrentTransform);
204 
205  ::map::core::PreCachedRegistrationKernel<3, 3>::Pointer kernel2 = ::map::core::PreCachedRegistrationKernel<3, 3>::New();
206  kernel2->setTransformModel(m_InverseCurrentTransform->GetInverseTransform());
207 
208  manipulator.setInverseMapping(kernel);
209  manipulator.setDirectMapping(kernel2);
210 
211  if (this->m_PreRegistration.IsNotNull())
212  { //compine registration with selected pre registration as baseline
213  typedef ::map::core::RegistrationCombinator<MAPRegistrationType, MAPRegistrationType> CombinatorType;
214  CombinatorType::Pointer combinator = CombinatorType::New();
215  newReg = combinator->process(*m_PreRegistration, *newReg);
216  }
217 
218  return newReg.GetPointer();
219 };
220 
222 {
223  if (!m_internalUpdate)
224  {
225  m_internalUpdate = true;
226  this->slideRotX->setValue(x);
227  m_internalUpdate = false;
228  this->UpdateTransform(true);
229  }
230 };
231 
233 {
234  if (!m_internalUpdate)
235  {
236  this->sbRotX->setValue(x);
237  }
238 };
239 
241 {
242  if (!m_internalUpdate)
243  {
244  m_internalUpdate = true;
245  this->slideRotY->setValue(y);
246  m_internalUpdate = false;
247  this->UpdateTransform(true);
248  }
249 };
250 
252 {
253  if (!m_internalUpdate)
254  {
255  this->sbRotY->setValue(y);
256  }
257 };
258 
260 {
261  if (!m_internalUpdate)
262  {
263  m_internalUpdate = true;
264  this->slideRotZ->setValue(z);
265  m_internalUpdate = false;
266  this->UpdateTransform(true);
267  }
268 };
269 
271 {
272  if (!m_internalUpdate)
273  {
274  this->sbRotZ->setValue(z);
275  }
276 };
277 
279 {
280  if (!m_internalUpdate)
281  {
282  m_internalUpdate = true;
283  this->slideTransX->setValue(x);
284  m_internalUpdate = false;
285  this->UpdateTransform();
286  }
287 };
288 
290 {
291  if (!m_internalUpdate)
292  {
293  this->sbTransX->setValue(x);
294  }
295 };
296 
298 {
299  if (!m_internalUpdate)
300  {
301  m_internalUpdate = true;
302  this->slideTransY->setValue(y);
303  m_internalUpdate = false;
304  this->UpdateTransform();
305  }
306 };
307 
309 {
310  if (!m_internalUpdate)
311  {
312  this->sbTransY->setValue(y);
313  }
314 };
315 
317 {
318  if (!m_internalUpdate)
319  {
320  m_internalUpdate = true;
321  this->slideTransZ->setValue(z);
322  m_internalUpdate = false;
323  this->UpdateTransform();
324  }
325 };
326 
328 {
329  if (!m_internalUpdate)
330  {
331  this->sbTransZ->setValue(z);
332  }
333 };
334 
335 void QmitkRegistrationManipulationWidget::ConfigureTransformCenter()
336 {
337  auto offset = m_DirectCurrentTransform->GetOffset();
338 
339 
340  if (this->m_CenterOfRotationIsRelativeToTarget)
341  {
342  auto newCenter = m_InverseCurrentTransform->TransformPoint(m_CenterOfRotation);
343  m_DirectCurrentTransform->SetCenter(newCenter);
344  }
345  else
346  {
347  m_DirectCurrentTransform->SetCenter(m_CenterOfRotation);
348  }
349 
350  m_DirectCurrentTransform->SetOffset(offset);
351  m_DirectCurrentTransform->GetInverse(m_InverseCurrentTransform);
352 };
static Vector3D offset
map::core::RegistrationBase * GetInterimRegistration() const
void RegistrationChanged(map::core::RegistrationBase *registration)
map::core::RegistrationBase::Pointer GenerateRegistration() const