Medical Imaging Interaction Toolkit  2018.4.99-ef453c4b
Medical Imaging Interaction Toolkit
QmitkSliceBasedInterpolatorWidget.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 #include <mitkColorProperty.h>
16 #include <mitkDiffSliceOperation.h>
18 #include <mitkExtractSliceFilter.h>
19 #include <mitkImageAccessByItk.h>
20 #include <mitkImageCast.h>
21 #include <mitkImageTimeSelector.h>
22 #include <mitkLabelSetImage.h>
23 #include <mitkOperationEvent.h>
24 #include <mitkProgressBar.h>
25 #include <mitkProperties.h>
26 #include <mitkRenderingManager.h>
27 #include <mitkSegTool2D.h>
29 #include <mitkToolManager.h>
31 #include <mitkUndoController.h>
32 #include <mitkVtkImageOverwrite.h>
33 
34 #include "QmitkStdMultiWidget.h"
35 
36 #include <itkCommand.h>
37 
38 #include <QApplication>
39 #include <QCursor>
40 #include <QMenu>
41 #include <QMessageBox>
42 
44  : QWidget(parent),
45  m_SliceInterpolatorController(mitk::SliceBasedInterpolationController::New()),
46  m_ToolManager(nullptr),
47  m_Activated(false),
48  m_DataStorage(nullptr),
49  m_LastSNC(nullptr),
50  m_LastSliceIndex(0)
51 {
52  m_Controls.setupUi(this);
53 
55  Q_ASSERT(m_ToolManager);
56 
59 
60  connect(m_Controls.m_btStart, SIGNAL(toggled(bool)), this, SLOT(OnToggleWidgetActivation(bool)));
61  connect(m_Controls.m_btApplyForCurrentSlice, SIGNAL(clicked()), this, SLOT(OnAcceptInterpolationClicked()));
62  connect(m_Controls.m_btApplyForAllSlices, SIGNAL(clicked()), this, SLOT(OnAcceptAllInterpolationsClicked()));
63 
64  itk::ReceptorMemberCommand<QmitkSliceBasedInterpolatorWidget>::Pointer command =
65  itk::ReceptorMemberCommand<QmitkSliceBasedInterpolatorWidget>::New();
66  command->SetCallbackFunction(this, &QmitkSliceBasedInterpolatorWidget::OnSliceInterpolationInfoChanged);
67  m_InterpolationInfoChangedObserverTag = m_SliceInterpolatorController->AddObserver(itk::ModifiedEvent(), command);
68 
69  // feedback node and its visualization properties
70  m_PreviewNode = mitk::DataNode::New();
71  m_PreviewNode->SetName("3D tool preview");
72 
73  m_PreviewNode->SetProperty("texture interpolation", mitk::BoolProperty::New(false));
74  m_PreviewNode->SetProperty("layer", mitk::IntProperty::New(100));
75  m_PreviewNode->SetProperty("binary", mitk::BoolProperty::New(true));
76  m_PreviewNode->SetProperty("outline binary", mitk::BoolProperty::New(true));
77  m_PreviewNode->SetProperty("outline binary shadow", mitk::BoolProperty::New(true));
78  m_PreviewNode->SetProperty("helper object", mitk::BoolProperty::New(true));
79  m_PreviewNode->SetOpacity(1.0);
80  m_PreviewNode->SetColor(0.0, 1.0, 0.0);
81 
82  m_Controls.m_btApplyForCurrentSlice->setEnabled(false);
83  m_Controls.m_btApplyForAllSlices->setEnabled(false);
84 
85  this->setEnabled(false);
86 }
87 
89 {
92 
93  foreach (mitk::SliceNavigationController *slicer, m_ControllerToSliceObserverTag.keys())
94  {
95  slicer->RemoveObserver(m_ControllerToDeleteObserverTag.take(slicer));
96  slicer->RemoveObserver(m_ControllerToTimeObserverTag.take(slicer));
97  slicer->RemoveObserver(m_ControllerToSliceObserverTag.take(slicer));
98  }
99 
101 
102  // remove observer
103  m_SliceInterpolatorController->RemoveObserver(m_InterpolationInfoChangedObserverTag);
104 }
105 
108 {
109  ActionToSliceDimensionMapType actionToSliceDimension;
110  foreach (mitk::SliceNavigationController *slicer, m_ControllerToDeleteObserverTag.keys())
111  {
112  std::string name = slicer->GetRenderer()->GetName();
113  if (name == "stdmulti.widget0")
114  name = "Axial (red window)";
115  else if (name == "stdmulti.widget1")
116  name = "Sagittal (green window)";
117  else if (name == "stdmulti.widget2")
118  name = "Coronal (blue window)";
119  actionToSliceDimension[new QAction(QString::fromStdString(name), nullptr)] = slicer;
120  }
121 
122  return actionToSliceDimension;
123 }
124 
126 {
127  m_DataStorage = &storage;
128 }
129 
131  const QList<mitk::SliceNavigationController *> &controllers)
132 {
133  Q_ASSERT(!controllers.empty());
134 
135  // connect to the slice navigation controller. after each change, call the interpolator
136  foreach (mitk::SliceNavigationController *slicer, controllers)
137  {
138  // Has to be initialized
139  m_LastSNC = slicer;
140 
141  m_TimeStep.insert(slicer, slicer->GetTime()->GetPos());
142 
143  itk::MemberCommand<QmitkSliceBasedInterpolatorWidget>::Pointer deleteCommand =
144  itk::MemberCommand<QmitkSliceBasedInterpolatorWidget>::New();
145  deleteCommand->SetCallbackFunction(this, &QmitkSliceBasedInterpolatorWidget::OnSliceNavigationControllerDeleted);
146  m_ControllerToDeleteObserverTag.insert(slicer, slicer->AddObserver(itk::DeleteEvent(), deleteCommand));
147 
148  itk::MemberCommand<QmitkSliceBasedInterpolatorWidget>::Pointer timeChangedCommand =
149  itk::MemberCommand<QmitkSliceBasedInterpolatorWidget>::New();
150  timeChangedCommand->SetCallbackFunction(this, &QmitkSliceBasedInterpolatorWidget::OnTimeChanged);
151  m_ControllerToTimeObserverTag.insert(
152  slicer,
153  slicer->AddObserver(mitk::SliceNavigationController::TimeGeometryEvent(nullptr, 0), timeChangedCommand));
154 
155  itk::MemberCommand<QmitkSliceBasedInterpolatorWidget>::Pointer sliceChangedCommand =
156  itk::MemberCommand<QmitkSliceBasedInterpolatorWidget>::New();
157  sliceChangedCommand->SetCallbackFunction(this, &QmitkSliceBasedInterpolatorWidget::OnSliceChanged);
158  m_ControllerToSliceObserverTag.insert(
159  slicer, slicer->AddObserver(mitk::SliceNavigationController::GeometrySliceEvent(nullptr, 0), sliceChangedCommand));
160  }
161 
163 }
164 
166 {
167  mitk::DataNode *workingNode = this->m_ToolManager->GetWorkingData(0);
168  if (!workingNode)
169  {
170  this->setEnabled(false);
171  return;
172  }
173 
174  mitk::LabelSetImage *workingImage = dynamic_cast<mitk::LabelSetImage *>(workingNode->GetData());
175  // TODO adapt tool manager so that this check is done there, e.g. convenience function
176  // Q_ASSERT(workingImage);
177  if (!workingImage)
178  {
179  this->setEnabled(false);
180  return;
181  }
182 
183  if (workingImage->GetDimension() > 4 || workingImage->GetDimension() < 3)
184  {
185  this->setEnabled(false);
186  return;
187  }
188 
189  m_WorkingImage = workingImage;
190 
191  this->setEnabled(true);
192 }
193 
194 void QmitkSliceBasedInterpolatorWidget::OnTimeChanged(itk::Object *sender, const itk::EventObject &e)
195 {
196  // Check if we really have a GeometryTimeEvent
197  if (!dynamic_cast<const mitk::SliceNavigationController::GeometryTimeEvent *>(&e))
198  return;
199 
200  mitk::SliceNavigationController *slicer = dynamic_cast<mitk::SliceNavigationController *>(sender);
201  Q_ASSERT(slicer);
202 
203  m_TimeStep[slicer] /* = event.GetPos()*/;
204 
205  // TODO Macht das hier wirklich Sinn????
206  if (m_LastSNC == slicer)
207  {
208  slicer->SendSlice(); // will trigger a new interpolation
209  }
210 }
211 
212 void QmitkSliceBasedInterpolatorWidget::OnSliceChanged(itk::Object *sender, const itk::EventObject &e)
213 {
214  if (m_Activated && m_WorkingImage.IsNotNull())
215  {
216  // Check whether we really have a GeometrySliceEvent
217  if (!dynamic_cast<const mitk::SliceNavigationController::GeometrySliceEvent *>(&e))
218  return;
219 
220  mitk::SliceNavigationController *slicer = dynamic_cast<mitk::SliceNavigationController *>(sender);
221  if (slicer)
222  {
223  this->TranslateAndInterpolateChangedSlice(e, slicer);
225  // slicer->GetRenderer()->RequestUpdate();
226  }
227  }
228 }
229 
232 {
233  if (m_Activated && m_WorkingImage.IsNotNull())
234  {
235  const mitk::SliceNavigationController::GeometrySliceEvent &geometrySliceEvent =
237  mitk::TimeGeometry *timeGeometry = geometrySliceEvent.GetTimeGeometry();
238  if (timeGeometry && m_TimeStep.contains(slicer))
239  {
240  mitk::SlicedGeometry3D *slicedGeometry =
241  dynamic_cast<mitk::SlicedGeometry3D *>(timeGeometry->GetGeometryForTimeStep(m_TimeStep[slicer]).GetPointer());
242  if (slicedGeometry)
243  {
244  mitk::PlaneGeometry *plane = slicedGeometry->GetPlaneGeometry(geometrySliceEvent.GetPos());
245  if (plane)
246  {
247  m_LastSNC = slicer;
248  this->Interpolate(plane, m_TimeStep[slicer], slicer);
249  }
250  }
251  }
252  }
253 }
254 
256  unsigned int timeStep,
258 {
259  int clickedSliceDimension(-1);
260  int clickedSliceIndex(-1);
261 
262  // calculate real slice position, i.e. slice of the image and not slice of the TimeSlicedGeometry
263  // see if timestep is needed here
264  mitk::SegTool2D::DetermineAffectedImageSlice(m_WorkingImage, plane, clickedSliceDimension, clickedSliceIndex);
265 
266  mitk::Image::Pointer interpolation =
267  m_SliceInterpolatorController->Interpolate(clickedSliceDimension, clickedSliceIndex, plane, timeStep);
268 
269  m_PreviewNode->SetData(interpolation);
270 
271  const mitk::Color &color = m_WorkingImage->GetActiveLabel()->GetColor();
272  m_PreviewNode->SetColor(color);
273 
274  m_LastSNC = slicer;
275  m_LastSliceIndex = clickedSliceIndex;
276 }
277 
279 {
280  unsigned int timeStep = m_LastSNC->GetTime()->GetPos();
281 
282  // Make sure that for reslicing and overwriting the same alogrithm is used. We can specify the mode of the vtk
283  // reslicer
284  vtkSmartPointer<mitkVtkImageOverwrite> reslice = vtkSmartPointer<mitkVtkImageOverwrite>::New();
285  // set to false to extract a slice
286  reslice->SetOverwriteMode(false);
287  reslice->Modified();
288 
289  // use ExtractSliceFilter with our specific vtkImageReslice for overwriting and extracting
291  extractor->SetInput(m_WorkingImage);
292  extractor->SetTimeStep(timeStep);
293  extractor->SetWorldGeometry(planeGeometry);
294  extractor->SetVtkOutputRequest(false);
295  extractor->SetResliceTransformByGeometry(m_WorkingImage->GetTimeGeometry()->GetGeometryForTimeStep(timeStep));
296 
297  extractor->Modified();
298 
299  try
300  {
301  extractor->Update();
302  }
303  catch (itk::ExceptionObject &excep)
304  {
305  MITK_ERROR << "Exception caught: " << excep.GetDescription();
306  return nullptr;
307  }
308 
309  mitk::Image::Pointer slice = extractor->GetOutput();
310 
311  // specify the undo operation with the non edited slice
312  // MLI TODO added code starts here
313  mitk::SlicedGeometry3D *sliceGeometry = dynamic_cast<mitk::SlicedGeometry3D *>(slice->GetGeometry());
314  // m_undoOperation = new mitk::DiffSliceOperation(m_WorkingImage, extractor->GetVtkOutput(), slice->GetGeometry(),
315  // timeStep, const_cast<mitk::PlaneGeometry*>(planeGeometry));
316  // added code ends here
317  m_undoOperation = new mitk::DiffSliceOperation(
318  m_WorkingImage, extractor->GetOutput(), sliceGeometry, timeStep, const_cast<mitk::PlaneGeometry *>(planeGeometry));
319 
320  slice->DisconnectPipeline();
321 
322  return slice;
323 }
324 
326 {
327  Q_ASSERT(m_ToolManager);
328 
329  mitk::DataNode *workingNode = m_ToolManager->GetWorkingData(0);
330  if (!workingNode)
331  return;
332 
333  m_Controls.m_btApplyForCurrentSlice->setEnabled(enabled);
334  m_Controls.m_btApplyForAllSlices->setEnabled(enabled);
335 
336  if (enabled)
337  m_Controls.m_btStart->setText("Stop");
338  else
339  m_Controls.m_btStart->setText("Start");
340 
341  unsigned int numberOfExistingTools = m_ToolManager->GetTools().size();
342  for (unsigned int i = 0; i < numberOfExistingTools; i++)
343  {
344  // mitk::SegTool2D* tool = dynamic_cast<mitk::SegTool2D*>(m_ToolManager->GetToolById(i));
345  // MLI TODO
346  // if (tool) tool->SetEnable2DInterpolation( enabled );
347  }
348 
349  if (enabled)
350  {
351  if (!m_DataStorage->Exists(m_PreviewNode))
352  {
353  m_DataStorage->Add(m_PreviewNode);
354  }
355 
356  m_SliceInterpolatorController->SetWorkingImage(m_WorkingImage);
357  this->UpdateVisibleSuggestion();
358  }
359  else
360  {
361  if (m_DataStorage->Exists(m_PreviewNode))
362  {
363  m_DataStorage->Remove(m_PreviewNode);
364  }
365 
367  }
368 
369  m_Activated = enabled;
370 
372 }
373 
374 template <typename TPixel, unsigned int VImageDimension>
375 void QmitkSliceBasedInterpolatorWidget::WritePreviewOnWorkingImage(itk::Image<TPixel, VImageDimension> *targetSlice,
376  const mitk::Image *sourceSlice,
377  int overwritevalue)
378 {
379  typedef itk::Image<TPixel, VImageDimension> ImageType;
380 
381  typename ImageType::Pointer sourceSliceITK;
382  mitk::CastToItkImage(sourceSlice, sourceSliceITK);
383 
384  // now the original slice and the ipSegmentation-painted slice are in the same format, and we can just copy all pixels
385  // that are non-zero
386  typedef itk::ImageRegionIterator<ImageType> OutputIteratorType;
387  typedef itk::ImageRegionConstIterator<ImageType> InputIteratorType;
388 
389  InputIteratorType inputIterator(sourceSliceITK, sourceSliceITK->GetLargestPossibleRegion());
390  OutputIteratorType outputIterator(targetSlice, targetSlice->GetLargestPossibleRegion());
391 
392  outputIterator.GoToBegin();
393  inputIterator.GoToBegin();
394 
395  int activePixelValue = m_WorkingImage->GetActiveLabel()->GetValue();
396 
397  if (activePixelValue == 0) // if exterior is the active label
398  {
399  while (!outputIterator.IsAtEnd())
400  {
401  if (inputIterator.Get() != 0)
402  {
403  outputIterator.Set(overwritevalue);
404  }
405  ++outputIterator;
406  ++inputIterator;
407  }
408  }
409  else if (overwritevalue != 0) // if we are not erasing
410  {
411  while (!outputIterator.IsAtEnd())
412  {
413  int targetValue = static_cast<int>(outputIterator.Get());
414  if (inputIterator.Get() != 0)
415  {
416  if (!m_WorkingImage->GetLabel(targetValue)->GetLocked())
417  outputIterator.Set(overwritevalue);
418  }
419 
420  ++outputIterator;
421  ++inputIterator;
422  }
423  }
424  else // if we are erasing
425  {
426  while (!outputIterator.IsAtEnd())
427  {
428  const int targetValue = outputIterator.Get();
429  if (inputIterator.Get() != 0)
430  {
431  if (targetValue == activePixelValue)
432  outputIterator.Set(overwritevalue);
433  }
434 
435  ++outputIterator;
436  ++inputIterator;
437  }
438  }
439 }
440 
442 {
443  if (m_WorkingImage.IsNotNull() && m_PreviewNode->GetData())
444  {
445  const mitk::PlaneGeometry *planeGeometry = m_LastSNC->GetCurrentPlaneGeometry();
446  if (!planeGeometry)
447  return;
448 
449  mitk::Image::Pointer sliceImage = this->GetWorkingSlice(planeGeometry);
450  if (sliceImage.IsNull())
451  return;
452 
453  mitk::Image::Pointer previewSlice = dynamic_cast<mitk::Image *>(m_PreviewNode->GetData());
454 
456  sliceImage, WritePreviewOnWorkingImage, 2, previewSlice, m_WorkingImage->GetActiveLabel()->GetValue());
457 
458  // Make sure that for reslicing and overwriting the same alogrithm is used. We can specify the mode of the vtk
459  // reslicer
460  vtkSmartPointer<mitkVtkImageOverwrite> overwrite = vtkSmartPointer<mitkVtkImageOverwrite>::New();
461  overwrite->SetInputSlice(sliceImage->GetVtkImageData());
462  // set overwrite mode to true to write back to the image volume
463  overwrite->SetOverwriteMode(true);
464  overwrite->Modified();
465 
466  unsigned int timeStep = m_LastSNC->GetTime()->GetPos();
467 
469  extractor->SetInput(m_WorkingImage);
470  extractor->SetTimeStep(timeStep);
471  extractor->SetWorldGeometry(planeGeometry);
472  extractor->SetVtkOutputRequest(false);
473  extractor->SetResliceTransformByGeometry(m_WorkingImage->GetTimeGeometry()->GetGeometryForTimeStep(timeStep));
474 
475  extractor->Modified();
476 
477  try
478  {
479  extractor->Update();
480  }
481  catch (itk::ExceptionObject &excep)
482  {
483  MITK_ERROR << "Exception caught: " << excep.GetDescription();
484  return;
485  }
486 
487  // the image was modified within the pipeline, but not marked so
488  m_WorkingImage->Modified();
489 
490  int clickedSliceDimension(-1);
491  int clickedSliceIndex(-1);
492 
494  m_WorkingImage, planeGeometry, clickedSliceDimension, clickedSliceIndex);
495 
496  m_SliceInterpolatorController->SetChangedSlice(sliceImage, clickedSliceDimension, clickedSliceIndex, timeStep);
497 
498  // specify the undo operation with the edited slice
499  // MLI TODO added code starts here
500  mitk::SlicedGeometry3D *sliceGeometry = dynamic_cast<mitk::SlicedGeometry3D *>(sliceImage->GetGeometry());
501  // m_undoOperation = new mitk::DiffSliceOperation(m_WorkingImage, extractor->GetVtkOutput(), slice->GetGeometry(),
502  // timeStep, const_cast<mitk::PlaneGeometry*>(planeGeometry));
503  // added code ends here
504  m_doOperation = new mitk::DiffSliceOperation(m_WorkingImage,
505  extractor->GetOutput(),
506  sliceGeometry,
507  timeStep,
508  const_cast<mitk::PlaneGeometry *>(planeGeometry));
509 
510  // create an operation event for the undo stack
511  mitk::OperationEvent *undoStackItem = new mitk::OperationEvent(
512  mitk::DiffSliceOperationApplier::GetInstance(), m_doOperation, m_undoOperation, "Slice Interpolation");
513 
514  // add it to the undo controller
516 
517  // clear the pointers as the operation are stored in the undo controller and also deleted from there
518  m_undoOperation = nullptr;
519  m_doOperation = nullptr;
520 
521  m_PreviewNode->SetData(nullptr);
522 
524  }
525 }
526 
528 {
529  // Since we need to shift the plane it must be clone so that the original plane isn't altered
530  mitk::PlaneGeometry::Pointer reslicePlane = slicer->GetCurrentPlaneGeometry()->Clone();
531  unsigned int timeStep = slicer->GetTime()->GetPos();
532 
533  int sliceDimension(-1);
534  int sliceIndex(-1);
535 
536  mitk::SegTool2D::DetermineAffectedImageSlice(m_WorkingImage, reslicePlane, sliceDimension, sliceIndex);
537 
538  unsigned int zslices = m_WorkingImage->GetDimension(sliceDimension);
539 
542 
543  mitk::Point3D origin = reslicePlane->GetOrigin();
544 
545  for (unsigned int idx = 0; idx < zslices; ++idx)
546  {
547  // Transforming the current origin of the reslice plane
548  // so that it matches the one of the next slice
549  m_WorkingImage->GetSlicedGeometry()->WorldToIndex(origin, origin);
550  origin[sliceDimension] = idx;
551  m_WorkingImage->GetSlicedGeometry()->IndexToWorld(origin, origin);
552  reslicePlane->SetOrigin(origin);
553 
554  mitk::Image::Pointer interpolation =
555  m_SliceInterpolatorController->Interpolate(sliceDimension, idx, reslicePlane, timeStep);
556 
557  if (interpolation.IsNotNull())
558  {
559  m_PreviewNode->SetData(interpolation);
560 
561  mitk::Image::Pointer sliceImage = this->GetWorkingSlice(reslicePlane);
562  if (sliceImage.IsNull())
563  return;
564 
566  sliceImage, WritePreviewOnWorkingImage, 2, interpolation, m_WorkingImage->GetActiveLabel()->GetValue());
567 
568  // Make sure that for reslicing and overwriting the same alogrithm is used. We can specify the mode of the vtk
569  // reslicer
570  vtkSmartPointer<mitkVtkImageOverwrite> overwrite = vtkSmartPointer<mitkVtkImageOverwrite>::New();
571  overwrite->SetInputSlice(sliceImage->GetVtkImageData());
572  // set overwrite mode to true to write back to the image volume
573  overwrite->SetOverwriteMode(true);
574  overwrite->Modified();
575 
577  extractor->SetInput(m_WorkingImage);
578  extractor->SetTimeStep(timeStep);
579  extractor->SetWorldGeometry(reslicePlane);
580  extractor->SetVtkOutputRequest(true);
581  extractor->SetResliceTransformByGeometry(m_WorkingImage->GetTimeGeometry()->GetGeometryForTimeStep(timeStep));
582 
583  extractor->Modified();
584 
585  try
586  {
587  extractor->Update();
588  }
589  catch (itk::ExceptionObject &excep)
590  {
591  MITK_ERROR << "Exception caught: " << excep.GetDescription();
592  return;
593  }
594 
595  m_WorkingImage->Modified();
596 
598  }
599 
601  }
602 
603  m_SliceInterpolatorController->SetWorkingImage(m_WorkingImage);
604 
606 }
607 
609 {
610  QMenu orientationPopup(this);
611  std::map<QAction *, mitk::SliceNavigationController *>::const_iterator it;
612  for (it = m_ActionToSliceDimensionMap.begin(); it != m_ActionToSliceDimensionMap.end(); it++)
613  orientationPopup.addAction(it->first);
614 
615  connect(&orientationPopup, SIGNAL(triggered(QAction *)), this, SLOT(OnAcceptAllPopupActivated(QAction *)));
616 
617  orientationPopup.exec(QCursor::pos());
618 }
619 
621 {
622  ActionToSliceDimensionMapType::const_iterator iter = m_ActionToSliceDimensionMap.find(action);
623  if (iter != m_ActionToSliceDimensionMap.end())
624  {
625  mitk::SliceNavigationController *slicer = iter->second;
626  this->AcceptAllInterpolations(slicer);
627  }
628 }
629 
631 {
632  if (m_Activated && m_LastSNC)
633  {
634  // determine which one is the current view, try to do an initial interpolation
635  mitk::BaseRenderer *renderer = m_LastSNC->GetRenderer();
636  if (renderer && renderer->GetMapperID() == mitk::BaseRenderer::Standard2D)
637  {
638  const mitk::TimeGeometry *timeGeometry =
639  dynamic_cast<const mitk::TimeGeometry *>(renderer->GetWorldTimeGeometry());
640  if (timeGeometry)
641  {
642  mitk::SliceNavigationController::GeometrySliceEvent event(const_cast<mitk::TimeGeometry *>(timeGeometry),
643  renderer->GetSlice());
644  this->TranslateAndInterpolateChangedSlice(event, m_LastSNC);
646  }
647  }
648  }
649 }
650 
652 {
653  // something (e.g. undo) changed the interpolation info, we should refresh our display
654  this->UpdateVisibleSuggestion();
655 }
656 
658  const itk::EventObject & /*e*/)
659 {
660  // Don't know how to avoid const_cast here?!
662  dynamic_cast<mitk::SliceNavigationController *>(const_cast<itk::Object *>(sender));
663  if (slicer)
664  {
665  m_ControllerToTimeObserverTag.remove(slicer);
666  m_ControllerToSliceObserverTag.remove(slicer);
667  m_ControllerToDeleteObserverTag.remove(slicer);
668  }
669 }
670 
672 {
673  QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
674 }
675 
677 {
678  this->RestoreOverrideCursor();
679 }
680 
682 {
683  QApplication::restoreOverrideCursor();
684 }
void Progress(unsigned int steps=1)
Sets the current amount of progress to current progress + steps.
Ui::QmitkSliceBasedInterpolatorWidgetGUIControls m_Controls
Data management class that handles &#39;was created by&#39; relations.
virtual unsigned int GetSlice() const
Message WorkingDataChanged
itk::Image< unsigned char, 3 > ImageType
#define MITK_ERROR
Definition: mitkLogMacros.h:20
void OnTimeChanged(itk::Object *sender, const itk::EventObject &)
Organizes the rendering process.
virtual const TimeGeometry * GetWorldTimeGeometry()
DataCollection - Class to facilitate loading/accessing structured data.
static Pointer New()
An Operation for applying an edited slice to the volume.
virtual mitk::ToolManager * GetToolManager()
Returns ToolManager object.
void TranslateAndInterpolateChangedSlice(const itk::EventObject &e, mitk::SliceNavigationController *slicer)
Pointer Clone() const
void Reset()
Explicitly reset progress bar.
static ProgressBar * GetInstance()
static method to get the GUI dependent ProgressBar-instance so the methods for steps to do and progre...
Controls the selection of the slice the associated BaseRenderer will display.
virtual mitk::PlaneGeometry * GetPlaneGeometry(int s) const
Returns the PlaneGeometry of the slice (s).
void OnToggleWidgetActivation(bool)
Reaction to "Start/Stop" button click.
void AcceptAllInterpolations(mitk::SliceNavigationController *slicer)
static Pointer New()
void OnSliceInterpolationInfoChanged(const itk::EventObject &)
virtual void SendSlice()
Send the currently selected slice to the connected observers (renderers)
BaseData * GetData() const
Get the data object (instance of BaseData, e.g., an Image) managed by this DataNode.
mitk::Image::Pointer GetWorkingSlice(const mitk::PlaneGeometry *planeGeometry)
unsigned int GetDimension() const
Get dimension of the image.
Definition: mitkImage.cpp:106
mitk::DataStorage::Pointer m_DataStorage
static Pointer New()
#define AccessFixedDimensionByItk_2(mitkImage, itkImageTypeFunction, dimension, arg1, arg2)
static RenderingManager * GetInstance()
void Interpolate(mitk::PlaneGeometry *plane, unsigned int timeStep, mitk::SliceNavigationController *slicer)
virtual MapperSlotId GetMapperID()
Get the MapperSlotId to use.
Image class for storing images.
Definition: mitkImage.h:72
const mitk::PlaneGeometry * GetCurrentPlaneGeometry()
Returns the currently selected Plane in the current BaseGeometry (if existent).
void SetSliceNavigationControllers(const QList< mitk::SliceNavigationController *> &controllers)
itk::RGBPixel< float > Color
Color Standard RGB color typedef (float)
Describes the geometry of a data object consisting of slices.
QmitkSliceBasedInterpolatorWidget(QWidget *parent=nullptr, const char *name=nullptr)
void AddStepsToDo(unsigned int steps)
Adds steps to totalSteps.
static Pointer New()
const ToolVectorTypeConst GetTools()
Gives you a list of all tools. This is const on purpose.
void MITKCORE_EXPORT CastToItkImage(const mitk::Image *mitkImage, itk::SmartPointer< ItkOutputImageType > &itkOutputImage)
Cast an mitk::Image to an itk::Image with a specific type.
ActionToSliceDimensionMapType m_ActionToSliceDimensionMap
virtual BaseGeometry::Pointer GetGeometryForTimeStep(TimeStepType timeStep) const =0
Returns the geometry which corresponds to the given time step.
virtual bool SetOperationEvent(UndoStackItem *stackItem)=0
static UndoModel * GetCurrentUndoModel()
gives access to the currently used UndoModel Introduced to access special functions of more specific ...
LabelSetImage class for handling labels and layers in a segmentation session.
mitk::Stepper * GetTime()
Get the Stepper through the time.
virtual unsigned int GetPos() const
Describes a two-dimensional, rectangular plane.
std::map< QAction *, mitk::SliceNavigationController * > ActionToSliceDimensionMapType
BaseRenderer * GetRenderer() const
Gets the BaseRenderer associated with this SNC (if any). While the BaseRenderer is not directly used ...
void OnSliceChanged(itk::Object *sender, const itk::EventObject &)
virtual void Clear()=0
clears undo and Redolist
void OnSliceNavigationControllerDeleted(const itk::Object *sender, const itk::EventObject &)
const ActionToSliceDimensionMapType CreateActionToSliceDimension()
void RequestUpdateAll(RequestType type=REQUEST_UPDATE_ALL)
Represents a pair of operations: undo and the according redo.
const char * GetName() const
get the name of the Renderer
Class for nodes of the DataTree.
Definition: mitkDataNode.h:57
void OnAcceptInterpolationClicked()
Reaction to "Accept Current Slice" button click.
DataVectorType GetWorkingData()
static mitk::ToolManagerProvider * GetInstance()
Returns an instance of ToolManagerProvider service.
static bool DetermineAffectedImageSlice(const Image *image, const PlaneGeometry *plane, int &affectedDimension, int &affectedSlice)
Calculates for a given Image and PlaneGeometry, which slice of the image (in index corrdinates) is me...