diff --git a/Modules/ContourModel/Rendering/mitkContourModelMapper3D.cpp b/Modules/ContourModel/Rendering/mitkContourModelMapper3D.cpp
index 03fa9641fc..e6b499da4b 100644
--- a/Modules/ContourModel/Rendering/mitkContourModelMapper3D.cpp
+++ b/Modules/ContourModel/Rendering/mitkContourModelMapper3D.cpp
@@ -1,233 +1,233 @@
 /*============================================================================
 
 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 <mitkContourModelMapper3D.h>
 
 #include <vtkCellArray.h>
 #include <vtkPoints.h>
 #include <vtkProperty.h>
 
 mitk::ContourModelMapper3D::ContourModelMapper3D()
 {
 }
 
 mitk::ContourModelMapper3D::~ContourModelMapper3D()
 {
 }
 
 const mitk::ContourModel *mitk::ContourModelMapper3D::GetInput(void)
 {
   // convient way to get the data from the dataNode
   return static_cast<const mitk::ContourModel *>(GetDataNode()->GetData());
 }
 
 vtkProp *mitk::ContourModelMapper3D::GetVtkProp(mitk::BaseRenderer *renderer)
 {
   // return the actor corresponding to the renderer
   return m_LSH.GetLocalStorage(renderer)->m_Actor;
 }
 
 void mitk::ContourModelMapper3D::GenerateDataForRenderer(mitk::BaseRenderer *renderer)
 {
   /* First convert the contourModel to vtkPolyData, then tube filter it and
    * set it input for our mapper
    */
 
   LocalStorage *localStorage = m_LSH.GetLocalStorage(renderer);
 
   auto *inputContour = static_cast<mitk::ContourModel *>(GetDataNode()->GetData());
 
   localStorage->m_OutlinePolyData = this->CreateVtkPolyDataFromContour(inputContour);
 
   this->ApplyContourProperties(renderer);
 
   // tube filter the polyData
   localStorage->m_TubeFilter->SetInputData(localStorage->m_OutlinePolyData);
 
   float lineWidth(1.0);
   if (this->GetDataNode()->GetFloatProperty("contour.3D.width", lineWidth, renderer))
   {
     localStorage->m_TubeFilter->SetRadius(lineWidth);
   }
   else
   {
     localStorage->m_TubeFilter->SetRadius(0.5);
   }
   localStorage->m_TubeFilter->CappingOn();
   localStorage->m_TubeFilter->SetNumberOfSides(10);
   localStorage->m_TubeFilter->Update();
   localStorage->m_Mapper->SetInputConnection(localStorage->m_TubeFilter->GetOutputPort());
 }
 
 void mitk::ContourModelMapper3D::Update(mitk::BaseRenderer *renderer)
 {
   bool visible = true;
   GetDataNode()->GetVisibility(visible, renderer, "visible");
 
   auto *data = static_cast<mitk::ContourModel *>(GetDataNode()->GetData());
   if (data == nullptr)
   {
     return;
   }
 
   // Calculate time step of the input data for the specified renderer (integer value)
   this->CalculateTimeStep(renderer);
 
   LocalStorage *localStorage = m_LSH.GetLocalStorage(renderer);
   // Check if time step is valid
   const TimeGeometry *dataTimeGeometry = data->GetTimeGeometry();
   if ((dataTimeGeometry == nullptr) || (dataTimeGeometry->CountTimeSteps() == 0) ||
-      (!dataTimeGeometry->IsValidTimePoint(renderer->GetTime())) || (this->GetTimestep() == -1))
+      (!dataTimeGeometry->IsValidTimePoint(renderer->GetTime())) || (this->GetTimestep() == TIMESTEP_INVALID))
   {
     // clear the rendered polydata
     localStorage->m_Mapper->SetInputData(vtkSmartPointer<vtkPolyData>::New());
     return;
   }
 
   const DataNode *node = this->GetDataNode();
   data->UpdateOutputInformation();
 
   // check if something important has changed and we need to rerender
   if ((localStorage->m_LastUpdateTime < node->GetMTime()) // was the node modified?
       ||
       (localStorage->m_LastUpdateTime < data->GetPipelineMTime()) // Was the data modified?
       ||
       (localStorage->m_LastUpdateTime <
        renderer->GetCurrentWorldPlaneGeometryUpdateTime()) // was the geometry modified?
       ||
       (localStorage->m_LastUpdateTime < renderer->GetCurrentWorldPlaneGeometry()->GetMTime()) ||
       (localStorage->m_LastUpdateTime < node->GetPropertyList()->GetMTime()) // was a property modified?
       ||
       (localStorage->m_LastUpdateTime < node->GetPropertyList(renderer)->GetMTime()))
   {
     this->GenerateDataForRenderer(renderer);
   }
 
   // since we have checked that nothing important has changed, we can set
   // m_LastUpdateTime to the current time
   localStorage->m_LastUpdateTime.Modified();
 }
 
 vtkSmartPointer<vtkPolyData> mitk::ContourModelMapper3D::CreateVtkPolyDataFromContour(mitk::ContourModel *inputContour)
 {
   const auto timestep = this->GetTimestep();
 
   // the points to draw
   vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
   // the lines to connect the points
   vtkSmartPointer<vtkCellArray> lines = vtkSmartPointer<vtkCellArray>::New();
   // Create a polydata to store everything in
   vtkSmartPointer<vtkPolyData> polyData = vtkSmartPointer<vtkPolyData>::New();
 
   // iterate over the control points
   auto current = inputContour->IteratorBegin(timestep);
   auto next = inputContour->IteratorBegin(timestep);
   if (next != inputContour->IteratorEnd(timestep))
   {
     next++;
 
     auto end = inputContour->IteratorEnd(timestep);
 
     while (next != end)
     {
       mitk::ContourModel::VertexType *currentControlPoint = *current;
       mitk::ContourModel::VertexType *nextControlPoint = *next;
 
       if (!(currentControlPoint->Coordinates[0] == nextControlPoint->Coordinates[0] &&
             currentControlPoint->Coordinates[1] == nextControlPoint->Coordinates[1] &&
             currentControlPoint->Coordinates[2] == nextControlPoint->Coordinates[2]))
       {
         vtkIdType p1 = points->InsertNextPoint(currentControlPoint->Coordinates[0],
                                                currentControlPoint->Coordinates[1],
                                                currentControlPoint->Coordinates[2]);
         vtkIdType p2 = points->InsertNextPoint(
           nextControlPoint->Coordinates[0], nextControlPoint->Coordinates[1], nextControlPoint->Coordinates[2]);
         // add the line between both contorlPoints
         lines->InsertNextCell(2);
         lines->InsertCellPoint(p1);
         lines->InsertCellPoint(p2);
       }
       current++;
       next++;
     }
 
     if (inputContour->IsClosed(timestep))
     {
       // If the contour is closed add a line from the last to the first control point
       mitk::ContourModel::VertexType *firstControlPoint = *(inputContour->IteratorBegin(timestep));
       mitk::ContourModel::VertexType *lastControlPoint = *(--(inputContour->IteratorEnd(timestep)));
       if (lastControlPoint->Coordinates[0] != firstControlPoint->Coordinates[0] ||
           lastControlPoint->Coordinates[1] != firstControlPoint->Coordinates[1] ||
           lastControlPoint->Coordinates[2] != firstControlPoint->Coordinates[2])
       {
         vtkIdType p2 = points->InsertNextPoint(
           lastControlPoint->Coordinates[0], lastControlPoint->Coordinates[1], lastControlPoint->Coordinates[2]);
         vtkIdType p1 = points->InsertNextPoint(
           firstControlPoint->Coordinates[0], firstControlPoint->Coordinates[1], firstControlPoint->Coordinates[2]);
 
         // add the line to the cellArray
         lines->InsertNextCell(2);
         lines->InsertCellPoint(p1);
         lines->InsertCellPoint(p2);
       }
     }
 
     // Add the points to the dataset
     polyData->SetPoints(points);
     // Add the lines to the dataset
     polyData->SetLines(lines);
   }
   return polyData;
 }
 
 void mitk::ContourModelMapper3D::ApplyContourProperties(mitk::BaseRenderer *renderer)
 {
   LocalStorage *localStorage = m_LSH.GetLocalStorage(renderer);
 
   mitk::ColorProperty::Pointer colorprop =
     dynamic_cast<mitk::ColorProperty *>(GetDataNode()->GetProperty("contour.color", renderer));
   if (colorprop)
   {
     // set the color of the contour
     double red = colorprop->GetColor().GetRed();
     double green = colorprop->GetColor().GetGreen();
     double blue = colorprop->GetColor().GetBlue();
     localStorage->m_Actor->GetProperty()->SetColor(red, green, blue);
   }
 }
 
 /*+++++++++++++++++++ LocalStorage part +++++++++++++++++++++++++*/
 
 mitk::ContourModelMapper3D::LocalStorage *mitk::ContourModelMapper3D::GetLocalStorage(mitk::BaseRenderer *renderer)
 {
   return m_LSH.GetLocalStorage(renderer);
 }
 
 mitk::ContourModelMapper3D::LocalStorage::LocalStorage()
 {
   m_Mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
   m_Actor = vtkSmartPointer<vtkActor>::New();
   m_OutlinePolyData = vtkSmartPointer<vtkPolyData>::New();
   m_TubeFilter = vtkSmartPointer<vtkTubeFilter>::New();
 
   // set the mapper for the actor
   m_Actor->SetMapper(m_Mapper);
 }
 
 void mitk::ContourModelMapper3D::SetDefaultProperties(mitk::DataNode *node,
                                                       mitk::BaseRenderer *renderer,
                                                       bool overwrite)
 {
   node->AddProperty("color", ColorProperty::New(1.0, 0.0, 0.0), renderer, overwrite);
   node->AddProperty("contour.3D.width", mitk::FloatProperty::New(0.5), renderer, overwrite);
 
   Superclass::SetDefaultProperties(node, renderer, overwrite);
 }
