diff --git a/Modules/SceneSerialization/src/mitkSceneReaderV1.cpp b/Modules/SceneSerialization/src/mitkSceneReaderV1.cpp
index 155f8f20f4..c55bf4e681 100644
--- a/Modules/SceneSerialization/src/mitkSceneReaderV1.cpp
+++ b/Modules/SceneSerialization/src/mitkSceneReaderV1.cpp
@@ -1,430 +1,457 @@
 /*============================================================================
 
 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 "mitkSceneReaderV1.h"
 #include "Poco/Path.h"
 #include "mitkBaseRenderer.h"
 #include "mitkIOUtil.h"
 #include "mitkProgressBar.h"
 #include "mitkPropertyListDeserializer.h"
 #include "mitkSerializerMacros.h"
 #include <mitkUIDManipulator.h>
 #include <mitkRenderingModeProperty.h>
 #include <tinyxml2.h>
 
 MITK_REGISTER_SERIALIZER(SceneReaderV1)
 
 namespace
 {
   typedef std::pair<mitk::DataNode::Pointer, std::list<std::string>> NodesAndParentsPair;
 
   bool NodeSortByLayerIsLessThan(const NodesAndParentsPair &left, const NodesAndParentsPair &right)
   {
     if (left.first.IsNotNull() && right.first.IsNotNull())
     {
       int leftLayer;
       int rightLayer;
       if (left.first->GetIntProperty("layer", leftLayer) && right.first->GetIntProperty("layer", rightLayer))
       {
         return leftLayer < rightLayer;
       }
       else
       {
         // fall back to name sort
         return left.first->GetName() < right.first->GetName();
       }
     }
 
     // in all other cases, fall back to stupid pointer comparison
     // this is not reasonable but at least answers the sorting
     // question clearly
     return left.first.GetPointer() < right.first.GetPointer();
   }
+
+  // This is a workaround until we are able to save time-related information in an
+  // actual file format of surfaces.
+  void ApplyProportionalTimeGeometryProperties(mitk::BaseData* data)
+  {
+    if (nullptr == data)
+      return;
+
+    auto properties = data->GetPropertyList();
+
+    if (properties.IsNull())
+      return;
+
+    auto* geometry = dynamic_cast<mitk::ProportionalTimeGeometry*>(data->GetTimeGeometry());
+
+    if (nullptr == geometry)
+      return;
+
+    float value = 0.0f;
+
+    if (properties->GetFloatProperty("ProportionalTimeGeometry.FirstTimePoint", value))
+      geometry->SetFirstTimePoint(value);
+
+    if (properties->GetFloatProperty("ProportionalTimeGeometry.StepDuration", value))
+      geometry->SetStepDuration(value);
+  }
 }
 
 bool mitk::SceneReaderV1::LoadScene(tinyxml2::XMLDocument &document, const std::string &workingDirectory, DataStorage *storage)
 {
   assert(storage);
   bool error(false);
 
   // TODO prepare to detect errors (such as cycles) from wrongly written or edited xml files
 
   // Get number of elements to initialze progress bar
   //   1. if there is a <data type="..." file="..."> element,
   //        - construct a name for the appropriate serializer
   //        - try to instantiate this serializer via itk object factory
   //        - if serializer could be created, use it to read the file into a BaseData object
   //        - if successful, call the new node's SetData(..)
 
   // create a node for the tag "data" and test if node was created
   typedef std::vector<mitk::DataNode::Pointer> DataNodeVector;
   DataNodeVector DataNodes;
   unsigned int listSize = 0;
   for (auto *element = document.FirstChildElement("node"); element != nullptr;
        element = element->NextSiblingElement("node"))
   {
     ++listSize;
   }
 
   ProgressBar::GetInstance()->AddStepsToDo(listSize * 2);
 
   for (auto *element = document.FirstChildElement("node"); element != nullptr;
        element = element->NextSiblingElement("node"))
   {
     DataNodes.push_back(LoadBaseDataFromDataTag(element->FirstChildElement("data"), workingDirectory, error));
     ProgressBar::GetInstance()->Progress();
   }
 
   // iterate all nodes
   // first level nodes should be <node> elements
   auto nit = DataNodes.begin();
   for (auto *element = document.FirstChildElement("node"); element != nullptr || nit != DataNodes.end();
        element = element->NextSiblingElement("node"), ++nit)
   {
     mitk::DataNode::Pointer node = *nit;
     // in case dataXmlElement is valid test whether it containts the "properties" child tag
     // and process further if and only if yes
     auto *dataXmlElement = element->FirstChildElement("data");
     if (dataXmlElement && dataXmlElement->FirstChildElement("properties"))
     {
       auto *baseDataElement = dataXmlElement->FirstChildElement("properties");
       if (node->GetData())
       {
         DecorateBaseDataWithProperties(node->GetData(), baseDataElement, workingDirectory);
+        ApplyProportionalTimeGeometryProperties(node->GetData());
       }
       else
       {
         MITK_WARN << "BaseData properties stored in scene file, but BaseData could not be read" << std::endl;
       }
     }
 
     //   2. check child nodes
     const char *uida = element->Attribute("UID");
     std::string uid("");
 
     if (uida)
     {
       uid = uida;
       m_NodeForID[uid] = node.GetPointer();
       m_IDForNode[node.GetPointer()] = uid;
     }
     else
     {
       MITK_ERROR << "No UID found for current node. Node will have no parents.";
       error = true;
     }
 
     //   3. if there are <properties> nodes,
     //        - instantiate the appropriate PropertyListDeSerializer
     //        - use them to construct PropertyList objects
     //        - add these properties to the node (if necessary, use renderwindow name)
     bool success = DecorateNodeWithProperties(node, element, workingDirectory);
     if (!success)
     {
       MITK_ERROR << "Could not load properties for node.";
       error = true;
     }
 
     // remember node for later adding to DataStorage
     m_OrderedNodePairs.push_back(std::make_pair(node, std::list<std::string>()));
 
     //   4. if there are <source> elements, remember parent objects
     for (auto *source = element->FirstChildElement("source"); source != nullptr;
          source = source->NextSiblingElement("source"))
     {
       const char *sourceUID = source->Attribute("UID");
       if (sourceUID)
       {
         m_OrderedNodePairs.back().second.push_back(std::string(sourceUID));
       }
     }
 
     ProgressBar::GetInstance()->Progress();
   } // end for all <node>
 
   // sort our nodes by their "layer" property
   // (to be inserted in that order)
   m_OrderedNodePairs.sort(&NodeSortByLayerIsLessThan);
 
   // remove all unknown parent UIDs
   for (auto nodesIter = m_OrderedNodePairs.begin(); nodesIter != m_OrderedNodePairs.end();
        ++nodesIter)
   {
     for (auto parentsIter = nodesIter->second.begin();
          parentsIter != nodesIter->second.end();)
     {
       if (m_NodeForID.find(*parentsIter) == m_NodeForID.end())
       {
         parentsIter = nodesIter->second.erase(parentsIter);
         MITK_WARN << "Found a DataNode with unknown parents. Will add it to DataStorage without any parent objects.";
         error = true;
       }
       else
       {
         ++parentsIter;
       }
     }
   }
 
   // repeat the following loop ...
   //   ... for all created nodes
   unsigned int lastMapSize(0);
   while (lastMapSize !=
          m_OrderedNodePairs
            .size()) // this is to prevent infinite loops; each iteration must at least add one node to DataStorage
   {
     lastMapSize = m_OrderedNodePairs.size();
 
     // iterate (layer) ordered nodes backwards
     // we insert the highest layers first
     for (auto nodesIter = m_OrderedNodePairs.begin(); nodesIter != m_OrderedNodePairs.end();
          ++nodesIter)
     {
       bool addThisNode(true);
 
       // if any parent node is not yet in DataStorage, skip node for now and check later
       for (auto parentsIter = nodesIter->second.begin();
            parentsIter != nodesIter->second.end();
            ++parentsIter)
       {
         if (!storage->Exists(m_NodeForID[*parentsIter]))
         {
           addThisNode = false;
           break;
         }
       }
 
       if (addThisNode)
       {
         DataStorage::SetOfObjects::Pointer parents = DataStorage::SetOfObjects::New();
         for (auto parentsIter = nodesIter->second.begin();
              parentsIter != nodesIter->second.end();
              ++parentsIter)
         {
           parents->push_back(m_NodeForID[*parentsIter]);
         }
 
         // if all parents are found in datastorage (or are unknown), add node to DataStorage
         storage->Add(nodesIter->first, parents);
 
         // remove this node from m_OrderedNodePairs
         m_OrderedNodePairs.erase(nodesIter);
 
         // break this for loop because iterators are probably invalid
         break;
       }
     }
   }
 
   // All nodes that are still in m_OrderedNodePairs at this point are not part of a proper directed graph structure.
   // We'll add such nodes without any parent information.
   for (auto nodesIter = m_OrderedNodePairs.begin(); nodesIter != m_OrderedNodePairs.end();
        ++nodesIter)
   {
     storage->Add(nodesIter->first);
     MITK_WARN << "Encountered node that is not part of a directed graph structure. Will be added to DataStorage "
                  "without parents.";
     error = true;
   }
 
   return !error;
 }
 
 mitk::DataNode::Pointer mitk::SceneReaderV1::LoadBaseDataFromDataTag(const tinyxml2::XMLElement *dataElement,
                                                                      const std::string &workingDirectory,
                                                                      bool &error)
 {
   DataNode::Pointer node;
 
   if (dataElement)
   {
     const char *filename = dataElement->Attribute("file");
     if (filename && strlen(filename) != 0)
     {
       try
       {
         std::vector<BaseData::Pointer> baseData = IOUtil::Load(workingDirectory + Poco::Path::separator() + filename);
         if (baseData.size() > 1)
         {
           MITK_WARN << "Discarding multiple base data results from " << filename << " except the first one.";
         }
         node = DataNode::New();
         node->SetData(baseData.front());
       }
       catch (std::exception &e)
       {
         MITK_ERROR << "Error during attempt to read '" << filename << "'. Exception says: " << e.what();
         error = true;
       }
 
       if (node.IsNull())
       {
         MITK_ERROR << "Error during attempt to read '" << filename << "'. Factory returned nullptr object.";
         error = true;
       }
     }
 
     const char* dataUID = dataElement->Attribute("UID");
     if (!error && dataUID != nullptr)
     {
       UIDManipulator manip(node->GetData());
       manip.SetUID(dataUID);
     }
   }
 
   // in case there was no <data> element we create a new empty node (for appending a propertylist later)
   if (node.IsNull())
   {
     node = DataNode::New();
   }
 
   return node;
 }
 
 void mitk::SceneReaderV1::ClearNodePropertyListWithExceptions(DataNode &node, PropertyList &propertyList)
 {
   // Basically call propertyList.Clear(), but implement exceptions (see bug 19354)
   BaseData *data = node.GetData();
 
   PropertyList::Pointer propertiesToKeep = PropertyList::New();
 
   if (dynamic_cast<Image *>(data))
   {
     /*
       Older scene files (before changes of bug 17547) could contain
       a RenderingMode property with value "LevelWindow_Color".
       Since bug 17547 this value has been removed and replaced by
       the default value LookupTable_LevelWindow_Color.
 
       This new default value does only result in "black-to-white"
       CT images (or others) if there is a corresponding lookup
       table. Such a lookup table is provided as a default value
       by the Image mapper. Since that value was never present in
       older scene files, we do well in not removing the new
       default value here. Otherwise the mapper would fall back
       to another default which is all the colors of the rainbow :-(
     */
     BaseProperty::Pointer lutProperty = propertyList.GetProperty("LookupTable");
     propertiesToKeep->SetProperty("LookupTable", lutProperty);
 
     /*
       Older scene files (before changes of T14807) may contain
       multi-component images without the "Image.Displayed Component"
       property.
 
       As the treatment as multi-component image and the corresponding
       visualization options hinges on that property we should not delete
       it, if it was added by the mapper.
 
       This is a fix for the issue reported in T19919.
     */
     BaseProperty::Pointer compProperty = propertyList.GetProperty("Image.Displayed Component");
     if (compProperty.IsNotNull())
     {
       propertiesToKeep->SetProperty("Image.Displayed Component", compProperty);
     }
   }
 
   propertyList.Clear();
 
   propertyList.ConcatenatePropertyList(propertiesToKeep);
 }
 
 bool mitk::SceneReaderV1::DecorateNodeWithProperties(DataNode *node,
                                                      const tinyxml2::XMLElement *nodeElement,
                                                      const std::string &workingDirectory)
 {
   assert(node);
   assert(nodeElement);
   bool error(false);
 
   for (auto *properties = nodeElement->FirstChildElement("properties"); properties != nullptr;
        properties = properties->NextSiblingElement("properties"))
   {
     const char *propertiesfilea(properties->Attribute("file"));
     std::string propertiesfile(propertiesfilea ? propertiesfilea : "");
 
     const char *renderwindowa(properties->Attribute("renderwindow"));
     std::string renderwindow(renderwindowa ? renderwindowa : "");
 
     PropertyList::Pointer propertyList =
       node->GetPropertyList(renderwindow); // DataNode implementation always returns a propertylist
     ClearNodePropertyListWithExceptions(*node, *propertyList);
 
     // use deserializer to construct new properties
     PropertyListDeserializer::Pointer deserializer = PropertyListDeserializer::New();
 
     deserializer->SetFilename(workingDirectory + Poco::Path::separator() + propertiesfile);
     bool success = deserializer->Deserialize();
     error |= !success;
     PropertyList::Pointer readProperties = deserializer->GetOutput();
 
     if (readProperties.IsNotNull())
     {
       propertyList->ConcatenatePropertyList(readProperties, true); // true = replace
     }
     else
     {
       MITK_ERROR << "Property list reader did not return a property list. This is an implementation error. Please tell "
                     "your developer.";
       error = true;
     }
   }
 
   return !error;
 }
 
 bool mitk::SceneReaderV1::DecorateBaseDataWithProperties(BaseData::Pointer data,
                                                          const tinyxml2::XMLElement *baseDataNodeElem,
                                                          const std::string &workingDir)
 {
   // check given variables, initialize error variable
   assert(baseDataNodeElem);
   bool error(false);
 
   // get the file name stored in the <properties ...> tag
   const char *baseDataPropertyFile(baseDataNodeElem->Attribute("file"));
   // check if the filename was found
   if (baseDataPropertyFile)
   {
     // PropertyList::Pointer dataPropList = data->GetPropertyList();
 
     PropertyListDeserializer::Pointer propertyDeserializer = PropertyListDeserializer::New();
 
     // initialize the property reader
     propertyDeserializer->SetFilename(workingDir + Poco::Path::separator() + baseDataPropertyFile);
     bool ioSuccess = propertyDeserializer->Deserialize();
     error = !ioSuccess;
 
     // get the output
     PropertyList::Pointer inProperties = propertyDeserializer->GetOutput();
 
     // store the read-in properties to the given node or throw error otherwise
     if (inProperties.IsNotNull())
     {
       data->SetPropertyList(inProperties);
     }
     else
     {
       MITK_ERROR << "The property deserializer did not return a (valid) property list.";
       error = true;
     }
   }
   else
   {
     MITK_ERROR << "Function DecorateBaseDataWithProperties(...) called with false XML element. \n \t ->Given element "
                   "does not contain a 'file' attribute. \n";
     error = true;
   }
 
   return !error;
 }
