diff --git a/Modules/ContourModel/IO/mitkContourModelWriter.h b/Modules/ContourModel/IO/mitkContourModelWriter.h
index 3a1b587533..0add146a3b 100644
--- a/Modules/ContourModel/IO/mitkContourModelWriter.h
+++ b/Modules/ContourModel/IO/mitkContourModelWriter.h
@@ -1,171 +1,158 @@
 /*============================================================================
 
 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 _MITK_CONTOURMODEL_WRITER__H_
 #define _MITK_CONTOURMODEL_WRITER__H_
 
 #include <mitkAbstractFileWriter.h>
 #include <mitkContourModel.h>
 
 // DEPRECATED
 #include <mitkTimeGeometry.h>
 
 namespace mitk
 {
   /**
    * @brief XML-based writer for mitk::ContourModels
    *
    * XML-based writer for mitk::ContourModels. Multiple ContourModels can be written in
    * a single XML file by simply setting multiple inputs to the filter.
    *
    * The xml file will look like:
    *
    *   <?xml version="1.0" encoding="utf-8"?>
    *   <contourModel>
    *      <head>
    *        <geometryInfo>
    *        </geometryInfo>
    *      </head>
    *      <data>
    *        <timestep n="0">
    *          <controlPoints>
    *            <point>
    *              <x></x>
    *              <y></y>
    *              <z></z>
    *            </point>
    *          </controlPoint>
    *        </timestep>
    *      </data>
    *    </contourModel>
    *
    * @ingroup MitkContourModelModule
    */
 
-  class TimeSlicedGeometry;
-
   class ContourModelWriter : public mitk::AbstractFileWriter
   {
   public:
     explicit ContourModelWriter(bool writeXMLHeader = true);
     ~ContourModelWriter() override;
 
     using AbstractFileWriter::Write;
     void Write() override;
 
   protected:
     ContourModelWriter(const ContourModelWriter &other);
 
     mitk::ContourModelWriter *Clone() const override;
 
     /**
      * Converts an arbitrary type to a string. The type has to
      * support the << operator. This works fine at least for integral
      * data types as float, int, long etc.
      * @param value the value to convert
      * @returns the string representation of value
      */
     template <typename T>
     std::string ConvertToString(T value);
 
     /**
      * Writes an XML representation of the given point set to
      * an outstream. The XML-Header an root node is not included!
      * @param contourModel the point set to be converted to xml
      * @param out the stream to write to.
      */
     void WriteXML(const mitk::ContourModel *contourModel, std::ostream &out);
 
     /**
     * Writes the geometry information of the TimeGeometry to an outstream.
     * The root tag is not included.
     * @param geometry the TimeGeometry of the contour.
     * @param out the stream to write to.
     */
     void WriteGeometryInformation(const mitk::TimeGeometry *geometry, std::ostream &out);
 
-    /**
-    * Writes the geometry information of the TimeGeometry to an outstream.
-    * The root tag is not included.
-    * @param geometry the TimeGeometry of the contour.
-    * @param out the stream to write to.
-    *
-    * \deprecatedSince{2013_09} Please use TimeGeometry instead of TimeSlicedGeometry. For more information see
-    * http://www.mitk.org/Development/Refactoring%20of%20the%20Geometry%20Classes%20-%20Part%201
-    */
-    DEPRECATED(void WriteGeometryInformation(const mitk::TimeSlicedGeometry *geometry, std::ostream &out));
-
     /**
      * Writes an standard xml header to the given stream.
      * @param file the stream in which the header is written.
      */
     void WriteXMLHeader(std::ostream &file);
 
     /** Write a start element tag */
     void WriteStartElement(const char *const tag, std::ostream &file);
 
     void WriteStartElementWithAttribut(const char *const tag,
                                        std::vector<std::string> attributes,
                                        std::vector<std::string> values,
                                        std::ostream &file);
 
     /**
      * Write an end element tag
      * End-Elements following character data should pass indent = false.
      */
     void WriteEndElement(const char *const tag, std::ostream &file, const bool &indent = true);
 
     /** Write character data inside a tag. */
     void WriteCharacterData(const char *const data, std::ostream &file);
 
     /** Write a start element tag */
     void WriteStartElement(std::string &tag, std::ostream &file);
 
     /** Write an end element tag */
     void WriteEndElement(std::string &tag, std::ostream &file, const bool &indent = true);
 
     /** Write character data inside a tag. */
     void WriteCharacterData(std::string &data, std::ostream &file);
 
     /** Writes empty spaces to the stream according to m_IndentDepth and m_Indent */
     void WriteIndent(std::ostream &file);
 
     bool m_WriteXMLHeader;
 
     unsigned int m_IndentDepth;
 
     unsigned int m_Indent;
 
   public:
     static const char *XML_CONTOURMODEL;
 
     static const char *XML_HEAD;
 
     static const char *XML_GEOMETRY_INFO;
 
     static const char *XML_DATA;
 
     static const char *XML_TIME_STEP;
 
     static const char *XML_CONTROL_POINTS;
 
     static const char *XML_POINT;
 
     static const char *XML_X;
 
     static const char *XML_Y;
 
     static const char *XML_Z;
   };
 }
 
 #endif
diff --git a/Modules/Core/include/mitkBaseRenderer.h b/Modules/Core/include/mitkBaseRenderer.h
index b4015ffd7a..909de3a27c 100644
--- a/Modules/Core/include/mitkBaseRenderer.h
+++ b/Modules/Core/include/mitkBaseRenderer.h
@@ -1,532 +1,523 @@
 /*============================================================================
 
 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 BASERENDERER_H_HEADER_INCLUDED_C1CCA0F4
 #define BASERENDERER_H_HEADER_INCLUDED_C1CCA0F4
 
 #include "mitkCameraRotationController.h"
 #include "mitkDataStorage.h"
 #include "mitkPlaneGeometry.h"
 #include "mitkPlaneGeometryData.h"
 #include "mitkSliceNavigationController.h"
 #include "mitkTimeGeometry.h"
 
 #include "mitkBindDispatcherInteractor.h"
 #include "mitkDispatcher.h"
 
 #include <vtkRenderWindow.h>
 #include <vtkRenderer.h>
 
 #include <map>
 #include <set>
 
-// DEPRECATED
-#include <mitkTimeSlicedGeometry.h>
-
 namespace mitk
 {
   class NavigationController;
   class SliceNavigationController;
   class CameraRotationController;
   class CameraController;
   class DataStorage;
   class Mapper;
   class BaseLocalStorageHandler;
   class KeyEvent;
 
   //##Documentation
   //## @brief Organizes the rendering process
   //##
   //## Organizes the rendering process. A Renderer contains a reference to a
   //## DataStorage and asks the mappers of the data objects to render
   //## the data into the renderwindow it is associated to.
   //##
   //## \#Render() checks if rendering is currently allowed by calling
   //## RenderWindow::PrepareRendering(). Initialization of a rendering context
   //## can also be performed in this method.
   //##
   //## The actual rendering code has been moved to \#Repaint()
   //## Both \#Repaint() and \#Update() are declared protected now.
   //##
   //## Note: Separation of the Repaint and Update processes (rendering vs
   //## creating a vtk prop tree) still needs to be worked on. The whole
   //## rendering process also should be reworked to use VTK based classes for
   //## both 2D and 3D rendering.
   //## @ingroup Renderer
   class MITKCORE_EXPORT BaseRenderer : public itk::Object
   {
   public:
     typedef std::map<vtkRenderWindow *, BaseRenderer *> BaseRendererMapType;
     static BaseRendererMapType baseRendererMap;
 
     static BaseRenderer *GetInstance(vtkRenderWindow *renWin);
     static void AddInstance(vtkRenderWindow *renWin, BaseRenderer *baseRenderer);
     static void RemoveInstance(vtkRenderWindow *renWin);
 
     static BaseRenderer *GetByName(const std::string &name);
     static vtkRenderWindow *GetRenderWindowByName(const std::string &name);
 
 #pragma GCC visibility push(default)
     itkEventMacro(RendererResetEvent, itk::AnyEvent);
 #pragma GCC visibility pop
 
     /** Standard class typedefs. */
     mitkClassMacroItkParent(BaseRenderer, itk::Object);
 
     BaseRenderer(const char *name = nullptr, vtkRenderWindow *renWin = nullptr);
 
     //##Documentation
     //## @brief MapperSlotId defines which kind of mapper (e.g. 2D or 3D) should be used.
     typedef int MapperSlotId;
 
     enum StandardMapperSlot
     {
       Standard2D = 1,
       Standard3D = 2
     };
 
     //##Documentation
     //## @brief Possible view directions for render windows.
     enum class ViewDirection
     {
       AXIAL = 0,
       SAGITTAL,
       CORONAL,
       THREE_D
     };
 
     virtual void SetDataStorage(DataStorage *storage); ///< set the datastorage that will be used for rendering
 
     //##Documentation
     //## return the DataStorage that is used for rendering
     virtual DataStorage::Pointer GetDataStorage() const { return m_DataStorage.GetPointer(); }
     //##Documentation
     //## @brief Access the RenderWindow into which this renderer renders.
     vtkRenderWindow *GetRenderWindow() const { return m_RenderWindow; }
     vtkRenderer *GetVtkRenderer() const { return m_VtkRenderer; }
     //##Documentation
     //## @brief Returns the Dispatcher which handles Events for this BaseRenderer
     Dispatcher::Pointer GetDispatcher() const;
 
     //##Documentation
     //## @brief Default mapper id to use.
     static const MapperSlotId defaultMapper;
 
     //##Documentation
     //## @brief Do the rendering and flush the result.
     virtual void Paint();
 
     //##Documentation
     //## @brief Initialize the RenderWindow. Should only be called from RenderWindow.
     virtual void Initialize();
 
     //##Documentation
     //## @brief Called to inform the renderer that the RenderWindow has been resized.
     virtual void Resize(int w, int h);
 
     //##Documentation
     //## @brief Initialize the renderer with a RenderWindow (@a renderwindow).
     virtual void InitRenderer(vtkRenderWindow *renderwindow);
 
     //##Documentation
     //## @brief Set the initial size. Called by RenderWindow after it has become
     //## visible for the first time.
     virtual void InitSize(int w, int h);
 
     //##Documentation
     //## @brief Draws a point on the widget.
     //## Should be used during conferences to show the position of the remote mouse
     virtual void DrawOverlayMouse(Point2D &p2d);
 
     //##Documentation
     //## @brief Set/Get the WorldGeometry (m_WorldGeometry) for 3D and 2D rendering, that describing the
     //## (maximal) area to be rendered.
     //##
     //## Depending of the type of the passed BaseGeometry more or less information can be extracted:
     //## \li if it is a PlaneGeometry (which is a sub-class of BaseGeometry), m_CurrentWorldPlaneGeometry is
     //## also set to point to it. m_WorldTimeGeometry is set to nullptr.
     //## \li if it is a TimeGeometry, m_WorldTimeGeometry is also set to point to it.
     //## If m_WorldTimeGeometry contains instances of SlicedGeometry3D, m_CurrentWorldPlaneGeometry is set to
     //## one of geometries stored in the SlicedGeometry3D according to the value of m_Slice;  otherwise
     //## a PlaneGeometry describing the top of the bounding-box of the BaseGeometry is set as the
     //## m_CurrentWorldPlaneGeometry.
     //## \li otherwise a PlaneGeometry describing the top of the bounding-box of the BaseGeometry
     //## is set as the m_CurrentWorldPlaneGeometry. m_WorldTimeGeometry is set to nullptr.
     //## @todo add calculation of PlaneGeometry describing the top of the bounding-box of the BaseGeometry
     //## when the passed BaseGeometry is not sliced.
     //## \sa m_WorldGeometry
     //## \sa m_WorldTimeGeometry
     //## \sa m_CurrentWorldPlaneGeometry
     virtual void SetWorldGeometry3D(const BaseGeometry *geometry);
     virtual void SetWorldTimeGeometry(const mitk::TimeGeometry *geometry);
 