diff --git a/Modules/ContourModel/Rendering/mitkContourModelSetMapper3D.cpp b/Modules/ContourModel/Rendering/mitkContourModelSetMapper3D.cpp
index cab6397f83..fa22fc0cbb 100644
--- a/Modules/ContourModel/Rendering/mitkContourModelSetMapper3D.cpp
+++ b/Modules/ContourModel/Rendering/mitkContourModelSetMapper3D.cpp
@@ -1,232 +1,232 @@
 /*============================================================================
 
 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 <mitkContourModelSetMapper3D.h>
 
 #include "mitkSurface.h"
 #include <vtkCellArray.h>
 #include <vtkPoints.h>
 #include <vtkPolyLine.h>
 #include <vtkProperty.h>
 
 mitk::ContourModelSetMapper3D::ContourModelSetMapper3D()
 {
 }
 
 mitk::ContourModelSetMapper3D::~ContourModelSetMapper3D()
 {
 }
 
 const mitk::ContourModelSet *mitk::ContourModelSetMapper3D::GetInput(void)
 {
   // convenient way to get the data from the dataNode
   return static_cast<const mitk::ContourModelSet *>(GetDataNode()->GetData());
 }
 
 vtkProp *mitk::ContourModelSetMapper3D::GetVtkProp(mitk::BaseRenderer *renderer)
 {
   // return the actor corresponding to the renderer
   return m_LSH.GetLocalStorage(renderer)->m_Assembly;
 }
 
 void mitk::ContourModelSetMapper3D::GenerateDataForRenderer(mitk::BaseRenderer *renderer)
 {
   /* First convert the contourModel to vtkPolyData, then tube filter it and
    * set it input for our mapper
    */
 
   LocalStorage *localStorage = m_LSH.GetLocalStorage(renderer);
 
   auto *contourModelSet = dynamic_cast<ContourModelSet *>(this->GetDataNode()->GetData());
 
   if (contourModelSet != nullptr)
   {
     vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
     vtkSmartPointer<vtkCellArray> cells = vtkSmartPointer<vtkCellArray>::New();
     vtkIdType baseIndex = 0;
 
     auto it = contourModelSet->Begin();
     auto end = contourModelSet->End();
 
     while (it != end)
     {
       ContourModel *contourModel = it->GetPointer();
 
       auto vertIt = contourModel->Begin();
       auto vertEnd = contourModel->End();
 
       while (vertIt != vertEnd)
       {
         points->InsertNextPoint((*vertIt)->Coordinates[0], (*vertIt)->Coordinates[1], (*vertIt)->Coordinates[2]);
         ++vertIt;
       }
 
       vtkSmartPointer<vtkPolyLine> line = vtkSmartPointer<vtkPolyLine>::New();
       vtkIdList *pointIds = line->GetPointIds();
 
       vtkIdType numPoints = contourModel->GetNumberOfVertices();
       pointIds->SetNumberOfIds(numPoints + 1);
 
       for (vtkIdType i = 0; i < numPoints; ++i)
         pointIds->SetId(i, baseIndex + i);
 
       pointIds->SetId(numPoints, baseIndex);
 
       cells->InsertNextCell(line);
 
       baseIndex += numPoints;
 
       ++it;
     }
 
     vtkSmartPointer<vtkPolyData> polyData = vtkSmartPointer<vtkPolyData>::New();
     polyData->SetPoints(points);
     polyData->SetLines(cells);
 
     vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
     vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
     actor->SetMapper(mapper);
 
     mapper->SetInputData(polyData);
 
     localStorage->m_Assembly->AddPart(actor);
   }
   this->ApplyContourProperties(renderer);
   this->ApplyContourModelSetProperties(renderer);
 }
 
 void mitk::ContourModelSetMapper3D::Update(mitk::BaseRenderer *renderer)
 {
   bool visible = true;
   GetDataNode()->GetVisibility(visible, renderer, "visible");
 
   auto *data = static_cast<mitk::ContourModel *>(GetDataNode()->GetData());
   if (data == nullptr)
   {
     return;
   }
 
   // Calculate time step of the input data for the specified renderer (integer value)
   this->CalculateTimeStep(renderer);
 
   LocalStorage *localStorage = m_LSH.GetLocalStorage(renderer);
 
-  if (this->GetTimestep() == -1)
+  if (this->GetTimestep() == TIMESTEP_INVALID)
   {
     return;
   }
 
   const DataNode *node = this->GetDataNode();
   data->UpdateOutputInformation();
 
   // check if something important has changed and we need to rerender
   if ((localStorage->m_LastUpdateTime < node->GetMTime()) // was the node modified?
       ||
       (localStorage->m_LastUpdateTime < data->GetPipelineMTime()) // Was the data modified?
       ||
       (localStorage->m_LastUpdateTime <
        renderer->GetCurrentWorldPlaneGeometryUpdateTime()) // was the geometry modified?
       ||
       (localStorage->m_LastUpdateTime < renderer->GetCurrentWorldPlaneGeometry()->GetMTime()) ||
       (localStorage->m_LastUpdateTime < node->GetPropertyList()->GetMTime()) // was a property modified?
       ||
       (localStorage->m_LastUpdateTime < node->GetPropertyList(renderer)->GetMTime()))
   {
     this->GenerateDataForRenderer(renderer);
   }
 
   // since we have checked that nothing important has changed, we can set
   // m_LastUpdateTime to the current time
   localStorage->m_LastUpdateTime.Modified();
 }
 
 vtkSmartPointer<vtkPolyData> mitk::ContourModelSetMapper3D::CreateVtkPolyDataFromContour(
   mitk::ContourModel *inputContour, mitk::BaseRenderer *renderer)
 {
   const auto timestep = this->GetTimestep();
 
   LocalStorage *localStorage = m_LSH.GetLocalStorage(renderer);
 
   localStorage->m_contourToPolyData->SetInput(inputContour);
   localStorage->m_contourToPolyData->Update();
 
   vtkSmartPointer<vtkPolyData> polyData = vtkSmartPointer<vtkPolyData>::New();
   polyData = localStorage->m_contourToPolyData->GetOutput()->GetVtkPolyData(timestep);
 
   return polyData;
 }
 
 void mitk::ContourModelSetMapper3D::ApplyContourModelSetProperties(BaseRenderer *renderer)
 {
   LocalStorage *localStorage = m_LSH.GetLocalStorage(renderer);
   DataNode *dataNode = this->GetDataNode();
 
   if (dataNode != nullptr)
   {
     float lineWidth = 1;
     dataNode->GetFloatProperty("contour.3D.width", lineWidth, renderer);
 
     vtkSmartPointer<vtkPropCollection> collection = vtkSmartPointer<vtkPropCollection>::New();
     localStorage->m_Assembly->GetActors(collection);
     collection->InitTraversal();
     for (vtkIdType i = 0; i < collection->GetNumberOfItems(); i++)
     {
       vtkActor::SafeDownCast(collection->GetNextProp())->GetProperty()->SetLineWidth(lineWidth);
     }
   }
 }
 
 void mitk::ContourModelSetMapper3D::ApplyContourProperties(mitk::BaseRenderer *renderer)
 {
   LocalStorage *localStorage = m_LSH.GetLocalStorage(renderer);
 
   mitk::ColorProperty::Pointer colorprop =
     dynamic_cast<mitk::ColorProperty *>(GetDataNode()->GetProperty("contour.color", renderer));
   if (colorprop)
   {
     // set the color of the contour
     double red = colorprop->GetColor().GetRed();
     double green = colorprop->GetColor().GetGreen();
     double blue = colorprop->GetColor().GetBlue();
 
     vtkSmartPointer<vtkPropCollection> collection = vtkSmartPointer<vtkPropCollection>::New();
     localStorage->m_Assembly->GetActors(collection);
     collection->InitTraversal();
     for (vtkIdType i = 0; i < collection->GetNumberOfItems(); i++)
     {
       vtkActor::SafeDownCast(collection->GetNextProp())->GetProperty()->SetColor(red, green, blue);
     }
   }
 }
 
 /*+++++++++++++++++++ LocalStorage part +++++++++++++++++++++++++*/
 
 mitk::ContourModelSetMapper3D::LocalStorage *mitk::ContourModelSetMapper3D::GetLocalStorage(
   mitk::BaseRenderer *renderer)
 {
   return m_LSH.GetLocalStorage(renderer);
 }
 
 mitk::ContourModelSetMapper3D::LocalStorage::LocalStorage()
 {
   m_Assembly = vtkSmartPointer<vtkAssembly>::New();
   m_contourToPolyData = mitk::ContourModelToSurfaceFilter::New();
 }
 
 void mitk::ContourModelSetMapper3D::SetDefaultProperties(mitk::DataNode *node,
                                                          mitk::BaseRenderer *renderer,
                                                          bool overwrite)
 {
   node->AddProperty("color", ColorProperty::New(1.0, 0.0, 0.0), renderer, overwrite);
   node->AddProperty("contour.3D.width", mitk::FloatProperty::New(0.5), renderer, overwrite);
 
   Superclass::SetDefaultProperties(node, renderer, overwrite);
 }
diff --git a/Modules/Core/include/mitkMapper.h b/Modules/Core/include/mitkMapper.h
index 17ee2d7719..d6c60ff7b0 100644
--- a/Modules/Core/include/mitkMapper.h
+++ b/Modules/Core/include/mitkMapper.h
@@ -1,211 +1,211 @@
 /*============================================================================
 
 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 mitkMapper_h
 #define mitkMapper_h
 
 #include "mitkBaseRenderer.h"
 #include "mitkCommon.h"
 #include "mitkLevelWindow.h"
 #include "mitkLocalStorageHandler.h"
 #include "mitkVtkPropRenderer.h"
 #include <MitkCoreExports.h>
 
 #include <itkObject.h>
 #include <itkWeakPointer.h>
 
 class vtkWindow;
 class vtkProp;
 
 namespace mitk
 {
   class BaseRenderer;
   class BaseData;
   class DataNode;
 
   /** \brief Base class of all mappers, Vtk as well as OpenGL mappers
   *
   * By the help of mappers, the input data is transformed to tangible primitives,
   * such as surfaces, points, lines, etc.
   * This is the base class of all mappers, Vtk as well as OpenGL mappers.
   * Subclasses of mitk::Mapper control the creation of rendering primitives
   * that interface to the graphics library (e.g., OpenGL, vtk).
   *
   * \todo Should Mapper be a subclass of ImageSource?
   * \ingroup Mapper
   */
   class MITKCORE_EXPORT Mapper : public itk::Object
   {
   public:
     mitkClassMacroItkParent(Mapper, itk::Object);
 
     /** \brief Set the DataNode containing the data to map */
     itkSetObjectMacro(DataNode, DataNode);
 
     /** \brief Get the DataNode containing the data to map.
     * Method only returns valid DataNode Pointer if the mapper belongs to a data node.
     * Otherwise, the returned DataNode Pointer might be invalid. */
     virtual DataNode *GetDataNode() const;
 
     /**\brief Get the data to map
     *
     * Returns the mitk::BaseData object associated with this mapper.
     * \return the mitk::BaseData associated with this mapper.
     * \deprecatedSince{2013_03} Use GetDataNode()->GetData() instead to access the data
     */
     DEPRECATED(BaseData *GetData() const);
 
     /** \brief Convenience access method for color properties (instances of
     * ColorProperty)
     * \return \a true property was found
     * \deprecatedSince{2013_03} Use GetDataNode()->GetColor(...) instead to get the color
     */
     DEPRECATED(virtual bool GetColor(float rgb[3], BaseRenderer *renderer, const char *name = "color") const);
 
     /** \brief Convenience access method for visibility properties (instances
     * of BoolProperty)
     * \return \a true property was found
     * \sa IsVisible
     * \deprecatedSince{2013_03} Use GetDataNode()->GetVisibility(...) instead to get the visibility
     */
     DEPRECATED(virtual bool GetVisibility(bool &visible, BaseRenderer *renderer, const char *name = "visible") const);
 
     /** \brief Convenience access method for opacity properties (instances of
     * FloatProperty)
     * \return \a true property was found
     * \deprecatedSince{2013_03} Use GetDataNode()->GetOpacity(...) instead to get the opacity
     */
     DEPRECATED(virtual bool GetOpacity(float &opacity, BaseRenderer *renderer, const char *name = "opacity") const);
 
     /** \brief Convenience access method for color properties (instances of
     * LevelWindoProperty)
     * \return \a true property was found
     * \deprecatedSince{2013_03} Use GetDataNode->GetLevelWindow(...) instead to get the levelwindow
     */
     DEPRECATED(virtual bool GetLevelWindow(LevelWindow &levelWindow,
                                            BaseRenderer *renderer,
                                            const char *name = "levelwindow") const);
 
     /** \brief Convenience access method for visibility properties (instances
     * of BoolProperty). Return value is the visibility. Default is
     * visible==true, i.e., true is returned even if the property (\a
     * propertyKey) is not found.
     *
     * Thus, the return value has a different meaning than in the
     * GetVisibility method!
     * \sa GetVisibility
     * \deprecatedSince{2013_03} Use GetDataNode()->GetVisibility(...) instead
     */
     DEPRECATED(virtual bool IsVisible(BaseRenderer *renderer, const char *name = "visible") const);
 
     /** \brief Returns whether this is an vtk-based mapper
    * \deprecatedSince{2013_03} All mappers of superclass VTKMapper are vtk based, use a dynamic_cast instead
    */
     virtual bool IsVtkBased() const { return true; }
 
     /** \brief Calls the time step of the input data for the specified renderer and checks
     * whether the time step is valid and calls method GenerateDataForRenderer()
     */
     virtual void Update(BaseRenderer *renderer);
 
     /** \brief Responsible for calling the appropriate render functions.
     *   To be implemented in sub-classes.
     */
     virtual void MitkRender(mitk::BaseRenderer *renderer, mitk::VtkPropRenderer::RenderType type) = 0;
 
     /**
     * \brief Apply specific color and opacity properties read from the PropertyList.
     * Reimplemented in GLmapper (does not use the actor) and the VtkMapper class.
     * The function is called by the individual mapper (mostly in the ApplyProperties() or ApplyAllProperties()
     * method).
     */
     virtual void ApplyColorAndOpacityProperties(mitk::BaseRenderer *renderer, vtkActor *actor = nullptr) = 0;
 
     /** \brief Set default values of properties used by this mapper
     * to \a node
     *
     * \param node The node for which the properties are set
     * \param overwrite overwrite existing properties (default: \a false)
     * \param renderer defines which property list of node is used
     * (default: \a nullptr, i.e. default property list)
     */
     static void SetDefaultProperties(DataNode *node, BaseRenderer *renderer = nullptr, bool overwrite = false);
 
     /** \brief Returns the current time step as calculated from the renderer */
-    int GetTimestep() const { return m_TimeStep; }
+    TimeStepType GetTimestep() const { return m_TimeStep; }
     /** Returns true if this Mapper currently allows for Level-of-Detail rendering.
      * This reflects whether this Mapper currently invokes StartEvent, EndEvent, and
      * ProgressEvent on BaseRenderer. */
     virtual bool IsLODEnabled(BaseRenderer * /*renderer*/) const { return false; }
   protected:
     /** \brief explicit constructor which disallows implicit conversions */
     explicit Mapper();
 
     /** \brief virtual destructor in order to derive from this class */
     ~Mapper() override;
 
     /** \brief Generate the data needed for rendering (independent of a specific renderer)
      *  \deprecatedSince{2013_03} Use GenerateDataForRenderer(BaseRenderer* renderer) instead.
      */
     DEPRECATED(virtual void GenerateData()) {}
     /** \brief Generate the data needed for rendering into \a renderer */
     virtual void GenerateDataForRenderer(BaseRenderer * /* renderer */) {}
     /** \brief Updates the time step, which is sometimes needed in subclasses */
     virtual void CalculateTimeStep(BaseRenderer *renderer);
 
     /** \brief Reset the mapper (i.e., make sure that nothing is displayed) if no
     * valid data is present. In most cases the reimplemented function
     * disables the according actors (toggling visibility off)
     *
     * To be implemented in sub-classes.
     */
     virtual void ResetMapper(BaseRenderer * /*renderer*/) {}
     mitk::DataNode *m_DataNode;
 
   private:
     /** \brief The current time step of the dataset to be rendered,
     * for use in subclasses.
     * The current timestep can be accessed via the GetTimestep() method.
     */
-    int m_TimeStep;
+    TimeStepType m_TimeStep;
 
     /** \brief copy constructor */
     Mapper(const Mapper &);
 
     /** \brief assignment operator */
     Mapper &operator=(const Mapper &);
 
   public:
     /** \brief Base class for mapper specific rendering resources.
      */
     class MITKCORE_EXPORT BaseLocalStorage
     {
     public:
       BaseLocalStorage() = default;
       virtual ~BaseLocalStorage() = default;
 
       BaseLocalStorage(const BaseLocalStorage &) = delete;
       BaseLocalStorage & operator=(const BaseLocalStorage &) = delete;
 
       bool IsGenerateDataRequired(mitk::BaseRenderer *renderer, mitk::Mapper *mapper, mitk::DataNode *dataNode) const;
 
       inline void UpdateGenerateDataTime() { m_LastGenerateDataTime.Modified(); }
       inline itk::TimeStamp &GetLastGenerateDataTime() { return m_LastGenerateDataTime; }
     protected:
       /** \brief timestamp of last update of stored data */
       itk::TimeStamp m_LastGenerateDataTime;
     };
   };
 
 } // namespace mitk
 
 #endif