diff --git a/Modules/SegmentationUI/Qmitk/QmitkSlicesInterpolator.cpp b/Modules/SegmentationUI/Qmitk/QmitkSlicesInterpolator.cpp
index 4f1e494523..6820efbc3b 100644
--- a/Modules/SegmentationUI/Qmitk/QmitkSlicesInterpolator.cpp
+++ b/Modules/SegmentationUI/Qmitk/QmitkSlicesInterpolator.cpp
@@ -1,1399 +1,1405 @@
 /*============================================================================
 
 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 "QmitkSlicesInterpolator.h"
 
 #include "QmitkSelectableGLWidget.h"
 #include "QmitkStdMultiWidget.h"
 
 #include "mitkApplyDiffImageOperation.h"
 #include "mitkColorProperty.h"
 #include "mitkCoreObjectFactory.h"
 #include "mitkDiffImageApplier.h"
 #include "mitkInteractionConst.h"
 #include "mitkLevelWindowProperty.h"
 #include "mitkOperationEvent.h"
 #include "mitkOverwriteSliceImageFilter.h"
 #include "mitkProgressBar.h"
 #include "mitkProperties.h"
 #include "mitkRenderingManager.h"
 #include "mitkSegTool2D.h"
 #include "mitkSliceNavigationController.h"
 #include "mitkSurfaceToImageFilter.h"
 #include "mitkToolManager.h"
 #include "mitkUndoController.h"
 #include <mitkExtractSliceFilter.h>
 #include <mitkImageReadAccessor.h>
 #include <mitkImageTimeSelector.h>
 #include <mitkImageWriteAccessor.h>
 #include <mitkPlaneProposer.h>
 #include <mitkUnstructuredGridClusteringFilter.h>
 #include <mitkVtkImageOverwrite.h>
 
 #include <itkCommand.h>
 
 #include <QCheckBox>
 #include <QCursor>
 #include <QMenu>
 #include <QMessageBox>
 #include <QPushButton>
 #include <QVBoxLayout>
 
 #include <vtkPolyVertex.h>
 #include <vtkUnstructuredGrid.h>
 
 #include <array>
 
 namespace
 {
   template <typename T = mitk::BaseData>
   itk::SmartPointer<T> GetData(const mitk::DataNode* dataNode)
   {
     return nullptr != dataNode
       ? dynamic_cast<T*>(dataNode->GetData())
       : nullptr;
   }
 }
 
 float SURFACE_COLOR_RGB[3] = {0.49f, 1.0f, 0.16f};
 
 const std::map<QAction *, mitk::SliceNavigationController *> QmitkSlicesInterpolator::createActionToSliceDimension()
 {
   std::map<QAction *, mitk::SliceNavigationController *> actionToSliceDimension;
   foreach (mitk::SliceNavigationController *slicer, m_ControllerToDeleteObserverTag.keys())
   {
     actionToSliceDimension[new QAction(QString::fromStdString(slicer->GetViewDirectionAsString()), nullptr)] = slicer;
   }
 
   return actionToSliceDimension;
 }
 
 QmitkSlicesInterpolator::QmitkSlicesInterpolator(QWidget *parent, const char * /*name*/)
   : QWidget(parent),
     //    ACTION_TO_SLICEDIMENSION( createActionToSliceDimension() ),
     m_Interpolator(mitk::SegmentationInterpolationController::New()),
     m_SurfaceInterpolator(mitk::SurfaceInterpolationController::GetInstance()),
     m_ToolManager(nullptr),
     m_Initialized(false),
     m_LastSNC(nullptr),
     m_LastSliceIndex(0),
     m_2DInterpolationEnabled(false),
     m_3DInterpolationEnabled(false),
     m_FirstRun(true)
 {
   m_GroupBoxEnableExclusiveInterpolationMode = new QGroupBox("Interpolation", this);
 
   QVBoxLayout *vboxLayout = new QVBoxLayout(m_GroupBoxEnableExclusiveInterpolationMode);
 
   m_EdgeDetector = mitk::FeatureBasedEdgeDetectionFilter::New();
   m_PointScorer = mitk::PointCloudScoringFilter::New();
 
   m_CmbInterpolation = new QComboBox(m_GroupBoxEnableExclusiveInterpolationMode);
   m_CmbInterpolation->addItem("Disabled");
   m_CmbInterpolation->addItem("2-Dimensional");
   m_CmbInterpolation->addItem("3-Dimensional");
   vboxLayout->addWidget(m_CmbInterpolation);
 
   m_BtnApply2D = new QPushButton("Confirm for single slice", m_GroupBoxEnableExclusiveInterpolationMode);
   vboxLayout->addWidget(m_BtnApply2D);
 
   m_BtnApplyForAllSlices2D = new QPushButton("Confirm for all slices", m_GroupBoxEnableExclusiveInterpolationMode);
   vboxLayout->addWidget(m_BtnApplyForAllSlices2D);
 
   m_BtnApply3D = new QPushButton("Confirm", m_GroupBoxEnableExclusiveInterpolationMode);
   vboxLayout->addWidget(m_BtnApply3D);
 
   // T28261
   // m_BtnSuggestPlane = new QPushButton("Suggest a plane", m_GroupBoxEnableExclusiveInterpolationMode);
   // vboxLayout->addWidget(m_BtnSuggestPlane);
 
   m_BtnReinit3DInterpolation = new QPushButton("Reinit Interpolation", m_GroupBoxEnableExclusiveInterpolationMode);
   vboxLayout->addWidget(m_BtnReinit3DInterpolation);
 
   m_ChkShowPositionNodes = new QCheckBox("Show Position Nodes", m_GroupBoxEnableExclusiveInterpolationMode);
   vboxLayout->addWidget(m_ChkShowPositionNodes);
 
   this->HideAllInterpolationControls();
 
   connect(m_CmbInterpolation, SIGNAL(currentIndexChanged(int)), this, SLOT(OnInterpolationMethodChanged(int)));
   connect(m_BtnApply2D, SIGNAL(clicked()), this, SLOT(OnAcceptInterpolationClicked()));
   connect(m_BtnApplyForAllSlices2D, SIGNAL(clicked()), this, SLOT(OnAcceptAllInterpolationsClicked()));
   connect(m_BtnApply3D, SIGNAL(clicked()), this, SLOT(OnAccept3DInterpolationClicked()));
 
   // T28261
   // connect(m_BtnSuggestPlane, SIGNAL(clicked()), this, SLOT(OnSuggestPlaneClicked()));
 
   connect(m_BtnReinit3DInterpolation, SIGNAL(clicked()), this, SLOT(OnReinit3DInterpolation()));
   connect(m_ChkShowPositionNodes, SIGNAL(toggled(bool)), this, SLOT(OnShowMarkers(bool)));
   connect(m_ChkShowPositionNodes, SIGNAL(toggled(bool)), this, SIGNAL(SignalShowMarkerNodes(bool)));
 
   QHBoxLayout *layout = new QHBoxLayout(this);
   layout->addWidget(m_GroupBoxEnableExclusiveInterpolationMode);
   this->setLayout(layout);
 
   itk::ReceptorMemberCommand<QmitkSlicesInterpolator>::Pointer command =
     itk::ReceptorMemberCommand<QmitkSlicesInterpolator>::New();
   command->SetCallbackFunction(this, &QmitkSlicesInterpolator::OnInterpolationInfoChanged);
   InterpolationInfoChangedObserverTag = m_Interpolator->AddObserver(itk::ModifiedEvent(), command);
 
   itk::ReceptorMemberCommand<QmitkSlicesInterpolator>::Pointer command2 =
     itk::ReceptorMemberCommand<QmitkSlicesInterpolator>::New();
   command2->SetCallbackFunction(this, &QmitkSlicesInterpolator::OnSurfaceInterpolationInfoChanged);
   SurfaceInterpolationInfoChangedObserverTag = m_SurfaceInterpolator->AddObserver(itk::ModifiedEvent(), command2);
 
   // feedback node and its visualization properties
   m_FeedbackNode = mitk::DataNode::New();
   mitk::CoreObjectFactory::GetInstance()->SetDefaultProperties(m_FeedbackNode);
 
   m_FeedbackNode->SetProperty("binary", mitk::BoolProperty::New(true));
   m_FeedbackNode->SetProperty("outline binary", mitk::BoolProperty::New(true));
   m_FeedbackNode->SetProperty("color", mitk::ColorProperty::New(255.0, 255.0, 0.0));
   m_FeedbackNode->SetProperty("texture interpolation", mitk::BoolProperty::New(false));
   m_FeedbackNode->SetProperty("layer", mitk::IntProperty::New(20));
   m_FeedbackNode->SetProperty("levelwindow", mitk::LevelWindowProperty::New(mitk::LevelWindow(0, 1)));
   m_FeedbackNode->SetProperty("name", mitk::StringProperty::New("Interpolation feedback"));
   m_FeedbackNode->SetProperty("opacity", mitk::FloatProperty::New(0.8));
   m_FeedbackNode->SetProperty("helper object", mitk::BoolProperty::New(true));
 
   m_InterpolatedSurfaceNode = mitk::DataNode::New();
   m_InterpolatedSurfaceNode->SetProperty("color", mitk::ColorProperty::New(SURFACE_COLOR_RGB));
   m_InterpolatedSurfaceNode->SetProperty("name", mitk::StringProperty::New("Surface Interpolation feedback"));
   m_InterpolatedSurfaceNode->SetProperty("opacity", mitk::FloatProperty::New(0.5));
   m_InterpolatedSurfaceNode->SetProperty("line width", mitk::FloatProperty::New(4.0f));
   m_InterpolatedSurfaceNode->SetProperty("includeInBoundingBox", mitk::BoolProperty::New(false));
   m_InterpolatedSurfaceNode->SetProperty("helper object", mitk::BoolProperty::New(true));
   m_InterpolatedSurfaceNode->SetVisibility(false);
 
   m_3DContourNode = mitk::DataNode::New();
   m_3DContourNode->SetProperty("color", mitk::ColorProperty::New(0.0, 0.0, 0.0));
   m_3DContourNode->SetProperty("hidden object", mitk::BoolProperty::New(true));
   m_3DContourNode->SetProperty("name", mitk::StringProperty::New("Drawn Contours"));
   m_3DContourNode->SetProperty("material.representation", mitk::VtkRepresentationProperty::New(VTK_WIREFRAME));
   m_3DContourNode->SetProperty("material.wireframeLineWidth", mitk::FloatProperty::New(2.0f));
   m_3DContourNode->SetProperty("3DContourContainer", mitk::BoolProperty::New(true));
   m_3DContourNode->SetProperty("includeInBoundingBox", mitk::BoolProperty::New(false));
   m_3DContourNode->SetVisibility(
     false, mitk::BaseRenderer::GetInstance(mitk::BaseRenderer::GetRenderWindowByName("stdmulti.widget0")));
   m_3DContourNode->SetVisibility(
     false, mitk::BaseRenderer::GetInstance(mitk::BaseRenderer::GetRenderWindowByName("stdmulti.widget1")));
   m_3DContourNode->SetVisibility(
     false, mitk::BaseRenderer::GetInstance(mitk::BaseRenderer::GetRenderWindowByName("stdmulti.widget2")));
   m_3DContourNode->SetVisibility(
     false, mitk::BaseRenderer::GetInstance(mitk::BaseRenderer::GetRenderWindowByName("stdmulti.widget3")));
 
   QWidget::setContentsMargins(0, 0, 0, 0);
   if (QWidget::layout() != nullptr)
   {
     QWidget::layout()->setContentsMargins(0, 0, 0, 0);
   }
 
   // For running 3D Interpolation in background
   // create a QFuture and a QFutureWatcher
 
   connect(&m_Watcher, SIGNAL(started()), this, SLOT(StartUpdateInterpolationTimer()));
   connect(&m_Watcher, SIGNAL(finished()), this, SLOT(OnSurfaceInterpolationFinished()));
   connect(&m_Watcher, SIGNAL(finished()), this, SLOT(StopUpdateInterpolationTimer()));
   m_Timer = new QTimer(this);
   connect(m_Timer, SIGNAL(timeout()), this, SLOT(ChangeSurfaceColor()));
 }
 
 void QmitkSlicesInterpolator::SetDataStorage(mitk::DataStorage::Pointer storage)
 {
   if (m_DataStorage == storage)
   {
     return;
   }
 
   if (m_DataStorage.IsNotNull())
   {
     m_DataStorage->RemoveNodeEvent.RemoveListener(
       mitk::MessageDelegate1<QmitkSlicesInterpolator, const mitk::DataNode*>(this, &QmitkSlicesInterpolator::NodeRemoved)
     );
   }
 
   m_DataStorage = storage;
   m_SurfaceInterpolator->SetDataStorage(storage);
 
   if (m_DataStorage.IsNotNull())
   {
     m_DataStorage->RemoveNodeEvent.AddListener(
       mitk::MessageDelegate1<QmitkSlicesInterpolator, const mitk::DataNode*>(this, &QmitkSlicesInterpolator::NodeRemoved)
     );
   }
 }
 
 mitk::DataStorage *QmitkSlicesInterpolator::GetDataStorage()
 {
   if (m_DataStorage.IsNotNull())
   {
     return m_DataStorage;
   }
   else
   {
     return nullptr;
   }
 }
 
 void QmitkSlicesInterpolator::Initialize(mitk::ToolManager *toolManager,
                                          const QList<mitk::SliceNavigationController *> &controllers)
 {
   Q_ASSERT(!controllers.empty());
 
   if (m_Initialized)
   {
     // remove old observers
     Uninitialize();
   }
 
   m_ToolManager = toolManager;
 
   if (m_ToolManager)
   {
     // set enabled only if a segmentation is selected
     mitk::DataNode *node = m_ToolManager->GetWorkingData(0);
     QWidget::setEnabled(node != nullptr);
 
     // react whenever the set of selected segmentation changes
     m_ToolManager->WorkingDataChanged +=
       mitk::MessageDelegate<QmitkSlicesInterpolator>(this, &QmitkSlicesInterpolator::OnToolManagerWorkingDataModified);
     m_ToolManager->ReferenceDataChanged += mitk::MessageDelegate<QmitkSlicesInterpolator>(
       this, &QmitkSlicesInterpolator::OnToolManagerReferenceDataModified);
 
     // 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<QmitkSlicesInterpolator>::Pointer deleteCommand =
         itk::MemberCommand<QmitkSlicesInterpolator>::New();
       deleteCommand->SetCallbackFunction(this, &QmitkSlicesInterpolator::OnSliceNavigationControllerDeleted);
       m_ControllerToDeleteObserverTag.insert(slicer, slicer->AddObserver(itk::DeleteEvent(), deleteCommand));
 
       itk::MemberCommand<QmitkSlicesInterpolator>::Pointer timeChangedCommand =
         itk::MemberCommand<QmitkSlicesInterpolator>::New();
       timeChangedCommand->SetCallbackFunction(this, &QmitkSlicesInterpolator::OnTimeChanged);
       m_ControllerToTimeObserverTag.insert(
         slicer, slicer->AddObserver(mitk::SliceNavigationController::TimeGeometryEvent(nullptr, 0), timeChangedCommand));
 
       itk::MemberCommand<QmitkSlicesInterpolator>::Pointer sliceChangedCommand =
         itk::MemberCommand<QmitkSlicesInterpolator>::New();
       sliceChangedCommand->SetCallbackFunction(this, &QmitkSlicesInterpolator::OnSliceChanged);
       m_ControllerToSliceObserverTag.insert(
         slicer, slicer->AddObserver(mitk::SliceNavigationController::GeometrySliceEvent(nullptr, 0), sliceChangedCommand));
     }
     ACTION_TO_SLICEDIMENSION = createActionToSliceDimension();
   }
 
   m_Initialized = true;
 }
 
 void QmitkSlicesInterpolator::Uninitialize()
 {
   if (m_ToolManager.IsNotNull())
   {
     m_ToolManager->WorkingDataChanged -=
       mitk::MessageDelegate<QmitkSlicesInterpolator>(this, &QmitkSlicesInterpolator::OnToolManagerWorkingDataModified);
     m_ToolManager->ReferenceDataChanged -= mitk::MessageDelegate<QmitkSlicesInterpolator>(
       this, &QmitkSlicesInterpolator::OnToolManagerReferenceDataModified);
   }
 
   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));
   }
 
   ACTION_TO_SLICEDIMENSION.clear();
 
   m_ToolManager = nullptr;
 
   m_Initialized = false;
 }
 
 QmitkSlicesInterpolator::~QmitkSlicesInterpolator()
 {
   if (m_Initialized)
   {
     // remove old observers
     Uninitialize();
   }
 
   WaitForFutures();
 
   if (m_DataStorage.IsNotNull())
   {
     m_DataStorage->RemoveNodeEvent.RemoveListener(
       mitk::MessageDelegate1<QmitkSlicesInterpolator, const mitk::DataNode*>(this, &QmitkSlicesInterpolator::NodeRemoved)
     );
     if (m_DataStorage->Exists(m_3DContourNode))
       m_DataStorage->Remove(m_3DContourNode);
     if (m_DataStorage->Exists(m_InterpolatedSurfaceNode))
       m_DataStorage->Remove(m_InterpolatedSurfaceNode);
   }
 
   // remove observer
   m_Interpolator->RemoveObserver(InterpolationInfoChangedObserverTag);
   m_SurfaceInterpolator->RemoveObserver(SurfaceInterpolationInfoChangedObserverTag);
 
   delete m_Timer;
 }
 
 /**
 External enableization...
 */
 void QmitkSlicesInterpolator::setEnabled(bool enable)
 {
   QWidget::setEnabled(enable);
 
   // Set the gui elements of the different interpolation modi enabled
   if (enable)
   {
     if (m_2DInterpolationEnabled)
     {
       this->Show2DInterpolationControls(true);
       m_Interpolator->Activate2DInterpolation(true);
     }
     else if (m_3DInterpolationEnabled)
     {
       this->Show3DInterpolationControls(true);
       this->Show3DInterpolationResult(true);
     }
   }
   // Set all gui elements of the interpolation disabled
   else
   {
     this->HideAllInterpolationControls();
     this->Show3DInterpolationResult(false);
   }
 }
 
 void QmitkSlicesInterpolator::On2DInterpolationEnabled(bool status)
 {
   OnInterpolationActivated(status);
   m_Interpolator->Activate2DInterpolation(status);
 }
 
 void QmitkSlicesInterpolator::On3DInterpolationEnabled(bool status)
 {
   On3DInterpolationActivated(status);
 }
 
 void QmitkSlicesInterpolator::OnInterpolationDisabled(bool status)
 {
   if (status)
   {
     OnInterpolationActivated(!status);
     On3DInterpolationActivated(!status);
     this->Show3DInterpolationResult(false);
   }
 }
 
 void QmitkSlicesInterpolator::HideAllInterpolationControls()
 {
   this->Show2DInterpolationControls(false);
   this->Show3DInterpolationControls(false);
 }
 
 void QmitkSlicesInterpolator::Show2DInterpolationControls(bool show)
 {
   m_BtnApply2D->setVisible(show);
   m_BtnApplyForAllSlices2D->setVisible(show);
 }
 
 void QmitkSlicesInterpolator::Show3DInterpolationControls(bool show)
 {
   m_BtnApply3D->setVisible(show);
 
   // T28261
   // m_BtnSuggestPlane->setVisible(show);
 
   m_ChkShowPositionNodes->setVisible(show);
   m_BtnReinit3DInterpolation->setVisible(show);
 }
 
 void QmitkSlicesInterpolator::OnInterpolationMethodChanged(int index)
 {
   switch (index)
   {
     case 0: // Disabled
       m_GroupBoxEnableExclusiveInterpolationMode->setTitle("Interpolation");
       this->HideAllInterpolationControls();
       this->OnInterpolationActivated(false);
       this->On3DInterpolationActivated(false);
       this->Show3DInterpolationResult(false);
       m_Interpolator->Activate2DInterpolation(false);
       break;
 
     case 1: // 2D
       m_GroupBoxEnableExclusiveInterpolationMode->setTitle("Interpolation (Enabled)");
       this->HideAllInterpolationControls();
       this->Show2DInterpolationControls(true);
       this->OnInterpolationActivated(true);
       this->On3DInterpolationActivated(false);
       m_Interpolator->Activate2DInterpolation(true);
       break;
 
     case 2: // 3D
       m_GroupBoxEnableExclusiveInterpolationMode->setTitle("Interpolation (Enabled)");
       this->HideAllInterpolationControls();
       this->Show3DInterpolationControls(true);
       this->OnInterpolationActivated(false);
       this->On3DInterpolationActivated(true);
       m_Interpolator->Activate2DInterpolation(false);
       break;
 
     default:
       MITK_ERROR << "Unknown interpolation method!";
       m_CmbInterpolation->setCurrentIndex(0);
       break;
   }
 }
 
 void QmitkSlicesInterpolator::OnShowMarkers(bool state)
 {
   mitk::DataStorage::SetOfObjects::ConstPointer allContourMarkers =
     m_DataStorage->GetSubset(mitk::NodePredicateProperty::New("isContourMarker", mitk::BoolProperty::New(true)));
 
   for (mitk::DataStorage::SetOfObjects::ConstIterator it = allContourMarkers->Begin(); it != allContourMarkers->End();
        ++it)
   {
     it->Value()->SetProperty("helper object", mitk::BoolProperty::New(!state));
   }
 }
 
 void QmitkSlicesInterpolator::OnToolManagerWorkingDataModified()
 {
   if (m_ToolManager->GetWorkingData(0) != nullptr)
   {
     m_Segmentation = dynamic_cast<mitk::Image *>(m_ToolManager->GetWorkingData(0)->GetData());
     m_BtnReinit3DInterpolation->setEnabled(true);
   }
   else
   {
     // If no workingdata is set, remove the interpolation feedback
     this->GetDataStorage()->Remove(m_FeedbackNode);
     m_FeedbackNode->SetData(nullptr);
     this->GetDataStorage()->Remove(m_3DContourNode);
     m_3DContourNode->SetData(nullptr);
     this->GetDataStorage()->Remove(m_InterpolatedSurfaceNode);
     m_InterpolatedSurfaceNode->SetData(nullptr);
     m_BtnReinit3DInterpolation->setEnabled(false);
     return;
   }
   // Updating the current selected segmentation for the 3D interpolation
   SetCurrentContourListID();
 
   if (m_2DInterpolationEnabled)
   {
     OnInterpolationActivated(true); // re-initialize if needed
   }
   this->CheckSupportedImageDimension();
 }
 
 void QmitkSlicesInterpolator::OnToolManagerReferenceDataModified()
 {
 }
 
 void QmitkSlicesInterpolator::OnTimeChanged(itk::Object *sender, const itk::EventObject &e)
 {
   // Check if we really have a GeometryTimeEvent
   if (!dynamic_cast<const mitk::SliceNavigationController::GeometryTimeEvent *>(&e))
     return;
 
   mitk::SliceNavigationController *slicer = dynamic_cast<mitk::SliceNavigationController *>(sender);
   Q_ASSERT(slicer);
 
   const auto timePoint = slicer->GetSelectedTimePoint();
   m_TimePoints[slicer] = timePoint;
 
   m_SurfaceInterpolator->SetCurrentTimePoint(timePoint);
 
   if (m_LastSNC == slicer)
   {
     slicer->SendSlice(); // will trigger a new interpolation
   }
 }
 
 void QmitkSlicesInterpolator::OnSliceChanged(itk::Object *sender, const itk::EventObject &e)
 {
   // Check whether we really have a GeometrySliceEvent
   if (!dynamic_cast<const mitk::SliceNavigationController::GeometrySliceEvent *>(&e))
     return;
 
   mitk::SliceNavigationController *slicer = dynamic_cast<mitk::SliceNavigationController *>(sender);
 
   if (TranslateAndInterpolateChangedSlice(e, slicer))
   {
     slicer->GetRenderer()->RequestUpdate();
   }
 }
 
 bool QmitkSlicesInterpolator::TranslateAndInterpolateChangedSlice(const itk::EventObject &e,
                                                                   mitk::SliceNavigationController *slicer)
 {
   if (!m_2DInterpolationEnabled)
     return false;
 
   try
   {
     const mitk::SliceNavigationController::GeometrySliceEvent &event =
       dynamic_cast<const mitk::SliceNavigationController::GeometrySliceEvent &>(e);
 
     mitk::TimeGeometry *tsg = event.GetTimeGeometry();
     if (tsg && m_TimePoints.contains(slicer) && tsg->IsValidTimePoint(m_TimePoints[slicer]))
     {
       mitk::SlicedGeometry3D *slicedGeometry =
         dynamic_cast<mitk::SlicedGeometry3D *>(tsg->GetGeometryForTimePoint(m_TimePoints[slicer]).GetPointer());
       if (slicedGeometry)
       {
         m_LastSNC = slicer;
         mitk::PlaneGeometry *plane =
           dynamic_cast<mitk::PlaneGeometry *>(slicedGeometry->GetPlaneGeometry(event.GetPos()));
         if (plane)
           Interpolate(plane, m_TimePoints[slicer], slicer);
         return true;
       }
     }
   }
   catch (const std::bad_cast &)
   {
     return false; // so what
   }
 
   return false;
 }
 
 void QmitkSlicesInterpolator::Interpolate(mitk::PlaneGeometry *plane,
                                           mitk::TimePointType timePoint,
                                           mitk::SliceNavigationController *slicer)
 {
   if (m_ToolManager)
   {
     mitk::DataNode *node = m_ToolManager->GetWorkingData(0);
     if (node)
     {
       m_Segmentation = dynamic_cast<mitk::Image *>(node->GetData());
       if (m_Segmentation)
       {
         if (!m_Segmentation->GetTimeGeometry()->IsValidTimePoint(timePoint))
         {
           MITK_WARN << "Cannot interpolate segmentation. Passed time point is not within the time bounds of WorkingImage. Time point: " << timePoint;
           return;
         }
         const auto timeStep = m_Segmentation->GetTimeGeometry()->TimePointToTimeStep(timePoint);
 
         int clickedSliceDimension(-1);
         int clickedSliceIndex(-1);
 
         // calculate real slice position, i.e. slice of the image and not slice of the TimeSlicedGeometry
         mitk::SegTool2D::DetermineAffectedImageSlice(m_Segmentation, plane, clickedSliceDimension, clickedSliceIndex);
 
         mitk::Image::Pointer interpolation =
           m_Interpolator->Interpolate(clickedSliceDimension, clickedSliceIndex, plane, timeStep);
         m_FeedbackNode->SetData(interpolation);
 
         m_LastSNC = slicer;
         m_LastSliceIndex = clickedSliceIndex;
       }
     }
   }
 }
 
 void QmitkSlicesInterpolator::OnSurfaceInterpolationFinished()
 {
   mitk::Surface::Pointer interpolatedSurface = m_SurfaceInterpolator->GetInterpolationResult();
   mitk::DataNode *workingNode = m_ToolManager->GetWorkingData(0);
 
   if (interpolatedSurface.IsNotNull() && workingNode &&
       workingNode->IsVisible(
         mitk::BaseRenderer::GetInstance(mitk::BaseRenderer::GetRenderWindowByName("stdmulti.widget2"))))
   {
     m_BtnApply3D->setEnabled(true);
 
     // T28261
     // m_BtnSuggestPlane->setEnabled(true);
 
     m_InterpolatedSurfaceNode->SetData(interpolatedSurface);
     m_3DContourNode->SetData(m_SurfaceInterpolator->GetContoursAsSurface());
 
     this->Show3DInterpolationResult(true);
 
     if (!m_DataStorage->Exists(m_InterpolatedSurfaceNode))
     {
       m_DataStorage->Add(m_InterpolatedSurfaceNode);
     }
     if (!m_DataStorage->Exists(m_3DContourNode))
     {
       m_DataStorage->Add(m_3DContourNode, workingNode);
     }
   }
   else if (interpolatedSurface.IsNull())
   {
     m_BtnApply3D->setEnabled(false);
 
     // T28261
     // m_BtnSuggestPlane->setEnabled(false);
 
     if (m_DataStorage->Exists(m_InterpolatedSurfaceNode))
     {
       this->Show3DInterpolationResult(false);
     }
   }
 
   m_BtnReinit3DInterpolation->setEnabled(true);
 
   foreach (mitk::SliceNavigationController *slicer, m_ControllerToTimeObserverTag.keys())
   {
     slicer->GetRenderer()->RequestUpdate();
   }
 }
 
 void QmitkSlicesInterpolator::OnAcceptInterpolationClicked()
 {
   if (m_Segmentation && m_FeedbackNode->GetData())
   {
     // Make sure that for reslicing and overwriting the same alogrithm is used. We can specify the mode of the vtk
     // reslicer
     vtkSmartPointer<mitkVtkImageOverwrite> reslice = vtkSmartPointer<mitkVtkImageOverwrite>::New();
 
     // Set slice as input
     mitk::Image::Pointer slice = dynamic_cast<mitk::Image *>(m_FeedbackNode->GetData());
     reslice->SetInputSlice(slice->GetSliceData()->GetVtkImageAccessor(slice)->GetVtkImageData());
     // set overwrite mode to true to write back to the image volume
     reslice->SetOverwriteMode(true);
     reslice->Modified();
 
     const auto timePoint = m_LastSNC->GetSelectedTimePoint();
     if (!m_Segmentation->GetTimeGeometry()->IsValidTimePoint(timePoint))
     {
       MITK_WARN << "Cannot accept interpolation. Time point selected by SliceNavigationController is not within the time bounds of segmentation. Time point: " << timePoint;
       return;
     }
 
     mitk::ExtractSliceFilter::Pointer extractor = mitk::ExtractSliceFilter::New(reslice);
     extractor->SetInput(m_Segmentation);
     const auto timeStep = m_Segmentation->GetTimeGeometry()->TimePointToTimeStep(timePoint);
     extractor->SetTimeStep(timeStep);
     extractor->SetWorldGeometry(m_LastSNC->GetCurrentPlaneGeometry());
     extractor->SetVtkOutputRequest(true);
     extractor->SetResliceTransformByGeometry(m_Segmentation->GetTimeGeometry()->GetGeometryForTimeStep(timeStep));
 
     extractor->Modified();
     extractor->Update();
 
     // the image was modified within the pipeline, but not marked so
     m_Segmentation->Modified();
     m_Segmentation->GetVtkImageData()->Modified();
 
     m_FeedbackNode->SetData(nullptr);
     mitk::RenderingManager::GetInstance()->RequestUpdateAll();
   }
 }
 
 void QmitkSlicesInterpolator::AcceptAllInterpolations(mitk::SliceNavigationController *slicer)
 {
   /*
    * What exactly is done here:
    * 1. We create an empty diff image for the current segmentation
    * 2. All interpolated slices are written into the diff image
    * 3. Then the diffimage is applied to the original segmentation
    */
   if (m_Segmentation)
   {
     mitk::Image::Pointer image3D = m_Segmentation;
     unsigned int timeStep(0);
     const auto timePoint = slicer->GetSelectedTimePoint();
     if (m_Segmentation->GetDimension() == 4)
     {
       if (!m_Segmentation->GetTimeGeometry()->IsValidTimePoint(timePoint))
       {
         MITK_WARN << "Cannot accept all interpolations. Time point selected by passed SliceNavigationController is not within the time bounds of segmentation. Time point: " << timePoint;
         return;
       }
 
       timeStep = m_Segmentation->GetTimeGeometry()->TimePointToTimeStep(timePoint);
       mitk::ImageTimeSelector::Pointer timeSelector = mitk::ImageTimeSelector::New();
       timeSelector->SetInput(m_Segmentation);
       timeSelector->SetTimeNr(timeStep);
       timeSelector->Update();
       image3D = timeSelector->GetOutput();
     }
     // create a empty diff image for the undo operation
     mitk::Image::Pointer diffImage = mitk::Image::New();
     diffImage->Initialize(image3D);
 
     // Create scope for ImageWriteAccessor so that the accessor is destroyed
     // after the image is initialized. Otherwise later image access will lead to an error
     {
       mitk::ImageWriteAccessor imAccess(diffImage);
 
       // Set all pixels to zero
       mitk::PixelType pixelType(mitk::MakeScalarPixelType<mitk::Tool::DefaultSegmentationDataType>());
 
       // For legacy purpose support former pixel type of segmentations (before multilabel)
       if (m_Segmentation->GetImageDescriptor()->GetChannelDescriptor().GetPixelType().GetComponentType() ==
           itk::ImageIOBase::UCHAR)
       {
         pixelType = mitk::MakeScalarPixelType<unsigned char>();
       }
 
       memset(imAccess.GetData(),
              0,
              (pixelType.GetBpe() >> 3) * diffImage->GetDimension(0) * diffImage->GetDimension(1) *
                diffImage->GetDimension(2));
     }
 
     // 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();
 
     int sliceDimension(-1);
     int sliceIndex(-1);
     mitk::SegTool2D::DetermineAffectedImageSlice(m_Segmentation, reslicePlane, sliceDimension, sliceIndex);
 
     unsigned int zslices = m_Segmentation->GetDimension(sliceDimension);
     mitk::ProgressBar::GetInstance()->AddStepsToDo(zslices);
 
     mitk::Point3D origin = reslicePlane->GetOrigin();
     unsigned int totalChangedSlices(0);
 
     for (unsigned int sliceIndex = 0; sliceIndex < zslices; ++sliceIndex)
     {
       // Transforming the current origin of the reslice plane
       // so that it matches the one of the next slice
       m_Segmentation->GetSlicedGeometry()->WorldToIndex(origin, origin);
       origin[sliceDimension] = sliceIndex;
       m_Segmentation->GetSlicedGeometry()->IndexToWorld(origin, origin);
       reslicePlane->SetOrigin(origin);
       // Set the slice as 'input'
       mitk::Image::Pointer interpolation =
         m_Interpolator->Interpolate(sliceDimension, sliceIndex, reslicePlane, timeStep);
 
       if (interpolation.IsNotNull()) // we don't check if interpolation is necessary/sensible - but m_Interpolator does
       {
         // Setting up the reslicing pipeline which allows us to write the interpolation results back into
         // the image volume
         vtkSmartPointer<mitkVtkImageOverwrite> reslice = vtkSmartPointer<mitkVtkImageOverwrite>::New();
 
         // set overwrite mode to true to write back to the image volume
         reslice->SetInputSlice(interpolation->GetSliceData()->GetVtkImageAccessor(interpolation)->GetVtkImageData());
         reslice->SetOverwriteMode(true);
         reslice->Modified();
 
         mitk::ExtractSliceFilter::Pointer diffslicewriter = mitk::ExtractSliceFilter::New(reslice);
         diffslicewriter->SetInput(diffImage);
         diffslicewriter->SetTimeStep(0);
         diffslicewriter->SetWorldGeometry(reslicePlane);
         diffslicewriter->SetVtkOutputRequest(true);
         diffslicewriter->SetResliceTransformByGeometry(diffImage->GetTimeGeometry()->GetGeometryForTimeStep(0));
 
         diffslicewriter->Modified();
         diffslicewriter->Update();
         ++totalChangedSlices;
       }
       mitk::ProgressBar::GetInstance()->Progress();
     }
     mitk::RenderingManager::GetInstance()->RequestUpdateAll();
 
     if (totalChangedSlices > 0)
     {
       // store undo stack items
       if (true)
       {
         // create do/undo operations
         mitk::ApplyDiffImageOperation *doOp =
           new mitk::ApplyDiffImageOperation(mitk::OpTEST, m_Segmentation, diffImage, timeStep);
         mitk::ApplyDiffImageOperation *undoOp =
           new mitk::ApplyDiffImageOperation(mitk::OpTEST, m_Segmentation, diffImage, timeStep);
         undoOp->SetFactor(-1.0);
         std::stringstream comment;
         comment << "Confirm all interpolations (" << totalChangedSlices << ")";
         mitk::OperationEvent *undoStackItem =
           new mitk::OperationEvent(mitk::DiffImageApplier::GetInstanceForUndo(), doOp, undoOp, comment.str());
         mitk::OperationEvent::IncCurrGroupEventId();
         mitk::OperationEvent::IncCurrObjectEventId();
         mitk::UndoController::GetCurrentUndoModel()->SetOperationEvent(undoStackItem);
 
         // acutally apply the changes here to the original image
         mitk::DiffImageApplier::GetInstanceForUndo()->ExecuteOperation(doOp);
       }
     }
 
     m_FeedbackNode->SetData(nullptr);
     mitk::RenderingManager::GetInstance()->RequestUpdateAll();
   }
 }
 
 void QmitkSlicesInterpolator::FinishInterpolation(mitk::SliceNavigationController *slicer)
 {
   // this redirect is for calling from outside
 
   if (slicer == nullptr)
     OnAcceptAllInterpolationsClicked();
   else
     AcceptAllInterpolations(slicer);
 }
 
 void QmitkSlicesInterpolator::OnAcceptAllInterpolationsClicked()
 {
   QMenu orientationPopup(this);
   std::map<QAction *, mitk::SliceNavigationController *>::const_iterator it;
   for (it = ACTION_TO_SLICEDIMENSION.begin(); it != ACTION_TO_SLICEDIMENSION.end(); it++)
     orientationPopup.addAction(it->first);
 
   connect(&orientationPopup, SIGNAL(triggered(QAction *)), this, SLOT(OnAcceptAllPopupActivated(QAction *)));
 
   orientationPopup.exec(QCursor::pos());
 }
 
 void QmitkSlicesInterpolator::OnAccept3DInterpolationClicked()
 {
   auto referenceImage = GetData<mitk::Image>(m_ToolManager->GetReferenceData(0));
 
   auto* segmentationDataNode = m_ToolManager->GetWorkingData(0);
   auto segmentation = GetData<mitk::Image>(segmentationDataNode);
 
   if (referenceImage.IsNull() || segmentation.IsNull())
     return;
 
   const auto* segmentationGeometry = segmentation->GetTimeGeometry();
   const auto timePoint = m_LastSNC->GetSelectedTimePoint();
 
   if (!referenceImage->GetTimeGeometry()->IsValidTimePoint(timePoint) ||
       !segmentationGeometry->IsValidTimePoint(timePoint))
   {
     MITK_WARN << "Cannot accept interpolation. Current time point is not within the time bounds of the patient image and segmentation.";
     return;
   }
 
   auto interpolatedSurface = GetData<mitk::Surface>(m_InterpolatedSurfaceNode);
 
   if (interpolatedSurface.IsNull())
     return;
 
   auto surfaceToImageFilter = mitk::SurfaceToImageFilter::New();
 
   surfaceToImageFilter->SetImage(referenceImage);
   surfaceToImageFilter->SetMakeOutputBinary(true);
   surfaceToImageFilter->SetUShortBinaryPixelType(itk::ImageIOBase::USHORT == segmentation->GetPixelType().GetComponentType());
   surfaceToImageFilter->SetInput(interpolatedSurface);
   surfaceToImageFilter->Update();
 
   mitk::Image::Pointer interpolatedSegmentation = surfaceToImageFilter->GetOutput();
 
   auto timeStep = interpolatedSegmentation->GetTimeGeometry()->TimePointToTimeStep(timePoint);
   mitk::ImageReadAccessor readAccessor(interpolatedSegmentation, interpolatedSegmentation->GetVolumeData(timeStep));
   const auto* dataPointer = readAccessor.GetData();
 
   if (nullptr == dataPointer)
     return;
 
   timeStep = segmentationGeometry->TimePointToTimeStep(timePoint);
   segmentation->SetVolume(dataPointer, timeStep, 0);
 
   m_CmbInterpolation->setCurrentIndex(0);
   this->Show3DInterpolationResult(false);
 
   std::string name = segmentationDataNode->GetName() + "_3D-interpolation";
   mitk::TimeBounds timeBounds;
 
   if (1 < interpolatedSurface->GetTimeSteps())
   {
     name += "_t" + std::to_string(timeStep);
 
     auto* polyData = vtkPolyData::New();
     polyData->DeepCopy(interpolatedSurface->GetVtkPolyData(timeStep));
 
     auto surface = mitk::Surface::New();
     surface->SetVtkPolyData(polyData);
 
     interpolatedSurface = surface;
     timeBounds = segmentationGeometry->GetTimeBounds(timeStep);
   }
   else
   {
     timeBounds = segmentationGeometry->GetTimeBounds(0);
   }
 
   auto* surfaceGeometry = static_cast<mitk::ProportionalTimeGeometry*>(interpolatedSurface->GetTimeGeometry());
   surfaceGeometry->SetFirstTimePoint(timeBounds[0]);
   surfaceGeometry->SetStepDuration(timeBounds[1] - timeBounds[0]);
 
+  // Typical file formats for surfaces do not save any time-related information. As a workaround at least for MITK scene files, we have the
+  // possibility to seralize this information as properties.
+
+  interpolatedSurface->SetProperty("ProportionalTimeGeometry.FirstTimePoint", mitk::FloatProperty::New(surfaceGeometry->GetFirstTimePoint()));
+  interpolatedSurface->SetProperty("ProportionalTimeGeometry.StepDuration", mitk::FloatProperty::New(surfaceGeometry->GetStepDuration()));
+
   auto interpolatedSurfaceDataNode = mitk::DataNode::New();
 
   interpolatedSurfaceDataNode->SetData(interpolatedSurface);
   interpolatedSurfaceDataNode->SetName(name);
   interpolatedSurfaceDataNode->SetOpacity(0.7f);
 
   std::array<float, 3> rgb;
   segmentationDataNode->GetColor(rgb.data());
   interpolatedSurfaceDataNode->SetColor(rgb.data());
 
   m_DataStorage->Add(interpolatedSurfaceDataNode, segmentationDataNode);
 }
 
 void ::QmitkSlicesInterpolator::OnSuggestPlaneClicked()
 {
   if (m_PlaneWatcher.isRunning())
     m_PlaneWatcher.waitForFinished();
   m_PlaneFuture = QtConcurrent::run(this, &QmitkSlicesInterpolator::RunPlaneSuggestion);
   m_PlaneWatcher.setFuture(m_PlaneFuture);
 }
 
 void ::QmitkSlicesInterpolator::RunPlaneSuggestion()
 {
   if (m_FirstRun)
     mitk::ProgressBar::GetInstance()->AddStepsToDo(7);
   else
     mitk::ProgressBar::GetInstance()->AddStepsToDo(3);
 
   m_EdgeDetector->SetSegmentationMask(m_Segmentation);
   m_EdgeDetector->SetInput(dynamic_cast<mitk::Image *>(m_ToolManager->GetReferenceData(0)->GetData()));
   m_EdgeDetector->Update();
 
   mitk::UnstructuredGrid::Pointer uGrid = mitk::UnstructuredGrid::New();
   uGrid->SetVtkUnstructuredGrid(m_EdgeDetector->GetOutput()->GetVtkUnstructuredGrid());
 
   mitk::ProgressBar::GetInstance()->Progress();
 
   mitk::Surface::Pointer surface = dynamic_cast<mitk::Surface *>(m_InterpolatedSurfaceNode->GetData());
 
   vtkSmartPointer<vtkPolyData> vtkpoly = surface->GetVtkPolyData();
   vtkSmartPointer<vtkPoints> vtkpoints = vtkpoly->GetPoints();
 
   vtkSmartPointer<vtkUnstructuredGrid> vGrid = vtkSmartPointer<vtkUnstructuredGrid>::New();
   vtkSmartPointer<vtkPolyVertex> verts = vtkSmartPointer<vtkPolyVertex>::New();
 
   verts->GetPointIds()->SetNumberOfIds(vtkpoints->GetNumberOfPoints());
   for (int i = 0; i < vtkpoints->GetNumberOfPoints(); i++)
   {
     verts->GetPointIds()->SetId(i, i);
   }
 
   vGrid->Allocate(1);
   vGrid->InsertNextCell(verts->GetCellType(), verts->GetPointIds());
   vGrid->SetPoints(vtkpoints);
 
   mitk::UnstructuredGrid::Pointer interpolationGrid = mitk::UnstructuredGrid::New();
   interpolationGrid->SetVtkUnstructuredGrid(vGrid);
 
   m_PointScorer->SetInput(0, uGrid);
   m_PointScorer->SetInput(1, interpolationGrid);
   m_PointScorer->Update();
 
   mitk::UnstructuredGrid::Pointer scoredGrid = mitk::UnstructuredGrid::New();
   scoredGrid = m_PointScorer->GetOutput();
 
   mitk::ProgressBar::GetInstance()->Progress();
 
   double spacing = mitk::SurfaceInterpolationController::GetInstance()->GetDistanceImageSpacing();
   mitk::UnstructuredGridClusteringFilter::Pointer clusterFilter = mitk::UnstructuredGridClusteringFilter::New();
   clusterFilter->SetInput(scoredGrid);
   clusterFilter->SetMeshing(false);
   clusterFilter->SetMinPts(4);
   clusterFilter->Seteps(spacing);
   clusterFilter->Update();
 
   mitk::ProgressBar::GetInstance()->Progress();
 
   // Create plane suggestion
   mitk::BaseRenderer::Pointer br =
     mitk::BaseRenderer::GetInstance(mitk::BaseRenderer::GetRenderWindowByName("stdmulti.widget0"));
   mitk::PlaneProposer planeProposer;
   std::vector<mitk::UnstructuredGrid::Pointer> grids = clusterFilter->GetAllClusters();
 
   planeProposer.SetUnstructuredGrids(grids);
   mitk::SliceNavigationController::Pointer snc = br->GetSliceNavigationController();
   planeProposer.SetSliceNavigationController(snc);
   planeProposer.SetUseDistances(true);
   try
   {
     planeProposer.CreatePlaneInfo();
   }
   catch (const mitk::Exception &e)
   {
     MITK_ERROR << e.what();
   }
 
   mitk::RenderingManager::GetInstance()->RequestUpdateAll();
 
   m_FirstRun = false;
 }
 
 void QmitkSlicesInterpolator::OnReinit3DInterpolation()
 {
   mitk::NodePredicateProperty::Pointer pred =
     mitk::NodePredicateProperty::New("3DContourContainer", mitk::BoolProperty::New(true));
   mitk::DataStorage::SetOfObjects::ConstPointer contourNodes =
     m_DataStorage->GetDerivations(m_ToolManager->GetWorkingData(0), pred);
 
   if (contourNodes->Size() != 0)
   {
     m_BtnApply3D->setEnabled(true);
     m_3DContourNode = contourNodes->at(0);
     mitk::Surface::Pointer contours = dynamic_cast<mitk::Surface *>(m_3DContourNode->GetData());
     if (contours)
       mitk::SurfaceInterpolationController::GetInstance()->ReinitializeInterpolation(contours);
     m_BtnReinit3DInterpolation->setEnabled(false);
   }
   else
   {
     m_BtnApply3D->setEnabled(false);
     QMessageBox errorInfo;
     errorInfo.setWindowTitle("Reinitialize surface interpolation");
     errorInfo.setIcon(QMessageBox::Information);
     errorInfo.setText("No contours available for the selected segmentation!");
     errorInfo.exec();
   }
 }
 
 void QmitkSlicesInterpolator::OnAcceptAllPopupActivated(QAction *action)
 {
   try
   {
     std::map<QAction *, mitk::SliceNavigationController *>::const_iterator iter = ACTION_TO_SLICEDIMENSION.find(action);
     if (iter != ACTION_TO_SLICEDIMENSION.end())
     {
       mitk::SliceNavigationController *slicer = iter->second;
       AcceptAllInterpolations(slicer);
     }
   }
   catch (...)
   {
     /* Showing message box with possible memory error */
     QMessageBox errorInfo;
     errorInfo.setWindowTitle("Interpolation Process");
     errorInfo.setIcon(QMessageBox::Critical);
     errorInfo.setText("An error occurred during interpolation. Possible cause: Not enough memory!");
     errorInfo.exec();
 
     // additional error message on std::cerr
     std::cerr << "Ill construction in " __FILE__ " l. " << __LINE__ << std::endl;
   }
 }
 
 void QmitkSlicesInterpolator::OnInterpolationActivated(bool on)
 {
   m_2DInterpolationEnabled = on;
 
   try
   {
     if (m_DataStorage.IsNotNull())
     {
       if (on && !m_DataStorage->Exists(m_FeedbackNode))
       {
         m_DataStorage->Add(m_FeedbackNode);
       }
     }
   }
   catch (...)
   {
     // don't care (double add/remove)
   }
 
   if (m_ToolManager)
   {
     mitk::DataNode *workingNode = m_ToolManager->GetWorkingData(0);
     mitk::DataNode *referenceNode = m_ToolManager->GetReferenceData(0);
     QWidget::setEnabled(workingNode != nullptr);
 
     m_BtnApply2D->setEnabled(on);
     m_FeedbackNode->SetVisibility(on);
 
     if (!on)
     {
       mitk::RenderingManager::GetInstance()->RequestUpdateAll();
       return;
     }
 
     if (workingNode)
     {
       mitk::Image *segmentation = dynamic_cast<mitk::Image *>(workingNode->GetData());
       if (segmentation)
       {
         m_Interpolator->SetSegmentationVolume(segmentation);
 
         if (referenceNode)
         {
           mitk::Image *referenceImage = dynamic_cast<mitk::Image *>(referenceNode->GetData());
           m_Interpolator->SetReferenceVolume(referenceImage); // may be nullptr
         }
       }
     }
   }
 
   UpdateVisibleSuggestion();
 }
 
 void QmitkSlicesInterpolator::Run3DInterpolation()
 {
   m_SurfaceInterpolator->Interpolate();
 }
 
 void QmitkSlicesInterpolator::StartUpdateInterpolationTimer()
 {
   m_Timer->start(500);
 }
 
 void QmitkSlicesInterpolator::StopUpdateInterpolationTimer()
 {
   m_Timer->stop();
   m_InterpolatedSurfaceNode->SetProperty("color", mitk::ColorProperty::New(SURFACE_COLOR_RGB));
   mitk::RenderingManager::GetInstance()->RequestUpdate(
     mitk::BaseRenderer::GetInstance(mitk::BaseRenderer::GetRenderWindowByName("stdmulti.widget3"))->GetRenderWindow());
 }
 
 void QmitkSlicesInterpolator::ChangeSurfaceColor()
 {
   float currentColor[3];
   m_InterpolatedSurfaceNode->GetColor(currentColor);
 
   if (currentColor[2] == SURFACE_COLOR_RGB[2])
   {
     m_InterpolatedSurfaceNode->SetProperty("color", mitk::ColorProperty::New(1.0f, 1.0f, 1.0f));
   }
   else
   {
     m_InterpolatedSurfaceNode->SetProperty("color", mitk::ColorProperty::New(SURFACE_COLOR_RGB));
   }
   m_InterpolatedSurfaceNode->Update();
   mitk::RenderingManager::GetInstance()->RequestUpdate(
     mitk::BaseRenderer::GetInstance(mitk::BaseRenderer::GetRenderWindowByName("stdmulti.widget3"))->GetRenderWindow());
 }
 
 void QmitkSlicesInterpolator::On3DInterpolationActivated(bool on)
 {
   m_3DInterpolationEnabled = on;
 
   this->CheckSupportedImageDimension();
   try
   {
     if (m_DataStorage.IsNotNull() && m_ToolManager && m_3DInterpolationEnabled)
     {
       mitk::DataNode *workingNode = m_ToolManager->GetWorkingData(0);
 
       if (workingNode)
       {
         if ((workingNode->IsVisible(mitk::BaseRenderer::GetInstance(mitk::BaseRenderer::GetRenderWindowByName("stdmulti.widget2")))))
         {
           int ret = QMessageBox::Yes;
 
           if (m_SurfaceInterpolator->EstimatePortionOfNeededMemory() > 0.5)
           {
             QMessageBox msgBox;
             msgBox.setText("Due to short handed system memory the 3D interpolation may be very slow!");
             msgBox.setInformativeText("Are you sure you want to activate the 3D interpolation?");
             msgBox.setStandardButtons(QMessageBox::No | QMessageBox::Yes);
             ret = msgBox.exec();
           }
 
           if (m_Watcher.isRunning())
             m_Watcher.waitForFinished();
 
           if (ret == QMessageBox::Yes)
           {
             m_Future = QtConcurrent::run(this, &QmitkSlicesInterpolator::Run3DInterpolation);
             m_Watcher.setFuture(m_Future);
           }
           else
           {
             m_CmbInterpolation->setCurrentIndex(0);
           }
         }
       }
       else
       {
         QWidget::setEnabled(false);
         m_ChkShowPositionNodes->setEnabled(m_3DInterpolationEnabled);
       }
     }
     if (!m_3DInterpolationEnabled)
     {
       this->Show3DInterpolationResult(false);
       m_BtnApply3D->setEnabled(m_3DInterpolationEnabled);
 
       // T28261
       // m_BtnSuggestPlane->setEnabled(m_3DInterpolationEnabled);
     }
   }
   catch (...)
   {
     MITK_ERROR << "Error with 3D surface interpolation!";
   }
   mitk::RenderingManager::GetInstance()->RequestUpdateAll();
 }
 
 void QmitkSlicesInterpolator::EnableInterpolation(bool on)
 {
   // only to be called from the outside world
   // just a redirection to OnInterpolationActivated
   OnInterpolationActivated(on);
 }
 
 void QmitkSlicesInterpolator::Enable3DInterpolation(bool on)
 {
   // only to be called from the outside world
   // just a redirection to OnInterpolationActivated
   On3DInterpolationActivated(on);
 }
 
 void QmitkSlicesInterpolator::UpdateVisibleSuggestion()
 {
   mitk::RenderingManager::GetInstance()->RequestUpdateAll();
 }
 
 void QmitkSlicesInterpolator::OnInterpolationInfoChanged(const itk::EventObject & /*e*/)
 {
   // something (e.g. undo) changed the interpolation info, we should refresh our display
   UpdateVisibleSuggestion();
 }
 
 void QmitkSlicesInterpolator::OnSurfaceInterpolationInfoChanged(const itk::EventObject & /*e*/)
 {
   if (m_3DInterpolationEnabled)
   {
     if (m_Watcher.isRunning())
       m_Watcher.waitForFinished();
     m_Future = QtConcurrent::run(this, &QmitkSlicesInterpolator::Run3DInterpolation);
     m_Watcher.setFuture(m_Future);
   }
 }
 
 void QmitkSlicesInterpolator::SetCurrentContourListID()
 {
   // New ContourList = hide current interpolation
   Show3DInterpolationResult(false);
 
   if (m_DataStorage.IsNotNull() && m_ToolManager && m_LastSNC)
   {
     mitk::DataNode *workingNode = m_ToolManager->GetWorkingData(0);
 
     if (workingNode)
     {
       QWidget::setEnabled(true);
 
       const auto timePoint = m_LastSNC->GetSelectedTimePoint();
       // In case the time is not valid use 0 to access the time geometry of the working node
       unsigned int time_position = 0;
       if (!workingNode->GetData()->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;
       }
       time_position = workingNode->GetData()->GetTimeGeometry()->TimePointToTimeStep(timePoint);
 
       mitk::Vector3D spacing = workingNode->GetData()->GetGeometry(time_position)->GetSpacing();
       double minSpacing(100);
       double maxSpacing(0);
       for (int i = 0; i < 3; i++)
       {
         if (spacing[i] < minSpacing)
         {
           minSpacing = spacing[i];
         }
         if (spacing[i] > maxSpacing)
         {
           maxSpacing = spacing[i];
         }
       }
 
       m_SurfaceInterpolator->SetMaxSpacing(maxSpacing);
       m_SurfaceInterpolator->SetMinSpacing(minSpacing);
       m_SurfaceInterpolator->SetDistanceImageVolume(50000);
 
       mitk::Image *segmentationImage = dynamic_cast<mitk::Image *>(workingNode->GetData());
 
       m_SurfaceInterpolator->SetCurrentInterpolationSession(segmentationImage);
       m_SurfaceInterpolator->SetCurrentTimePoint(timePoint);
 
       if (m_3DInterpolationEnabled)
       {
         if (m_Watcher.isRunning())
           m_Watcher.waitForFinished();
         m_Future = QtConcurrent::run(this, &QmitkSlicesInterpolator::Run3DInterpolation);
         m_Watcher.setFuture(m_Future);
       }
     }
     else
     {
       QWidget::setEnabled(false);
     }
   }
 }
 
 void QmitkSlicesInterpolator::Show3DInterpolationResult(bool status)
 {
   if (m_InterpolatedSurfaceNode.IsNotNull())
     m_InterpolatedSurfaceNode->SetVisibility(status);
 
   if (m_3DContourNode.IsNotNull())
     m_3DContourNode->SetVisibility(
       status, mitk::BaseRenderer::GetInstance(mitk::BaseRenderer::GetRenderWindowByName("stdmulti.widget3")));
 
   mitk::RenderingManager::GetInstance()->RequestUpdateAll();
 }
 
 void QmitkSlicesInterpolator::CheckSupportedImageDimension()
 {
   if (m_ToolManager->GetWorkingData(0))
     m_Segmentation = dynamic_cast<mitk::Image *>(m_ToolManager->GetWorkingData(0)->GetData());
 
   /*if (m_3DInterpolationEnabled && m_Segmentation && m_Segmentation->GetDimension() != 3)
   {
     QMessageBox info;
     info.setWindowTitle("3D Interpolation Process");
     info.setIcon(QMessageBox::Information);
     info.setText("3D Interpolation is only supported for 3D images at the moment!");
     info.exec();
     m_CmbInterpolation->setCurrentIndex(0);
   }*/
 }
 
 void QmitkSlicesInterpolator::OnSliceNavigationControllerDeleted(const itk::Object *sender,
                                                                  const itk::EventObject & /*e*/)
 {
   // Don't know how to avoid const_cast here?!
   mitk::SliceNavigationController *slicer =
     dynamic_cast<mitk::SliceNavigationController *>(const_cast<itk::Object *>(sender));
   if (slicer)
   {
     m_ControllerToTimeObserverTag.remove(slicer);
     m_ControllerToSliceObserverTag.remove(slicer);
     m_ControllerToDeleteObserverTag.remove(slicer);
   }
 }
 
 void QmitkSlicesInterpolator::WaitForFutures()
 {
   if (m_Watcher.isRunning())
   {
     m_Watcher.waitForFinished();
   }
 
   if (m_PlaneWatcher.isRunning())
   {
     m_PlaneWatcher.waitForFinished();
   }
 }
 
 void QmitkSlicesInterpolator::NodeRemoved(const mitk::DataNode* node)
 {
   if ((m_ToolManager && m_ToolManager->GetWorkingData(0) == node) ||
       node == m_3DContourNode ||
       node == m_FeedbackNode ||
       node == m_InterpolatedSurfaceNode)
   {
     WaitForFutures();
   }
 }