-    /**
-    * \deprecatedSince{2013_09} Please use TimeGeometry instead of TimeSlicedGeometry. For more information see
-    * http://www.mitk.org/Development/Refactoring%20of%20the%20Geometry%20Classes%20-%20Part%201
-    */
-    DEPRECATED(void SetWorldGeometry3D(TimeSlicedGeometry *geometry));
-
     itkGetConstObjectMacro(WorldTimeGeometry, TimeGeometry);
 
       //##Documentation
       //## @brief Get the current 3D-worldgeometry (m_CurrentWorldGeometry) used for 3D-rendering
       itkGetConstObjectMacro(CurrentWorldGeometry, BaseGeometry);
 
       //##Documentation
       //## @brief Get the current 2D-worldgeometry (m_CurrentWorldPlaneGeometry) used for 2D-rendering
       itkGetConstObjectMacro(CurrentWorldPlaneGeometry, PlaneGeometry)
       /**
       * \deprecatedSince{2014_10} Please use GetCurrentWorldPlaneGeometry
       */
       DEPRECATED(const PlaneGeometry *GetCurrentWorldGeometry2D())
     {
       return GetCurrentWorldPlaneGeometry();
     };
 
     //##Documentation
     //## Calculates the bounds of the DataStorage (if it contains any valid data),
     //## creates a geometry from these bounds and sets it as world geometry of the renderer.
     //##
     //## Call this method to re-initialize the renderer to the current DataStorage
     //## (e.g. after loading an additional dataset), to ensure that the view is
     //## aligned correctly.
     //## \warning This is not implemented yet.
     virtual bool SetWorldGeometryToDataStorageBounds() { return false; }
     //##Documentation
     //## @brief Set/Get m_Slice which defines together with m_TimeStep the 2D geometry
     //## stored in m_WorldTimeGeometry used as m_CurrentWorldPlaneGeometry
     //##
     //## \sa m_Slice
     virtual void SetSlice(unsigned int slice);
 
     itkGetConstMacro(Slice, unsigned int);
 
       //##Documentation
       //## @brief Set/Get m_TimeStep which defines together with m_Slice the 2D geometry
       //## stored in m_WorldTimeGeometry used as m_CurrentWorldPlaneGeometry
       //##
       //## \sa m_TimeStep
       virtual void SetTimeStep(unsigned int timeStep);
 
     itkGetConstMacro(TimeStep, unsigned int);
 
       //##Documentation
       //## @brief Get the time-step of a BaseData object which
       //## exists at the time of the currently displayed content
       //##
       //## Returns -1 or mitk::BaseData::m_TimeSteps if there
       //## is no data at the current time.
       //## \sa GetTimeStep, m_TimeStep
       TimeStepType GetTimeStep(const BaseData *data) const;
 
     //##Documentation
     //## @brief Get the time in ms of the currently displayed content
     //##
     //## \sa GetTimeStep, m_TimeStep
     ScalarType GetTime() const;
 
     //##Documentation
     //## @brief SetWorldGeometry is called according to the geometrySliceEvent,
     //## which is supposed to be a SliceNavigationController::GeometrySendEvent
     virtual void SetGeometry(const itk::EventObject &geometrySliceEvent);
 
     //##Documentation
     //## @brief UpdateWorldGeometry is called to re-read the 2D geometry from the
     //## slice navigation controller
     virtual void UpdateGeometry(const itk::EventObject &geometrySliceEvent);
 
     //##Documentation
     //## @brief SetSlice is called according to the geometrySliceEvent,
     //## which is supposed to be a SliceNavigationController::GeometrySliceEvent
     virtual void SetGeometrySlice(const itk::EventObject &geometrySliceEvent);
 
     //##Documentation
     //## @brief SetTimeStep is called according to the geometrySliceEvent,
     //## which is supposed to be a SliceNavigationController::GeometryTimeEvent
     virtual void SetGeometryTime(const itk::EventObject &geometryTimeEvent);
 
     //##Documentation
     //## @brief Get a DataNode pointing to a data object containing the current 2D-worldgeometry
     // m_CurrentWorldPlaneGeometry (for 2D rendering)
     itkGetObjectMacro(CurrentWorldPlaneGeometryNode, DataNode)
       /**
       * \deprecatedSince{2014_10} Please use GetCurrentWorldPlaneGeometryNode
       */
       DEPRECATED(DataNode *GetCurrentWorldGeometry2DNode())
     {
       return GetCurrentWorldPlaneGeometryNode();
     };
 
     //##Documentation
     //## @brief Sets timestamp of CurrentWorldPlaneGeometry and forces so reslicing in that renderwindow
     void SendUpdateSlice();
 
     //##Documentation
     //## @brief Get timestamp of last call of SetCurrentWorldPlaneGeometry
     unsigned long GetCurrentWorldPlaneGeometryUpdateTime() { return m_CurrentWorldPlaneGeometryUpdateTime; }
     /**
     * \deprecatedSince{2014_10} Please use GetCurrentWorldPlaneGeometryUpdateTime
     */
     DEPRECATED(unsigned long GetCurrentWorldGeometry2DUpdateTime())
     {
       return GetCurrentWorldPlaneGeometryUpdateTime();
     };
     //##Documentation
     //## @brief Get timestamp of last change of current TimeStep
     unsigned long GetTimeStepUpdateTime() { return m_TimeStepUpdateTime; }
     //##Documentation
     //## @brief Perform a picking: find the x,y,z world coordinate of a
     //## display x,y coordinate.
     //## @warning Has to be overwritten in subclasses for the 3D-case.
     //##
     //## Implemented here only for 2D-rendering
     virtual void PickWorldPoint(const Point2D &diplayPosition, Point3D &worldPosition) const = 0;
 
     /** \brief Determines the object (mitk::DataNode) closest to the current
     * position by means of picking
     *
     * \warning Implementation currently empty for 2D rendering; intended to be
     * implemented for 3D renderers */
     virtual DataNode *PickObject(const Point2D & /*displayPosition*/, Point3D & /*worldPosition*/) const
     {
       return nullptr;
     }
 
     //##Documentation
     //## @brief Get the MapperSlotId to use.
     itkGetMacro(MapperID, MapperSlotId);
     itkGetConstMacro(MapperID, MapperSlotId);
 
       //##Documentation
       //## @brief Set the MapperSlotId to use.
       virtual void SetMapperID(MapperSlotId id);
 
         virtual int *GetSize() const;
     virtual int *GetViewportSize() const;
 
     void SetSliceNavigationController(SliceNavigationController *SlicenavigationController);
     itkGetObjectMacro(CameraController, CameraController);
     itkGetObjectMacro(SliceNavigationController, SliceNavigationController);
     itkGetObjectMacro(CameraRotationController, CameraRotationController);
     itkGetMacro(EmptyWorldGeometry, bool);
 
       //##Documentation
       //## @brief Tells if the displayed region is shifted and rescaled if the render window is resized.
       itkGetMacro(KeepDisplayedRegion, bool)
       //##Documentation
       //## @brief Tells if the displayed region should be shifted and rescaled if the render window is resized.
       itkSetMacro(KeepDisplayedRegion, bool);
 
       //##Documentation
       //## @brief get the name of the Renderer
       //## @note
       const char *GetName() const
     {
       return m_Name.c_str();
     }
 
     //##Documentation
     //## @brief get the x_size of the RendererWindow
     //## @note
     int GetSizeX() const { return GetSize()[0]; }
     //##Documentation
     //## @brief get the y_size of the RendererWindow
     //## @note
     int GetSizeY() const { return GetSize()[1]; }
     const double *GetBounds() const;
 
     void RequestUpdate();
     void ForceImmediateUpdate();
 
     /** Returns number of mappers which are visible and have level-of-detail
     * rendering enabled */
     unsigned int GetNumberOfVisibleLODEnabledMappers() const;
 
     //##Documentation
     //## @brief This method converts a display point to the 3D world index
     //## using the geometry of the renderWindow.
     void DisplayToWorld(const Point2D &displayPoint, Point3D &worldIndex) const;
 
     //##Documentation
     //## @brief This method converts a display point to the 2D world index, mapped onto the display plane
     //## using the geometry of the renderWindow.
     void DisplayToPlane(const Point2D &displayPoint, Point2D &planePointInMM) const;
 
     //##Documentation
     //## @brief This method converts a 3D world index to the display point
     //## using the geometry of the renderWindow.
     void WorldToDisplay(const Point3D &worldIndex, Point2D &displayPoint) const;
 
     //##Documentation
     //## @brief This method converts a 3D world index to the point on the viewport
     //## using the geometry of the renderWindow.
     void WorldToView(const Point3D &worldIndex, Point2D &viewPoint) const;
 
     //##Documentation
     //## @brief This method converts a 2D plane coordinate to the display point
     //## using the geometry of the renderWindow.
     void PlaneToDisplay(const Point2D &planePointInMM, Point2D &displayPoint) const;
 
     //##Documentation
     //## @brief This method converts a 2D plane coordinate to the point on the viewport
     //## using the geometry of the renderWindow.
     void PlaneToView(const Point2D &planePointInMM, Point2D &viewPoint) const;
 
 
     double GetScaleFactorMMPerDisplayUnit() const;
 
     Point2D GetDisplaySizeInMM() const;
     Point2D GetViewportSizeInMM() const;
 
     Point2D GetOriginInMM() const;
 
     itkGetConstMacro(ConstrainZoomingAndPanning, bool) virtual void SetConstrainZoomingAndPanning(bool constrain);
 
     /**
     * \brief Provides (1) world coordinates for a given mouse position and (2)
     * translates mousePosition to Display coordinates
     * \deprecated Map2DRendererPositionTo3DWorldPosition is deprecated. Please use DisplayToWorld instead.
     */
     DEPRECATED(virtual Point3D Map2DRendererPositionTo3DWorldPosition(const Point2D &mousePosition) const);
 
   protected:
     ~BaseRenderer() override;
 
     //##Documentation
     //## @brief Call update of all mappers. To be implemented in subclasses.
     virtual void Update() = 0;
 
     vtkRenderWindow *m_RenderWindow;
     vtkRenderer *m_VtkRenderer;
 
     //##Documentation
     //## @brief MapperSlotId to use. Defines which kind of mapper (e.g., 2D or 3D) shoud be used.
     MapperSlotId m_MapperID;
 
     //##Documentation
     //## @brief The DataStorage that is used for rendering.
     DataStorage::Pointer m_DataStorage;
 
     //##Documentation
     //## @brief Timestamp of last call of Update().
     unsigned long m_LastUpdateTime;
 
     //##Documentation
     //## @brief CameraController for 3D rendering
     //## @note preliminary.
     itk::SmartPointer<CameraController> m_CameraController;
     SliceNavigationController::Pointer m_SliceNavigationController;
     CameraRotationController::Pointer m_CameraRotationController;
 
     //##Documentation
     //## @brief Sets m_CurrentWorldPlaneGeometry
     virtual void SetCurrentWorldPlaneGeometry(const PlaneGeometry *geometry2d);
     /**
     * \deprecatedSince{2014_10} Please use SetCurrentWorldPlaneGeometry
     */
     DEPRECATED(void SetCurrentWorldGeometry2D(PlaneGeometry *geometry2d)) { SetCurrentWorldPlaneGeometry(geometry2d); };
     //##Documentation
     //## @brief Sets m_CurrentWorldGeometry
     virtual void SetCurrentWorldGeometry(const BaseGeometry *geometry);
 
   private:
     //##Documentation
     //## m_WorldTimeGeometry is set by SetWorldGeometry if the passed BaseGeometry is a
     //## TimeGeometry (or a sub-class of it). If it contains instances of SlicedGeometry3D,
     //## m_Slice and m_TimeStep (set via SetSlice and SetTimeStep, respectively) define
     //## which 2D geometry stored in m_WorldTimeGeometry (if available)
     //## is used as m_CurrentWorldPlaneGeometry.
     //## \sa m_CurrentWorldPlaneGeometry
     TimeGeometry::ConstPointer m_WorldTimeGeometry;
 
     //##Documentation
     //## Pointer to the current 3D-worldgeometry.
     BaseGeometry::ConstPointer m_CurrentWorldGeometry;
 
     //##Documentation
     //## Pointer to the current 2D-worldgeometry. The 2D-worldgeometry
     //## describes the maximal area (2D manifold) to be rendered in case we
     //## are doing 2D-rendering.
     //## It is const, since we are not allowed to change it (it may be taken
     //## directly from the geometry of an image-slice and thus it would be
     //## very strange when suddenly the image-slice changes its geometry).
     PlaneGeometry::Pointer m_CurrentWorldPlaneGeometry;
 
     //##Documentation
     //## Defines together with m_Slice which 2D geometry stored in m_WorldTimeGeometry
     //## is used as m_CurrentWorldPlaneGeometry: m_WorldTimeGeometry->GetPlaneGeometry(m_Slice, m_TimeStep).
     //## \sa m_WorldTimeGeometry
     unsigned int m_Slice;
     //##Documentation
     //## Defines together with m_TimeStep which 2D geometry stored in m_WorldTimeGeometry
     //## is used as m_CurrentWorldPlaneGeometry: m_WorldTimeGeometry->GetPlaneGeometry(m_Slice, m_TimeStep).
     //## \sa m_WorldTimeGeometry
     unsigned int m_TimeStep;
 
     //##Documentation
     //## @brief timestamp of last call of SetWorldGeometry
     itk::TimeStamp m_CurrentWorldPlaneGeometryUpdateTime;
 
     //##Documentation
     //## @brief timestamp of last change of the current time step
     itk::TimeStamp m_TimeStepUpdateTime;
 
     //##Documentation
     //## @brief Helper class which establishes connection between Interactors and Dispatcher via a common DataStorage.
     BindDispatcherInteractor *m_BindDispatcherInteractor;
 
     //##Documentation
     //## @brief Tells if the displayed region should be shifted or rescaled if the render window is resized.
     bool m_KeepDisplayedRegion;
 
   protected:
     void PrintSelf(std::ostream &os, itk::Indent indent) const override;
 
     //##Documentation
     //## Data object containing the m_CurrentWorldPlaneGeometry defined above.
     PlaneGeometryData::Pointer m_CurrentWorldPlaneGeometryData;
 
     //##Documentation
     //## DataNode objects containing the m_CurrentWorldPlaneGeometryData defined above.
     DataNode::Pointer m_CurrentWorldPlaneGeometryNode;
 
     //##Documentation
     //## @brief test only
     unsigned long m_CurrentWorldPlaneGeometryTransformTime;
 
     std::string m_Name;
 
     double m_Bounds[6];
 
     bool m_EmptyWorldGeometry;
 
     typedef std::set<Mapper *> LODEnabledMappersType;
 
     /** Number of mappers which are visible and have level-of-detail
     * rendering enabled */
     unsigned int m_NumberOfVisibleLODEnabledMappers;
 
     // Local Storage Handling for mappers
 
   protected:
     std::list<mitk::BaseLocalStorageHandler *> m_RegisteredLocalStorageHandlers;
 
     bool m_ConstrainZoomingAndPanning;
 
   public:
     void RemoveAllLocalStorages();
     void RegisterLocalStorageHandler(mitk::BaseLocalStorageHandler *lsh);
     void UnregisterLocalStorageHandler(mitk::BaseLocalStorageHandler *lsh);
   };
 } // namespace mitk
 
 #endif /* BASERENDERER_H_HEADER_INCLUDED_C1CCA0F4 */
