diff --git a/Modules/Segmentation/Interactions/mitkAutoSegmentationWithPreviewTool.cpp b/Modules/Segmentation/Interactions/mitkAutoSegmentationWithPreviewTool.cpp new file mode 100644 index 0000000000..f26dcdc985 --- /dev/null +++ b/Modules/Segmentation/Interactions/mitkAutoSegmentationWithPreviewTool.cpp @@ -0,0 +1,465 @@ +/*============================================================================ + +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 "mitkAutoSegmentationWithPreviewTool.h" + +#include "mitkToolManager.h" + +#include "mitkColorProperty.h" +#include "mitkLevelWindowProperty.h" +#include "mitkProperties.h" + +#include "mitkDataStorage.h" +#include "mitkRenderingManager.h" +#include + +#include "mitkImageAccessByItk.h" +#include "mitkImageCast.h" +#include "mitkImageStatisticsHolder.h" +#include "mitkImageTimeSelector.h" +#include "mitkLabelSetImage.h" +#include "mitkMaskAndCutRoiImageFilter.h" +#include "mitkPadImageFilter.h" +#include "mitkNodePredicateGeometry.h" + +mitk::AutoSegmentationWithPreviewTool::AutoSegmentationWithPreviewTool(bool lazyDynamicPreviews): m_LazyDynamicPreviews(lazyDynamicPreviews) +{ + m_ProgressCommand = mitk::ToolCommand::New(); +} + +mitk::AutoSegmentationWithPreviewTool::~AutoSegmentationWithPreviewTool() +{ +} + +bool mitk::AutoSegmentationWithPreviewTool::CanHandle(const BaseData* referenceData, const BaseData* workingData) const +{ + if (workingData == nullptr) + return true; + + auto* labelSet = dynamic_cast(workingData); + + if (labelSet != nullptr) + return true; + + auto* image = dynamic_cast(workingData); + + if (image == nullptr) + return false; + + //if it is a normal image and not a lable set as working data it must have the same pixel type as a label set. + return MakeScalarPixelType< DefaultSegmentationDataType >() == image->GetPixelType(); +} + +void mitk::AutoSegmentationWithPreviewTool::Activated() +{ + Superclass::Activated(); + + m_ToolManager->RoiDataChanged += + mitk::MessageDelegate(this, &mitk::AutoSegmentationWithPreviewTool::OnRoiDataChanged); + + m_ToolManager->SelectedTimePointChanged += + mitk::MessageDelegate(this, &mitk::AutoSegmentationWithPreviewTool::OnTimePointChanged); + + m_ReferenceDataNode = m_ToolManager->GetReferenceData(0); + m_SegmentationInputNode = m_ReferenceDataNode; + + m_LastTimePointOfUpdate = 0; + + if (m_PreviewNode.IsNull()) + { + m_PreviewNode = DataNode::New(); + m_PreviewNode->SetProperty("color", ColorProperty::New(0.0, 1.0, 0.0)); + m_PreviewNode->SetProperty("name", StringProperty::New(std::string(this->GetName())+" preview")); + m_PreviewNode->SetProperty("opacity", FloatProperty::New(0.3)); + m_PreviewNode->SetProperty("binary", BoolProperty::New(true)); + m_PreviewNode->SetProperty("helper object", BoolProperty::New(true)); + } + + if (m_SegmentationInputNode.IsNotNull()) + { + this->ResetPreviewNode(); + this->InitiateToolByInput(); + } + else + { + m_ToolManager->ActivateTool(-1); + } +} + +void mitk::AutoSegmentationWithPreviewTool::Deactivated() +{ + m_ToolManager->RoiDataChanged -= + mitk::MessageDelegate(this, &mitk::AutoSegmentationWithPreviewTool::OnRoiDataChanged); + + m_ToolManager->SelectedTimePointChanged -= + mitk::MessageDelegate(this, &mitk::AutoSegmentationWithPreviewTool::OnTimePointChanged); + + m_SegmentationInputNode = nullptr; + m_ReferenceDataNode = nullptr; + + try + { + if (DataStorage *storage = m_ToolManager->GetDataStorage()) + { + storage->Remove(m_PreviewNode); + RenderingManager::GetInstance()->RequestUpdateAll(); + } + } + catch (...) + { + // don't care + } + + m_PreviewNode->SetData(nullptr); + + Superclass::Deactivated(); +} + +void mitk::AutoSegmentationWithPreviewTool::ConfirmSegmentation() +{ + + if (m_LazyDynamicPreviews && m_CreateAllTimeSteps) + { // The tool should create all time steps but is currently in lazy mode, + // thus ensure that a preview for all time steps is available. + this->UpdatePreview(true); + } + + CreateResultSegmentationFromPreview(); + + RenderingManager::GetInstance()->RequestUpdateAll(); + + if (!m_KeepActiveAfterAccept) + { + m_ToolManager->ActivateTool(-1); + } +} + +void mitk::AutoSegmentationWithPreviewTool::InitiateToolByInput() +{ + //default implementation does nothing. + //implement in derived classes to change behavior +} + +mitk::Image* mitk::AutoSegmentationWithPreviewTool::GetPreviewSegmentation() +{ + if (m_PreviewNode.IsNull()) + { + return nullptr; + } + + return dynamic_cast(m_PreviewNode->GetData()); +} + +mitk::DataNode* mitk::AutoSegmentationWithPreviewTool::GetPreviewSegmentationNode() +{ + return m_PreviewNode; +} + +const mitk::Image* mitk::AutoSegmentationWithPreviewTool::GetSegmentationInput() const +{ + if (m_SegmentationInputNode.IsNull()) + { + return nullptr; + } + + return dynamic_cast(m_SegmentationInputNode->GetData()); +} + +const mitk::Image* mitk::AutoSegmentationWithPreviewTool::GetReferenceData() const +{ + if (m_ReferenceDataNode.IsNull()) + { + return nullptr; + } + + return dynamic_cast(m_ReferenceDataNode->GetData()); +} + +void mitk::AutoSegmentationWithPreviewTool::ResetPreviewNode() +{ + itk::RGBPixel previewColor; + previewColor[0] = 0.0f; + previewColor[1] = 1.0f; + previewColor[2] = 0.0f; + + const auto image = this->GetSegmentationInput(); + if (nullptr != image) + { + mitk::LabelSetImage::ConstPointer workingImage = + dynamic_cast(m_ToolManager->GetWorkingData(0)->GetData()); + + if (workingImage.IsNotNull()) + { + auto newPreviewImage = workingImage->Clone(); + if (newPreviewImage.IsNull()) + { + MITK_ERROR << "Cannot create preview helper objects. Unable to clone working image"; + return; + } + + m_PreviewNode->SetData(newPreviewImage); + + // Let's paint the feedback node green... + newPreviewImage->GetActiveLabel()->SetColor(previewColor); + newPreviewImage->GetActiveLabelSet()->UpdateLookupTable(newPreviewImage->GetActiveLabel()->GetValue()); + } + else + { + mitk::Image::ConstPointer workingImageBin = dynamic_cast(m_ToolManager->GetWorkingData(0)->GetData()); + if (workingImageBin) + { + m_PreviewNode->SetData(workingImageBin->Clone()); + } + else + { + mitkThrow() << "Tool is an invalid state. Cannot setup preview node. Working data is an unsupported class and should have never be accepted by CanHandle()."; + } + } + + m_PreviewNode->SetColor(previewColor); + m_PreviewNode->SetOpacity(0.5); + + int layer(50); + m_ReferenceDataNode->GetIntProperty("layer", layer); + m_PreviewNode->SetIntProperty("layer", layer + 1); + + if (DataStorage *ds = m_ToolManager->GetDataStorage()) + { + if (!ds->Exists(m_PreviewNode)) + ds->Add(m_PreviewNode, m_ReferenceDataNode); + } + } +} + +template +static void ITKSetVolume(const itk::Image *originalImage, + mitk::Image *segmentation, + unsigned int timeStep) +{ + auto constPixelContainer = originalImage->GetPixelContainer(); + //have to make a const cast because itk::PixelContainer does not provide a const correct access :( + auto pixelContainer = const_cast::PixelContainer*>(constPixelContainer); + + segmentation->SetVolume((void *)pixelContainer->GetBufferPointer(), timeStep); +} + +void mitk::AutoSegmentationWithPreviewTool::TransferImageAtTimeStep(const Image* sourceImage, Image* destinationImage, const TimeStepType timeStep) +{ + try + { + Image::ConstPointer image3D = this->Get3DImage(sourceImage, timeStep); + + if (image3D->GetPixelType() != destinationImage->GetPixelType()) + { + mitkThrow() << "Cannot transfer images. Tool is in an invalid state, source image and destination image do not have the same pixel type. " + << "Source pixel type: " << sourceImage->GetPixelType().GetTypeAsString() + << "; destination pixel type: " << destinationImage->GetPixelType().GetTypeAsString(); + } + + if (!Equal(*(sourceImage->GetGeometry(timeStep)), *(destinationImage->GetGeometry(timeStep)), NODE_PREDICATE_GEOMETRY_DEFAULT_CHECK_PRECISION, false)) + { + mitkThrow() << "Cannot transfer images. Tool is in an invalid state, source image and destination image do not have the same geometry."; + } + + if (image3D->GetDimension() == 2) + { + AccessFixedDimensionByItk_2( + image3D, ITKSetVolume, 2, destinationImage, timeStep); + } + else + { + AccessFixedDimensionByItk_2( + image3D, ITKSetVolume, 3, destinationImage, timeStep); + } + } + catch (...) + { + Tool::ErrorMessage("Error accessing single time steps of the original image. Cannot create segmentation."); + throw; + } +} + +void mitk::AutoSegmentationWithPreviewTool::CreateResultSegmentationFromPreview() +{ + const auto segInput = this->GetSegmentationInput(); + auto previewImage = this->GetPreviewSegmentation(); + if (nullptr != segInput && nullptr != previewImage) + { + DataNode::Pointer resultSegmentationNode = GetTargetSegmentationNode(); + + if (resultSegmentationNode.IsNotNull()) + { + const auto timePoint = mitk::RenderingManager::GetInstance()->GetTimeNavigationController()->GetSelectedTimePoint(); + auto resultSegmentation = dynamic_cast(resultSegmentationNode->GetData()); + + // actually perform a thresholding + // REMARK: the following code in this scope assumes that feedBackImage and emptySegmentationImage + // are clones of the working image (segmentation provided to the tool). Therefor the have the same + // time geometry. + if (previewImage->GetTimeSteps() != resultSegmentation->GetTimeSteps()) + { + mitkThrow() << "Cannot performe threshold. Internal tool state is invalid." + << " Preview segmentation and segmentation result image have different time geometries."; + } + + if (m_CreateAllTimeSteps) + { + for (unsigned int timeStep = 0; timeStep < previewImage->GetTimeSteps(); ++timeStep) + { + TransferImageAtTimeStep(previewImage, resultSegmentation, timeStep); + } + } + else + { + const auto timeStep = resultSegmentation->GetTimeGeometry()->TimePointToTimeStep(timePoint); + TransferImageAtTimeStep(previewImage, resultSegmentation, timeStep); + } + + // since we are maybe working on a smaller image, pad it to the size of the original image + if (m_ReferenceDataNode.GetPointer() != m_SegmentationInputNode.GetPointer()) + { + mitk::PadImageFilter::Pointer padFilter = mitk::PadImageFilter::New(); + + padFilter->SetInput(0, resultSegmentation); + padFilter->SetInput(1, dynamic_cast(m_ReferenceDataNode->GetData())); + padFilter->SetBinaryFilter(true); + padFilter->SetUpperThreshold(1); + padFilter->SetLowerThreshold(1); + padFilter->Update(); + + resultSegmentationNode->SetData(padFilter->GetOutput()); + } + + m_ToolManager->SetWorkingData(resultSegmentationNode); + m_ToolManager->GetWorkingData(0)->Modified(); + } + } +} + +void mitk::AutoSegmentationWithPreviewTool::OnRoiDataChanged() +{ + mitk::DataNode::ConstPointer node = m_ToolManager->GetRoiData(0); + + if (node.IsNotNull()) + { + mitk::MaskAndCutRoiImageFilter::Pointer roiFilter = mitk::MaskAndCutRoiImageFilter::New(); + mitk::Image::Pointer image = dynamic_cast(m_SegmentationInputNode->GetData()); + + if (image.IsNull()) + return; + + roiFilter->SetInput(image); + roiFilter->SetRegionOfInterest(node->GetData()); + roiFilter->Update(); + + mitk::DataNode::Pointer tmpNode = mitk::DataNode::New(); + tmpNode->SetData(roiFilter->GetOutput()); + + m_SegmentationInputNode = tmpNode; + } + else + m_SegmentationInputNode = m_ReferenceDataNode; + + this->ResetPreviewNode(); + this->InitiateToolByInput(); + this->UpdatePreview(); +} + +void mitk::AutoSegmentationWithPreviewTool::OnTimePointChanged() +{ + if (m_IsTimePointChangeAware && m_PreviewNode.IsNotNull() && m_SegmentationInputNode.IsNotNull()) + { + const auto timePoint = mitk::RenderingManager::GetInstance()->GetTimeNavigationController()->GetSelectedTimePoint(); + + const bool isStaticSegOnDynamicImage = m_PreviewNode->GetData()->GetTimeSteps() == 1 && m_SegmentationInputNode->GetData()->GetTimeSteps() > 1; + if (timePoint!=m_LastTimePointOfUpdate && (isStaticSegOnDynamicImage || m_LazyDynamicPreviews)) + { //we only need to update either because we are lazzy + //or because we have a static segmentation with a dynamic image + this->UpdatePreview(); + } + } +} + +void mitk::AutoSegmentationWithPreviewTool::UpdatePreview(bool ignoreLazyPreviewSetting) +{ + const auto inputImage = this->GetSegmentationInput(); + auto previewImage = this->GetPreviewSegmentation(); + int progress_steps = 200; + + this->UpdatePrepare(); + + const auto timePoint = mitk::RenderingManager::GetInstance()->GetTimeNavigationController()->GetSelectedTimePoint(); + + try + { + this->CurrentlyBusy.Send(true); + if (nullptr != inputImage && nullptr != previewImage) + { + m_ProgressCommand->AddStepsToDo(progress_steps); + + if (previewImage->GetTimeSteps() > 1 && (ignoreLazyPreviewSetting || !m_LazyDynamicPreviews)) + { + for (unsigned int timeStep = 0; timeStep < inputImage->GetTimeSteps(); ++timeStep) + { + auto feedBackImage3D = this->Get3DImage(inputImage, timeStep); + + this->DoUpdatePreview(feedBackImage3D, previewImage, timeStep); + } + } + else + { + auto feedBackImage3D = this->Get3DImageByTimePoint(inputImage, timePoint); + auto timeStep = previewImage->GetTimeGeometry()->TimePointToTimeStep(timePoint); + + this->DoUpdatePreview(feedBackImage3D, previewImage, timeStep); + } + RenderingManager::GetInstance()->RequestUpdateAll(); + } + } + catch (itk::ExceptionObject & excep) + { + MITK_ERROR << "Exception caught: " << excep.GetDescription(); + + m_ProgressCommand->SetProgress(progress_steps); + + std::string msg = excep.GetDescription(); + ErrorMessage.Send(msg); + } + catch (...) + { + m_ProgressCommand->SetProgress(progress_steps); + CurrentlyBusy.Send(false); + throw; + } + + this->UpdateCleanUp(); + m_LastTimePointOfUpdate = timePoint; + m_ProgressCommand->SetProgress(progress_steps); + CurrentlyBusy.Send(false); +} + +void mitk::AutoSegmentationWithPreviewTool::UpdatePrepare() +{ + // default implementation does nothing + //reimplement in derived classes for special behavior +} + +void mitk::AutoSegmentationWithPreviewTool::UpdateCleanUp() +{ + // default implementation does nothing + //reimplement in derived classes for special behavior +} + +mitk::TimePointType mitk::AutoSegmentationWithPreviewTool::GetLastTimePointOfUpdate() const +{ + return m_LastTimePointOfUpdate; +} diff --git a/Modules/Segmentation/Interactions/mitkAutoSegmentationWithPreviewTool.h b/Modules/Segmentation/Interactions/mitkAutoSegmentationWithPreviewTool.h new file mode 100644 index 0000000000..70dc2d9dba --- /dev/null +++ b/Modules/Segmentation/Interactions/mitkAutoSegmentationWithPreviewTool.h @@ -0,0 +1,149 @@ +/*============================================================================ + +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 mitkAutoSegmentationWithPreviewTool_h_Included +#define mitkAutoSegmentationWithPreviewTool_h_Included + +#include "mitkAutoSegmentationTool.h" +#include "mitkCommon.h" +#include "mitkDataNode.h" +#include "mitkToolCommand.h" +#include + +namespace mitk +{ + /** + \brief Base class for any auto segmentation tool that provides a preview of the new segmentation. + + This tool class implements a lot basic logic to handle auto segmentation tools with preview, + Time point and ROI support. Derived classes will ask to update the segmentation preview if needed + (e.g. because the ROI or the current time point has changed) or because derived tools + indicated the need of update them self. + This class also then take care to properly transfer a confirmed preview into the segementation + result. + + \ingroup ToolManagerEtAl + \sa mitk::Tool + \sa QmitkInteractiveSegmentation + */ + class MITKSEGMENTATION_EXPORT AutoSegmentationWithPreviewTool : public AutoSegmentationTool + { + public: + + mitkClassMacro(AutoSegmentationWithPreviewTool, AutoSegmentationTool); + + void Activated() override; + void Deactivated() override; + + void ConfirmSegmentation(); + + itkSetMacro(CreateAllTimeSteps, bool); + itkGetMacro(CreateAllTimeSteps, bool); + itkBooleanMacro(CreateAllTimeSteps); + + itkSetMacro(KeepActiveAfterAccept, bool); + itkGetMacro(KeepActiveAfterAccept, bool); + itkBooleanMacro(KeepActiveAfterAccept); + + itkSetMacro(IsTimePointChangeAware, bool); + itkGetMacro(IsTimePointChangeAware, bool); + itkBooleanMacro(IsTimePointChangeAware); + + bool CanHandle(const BaseData* referenceData, const BaseData* workingData) const override; + + /** Triggers the actualization of the preview + * @param ignoreLazyPreviewSetting If set true UpdatePreview will always + * generate the preview for all time steps. If set to false, UpdatePreview + * will regard the setting of m_LazyDynamicPreviews. + * To define the update generation for time steps implement DoUpdatePreview. + * To alter what should be done directly before or after the update of the preview, + * reimplement UpdatePrepare() or UpdateCleanUp().*/ + void UpdatePreview(bool ignoreLazyPreviewSetting = false); + + protected: + mitk::ToolCommand::Pointer m_ProgressCommand; + + /** Member is always called if GetSegmentationInput() has changed + * (e.g. because a new ROI was defined, or on activation) to give derived + * classes the posibility to initiate their state accordingly. + * Reimplement this function to implement special behavior. + */ + virtual void InitiateToolByInput(); + + virtual void UpdatePrepare(); + virtual void UpdateCleanUp(); + + /** This function does the real work. Here the preview for a given + * input image should be computed and stored in the also passed + * preview image at the passed time step. + */ + virtual void DoUpdatePreview(const Image* inputAtTimeStep, Image* previewImage, TimeStepType timeStep) = 0; + + AutoSegmentationWithPreviewTool(bool lazyDynamicPreviews = false); + ~AutoSegmentationWithPreviewTool() override; + + /** Returns the image that contains the preview of the current segmentation. + * Returns null if the node is not set or does not contain an image.*/ + Image* GetPreviewSegmentation(); + DataNode* GetPreviewSegmentationNode(); + + /** Returns the input that should be used for any segmentation/preview or tool update. + * It is either the data of ReferenceDataNode itself or a part of it defined by a ROI mask + * provided by the tool manager. Derived classes should regard this as the relevant + * input data for any processing. + * Returns null if the node is not set or does not contain an image.*/ + const Image* GetSegmentationInput() const; + + /** Returns the image that is provided by the ReferenceDataNode. + * Returns null if the node is not set or does not contain an image.*/ + const Image* GetReferenceData() const; + + /** Resets the preview node so it is empty and ready to be filled by the tool*/ + void ResetPreviewNode(); + + TimePointType GetLastTimePointOfUpdate() const; + + private: + void TransferImageAtTimeStep(const Image* sourceImage, Image* destinationImage, const TimeStepType timeStep); + + void CreateResultSegmentationFromPreview(); + + void OnRoiDataChanged(); + void OnTimePointChanged(); + + DataNode::Pointer m_PreviewNode; + /** The reference data recieved from tool manager when tool was activated.*/ + DataNode::Pointer m_ReferenceDataNode; + DataNode::Pointer m_SegmentationInputNode; + + /** Indicates if Accepting the threshold should transfer/create the segmentations + of all time steps (true) or only of the currently selected timepoint (false).*/ + bool m_CreateAllTimeSteps = false; + + /** Indicates if the tool should kept active after accepting the segmentation or not.*/ + bool m_KeepActiveAfterAccept = false; + + /** Relevant if the working data / preview image has multiple time steps (dynamic segmentations). + * This flag has to be set by derived classes accordingly to there way to generate dynamic previews. + * If LazyDynamicPreview is true, the tool generates only the preview for the current time step. + * so it always has to update the preview if current time point has changed and it has to (re)compute + * the whole previewnode Indicates it a tool */ + bool m_LazyDynamicPreviews = false; + + bool m_IsTimePointChangeAware = true; + + TimePointType m_LastTimePointOfUpdate = 0.; + }; + +} // namespace + +#endif diff --git a/Modules/Segmentation/files.cmake b/Modules/Segmentation/files.cmake index 676362200a..1deb993fd5 100644 --- a/Modules/Segmentation/files.cmake +++ b/Modules/Segmentation/files.cmake @@ -1,116 +1,117 @@ set(CPP_FILES Algorithms/mitkCalculateSegmentationVolume.cpp Algorithms/mitkContourModelSetToImageFilter.cpp Algorithms/mitkContourSetToPointSetFilter.cpp Algorithms/mitkContourUtils.cpp Algorithms/mitkCorrectorAlgorithm.cpp Algorithms/mitkDiffImageApplier.cpp Algorithms/mitkDiffSliceOperation.cpp Algorithms/mitkDiffSliceOperationApplier.cpp Algorithms/mitkFeatureBasedEdgeDetectionFilter.cpp Algorithms/mitkImageLiveWireContourModelFilter.cpp Algorithms/mitkImageToContourFilter.cpp #Algorithms/mitkImageToContourModelFilter.cpp Algorithms/mitkImageToLiveWireContourFilter.cpp Algorithms/mitkManualSegmentationToSurfaceFilter.cpp Algorithms/mitkOtsuSegmentationFilter.cpp Algorithms/mitkOverwriteDirectedPlaneImageFilter.cpp Algorithms/mitkOverwriteSliceImageFilter.cpp Algorithms/mitkSegmentationObjectFactory.cpp Algorithms/mitkShapeBasedInterpolationAlgorithm.cpp Algorithms/mitkShowSegmentationAsSmoothedSurface.cpp Algorithms/mitkShowSegmentationAsSurface.cpp Algorithms/mitkVtkImageOverwrite.cpp Controllers/mitkSegmentationInterpolationController.cpp Controllers/mitkToolManager.cpp Controllers/mitkSegmentationModuleActivator.cpp Controllers/mitkToolManagerProvider.cpp DataManagement/mitkContour.cpp DataManagement/mitkContourSet.cpp DataManagement/mitkExtrudedContour.cpp Interactions/mitkAdaptiveRegionGrowingTool.cpp Interactions/mitkAddContourTool.cpp Interactions/mitkAutoCropTool.cpp Interactions/mitkAutoSegmentationTool.cpp + Interactions/mitkAutoSegmentationWithPreviewTool.cpp Interactions/mitkBinaryThresholdBaseTool.cpp Interactions/mitkBinaryThresholdTool.cpp Interactions/mitkBinaryThresholdULTool.cpp Interactions/mitkCalculateGrayValueStatisticsTool.cpp Interactions/mitkCalculateVolumetryTool.cpp Interactions/mitkContourModelInteractor.cpp Interactions/mitkContourModelLiveWireInteractor.cpp Interactions/mitkLiveWireTool2D.cpp Interactions/mitkContourTool.cpp Interactions/mitkCorrectorTool2D.cpp Interactions/mitkCreateSurfaceTool.cpp Interactions/mitkDrawPaintbrushTool.cpp Interactions/mitkErasePaintbrushTool.cpp Interactions/mitkEraseRegionTool.cpp Interactions/mitkFastMarchingTool.cpp Interactions/mitkFastMarchingTool3D.cpp Interactions/mitkFeedbackContourTool.cpp Interactions/mitkFillRegionTool.cpp Interactions/mitkOtsuTool3D.cpp Interactions/mitkPaintbrushTool.cpp Interactions/mitkPixelManipulationTool.cpp Interactions/mitkRegionGrowingTool.cpp Interactions/mitkSegmentationsProcessingTool.cpp Interactions/mitkSetRegionTool.cpp Interactions/mitkSegTool2D.cpp Interactions/mitkSubtractContourTool.cpp Interactions/mitkTool.cpp Interactions/mitkToolCommand.cpp Interactions/mitkWatershedTool.cpp Interactions/mitkPickingTool.cpp Interactions/mitkSegmentationInteractor.cpp #SO Rendering/mitkContourMapper2D.cpp Rendering/mitkContourSetMapper2D.cpp Rendering/mitkContourSetVtkMapper3D.cpp Rendering/mitkContourVtkMapper3D.cpp SegmentationUtilities/BooleanOperations/mitkBooleanOperation.cpp SegmentationUtilities/MorphologicalOperations/mitkMorphologicalOperations.cpp #Added from ML Controllers/mitkSliceBasedInterpolationController.cpp Algorithms/mitkSurfaceStampImageFilter.cpp ) set(RESOURCE_FILES Add_48x48.png Add_Cursor_32x32.png Correction_48x48.png Correction_Cursor_32x32.png Erase_48x48.png Erase_Cursor_32x32.png FastMarching_48x48.png FastMarching_Cursor_32x32.png Fill_48x48.png Fill_Cursor_32x32.png LiveWire_48x48.png LiveWire_Cursor_32x32.png Otsu_48x48.png Paint_48x48.png Paint_Cursor_32x32.png Pick_48x48.png RegionGrowing_48x48.png RegionGrowing_Cursor_32x32.png Subtract_48x48.png Subtract_Cursor_32x32.png Threshold_48x48.png TwoThresholds_48x48.png Watershed_48x48.png Watershed_Cursor_32x32.png Wipe_48x48.png Wipe_Cursor_32x32.png Interactions/dummy.xml Interactions/LiveWireTool.xml Interactions/FastMarchingTool.xml Interactions/PressMoveRelease.xml Interactions/PressMoveReleaseAndPointSetting.xml Interactions/PressMoveReleaseWithCTRLInversion.xml Interactions/PressMoveReleaseWithCTRLInversionAllMouseMoves.xml Interactions/SegmentationToolsConfig.xml Interactions/ContourModelModificationConfig.xml Interactions/ContourModelModificationInteractor.xml )