diff --git a/Modules/SegmentationUI/Qmitk/QmitkSliceBasedInterpolatorWidget.cpp b/Modules/SegmentationUI/Qmitk/QmitkSliceBasedInterpolatorWidget.cpp deleted file mode 100644 index e0f5f84b4d..0000000000 --- a/Modules/SegmentationUI/Qmitk/QmitkSliceBasedInterpolatorWidget.cpp +++ /dev/null @@ -1,708 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#include "QmitkSliceBasedInterpolatorWidget.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include - -QmitkSliceBasedInterpolatorWidget::QmitkSliceBasedInterpolatorWidget(QWidget *parent, const char * /*name*/) - : QWidget(parent), - m_SliceInterpolatorController(mitk::SliceBasedInterpolationController::New()), - m_ToolManager(nullptr), - m_Activated(false), - m_DataStorage(nullptr), - m_LastSNC(nullptr), - m_LastSliceIndex(0) -{ - m_Controls.setupUi(this); - - m_ToolManager = mitk::ToolManagerProvider::GetInstance()->GetToolManager(); - - m_ToolManager->WorkingDataChanged += mitk::MessageDelegate( - this, &QmitkSliceBasedInterpolatorWidget::OnToolManagerWorkingDataModified); - - connect(m_Controls.m_btStart, SIGNAL(toggled(bool)), this, SLOT(OnToggleWidgetActivation(bool))); - connect(m_Controls.m_btApplyForCurrentSlice, SIGNAL(clicked()), this, SLOT(OnAcceptInterpolationClicked())); - connect(m_Controls.m_btApplyForAllSlices, SIGNAL(clicked()), this, SLOT(OnAcceptAllInterpolationsClicked())); - - itk::ReceptorMemberCommand::Pointer command = - itk::ReceptorMemberCommand::New(); - command->SetCallbackFunction(this, &QmitkSliceBasedInterpolatorWidget::OnSliceInterpolationInfoChanged); - m_InterpolationInfoChangedObserverTag = m_SliceInterpolatorController->AddObserver(itk::ModifiedEvent(), command); - - // feedback node and its visualization properties - m_PreviewNode = mitk::DataNode::New(); - m_PreviewNode->SetName("3D tool preview"); - - m_PreviewNode->SetProperty("texture interpolation", mitk::BoolProperty::New(false)); - m_PreviewNode->SetProperty("layer", mitk::IntProperty::New(100)); - m_PreviewNode->SetProperty("binary", mitk::BoolProperty::New(true)); - m_PreviewNode->SetProperty("outline binary", mitk::BoolProperty::New(true)); - m_PreviewNode->SetProperty("outline binary shadow", mitk::BoolProperty::New(true)); - m_PreviewNode->SetProperty("helper object", mitk::BoolProperty::New(true)); - m_PreviewNode->SetOpacity(1.0); - m_PreviewNode->SetColor(0.0, 1.0, 0.0); - - m_Controls.m_btApplyForCurrentSlice->setEnabled(false); - m_Controls.m_btApplyForAllSlices->setEnabled(false); - - this->setEnabled(false); -} - -QmitkSliceBasedInterpolatorWidget::~QmitkSliceBasedInterpolatorWidget() -{ - m_ToolManager->WorkingDataChanged -= mitk::MessageDelegate( - this, &QmitkSliceBasedInterpolatorWidget::OnToolManagerWorkingDataModified); - - foreach (mitk::SliceNavigationController *slicer, m_ControllerToSliceObserverTag.keys()) - { - slicer->RemoveObserver(m_ControllerToDeleteObserverTag.take(slicer)); - slicer->RemoveObserver(m_ControllerToTimeObserverTag.take(slicer)); - slicer->RemoveObserver(m_ControllerToSliceObserverTag.take(slicer)); - } - - m_ActionToSliceDimensionMap.clear(); - - // remove observer - m_SliceInterpolatorController->RemoveObserver(m_InterpolationInfoChangedObserverTag); -} - -const QmitkSliceBasedInterpolatorWidget::ActionToSliceDimensionMapType - QmitkSliceBasedInterpolatorWidget::CreateActionToSliceDimension() -{ - ActionToSliceDimensionMapType actionToSliceDimension; - foreach (mitk::SliceNavigationController *slicer, m_ControllerToDeleteObserverTag.keys()) - { - std::string name = slicer->GetRenderer()->GetName(); - if (name == "stdmulti.widget0") - name = "Axial (red window)"; - else if (name == "stdmulti.widget1") - name = "Sagittal (green window)"; - else if (name == "stdmulti.widget2") - name = "Coronal (blue window)"; - actionToSliceDimension[new QAction(QString::fromStdString(name), nullptr)] = slicer; - } - - return actionToSliceDimension; -} - -void QmitkSliceBasedInterpolatorWidget::SetDataStorage(mitk::DataStorage &storage) -{ - m_DataStorage = &storage; -} - -void QmitkSliceBasedInterpolatorWidget::SetSliceNavigationControllers( - const QList &controllers) -{ - Q_ASSERT(!controllers.empty()); - - // connect to the slice navigation controller. after each change, call the interpolator - foreach (mitk::SliceNavigationController *slicer, controllers) - { - // Has to be initialized - m_LastSNC = slicer; - - m_TimePoints.insert(slicer, slicer->GetSelectedTimePoint()); - - itk::MemberCommand::Pointer deleteCommand = - itk::MemberCommand::New(); - deleteCommand->SetCallbackFunction(this, &QmitkSliceBasedInterpolatorWidget::OnSliceNavigationControllerDeleted); - m_ControllerToDeleteObserverTag.insert(slicer, slicer->AddObserver(itk::DeleteEvent(), deleteCommand)); - - itk::MemberCommand::Pointer timeChangedCommand = - itk::MemberCommand::New(); - timeChangedCommand->SetCallbackFunction(this, &QmitkSliceBasedInterpolatorWidget::OnTimeChanged); - m_ControllerToTimeObserverTag.insert( - slicer, - slicer->AddObserver(mitk::SliceNavigationController::TimeGeometryEvent(nullptr, 0), timeChangedCommand)); - - itk::MemberCommand::Pointer sliceChangedCommand = - itk::MemberCommand::New(); - sliceChangedCommand->SetCallbackFunction(this, &QmitkSliceBasedInterpolatorWidget::OnSliceChanged); - m_ControllerToSliceObserverTag.insert( - slicer, slicer->AddObserver(mitk::SliceNavigationController::GeometrySliceEvent(nullptr, 0), sliceChangedCommand)); - } - - m_ActionToSliceDimensionMap = this->CreateActionToSliceDimension(); -} - -void QmitkSliceBasedInterpolatorWidget::OnToolManagerWorkingDataModified() -{ - mitk::DataNode *workingNode = this->m_ToolManager->GetWorkingData(0); - if (!workingNode) - { - this->setEnabled(false); - return; - } - - mitk::LabelSetImage *workingImage = dynamic_cast(workingNode->GetData()); - // TODO adapt tool manager so that this check is done there, e.g. convenience function - // Q_ASSERT(workingImage); - if (!workingImage) - { - this->setEnabled(false); - return; - } - - if (workingImage->GetDimension() > 4 || workingImage->GetDimension() < 3) - { - this->setEnabled(false); - return; - } - - m_WorkingImage = workingImage; - - this->setEnabled(true); -} - -void QmitkSliceBasedInterpolatorWidget::OnTimeChanged(itk::Object *sender, const itk::EventObject &e) -{ - // Check if we really have a GeometryTimeEvent - if (!dynamic_cast(&e)) - return; - - mitk::SliceNavigationController *slicer = dynamic_cast(sender); - Q_ASSERT(slicer); - - m_TimePoints[slicer] = slicer->GetSelectedTimePoint(); - - // TODO Macht das hier wirklich Sinn???? - if (m_LastSNC == slicer) - { - slicer->SendSlice(); // will trigger a new interpolation - } -} - -void QmitkSliceBasedInterpolatorWidget::OnSliceChanged(itk::Object *sender, const itk::EventObject &e) -{ - if (m_Activated && m_WorkingImage.IsNotNull()) - { - // Check whether we really have a GeometrySliceEvent - if (!dynamic_cast(&e)) - return; - - mitk::SliceNavigationController *slicer = dynamic_cast(sender); - if (slicer) - { - this->TranslateAndInterpolateChangedSlice(e, slicer); - mitk::RenderingManager::GetInstance()->RequestUpdateAll(); - // slicer->GetRenderer()->RequestUpdate(); - } - } -} - -void QmitkSliceBasedInterpolatorWidget::TranslateAndInterpolateChangedSlice(const itk::EventObject &e, - mitk::SliceNavigationController *slicer) -{ - if (m_Activated && m_WorkingImage.IsNotNull()) - { - const mitk::SliceNavigationController::GeometrySliceEvent &geometrySliceEvent = - dynamic_cast(e); - mitk::TimeGeometry *timeGeometry = geometrySliceEvent.GetTimeGeometry(); - if (timeGeometry && m_TimePoints.contains(slicer) && timeGeometry->IsValidTimePoint(m_TimePoints[slicer])) - { - mitk::SlicedGeometry3D *slicedGeometry = - dynamic_cast(timeGeometry->GetGeometryForTimePoint(m_TimePoints[slicer]).GetPointer()); - if (slicedGeometry) - { - mitk::PlaneGeometry *plane = slicedGeometry->GetPlaneGeometry(geometrySliceEvent.GetPos()); - if (plane) - { - m_LastSNC = slicer; - this->Interpolate(plane, m_TimePoints[slicer], slicer); - } - } - } - } -} - -void QmitkSliceBasedInterpolatorWidget::Interpolate(mitk::PlaneGeometry *plane, - mitk::TimePointType timePoint, - mitk::SliceNavigationController *slicer) -{ - int clickedSliceDimension(-1); - int clickedSliceIndex(-1); - - if (!m_WorkingImage->GetTimeGeometry()->IsValidTimePoint(timePoint)) - { - MITK_WARN << "Cannot interpolate WorkingImage. Passed time point is not within the time bounds of WorkingImage. Time point: " << timePoint; - return; - } - const auto timeStep = m_WorkingImage->GetTimeGeometry()->TimePointToTimeStep(timePoint); - - // calculate real slice position, i.e. slice of the image - // see if timestep is needed here - mitk::SegTool2D::DetermineAffectedImageSlice(m_WorkingImage, plane, clickedSliceDimension, clickedSliceIndex); - - mitk::Image::Pointer interpolation = - m_SliceInterpolatorController->Interpolate(clickedSliceDimension, clickedSliceIndex, plane, timeStep); - - m_PreviewNode->SetData(interpolation); - - const mitk::Color &color = m_WorkingImage->GetActiveLabel()->GetColor(); - m_PreviewNode->SetColor(color); - - m_LastSNC = slicer; - m_LastSliceIndex = clickedSliceIndex; -} - -mitk::Image::Pointer QmitkSliceBasedInterpolatorWidget::GetWorkingSlice(const mitk::PlaneGeometry *planeGeometry) -{ - const auto timePoint = m_LastSNC->GetSelectedTimePoint(); - - if (!m_WorkingImage->GetTimeGeometry()->IsValidTimePoint(timePoint)) - { - MITK_WARN << "Cannot get slice of WorkingImage. Time point selected by SliceNavigationController is not within the time bounds of WorkingImage. Time point: " << timePoint; - return nullptr; - } - - // Make sure that for reslicing and overwriting the same alogrithm is used. We can specify the mode of the vtk - // reslicer - vtkSmartPointer reslice = vtkSmartPointer::New(); - // set to false to extract a slice - reslice->SetOverwriteMode(false); - reslice->Modified(); - - // use ExtractSliceFilter with our specific vtkImageReslice for overwriting and extracting - mitk::ExtractSliceFilter::Pointer extractor = mitk::ExtractSliceFilter::New(reslice); - extractor->SetInput(m_WorkingImage); - const auto timeStep = m_WorkingImage->GetTimeGeometry()->TimePointToTimeStep(timePoint); - extractor->SetTimeStep(timeStep); - extractor->SetWorldGeometry(planeGeometry); - extractor->SetVtkOutputRequest(false); - extractor->SetResliceTransformByGeometry(m_WorkingImage->GetTimeGeometry()->GetGeometryForTimeStep(timeStep)); - - extractor->Modified(); - - try - { - extractor->Update(); - } - catch (itk::ExceptionObject &excep) - { - MITK_ERROR << "Exception caught: " << excep.GetDescription(); - return nullptr; - } - - mitk::Image::Pointer slice = extractor->GetOutput(); - - // specify the undo operation with the non edited slice - // MLI TODO added code starts here - mitk::SlicedGeometry3D *sliceGeometry = dynamic_cast(slice->GetGeometry()); - // m_undoOperation = new mitk::DiffSliceOperation(m_WorkingImage, extractor->GetVtkOutput(), slice->GetGeometry(), - // timeStep, const_cast(planeGeometry)); - // added code ends here - m_undoOperation = new mitk::DiffSliceOperation( - m_WorkingImage, extractor->GetOutput(), sliceGeometry, timeStep, const_cast(planeGeometry)); - - slice->DisconnectPipeline(); - - return slice; -} - -void QmitkSliceBasedInterpolatorWidget::OnToggleWidgetActivation(bool enabled) -{ - Q_ASSERT(m_ToolManager); - - mitk::DataNode *workingNode = m_ToolManager->GetWorkingData(0); - if (!workingNode) - return; - - m_Controls.m_btApplyForCurrentSlice->setEnabled(enabled); - m_Controls.m_btApplyForAllSlices->setEnabled(enabled); - - if (enabled) - m_Controls.m_btStart->setText("Stop"); - else - m_Controls.m_btStart->setText("Start"); - - unsigned int numberOfExistingTools = m_ToolManager->GetTools().size(); - for (unsigned int i = 0; i < numberOfExistingTools; i++) - { - // mitk::SegTool2D* tool = dynamic_cast(m_ToolManager->GetToolById(i)); - // MLI TODO - // if (tool) tool->SetEnable2DInterpolation( enabled ); - } - - if (enabled) - { - if (!m_DataStorage->Exists(m_PreviewNode)) - { - m_DataStorage->Add(m_PreviewNode); - } - - m_SliceInterpolatorController->SetWorkingImage(m_WorkingImage); - this->UpdateVisibleSuggestion(); - } - else - { - if (m_DataStorage->Exists(m_PreviewNode)) - { - m_DataStorage->Remove(m_PreviewNode); - } - - mitk::UndoController::GetCurrentUndoModel()->Clear(); - } - - m_Activated = enabled; - - mitk::RenderingManager::GetInstance()->RequestUpdateAll(); -} - -template -void QmitkSliceBasedInterpolatorWidget::WritePreviewOnWorkingImage(itk::Image *targetSlice, - const mitk::Image *sourceSlice, - int overwritevalue) -{ - typedef itk::Image ImageType; - - typename ImageType::Pointer sourceSliceITK; - mitk::CastToItkImage(sourceSlice, sourceSliceITK); - - // now the original slice and the ipSegmentation-painted slice are in the same format, and we can just copy all pixels - // that are non-zero - typedef itk::ImageRegionIterator OutputIteratorType; - typedef itk::ImageRegionConstIterator InputIteratorType; - - InputIteratorType inputIterator(sourceSliceITK, sourceSliceITK->GetLargestPossibleRegion()); - OutputIteratorType outputIterator(targetSlice, targetSlice->GetLargestPossibleRegion()); - - outputIterator.GoToBegin(); - inputIterator.GoToBegin(); - - int activePixelValue = m_WorkingImage->GetActiveLabel()->GetValue(); - - if (activePixelValue == 0) // if exterior is the active label - { - while (!outputIterator.IsAtEnd()) - { - if (inputIterator.Get() != 0) - { - outputIterator.Set(overwritevalue); - } - ++outputIterator; - ++inputIterator; - } - } - else if (overwritevalue != 0) // if we are not erasing - { - while (!outputIterator.IsAtEnd()) - { - int targetValue = static_cast(outputIterator.Get()); - if (inputIterator.Get() != 0) - { - if (!m_WorkingImage->GetLabel(targetValue)->GetLocked()) - outputIterator.Set(overwritevalue); - } - - ++outputIterator; - ++inputIterator; - } - } - else // if we are erasing - { - while (!outputIterator.IsAtEnd()) - { - const int targetValue = outputIterator.Get(); - if (inputIterator.Get() != 0) - { - if (targetValue == activePixelValue) - outputIterator.Set(overwritevalue); - } - - ++outputIterator; - ++inputIterator; - } - } -} - -void QmitkSliceBasedInterpolatorWidget::OnAcceptInterpolationClicked() -{ - if (m_WorkingImage.IsNotNull() && m_PreviewNode->GetData()) - { - const mitk::PlaneGeometry *planeGeometry = m_LastSNC->GetCurrentPlaneGeometry(); - if (!planeGeometry) - return; - - mitk::Image::Pointer sliceImage = this->GetWorkingSlice(planeGeometry); - if (sliceImage.IsNull()) - return; - - mitk::Image::Pointer previewSlice = dynamic_cast(m_PreviewNode->GetData()); - - AccessFixedDimensionByItk_2( - sliceImage, WritePreviewOnWorkingImage, 2, previewSlice, m_WorkingImage->GetActiveLabel()->GetValue()); - - // Make sure that for reslicing and overwriting the same alogrithm is used. We can specify the mode of the vtk - // reslicer - vtkSmartPointer overwrite = vtkSmartPointer::New(); - overwrite->SetInputSlice(sliceImage->GetVtkImageData()); - // set overwrite mode to true to write back to the image volume - overwrite->SetOverwriteMode(true); - overwrite->Modified(); - - const auto timePoint = m_LastSNC->GetSelectedTimePoint(); - if (!m_WorkingImage->GetTimeGeometry()->IsValidTimePoint(timePoint)) - { - MITK_WARN << "Cannot accept interpolation. Time point selected by SliceNavigationController is not within the time bounds of WorkingImage. Time point: " << timePoint; - return; - } - - mitk::ExtractSliceFilter::Pointer extractor = mitk::ExtractSliceFilter::New(overwrite); - extractor->SetInput(m_WorkingImage); - const auto timeStep = m_WorkingImage->GetTimeGeometry()->TimePointToTimeStep(timePoint); - extractor->SetTimeStep(timeStep); - extractor->SetWorldGeometry(planeGeometry); - extractor->SetVtkOutputRequest(false); - extractor->SetResliceTransformByGeometry(m_WorkingImage->GetTimeGeometry()->GetGeometryForTimeStep(timeStep)); - - extractor->Modified(); - - try - { - extractor->Update(); - } - catch (itk::ExceptionObject &excep) - { - MITK_ERROR << "Exception caught: " << excep.GetDescription(); - return; - } - - // the image was modified within the pipeline, but not marked so - m_WorkingImage->Modified(); - - int clickedSliceDimension(-1); - int clickedSliceIndex(-1); - - mitk::SegTool2D::DetermineAffectedImageSlice( - m_WorkingImage, planeGeometry, clickedSliceDimension, clickedSliceIndex); - - m_SliceInterpolatorController->SetChangedSlice(sliceImage, clickedSliceDimension, clickedSliceIndex, timeStep); - - // specify the undo operation with the edited slice - // MLI TODO added code starts here - mitk::SlicedGeometry3D *sliceGeometry = dynamic_cast(sliceImage->GetGeometry()); - // m_undoOperation = new mitk::DiffSliceOperation(m_WorkingImage, extractor->GetVtkOutput(), slice->GetGeometry(), - // timeStep, const_cast(planeGeometry)); - // added code ends here - m_doOperation = new mitk::DiffSliceOperation(m_WorkingImage, - extractor->GetOutput(), - sliceGeometry, - timeStep, - const_cast(planeGeometry)); - - // create an operation event for the undo stack - mitk::OperationEvent *undoStackItem = new mitk::OperationEvent( - mitk::DiffSliceOperationApplier::GetInstance(), m_doOperation, m_undoOperation, "Slice Interpolation"); - - // add it to the undo controller - mitk::UndoController::GetCurrentUndoModel()->SetOperationEvent(undoStackItem); - - // clear the pointers as the operation are stored in the undo controller and also deleted from there - m_undoOperation = nullptr; - m_doOperation = nullptr; - - m_PreviewNode->SetData(nullptr); - - mitk::RenderingManager::GetInstance()->RequestUpdateAll(); - } -} - -void QmitkSliceBasedInterpolatorWidget::AcceptAllInterpolations(mitk::SliceNavigationController *slicer) -{ - // Since we need to shift the plane it must be clone so that the original plane isn't altered - mitk::PlaneGeometry::Pointer reslicePlane = slicer->GetCurrentPlaneGeometry()->Clone(); - const auto timePoint = slicer->GetSelectedTimePoint(); - if (!m_WorkingImage->GetTimeGeometry()->IsValidTimePoint(timePoint)) - { - MITK_WARN << "Cannot accept all interpolations. Time point selected by SliceNavigationController is not within the time bounds of WorkingImage. Time point: " << timePoint; - - return; - } - const auto timeStep = m_WorkingImage->GetTimeGeometry()->TimePointToTimeStep(timePoint); - - int sliceDimension(-1); - int sliceIndex(-1); - - mitk::SegTool2D::DetermineAffectedImageSlice(m_WorkingImage, reslicePlane, sliceDimension, sliceIndex); - - unsigned int zslices = m_WorkingImage->GetDimension(sliceDimension); - - mitk::ProgressBar::GetInstance()->Reset(); - mitk::ProgressBar::GetInstance()->AddStepsToDo(zslices); - - mitk::Point3D origin = reslicePlane->GetOrigin(); - - for (unsigned int idx = 0; idx < zslices; ++idx) - { - // Transforming the current origin of the reslice plane - // so that it matches the one of the next slice - m_WorkingImage->GetSlicedGeometry()->WorldToIndex(origin, origin); - origin[sliceDimension] = idx; - m_WorkingImage->GetSlicedGeometry()->IndexToWorld(origin, origin); - reslicePlane->SetOrigin(origin); - - mitk::Image::Pointer interpolation = - m_SliceInterpolatorController->Interpolate(sliceDimension, idx, reslicePlane, timeStep); - - if (interpolation.IsNotNull()) - { - m_PreviewNode->SetData(interpolation); - - mitk::Image::Pointer sliceImage = this->GetWorkingSlice(reslicePlane); - if (sliceImage.IsNull()) - return; - - AccessFixedDimensionByItk_2( - sliceImage, WritePreviewOnWorkingImage, 2, interpolation, m_WorkingImage->GetActiveLabel()->GetValue()); - - // Make sure that for reslicing and overwriting the same alogrithm is used. We can specify the mode of the vtk - // reslicer - vtkSmartPointer overwrite = vtkSmartPointer::New(); - overwrite->SetInputSlice(sliceImage->GetVtkImageData()); - // set overwrite mode to true to write back to the image volume - overwrite->SetOverwriteMode(true); - overwrite->Modified(); - - mitk::ExtractSliceFilter::Pointer extractor = mitk::ExtractSliceFilter::New(overwrite); - extractor->SetInput(m_WorkingImage); - extractor->SetTimeStep(timeStep); - extractor->SetWorldGeometry(reslicePlane); - extractor->SetVtkOutputRequest(true); - extractor->SetResliceTransformByGeometry(m_WorkingImage->GetTimeGeometry()->GetGeometryForTimeStep(timeStep)); - - extractor->Modified(); - - try - { - extractor->Update(); - } - catch (itk::ExceptionObject &excep) - { - MITK_ERROR << "Exception caught: " << excep.GetDescription(); - return; - } - - m_WorkingImage->Modified(); - - mitk::RenderingManager::GetInstance()->RequestUpdateAll(mitk::RenderingManager::REQUEST_UPDATE_2DWINDOWS); - } - - mitk::ProgressBar::GetInstance()->Progress(); - } - - m_SliceInterpolatorController->SetWorkingImage(m_WorkingImage); - - mitk::RenderingManager::GetInstance()->RequestUpdateAll(); -} - -void QmitkSliceBasedInterpolatorWidget::OnAcceptAllInterpolationsClicked() -{ - QMenu orientationPopup(this); - std::map::const_iterator it; - for (it = m_ActionToSliceDimensionMap.begin(); it != m_ActionToSliceDimensionMap.end(); it++) - orientationPopup.addAction(it->first); - - connect(&orientationPopup, SIGNAL(triggered(QAction *)), this, SLOT(OnAcceptAllPopupActivated(QAction *))); - - orientationPopup.exec(QCursor::pos()); -} - -void QmitkSliceBasedInterpolatorWidget::OnAcceptAllPopupActivated(QAction *action) -{ - ActionToSliceDimensionMapType::const_iterator iter = m_ActionToSliceDimensionMap.find(action); - if (iter != m_ActionToSliceDimensionMap.end()) - { - mitk::SliceNavigationController *slicer = iter->second; - this->AcceptAllInterpolations(slicer); - } -} - -void QmitkSliceBasedInterpolatorWidget::UpdateVisibleSuggestion() -{ - if (m_Activated && m_LastSNC) - { - // determine which one is the current view, try to do an initial interpolation - mitk::BaseRenderer *renderer = m_LastSNC->GetRenderer(); - if (renderer && renderer->GetMapperID() == mitk::BaseRenderer::Standard2D) - { - const mitk::TimeGeometry *timeGeometry = - dynamic_cast(renderer->GetWorldTimeGeometry()); - if (timeGeometry) - { - mitk::SliceNavigationController::GeometrySliceEvent event(const_cast(timeGeometry), - renderer->GetSlice()); - this->TranslateAndInterpolateChangedSlice(event, m_LastSNC); - mitk::RenderingManager::GetInstance()->RequestUpdateAll(); - } - } - } -} - -void QmitkSliceBasedInterpolatorWidget::OnSliceInterpolationInfoChanged(const itk::EventObject & /*e*/) -{ - // something (e.g. undo) changed the interpolation info, we should refresh our display - this->UpdateVisibleSuggestion(); -} - -void QmitkSliceBasedInterpolatorWidget::OnSliceNavigationControllerDeleted(const itk::Object *sender, - const itk::EventObject & /*e*/) -{ - // Don't know how to avoid const_cast here?! - mitk::SliceNavigationController *slicer = - dynamic_cast(const_cast(sender)); - if (slicer) - { - m_ControllerToTimeObserverTag.remove(slicer); - m_ControllerToSliceObserverTag.remove(slicer); - m_ControllerToDeleteObserverTag.remove(slicer); - } -} - -void QmitkSliceBasedInterpolatorWidget::WaitCursorOn() -{ - QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); -} - -void QmitkSliceBasedInterpolatorWidget::WaitCursorOff() -{ - this->RestoreOverrideCursor(); -} - -void QmitkSliceBasedInterpolatorWidget::RestoreOverrideCursor() -{ - QApplication::restoreOverrideCursor(); -} diff --git a/Modules/SegmentationUI/Qmitk/QmitkSliceBasedInterpolatorWidget.h b/Modules/SegmentationUI/Qmitk/QmitkSliceBasedInterpolatorWidget.h deleted file mode 100644 index 86c6cdab0a..0000000000 --- a/Modules/SegmentationUI/Qmitk/QmitkSliceBasedInterpolatorWidget.h +++ /dev/null @@ -1,195 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#ifndef QmitkSliceBasedInterpolatorWidget_h_Included -#define QmitkSliceBasedInterpolatorWidget_h_Included - -#include "MitkSegmentationUIExports.h" -#include "mitkDataStorage.h" -#include "mitkSliceBasedInterpolationController.h" - -#include - -#include - -#include "ui_QmitkSliceBasedInterpolatorWidgetGUIControls.h" - -namespace mitk -{ - class PlaneGeometry; - class SliceNavigationController; - class LabelSetImage; - class ToolManager; - class DiffSliceOperation; -} - -/** - \brief GUI for slices interpolation. - - \ingroup ToolManagerEtAl - \ingroup Widgets - - \sa QmitkInteractiveSegmentation - \sa mitk::SegmentationInterpolation - - While mitk::SegmentationInterpolation does the bookkeeping of interpolation - (keeping track of which slices contain how much segmentation) and the algorithmic work, - QmitkSliceBasedInterpolatorWidget is responsible to watch the GUI, to notice, which slice is currently - visible. It triggers generation of interpolation suggestions and also triggers acception of - suggestions. - - \todo show/hide feedback on demand - - Last contributor: $Author: maleike $ -*/ - -class MITKSEGMENTATIONUI_EXPORT QmitkSliceBasedInterpolatorWidget : public QWidget -{ - Q_OBJECT - -public: - QmitkSliceBasedInterpolatorWidget(QWidget *parent = nullptr, const char *name = nullptr); - ~QmitkSliceBasedInterpolatorWidget() override; - - void SetDataStorage(mitk::DataStorage &storage); - - /** - Sets the slice navigation controllers for getting slice changed events from the views. - */ - void SetSliceNavigationControllers(const QList &controllers); - - void OnToolManagerWorkingDataModified(); - - void OnTimeChanged(itk::Object *sender, const itk::EventObject &); - - void OnSliceChanged(itk::Object *sender, const itk::EventObject &); - - void OnSliceNavigationControllerDeleted(const itk::Object *sender, const itk::EventObject &); - - /** - Just public because it is called by itk::Commands. You should not need to call this. - */ - void OnSliceInterpolationInfoChanged(const itk::EventObject &); - - Ui::QmitkSliceBasedInterpolatorWidgetGUIControls m_Controls; - -signals: - - void signalSliceBasedInterpolationEnabled(bool); - -public slots: - - /** - \brief Reaction to "Start/Stop" button click - */ - void OnToggleWidgetActivation(bool); - -protected slots: - - /** - \brief Reaction to "Accept Current Slice" button click. - */ - void OnAcceptInterpolationClicked(); - - /* - \brief Reaction to "Accept All Slices" button click. - Opens popup to ask about which orientation should be interpolated - */ - void OnAcceptAllInterpolationsClicked(); - - /* - \brief Called from popup menu of OnAcceptAllInterpolationsClicked() - Will trigger interpolation for all slices in given orientation - */ - void OnAcceptAllPopupActivated(QAction *action); - -protected: - typedef std::map ActionToSliceDimensionMapType; - - const ActionToSliceDimensionMapType CreateActionToSliceDimension(); - - ActionToSliceDimensionMapType m_ActionToSliceDimensionMap; - - void AcceptAllInterpolations(mitk::SliceNavigationController *slicer); - - void WaitCursorOn(); - - void WaitCursorOff(); - - void RestoreOverrideCursor(); - - /** - Gets the working slice based on the given plane geometry and last saved interaction - - \param planeGeometry a plane geometry - */ - mitk::Image::Pointer GetWorkingSlice(const mitk::PlaneGeometry *planeGeometry); - - /** - Retrieves the currently selected PlaneGeometry from a SlicedGeometry3D that is generated by a - SliceNavigationController - and calls Interpolate to further process this PlaneGeometry into an interpolation. - - \param e is a actually a mitk::SliceNavigationController::GeometrySliceEvent, sent by a SliceNavigationController - \param slicer the SliceNavigationController - */ - void TranslateAndInterpolateChangedSlice(const itk::EventObject &e, mitk::SliceNavigationController *slicer); - - /** - Given a PlaneGeometry, this method figures out which slice of the first working image (of the associated - ToolManager) - should be interpolated. The actual work is then done by our SegmentationInterpolation object. - */ - void Interpolate(mitk::PlaneGeometry *plane, mitk::TimePointType timePoint, mitk::SliceNavigationController *slicer); - - /** - Called internally to update the interpolation suggestion. Finds out about the focused render window and requests an - interpolation. - */ - void UpdateVisibleSuggestion(); - -private: - mitk::SliceBasedInterpolationController::Pointer m_SliceInterpolatorController; - - mitk::ToolManager *m_ToolManager; - - bool m_Activated; - - template - void WritePreviewOnWorkingImage(itk::Image *target, - const mitk::Image *source, - int overwritevalue); - - QHash m_ControllerToTimeObserverTag; - QHash m_ControllerToSliceObserverTag; - QHash m_ControllerToDeleteObserverTag; - - unsigned int m_InterpolationInfoChangedObserverTag; - - mitk::DiffSliceOperation *m_doOperation; - mitk::DiffSliceOperation *m_undoOperation; - - mitk::DataNode::Pointer m_PreviewNode; - mitk::Image::Pointer m_PreviewImage; - - mitk::LabelSetImage::Pointer m_WorkingImage; - - QHash m_TimePoints; - - mitk::DataStorage::Pointer m_DataStorage; - - mitk::SliceNavigationController *m_LastSNC; - - unsigned int m_LastSliceIndex; -}; - -#endif diff --git a/Modules/SegmentationUI/Qmitk/QmitkSliceBasedInterpolatorWidgetGUIControls.ui b/Modules/SegmentationUI/Qmitk/QmitkSliceBasedInterpolatorWidgetGUIControls.ui deleted file mode 100644 index d8e8eeeca3..0000000000 --- a/Modules/SegmentationUI/Qmitk/QmitkSliceBasedInterpolatorWidgetGUIControls.ui +++ /dev/null @@ -1,159 +0,0 @@ - - - QmitkSliceBasedInterpolatorWidgetGUIControls - - - - 0 - 0 - 265 - 94 - - - - - 0 - 0 - - - - - 0 - 0 - - - - Slice-Based Interpolation - - - - - - - QLayout::SetDefaultConstraint - - - 6 - - - - - QLayout::SetDefaultConstraint - - - - - true - - - - 0 - 0 - - - - Start/Stop the 3D interpolation utility - - - Start - - - - :/Qmitk/Start.png - :/Qmitk/Stop.png:/Qmitk/Start.png - - - - 32 - 32 - - - - true - - - false - - - Qt::ToolButtonTextUnderIcon - - - Qt::NoArrow - - - - - - - - 0 - 0 - - - - Accept Single - - - - :/Qmitk/AcceptCurrentInterpolation.png:/Qmitk/AcceptCurrentInterpolation.png - - - - 32 - 32 - - - - Qt::ToolButtonTextUnderIcon - - - - - - - - 0 - 0 - - - - Accept All - - - - :/Qmitk/AcceptAllInterpolations.png:/Qmitk/AcceptAllInterpolations.png - - - - 32 - 32 - - - - Qt::ToolButtonTextUnderIcon - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - - - diff --git a/Modules/SegmentationUI/files.cmake b/Modules/SegmentationUI/files.cmake index 55171904f3..aa38f2c30f 100644 --- a/Modules/SegmentationUI/files.cmake +++ b/Modules/SegmentationUI/files.cmake @@ -1,79 +1,76 @@ set( CPP_FILES Qmitk/QmitkSegWithPreviewToolGUIBase.cpp Qmitk/QmitkMultiLabelSegWithPreviewToolGUIBase.cpp Qmitk/QmitkBinaryThresholdToolGUIBase.cpp Qmitk/QmitkBinaryThresholdToolGUI.cpp Qmitk/QmitkBinaryThresholdULToolGUI.cpp Qmitk/QmitkConfirmSegmentationDialog.cpp Qmitk/QmitkCopyToClipBoardDialog.cpp Qmitk/QmitkDrawPaintbrushToolGUI.cpp Qmitk/QmitkErasePaintbrushToolGUI.cpp Qmitk/QmitkEditableContourToolGUIBase.cpp Qmitk/QmitkLiveWireTool2DGUI.cpp Qmitk/QmitkLassoToolGUI.cpp Qmitk/QmitkOtsuTool3DGUI.cpp Qmitk/QmitkPaintbrushToolGUI.cpp Qmitk/QmitkPickingToolGUI.cpp Qmitk/QmitkSlicesInterpolator.cpp Qmitk/QmitkToolGUI.cpp Qmitk/QmitkToolGUIArea.cpp Qmitk/QmitkToolSelectionBox.cpp Qmitk/QmitknnUNetFolderParser.cpp Qmitk/QmitknnUNetToolGUI.cpp Qmitk/QmitknnUNetWorker.cpp Qmitk/QmitknnUNetGPU.cpp Qmitk/QmitkSurfaceStampWidget.cpp Qmitk/QmitkMaskStampWidget.cpp -Qmitk/QmitkSliceBasedInterpolatorWidget.cpp Qmitk/QmitkStaticDynamicSegmentationDialog.cpp Qmitk/QmitkSurfaceBasedInterpolatorWidget.cpp Qmitk/QmitkSimpleLabelSetListWidget.cpp ) set(MOC_H_FILES Qmitk/QmitkSegWithPreviewToolGUIBase.h Qmitk/QmitkMultiLabelSegWithPreviewToolGUIBase.h Qmitk/QmitkBinaryThresholdToolGUIBase.h Qmitk/QmitkBinaryThresholdToolGUI.h Qmitk/QmitkBinaryThresholdULToolGUI.h Qmitk/QmitkConfirmSegmentationDialog.h Qmitk/QmitkCopyToClipBoardDialog.h Qmitk/QmitkDrawPaintbrushToolGUI.h Qmitk/QmitkErasePaintbrushToolGUI.h Qmitk/QmitkEditableContourToolGUIBase.h Qmitk/QmitkLiveWireTool2DGUI.h Qmitk/QmitkLassoToolGUI.h Qmitk/QmitkOtsuTool3DGUI.h Qmitk/QmitkPaintbrushToolGUI.h Qmitk/QmitkPickingToolGUI.h Qmitk/QmitkSlicesInterpolator.h Qmitk/QmitkToolGUI.h Qmitk/QmitkToolGUIArea.h Qmitk/QmitkToolSelectionBox.h Qmitk/QmitknnUNetFolderParser.h Qmitk/QmitknnUNetToolGUI.h Qmitk/QmitknnUNetGPU.h Qmitk/QmitknnUNetWorker.h Qmitk/QmitknnUNetEnsembleLayout.h Qmitk/QmitkSurfaceStampWidget.h Qmitk/QmitkMaskStampWidget.h -Qmitk/QmitkSliceBasedInterpolatorWidget.h Qmitk/QmitkStaticDynamicSegmentationDialog.h Qmitk/QmitkSurfaceBasedInterpolatorWidget.h Qmitk/QmitkSimpleLabelSetListWidget.h ) set(UI_FILES Qmitk/QmitkConfirmSegmentationDialog.ui Qmitk/QmitkOtsuToolWidgetControls.ui Qmitk/QmitkSurfaceStampWidgetGUIControls.ui Qmitk/QmitkMaskStampWidgetGUIControls.ui -Qmitk/QmitkSliceBasedInterpolatorWidgetGUIControls.ui Qmitk/QmitkSurfaceBasedInterpolatorWidgetGUIControls.ui Qmitk/QmitknnUNetToolGUIControls.ui Qmitk/QmitkEditableContourToolGUIControls.ui ) set(QRC_FILES resources/SegmentationUI.qrc )