diff --git a/Modules/Core/include/mitkPointSetVtkMapper2D.h b/Modules/Core/include/mitkPointSetVtkMapper2D.h
index 08a0524cc5..f8520be771 100644
--- a/Modules/Core/include/mitkPointSetVtkMapper2D.h
+++ b/Modules/Core/include/mitkPointSetVtkMapper2D.h
@@ -1,238 +1,238 @@
 /*============================================================================
 
 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 mitkPointSetVtkMapper2D_h
 #define mitkPointSetVtkMapper2D_h
 
 #include "mitkBaseRenderer.h"
 #include "mitkLocalStorageHandler.h"
 #include "mitkVtkMapper.h"
 #include <MitkCoreExports.h>
 #include <mitkPointSetShapeProperty.h>
 
 // VTK
 #include <vtkSmartPointer.h>
 class vtkActor;
 class vtkPropAssembly;
 class vtkPolyData;
 class vtkPolyDataMapper;
 class vtkGlyphSource2D;
 class vtkGlyph3D;
 class vtkFloatArray;
 class vtkCellArray;
 
 namespace mitk
 {
   class PointSet;
 
   /**
   * @brief Vtk-based 2D mapper for PointSet
   *
   * Due to the need of different colors for selected
   * and unselected points and the facts, that we also have a contour and
   * labels for the points, the vtk structure is build up the following way:
   *
   * We have three PolyData, one selected, and one unselected and one
   * for a contour between the points. Each one is connected to an own
   * PolyDataMapper and an Actor. The different color for the unselected and
   * selected state and for the contour is read from properties.
   *
   * This mapper has several additional functionalities, such as rendering
   * a contour between points, calculating and displaying distances or angles
   * between points.
   *
   * @section mitkPointSetVtkMapper2D_point_rep Point Representation
   *
   * The points are displayed as small glyphs of configurable shape
   * (see property "PointSet.2D.shape"). The size of these glyphs
   * is given in world units. That means, the size or shape of those
   * glyphs is independent of the BaseGeometry object that you assign
   * to the PointSet. As for all other objects, _positions_ of points
   * will be transformed into the world via the Geometry's index-to-world
   * transform.
   *
   * Then the three Actors are combined inside a vtkPropAssembly and this
   * object is returned in GetProp() and so hooked up into the rendering
   * pipeline.
   *
   * @section mitkPointSetVtkMapper2D_propertires Applicable Properties
   *
   * Properties that can be set for point sets and influence the PointSetVTKMapper2D are:
   *
   *   - \b "line width": (IntProperty 2)                      // line width of the line from one point to another
   *   - \b "point line width": (IntProperty 1)                // line width of the cross marking a point
   *   - \b "point 2D size": (FloatProperty 6)                 // size of the glyph marking a point (diameter, in world
   * units!)
   *   - \b "show contour": (BoolProperty false)               // enable contour rendering between points (lines)
   *   - \b "close contour": (BoolProperty false)              // if enabled, the open strip is closed (first point
   * connected with last point)
   *   - \b "show points": (BoolProperty true)                 // show or hide points
   *   - \b "show distances": (BoolProperty false)             // show or hide distance measure
   *   - \b "distance decimal digits": (IntProperty 2)         // set the number of decimal digits to be shown when
   * rendering the distance information
   *   - \b "show angles": (BoolProperty false)                // show or hide angle measurement
   *   - \b "show distant lines": (BoolProperty false)         // show the line between to points from a distant view
   * (equals "always on top" option)
   *   - \b "layer": (IntProperty 1)                           // default is drawing pointset above images (they have a
   * default layer of 0)
   *   - \b "PointSet.2D.shape" (EnumerationProperty Cross)    // provides different shapes marking a point
   *       0 = "None", 1 = "Vertex", 2 = "Dash", 3 = "Cross", 4 = "ThickCross", 5 = "Triangle", 6 = "Square", 7 =
   * "Circle",
   *       8 = "Diamond", 9 = "Arrow", 10 = "ThickArrow", 11 = "HookedArrow", 12 = "Cross"
   *   - \b "PointSet.2D.fill shape": (BoolProperty false)     // fill or do not fill the glyph shape
   *   - \b "Pointset.2D.distance to plane": (FloatProperty 4.0) //In the 2D render window, points are rendered which lie
   * within a certain distance
   *                                                             to the current plane. They are projected on the current
   * plane and scaled according to their distance.
   *                                                             Point markers appear smaller as the plane moves away
   * from
   * their true location.
   *                                                             The distance threshold can be adjusted by this float
   * property, which ables the user to delineate the points
   *                                                             that lie exactly on the plane. (+/- rounding error)
   *
   * Other Properties used here but not defined in this class:
   *
   *   - \b "selectedcolor": (ColorProperty (1.0f, 0.0f, 0.0f))  // default color of the selected pointset e.g. the
   * current
   * point is red
   *   - \b "contourcolor" : (ColorProperty (1.0f, 0.0f, 0.0f))  // default color for the contour is red
   *   - \b "color": (ColorProperty (1.0f, 1.0f, 0.0f))          // default color of the (unselected) pointset is yellow
   *   - \b "opacity": (FloatProperty 1.0)                       // opacity of point set, contours
   *   - \b "label": (StringProperty nullptr)     // a label can be defined for each point, which is rendered in proximity
   * to
   * the point
   *
   * @ingroup Mapper
   */
   class MITKCORE_EXPORT PointSetVtkMapper2D : public VtkMapper
   {
   public:
     mitkClassMacro(PointSetVtkMapper2D, VtkMapper);
 
     itkFactorylessNewMacro(Self);
 
     itkCloneMacro(Self);
 
       virtual const mitk::PointSet *GetInput() const;
 
     /** \brief returns the a prop assembly */
     vtkProp *GetVtkProp(mitk::BaseRenderer *renderer) override;
 
     /** \brief set the default properties for this mapper */
     static void SetDefaultProperties(mitk::DataNode *node, mitk::BaseRenderer *renderer = nullptr, bool overwrite = false);
 
     /** \brief Internal class holding the mapper, actor, etc. for each of the 3 2D render windows */
     class LocalStorage : public mitk::Mapper::BaseLocalStorage
     {
     public:
       /* constructor */
       LocalStorage();
 
       /* destructor */
       ~LocalStorage() override;
 
       // points
       vtkSmartPointer<vtkPoints> m_UnselectedPoints;
       vtkSmartPointer<vtkPoints> m_SelectedPoints;
       vtkSmartPointer<vtkPoints> m_ContourPoints;
 
       // scales
       vtkSmartPointer<vtkFloatArray> m_UnselectedScales;
       vtkSmartPointer<vtkFloatArray> m_SelectedScales;
 
       // distances
       vtkSmartPointer<vtkFloatArray> m_DistancesBetweenPoints;
 
       // lines
       vtkSmartPointer<vtkCellArray> m_ContourLines;
 
       // glyph source (provides different shapes for the points)
       vtkSmartPointer<vtkGlyphSource2D> m_UnselectedGlyphSource2D;
       vtkSmartPointer<vtkGlyphSource2D> m_SelectedGlyphSource2D;
 
       // glyph
       vtkSmartPointer<vtkGlyph3D> m_UnselectedGlyph3D;
       vtkSmartPointer<vtkGlyph3D> m_SelectedGlyph3D;
 
       // polydata
       vtkSmartPointer<vtkPolyData> m_VtkUnselectedPointListPolyData;
       vtkSmartPointer<vtkPolyData> m_VtkSelectedPointListPolyData;
       vtkSmartPointer<vtkPolyData> m_VtkContourPolyData;
 
       // actor
       vtkSmartPointer<vtkActor> m_UnselectedActor;
       vtkSmartPointer<vtkActor> m_SelectedActor;
       vtkSmartPointer<vtkActor> m_ContourActor;
       vtkSmartPointer<vtkTextActor> m_VtkTextActor;
 
       std::vector<vtkSmartPointer<vtkTextActor>> m_VtkTextLabelActors;
       std::vector<vtkSmartPointer<vtkTextActor>> m_VtkTextDistanceActors;
       std::vector<vtkSmartPointer<vtkTextActor>> m_VtkTextAngleActors;
 
       // mappers
       vtkSmartPointer<vtkPolyDataMapper> m_VtkUnselectedPolyDataMapper;
       vtkSmartPointer<vtkPolyDataMapper> m_VtkSelectedPolyDataMapper;
       vtkSmartPointer<vtkPolyDataMapper> m_VtkContourPolyDataMapper;
 
       // propassembly
       vtkSmartPointer<vtkPropAssembly> m_PropAssembly;
     };
 
     /** \brief The LocalStorageHandler holds all (three) LocalStorages for the three 2D render windows. */
     mitk::LocalStorageHandler<LocalStorage> m_LSH;
 
   protected:
     /* constructor */
     PointSetVtkMapper2D();
 
     /* destructor */
     ~PointSetVtkMapper2D() override;
 
     /* \brief Applies the color and opacity properties and calls CreateVTKRenderObjects */
     void GenerateDataForRenderer(mitk::BaseRenderer *renderer) override;
     /* \brief Called in mitk::Mapper::Update
-    * If TimeSlicedGeometry or time step is not valid of point set: reset mapper so that nothing is
+    * If TimeGeometry or time step is not valid of point set: reset mapper so that nothing is
     * displayed e.g. toggle visiblity of the propassembly */
     void ResetMapper(BaseRenderer *renderer) override;
 
     /* \brief Fills the vtk objects, thus it is only called when the point set has been changed.
    * This function iterates over the input point set and determines the glyphs which lie in a specific
    * range around the current slice. Those glyphs are rendered using a specific shape defined in vtk glyph source
    * to mark each point. The shape can be changed in MITK using the property "PointSet.2D.shape".
    *
    * There were issues when rendering vtk glyphs in the 2D-render windows. By default, the glyphs are
    * rendered within the x-y plane in each 2D-render window, so you would only see them from the
    * side in the saggital and coronal 2D-render window. The solution to this is to rotate the glyphs in order
    * to be ortogonal to the current view vector. To achieve this, the rotation (vtktransform) of the current
    * PlaneGeometry is applied to the orienation of the glyphs. */
     virtual void CreateVTKRenderObjects(mitk::BaseRenderer *renderer);
 
     // member variables holding the current value of the properties used in this mapper
     bool m_ShowContour;           // "show contour" property
     bool m_CloseContour;          // "close contour" property
     bool m_ShowPoints;            // "show points" property
     bool m_ShowDistances;         // "show distances" property
     int m_DistancesDecimalDigits; // "distance decimal digits" property
     bool m_ShowAngles;            // "show angles" property
     bool m_ShowDistantLines;      // "show distant lines" property
     int m_LineWidth;              // "line width" property
     int m_PointLineWidth;         // "point line width" property
     float m_Point2DSize;          // "point 2D size" property
     int m_IDShapeProperty;        // ID for mitkPointSetShape Enumeration Property "Pointset.2D.shape"
     bool m_FillShape;             // "Pointset.2D.fill shape" property
     float m_DistanceToPlane;      // "Pointset.2D.distance to plane" property
   };
 
 } // namespace mitk
 
 #endif /* mitkPointSetVtkMapper2D_h */