diff --git a/Modules/Core/include/mitkTimeGeometry.h b/Modules/Core/include/mitkTimeGeometry.h
index de6de74c97..cfbd8c732e 100644
--- a/Modules/Core/include/mitkTimeGeometry.h
+++ b/Modules/Core/include/mitkTimeGeometry.h
@@ -1,349 +1,351 @@
 /*============================================================================
 
 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 mitkTimeGeometry_h
 #define mitkTimeGeometry_h
 
 // ITK
 #include <itkObject.h>
 // MITK
 #include "mitkOperationActor.h"
 #include <MitkCoreExports.h>
 #include <mitkBaseGeometry.h>
 #include <mitkCommon.h>
 
 namespace mitk
 {
   typedef mitk::ScalarType TimePointType;
   typedef std::size_t TimeStepType;
 
+  static const TimeStepType TIMESTEP_INVALID = -1;
+
   /**
   * \brief Manages the geometries of a data object for each time step
   *
   * This class is an abstract class. The concrete implementation
   * depends on the way the different time steps are managed.
   *
   * The time is defined either by a time step or a time point. Time steps
   * are non-negative integers starting from 0. A time point is a ScalarType value
   * which gives the passed time since start in ms. Be aware that the starting
   * point is not fixed so it is possible that the same time point  defines two
   * different time depending on the start time of the used time geometry.
   *
   * \addtogroup geometry
   */
   class MITKCORE_EXPORT TimeGeometry : public itk::Object, public OperationActor
   {
   protected:
     TimeGeometry();
     ~TimeGeometry() override;
 
     /**
     * \brief Contains a bounding box which includes all time steps
     */
     BoundingBox::Pointer m_BoundingBox;
 
     /**
     * \brief Makes a deep copy of the current object
     */
     LightObject::Pointer InternalClone() const override;
 
   public:
     mitkClassMacroItkParent(TimeGeometry, itk::Object);
     itkCloneMacro(Self);
     itkCreateAnotherMacro(Self);
 
       /**
       * \brief Returns the number of time steps.
       *
       * Returns the number of time steps for which
       * geometries are saved. The number of time steps
       * is also the upper bound of the time steps. The
       * minimum time steps is always 0.
       */
       virtual TimeStepType CountTimeSteps() const = 0;
     /**
     * \brief Returns the first time point for which the object is valid.
     *
     * Returns the first valid time point for this geometry. If only one
     * time steps available it usually goes from -max to +max. The time point
     * is given in ms.
     */
     virtual TimePointType GetMinimumTimePoint() const = 0;
     /**
     * \brief Returns the last time point for which the object is valid
     *
     * Gives the last time point for which a valid geometry is saved in
     * this time geometry. The time point is given in ms.
     */
     virtual TimePointType GetMaximumTimePoint() const = 0;
 
     /**
     * \brief Returns the first time point for which the object is valid.
     *
     * Returns the first valid time point for the given TimeStep. The time point
     * is given in ms.
     */
     virtual TimePointType GetMinimumTimePoint(TimeStepType step) const = 0;
     /**
     * \brief Returns the last time point for which the object is valid
     *
     * Gives the last time point for the Geometry specified by the given TimeStep. The time point is given in ms.
     */
     virtual TimePointType GetMaximumTimePoint(TimeStepType step) const = 0;
 
     /**
     * \brief Get the time bounds (in ms)
     */
     virtual TimeBounds GetTimeBounds() const = 0;
 
     /**
     * \brief Get the time bounds for the given TimeStep (in ms)
     */
     virtual TimeBounds GetTimeBounds(TimeStepType step) const = 0;
     /**
     * \brief Tests if a given time point is covered by this object
     *
     * Returns true if a geometry can be returned for the given time
     * point and falls if not. The time point must be given in ms.
     */
     virtual bool IsValidTimePoint(TimePointType timePoint) const = 0;
     /**
     * \brief Test for the given time step if a geometry is available
     *
     * Returns true if a geometry is defined for the given time step.
     * Otherwise false is returned.
     * The time step is defined as positive number.
     */
     virtual bool IsValidTimeStep(TimeStepType timeStep) const = 0;
 
     /**
     * \brief Converts a time step to a time point
     *
     * Converts a time step to a time point in a way that
     * the new time point indicates the same geometry as the time step.
     * If the original time steps does not point to a valid geometry,
     * a time point is calculated that also does not point to a valid
     * geometry, but no exception is raised.
     */
     virtual TimePointType TimeStepToTimePoint(TimeStepType timeStep) const = 0;
     /**
     * \brief Converts a time point to the corresponding time step
     *
     * Converts a time point to a time step in a way that
     * the new time step indicates the same geometry as the time point.
     * If a negative invalid time point is given always time step 0 is
     * returned. If an positive invalid time step is given an invalid
     * time step will be returned.
     */
     virtual TimeStepType TimePointToTimeStep(TimePointType timePoint) const = 0;
 
     /**
     * \brief Returns the geometry of a specific time point
     *
     * Returns the geometry which defines the given time point. If
     * the given time point is invalid an null-pointer is returned.
     *
     * The pointer to the returned geometry may point to the saved
     * geometry but this is not necessarily the case. So a change to
     * the returned geometry may or may not afflict the geometry for the
     * time point or all time points depending on the used implementation
     * of TimeGeometry.
     */
     virtual BaseGeometry::Pointer GetGeometryForTimePoint(TimePointType timePoint) const = 0;
     /**
     * \brief Returns the geometry which corresponds to the given time step
     *
     * Returns the geometry which defines the given time step. If
     * the given time step is invalid an null-pointer is returned.
     *
     * The pointer to the returned geometry may point to the saved
     * geometry but this is not necessarily the case. So a change to
     * the returned geometry may or may not afflict the geometry for the
     * time step or all time steps depending on the used implementation
     * of TimeGeometry.
     */
     virtual BaseGeometry::Pointer GetGeometryForTimeStep(TimeStepType timeStep) const = 0;
 
     /**
     * \brief Returns a clone of the geometry of a specific time point
     *
     * If an invalid time step is given (e.g. no geometry is defined for this time step)
     * a null-pointer will be returned.
     */
     virtual BaseGeometry::Pointer GetGeometryCloneForTimeStep(TimeStepType timeStep) const = 0;
 
     /**
     * \brief Sets the geometry for a given time step
     *
     * Sets the geometry for the given time steps. This may also afflects other
     * time steps, depending on the implementation of TimeGeometry.
     */
     virtual void SetTimeStepGeometry(BaseGeometry *geometry, TimeStepType timeStep) = 0;
 
     /**
     * \brief Expands to the given number of time steps
     *
     * Expands to the given number of time steps. Each new created time
     * step is filled with an empty geometry.
     * Shrinking is not supported!
     */
     virtual void Expand(TimeStepType size) = 0;
 
     /**
     * \brief Replaces the geometry instances with clones ot the passed geometry.
     *
     * Replaces the geometries of all time steps with clones of the passed
     * geometry. Replacement strategy depends on the implementation of TimeGeometry
     * sub class.
     * @remark The time points itself stays untouched. Use this method if you want
     * to change the spatial properties of a TimeGeometry and preserve the time
     * "grid".
     */
     virtual void ReplaceTimeStepGeometries(const BaseGeometry *geometry) = 0;
 
     /**
     * \brief Tests if all necessary information are set and the object is valid
     */
     virtual bool IsValid() const = 0;
     /**
     * \brief Get the position of the corner number \a id (in world coordinates)
     *
     * See SetImageGeometry for how a corner is defined on images.
     */
     Point3D GetCornerPointInWorld(int id) const;
 
     /**
     * \brief Get the position of a corner (in world coordinates)
     *
     * See SetImageGeometry for how a corner is defined on images.
     */
     Point3D GetCornerPointInWorld(bool xFront = true, bool yFront = true, bool zFront = true) const;
 
     /**
     * \brief Get the center of the bounding-box in mm
     */
     Point3D GetCenterInWorld() const;
 
     /**
     * \brief Get the squared length of the diagonal of the bounding-box in mm
     */
     double GetDiagonalLength2InWorld() const;
 
     /**
     * \brief Get the length of the diagonal of the bounding-box in mm
     */
     double GetDiagonalLengthInWorld() const;
 
     /**
     * \brief Test whether the point \a p (world coordinates in mm) is inside the bounding box
     */
     bool IsWorldPointInside(const mitk::Point3D &p) const;
 
     /**
     * \brief Updates the bounding box to cover the area used in all time steps
     *
     * The bounding box is updated by this method. The new bounding box
     * covers an area which includes all bounding boxes during
     * all times steps.
     */
     void UpdateBoundingBox();
 
     /**
     * \brief Returns a bounding box that covers all time steps
     */
     BoundingBox *GetBoundingBoxInWorld() const { return m_BoundingBox; }
     /**
     * \brief Returns the world bounds of the object that cover all time steps
     */
     BoundingBox::BoundsArrayType GetBoundsInWorld() const { return m_BoundingBox->GetBounds(); }
     /**
     * \brief Returns the Extend of the bounding in the given direction
     */
     ScalarType GetExtentInWorld(unsigned int direction) const;
 
     /**
     * \brief Initializes the TimeGeometry
     */
     virtual void Initialize();
 
     /**
     * \brief Updates the geometry
     */
     void Update();
 
     /**
     * \brief Updates everything except the Bounding box
     *
     * This class should be overwritten by child classes.
     * The method is called when Update() is required.
     */
     virtual void UpdateWithoutBoundingBox(){};
 
     /**
     * \brief Executes the given operation on all time steps
     */
     void ExecuteOperation(Operation *op) override;
 
     void PrintSelf(std::ostream &os, itk::Indent indent) const override;
   }; // end class TimeGeometry
 
   /**
   * @brief Equal A function comparing two instances of TimeGeometry for being identical.
   *
   * @ingroup MITKTestingAPI
   *
   * The function compares two instances of TimeGeometries in all their aspects.
   *
   * The parameter eps is a tolerance value for all methods which are internally used for comparison.
   * If you want to use different tolerance values for different parts of the geometry, feel free to use
   * the other comparison methods and write your own implementation of Equal.
   *
   * @param rightHandSide Compare this against leftHandSide.
   * @param leftHandSide Compare this against rightHandSide.
   * @param eps Tolerance for comparison. You can use mitk::eps in most cases.
   * @param verbose Flag indicating if the user wants detailed console output or not.
   *
   * @return True, if all comparison are true. False in any other case.
   */
   MITKCORE_EXPORT bool Equal(const mitk::TimeGeometry &leftHandSide,
                              const mitk::TimeGeometry &rightHandSide,
                              ScalarType eps,
                              bool verbose);
 
   /**
   * @brief Compare two instances of TimeGeometry
   *
   * @ingroup MITKTestingAPI
   *
   * The function compares two instances of TimeGeometries in all their aspects.
   *
   * The parameter eps is a tolerance value for all methods which are internally used for comparison.
   * If you want to use different tolerance values for different parts of the geometry, feel free to use
   * the other comparison methods and write your own implementation of Equal.
   *
   * @param leftHandSide Compare this against rightHandSide.
   * @param rightHandSide Compare this against leftHandSide.
   * @param coordinateEps Tolerance for comparison of all spatial and temporal aspects (spacing, origin and grid alignment, time points).
   * You can use mitk::eps in most cases.
   * @param directionEps Tolerance for comparison of all directional aspects (axis). You can use mitk::eps in most cases.
   * @param verbose Flag indicating if the user wants detailed console output or not.
   *
   * @return True, if all comparisons are true. False in any other case.
   */
   MITKCORE_EXPORT bool Equal(const mitk::TimeGeometry& leftHandSide,
     const mitk::TimeGeometry& rightHandSide,
     ScalarType coordinateEps,
     ScalarType directionEps,
     bool verbose);
 
 } // end namespace MITK
 #endif
