Medical Imaging Interaction Toolkit  2018.4.99-389bf124
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  auto currenttrans = m_DirectCurrentTransform->GetTranslation();
130  this->slideTransX->setMinimum(currenttrans[0] - 250);
131  this->slideTransY->setMinimum(currenttrans[1] - 250);
132  this->slideTransZ->setMinimum(currenttrans[2] - 250);
133  this->slideTransX->setMaximum(currenttrans[0] + 250);
134  this->slideTransY->setMaximum(currenttrans[1] + 250);
135  this->slideTransZ->setMaximum(currenttrans[2] + 250);
136 };
137 
138 void QmitkRegistrationManipulationWidget::UpdateTransformWidgets()
139 {
140  this->m_internalUpdate = true;
141  this->sbTransX->setValue(this->m_DirectCurrentTransform->GetTranslation()[0]);
142  this->sbTransY->setValue(this->m_DirectCurrentTransform->GetTranslation()[1]);
143  this->sbTransZ->setValue(this->m_DirectCurrentTransform->GetTranslation()[2]);
144  this->slideTransX->setValue(this->m_DirectCurrentTransform->GetTranslation()[0]);
145  this->slideTransY->setValue(this->m_DirectCurrentTransform->GetTranslation()[1]);
146  this->slideTransZ->setValue(this->m_DirectCurrentTransform->GetTranslation()[2]);
147 
148  this->sbRotX->setValue(this->m_DirectCurrentTransform->GetAngleX()*(180 / boost::math::double_constants::pi));
149  this->sbRotY->setValue(this->m_DirectCurrentTransform->GetAngleY()*(180 / boost::math::double_constants::pi));
150  this->sbRotZ->setValue(this->m_DirectCurrentTransform->GetAngleZ()*(180 / boost::math::double_constants::pi));
151  this->slideRotX->setValue(this->m_DirectCurrentTransform->GetAngleX()*(180 / boost::math::double_constants::pi));
152  this->slideRotY->setValue(this->m_DirectCurrentTransform->GetAngleY()*(180 / boost::math::double_constants::pi));
153  this->slideRotZ->setValue(this->m_DirectCurrentTransform->GetAngleZ()*(180 / boost::math::double_constants::pi));
154  this->m_internalUpdate = false;
155 };
156 
157 void QmitkRegistrationManipulationWidget::UpdateTransform(bool updateRotation)
158 {
159  if (updateRotation)
160  {
161  if (this->m_CenterOfRotationIsRelativeToTarget)
162  {
163  ConfigureTransformCenter();
164  }
165 
166  this->m_DirectCurrentTransform->SetRotation(this->sbRotX->value()*(boost::math::double_constants::pi / 180),
167  this->sbRotY->value()*(boost::math::double_constants::pi / 180),
168  this->sbRotZ->value()*(boost::math::double_constants::pi / 180));
169  }
170  else
171  {
172  TransformType::OutputVectorType trans;
173  trans[0] = this->sbTransX->value();
174  trans[1] = this->sbTransY->value();
175  trans[2] = this->sbTransZ->value();
176 
177  this->m_DirectCurrentTransform->SetTranslation(trans);
178  }
179 
180  this->m_DirectCurrentTransform->GetInverse(this->m_InverseCurrentTransform);
181 
182  this->UpdateTransformWidgets();
183 
184  emit RegistrationChanged(this->m_CurrentRegistration);
185 };
186 
188 {
189  return this->m_CurrentRegistration.GetPointer();
190 };
191 
192 map::core::RegistrationBase::Pointer QmitkRegistrationManipulationWidget::GenerateRegistration() const
193 {
194  MAPRegistrationType::Pointer newReg = MAPRegistrationType::New();
195 
196  ::map::core::RegistrationManipulator<MAPRegistrationType> manipulator(newReg);
197 
198  ::map::core::PreCachedRegistrationKernel<3, 3>::Pointer kernel = ::map::core::PreCachedRegistrationKernel<3, 3>::New();
199  kernel->setTransformModel(m_InverseCurrentTransform);
200 
201  ::map::core::PreCachedRegistrationKernel<3, 3>::Pointer kernel2 = ::map::core::PreCachedRegistrationKernel<3, 3>::New();
202  kernel2->setTransformModel(m_InverseCurrentTransform->GetInverseTransform());
203 
204  manipulator.setInverseMapping(kernel);
205  manipulator.setDirectMapping(kernel2);
206 
207  if (this->m_PreRegistration.IsNotNull())
208  { //compine registration with selected pre registration as baseline
209  typedef ::map::core::RegistrationCombinator<MAPRegistrationType, MAPRegistrationType> CombinatorType;
210  CombinatorType::Pointer combinator = CombinatorType::New();
211  newReg = combinator->process(*m_PreRegistration, *newReg);
212  }
213 
214  return newReg.GetPointer();
215 };
216 
218 {
219  if (!m_internalUpdate)
220  {
221  m_internalUpdate = true;
222  this->slideRotX->setValue(x);
223  m_internalUpdate = false;
224  this->UpdateTransform(true);
225  }
226 };
227 
229 {
230  if (!m_internalUpdate)
231  {
232  this->sbRotX->setValue(x);
233  }
234 };
235 
237 {
238  if (!m_internalUpdate)
239  {
240  m_internalUpdate = true;
241  this->slideRotY->setValue(y);
242  m_internalUpdate = false;
243  this->UpdateTransform(true);
244  }
245 };
246 
248 {
249  if (!m_internalUpdate)
250  {
251  this->sbRotY->setValue(y);
252  }
253 };
254 
256 {
257  if (!m_internalUpdate)
258  {
259  m_internalUpdate = true;
260  this->slideRotZ->setValue(z);
261  m_internalUpdate = false;
262  this->UpdateTransform(true);
263  }
264 };
265 
267 {
268  if (!m_internalUpdate)
269  {
270  this->sbRotZ->setValue(z);
271  }
272 };
273 
275 {
276  if (!m_internalUpdate)
277  {
278  m_internalUpdate = true;
279  this->slideTransX->setValue(x);
280  m_internalUpdate = false;
281  this->UpdateTransform();
282  }
283 };
284 
286 {
287  if (!m_internalUpdate)
288  {
289  this->sbTransX->setValue(x);
290  }
291 };
292 
294 {
295  if (!m_internalUpdate)
296  {
297  m_internalUpdate = true;
298  this->slideTransY->setValue(y);
299  m_internalUpdate = false;
300  this->UpdateTransform();
301  }
302 };
303 
305 {
306  if (!m_internalUpdate)
307  {
308  this->sbTransY->setValue(y);
309  }
310 };
311 
313 {
314  if (!m_internalUpdate)
315  {
316  m_internalUpdate = true;
317  this->slideTransZ->setValue(z);
318  m_internalUpdate = false;
319  this->UpdateTransform();
320  }
321 };
322 
324 {
325  if (!m_internalUpdate)
326  {
327  this->sbTransZ->setValue(z);
328  }
329 };
330 
331 void QmitkRegistrationManipulationWidget::ConfigureTransformCenter()
332 {
333  auto offset = m_DirectCurrentTransform->GetOffset();
334 
335 
336  if (this->m_CenterOfRotationIsRelativeToTarget)
337  {
338  auto newCenter = m_InverseCurrentTransform->TransformPoint(m_CenterOfRotation);
339  m_DirectCurrentTransform->SetCenter(newCenter);
340  }
341  else
342  {
343  m_DirectCurrentTransform->SetCenter(m_CenterOfRotation);
344  }
345 
346  m_DirectCurrentTransform->SetOffset(offset);
347  m_DirectCurrentTransform->GetInverse(m_InverseCurrentTransform);
348 };
static Vector3D offset
map::core::RegistrationBase * GetInterimRegistration() const
void RegistrationChanged(map::core::RegistrationBase *registration)
map::core::RegistrationBase::Pointer GenerateRegistration() const