diff --git a/Modules/Core/include/mitkSurfaceVtkMapper2D.h b/Modules/Core/include/mitkSurfaceVtkMapper2D.h
index 1a0e357f42..9e52cbc226 100644
--- a/Modules/Core/include/mitkSurfaceVtkMapper2D.h
+++ b/Modules/Core/include/mitkSurfaceVtkMapper2D.h
@@ -1,215 +1,215 @@
 /*============================================================================
 
 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 mitkSurfaceVtkMapper2D_h
 #define mitkSurfaceVtkMapper2D_h
 
 #include "mitkBaseRenderer.h"
 #include "mitkLocalStorageHandler.h"
 #include "mitkVtkMapper.h"
 #include <MitkCoreExports.h>
 
 // VTK
 #include <vtkSmartPointer.h>
 class vtkAssembly;
 class vtkCutter;
 class vtkPlane;
 class vtkLookupTable;
 class vtkGlyph3D;
 class vtkArrowSource;
 class vtkReverseSense;
 
 namespace mitk
 {
   class Surface;
 
   /**
     * @brief Vtk-based mapper for cutting 2D slices out of Surfaces.
     *
     * The mapper uses a vtkCutter filter to cut out slices (contours) of the 3D
     * volume and render these slices as vtkPolyData. The data is transformed
     * according to its geometry before cutting, to support the geometry concept
     * of MITK.
     *
     * Properties:
     * \b Surface.2D.Line Width: Thickness of the rendered lines in 2D.
     * \b Surface.2D.Normals.Draw Normals: enables drawing of normals as 3D arrows
     * in the 2D render window. The normals are created with a vtkGlyph3D from
     * the vtkPolyData.
     * \b Surface.2D.Normals.Draw Inverse Normals: same as normals, but in the
     * other direction. The inverse normals are computed with a vtkReverseSense
     * filter.
     * \b Surface.2D.Normals.(Inverse) Normals Color: Color of the (inverse) normals.
     * \b Surface.2D.Normals.(Inverse) Normals Scale Factor: Regulates the size of the normals.
     *
     * @ingroup Mapper
     */
   class MITKCORE_EXPORT SurfaceVtkMapper2D : public VtkMapper
   {
   public:
     mitkClassMacro(SurfaceVtkMapper2D, VtkMapper);
 
     itkFactorylessNewMacro(Self);
 
     itkCloneMacro(Self);
 
       virtual const mitk::Surface *GetInput() const;
 
     /** \brief returns the prop assembly */
     vtkProp *GetVtkProp(mitk::BaseRenderer *renderer) override;
 
     /** \brief set the default properties for this mapper */
     static void SetDefaultProperties(mitk::DataNode *node, mitk::BaseRenderer *renderer = nullptr, bool overwrite = false);
 
     /** \brief Internal class holding the mapper, actor, etc. for each of the 3 2D render windows */
     class LocalStorage : public mitk::Mapper::BaseLocalStorage
     {
     public:
       /** \brief Timestamp of last update of stored data. */
       itk::TimeStamp m_LastUpdateTime;
       /**
          * @brief m_PropAssembly Contains all vtkProps for the final rendering.
          *
          * Consists of 3 actors:
          * The surface cut (the slice from the 3D surface).
          * The normals and the inverse normals.
          */
       vtkSmartPointer<vtkAssembly> m_PropAssembly;
 
       /**
        * @brief m_Actor actor for the surface cut.
        */
       vtkSmartPointer<vtkActor> m_Actor;
       /**
        * @brief m_NormalActor actor for the normals.
        */
       vtkSmartPointer<vtkActor> m_NormalActor;
       /**
        * @brief m_InverseNormalActor actor for the inverse normals.
        */
       vtkSmartPointer<vtkActor> m_InverseNormalActor;
       /**
          * @brief m_Mapper VTK mapper for all types of 2D polydata e.g. werewolves.
          */
       vtkSmartPointer<vtkPolyDataMapper> m_Mapper;
       /**
          * @brief m_Cutter Filter to cut out the 2D slice.
          */
       vtkSmartPointer<vtkCutter> m_Cutter;
       /**
          * @brief m_CuttingPlane The plane where to cut off the 2D slice.
          */
       vtkSmartPointer<vtkPlane> m_CuttingPlane;
 
       /**
        * @brief m_NormalMapper Mapper for the normals.
        */
       vtkSmartPointer<vtkPolyDataMapper> m_NormalMapper;
 
       /**
        * @brief m_InverseNormalMapper Mapper for the inverse normals.
        */
       vtkSmartPointer<vtkPolyDataMapper> m_InverseNormalMapper;
 
       /**
        * @brief m_NormalGlyph Glyph for creating normals.
        */
       vtkSmartPointer<vtkGlyph3D> m_NormalGlyph;
 
       /**
        * @brief m_InverseNormalGlyph Glyph for creating inverse normals.
        */
       vtkSmartPointer<vtkGlyph3D> m_InverseNormalGlyph;
 
       /**
        * @brief m_ArrowSource Arrow representation of the normals.
        */
       vtkSmartPointer<vtkArrowSource> m_ArrowSource;
 
       /**
        * @brief m_ReverseSense Filter to invert the normals.
        */
       vtkSmartPointer<vtkReverseSense> m_ReverseSense;
 
       /** \brief Default constructor of the local storage. */
       LocalStorage();
       /** \brief Default deconstructor of the local storage. */
       ~LocalStorage() override;
     };
 
     /** \brief The LocalStorageHandler holds all (three) LocalStorages for the three 2D render windows. */
     mitk::LocalStorageHandler<LocalStorage> m_LSH;
 
     /**
      * @brief UpdateVtkTransform Overwrite the method of the base class.
      *
      * The base class transforms the actor according to the respective
      * geometry which is correct for most cases. This mapper, however,
      * uses a vtkCutter to cut out a contour. To cut out the correct
      * contour, the data has to be transformed beforehand. Else the
      * current plane geometry will point the cutter to en empty location
      * (if the surface does have a geometry, which is a rather rare case).
      */
     void UpdateVtkTransform(mitk::BaseRenderer * /*renderer*/) override {}
   protected:
     /**
        * @brief SurfaceVtkMapper2D default constructor.
        */
     SurfaceVtkMapper2D();
 
     /**
        * @brief ~SurfaceVtkMapper2D default destructor.
        */
     ~SurfaceVtkMapper2D() override;
 
     /**
        * @brief GenerateDataForRenderer produces all the data.
        * @param renderer The respective renderer of the mitkRenderWindow.
        */
     void GenerateDataForRenderer(mitk::BaseRenderer *renderer) override;
 
     /**
        * @brief ResetMapper Called in mitk::Mapper::Update to hide objects.
-       * If TimeSlicedGeometry or time step is not valid, reset the mapper.
+       * If TimeGeometry or time step is not valid, reset the mapper.
        * so that nothing is displayed e.g. toggle visiblity of the propassembly.
        *
        * @param renderer The respective renderer of the mitkRenderWindow.
        */
     void ResetMapper(BaseRenderer *renderer) override;
 
     /**
      * @brief Updates legacy properties to current behavior/interpretation.
      * @param properties The property list which should be adapted to new behaviour.
      *
      * Whenever a mapper decides to change its property types or its
      * interpretation of certain values, it should add something to this
      * method and call it before methods like ApplyProperties();
      *
      * This is particularly helpful when dealing with data from
      * archive/scene files that were created before changes.
      */
     virtual void FixupLegacyProperties(PropertyList *properties);
 
     /**
      * @brief ApplyAllProperties Pass all the properties to VTK.
      * @param renderer The respective renderer of the mitkRenderWindow.
      */
     void ApplyAllProperties(BaseRenderer *renderer);
 
     /**
        * @brief Update Check if data should be generated.
        * @param renderer The respective renderer of the mitkRenderWindow.
        */
     void Update(BaseRenderer *renderer) override;
   };
 } // namespace mitk
 #endif /* mitkSurfaceVtkMapper2D_h */