diff --git a/Modules/Core/src/Rendering/mitkBaseRenderer.cpp b/Modules/Core/src/Rendering/mitkBaseRenderer.cpp
index f0c4d9b9d3..37d9ac5b90 100644
--- a/Modules/Core/src/Rendering/mitkBaseRenderer.cpp
+++ b/Modules/Core/src/Rendering/mitkBaseRenderer.cpp
@@ -1,780 +1,780 @@
 /*============================================================================
 
 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 "mitkBaseRenderer.h"
 #include "mitkBaseRendererHelper.h"
 
 #include "mitkMapper.h"
 #include "mitkResliceMethodProperty.h"
 
 // Geometries
 #include "mitkSlicedGeometry3D.h"
 
 #include "mitkVtkLayerController.h"
 
 #include "mitkInteractionConst.h"
 #include "mitkProperties.h"
 #include "mitkWeakPointerProperty.h"
 
 // VTK
 #include <vtkCamera.h>
 #include <vtkLinearTransform.h>
 
 #include <vtkActor.h>
 #include <vtkPolyDataMapper.h>
 #include <vtkProperty.h>
 
 namespace mitk
 {
   itkEventMacroDefinition(RendererResetEvent, itk::AnyEvent);
 }
 
 mitk::BaseRenderer::BaseRendererMapType mitk::BaseRenderer::baseRendererMap;
 
 mitk::BaseRenderer *mitk::BaseRenderer::GetInstance(vtkRenderWindow *renWin)
 {
   for (auto mapit = baseRendererMap.begin(); mapit != baseRendererMap.end(); ++mapit)
   {
     if ((*mapit).first == renWin)
       return (*mapit).second;
   }
   return nullptr;
 }
 
 void mitk::BaseRenderer::AddInstance(vtkRenderWindow *renWin, BaseRenderer *baseRenderer)
 {
   if (renWin == nullptr || baseRenderer == nullptr)
     return;
 
   // ensure that no BaseRenderer is managed twice
   mitk::BaseRenderer::RemoveInstance(renWin);
 
   baseRendererMap.insert(BaseRendererMapType::value_type(renWin, baseRenderer));
 }
 
 void mitk::BaseRenderer::RemoveInstance(vtkRenderWindow *renWin)
 {
   auto mapit = baseRendererMap.find(renWin);
   if (mapit != baseRendererMap.end())
     baseRendererMap.erase(mapit);
 }
 
 mitk::BaseRenderer *mitk::BaseRenderer::GetByName(const std::string &name)
 {
   for (auto mapit = baseRendererMap.begin(); mapit != baseRendererMap.end(); ++mapit)
   {
     if ((*mapit).second->m_Name == name)
       return (*mapit).second;
   }
   return nullptr;
 }
 
 vtkRenderWindow *mitk::BaseRenderer::GetRenderWindowByName(const std::string &name)
 {
   for (auto mapit = baseRendererMap.begin(); mapit != baseRendererMap.end(); ++mapit)
   {
     if ((*mapit).second->m_Name == name)
       return (*mapit).first;
   }
   return nullptr;
 }
 
 mitk::BaseRenderer::BaseRendererMapType mitk::BaseRenderer::GetSpecificRenderWindows(MapperSlotId mapper)
 {
   BaseRendererMapType allRenderWindows;
   for (auto mapit = baseRendererMap.begin(); mapit != baseRendererMap.end(); ++mapit)
   {
     if (mapper == mapit->second->GetMapperID())
     {
       allRenderWindows.insert(BaseRendererMapType::value_type(mapit->first, mapit->second));
     }
   }
 
   return allRenderWindows;
 }
 
 mitk::BaseRenderer::BaseRendererMapType mitk::BaseRenderer::GetAll2DRenderWindows()
 {
   return GetSpecificRenderWindows(BaseRenderer::Standard2D);
 }
 
 mitk::BaseRenderer::BaseRendererMapType mitk::BaseRenderer::GetAll3DRenderWindows()
 {
   return GetSpecificRenderWindows(BaseRenderer::Standard3D);
 }
 
 mitk::BaseRenderer::BaseRenderer(const char *name,
                                  vtkRenderWindow *renWin)
   : m_RenderWindow(nullptr),
     m_VtkRenderer(nullptr),
     m_MapperID(StandardMapperSlot::Standard2D),
     m_DataStorage(nullptr),
     m_LastUpdateTime(0),
     m_CameraController(nullptr),
     m_CameraRotationController(nullptr),
     m_SliceNavigationController(nullptr),
     m_WorldTimeGeometry(nullptr),
     m_InteractionReferenceGeometry(nullptr),
     m_CurrentWorldGeometry(nullptr),
     m_CurrentWorldPlaneGeometry(nullptr),
     m_Slice(0),
     m_TimeStep(),
     m_CurrentWorldPlaneGeometryUpdateTime(),
     m_TimeStepUpdateTime(),
     m_KeepDisplayedRegion(true),
     m_ReferenceGeometryAligned(true),
     m_CurrentWorldPlaneGeometryData(nullptr),
     m_CurrentWorldPlaneGeometryNode(nullptr),
     m_CurrentWorldPlaneGeometryTransformTime(0),
     m_Name(name),
     m_EmptyWorldGeometry(true),
     m_NumberOfVisibleLODEnabledMappers(0)
 {
   m_Bounds[0] = 0;
   m_Bounds[1] = 0;
   m_Bounds[2] = 0;
   m_Bounds[3] = 0;
   m_Bounds[4] = 0;
   m_Bounds[5] = 0;
 
   if (name != nullptr)
   {
     m_Name = name;
   }
   else
   {
     m_Name = "unnamed renderer";
     itkWarningMacro(<< "Created unnamed renderer. Bad for serialization. Please choose a name.");
   }
 
   if (renWin != nullptr)
   {
     m_RenderWindow = renWin;
     m_RenderWindow->Register(nullptr);
   }
   else
   {
     itkWarningMacro(<< "Created mitkBaseRenderer without vtkRenderWindow present.");
   }
   // instances.insert( this );
 
   // adding this BaseRenderer to the List of all BaseRenderer
 
   m_BindDispatcherInteractor = new mitk::BindDispatcherInteractor(GetName());
 
   WeakPointerProperty::Pointer rendererProp = WeakPointerProperty::New((itk::Object *)this);
 
   m_CurrentWorldPlaneGeometry = mitk::PlaneGeometry::New();
 
   m_CurrentWorldPlaneGeometryData = mitk::PlaneGeometryData::New();
   m_CurrentWorldPlaneGeometryData->SetPlaneGeometry(m_CurrentWorldPlaneGeometry);
   m_CurrentWorldPlaneGeometryNode = mitk::DataNode::New();
   m_CurrentWorldPlaneGeometryNode->SetData(m_CurrentWorldPlaneGeometryData);
   m_CurrentWorldPlaneGeometryNode->GetPropertyList()->SetProperty("renderer", rendererProp);
   m_CurrentWorldPlaneGeometryNode->GetPropertyList()->SetProperty("layer", IntProperty::New(1000));
 
   m_CurrentWorldPlaneGeometryNode->SetProperty("reslice.thickslices", mitk::ResliceMethodProperty::New());
   m_CurrentWorldPlaneGeometryNode->SetProperty("reslice.thickslices.num", mitk::IntProperty::New(1));
 
   m_CurrentWorldPlaneGeometryTransformTime = m_CurrentWorldPlaneGeometryNode->GetVtkTransform()->GetMTime();
 
   m_SliceNavigationController = mitk::SliceNavigationController::New();
   m_SliceNavigationController->SetRenderer(this);
   m_SliceNavigationController->ConnectGeometrySendEvent(this);
   m_SliceNavigationController->ConnectGeometryUpdateEvent(this);
   m_SliceNavigationController->ConnectGeometrySliceEvent(this);
 
   auto* timeNavigationController = RenderingManager::GetInstance()->GetTimeNavigationController();
   timeNavigationController->ConnectTimeEvent(this);
 
   m_CameraRotationController = mitk::CameraRotationController::New();
   m_CameraRotationController->SetRenderWindow(m_RenderWindow);
   m_CameraRotationController->AcquireCamera();
 
   m_CameraController = mitk::CameraController::New();
   m_CameraController->SetRenderer(this);
 
   m_VtkRenderer = vtkRenderer::New();
   m_VtkRenderer->SetMaximumNumberOfPeels(16);
 
   if (AntiAliasing::FastApproximate == RenderingManager::GetInstance()->GetAntiAliasing())
     m_VtkRenderer->UseFXAAOn();
 
   if (nullptr == mitk::VtkLayerController::GetInstance(m_RenderWindow))
     mitk::VtkLayerController::AddInstance(m_RenderWindow, m_VtkRenderer);
 
   mitk::VtkLayerController::GetInstance(m_RenderWindow)->InsertSceneRenderer(m_VtkRenderer);
 }
 
 mitk::BaseRenderer::~BaseRenderer()
 {
   if (m_VtkRenderer != nullptr)
   {
     m_VtkRenderer->Delete();
     m_VtkRenderer = nullptr;
   }
 
   if (m_CameraController.IsNotNull())
     m_CameraController->SetRenderer(nullptr);
 
   mitk::VtkLayerController::RemoveInstance(m_RenderWindow);
 
   RemoveAllLocalStorages();
 
   m_DataStorage = nullptr;
 
   if (m_BindDispatcherInteractor != nullptr)
   {
     delete m_BindDispatcherInteractor;
   }
 
   if (m_RenderWindow != nullptr)
   {
     m_RenderWindow->Delete();
     m_RenderWindow = nullptr;
   }
 
   auto* timeNavigationController = RenderingManager::GetInstance()->GetTimeNavigationController();
   timeNavigationController->Disconnect(this);
 }
 
 void mitk::BaseRenderer::RemoveAllLocalStorages()
 {
   this->InvokeEvent(RendererResetEvent());
 
   std::list<mitk::BaseLocalStorageHandler *>::iterator it;
   for (it = m_RegisteredLocalStorageHandlers.begin(); it != m_RegisteredLocalStorageHandlers.end(); ++it)
     (*it)->ClearLocalStorage(this, false);
   m_RegisteredLocalStorageHandlers.clear();
 }
 
 void mitk::BaseRenderer::RegisterLocalStorageHandler(mitk::BaseLocalStorageHandler *lsh)
 {
   m_RegisteredLocalStorageHandlers.push_back(lsh);
 }
 
 void mitk::BaseRenderer::UnregisterLocalStorageHandler(mitk::BaseLocalStorageHandler *lsh)
 {
   m_RegisteredLocalStorageHandlers.remove(lsh);
 }
 
 void mitk::BaseRenderer::SetDataStorage(DataStorage *storage)
 {
   if (storage != m_DataStorage && storage != nullptr)
   {
     m_DataStorage = storage;
     m_BindDispatcherInteractor->SetDataStorage(m_DataStorage);
     this->Modified();
   }
 }
 
 mitk::Dispatcher::Pointer mitk::BaseRenderer::GetDispatcher() const
 {
   return m_BindDispatcherInteractor->GetDispatcher();
 }
 
 void mitk::BaseRenderer::Resize(int w, int h)
 {
   m_RenderWindow->SetSize(w, h);
 }
 
 void mitk::BaseRenderer::InitRenderer(vtkRenderWindow *renderwindow)
 {
   if (m_RenderWindow != renderwindow)
   {
     if (m_RenderWindow != nullptr)
     {
       m_RenderWindow->Delete();
     }
     m_RenderWindow = renderwindow;
     if (m_RenderWindow != nullptr)
     {
       m_RenderWindow->Register(nullptr);
     }
   }
   RemoveAllLocalStorages();
 
   if (m_CameraController.IsNotNull())
   {
     m_CameraController->SetRenderer(this);
   }
 }
 
 void mitk::BaseRenderer::InitSize(int w, int h)
 {
   m_RenderWindow->SetSize(w, h);
 }
 
 void mitk::BaseRenderer::SetWorldTimeGeometry(const mitk::TimeGeometry* geometry)
 {
   if (m_WorldTimeGeometry == geometry)
   {
     return;
   }
 
   m_WorldTimeGeometry = geometry;
 
   this->UpdateCurrentGeometries();
 }
 
 void mitk::BaseRenderer::SetInteractionReferenceGeometry(const TimeGeometry* geometry)
 {
   if (m_InteractionReferenceGeometry == geometry)
   {
     return;
   }
 
   m_InteractionReferenceGeometry = geometry;
 
   this->UpdateCurrentGeometries();
 }
 
 void mitk::BaseRenderer::SetSlice(unsigned int slice)
 {
   if (m_Slice == slice)
   {
     return;
   }
 
   m_Slice = slice;
 
   this->UpdateCurrentGeometries();
 }
 
 void mitk::BaseRenderer::SetTimeStep(unsigned int timeStep)
 {
   if (m_TimeStep == timeStep)
   {
     return;
   }
 
   m_TimeStep = timeStep;
   m_TimeStepUpdateTime.Modified();
 
   this->UpdateCurrentGeometries();
 }
 
 mitk::TimeStepType mitk::BaseRenderer::GetTimeStep(const mitk::BaseData* data) const
 {
   if ((data == nullptr) || (data->IsInitialized() == false))
   {
-    return -1;
+    return TIMESTEP_INVALID;
   }
   return data->GetTimeGeometry()->TimePointToTimeStep(GetTime());
 }
 
 mitk::ScalarType mitk::BaseRenderer::GetTime() const
 {
   if (m_WorldTimeGeometry.IsNull())
   {
     return 0;
   }
   else
   {
     ScalarType timeInMS = m_WorldTimeGeometry->TimeStepToTimePoint(GetTimeStep());
     if (timeInMS == itk::NumericTraits<mitk::ScalarType>::NonpositiveMin())
       return 0;
     else
       return timeInMS;
   }
 }
 
 void mitk::BaseRenderer::SetGeometry(const itk::EventObject& geometrySendEvent)
 {
   const auto* sendEvent = dynamic_cast<const SliceNavigationController::GeometrySendEvent*>(&geometrySendEvent);
 
   if (nullptr == sendEvent)
   {
     return;
   }
 
   SetWorldTimeGeometry(sendEvent->GetTimeGeometry());
 }
 
 void mitk::BaseRenderer::UpdateGeometry(const itk::EventObject& geometryUpdateEvent)
 {
   const auto* updateEvent = dynamic_cast<const SliceNavigationController::GeometryUpdateEvent*>(&geometryUpdateEvent);
 
   if (nullptr == updateEvent)
   {
     return;
   }
 
   if (m_CurrentWorldGeometry.IsNull())
   {
     return;
   }
 
   const auto* slicedWorldGeometry = dynamic_cast<const SlicedGeometry3D*>(m_CurrentWorldGeometry.GetPointer());
   if (slicedWorldGeometry)
   {
     PlaneGeometry* geometry2D = slicedWorldGeometry->GetPlaneGeometry(m_Slice);
 
     SetCurrentWorldPlaneGeometry(geometry2D); // calls Modified()
   }
 }
 
 void mitk::BaseRenderer::SetGeometrySlice(const itk::EventObject& geometrySliceEvent)
 {
   const auto* sliceEvent = dynamic_cast<const SliceNavigationController::GeometrySliceEvent*>(&geometrySliceEvent);
 
   if (nullptr == sliceEvent)
   {
     return;
   }
 
   this->SetSlice(sliceEvent->GetPos());
 }
 
 void mitk::BaseRenderer::SetGeometryTime(const itk::EventObject& geometryTimeEvent)
 {
   const auto* timeEvent = dynamic_cast<const TimeNavigationController::TimeEvent *>(&geometryTimeEvent);
 
   if (nullptr == timeEvent)
   {
     return;
   }
 
   this->SetTimeStep(timeEvent->GetTimeStep());
 }
 
 void mitk::BaseRenderer::SendUpdateSlice()
 {
   m_CurrentWorldPlaneGeometryUpdateTime.Modified();
 }
 
 void mitk::BaseRenderer::SetMapperID(MapperSlotId id)
 {
   if (m_MapperID != id)
   {
     bool useDepthPeeling = Standard3D == id;
     m_VtkRenderer->SetUseDepthPeeling(useDepthPeeling);
     m_VtkRenderer->SetUseDepthPeelingForVolumes(useDepthPeeling);
 
     m_MapperID = id;
     this->Modified();
   }
 }
 
 int* mitk::BaseRenderer::GetSize() const
 {
   return m_RenderWindow->GetSize();
 }
 
 int* mitk::BaseRenderer::GetViewportSize() const
 {
   return m_VtkRenderer->GetSize();
 }
 
 const double* mitk::BaseRenderer::GetBounds() const
 {
   return m_Bounds;
 }
 
 void mitk::BaseRenderer::RequestUpdate()
 {
   SetConstrainZoomingAndPanning(true);
   RenderingManager::GetInstance()->RequestUpdate(m_RenderWindow);
 }
 
 void mitk::BaseRenderer::ForceImmediateUpdate()
 {
   RenderingManager::GetInstance()->ForceImmediateUpdate(m_RenderWindow);
 }
 
 unsigned int mitk::BaseRenderer::GetNumberOfVisibleLODEnabledMappers() const
 {
   return m_NumberOfVisibleLODEnabledMappers;
 }
 
 void mitk::BaseRenderer::SetSliceNavigationController(mitk::SliceNavigationController *SlicenavigationController)
 {
   if (SlicenavigationController == nullptr)
     return;
 
   // copy worldgeometry
   SlicenavigationController->SetInputWorldTimeGeometry(SlicenavigationController->GetCreatedWorldGeometry());
   SlicenavigationController->Update();
 
   // set new
   m_SliceNavigationController = SlicenavigationController;
   m_SliceNavigationController->SetRenderer(this);
 
   if (m_SliceNavigationController.IsNotNull())
   {
     m_SliceNavigationController->ConnectGeometrySendEvent(this);
     m_SliceNavigationController->ConnectGeometryUpdateEvent(this);
     m_SliceNavigationController->ConnectGeometrySliceEvent(this);
   }
 }
 
 void mitk::BaseRenderer::DisplayToWorld(const Point2D& displayPoint, Point3D& worldIndex) const
 {
   if (m_MapperID == BaseRenderer::Standard2D)
   {
     double display[3], * world;
 
     // For the right z-position in display coordinates, take the focal point, convert it to display and use it for
     // correct depth.
     double* displayCoord;
     double cameraFP[4];
     // Get camera focal point and position. Convert to display (screen)
     // coordinates. We need a depth value for z-buffer.
     this->GetVtkRenderer()->GetActiveCamera()->GetFocalPoint(cameraFP);
     cameraFP[3] = 0.0;
     this->GetVtkRenderer()->SetWorldPoint(cameraFP[0], cameraFP[1], cameraFP[2], cameraFP[3]);
     this->GetVtkRenderer()->WorldToDisplay();
     displayCoord = this->GetVtkRenderer()->GetDisplayPoint();
 
     // now convert the display point to world coordinates
     display[0] = displayPoint[0];
     display[1] = displayPoint[1];
     display[2] = displayCoord[2];
 
     this->GetVtkRenderer()->SetDisplayPoint(display);
     this->GetVtkRenderer()->DisplayToWorld();
     world = this->GetVtkRenderer()->GetWorldPoint();
 
     for (int i = 0; i < 3; i++)
     {
       worldIndex[i] = world[i] / world[3];
     }
   }
   else if (m_MapperID == BaseRenderer::Standard3D)
   {
     // Seems to be the same code as above, but subclasses may contain different implementations.
     PickWorldPoint(displayPoint, worldIndex);
   }
   return;
 }
 
 void mitk::BaseRenderer::DisplayToPlane(const Point2D &displayPoint, Point2D &planePointInMM) const
 {
   if (m_MapperID == BaseRenderer::Standard2D)
   {
     Point3D worldPoint;
     this->DisplayToWorld(displayPoint, worldPoint);
     m_CurrentWorldPlaneGeometry->Map(worldPoint, planePointInMM);
   }
   else if (m_MapperID == BaseRenderer::Standard3D)
   {
     MITK_WARN << "No conversion possible with 3D mapper.";
     return;
   }
 
   return;
 }
 
 void mitk::BaseRenderer::WorldToDisplay(const Point3D &worldIndex, Point2D &displayPoint) const
 {
   double world[4], *display;
 
   world[0] = worldIndex[0];
   world[1] = worldIndex[1];
   world[2] = worldIndex[2];
   world[3] = 1.0;
 
   this->GetVtkRenderer()->SetWorldPoint(world);
   this->GetVtkRenderer()->WorldToDisplay();
   display = this->GetVtkRenderer()->GetDisplayPoint();
 
   displayPoint[0] = display[0];
   displayPoint[1] = display[1];
 
   return;
 }
 
 void mitk::BaseRenderer::WorldToView(const mitk::Point3D &worldIndex, mitk::Point2D &viewPoint) const
 {
   double world[4], *view;
 
   world[0] = worldIndex[0];
   world[1] = worldIndex[1];
   world[2] = worldIndex[2];
   world[3] = 1.0;
 
   this->GetVtkRenderer()->SetWorldPoint(world);
   this->GetVtkRenderer()->WorldToView();
   view = this->GetVtkRenderer()->GetViewPoint();
   this->GetVtkRenderer()->ViewToNormalizedViewport(view[0], view[1], view[2]);
 
   viewPoint[0] = view[0] * this->GetViewportSize()[0];
   viewPoint[1] = view[1] * this->GetViewportSize()[1];
 
   return;
 }
 
 void mitk::BaseRenderer::PlaneToDisplay(const Point2D &planePointInMM, Point2D &displayPoint) const
 {
   Point3D worldPoint;
   m_CurrentWorldPlaneGeometry->Map(planePointInMM, worldPoint);
   this->WorldToDisplay(worldPoint, displayPoint);
 
   return;
 }
 
 void mitk::BaseRenderer::PlaneToView(const Point2D &planePointInMM, Point2D &viewPoint) const
 {
   Point3D worldPoint;
   m_CurrentWorldPlaneGeometry->Map(planePointInMM, worldPoint);
   this->WorldToView(worldPoint,viewPoint);
 
   return;
 }
 
 double mitk::BaseRenderer::GetScaleFactorMMPerDisplayUnit() const
 {
   if (this->GetMapperID() == BaseRenderer::Standard2D)
   {
     // GetParallelScale returns half of the height of the render window in mm.
     // Divided by the half size of the Display size in pixel givest the mm per pixel.
     return this->GetVtkRenderer()->GetActiveCamera()->GetParallelScale() * 2.0 / GetViewportSize()[1];
   }
   else
     return 1.0;
 }
 
 mitk::Point2D mitk::BaseRenderer::GetDisplaySizeInMM() const
 {
   Point2D dispSizeInMM;
   dispSizeInMM[0] = GetSizeX() * GetScaleFactorMMPerDisplayUnit();
   dispSizeInMM[1] = GetSizeY() * GetScaleFactorMMPerDisplayUnit();
   return dispSizeInMM;
 }
 
 mitk::Point2D mitk::BaseRenderer::GetViewportSizeInMM() const
 {
   Point2D dispSizeInMM;
   dispSizeInMM[0] = GetViewportSize()[0] * GetScaleFactorMMPerDisplayUnit();
   dispSizeInMM[1] = GetViewportSize()[1] * GetScaleFactorMMPerDisplayUnit();
   return dispSizeInMM;
 }
 
 mitk::Point2D mitk::BaseRenderer::GetOriginInMM() const
 {
   Point2D originPx;
   originPx[0] = m_VtkRenderer->GetOrigin()[0];
   originPx[1] = m_VtkRenderer->GetOrigin()[1];
   Point2D displayGeometryOriginInMM;
   DisplayToPlane(originPx, displayGeometryOriginInMM); // top left of the render window (Origin)
   return displayGeometryOriginInMM;
 }
 
 void mitk::BaseRenderer::SetConstrainZoomingAndPanning(bool constrain)
 {
   m_ConstrainZoomingAndPanning = constrain;
   if (m_ConstrainZoomingAndPanning)
   {
     this->GetCameraController()->AdjustCameraToPlane();
   }
 }
 
 void mitk::BaseRenderer::UpdateCurrentGeometries()
 {
   m_ReferenceGeometryAligned = true;
 
   if (m_WorldTimeGeometry.IsNull())
   {
     // simply mark the base renderer as modified
     Modified();
     return;
   }
 
   if (m_TimeStep >= m_WorldTimeGeometry->CountTimeSteps())
   {
     m_TimeStep = m_WorldTimeGeometry->CountTimeSteps() - 1;
   }
 
   auto slicedWorldGeometry =
     dynamic_cast<SlicedGeometry3D*>(m_WorldTimeGeometry->GetGeometryForTimeStep(m_TimeStep).GetPointer());
   if (slicedWorldGeometry != nullptr)
   {
     if (m_Slice >= slicedWorldGeometry->GetSlices())
     {
       m_Slice = slicedWorldGeometry->GetSlices() - 1;
     }
 
     SetCurrentWorldGeometry(slicedWorldGeometry);
     SetCurrentWorldPlaneGeometry(slicedWorldGeometry->GetPlaneGeometry(m_Slice));
     m_ReferenceGeometryAligned = BaseRendererHelper::IsRendererGeometryAlignedWithGeometry(this, m_InteractionReferenceGeometry);
   }
 }
 
 void mitk::BaseRenderer::SetCurrentWorldPlaneGeometry(const mitk::PlaneGeometry* geometry2d)
 {
   if (m_CurrentWorldPlaneGeometry == geometry2d)
   {
     return;
   }
 
   m_CurrentWorldPlaneGeometry = geometry2d->Clone();
   m_CurrentWorldPlaneGeometryData->SetPlaneGeometry(m_CurrentWorldPlaneGeometry);
   m_CurrentWorldPlaneGeometryUpdateTime.Modified();
   Modified();
 }
 
 void mitk::BaseRenderer::SetCurrentWorldGeometry(const mitk::BaseGeometry* geometry)
 {
   if (m_CurrentWorldGeometry == geometry)
   {
     return;
   }
 
   m_CurrentWorldGeometry = geometry;
   if (geometry == nullptr)
   {
     m_Bounds[0] = 0;
     m_Bounds[1] = 0;
     m_Bounds[2] = 0;
     m_Bounds[3] = 0;
     m_Bounds[4] = 0;
     m_Bounds[5] = 0;
     m_EmptyWorldGeometry = true;
     return;
   }
 
   BoundingBox::Pointer boundingBox = m_CurrentWorldGeometry->CalculateBoundingBoxRelativeToTransform(nullptr);
   const BoundingBox::BoundsArrayType& worldBounds = boundingBox->GetBounds();
   m_Bounds[0] = worldBounds[0];
   m_Bounds[1] = worldBounds[1];
   m_Bounds[2] = worldBounds[2];
   m_Bounds[3] = worldBounds[3];
   m_Bounds[4] = worldBounds[4];
   m_Bounds[5] = worldBounds[5];
 
   if (boundingBox->GetDiagonalLength2() <= mitk::eps)
   {
     m_EmptyWorldGeometry = true;
   }
   else
   {
     m_EmptyWorldGeometry = false;
   }
 }
 
 void mitk::BaseRenderer::PrintSelf(std::ostream &os, itk::Indent indent) const
 {
   os << indent << " MapperID: " << m_MapperID << std::endl;
   os << indent << " Slice: " << m_Slice << std::endl;
   os << indent << " TimeStep: " << m_TimeStep << std::endl;
 
   os << indent << " CurrentWorldPlaneGeometry: ";
   if (m_CurrentWorldPlaneGeometry.IsNull())
     os << "nullptr" << std::endl;
   else
     m_CurrentWorldPlaneGeometry->Print(os, indent);
 
   os << indent << " CurrentWorldPlaneGeometryUpdateTime: " << m_CurrentWorldPlaneGeometryUpdateTime << std::endl;
   os << indent << " CurrentWorldPlaneGeometryTransformTime: " << m_CurrentWorldPlaneGeometryTransformTime << std::endl;
 
   Superclass::PrintSelf(os, indent);
 }
diff --git a/Modules/Multilabel/mitkLabelSetImageVtkMapper2D.cpp b/Modules/Multilabel/mitkLabelSetImageVtkMapper2D.cpp
index 7a4210ee50..70893567b1 100644
--- a/Modules/Multilabel/mitkLabelSetImageVtkMapper2D.cpp
+++ b/Modules/Multilabel/mitkLabelSetImageVtkMapper2D.cpp
@@ -1,755 +1,764 @@
 /*============================================================================
 
 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 <mitkPlaneGeometry.h>
 #include <mitkProperties.h>
 #include <mitkVectorProperty.h>
 
 // MITK Rendering
 #include "vtkNeverTranslucentTexture.h"
 
 // VTK
 #include <vtkCamera.h>
 #include <vtkImageData.h>
 #include <vtkImageReslice.h>
 #include <vtkLookupTable.h>
 #include <vtkPlaneSource.h>
 #include <vtkPolyData.h>
 #include <vtkPolyDataMapper.h>
 #include <vtkImageMapToColors.h>
 
 namespace
 {
   itk::ModifiedTimeType PropertyTimeStampIsNewer(const mitk::IPropertyProvider* provider, mitk::BaseRenderer* renderer, const std::string& propName, itk::ModifiedTimeType refMT)
   {
     const std::string context = renderer != nullptr ? renderer->GetName() : "";
     auto prop = provider->GetConstProperty(propName, context);
     if (prop != nullptr)
     {
       return prop->GetTimeStamp() > refMT;
     }
     return false;
   }
 }
 
 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::GenerateLookupTable(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());
 
   localStorage->m_LabelLookupTable = image->GetLookupTable()->Clone();
   const auto labelValues = image->GetAllLabelValues();
 
   std::string propertyName = "org.mitk.multilabel.labels.highlighted";
 
   mitk::IntVectorProperty::Pointer prop = dynamic_cast<mitk::IntVectorProperty*>(node->GetNonConstProperty(propertyName));
   if (nullptr != prop)
   {
     const auto highlightedLabelValues = prop->GetValue();
 
     if (!highlightedLabelValues.empty())
     {
       auto lookUpTable  = localStorage->m_LabelLookupTable->GetVtkLookupTable();
       auto highlightEnd = highlightedLabelValues.cend();
 
       double rgba[4];
       for (const auto& value : labelValues)
       {
         lookUpTable->GetTableValue(value, rgba);
         if (highlightEnd == std::find(highlightedLabelValues.begin(), highlightedLabelValues.end(), value))
         { //make all none highlighted values more transparent
           rgba[3] *= 0.3;
         }
         else
         {
           if (rgba[3] != 0)
           { //if highlighted values are visible set them to opaque to pop out
             rgba[3] = 1.;
           }
           else
           { //if highlighted values are invisible the opacity is increased a bit
             //to give a visual hint that the are highlighted but also invisible.
             //e.g. needed to see a difference if you change the visibility of
             //a highlighted label in the MultiLabelInspector
             rgba[3] = 0.4;
           }
         }
         lookUpTable->SetTableValue(value, rgba);
       }
       localStorage->m_LabelLookupTable->Modified();
     }
   }
 }
 
 namespace
 {
   std::vector<mitk::LabelSetImage::GroupIndexType> GetOutdatedGroups(const mitk::LabelSetImageVtkMapper2D::LocalStorage* ls, const mitk::LabelSetImage* seg)
   {
     const auto nrOfGroups = seg->GetNumberOfLayers();
     std::vector<mitk::LabelSetImage::GroupIndexType> result;
 
     for (mitk::LabelSetImage::GroupIndexType groupID = 0; groupID < nrOfGroups; ++groupID)
     {
       const auto groupImage = seg->GetGroupImage(groupID);
       if (groupImage->GetMTime() > ls->m_LastDataUpdateTime
         || groupImage->GetPipelineMTime() > ls->m_LastDataUpdateTime
         || ls->m_GroupImageIDs.size() <= groupID
         || groupImage != ls->m_GroupImageIDs[groupID])
       {
         result.push_back(groupID);
       }
     }
     return result;
   }
 }
 
 void mitk::LabelSetImageVtkMapper2D::GenerateDataForRenderer(mitk::BaseRenderer *renderer)
 {
   LocalStorage *localStorage = m_LSH.GetLocalStorage(renderer);
   mitk::DataNode *node = this->GetDataNode();
   auto *segmentation = dynamic_cast<mitk::LabelSetImage *>(node->GetData());
   assert(segmentation && segmentation->IsInitialized());
 
   bool isLookupModified = localStorage->m_LabelLookupTable.IsNull() ||
     (localStorage->m_LabelLookupTable->GetMTime() < segmentation->GetLookupTable()->GetMTime()) ||
     PropertyTimeStampIsNewer(node, renderer, "org.mitk.multilabel.labels.highlighted", localStorage->m_LabelLookupTable->GetMTime()) ||
     PropertyTimeStampIsNewer(node, renderer, "opacity", localStorage->m_LabelLookupTable->GetMTime());
 
   if (isLookupModified)
   {
     this->GenerateLookupTable(renderer);
   }
 
-  auto outdatedGroups = GetOutdatedGroups(localStorage, segmentation);
-
   bool isGeometryModified = (localStorage->m_LastDataUpdateTime < renderer->GetCurrentWorldPlaneGeometryUpdateTime()) ||
     (localStorage->m_LastDataUpdateTime < renderer->GetCurrentWorldPlaneGeometry()->GetMTime());
 
   bool rendererGeometryIsValid = true;
 
   // check if there is a valid worldGeometry
   if (isGeometryModified)
   {
     const PlaneGeometry* worldGeometry = renderer->GetCurrentWorldPlaneGeometry();
     rendererGeometryIsValid = worldGeometry != nullptr
       && worldGeometry->IsValid()
       && worldGeometry->HasReferenceGeometry();
 
     isGeometryModified = rendererGeometryIsValid
       && localStorage->m_WorldPlane.IsNotNull() && !Equal(*worldGeometry, *(localStorage->m_WorldPlane.GetPointer()));
 
     localStorage->m_WorldPlane = rendererGeometryIsValid ? worldGeometry->Clone() : nullptr;
   }
 
-  bool hasValidContent = rendererGeometryIsValid && RenderingGeometryIntersectsImage(localStorage->m_WorldPlane, segmentation->GetSlicedGeometry());
+  const bool hasValidContent = rendererGeometryIsValid && RenderingGeometryIntersectsImage(localStorage->m_WorldPlane, segmentation->GetSlicedGeometry());
+  const bool contentBecameValid = hasValidContent && !localStorage->m_HasValidContent;
+  const bool contentBecameInvalid = !hasValidContent && localStorage->m_HasValidContent;
 
-  if (!hasValidContent && localStorage->m_HasValidContent)
+  if (contentBecameInvalid)
   {
     // 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 (unsigned int lidx = 0; lidx < localStorage->m_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);
     }
     localStorage->m_LastDataUpdateTime.Modified();
   }
 
-  if (isGeometryModified || (hasValidContent && !localStorage->m_HasValidContent))
+  localStorage->m_HasValidContent = hasValidContent;
+  if (!hasValidContent)
+  {
+    // early out if there is no intersection of the current rendering geometry
+    // and the geometry of the image that is to be rendered.
+    return;
+  }
+
+  std::vector<mitk::LabelSetImage::GroupIndexType> outdatedGroups;
+  auto currentTimestep = this->GetTimestep();
+  if (isGeometryModified || contentBecameValid || localStorage->m_LastTimeStep!= currentTimestep)
   {
     //if geometry is outdated or we have valid content again
     // -> all groups need regeneration
     outdatedGroups.resize(segmentation->GetNumberOfLayers());
     std::iota(outdatedGroups.begin(), outdatedGroups.end(), 0);
   }
-
-  localStorage->m_HasValidContent = hasValidContent;
-
-  if (!hasValidContent)
+  else
   {
-    // early out if there is no intersection of the current rendering geometry
-    // and the geometry of the image that is to be rendered.
-    return;
+    outdatedGroups = GetOutdatedGroups(localStorage, segmentation);
   }
 
   if (!outdatedGroups.empty())
   {
     this->GenerateImageSlice(renderer, outdatedGroups);
   }
 
+  localStorage->m_LastTimeStep = currentTimestep;
+
+
   float opacity = 1.0f;
   node->GetOpacity(opacity, renderer, "opacity");
 
   if (isLookupModified)
   {
     //if lookup table is modified all groups need a new color mapping
     outdatedGroups.resize(segmentation->GetNumberOfLayers());
     std::iota(outdatedGroups.begin(), outdatedGroups.end(), 0);
   }
 
   for (const auto groupID: outdatedGroups)
   {
     localStorage->m_LayerImageMapToColors[groupID]->SetLookupTable(localStorage->m_LabelLookupTable->GetVtkLookupTable());
     localStorage->m_LayerImageMapToColors[groupID]->SetInputData(localStorage->m_ReslicedImageVector[groupID]);
     localStorage->m_LayerImageMapToColors[groupID]->Update();
 
     // 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[groupID]->SetInterpolate(textureInterpolation);
 
     localStorage->m_LayerTextureVector[groupID]->SetInputConnection(
       localStorage->m_LayerImageMapToColors[groupID]->GetOutputPort());
     this->TransformActor(renderer);
 
     // set the plane as input for the mapper
     localStorage->m_LayerMapperVector[groupID]->SetInputConnection(localStorage->m_Plane->GetOutputPort());
 
     // set the texture for the actor
     localStorage->m_LayerActorVector[groupID]->SetTexture(localStorage->m_LayerTextureVector[groupID]);
     localStorage->m_LayerActorVector[groupID]->GetProperty()->SetOpacity(opacity);
   }
 
   auto activeLayer = segmentation->GetActiveLayer();
   bool activeGroupIsOutdated = std::find(outdatedGroups.begin(), outdatedGroups.end(), activeLayer) != outdatedGroups.end();
 
   if (activeGroupIsOutdated
       || PropertyTimeStampIsNewer(node, renderer, "opacity", localStorage->m_LastActiveLabelUpdateTime.GetMTime())
       || PropertyTimeStampIsNewer(node, renderer, "labelset.contour.active", localStorage->m_LastActiveLabelUpdateTime.GetMTime())
       || PropertyTimeStampIsNewer(node, renderer, "labelset.contour.width", localStorage->m_LastActiveLabelUpdateTime.GetMTime())
     )
   {
     this->GenerateActiveLabelOutline(renderer);
   }
 }
 
 void mitk::LabelSetImageVtkMapper2D::GenerateImageSlice(mitk::BaseRenderer* renderer, const std::vector<mitk::LabelSetImage::GroupIndexType>& outdatedGroupIDs)
 {
   LocalStorage* localStorage = m_LSH.GetLocalStorage(renderer);
   mitk::DataNode* node = this->GetDataNode();
   auto* segmentation = dynamic_cast<mitk::LabelSetImage*>(node->GetData());
   assert(segmentation && segmentation->IsInitialized());
 
   segmentation->Update();
 
   const auto numberOfLayers = segmentation->GetNumberOfLayers();
 
   if (numberOfLayers != localStorage->m_NumberOfLayers)
   {
     if (numberOfLayers > localStorage->m_NumberOfLayers)
     {
       for (unsigned int lidx = localStorage->m_NumberOfLayers; lidx < numberOfLayers; ++lidx)
       {
         localStorage->m_GroupImageIDs.push_back(nullptr);
         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_LayerMapperVector.push_back(vtkSmartPointer<vtkPolyDataMapper>::New());
         localStorage->m_LayerActorVector.push_back(vtkSmartPointer<vtkActor>::New());
         localStorage->m_LayerImageMapToColors.push_back(vtkSmartPointer<vtkImageMapToColors>::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]);
       }
     }
     else
     {
       localStorage->m_GroupImageIDs.resize(numberOfLayers);
       localStorage->m_ReslicedImageVector.resize(numberOfLayers);
       localStorage->m_ReslicerVector.resize(numberOfLayers);
       localStorage->m_LayerTextureVector.resize(numberOfLayers);
       localStorage->m_LayerMapperVector.resize(numberOfLayers);
       localStorage->m_LayerActorVector.resize(numberOfLayers);
       localStorage->m_LayerImageMapToColors.resize(numberOfLayers);
     }
     localStorage->m_NumberOfLayers = numberOfLayers;
 
     localStorage->m_Actors = vtkSmartPointer<vtkPropAssembly>::New();
 
     for (unsigned int lidx = 0; lidx < numberOfLayers; ++lidx)
     {
       localStorage->m_Actors->AddPart(localStorage->m_LayerActorVector[lidx]);
     }
     localStorage->m_Actors->AddPart(localStorage->m_OutlineShadowActor);
     localStorage->m_Actors->AddPart(localStorage->m_OutlineActor);
   }
 
   for (const auto groupID : outdatedGroupIDs)
   {
     const auto groupImage = segmentation->GetGroupImage(groupID);
     localStorage->m_GroupImageIDs[groupID] = groupImage;
 
     localStorage->m_ReslicerVector[groupID]->SetInput(groupImage);
     localStorage->m_ReslicerVector[groupID]->SetWorldGeometry(localStorage->m_WorldPlane);
     localStorage->m_ReslicerVector[groupID]->SetTimeStep(this->GetTimestep());
 
     // set the transformation of the image to adapt reslice axis
     localStorage->m_ReslicerVector[groupID]->SetResliceTransformByGeometry(
       groupImage->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[groupID]->SetInPlaneResampleExtentByGeometry(inPlaneResampleExtentByGeometry);
     localStorage->m_ReslicerVector[groupID]->SetInterpolationMode(ExtractSliceFilter::RESLICE_NEAREST);
     localStorage->m_ReslicerVector[groupID]->SetVtkOutputRequest(true);
 
     // this is needed when thick mode was enabled before. These variables have to be reset to default values
     localStorage->m_ReslicerVector[groupID]->SetOutputDimensionality(2);
     localStorage->m_ReslicerVector[groupID]->SetOutputSpacingZDirection(1.0);
     localStorage->m_ReslicerVector[groupID]->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[groupID]->GetClippedPlaneBounds(sliceBounds);
 
     // setup the textured plane
     this->GeneratePlane(renderer, sliceBounds);
 
     // get the spacing of the slice
     localStorage->m_mmPerPixel = localStorage->m_ReslicerVector[groupID]->GetOutputSpacing();
     localStorage->m_ReslicerVector[groupID]->Modified();
     // start the pipeline with updating the largest possible, needed if the geometry of the image has changed
     localStorage->m_ReslicerVector[groupID]->UpdateLargestPossibleRegion();
     localStorage->m_ReslicedImageVector[groupID] = localStorage->m_ReslicerVector[groupID]->GetVtkOutput();
   }
   localStorage->m_LastDataUpdateTime.Modified();
 }
 
 void mitk::LabelSetImageVtkMapper2D::GenerateActiveLabelOutline(mitk::BaseRenderer* renderer)
 {
   LocalStorage* localStorage = m_LSH.GetLocalStorage(renderer);
   mitk::DataNode* node = this->GetDataNode();
   auto* image = dynamic_cast<mitk::LabelSetImage*>(node->GetData());
 
   int activeLayer = image->GetActiveLayer();
 
   float opacity = 1.0f;
   node->GetOpacity(opacity, renderer, "opacity");
 
   mitk::Label* activeLabel = image->GetActiveLabel();
   bool contourActive = false;
   node->GetBoolProperty("labelset.contour.active", contourActive, renderer);
   if (nullptr != activeLabel && contourActive && activeLabel->GetVisible())
   {
     //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);
   }
   else
   {
     localStorage->m_OutlineActor->SetVisibility(false);
     localStorage->m_OutlineShadowActor->SetVisibility(false);
   }
   localStorage->m_LastActiveLabelUpdateTime.Modified();
 }
 
 
 bool mitk::LabelSetImageVtkMapper2D::RenderingGeometryIntersectsImage(const PlaneGeometry *renderingGeometry,
   const BaseGeometry *imageGeometry) const
 {
   // 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::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_LabelLookupTable.IsNull() ||
       (localStorage->m_LabelLookupTable->GetMTime() < image->GetLookupTable()->GetMTime()) ||
       (localStorage->m_LastDataUpdateTime < image->GetMTime()) ||
       (localStorage->m_LastDataUpdateTime < image->GetPipelineMTime()) ||
       (localStorage->m_LastDataUpdateTime < renderer->GetCurrentWorldPlaneGeometryUpdateTime()) ||
       (localStorage->m_LastDataUpdateTime < renderer->GetCurrentWorldPlaneGeometry()->GetMTime()) ||
       (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();
   }
   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 sagittal) 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 sagittal
   vtkSmartPointer<vtkTransform> trans = vtkSmartPointer<vtkTransform>::New();
   vtkSmartPointer<vtkMatrix4x4> matrix = localStorage->m_ReslicerVector[0]->GetResliceAxes(); // same for all layers
   trans->SetMatrix(matrix);
 
   for (unsigned int lidx = 0; lidx < localStorage->m_NumberOfLayers; ++lidx)
   {
     // transform the plane/contour (the actual actor) to the corresponding view (axial, coronal or sagittal)
     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);
 
   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_HasValidContent = false;
   m_NumberOfLayers = 0;
   m_mmPerPixel = nullptr;
+  m_LastTimeStep = 0;
 
   m_OutlineActor->SetMapper(m_OutlineMapper);
   m_OutlineShadowActor->SetMapper(m_OutlineMapper);
 
   m_OutlineActor->SetVisibility(false);
   m_OutlineShadowActor->SetVisibility(false);
 }
diff --git a/Modules/Multilabel/mitkLabelSetImageVtkMapper2D.h b/Modules/Multilabel/mitkLabelSetImageVtkMapper2D.h
index c213b7fff5..4defba4876 100644
--- a/Modules/Multilabel/mitkLabelSetImageVtkMapper2D.h
+++ b/Modules/Multilabel/mitkLabelSetImageVtkMapper2D.h
@@ -1,231 +1,233 @@
 /*============================================================================
 
 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 mitkLabelSetImageVtkMapper2D_h
 #define mitkLabelSetImageVtkMapper2D_h
 
 // MITK
 #include "MitkMultilabelExports.h"
 #include "mitkCommon.h"
 
 // MITK Rendering
 #include "mitkBaseRenderer.h"
 #include "mitkExtractSliceFilter.h"
 #include "mitkLabelSetImage.h"
 #include "mitkVtkMapper.h"
 
 // VTK
 #include <vtkSmartPointer.h>
 
 class vtkActor;
 class vtkPolyDataMapper;
 class vtkPlaneSource;
 class vtkImageData;
 class vtkLookupTable;
 class vtkImageReslice;
 class vtkPoints;
 class vtkMitkThickSlicesFilter;
 class vtkPolyData;
 class vtkNeverTranslucentTexture;
 class vtkImageMapToColors;
 
 namespace mitk
 {
 
   /** \brief Mapper to resample and display 2D slices of a 3D labelset image.
    *
    * Properties that can be set for labelset images and influence this mapper are:
    *
    *   - \b "labelset.contour.active": (BoolProperty) whether to show only the active label as a contour or not
    *   - \b "labelset.contour.width": (FloatProperty) line width of the contour
 
    * The default properties are:
 
    *   - \b "labelset.contour.active", mitk::BoolProperty::New( true ), renderer, overwrite )
    *   - \b "labelset.contour.width", mitk::FloatProperty::New( 2.0 ), renderer, overwrite )
 
    * \ingroup Mapper
    */
   class MITKMULTILABEL_EXPORT LabelSetImageVtkMapper2D : public VtkMapper
   {
   public:
     /** Standard class typedefs. */
     mitkClassMacro(LabelSetImageVtkMapper2D, VtkMapper);
 
     /** Method for creation through the object factory. */
     itkNewMacro(Self);
 
     /** \brief Get the Image to map */
     const mitk::Image *GetInput(void);
 
     /** \brief Checks whether this mapper needs to update itself and generate
      * data. */
     void Update(mitk::BaseRenderer *renderer) override;
 
     //### methods of MITK-VTK rendering pipeline
     vtkProp *GetVtkProp(mitk::BaseRenderer *renderer) override;
     //### end of methods of MITK-VTK rendering pipeline
 
     /** \brief Internal class holding the mapper, actor, etc. for each of the 3 2D render windows */
     /**
        * To render axial, coronal, and sagittal, the mapper is called three times.
        * For performance reasons, the corresponding data for each view is saved in the
        * internal helper class LocalStorage. This allows rendering n views with just
        * 1 mitkMapper using n vtkMapper.
        * */
     class MITKMULTILABEL_EXPORT LocalStorage : public mitk::Mapper::BaseLocalStorage
     {
     public:
       vtkSmartPointer<vtkPropAssembly> m_Actors;
 
       /** Vector containing the pointer of the currently used group images.
        * IMPORTANT: This member must not be used to access any data.
        * Its purpose is to allow checking if the order of the groups has changed
        * in order to adapt the pipe line accordingly*/
       std::vector<const Image*> m_GroupImageIDs;
 
       std::vector<vtkSmartPointer<vtkActor>> m_LayerActorVector;
       std::vector<vtkSmartPointer<vtkPolyDataMapper>> m_LayerMapperVector;
       std::vector<vtkSmartPointer<vtkImageData>> m_ReslicedImageVector;
       std::vector<vtkSmartPointer<vtkImageMapToColors>> m_LayerImageMapToColors;
       std::vector<vtkSmartPointer<vtkNeverTranslucentTexture>> m_LayerTextureVector;
 
       vtkSmartPointer<vtkPolyData> m_EmptyPolyData;
       vtkSmartPointer<vtkPlaneSource> m_Plane;
 
       std::vector<mitk::ExtractSliceFilter::Pointer> m_ReslicerVector;
 
       vtkSmartPointer<vtkPolyData> m_OutlinePolyData;
       /** \brief An actor for the outline */
       vtkSmartPointer<vtkActor> m_OutlineActor;
       /** \brief An actor for the outline shadow*/
       vtkSmartPointer<vtkActor> m_OutlineShadowActor;
       /** \brief A mapper for the outline */
       vtkSmartPointer<vtkPolyDataMapper> m_OutlineMapper;
 
       /** \brief Timestamp of last update of stored data. */
       itk::TimeStamp m_LastDataUpdateTime;
       /** \brief Timestamp of last update of a property. */
       itk::TimeStamp m_LastPropertyUpdateTime;
       /** \brief Timestamp of last update of a property. */
       itk::TimeStamp m_LastActiveLabelUpdateTime;
 
       /** \brief mmPerPixel relation between pixel and mm. (World spacing).*/
       mitk::ScalarType *m_mmPerPixel;
 
       /** look up table for label colors. */
       mitk::LookupTable::Pointer m_LabelLookupTable;
 
       mitk::PlaneGeometry::Pointer m_WorldPlane;
       bool m_HasValidContent;
 
+      mitk::TimeStepType m_LastTimeStep;
+
       unsigned int m_NumberOfLayers;
 
       /** \brief Default constructor of the local storage. */
       LocalStorage();
       /** \brief Default destructor 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 Get the LocalStorage corresponding to the current renderer. */
     LocalStorage *GetLocalStorage(mitk::BaseRenderer *renderer);
 
     /** \brief Set the default properties for general image rendering. */
     static void SetDefaultProperties(mitk::DataNode *node, mitk::BaseRenderer *renderer = nullptr, bool overwrite = false);
 
     /** \brief This method switches between different rendering modes (e.g. use a lookup table or a transfer function).
      * Detailed documentation about the modes can be found here: \link mitk::RenderingModeProperty \endlink
      */
     void ApplyRenderingMode(mitk::BaseRenderer *renderer);
 
   protected:
     /** \brief Transforms the actor to the actual position in 3D.
       *   \param renderer The current renderer corresponding to the render window.
       */
     void TransformActor(mitk::BaseRenderer *renderer);
 
     /** \brief Generates a plane according to the size of the resliced image in milimeters.
       *
       * In VTK a vtkPlaneSource is defined through three points. The origin and two
       * points defining the axes of the plane (see VTK documentation). The origin is
       * set to (xMin; yMin; Z), where xMin and yMin are the minimal bounds of the
       * resliced image in space. Z is relevant for blending and the layer property.
       * The center of the plane (C) is also the center of the view plane (cf. the image above).
       *
       * \note For the standard MITK view with three 2D render windows showing three
       * different slices, three such planes are generated. All these planes are generated
       * in the XY-plane (even if they depict a YZ-slice of the volume).
       *
       */
     void GeneratePlane(mitk::BaseRenderer *renderer, double planeBounds[6]);
 
     /** \brief Generates a vtkPolyData object containing the outline of a given binary slice.
         \param renderer Pointer to the renderer containing the needed information
         \param image
         \param pixelValue
         \note This code is based on code from the iil library.
         */
     vtkSmartPointer<vtkPolyData> CreateOutlinePolyData(mitk::BaseRenderer *renderer,
                                                        vtkImageData *image,
                                                        int pixelValue = 1);
 
     /** Default constructor */
     LabelSetImageVtkMapper2D();
     /** Default deconstructor */
     ~LabelSetImageVtkMapper2D() override;
 
     /** \brief Does the actual resampling, without rendering the image yet.
       * All the data is generated inside this method. The vtkProp (or Actor)
       * is filled with content (i.e. the resliced image).
       *
       * After generation, a 4x4 transformation matrix(t) of the current slice is obtained
       * from the vtkResliceImage object via GetReslicesAxis(). This matrix is
       * applied to each textured plane (actor->SetUserTransform(t)) to transform everything
       * to the actual 3D position (cf. the following image).
       *
       * \image html cameraPositioning3D.png
       *
       */
     void GenerateDataForRenderer(mitk::BaseRenderer *renderer) override;
 
     void GenerateImageSlice(mitk::BaseRenderer* renderer, const std::vector<mitk::LabelSetImage::GroupIndexType>& outdatedGroupIDs);
 
     void GenerateActiveLabelOutline(mitk::BaseRenderer* renderer);
 
     /** \brief Generates the look up table that should be used.
       */
     void GenerateLookupTable(mitk::BaseRenderer* renderer);
 
     /** \brief This method uses the vtkCamera clipping range and the layer property
       * to calcualte the depth of the object (e.g. image or contour). The depth is used
       * to keep the correct order for the final VTK rendering.*/
     float CalculateLayerDepth(mitk::BaseRenderer *renderer);
 
     /**
       * \brief Calculates whether the given rendering geometry intersects the
       * given SlicedGeometry3D.
       *
       * This method checks if the given Geometry2D intersects the given
       * SlicedGeometry3D. It calculates the distance of the Geometry2D to all
       * 8 cornerpoints of the SlicedGeometry3D. If all distances have the same
       * sign (all positive or all negative) there is no intersection.
       * If the distances have different sign, there is an intersection.
       **/
     bool RenderingGeometryIntersectsImage(const PlaneGeometry *renderingGeometry, const BaseGeometry* imageGeometry) const;
   };
 
 } // namespace mitk
 
 #endif