diff --git a/Modules/Core/include/mitkTimeSlicedGeometry.h b/Modules/Core/include/mitkTimeSlicedGeometry.h
deleted file mode 100644
index 6d350b4689..0000000000
--- a/Modules/Core/include/mitkTimeSlicedGeometry.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*============================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center (DKFZ)
-All rights reserved.
-
-Use of this source code is governed by a 3-clause BSD license that can be
-found in the LICENSE file.
-
-============================================================================*/
-
-#ifndef mitkTimeSlicedGeometry_h
-#define mitkTimeSlicedGeometry_h
-
-#include <mitkCommon.h>
-
-namespace mitk
-{
-  /**
-  * \deprecatedSince{2013_09} Please use TimeGeometry instead. For more information see
-  * http://www.mitk.org/Development/Refactoring%20of%20the%20Geometry%20Classes%20-%20Part%201
-  */
-  class TimeSlicedGeometry
-  {
-    DEPRECATED(TimeSlicedGeometry());
-  };
-}
-
-#endif
diff --git a/Modules/Multilabel/mitkLabelSetImageVtkMapper2D.cpp b/Modules/Multilabel/mitkLabelSetImageVtkMapper2D.cpp
index 56069a2be9..beb6d792ce 100644
--- a/Modules/Multilabel/mitkLabelSetImageVtkMapper2D.cpp
+++ b/Modules/Multilabel/mitkLabelSetImageVtkMapper2D.cpp
@@ -1,650 +1,649 @@
 /*============================================================================
 
 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 "mitkLabelSetImageVtkMapper2D.h"
 
 // MITK
 #include <mitkAbstractTransformGeometry.h>
 #include <mitkDataNode.h>
 #include <mitkImageSliceSelector.h>
 #include <mitkImageStatisticsHolder.h>
 #include <mitkLevelWindowProperty.h>
 #include <mitkLookupTableProperty.h>
 #include <mitkPixelType.h>
 #include <mitkPlaneClipping.h>
 #include <mitkPlaneGeometry.h>
 #include <mitkProperties.h>
 #include <mitkResliceMethodProperty.h>
-#include <mitkTimeSlicedGeometry.h>
 #include <mitkTransferFunctionProperty.h>
 #include <mitkVtkResliceInterpolationProperty.h>
 
 // MITK Rendering
 #include "vtkMitkLevelWindowFilter.h"
 #include "vtkMitkThickSlicesFilter.h"
 #include "vtkNeverTranslucentTexture.h"
 
 // VTK
 #include <vtkCamera.h>
 #include <vtkCellArray.h>
 #include <vtkImageData.h>
 #include <vtkImageReslice.h>
 #include <vtkLookupTable.h>
 #include <vtkMatrix4x4.h>
 #include <vtkPlaneSource.h>
 #include <vtkPoints.h>
 #include <vtkPolyData.h>
 #include <vtkPolyDataMapper.h>
 #include <vtkProperty.h>
 #include <vtkTransform.h>
 //#include <vtkOpenGLTexture.h>
 
 // ITK
 #include <itkRGBAPixel.h>
 #include <mitkRenderingModeProperty.h>
 
 mitk::LabelSetImageVtkMapper2D::LabelSetImageVtkMapper2D()
 {
 }
 
 mitk::LabelSetImageVtkMapper2D::~LabelSetImageVtkMapper2D()
 {
 }
 
 vtkProp *mitk::LabelSetImageVtkMapper2D::GetVtkProp(mitk::BaseRenderer *renderer)
 {
   // return the actor corresponding to the renderer
   return m_LSH.GetLocalStorage(renderer)->m_Actors;
 }
 
 mitk::LabelSetImageVtkMapper2D::LocalStorage *mitk::LabelSetImageVtkMapper2D::GetLocalStorage(
   mitk::BaseRenderer *renderer)
 {
   return m_LSH.GetLocalStorage(renderer);
 }
 
 void mitk::LabelSetImageVtkMapper2D::GenerateDataForRenderer(mitk::BaseRenderer *renderer)
 {
   LocalStorage *localStorage = m_LSH.GetLocalStorage(renderer);
   mitk::DataNode *node = this->GetDataNode();
   auto *image = dynamic_cast<mitk::LabelSetImage *>(node->GetData());
   assert(image && image->IsInitialized());
 
   // check if there is a valid worldGeometry
   const PlaneGeometry *worldGeometry = renderer->GetCurrentWorldPlaneGeometry();
   if ((worldGeometry == nullptr) || (!worldGeometry->IsValid()) || (!worldGeometry->HasReferenceGeometry()))
     return;
 
   image->Update();
 
   int numberOfLayers = image->GetNumberOfLayers();
   int activeLayer = image->GetActiveLayer();
 
   float opacity = 1.0f;
   node->GetOpacity(opacity, renderer, "opacity");
 
   if (numberOfLayers != localStorage->m_NumberOfLayers)
   {
     localStorage->m_NumberOfLayers = numberOfLayers;
     localStorage->m_ReslicedImageVector.clear();
     localStorage->m_ReslicerVector.clear();
     localStorage->m_LayerTextureVector.clear();
     localStorage->m_LevelWindowFilterVector.clear();
     localStorage->m_LayerMapperVector.clear();
     localStorage->m_LayerActorVector.clear();
 
     localStorage->m_Actors = vtkSmartPointer<vtkPropAssembly>::New();
 
     for (int lidx = 0; lidx < numberOfLayers; ++lidx)
     {
       localStorage->m_ReslicedImageVector.push_back(vtkSmartPointer<vtkImageData>::New());
       localStorage->m_ReslicerVector.push_back(mitk::ExtractSliceFilter::New());
       localStorage->m_LayerTextureVector.push_back(vtkSmartPointer<vtkNeverTranslucentTexture>::New());
       localStorage->m_LevelWindowFilterVector.push_back(vtkSmartPointer<vtkMitkLevelWindowFilter>::New());
       localStorage->m_LayerMapperVector.push_back(vtkSmartPointer<vtkPolyDataMapper>::New());
       localStorage->m_LayerActorVector.push_back(vtkSmartPointer<vtkActor>::New());
 
       // do not repeat the texture (the image)
       localStorage->m_LayerTextureVector[lidx]->RepeatOff();
 
       // set corresponding mappers for the actors
       localStorage->m_LayerActorVector[lidx]->SetMapper(localStorage->m_LayerMapperVector[lidx]);
 
       localStorage->m_Actors->AddPart(localStorage->m_LayerActorVector[lidx]);
     }
 
     localStorage->m_Actors->AddPart(localStorage->m_OutlineShadowActor);
     localStorage->m_Actors->AddPart(localStorage->m_OutlineActor);
   }
 
   // early out if there is no intersection of the current rendering geometry
   // and the geometry of the image that is to be rendered.
   if (!RenderingGeometryIntersectsImage(worldGeometry, image->GetSlicedGeometry()))
   {
     // set image to nullptr, to clear the texture in 3D, because
     // the latest image is used there if the plane is out of the geometry
     // see bug-13275
     for (int lidx = 0; lidx < numberOfLayers; ++lidx)
     {
       localStorage->m_ReslicedImageVector[lidx] = nullptr;
       localStorage->m_LayerMapperVector[lidx]->SetInputData(localStorage->m_EmptyPolyData);
       localStorage->m_OutlineActor->SetVisibility(false);
       localStorage->m_OutlineShadowActor->SetVisibility(false);
     }
     return;
   }
 
   for (int lidx = 0; lidx < numberOfLayers; ++lidx)
   {
     mitk::Image *layerImage = nullptr;
 
     // set main input for ExtractSliceFilter
     if (lidx == activeLayer)
       layerImage = image;
     else
       layerImage = image->GetLayerImage(lidx);
 
     localStorage->m_ReslicerVector[lidx]->SetInput(layerImage);
     localStorage->m_ReslicerVector[lidx]->SetWorldGeometry(worldGeometry);
     localStorage->m_ReslicerVector[lidx]->SetTimeStep(this->GetTimestep());
 
     // set the transformation of the image to adapt reslice axis
     localStorage->m_ReslicerVector[lidx]->SetResliceTransformByGeometry(
       layerImage->GetTimeGeometry()->GetGeometryForTimeStep(this->GetTimestep()));
 
     // is the geometry of the slice based on the image image or the worldgeometry?
     bool inPlaneResampleExtentByGeometry = false;
     node->GetBoolProperty("in plane resample extent by geometry", inPlaneResampleExtentByGeometry, renderer);
     localStorage->m_ReslicerVector[lidx]->SetInPlaneResampleExtentByGeometry(inPlaneResampleExtentByGeometry);
     localStorage->m_ReslicerVector[lidx]->SetInterpolationMode(ExtractSliceFilter::RESLICE_NEAREST);
     localStorage->m_ReslicerVector[lidx]->SetVtkOutputRequest(true);
 
     // this is needed when thick mode was enabled before. These variables have to be reset to default values
     localStorage->m_ReslicerVector[lidx]->SetOutputDimensionality(2);
     localStorage->m_ReslicerVector[lidx]->SetOutputSpacingZDirection(1.0);
     localStorage->m_ReslicerVector[lidx]->SetOutputExtentZDirection(0, 0);
 
     // Bounds information for reslicing (only required if reference geometry is present)
     // this used for generating a vtkPLaneSource with the right size
     double sliceBounds[6];
     sliceBounds[0] = 0.0;
     sliceBounds[1] = 0.0;
     sliceBounds[2] = 0.0;
     sliceBounds[3] = 0.0;
     sliceBounds[4] = 0.0;
     sliceBounds[5] = 0.0;
 
     localStorage->m_ReslicerVector[lidx]->GetClippedPlaneBounds(sliceBounds);
 
     // setup the textured plane
     this->GeneratePlane(renderer, sliceBounds);
 
     // get the spacing of the slice
     localStorage->m_mmPerPixel = localStorage->m_ReslicerVector[lidx]->GetOutputSpacing();
     localStorage->m_ReslicerVector[lidx]->Modified();
     // start the pipeline with updating the largest possible, needed if the geometry of the image has changed
     localStorage->m_ReslicerVector[lidx]->UpdateLargestPossibleRegion();
     localStorage->m_ReslicedImageVector[lidx] = localStorage->m_ReslicerVector[lidx]->GetVtkOutput();
 
     const auto *planeGeometry = dynamic_cast<const PlaneGeometry *>(worldGeometry);
 
     double textureClippingBounds[6];
     for (auto &textureClippingBound : textureClippingBounds)
     {
       textureClippingBound = 0.0;
     }
 
     // Calculate the actual bounds of the transformed plane clipped by the
     // dataset bounding box; this is required for drawing the texture at the
     // correct position during 3D mapping.
     mitk::PlaneClipping::CalculateClippedPlaneBounds(layerImage->GetGeometry(), planeGeometry, textureClippingBounds);
 
     textureClippingBounds[0] = static_cast<int>(textureClippingBounds[0] / localStorage->m_mmPerPixel[0] + 0.5);
     textureClippingBounds[1] = static_cast<int>(textureClippingBounds[1] / localStorage->m_mmPerPixel[0] + 0.5);
     textureClippingBounds[2] = static_cast<int>(textureClippingBounds[2] / localStorage->m_mmPerPixel[1] + 0.5);
     textureClippingBounds[3] = static_cast<int>(textureClippingBounds[3] / localStorage->m_mmPerPixel[1] + 0.5);
 
     // clipping bounds for cutting the imageLayer
     localStorage->m_LevelWindowFilterVector[lidx]->SetClippingBounds(textureClippingBounds);
 
     localStorage->m_LevelWindowFilterVector[lidx]->SetLookupTable(
       image->GetLabelSet(lidx)->GetLookupTable()->GetVtkLookupTable());
 
     // do not use a VTK lookup table (we do that ourselves in m_LevelWindowFilter)
     localStorage->m_LayerTextureVector[lidx]->SetColorModeToDirectScalars();
 
     // connect the imageLayer with the levelwindow filter
     localStorage->m_LevelWindowFilterVector[lidx]->SetInputData(localStorage->m_ReslicedImageVector[lidx]);
     // connect the texture with the output of the levelwindow filter
 
     // check for texture interpolation property
     bool textureInterpolation = false;
     node->GetBoolProperty("texture interpolation", textureInterpolation, renderer);
 
     // set the interpolation modus according to the property
     localStorage->m_LayerTextureVector[lidx]->SetInterpolate(textureInterpolation);
 
     localStorage->m_LayerTextureVector[lidx]->SetInputConnection(
       localStorage->m_LevelWindowFilterVector[lidx]->GetOutputPort());
 
     this->TransformActor(renderer);
 
     // set the plane as input for the mapper
     localStorage->m_LayerMapperVector[lidx]->SetInputConnection(localStorage->m_Plane->GetOutputPort());
 
     // set the texture for the actor
     localStorage->m_LayerActorVector[lidx]->SetTexture(localStorage->m_LayerTextureVector[lidx]);
     localStorage->m_LayerActorVector[lidx]->GetProperty()->SetOpacity(opacity);
   }
 
   mitk::Label* activeLabel = image->GetActiveLabel(activeLayer);
   if (nullptr != activeLabel)
   {
     bool contourActive = false;
     node->GetBoolProperty("labelset.contour.active", contourActive, renderer);
     if (contourActive && activeLabel->GetVisible()) //contour rendering
     {
       //generate contours/outlines
       localStorage->m_OutlinePolyData =
         this->CreateOutlinePolyData(renderer, localStorage->m_ReslicedImageVector[activeLayer], activeLabel->GetValue());
       localStorage->m_OutlineActor->SetVisibility(true);
       localStorage->m_OutlineShadowActor->SetVisibility(true);
       const mitk::Color& color = activeLabel->GetColor();
       localStorage->m_OutlineActor->GetProperty()->SetColor(color.GetRed(), color.GetGreen(), color.GetBlue());
       localStorage->m_OutlineShadowActor->GetProperty()->SetColor(0, 0, 0);
 
       float contourWidth(2.0);
       node->GetFloatProperty("labelset.contour.width", contourWidth, renderer);
       localStorage->m_OutlineActor->GetProperty()->SetLineWidth(contourWidth);
       localStorage->m_OutlineShadowActor->GetProperty()->SetLineWidth(contourWidth * 1.5);
 
       localStorage->m_OutlineActor->GetProperty()->SetOpacity(opacity);
       localStorage->m_OutlineShadowActor->GetProperty()->SetOpacity(opacity);
 
       localStorage->m_OutlineMapper->SetInputData(localStorage->m_OutlinePolyData);
       return;
     }
   }
   localStorage->m_OutlineActor->SetVisibility(false);
   localStorage->m_OutlineShadowActor->SetVisibility(false);
 }
 
 bool mitk::LabelSetImageVtkMapper2D::RenderingGeometryIntersectsImage(const PlaneGeometry *renderingGeometry,
                                                                       SlicedGeometry3D *imageGeometry)
 {
   // if either one of the two geometries is nullptr we return true
   // for safety reasons
   if (renderingGeometry == nullptr || imageGeometry == nullptr)
     return true;
 
   // get the distance for the first cornerpoint
   ScalarType initialDistance = renderingGeometry->SignedDistance(imageGeometry->GetCornerPoint(0));
   for (int i = 1; i < 8; i++)
   {
     mitk::Point3D cornerPoint = imageGeometry->GetCornerPoint(i);
 
     // get the distance to the other cornerpoints
     ScalarType distance = renderingGeometry->SignedDistance(cornerPoint);
 
     // if it has not the same signing as the distance of the first point
     if (initialDistance * distance < 0)
     {
       // we have an intersection and return true
       return true;
     }
   }
 
   // all distances have the same sign, no intersection and we return false
   return false;
 }
 
 vtkSmartPointer<vtkPolyData> mitk::LabelSetImageVtkMapper2D::CreateOutlinePolyData(mitk::BaseRenderer *renderer,
                                                                                    vtkImageData *image,
                                                                                    int pixelValue)
 {
   LocalStorage *localStorage = this->GetLocalStorage(renderer);
 
   // get the min and max index values of each direction
   int *extent = image->GetExtent();
   int xMin = extent[0];
   int xMax = extent[1];
   int yMin = extent[2];
   int yMax = extent[3];
 
   int *dims = image->GetDimensions(); // dimensions of the image
   int line = dims[0];                 // how many pixels per line?
   int x = xMin;                       // pixel index x
   int y = yMin;                       // pixel index y
 
   // get the depth for each contour
   float depth = this->CalculateLayerDepth(renderer);
 
   vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();      // the points to draw
   vtkSmartPointer<vtkCellArray> lines = vtkSmartPointer<vtkCellArray>::New(); // the lines to connect the points
 
   // We take the pointer to the first pixel of the image
   auto *currentPixel = static_cast<mitk::Label::PixelType *>(image->GetScalarPointer());
 
   while (y <= yMax)
   {
     // if the current pixel value is set to something
     if ((currentPixel) && (*currentPixel == pixelValue))
     {
       // check in which direction a line is necessary
       // a line is added if the neighbor of the current pixel has the value 0
       // and if the pixel is located at the edge of the image
 
       // if   vvvvv  not the first line vvvvv
       if (y > yMin && *(currentPixel - line) != pixelValue)
       { // x direction - bottom edge of the pixel
         // add the 2 points
         vtkIdType p1 =
           points->InsertNextPoint(x * localStorage->m_mmPerPixel[0], y * localStorage->m_mmPerPixel[1], depth);
         vtkIdType p2 =
           points->InsertNextPoint((x + 1) * localStorage->m_mmPerPixel[0], y * localStorage->m_mmPerPixel[1], depth);
         // add the line between both points
         lines->InsertNextCell(2);
         lines->InsertCellPoint(p1);
         lines->InsertCellPoint(p2);
       }
 
       // if   vvvvv  not the last line vvvvv
       if (y < yMax && *(currentPixel + line) != pixelValue)
       { // x direction - top edge of the pixel
         vtkIdType p1 =
           points->InsertNextPoint(x * localStorage->m_mmPerPixel[0], (y + 1) * localStorage->m_mmPerPixel[1], depth);
         vtkIdType p2 = points->InsertNextPoint(
           (x + 1) * localStorage->m_mmPerPixel[0], (y + 1) * localStorage->m_mmPerPixel[1], depth);
         lines->InsertNextCell(2);
         lines->InsertCellPoint(p1);
         lines->InsertCellPoint(p2);
       }
 
       // if   vvvvv  not the first pixel vvvvv
       if ((x > xMin || y > yMin) && *(currentPixel - 1) != pixelValue)
       { // y direction - left edge of the pixel
         vtkIdType p1 =
           points->InsertNextPoint(x * localStorage->m_mmPerPixel[0], y * localStorage->m_mmPerPixel[1], depth);
         vtkIdType p2 =
           points->InsertNextPoint(x * localStorage->m_mmPerPixel[0], (y + 1) * localStorage->m_mmPerPixel[1], depth);
         lines->InsertNextCell(2);
         lines->InsertCellPoint(p1);
         lines->InsertCellPoint(p2);
       }
 
       // if   vvvvv  not the last pixel vvvvv
       if ((y < yMax || (x < xMax)) && *(currentPixel + 1) != pixelValue)
       { // y direction - right edge of the pixel
         vtkIdType p1 =
           points->InsertNextPoint((x + 1) * localStorage->m_mmPerPixel[0], y * localStorage->m_mmPerPixel[1], depth);
         vtkIdType p2 = points->InsertNextPoint(
           (x + 1) * localStorage->m_mmPerPixel[0], (y + 1) * localStorage->m_mmPerPixel[1], depth);
         lines->InsertNextCell(2);
         lines->InsertCellPoint(p1);
         lines->InsertCellPoint(p2);
       }
 
       /*  now consider pixels at the edge of the image  */
 
       // if   vvvvv  left edge of image vvvvv
       if (x == xMin)
       { // draw left edge of the pixel
         vtkIdType p1 =
           points->InsertNextPoint(x * localStorage->m_mmPerPixel[0], y * localStorage->m_mmPerPixel[1], depth);
         vtkIdType p2 =
           points->InsertNextPoint(x * localStorage->m_mmPerPixel[0], (y + 1) * localStorage->m_mmPerPixel[1], depth);
         lines->InsertNextCell(2);
         lines->InsertCellPoint(p1);
         lines->InsertCellPoint(p2);
       }
 
       // if   vvvvv  right edge of image vvvvv
       if (x == xMax)
       { // draw right edge of the pixel
         vtkIdType p1 =
           points->InsertNextPoint((x + 1) * localStorage->m_mmPerPixel[0], y * localStorage->m_mmPerPixel[1], depth);
         vtkIdType p2 = points->InsertNextPoint(
           (x + 1) * localStorage->m_mmPerPixel[0], (y + 1) * localStorage->m_mmPerPixel[1], depth);
         lines->InsertNextCell(2);
         lines->InsertCellPoint(p1);
         lines->InsertCellPoint(p2);
       }
 
       // if   vvvvv  bottom edge of image vvvvv
       if (y == yMin)
       { // draw bottom edge of the pixel
         vtkIdType p1 =
           points->InsertNextPoint(x * localStorage->m_mmPerPixel[0], y * localStorage->m_mmPerPixel[1], depth);
         vtkIdType p2 =
           points->InsertNextPoint((x + 1) * localStorage->m_mmPerPixel[0], y * localStorage->m_mmPerPixel[1], depth);
         lines->InsertNextCell(2);
         lines->InsertCellPoint(p1);
         lines->InsertCellPoint(p2);
       }
 
       // if   vvvvv  top edge of image vvvvv
       if (y == yMax)
       { // draw top edge of the pixel
         vtkIdType p1 =
           points->InsertNextPoint(x * localStorage->m_mmPerPixel[0], (y + 1) * localStorage->m_mmPerPixel[1], depth);
         vtkIdType p2 = points->InsertNextPoint(
           (x + 1) * localStorage->m_mmPerPixel[0], (y + 1) * localStorage->m_mmPerPixel[1], depth);
         lines->InsertNextCell(2);
         lines->InsertCellPoint(p1);
         lines->InsertCellPoint(p2);
       }
     } // end if currentpixel is set
 
     x++;
 
     if (x > xMax)
     { // reached end of line
       x = xMin;
       y++;
     }
 
     // Increase the pointer-position to the next pixel.
     // This is safe, as the while-loop and the x-reset logic above makes
     // sure we do not exceed the bounds of the image
     currentPixel++;
   } // end of while
 
   // Create a polydata to store everything in
   vtkSmartPointer<vtkPolyData> polyData = vtkSmartPointer<vtkPolyData>::New();
   // Add the points to the dataset
   polyData->SetPoints(points);
   // Add the lines to the dataset
   polyData->SetLines(lines);
   return polyData;
 }
 
 void mitk::LabelSetImageVtkMapper2D::ApplyColor(mitk::BaseRenderer *renderer, const mitk::Color &color)
 {
   LocalStorage *localStorage = this->GetLocalStorage(renderer);
   localStorage->m_OutlineActor->GetProperty()->SetColor(color.GetRed(), color.GetGreen(), color.GetBlue());
   localStorage->m_OutlineShadowActor->GetProperty()->SetColor(0, 0, 0);
 }
 
 void mitk::LabelSetImageVtkMapper2D::ApplyOpacity(mitk::BaseRenderer *renderer, int layer)
 {
   LocalStorage *localStorage = this->GetLocalStorage(renderer);
   float opacity = 1.0f;
   this->GetDataNode()->GetOpacity(opacity, renderer, "opacity");
   localStorage->m_LayerActorVector[layer]->GetProperty()->SetOpacity(opacity);
   localStorage->m_OutlineActor->GetProperty()->SetOpacity(opacity);
   localStorage->m_OutlineShadowActor->GetProperty()->SetOpacity(opacity);
 }
 
 void mitk::LabelSetImageVtkMapper2D::ApplyLookuptable(mitk::BaseRenderer *renderer, int layer)
 {
   LocalStorage *localStorage = m_LSH.GetLocalStorage(renderer);
   auto *input = dynamic_cast<mitk::LabelSetImage *>(this->GetDataNode()->GetData());
   localStorage->m_LevelWindowFilterVector[layer]->SetLookupTable(
     input->GetLabelSet(layer)->GetLookupTable()->GetVtkLookupTable());
 }
 
 void mitk::LabelSetImageVtkMapper2D::Update(mitk::BaseRenderer *renderer)
 {
   bool visible = true;
   const DataNode *node = this->GetDataNode();
   node->GetVisibility(visible, renderer, "visible");
 
   if (!visible)
     return;
 
   auto *image = dynamic_cast<mitk::LabelSetImage *>(node->GetData());
 
   if (image == nullptr || image->IsInitialized() == false)
     return;
 
   // Calculate time step of the image data for the specified renderer (integer value)
   this->CalculateTimeStep(renderer);
 
   // Check if time step is valid
   const TimeGeometry *dataTimeGeometry = image->GetTimeGeometry();
   if ((dataTimeGeometry == nullptr) || (dataTimeGeometry->CountTimeSteps() == 0) ||
       (!dataTimeGeometry->IsValidTimeStep(this->GetTimestep())))
   {
     return;
   }
 
   image->UpdateOutputInformation();
   LocalStorage *localStorage = m_LSH.GetLocalStorage(renderer);
 
   // check if something important has changed and we need to re-render
 
   if ((localStorage->m_LastDataUpdateTime < image->GetMTime()) ||
       (localStorage->m_LastDataUpdateTime < image->GetPipelineMTime()) ||
       (localStorage->m_LastDataUpdateTime < renderer->GetCurrentWorldPlaneGeometryUpdateTime()) ||
       (localStorage->m_LastDataUpdateTime < renderer->GetCurrentWorldPlaneGeometry()->GetMTime()))
   {
     this->GenerateDataForRenderer(renderer);
     localStorage->m_LastDataUpdateTime.Modified();
   }
   else if ((localStorage->m_LastPropertyUpdateTime < node->GetPropertyList()->GetMTime()) ||
            (localStorage->m_LastPropertyUpdateTime < node->GetPropertyList(renderer)->GetMTime()) ||
            (localStorage->m_LastPropertyUpdateTime < image->GetPropertyList()->GetMTime()))
   {
     this->GenerateDataForRenderer(renderer);
     localStorage->m_LastPropertyUpdateTime.Modified();
   }
 }
 
 // set the two points defining the textured plane according to the dimension and spacing
 void mitk::LabelSetImageVtkMapper2D::GeneratePlane(mitk::BaseRenderer *renderer, double planeBounds[6])
 {
   LocalStorage *localStorage = m_LSH.GetLocalStorage(renderer);
 
   float depth = this->CalculateLayerDepth(renderer);
   // Set the origin to (xMin; yMin; depth) of the plane. This is necessary for obtaining the correct
   // plane size in crosshair rotation and swivel mode.
   localStorage->m_Plane->SetOrigin(planeBounds[0], planeBounds[2], depth);
   // These two points define the axes of the plane in combination with the origin.
   // Point 1 is the x-axis and point 2 the y-axis.
   // Each plane is transformed according to the view (axial, coronal and saggital) afterwards.
   localStorage->m_Plane->SetPoint1(planeBounds[1], planeBounds[2], depth); // P1: (xMax, yMin, depth)
   localStorage->m_Plane->SetPoint2(planeBounds[0], planeBounds[3], depth); // P2: (xMin, yMax, depth)
 }
 
 float mitk::LabelSetImageVtkMapper2D::CalculateLayerDepth(mitk::BaseRenderer *renderer)
 {
   // get the clipping range to check how deep into z direction we can render images
   double maxRange = renderer->GetVtkRenderer()->GetActiveCamera()->GetClippingRange()[1];
 
   // Due to a VTK bug, we cannot use the whole clipping range. /100 is empirically determined
   float depth = -maxRange * 0.01; // divide by 100
   int layer = 0;
   GetDataNode()->GetIntProperty("layer", layer, renderer);
   // add the layer property for each image to render images with a higher layer on top of the others
   depth += layer * 10; //*10: keep some room for each image (e.g. for ODFs in between)
   if (depth > 0.0f)
   {
     depth = 0.0f;
     MITK_WARN << "Layer value exceeds clipping range. Set to minimum instead.";
   }
   return depth;
 }
 
 void mitk::LabelSetImageVtkMapper2D::TransformActor(mitk::BaseRenderer *renderer)
 {
   LocalStorage *localStorage = m_LSH.GetLocalStorage(renderer);
   // get the transformation matrix of the reslicer in order to render the slice as axial, coronal or saggital
   vtkSmartPointer<vtkTransform> trans = vtkSmartPointer<vtkTransform>::New();
   vtkSmartPointer<vtkMatrix4x4> matrix = localStorage->m_ReslicerVector[0]->GetResliceAxes(); // same for all layers
   trans->SetMatrix(matrix);
 
   for (int lidx = 0; lidx < localStorage->m_NumberOfLayers; ++lidx)
   {
     // transform the plane/contour (the actual actor) to the corresponding view (axial, coronal or saggital)
     localStorage->m_LayerActorVector[lidx]->SetUserTransform(trans);
     // transform the origin to center based coordinates, because MITK is center based.
     localStorage->m_LayerActorVector[lidx]->SetPosition(
       -0.5 * localStorage->m_mmPerPixel[0], -0.5 * localStorage->m_mmPerPixel[1], 0.0);
   }
   // same for outline actor
   localStorage->m_OutlineActor->SetUserTransform(trans);
   localStorage->m_OutlineActor->SetPosition(
     -0.5 * localStorage->m_mmPerPixel[0], -0.5 * localStorage->m_mmPerPixel[1], 0.0);
   // same for outline shadow actor
   localStorage->m_OutlineShadowActor->SetUserTransform(trans);
   localStorage->m_OutlineShadowActor->SetPosition(
     -0.5 * localStorage->m_mmPerPixel[0], -0.5 * localStorage->m_mmPerPixel[1], 0.0);
 }
 
 void mitk::LabelSetImageVtkMapper2D::SetDefaultProperties(mitk::DataNode *node,
                                                           mitk::BaseRenderer *renderer,
                                                           bool overwrite)
 {
   // add/replace the following properties
   node->SetProperty("opacity", FloatProperty::New(1.0f), renderer);
   node->SetProperty("binary", BoolProperty::New(false), renderer);
 
   mitk::RenderingModeProperty::Pointer renderingModeProperty =
     mitk::RenderingModeProperty::New(RenderingModeProperty::LOOKUPTABLE_LEVELWINDOW_COLOR);
   node->SetProperty("Image Rendering.Mode", renderingModeProperty, renderer);
 
   mitk::LevelWindow levelwindow(32767.5, 65535);
   mitk::LevelWindowProperty::Pointer levWinProp = mitk::LevelWindowProperty::New(levelwindow);
 
   levWinProp->SetLevelWindow(levelwindow);
   node->SetProperty("levelwindow", levWinProp, renderer);
 
   node->SetProperty("labelset.contour.active", BoolProperty::New(true), renderer);
   node->SetProperty("labelset.contour.width", FloatProperty::New(2.0), renderer);
 
   Superclass::SetDefaultProperties(node, renderer, overwrite);
 }
 
 mitk::LabelSetImageVtkMapper2D::LocalStorage::~LocalStorage()
 {
 }
 
 mitk::LabelSetImageVtkMapper2D::LocalStorage::LocalStorage()
 {
   // Do as much actions as possible in here to avoid double executions.
   m_Plane = vtkSmartPointer<vtkPlaneSource>::New();
   m_Actors = vtkSmartPointer<vtkPropAssembly>::New();
   m_OutlinePolyData = vtkSmartPointer<vtkPolyData>::New();
   m_EmptyPolyData = vtkSmartPointer<vtkPolyData>::New();
   m_OutlineActor = vtkSmartPointer<vtkActor>::New();
   m_OutlineMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
   m_OutlineShadowActor = vtkSmartPointer<vtkActor>::New();
 
   m_NumberOfLayers = 0;
   m_mmPerPixel = nullptr;
 
   m_OutlineActor->SetMapper(m_OutlineMapper);
   m_OutlineShadowActor->SetMapper(m_OutlineMapper);
 
   m_OutlineActor->SetVisibility(false);
   m_OutlineShadowActor->SetVisibility(false);
 }
diff --git a/Modules/SegmentationUI/Qmitk/QmitkSliceBasedInterpolatorWidget.cpp b/Modules/SegmentationUI/Qmitk/QmitkSliceBasedInterpolatorWidget.cpp
index 81080382e7..d731966d1f 100644
--- a/Modules/SegmentationUI/Qmitk/QmitkSliceBasedInterpolatorWidget.cpp
+++ b/Modules/SegmentationUI/Qmitk/QmitkSliceBasedInterpolatorWidget.cpp
@@ -1,710 +1,710 @@
 /*============================================================================
 
 The Medical Imaging Interaction Toolkit (MITK)
 
 Copyright (c) German Cancer Research Center (DKFZ)
 All rights reserved.
 
 Use of this source code is governed by a 3-clause BSD license that can be
 found in the LICENSE file.
 
 ============================================================================*/
 
 #include "QmitkSliceBasedInterpolatorWidget.h"
 
 #include <mitkColorProperty.h>
 #include <mitkDiffSliceOperation.h>
 #include <mitkDiffSliceOperationApplier.h>
 #include <mitkExtractSliceFilter.h>
 #include <mitkImageAccessByItk.h>
 #include <mitkImageCast.h>
 #include <mitkImageTimeSelector.h>
 #include <mitkLabelSetImage.h>
 #include <mitkOperationEvent.h>
 #include <mitkProgressBar.h>
 #include <mitkProperties.h>
 #include <mitkRenderingManager.h>
 #include <mitkSegTool2D.h>
 #include <mitkSliceNavigationController.h>
 #include <mitkToolManager.h>
 #include <mitkToolManagerProvider.h>
 #include <mitkUndoController.h>
 #include <mitkVtkImageOverwrite.h>
 
 #include "QmitkStdMultiWidget.h"
 
 #include <itkCommand.h>
 
 #include <QApplication>
 #include <QCursor>
 #include <QMenu>
 #include <QMessageBox>
 
 QmitkSliceBasedInterpolatorWidget::QmitkSliceBasedInterpolatorWidget(QWidget *parent, const char * /*name*/)
   : QWidget(parent),
     m_SliceInterpolatorController(mitk::SliceBasedInterpolationController::New()),
     m_ToolManager(nullptr),
     m_Activated(false),
     m_DataStorage(nullptr),
     m_LastSNC(nullptr),
     m_LastSliceIndex(0)
 {
   m_Controls.setupUi(this);
 
   m_ToolManager = mitk::ToolManagerProvider::GetInstance()->GetToolManager(mitk::ToolManagerProvider::MULTILABEL_SEGMENTATION);
 
   m_ToolManager->WorkingDataChanged += mitk::MessageDelegate<QmitkSliceBasedInterpolatorWidget>(
     this, &QmitkSliceBasedInterpolatorWidget::OnToolManagerWorkingDataModified);
 
   connect(m_Controls.m_btStart, SIGNAL(toggled(bool)), this, SLOT(OnToggleWidgetActivation(bool)));
   connect(m_Controls.m_btApplyForCurrentSlice, SIGNAL(clicked()), this, SLOT(OnAcceptInterpolationClicked()));
   connect(m_Controls.m_btApplyForAllSlices, SIGNAL(clicked()), this, SLOT(OnAcceptAllInterpolationsClicked()));
 
   itk::ReceptorMemberCommand<QmitkSliceBasedInterpolatorWidget>::Pointer command =
     itk::ReceptorMemberCommand<QmitkSliceBasedInterpolatorWidget>::New();
   command->SetCallbackFunction(this, &QmitkSliceBasedInterpolatorWidget::OnSliceInterpolationInfoChanged);
   m_InterpolationInfoChangedObserverTag = m_SliceInterpolatorController->AddObserver(itk::ModifiedEvent(), command);
 
   // feedback node and its visualization properties
   m_PreviewNode = mitk::DataNode::New();
   m_PreviewNode->SetName("3D tool preview");
 
   m_PreviewNode->SetProperty("texture interpolation", mitk::BoolProperty::New(false));
   m_PreviewNode->SetProperty("layer", mitk::IntProperty::New(100));
   m_PreviewNode->SetProperty("binary", mitk::BoolProperty::New(true));
   m_PreviewNode->SetProperty("outline binary", mitk::BoolProperty::New(true));
   m_PreviewNode->SetProperty("outline binary shadow", mitk::BoolProperty::New(true));
   m_PreviewNode->SetProperty("helper object", mitk::BoolProperty::New(true));
   m_PreviewNode->SetOpacity(1.0);
   m_PreviewNode->SetColor(0.0, 1.0, 0.0);
 
   m_Controls.m_btApplyForCurrentSlice->setEnabled(false);
   m_Controls.m_btApplyForAllSlices->setEnabled(false);
 
   this->setEnabled(false);
 }
 
 QmitkSliceBasedInterpolatorWidget::~QmitkSliceBasedInterpolatorWidget()
 {
   m_ToolManager->WorkingDataChanged -= mitk::MessageDelegate<QmitkSliceBasedInterpolatorWidget>(
     this, &QmitkSliceBasedInterpolatorWidget::OnToolManagerWorkingDataModified);
 
   foreach (mitk::SliceNavigationController *slicer, m_ControllerToSliceObserverTag.keys())
   {
     slicer->RemoveObserver(m_ControllerToDeleteObserverTag.take(slicer));
     slicer->RemoveObserver(m_ControllerToTimeObserverTag.take(slicer));
     slicer->RemoveObserver(m_ControllerToSliceObserverTag.take(slicer));
   }
 
   m_ActionToSliceDimensionMap.clear();
 
   // remove observer
   m_SliceInterpolatorController->RemoveObserver(m_InterpolationInfoChangedObserverTag);
 }
 
 const QmitkSliceBasedInterpolatorWidget::ActionToSliceDimensionMapType
   QmitkSliceBasedInterpolatorWidget::CreateActionToSliceDimension()
 {
   ActionToSliceDimensionMapType actionToSliceDimension;
   foreach (mitk::SliceNavigationController *slicer, m_ControllerToDeleteObserverTag.keys())
   {
     std::string name = slicer->GetRenderer()->GetName();
     if (name == "stdmulti.widget0")
       name = "Axial (red window)";
     else if (name == "stdmulti.widget1")
       name = "Sagittal (green window)";
     else if (name == "stdmulti.widget2")
       name = "Coronal (blue window)";
     actionToSliceDimension[new QAction(QString::fromStdString(name), nullptr)] = slicer;
   }
 
   return actionToSliceDimension;
 }
 
 void QmitkSliceBasedInterpolatorWidget::SetDataStorage(mitk::DataStorage &storage)
 {
   m_DataStorage = &storage;
 }
 
 void QmitkSliceBasedInterpolatorWidget::SetSliceNavigationControllers(
   const QList<mitk::SliceNavigationController *> &controllers)
 {
   Q_ASSERT(!controllers.empty());
 
   // connect to the slice navigation controller. after each change, call the interpolator
   foreach (mitk::SliceNavigationController *slicer, controllers)
   {
     // Has to be initialized
     m_LastSNC = slicer;
 
     m_TimePoints.insert(slicer, slicer->GetSelectedTimePoint());
 
     itk::MemberCommand<QmitkSliceBasedInterpolatorWidget>::Pointer deleteCommand =
       itk::MemberCommand<QmitkSliceBasedInterpolatorWidget>::New();
     deleteCommand->SetCallbackFunction(this, &QmitkSliceBasedInterpolatorWidget::OnSliceNavigationControllerDeleted);
     m_ControllerToDeleteObserverTag.insert(slicer, slicer->AddObserver(itk::DeleteEvent(), deleteCommand));
 
     itk::MemberCommand<QmitkSliceBasedInterpolatorWidget>::Pointer timeChangedCommand =
       itk::MemberCommand<QmitkSliceBasedInterpolatorWidget>::New();
     timeChangedCommand->SetCallbackFunction(this, &QmitkSliceBasedInterpolatorWidget::OnTimeChanged);
     m_ControllerToTimeObserverTag.insert(
       slicer,
       slicer->AddObserver(mitk::SliceNavigationController::TimeGeometryEvent(nullptr, 0), timeChangedCommand));
 
     itk::MemberCommand<QmitkSliceBasedInterpolatorWidget>::Pointer sliceChangedCommand =
       itk::MemberCommand<QmitkSliceBasedInterpolatorWidget>::New();
     sliceChangedCommand->SetCallbackFunction(this, &QmitkSliceBasedInterpolatorWidget::OnSliceChanged);
     m_ControllerToSliceObserverTag.insert(
       slicer, slicer->AddObserver(mitk::SliceNavigationController::GeometrySliceEvent(nullptr, 0), sliceChangedCommand));
   }
 
   m_ActionToSliceDimensionMap = this->CreateActionToSliceDimension();
 }
 
 void QmitkSliceBasedInterpolatorWidget::OnToolManagerWorkingDataModified()
 {
   mitk::DataNode *workingNode = this->m_ToolManager->GetWorkingData(0);
   if (!workingNode)
   {
     this->setEnabled(false);
     return;
   }
 
   mitk::LabelSetImage *workingImage = dynamic_cast<mitk::LabelSetImage *>(workingNode->GetData());
   // TODO adapt tool manager so that this check is done there, e.g. convenience function
   //  Q_ASSERT(workingImage);
   if (!workingImage)
   {
     this->setEnabled(false);
     return;
   }
 
   if (workingImage->GetDimension() > 4 || workingImage->GetDimension() < 3)
   {
     this->setEnabled(false);
     return;
   }
 
   m_WorkingImage = workingImage;
 
   this->setEnabled(true);
 }
 
 void QmitkSliceBasedInterpolatorWidget::OnTimeChanged(itk::Object *sender, const itk::EventObject &e)
 {
   // Check if we really have a GeometryTimeEvent
   if (!dynamic_cast<const mitk::SliceNavigationController::GeometryTimeEvent *>(&e))
     return;
 
   mitk::SliceNavigationController *slicer = dynamic_cast<mitk::SliceNavigationController *>(sender);
   Q_ASSERT(slicer);
 
   m_TimePoints[slicer] = slicer->GetSelectedTimePoint();
 
   // TODO Macht das hier wirklich Sinn????
   if (m_LastSNC == slicer)
   {
     slicer->SendSlice(); // will trigger a new interpolation
   }
 }
 
 void QmitkSliceBasedInterpolatorWidget::OnSliceChanged(itk::Object *sender, const itk::EventObject &e)
 {
   if (m_Activated && m_WorkingImage.IsNotNull())
   {
     // Check whether we really have a GeometrySliceEvent
     if (!dynamic_cast<const mitk::SliceNavigationController::GeometrySliceEvent *>(&e))
       return;
 
     mitk::SliceNavigationController *slicer = dynamic_cast<mitk::SliceNavigationController *>(sender);
     if (slicer)
     {
       this->TranslateAndInterpolateChangedSlice(e, slicer);
       mitk::RenderingManager::GetInstance()->RequestUpdateAll();
       //  slicer->GetRenderer()->RequestUpdate();
     }
   }
 }
 
 void QmitkSliceBasedInterpolatorWidget::TranslateAndInterpolateChangedSlice(const itk::EventObject &e,
                                                                             mitk::SliceNavigationController *slicer)
 {
   if (m_Activated && m_WorkingImage.IsNotNull())
   {
     const mitk::SliceNavigationController::GeometrySliceEvent &geometrySliceEvent =
       dynamic_cast<const mitk::SliceNavigationController::GeometrySliceEvent &>(e);
     mitk::TimeGeometry *timeGeometry = geometrySliceEvent.GetTimeGeometry();
     if (timeGeometry && m_TimePoints.contains(slicer) && timeGeometry->IsValidTimePoint(m_TimePoints[slicer]))
     {
       mitk::SlicedGeometry3D *slicedGeometry =
         dynamic_cast<mitk::SlicedGeometry3D *>(timeGeometry->GetGeometryForTimePoint(m_TimePoints[slicer]).GetPointer());
       if (slicedGeometry)
       {
         mitk::PlaneGeometry *plane = slicedGeometry->GetPlaneGeometry(geometrySliceEvent.GetPos());
         if (plane)
         {
           m_LastSNC = slicer;
           this->Interpolate(plane, m_TimePoints[slicer], slicer);
         }
       }
     }
   }
 }
 
 void QmitkSliceBasedInterpolatorWidget::Interpolate(mitk::PlaneGeometry *plane,
                                                     mitk::TimePointType timePoint,
                                                     mitk::SliceNavigationController *slicer)
 {
   int clickedSliceDimension(-1);
   int clickedSliceIndex(-1);
 
   if (!m_WorkingImage->GetTimeGeometry()->IsValidTimePoint(timePoint))
   {
     MITK_WARN << "Cannot interpolate WorkingImage. Passed time point is not within the time bounds of WorkingImage. Time point: " << timePoint;
     return;
   }
   const auto timeStep = m_WorkingImage->GetTimeGeometry()->TimePointToTimeStep(timePoint);
 
-  // calculate real slice position, i.e. slice of the image and not slice of the TimeSlicedGeometry
+  // calculate real slice position, i.e. slice of the image
   // see if timestep is needed here
   mitk::SegTool2D::DetermineAffectedImageSlice(m_WorkingImage, plane, clickedSliceDimension, clickedSliceIndex);
 
   mitk::Image::Pointer interpolation =
     m_SliceInterpolatorController->Interpolate(clickedSliceDimension, clickedSliceIndex, plane, timeStep);
 
   m_PreviewNode->SetData(interpolation);
 
   const mitk::Color &color = m_WorkingImage->GetActiveLabel()->GetColor();
   m_PreviewNode->SetColor(color);
 
   m_LastSNC = slicer;
   m_LastSliceIndex = clickedSliceIndex;
 }
 
 mitk::Image::Pointer QmitkSliceBasedInterpolatorWidget::GetWorkingSlice(const mitk::PlaneGeometry *planeGeometry)
 {
   const auto timePoint = m_LastSNC->GetSelectedTimePoint();
 
   if (!m_WorkingImage->GetTimeGeometry()->IsValidTimePoint(timePoint))
   {
     MITK_WARN << "Cannot get slice of WorkingImage. Time point selected by SliceNavigationController is not within the time bounds of WorkingImage. Time point: " << timePoint;
     return nullptr;
   }
 
   // Make sure that for reslicing and overwriting the same alogrithm is used. We can specify the mode of the vtk
   // reslicer
   vtkSmartPointer<mitkVtkImageOverwrite> reslice = vtkSmartPointer<mitkVtkImageOverwrite>::New();
   // set to false to extract a slice
   reslice->SetOverwriteMode(false);
   reslice->Modified();
 
   // use ExtractSliceFilter with our specific vtkImageReslice for overwriting and extracting
   mitk::ExtractSliceFilter::Pointer extractor = mitk::ExtractSliceFilter::New(reslice);
   extractor->SetInput(m_WorkingImage);
   const auto timeStep = m_WorkingImage->GetTimeGeometry()->TimePointToTimeStep(timePoint);
   extractor->SetTimeStep(timeStep);
   extractor->SetWorldGeometry(planeGeometry);
   extractor->SetVtkOutputRequest(false);
   extractor->SetResliceTransformByGeometry(m_WorkingImage->GetTimeGeometry()->GetGeometryForTimeStep(timeStep));
 
   extractor->Modified();
 
   try
   {
     extractor->Update();
   }
   catch (itk::ExceptionObject &excep)
   {
     MITK_ERROR << "Exception caught: " << excep.GetDescription();
     return nullptr;
   }
 
   mitk::Image::Pointer slice = extractor->GetOutput();
 
   // specify the undo operation with the non edited slice
   // MLI TODO added code starts here
   mitk::SlicedGeometry3D *sliceGeometry = dynamic_cast<mitk::SlicedGeometry3D *>(slice->GetGeometry());
   // m_undoOperation = new mitk::DiffSliceOperation(m_WorkingImage, extractor->GetVtkOutput(), slice->GetGeometry(),
   // timeStep, const_cast<mitk::PlaneGeometry*>(planeGeometry));
   // added code ends here
   m_undoOperation = new mitk::DiffSliceOperation(
     m_WorkingImage, extractor->GetOutput(), sliceGeometry, timeStep, const_cast<mitk::PlaneGeometry *>(planeGeometry));
 
   slice->DisconnectPipeline();
 
   return slice;
 }
 
 void QmitkSliceBasedInterpolatorWidget::OnToggleWidgetActivation(bool enabled)
 {
   Q_ASSERT(m_ToolManager);
 
   mitk::DataNode *workingNode = m_ToolManager->GetWorkingData(0);
   if (!workingNode)
     return;
 
   m_Controls.m_btApplyForCurrentSlice->setEnabled(enabled);
   m_Controls.m_btApplyForAllSlices->setEnabled(enabled);
 
   if (enabled)
     m_Controls.m_btStart->setText("Stop");
   else
     m_Controls.m_btStart->setText("Start");
 
   unsigned int numberOfExistingTools = m_ToolManager->GetTools().size();
   for (unsigned int i = 0; i < numberOfExistingTools; i++)
   {
     // mitk::SegTool2D* tool = dynamic_cast<mitk::SegTool2D*>(m_ToolManager->GetToolById(i));
     // MLI TODO
     // if (tool) tool->SetEnable2DInterpolation( enabled );
   }
 
   if (enabled)
   {
     if (!m_DataStorage->Exists(m_PreviewNode))
     {
       m_DataStorage->Add(m_PreviewNode);
     }
 
     m_SliceInterpolatorController->SetWorkingImage(m_WorkingImage);
     this->UpdateVisibleSuggestion();
   }
   else
   {
     if (m_DataStorage->Exists(m_PreviewNode))
     {
       m_DataStorage->Remove(m_PreviewNode);
     }
 
     mitk::UndoController::GetCurrentUndoModel()->Clear();
   }
 
   m_Activated = enabled;
 
   mitk::RenderingManager::GetInstance()->RequestUpdateAll();
 }
 
 template <typename TPixel, unsigned int VImageDimension>
 void QmitkSliceBasedInterpolatorWidget::WritePreviewOnWorkingImage(itk::Image<TPixel, VImageDimension> *targetSlice,
                                                                    const mitk::Image *sourceSlice,
                                                                    int overwritevalue)
 {
   typedef itk::Image<TPixel, VImageDimension> ImageType;
 
   typename ImageType::Pointer sourceSliceITK;
   mitk::CastToItkImage(sourceSlice, sourceSliceITK);
 
   // now the original slice and the ipSegmentation-painted slice are in the same format, and we can just copy all pixels
   // that are non-zero
   typedef itk::ImageRegionIterator<ImageType> OutputIteratorType;
   typedef itk::ImageRegionConstIterator<ImageType> InputIteratorType;
 
   InputIteratorType inputIterator(sourceSliceITK, sourceSliceITK->GetLargestPossibleRegion());
   OutputIteratorType outputIterator(targetSlice, targetSlice->GetLargestPossibleRegion());
 
   outputIterator.GoToBegin();
   inputIterator.GoToBegin();
 
   int activePixelValue = m_WorkingImage->GetActiveLabel()->GetValue();
 
   if (activePixelValue == 0) // if exterior is the active label
   {
     while (!outputIterator.IsAtEnd())
     {
       if (inputIterator.Get() != 0)
       {
         outputIterator.Set(overwritevalue);
       }
       ++outputIterator;
       ++inputIterator;
     }
   }
   else if (overwritevalue != 0) // if we are not erasing
   {
     while (!outputIterator.IsAtEnd())
     {
       int targetValue = static_cast<int>(outputIterator.Get());
       if (inputIterator.Get() != 0)
       {
         if (!m_WorkingImage->GetLabel(targetValue)->GetLocked())
           outputIterator.Set(overwritevalue);
       }
 
       ++outputIterator;
       ++inputIterator;
     }
   }
   else // if we are erasing
   {
     while (!outputIterator.IsAtEnd())
     {
       const int targetValue = outputIterator.Get();
       if (inputIterator.Get() != 0)
       {
         if (targetValue == activePixelValue)
           outputIterator.Set(overwritevalue);
       }
 
       ++outputIterator;
       ++inputIterator;
     }
   }
 }
 
 void QmitkSliceBasedInterpolatorWidget::OnAcceptInterpolationClicked()
 {
   if (m_WorkingImage.IsNotNull() && m_PreviewNode->GetData())
   {
     const mitk::PlaneGeometry *planeGeometry = m_LastSNC->GetCurrentPlaneGeometry();
     if (!planeGeometry)
       return;
 
     mitk::Image::Pointer sliceImage = this->GetWorkingSlice(planeGeometry);
     if (sliceImage.IsNull())
       return;
 
     mitk::Image::Pointer previewSlice = dynamic_cast<mitk::Image *>(m_PreviewNode->GetData());
 
     AccessFixedDimensionByItk_2(
       sliceImage, WritePreviewOnWorkingImage, 2, previewSlice, m_WorkingImage->GetActiveLabel()->GetValue());
 
     // Make sure that for reslicing and overwriting the same alogrithm is used. We can specify the mode of the vtk
     // reslicer
     vtkSmartPointer<mitkVtkImageOverwrite> overwrite = vtkSmartPointer<mitkVtkImageOverwrite>::New();
     overwrite->SetInputSlice(sliceImage->GetVtkImageData());
     // set overwrite mode to true to write back to the image volume
     overwrite->SetOverwriteMode(true);
     overwrite->Modified();
 
     const auto timePoint = m_LastSNC->GetSelectedTimePoint();
     if (!m_WorkingImage->GetTimeGeometry()->IsValidTimePoint(timePoint))
     {
       MITK_WARN << "Cannot accept interpolation. Time point selected by SliceNavigationController is not within the time bounds of WorkingImage. Time point: " << timePoint;
       return;
     }
 
     mitk::ExtractSliceFilter::Pointer extractor = mitk::ExtractSliceFilter::New(overwrite);
     extractor->SetInput(m_WorkingImage);
     const auto timeStep = m_WorkingImage->GetTimeGeometry()->TimePointToTimeStep(timePoint);
     extractor->SetTimeStep(timeStep);
     extractor->SetWorldGeometry(planeGeometry);
     extractor->SetVtkOutputRequest(false);
     extractor->SetResliceTransformByGeometry(m_WorkingImage->GetTimeGeometry()->GetGeometryForTimeStep(timeStep));
 
     extractor->Modified();
 
     try
     {
       extractor->Update();
     }
     catch (itk::ExceptionObject &excep)
     {
       MITK_ERROR << "Exception caught: " << excep.GetDescription();
       return;
     }
 
     // the image was modified within the pipeline, but not marked so
     m_WorkingImage->Modified();
 
     int clickedSliceDimension(-1);
     int clickedSliceIndex(-1);
 
     mitk::SegTool2D::DetermineAffectedImageSlice(
       m_WorkingImage, planeGeometry, clickedSliceDimension, clickedSliceIndex);
 
     m_SliceInterpolatorController->SetChangedSlice(sliceImage, clickedSliceDimension, clickedSliceIndex, timeStep);
 
     // specify the undo operation with the edited slice
     // MLI TODO added code starts here
     mitk::SlicedGeometry3D *sliceGeometry = dynamic_cast<mitk::SlicedGeometry3D *>(sliceImage->GetGeometry());
     // m_undoOperation = new mitk::DiffSliceOperation(m_WorkingImage, extractor->GetVtkOutput(), slice->GetGeometry(),
     // timeStep, const_cast<mitk::PlaneGeometry*>(planeGeometry));
     // added code ends here
     m_doOperation = new mitk::DiffSliceOperation(m_WorkingImage,
                                                  extractor->GetOutput(),
                                                  sliceGeometry,
                                                  timeStep,
                                                  const_cast<mitk::PlaneGeometry *>(planeGeometry));
 
     // create an operation event for the undo stack
     mitk::OperationEvent *undoStackItem = new mitk::OperationEvent(
       mitk::DiffSliceOperationApplier::GetInstance(), m_doOperation, m_undoOperation, "Slice Interpolation");
 
     // add it to the undo controller
     mitk::UndoController::GetCurrentUndoModel()->SetOperationEvent(undoStackItem);
 
     // clear the pointers as the operation are stored in the undo controller and also deleted from there
     m_undoOperation = nullptr;
     m_doOperation = nullptr;
 
     m_PreviewNode->SetData(nullptr);
 
     mitk::RenderingManager::GetInstance()->RequestUpdateAll();
   }
 }
 
 void QmitkSliceBasedInterpolatorWidget::AcceptAllInterpolations(mitk::SliceNavigationController *slicer)
 {
   // Since we need to shift the plane it must be clone so that the original plane isn't altered
   mitk::PlaneGeometry::Pointer reslicePlane = slicer->GetCurrentPlaneGeometry()->Clone();
   const auto timePoint = slicer->GetSelectedTimePoint();
   if (!m_WorkingImage->GetTimeGeometry()->IsValidTimePoint(timePoint))
   {
     MITK_WARN << "Cannot accept all interpolations. Time point selected by SliceNavigationController is not within the time bounds of WorkingImage. Time point: " << timePoint;
 
     return;
   }
   const auto timeStep = m_WorkingImage->GetTimeGeometry()->TimePointToTimeStep(timePoint);
 
   int sliceDimension(-1);
   int sliceIndex(-1);
 
   mitk::SegTool2D::DetermineAffectedImageSlice(m_WorkingImage, reslicePlane, sliceDimension, sliceIndex);
 
   unsigned int zslices = m_WorkingImage->GetDimension(sliceDimension);
 
   mitk::ProgressBar::GetInstance()->Reset();
   mitk::ProgressBar::GetInstance()->AddStepsToDo(zslices);
 
   mitk::Point3D origin = reslicePlane->GetOrigin();
 
   for (unsigned int idx = 0; idx < zslices; ++idx)
   {
     // Transforming the current origin of the reslice plane
     // so that it matches the one of the next slice
     m_WorkingImage->GetSlicedGeometry()->WorldToIndex(origin, origin);
     origin[sliceDimension] = idx;
     m_WorkingImage->GetSlicedGeometry()->IndexToWorld(origin, origin);
     reslicePlane->SetOrigin(origin);
 
     mitk::Image::Pointer interpolation =
       m_SliceInterpolatorController->Interpolate(sliceDimension, idx, reslicePlane, timeStep);
 
     if (interpolation.IsNotNull())
     {
       m_PreviewNode->SetData(interpolation);
 
       mitk::Image::Pointer sliceImage = this->GetWorkingSlice(reslicePlane);
       if (sliceImage.IsNull())
         return;
 
       AccessFixedDimensionByItk_2(
         sliceImage, WritePreviewOnWorkingImage, 2, interpolation, m_WorkingImage->GetActiveLabel()->GetValue());
 
       // Make sure that for reslicing and overwriting the same alogrithm is used. We can specify the mode of the vtk
       // reslicer
       vtkSmartPointer<mitkVtkImageOverwrite> overwrite = vtkSmartPointer<mitkVtkImageOverwrite>::New();
       overwrite->SetInputSlice(sliceImage->GetVtkImageData());
       // set overwrite mode to true to write back to the image volume
       overwrite->SetOverwriteMode(true);
       overwrite->Modified();
 
       mitk::ExtractSliceFilter::Pointer extractor = mitk::ExtractSliceFilter::New(overwrite);
       extractor->SetInput(m_WorkingImage);
       extractor->SetTimeStep(timeStep);
       extractor->SetWorldGeometry(reslicePlane);
       extractor->SetVtkOutputRequest(true);
       extractor->SetResliceTransformByGeometry(m_WorkingImage->GetTimeGeometry()->GetGeometryForTimeStep(timeStep));
 
       extractor->Modified();
 
       try
       {
         extractor->Update();
       }
       catch (itk::ExceptionObject &excep)
       {
         MITK_ERROR << "Exception caught: " << excep.GetDescription();
         return;
       }
 
       m_WorkingImage->Modified();
 
       mitk::RenderingManager::GetInstance()->RequestUpdateAll(mitk::RenderingManager::REQUEST_UPDATE_2DWINDOWS);
     }
 
     mitk::ProgressBar::GetInstance()->Progress();
   }
 
   m_SliceInterpolatorController->SetWorkingImage(m_WorkingImage);
 
   mitk::RenderingManager::GetInstance()->RequestUpdateAll();
 }
 
 void QmitkSliceBasedInterpolatorWidget::OnAcceptAllInterpolationsClicked()
 {
   QMenu orientationPopup(this);
   std::map<QAction *, mitk::SliceNavigationController *>::const_iterator it;
   for (it = m_ActionToSliceDimensionMap.begin(); it != m_ActionToSliceDimensionMap.end(); it++)
     orientationPopup.addAction(it->first);
 
   connect(&orientationPopup, SIGNAL(triggered(QAction *)), this, SLOT(OnAcceptAllPopupActivated(QAction *)));
 
   orientationPopup.exec(QCursor::pos());
 }
 
 void QmitkSliceBasedInterpolatorWidget::OnAcceptAllPopupActivated(QAction *action)
 {
   ActionToSliceDimensionMapType::const_iterator iter = m_ActionToSliceDimensionMap.find(action);
   if (iter != m_ActionToSliceDimensionMap.end())
   {
     mitk::SliceNavigationController *slicer = iter->second;
     this->AcceptAllInterpolations(slicer);
   }
 }
 
 void QmitkSliceBasedInterpolatorWidget::UpdateVisibleSuggestion()
 {
   if (m_Activated && m_LastSNC)
   {
     // determine which one is the current view, try to do an initial interpolation
     mitk::BaseRenderer *renderer = m_LastSNC->GetRenderer();
     if (renderer && renderer->GetMapperID() == mitk::BaseRenderer::Standard2D)
     {
       const mitk::TimeGeometry *timeGeometry =
         dynamic_cast<const mitk::TimeGeometry *>(renderer->GetWorldTimeGeometry());
       if (timeGeometry)
       {
         mitk::SliceNavigationController::GeometrySliceEvent event(const_cast<mitk::TimeGeometry *>(timeGeometry),
                                                                   renderer->GetSlice());
         this->TranslateAndInterpolateChangedSlice(event, m_LastSNC);
         mitk::RenderingManager::GetInstance()->RequestUpdateAll();
       }
     }
   }
 }
 
 void QmitkSliceBasedInterpolatorWidget::OnSliceInterpolationInfoChanged(const itk::EventObject & /*e*/)
 {
   // something (e.g. undo) changed the interpolation info, we should refresh our display
   this->UpdateVisibleSuggestion();
 }
 
 void QmitkSliceBasedInterpolatorWidget::OnSliceNavigationControllerDeleted(const itk::Object *sender,
                                                                            const itk::EventObject & /*e*/)
 {
   // Don't know how to avoid const_cast here?!
   mitk::SliceNavigationController *slicer =
     dynamic_cast<mitk::SliceNavigationController *>(const_cast<itk::Object *>(sender));
   if (slicer)
   {
     m_ControllerToTimeObserverTag.remove(slicer);
     m_ControllerToSliceObserverTag.remove(slicer);
     m_ControllerToDeleteObserverTag.remove(slicer);
   }
 }
 
 void QmitkSliceBasedInterpolatorWidget::WaitCursorOn()
 {
   QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
 }
 
 void QmitkSliceBasedInterpolatorWidget::WaitCursorOff()
 {
   this->RestoreOverrideCursor();
 }
 
 void QmitkSliceBasedInterpolatorWidget::RestoreOverrideCursor()
 {
   QApplication::restoreOverrideCursor();
 }
diff --git a/Modules/SegmentationUI/Qmitk/QmitkSlicesInterpolator.cpp b/Modules/SegmentationUI/Qmitk/QmitkSlicesInterpolator.cpp
index 6820efbc3b..8353719169 100644
--- a/Modules/SegmentationUI/Qmitk/QmitkSlicesInterpolator.cpp
+++ b/Modules/SegmentationUI/Qmitk/QmitkSlicesInterpolator.cpp
@@ -1,1405 +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
+        // calculate real slice position, i.e. slice of the image
         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();
   }
 }