diff --git a/Modules/ContourModel/Algorithms/mitkContourModelUtils.cpp b/Modules/ContourModel/Algorithms/mitkContourModelUtils.cpp
index a27d5607b4..c2eff3c43f 100755
--- a/Modules/ContourModel/Algorithms/mitkContourModelUtils.cpp
+++ b/Modules/ContourModel/Algorithms/mitkContourModelUtils.cpp
@@ -1,216 +1,228 @@
 /*============================================================================
 
 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 <mitkContourModelUtils.h>
 
 #include <mitkContourModelToSurfaceFilter.h>
 #include <mitkLabelSetImage.h>
 #include <mitkSurface.h>
 #include <vtkImageStencil.h>
 #include <vtkPointData.h>
 #include <vtkPolyData.h>
 #include <vtkPolyDataToImageStencil.h>
 
 mitk::ContourModelUtils::ContourModelUtils()
 {
 }
 
 mitk::ContourModelUtils::~ContourModelUtils()
 {
 }
 
 mitk::ContourModel::Pointer mitk::ContourModelUtils::ProjectContourTo2DSlice(
   Image *slice, ContourModel *contourIn3D, bool, bool)
 {
   if (nullptr == slice || nullptr == contourIn3D)
     return nullptr;
 
   auto projectedContour = ContourModel::New();
   projectedContour->Initialize(*contourIn3D);
 
   auto sliceGeometry = slice->GetGeometry();
   auto numberOfTimesteps = static_cast<int>(contourIn3D->GetTimeSteps());
 
   for (decltype(numberOfTimesteps) t = 0; t < numberOfTimesteps; ++t)
   {
     auto iter = contourIn3D->Begin(t);
     auto end = contourIn3D->End(t);
 
     while (iter != end)
     {
       const auto &currentPointIn3D = (*iter)->Coordinates;
 
       Point3D projectedPointIn2D;
       projectedPointIn2D.Fill(0.0);
 
       sliceGeometry->WorldToIndex(currentPointIn3D, projectedPointIn2D);
 
       projectedContour->AddVertex(projectedPointIn2D, t);
       ++iter;
     }
   }
 
   return projectedContour;
 }
 
 mitk::ContourModel::Pointer mitk::ContourModelUtils::BackProjectContourFrom2DSlice(
   const BaseGeometry *sliceGeometry, ContourModel *contourIn2D, bool)
 {
   if (nullptr == sliceGeometry || nullptr == contourIn2D)
     return nullptr;
 
   auto worldContour = ContourModel::New();
   worldContour->Initialize(*contourIn2D);
 
   auto numberOfTimesteps = static_cast<int>(contourIn2D->GetTimeSteps());
 
   for (decltype(numberOfTimesteps) t = 0; t < numberOfTimesteps; ++t)
   {
     auto iter = contourIn2D->Begin(t);
     auto end = contourIn2D->End(t);
 
     while (iter != end)
     {
       const auto &currentPointIn2D = (*iter)->Coordinates;
 
       Point3D worldPointIn3D;
       worldPointIn3D.Fill(0.0);
 
       sliceGeometry->IndexToWorld(currentPointIn2D, worldPointIn3D);
 
       worldContour->AddVertex(worldPointIn3D, t);
       ++iter;
     }
   }
 
   return worldContour;
 }
 
 void mitk::ContourModelUtils::FillContourInSlice(
   ContourModel *projectedContour, Image *sliceImage, Image::Pointer workingImage, int paintingPixelValue)
 {
   FillContourInSlice(projectedContour, 0, sliceImage, workingImage, paintingPixelValue);
 }
 
 void mitk::ContourModelUtils::FillContourInSlice(
   ContourModel *projectedContour, unsigned int t, Image *sliceImage, Image::Pointer workingImage, int paintingPixelValue)
 {
   auto contourModelFilter = mitk::ContourModelToSurfaceFilter::New();
   contourModelFilter->SetInput(projectedContour);
   contourModelFilter->Update();
 
   auto surface = mitk::Surface::New();
   surface = contourModelFilter->GetOutput();
 
   if (nullptr == surface->GetVtkPolyData(t))
   {
     MITK_WARN << "Could not create surface from contour model.";
     return;
   }
 
   auto surface2D = vtkSmartPointer<vtkPolyData>::New();
   surface2D->SetPoints(surface->GetVtkPolyData(t)->GetPoints());
   surface2D->SetLines(surface->GetVtkPolyData(t)->GetLines());
 
   auto image = vtkSmartPointer<vtkImageData>::New();
   image->DeepCopy(sliceImage->GetVtkImageData());
 
   const double FOREGROUND_VALUE = 255.0;
   const double BACKGROUND_VALUE = 0.0;
 
   vtkIdType count = image->GetNumberOfPoints();
   for (decltype(count) i = 0; i < count; ++i)
     image->GetPointData()->GetScalars()->SetTuple1(i, FOREGROUND_VALUE);
 
   auto polyDataToImageStencil = vtkSmartPointer<vtkPolyDataToImageStencil>::New();
 
   // Set a minimal tolerance, so that clipped pixels will be added to contour as well.
   polyDataToImageStencil->SetTolerance(mitk::eps);
   polyDataToImageStencil->SetInputData(surface2D);
   polyDataToImageStencil->Update();
 
   auto imageStencil = vtkSmartPointer<vtkImageStencil>::New();
 
   imageStencil->SetInputData(image);
   imageStencil->SetStencilConnection(polyDataToImageStencil->GetOutputPort());
   imageStencil->ReverseStencilOff();
   imageStencil->SetBackgroundValue(BACKGROUND_VALUE);
   imageStencil->Update();
 
   vtkSmartPointer<vtkImageData> filledImage = imageStencil->GetOutput();
   vtkSmartPointer<vtkImageData> resultImage = sliceImage->GetVtkImageData();
   FillSliceInSlice(filledImage, resultImage, workingImage, paintingPixelValue);
 
   sliceImage->SetVolume(resultImage->GetScalarPointer());
 }
 
 void mitk::ContourModelUtils::FillSliceInSlice(
   vtkSmartPointer<vtkImageData> filledImage, vtkSmartPointer<vtkImageData> resultImage, mitk::Image::Pointer image, int paintingPixelValue)
 {
   auto labelImage = dynamic_cast<LabelSetImage *>(image.GetPointer());
   auto numberOfPoints = filledImage->GetNumberOfPoints();
 
   if (nullptr == labelImage)
   {
     for (decltype(numberOfPoints) i = 0; i < numberOfPoints; ++i)
     {
       if (1 < filledImage->GetPointData()->GetScalars()->GetTuple1(i))
         resultImage->GetPointData()->GetScalars()->SetTuple1(i, paintingPixelValue);
     }
   }
   else
   {
     auto backgroundValue = labelImage->GetExteriorLabel()->GetValue();
 
     if (paintingPixelValue != backgroundValue)
     {
       for (decltype(numberOfPoints) i = 0; i < numberOfPoints; ++i)
       {
         if (1 < filledImage->GetPointData()->GetScalars()->GetTuple1(i))
         {
           auto existingValue = resultImage->GetPointData()->GetScalars()->GetTuple1(i);
 
           if (!labelImage->GetLabel(existingValue, labelImage->GetActiveLayer())->GetLocked())
             resultImage->GetPointData()->GetScalars()->SetTuple1(i, paintingPixelValue);
         }
       }
     }
     else
     {
       auto activePixelValue = labelImage->GetActiveLabel(labelImage->GetActiveLayer())->GetValue();
 
       for (decltype(numberOfPoints) i = 0; i < numberOfPoints; ++i)
       {
         if (1 < filledImage->GetPointData()->GetScalars()->GetTuple1(i))
         {
           if (resultImage->GetPointData()->GetScalars()->GetTuple1(i) == activePixelValue)
             resultImage->GetPointData()->GetScalars()->SetTuple1(i, paintingPixelValue);
         }
       }
     }
   }
 }
 
 mitk::ContourModel::Pointer mitk::ContourModelUtils::MoveZerothContourTimeStep(const ContourModel *contour, unsigned int t)
 {
   if (nullptr == contour)
     return nullptr;
 
   auto resultContour = ContourModel::New();
   resultContour->Expand(t + 1);
 
   std::for_each(contour->Begin(), contour->End(), [&resultContour, t](ContourElement::VertexType *vertex) {
     resultContour->AddVertex(vertex, t);
   });
 
   return resultContour;
 }
+
+int mitk::ContourModelUtils::GetActivePixelValue(mitk::Image* workingImage)
+{
+  auto* labelSetImage = dynamic_cast<LabelSetImage*>(workingImage);
+  int activePixelValue = 1;
+  if (nullptr != labelSetImage)
+  {
+    activePixelValue = labelSetImage->GetActiveLabel(labelSetImage->GetActiveLayer())->GetValue();
+  }
+
+  return activePixelValue;
+}
diff --git a/Modules/ContourModel/Algorithms/mitkContourModelUtils.h b/Modules/ContourModel/Algorithms/mitkContourModelUtils.h
index 42c91c021e..61a33c0c87 100644
--- a/Modules/ContourModel/Algorithms/mitkContourModelUtils.h
+++ b/Modules/ContourModel/Algorithms/mitkContourModelUtils.h
@@ -1,96 +1,106 @@
 /*============================================================================
 
 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 mitkContourModelUtils_h
 #define mitkContourModelUtils_h
 
 #include <mitkContourModel.h>
 #include <mitkImage.h>
 #include <vtkSmartPointer.h>
 
 #include <MitkContourModelExports.h>
 
 namespace mitk
 {
   /**
    * \brief Helpful methods for working with contours and images
    *
    *
    */
   class MITKCONTOURMODEL_EXPORT ContourModelUtils : public itk::Object
   {
   public:
     mitkClassMacroItkParent(ContourModelUtils, itk::Object);
 
     /**
       \brief Projects a contour onto an image point by point. Converts from world to index coordinates.
 
       \param slice
       \param contourIn3D
       \param correctionForIpSegmentation adds 0.5 to x and y index coordinates (difference between ipSegmentation and
       MITK contours)
       \param constrainToInside
     */
     static ContourModel::Pointer ProjectContourTo2DSlice(Image *slice,
                                                          ContourModel *contourIn3D,
                                                          bool correctionForIpSegmentation,
                                                          bool constrainToInside);
 
     /**
       \brief Projects a slice index coordinates of a contour back into world coordinates.
 
       \param sliceGeometry
       \param contourIn2D
       \param correctionForIpSegmentation subtracts 0.5 to x and y index coordinates (difference between ipSegmentation
       and MITK contours)
     */
     static ContourModel::Pointer BackProjectContourFrom2DSlice(const BaseGeometry *sliceGeometry,
                                                                ContourModel *contourIn2D,
                                                                bool correctionForIpSegmentation = false);
 
     /**
     \brief Fill a contour in a 2D slice with a specified pixel value at time step 0.
     */
     static void FillContourInSlice(ContourModel *projectedContour,
                                    Image *sliceImage,
                                    mitk::Image::Pointer workingImage,
                                    int paintingPixelValue = 1);
 
     /**
     \brief Fill a contour in a 2D slice with a specified pixel value at a given time step.
     */
     static void FillContourInSlice(ContourModel *projectedContour,
                                    unsigned int timeStep,
                                    Image *sliceImage,
                                    mitk::Image::Pointer workingImage,
                                    int paintingPixelValue = 1);
 
     /**
     \brief Fills a image (filledImage) into another image (resultImage) by incorporating the rules of LabelSet-Images
     */
     static void FillSliceInSlice(vtkSmartPointer<vtkImageData> filledImage,
                                  vtkSmartPointer<vtkImageData> resultImage,
                                  mitk::Image::Pointer image,
                                  int paintingPixelValue);
 
     /**
     \brief Move the contour in time step 0 to to a new contour model at the given time step.
     */
     static ContourModel::Pointer MoveZerothContourTimeStep(const ContourModel *contour, unsigned int timeStep);
 
+    /**
+    \brief Retrieves the active pixel value of a (labelset) image.
+           If the image is basic image, the pixel value 1 (one) will be returned.
+           If the image is actually a labelset image, the pixel value of the active label of the active layer will be
+           returned.
+
+    \param workingImage   The (labelset) image to retrieve the active pixel value of.
+    */
+    static int GetActivePixelValue(mitk::Image* workingImage);
+
   protected:
     ContourModelUtils();
     ~ContourModelUtils() override;
   };
 }
 
 #endif
diff --git a/Modules/Segmentation/Interactions/mitkContourTool.cpp b/Modules/Segmentation/Interactions/mitkContourTool.cpp
index 109fd68bdc..3cc6e941fe 100644
--- a/Modules/Segmentation/Interactions/mitkContourTool.cpp
+++ b/Modules/Segmentation/Interactions/mitkContourTool.cpp
@@ -1,190 +1,180 @@
 /*============================================================================
 
 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 "mitkContourTool.h"
 
 #include "mitkAbstractTransformGeometry.h"
 #include "mitkOverwriteDirectedPlaneImageFilter.h"
 #include "mitkOverwriteSliceImageFilter.h"
 #include "mitkToolManager.h"
 
 #include "mitkBaseRenderer.h"
 #include "mitkRenderingManager.h"
-//#include "mitkProperties.h"
-//#include "mitkPlanarCircle.h"
-#include "mitkLabelSetImage.h"
 
 #include "mitkInteractionEvent.h"
 #include "mitkStateMachineAction.h"
 
 mitk::ContourTool::ContourTool(int paintingPixelValue)
   : FeedbackContourTool("PressMoveReleaseWithCTRLInversion"),
     m_PaintingPixelValue(paintingPixelValue)
 {
 }
 
 mitk::ContourTool::~ContourTool()
 {
 }
 
 void mitk::ContourTool::ConnectActionsAndFunctions()
 {
   CONNECT_FUNCTION("PrimaryButtonPressed", OnMousePressed);
   CONNECT_FUNCTION("Move", OnMouseMoved);
   CONNECT_FUNCTION("Release", OnMouseReleased);
   CONNECT_FUNCTION("InvertLogic", OnInvertLogic);
 }
 
 void mitk::ContourTool::Activated()
 {
   Superclass::Activated();
 }
 
 void mitk::ContourTool::Deactivated()
 {
   Superclass::Deactivated();
 }
 
 /**
  Just show the contour, insert the first point.
 */
 void mitk::ContourTool::OnMousePressed(StateMachineAction *, InteractionEvent *interactionEvent)
 {
   auto *positionEvent = dynamic_cast<mitk::InteractionPositionEvent *>(interactionEvent);
   if (!positionEvent)
     return;
 
   m_LastEventSender = positionEvent->GetSender();
   m_LastEventSlice = m_LastEventSender->GetSlice();
 
   int timestep = positionEvent->GetSender()->GetTimeStep();
 
   ContourModel *contour = FeedbackContourTool::GetFeedbackContour();
   // Clear feedback contour
   contour->Initialize();
   // expand time bounds because our contour was initialized
   contour->Expand(timestep + 1);
   // draw as a closed contour
   contour->SetClosed(true, timestep);
   // add first mouse position
   mitk::Point3D point = positionEvent->GetPositionInWorld();
   contour->AddVertex(point, timestep);
 
   FeedbackContourTool::SetFeedbackContourVisible(true);
   assert(positionEvent->GetSender()->GetRenderWindow());
   mitk::RenderingManager::GetInstance()->RequestUpdate(positionEvent->GetSender()->GetRenderWindow());
 }
 
 /**
  Insert the point to the feedback contour.
 */
 void mitk::ContourTool::OnMouseMoved(StateMachineAction *, InteractionEvent *interactionEvent)
 {
   auto *positionEvent = dynamic_cast<mitk::InteractionPositionEvent *>(interactionEvent);
   if (!positionEvent)
     return;
 
   int timestep = positionEvent->GetSender()->GetTimeStep();
 
   ContourModel *contour = FeedbackContourTool::GetFeedbackContour();
   mitk::Point3D point = positionEvent->GetPositionInWorld();
   contour->AddVertex(point, timestep);
 
   assert(positionEvent->GetSender()->GetRenderWindow());
   mitk::RenderingManager::GetInstance()->RequestUpdate(positionEvent->GetSender()->GetRenderWindow());
 }
 
 /**
   Close the contour, project it to the image slice and fill it in 2D.
 */
 void mitk::ContourTool::OnMouseReleased(StateMachineAction *, InteractionEvent *interactionEvent)
 {
   // 1. Hide the feedback contour, find out which slice the user clicked, find out which slice of the toolmanager's
   // working image corresponds to that
   FeedbackContourTool::SetFeedbackContourVisible(false);
 
   auto *positionEvent = dynamic_cast<mitk::InteractionPositionEvent *>(interactionEvent);
   // const PositionEvent* positionEvent = dynamic_cast<const PositionEvent*>(stateEvent->GetEvent());
   if (!positionEvent)
     return;
 
   assert(positionEvent->GetSender()->GetRenderWindow());
   mitk::RenderingManager::GetInstance()->RequestUpdate(positionEvent->GetSender()->GetRenderWindow());
 
   DataNode *workingNode(m_ToolManager->GetWorkingData(0));
   if (!workingNode)
     return;
 
-  auto *image = dynamic_cast<Image *>(workingNode->GetData());
+  auto workingImage = dynamic_cast<Image *>(workingNode->GetData());
   const PlaneGeometry *planeGeometry((positionEvent->GetSender()->GetCurrentWorldPlaneGeometry()));
-  if (!image || !planeGeometry)
+  if (!workingImage || !planeGeometry)
     return;
 
-  // Check if it is a multilabel-image. If yes, get the new drawing color from it.
-  auto *labelSetImage = dynamic_cast<LabelSetImage *>(image);
-  int activePixelValue = 1;
-  if (nullptr != labelSetImage)
-  {
-    activePixelValue = labelSetImage->GetActiveLabel(labelSetImage->GetActiveLayer())->GetValue();
-  }
-
   const auto *abstractTransformGeometry(
     dynamic_cast<const AbstractTransformGeometry *>(positionEvent->GetSender()->GetCurrentWorldPlaneGeometry()));
-  if (!image || abstractTransformGeometry)
+  if (!workingImage || abstractTransformGeometry)
     return;
 
   // 2. Slice is known, now we try to get it as a 2D image and project the contour into index coordinates of this slice
-  Image::Pointer slice = SegTool2D::GetAffectedImageSliceAs2DImage(positionEvent, image);
+  Image::Pointer slice = SegTool2D::GetAffectedImageSliceAs2DImage(positionEvent, workingImage);
 
   if (slice.IsNull())
   {
     MITK_ERROR << "Unable to extract slice." << std::endl;
     return;
   }
 
   ContourModel *feedbackContour = FeedbackContourTool::GetFeedbackContour();
   ContourModel::Pointer projectedContour = FeedbackContourTool::ProjectContourTo2DSlice(
     slice, feedbackContour, true, false); // true: actually no idea why this is neccessary, but it works :-(
 
   if (projectedContour.IsNull())
     return;
 
   int timestep = positionEvent->GetSender()->GetTimeStep();
+  int activePixelValue = ContourModelUtils::GetActivePixelValue(workingImage);
 
   // m_PaintingPixelValue only decides whether to paint or erase
   mitk::ContourModelUtils::FillContourInSlice(
-    projectedContour, timestep, slice, image, (m_PaintingPixelValue * activePixelValue));
+    projectedContour, timestep, slice, workingImage, m_PaintingPixelValue * activePixelValue);
 
   // this->WriteBackSegmentationResult(positionEvent, slice);
   SegTool2D::WriteBackSegmentationResult(positionEvent, slice);
 
   // 4. Make sure the result is drawn again --> is visible then.
   assert(positionEvent->GetSender()->GetRenderWindow());
 }
 
 /**
   Called when the CTRL key is pressed. Will change the painting pixel value from 0 to 1 or from 1 to 0.
 */
 void mitk::ContourTool::OnInvertLogic(StateMachineAction *, InteractionEvent *)
 {
   // Inversion only for 0 and 1 as painting values
   if (m_PaintingPixelValue == 1)
   {
     m_PaintingPixelValue = 0;
     FeedbackContourTool::SetFeedbackContourColor(1.0, 0.0, 0.0);
   }
   else if (m_PaintingPixelValue == 0)
   {
     m_PaintingPixelValue = 1;
     FeedbackContourTool::SetFeedbackContourColorDefault();
   }
 }
diff --git a/Modules/Segmentation/Interactions/mitkLiveWireTool2D.cpp b/Modules/Segmentation/Interactions/mitkLiveWireTool2D.cpp
index a1acec8f4b..a75e5bd1ce 100644
--- a/Modules/Segmentation/Interactions/mitkLiveWireTool2D.cpp
+++ b/Modules/Segmentation/Interactions/mitkLiveWireTool2D.cpp
@@ -1,599 +1,593 @@
 /*============================================================================
 
 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 <mitkContourModelUtils.h>
 #include <mitkLiveWireTool2D.h>
 #include <mitkLiveWireTool2D.xpm>
 #include <mitkToolManager.h>
 
 #include <usGetModuleContext.h>
 #include <usModuleResource.h>
 
 #include <type_traits>
 
 namespace mitk
 {
   MITK_TOOL_MACRO(MITKSEGMENTATION_EXPORT, LiveWireTool2D, "LiveWire tool");
 }
 
 mitk::LiveWireTool2D::LiveWireTool2D()
   : SegTool2D("LiveWireTool"), m_CreateAndUseDynamicCosts(false)
 {
 }
 
 mitk::LiveWireTool2D::~LiveWireTool2D()
 {
   this->ClearSegmentation();
 }
 
 void mitk::LiveWireTool2D::RemoveHelperObjects()
 {
   auto dataStorage = m_ToolManager->GetDataStorage();
 
   if (nullptr == dataStorage)
     return;
 
   for (const auto &editingContour : m_EditingContours)
     dataStorage->Remove(editingContour.first);
 
   for (const auto &workingContour : m_WorkingContours)
     dataStorage->Remove(workingContour.first);
 
   if (m_EditingContourNode.IsNotNull())
     dataStorage->Remove(m_EditingContourNode);
 
   if (m_LiveWireContourNode.IsNotNull())
     dataStorage->Remove(m_LiveWireContourNode);
 
   if (m_ContourNode.IsNotNull())
     dataStorage->Remove(m_ContourNode);
 
   mitk::RenderingManager::GetInstance()->RequestUpdateAll();
 }
 
 void mitk::LiveWireTool2D::ReleaseHelperObjects()
 {
   this->RemoveHelperObjects();
 
   m_EditingContours.clear();
   m_WorkingContours.clear();
 
   m_EditingContourNode = nullptr;
   m_EditingContour = nullptr;
 
   m_LiveWireContourNode = nullptr;
   m_LiveWireContour = nullptr;
 
   m_ContourNode = nullptr;
   m_Contour = nullptr;
 }
 
 void mitk::LiveWireTool2D::ReleaseInteractors()
 {
   this->EnableContourLiveWireInteraction(false);
   m_LiveWireInteractors.clear();
 }
 
 void mitk::LiveWireTool2D::ConnectActionsAndFunctions()
 {
   CONNECT_CONDITION("CheckContourClosed", OnCheckPoint);
 
   CONNECT_FUNCTION("InitObject", OnInitLiveWire);
   CONNECT_FUNCTION("AddPoint", OnAddPoint);
   CONNECT_FUNCTION("CtrlAddPoint", OnAddPoint);
   CONNECT_FUNCTION("MovePoint", OnMouseMoveNoDynamicCosts);
   CONNECT_FUNCTION("FinishContour", OnFinish);
   CONNECT_FUNCTION("DeletePoint", OnLastSegmentDelete);
   CONNECT_FUNCTION("CtrlMovePoint", OnMouseMoved);
 }
 
 const char **mitk::LiveWireTool2D::GetXPM() const
 {
   return mitkLiveWireTool2D_xpm;
 }
 
 us::ModuleResource mitk::LiveWireTool2D::GetIconResource() const
 {
   return us::GetModuleContext()->GetModule()->GetResource("LiveWire_48x48.png");
 }
 
 us::ModuleResource mitk::LiveWireTool2D::GetCursorIconResource() const
 {
   return us::GetModuleContext()->GetModule()->GetResource("LiveWire_Cursor_32x32.png");
 }
 
 const char *mitk::LiveWireTool2D::GetName() const
 {
   return "Live Wire";
 }
 
 void mitk::LiveWireTool2D::Activated()
 {
   Superclass::Activated();
   this->ResetToStartState();
   this->EnableContourLiveWireInteraction(true);
 }
 
 void mitk::LiveWireTool2D::Deactivated()
 {
   this->ConfirmSegmentation();
   Superclass::Deactivated();
 }
 
 void mitk::LiveWireTool2D::EnableContourLiveWireInteraction(bool on)
 {
   for (const auto &interactor : m_LiveWireInteractors)
     interactor->EnableInteraction(on);
 }
 
 void mitk::LiveWireTool2D::ConfirmSegmentation()
 {
   auto referenceNode = m_ToolManager->GetReferenceData(0);
   auto workingNode = m_ToolManager->GetWorkingData(0);
 
   if (nullptr == referenceNode || nullptr == workingNode)
     return;
 
   auto referenceImage = dynamic_cast<Image *>(referenceNode->GetData());
   auto workingImage = dynamic_cast<Image *>(workingNode->GetData());
 
   if (nullptr == referenceImage || nullptr == workingImage)
     return;
 
   std::vector<SliceInformation> sliceInfos;
   sliceInfos.reserve(m_WorkingContours.size());
 
   for (const auto &workingContour : m_WorkingContours)
   {
     auto contour = dynamic_cast<ContourModel *>(workingContour.first->GetData());
 
     if (nullptr == contour)
       continue;
 
     const auto numberOfTimeSteps = contour->GetTimeSteps();
 
     for (std::remove_const_t<decltype(numberOfTimeSteps)> t = 0; t < numberOfTimeSteps; ++t)
     {
       if (contour->IsEmptyTimeStep(t))
         continue;
 
       TimePointType referenceImageTimePoint = referenceImage->GetTimeGeometry()->TimeStepToTimePoint(t);
       TimeStepType workingImageTimeStep = workingImage->GetTimeGeometry()->TimePointToTimeStep(referenceImageTimePoint);
 
       auto workingSlice = this->GetAffectedImageSliceAs2DImage(workingContour.second, workingImage, workingImageTimeStep);
       auto projectedContour = ContourModelUtils::ProjectContourTo2DSlice(workingSlice, contour, true, false);
-
-      auto* labelSetImage = dynamic_cast<LabelSetImage*>(workingImage);
-      int activePixelValue = 1;
-      if (nullptr != labelSetImage)
-      {
-        activePixelValue = labelSetImage->GetActiveLabel(labelSetImage->GetActiveLayer())->GetValue();
-      }
+      int activePixelValue = ContourModelUtils::GetActivePixelValue(workingImage);
 
       ContourModelUtils::FillContourInSlice(
         projectedContour, referenceImageTimePoint, workingSlice, workingImage, activePixelValue);
 
       sliceInfos.emplace_back(workingSlice, workingContour.second, referenceImageTimePoint);
       this->WriteSliceToVolume(sliceInfos.back());
     }
   }
 
   this->WriteBackSegmentationResult(sliceInfos, false);
   this->ClearSegmentation();
 }
 
 void mitk::LiveWireTool2D::ClearSegmentation()
 {
   this->ReleaseHelperObjects();
   this->ReleaseInteractors();
   this->ResetToStartState();
 }
 
 bool mitk::LiveWireTool2D::IsPositionEventInsideImageRegion(mitk::InteractionPositionEvent *positionEvent,
                                                             mitk::BaseData *data)
 {
   bool isPositionEventInsideImageRegion = nullptr != data && data->GetGeometry()->IsInside(positionEvent->GetPositionInWorld());
 
   if (!isPositionEventInsideImageRegion)
     MITK_WARN("LiveWireTool2D") << "PositionEvent is outside ImageRegion!";
 
   return isPositionEventInsideImageRegion;
 }
 
 void mitk::LiveWireTool2D::OnInitLiveWire(StateMachineAction *, InteractionEvent *interactionEvent)
 {
   auto positionEvent = dynamic_cast<mitk::InteractionPositionEvent *>(interactionEvent);
 
   if (nullptr == positionEvent)
     return;
 
   auto workingDataNode = m_ToolManager->GetWorkingData(0);
 
   if (!IsPositionEventInsideImageRegion(positionEvent, workingDataNode->GetData()))
   {
     this->ResetToStartState();
     return;
   }
 
   m_LastEventSender = positionEvent->GetSender();
   m_LastEventSlice = m_LastEventSender->GetSlice();
 
   auto t = positionEvent->GetSender()->GetTimeStep();
 
   m_Contour = mitk::ContourModel::New();
   m_Contour->Expand(t + 1);
   m_ContourNode = mitk::DataNode::New();
   m_ContourNode->SetData(m_Contour);
   m_ContourNode->SetName("working contour node");
   m_ContourNode->SetProperty("layer", IntProperty::New(100));
   m_ContourNode->AddProperty("fixedLayer", BoolProperty::New(true));
   m_ContourNode->SetProperty("helper object", mitk::BoolProperty::New(true));
   m_ContourNode->AddProperty("contour.color", ColorProperty::New(1.0f, 1.0f, 0.0f), nullptr, true);
   m_ContourNode->AddProperty("contour.points.color", ColorProperty::New(1.0f, 0.0f, 0.1f), nullptr, true);
   m_ContourNode->AddProperty("contour.controlpoints.show", BoolProperty::New(true), nullptr, true);
 
   m_LiveWireContour = mitk::ContourModel::New();
   m_LiveWireContour->Expand(t + 1);
   m_LiveWireContourNode = mitk::DataNode::New();
   m_LiveWireContourNode->SetData(m_LiveWireContour);
   m_LiveWireContourNode->SetName("active livewire node");
   m_LiveWireContourNode->SetProperty("layer", IntProperty::New(101));
   m_LiveWireContourNode->AddProperty("fixedLayer", BoolProperty::New(true));
   m_LiveWireContourNode->SetProperty("helper object", mitk::BoolProperty::New(true));
   m_LiveWireContourNode->AddProperty("contour.color", ColorProperty::New(0.1f, 1.0f, 0.1f), nullptr, true);
   m_LiveWireContourNode->AddProperty("contour.width", mitk::FloatProperty::New(4.0f), nullptr, true);
 
   m_EditingContour = mitk::ContourModel::New();
   m_EditingContour->Expand(t + 1);
   m_EditingContourNode = mitk::DataNode::New();
   m_EditingContourNode->SetData(m_EditingContour);
   m_EditingContourNode->SetName("editing node");
   m_EditingContourNode->SetProperty("layer", IntProperty::New(102));
   m_EditingContourNode->AddProperty("fixedLayer", BoolProperty::New(true));
   m_EditingContourNode->SetProperty("helper object", mitk::BoolProperty::New(true));
   m_EditingContourNode->AddProperty("contour.color", ColorProperty::New(0.1f, 1.0f, 0.1f), nullptr, true);
   m_EditingContourNode->AddProperty("contour.points.color", ColorProperty::New(0.0f, 0.0f, 1.0f), nullptr, true);
   m_EditingContourNode->AddProperty("contour.width", mitk::FloatProperty::New(4.0f), nullptr, true);
 
   auto dataStorage = m_ToolManager->GetDataStorage();
   dataStorage->Add(m_ContourNode, workingDataNode);
   dataStorage->Add(m_LiveWireContourNode, workingDataNode);
   dataStorage->Add(m_EditingContourNode, workingDataNode);
 
   // Set current slice as input for ImageToLiveWireContourFilter
   m_WorkingSlice = this->GetAffectedReferenceSlice(positionEvent);
 
   auto origin = m_WorkingSlice->GetSlicedGeometry()->GetOrigin();
   m_WorkingSlice->GetSlicedGeometry()->WorldToIndex(origin, origin);
   m_WorkingSlice->GetSlicedGeometry()->IndexToWorld(origin, origin);
   m_WorkingSlice->GetSlicedGeometry()->SetOrigin(origin);
 
   m_LiveWireFilter = ImageLiveWireContourModelFilter::New();
   m_LiveWireFilter->SetInput(m_WorkingSlice);
 
   // Map click to pixel coordinates
   auto click = positionEvent->GetPositionInWorld();
   itk::Index<3> idx;
   m_WorkingSlice->GetGeometry()->WorldToIndex(click, idx);
 
   // Get the pixel with the highest gradient in a 7x7 region
   itk::Index<3> indexWithHighestGradient;
   AccessFixedDimensionByItk_2(m_WorkingSlice, FindHighestGradientMagnitudeByITK, 2, idx, indexWithHighestGradient);
 
   click[0] = indexWithHighestGradient[0];
   click[1] = indexWithHighestGradient[1];
   click[2] = indexWithHighestGradient[2];
   m_WorkingSlice->GetGeometry()->IndexToWorld(click, click);
 
   // Set initial start point
   m_Contour->AddVertex(click, true, t);
   m_LiveWireFilter->SetStartPoint(click);
 
   // Remember PlaneGeometry to determine if events were triggered in the same plane
   m_PlaneGeometry = interactionEvent->GetSender()->GetCurrentWorldPlaneGeometry();
 
   m_CreateAndUseDynamicCosts = true;
 
   mitk::RenderingManager::GetInstance()->RequestUpdate(positionEvent->GetSender()->GetRenderWindow());
 }
 
 void mitk::LiveWireTool2D::OnAddPoint(StateMachineAction *, InteractionEvent *interactionEvent)
 {
   // Complete LiveWire interaction for the last segment. Add current LiveWire contour to
   // the finished contour and reset to start a new segment and computation.
 
   auto positionEvent = dynamic_cast<mitk::InteractionPositionEvent *>(interactionEvent);
 
   if (nullptr == positionEvent)
     return;
 
   if (m_PlaneGeometry.IsNotNull())
   {
     // Check if the point is in the correct slice
     if (m_PlaneGeometry->DistanceFromPlane(positionEvent->GetPositionInWorld()) > mitk::sqrteps)
       return;
   }
 
   auto t = static_cast<int>(positionEvent->GetSender()->GetTimeStep());
 
   // Add repulsive points to avoid getting the same path again
   std::for_each(m_LiveWireContour->IteratorBegin(), m_LiveWireContour->IteratorEnd(), [this](ContourElement::VertexType *vertex) {
     ImageLiveWireContourModelFilter::InternalImageType::IndexType idx;
     this->m_WorkingSlice->GetGeometry()->WorldToIndex(vertex->Coordinates, idx);
     this->m_LiveWireFilter->AddRepulsivePoint(idx);
   });
 
   // Remove duplicate first vertex, it's already contained in m_Contour
   m_LiveWireContour->RemoveVertexAt(0, t);
 
   // Set last point as control point
   m_LiveWireContour->SetControlVertexAt(m_LiveWireContour->GetNumberOfVertices(t) - 1, t);
 
   // Merge contours
   m_Contour->Concatenate(m_LiveWireContour, t);
 
   // Clear the LiveWire contour and reset the corresponding DataNode
   m_LiveWireContour->Clear(t);
 
   // Set new start point
   m_LiveWireFilter->SetStartPoint(positionEvent->GetPositionInWorld());
 
   if (m_CreateAndUseDynamicCosts)
   {
     // Use dynamic cost map for next update
     m_LiveWireFilter->CreateDynamicCostMap(m_Contour);
     m_LiveWireFilter->SetUseDynamicCostMap(true);
   }
 
   mitk::RenderingManager::GetInstance()->RequestUpdate(positionEvent->GetSender()->GetRenderWindow());
 }
 
 void mitk::LiveWireTool2D::OnMouseMoved(StateMachineAction *, InteractionEvent *interactionEvent)
 {
   // Compute LiveWire segment from last control point to current mouse position
 
   auto positionEvent = dynamic_cast<mitk::InteractionPositionEvent *>(interactionEvent);
 
   if (nullptr == positionEvent)
     return;
 
   auto t = positionEvent->GetSender()->GetTimeStep();
 
   m_LiveWireFilter->SetEndPoint(positionEvent->GetPositionInWorld());
   m_LiveWireFilter->SetTimeStep(t);
   m_LiveWireFilter->Update();
 
   m_LiveWireContour = this->m_LiveWireFilter->GetOutput();
   m_LiveWireContourNode->SetData(this->m_LiveWireContour);
 
   RenderingManager::GetInstance()->RequestUpdate(positionEvent->GetSender()->GetRenderWindow());
 }
 
 void mitk::LiveWireTool2D::OnMouseMoveNoDynamicCosts(StateMachineAction *, InteractionEvent *interactionEvent)
 {
   m_LiveWireFilter->SetUseDynamicCostMap(false);
   this->OnMouseMoved(nullptr, interactionEvent);
   m_LiveWireFilter->SetUseDynamicCostMap(true);
 }
 
 bool mitk::LiveWireTool2D::OnCheckPoint(const InteractionEvent *interactionEvent)
 {
   // Check double click on first control point to finish the LiveWire tool
 
   auto positionEvent = dynamic_cast<const mitk::InteractionPositionEvent *>(interactionEvent);
 
   if (nullptr == positionEvent)
     return false;
 
   auto t = static_cast<int>(positionEvent->GetSender()->GetTimeStep());
 
   mitk::Point3D click = positionEvent->GetPositionInWorld();
   mitk::Point3D first = this->m_Contour->GetVertexAt(0, t)->Coordinates;
 
   return first.EuclideanDistanceTo(click) < 4.5;
 }
 
 void mitk::LiveWireTool2D::OnFinish(StateMachineAction *, InteractionEvent *interactionEvent)
 {
   // Finish LiveWire tool interaction
 
   auto positionEvent = dynamic_cast<mitk::InteractionPositionEvent *>(interactionEvent);
 
   if (nullptr == positionEvent)
     return;
 
   // Have to do that here so that the m_LastEventSender is set correctly
   mitk::SegTool2D::AddContourmarker();
 
   auto t = static_cast<int>(positionEvent->GetSender()->GetTimeStep());
 
   // Remove last control point added by double click
   m_Contour->RemoveVertexAt(m_Contour->GetNumberOfVertices(t) - 1, t);
 
   // Save contour and corresponding plane geometry to list
   this->m_WorkingContours.emplace_back(std::make_pair(m_ContourNode, positionEvent->GetSender()->GetCurrentWorldPlaneGeometry()->Clone()));
   this->m_EditingContours.emplace_back(std::make_pair(m_EditingContourNode, positionEvent->GetSender()->GetCurrentWorldPlaneGeometry()->Clone()));
 
   m_LiveWireFilter->SetUseDynamicCostMap(false);
 
   this->FinishTool();
 }
 
 void mitk::LiveWireTool2D::FinishTool()
 {
   auto numberOfTimesteps = static_cast<int>(m_Contour->GetTimeGeometry()->CountTimeSteps());
 
   for (int i = 0; i <= numberOfTimesteps; ++i)
     m_Contour->Close(i);
 
   m_ToolManager->GetDataStorage()->Remove(m_LiveWireContourNode);
 
   m_LiveWireContourNode = nullptr;
   m_LiveWireContour = nullptr;
 
   m_ContourInteractor = mitk::ContourModelLiveWireInteractor::New();
   m_ContourInteractor->SetDataNode(m_ContourNode);
   m_ContourInteractor->LoadStateMachine("ContourModelModificationInteractor.xml", us::GetModuleContext()->GetModule());
   m_ContourInteractor->SetEventConfig("ContourModelModificationConfig.xml", us::GetModuleContext()->GetModule());
   m_ContourInteractor->SetWorkingImage(this->m_WorkingSlice);
   m_ContourInteractor->SetEditingContourModelNode(this->m_EditingContourNode);
 
   m_ContourNode->SetDataInteractor(m_ContourInteractor.GetPointer());
 
   this->m_LiveWireInteractors.push_back(m_ContourInteractor);
 }
 
 void mitk::LiveWireTool2D::OnLastSegmentDelete(StateMachineAction *, InteractionEvent *interactionEvent)
 {
   int t = static_cast<int>(interactionEvent->GetSender()->GetTimeStep());
 
   // If last point of current contour will be removed go to start state and remove nodes
   if (m_Contour->GetNumberOfVertices(t) <= 1)
   {
     auto dataStorage = m_ToolManager->GetDataStorage();
 
     dataStorage->Remove(m_LiveWireContourNode);
     dataStorage->Remove(m_ContourNode);
     dataStorage->Remove(m_EditingContourNode);
 
     m_LiveWireContour = mitk::ContourModel::New();
     m_LiveWireContourNode->SetData(m_LiveWireContour);
 
     m_Contour = mitk::ContourModel::New();
     m_ContourNode->SetData(m_Contour);
 
     this->ResetToStartState();
   }
   else // Remove last segment from contour and reset LiveWire contour
   {
     m_LiveWireContour = mitk::ContourModel::New();
     m_LiveWireContourNode->SetData(m_LiveWireContour);
 
     auto newContour = mitk::ContourModel::New();
     newContour->Expand(m_Contour->GetTimeSteps());
 
     auto begin = m_Contour->IteratorBegin();
 
     // Iterate from last point to next active point
     auto newLast = m_Contour->IteratorBegin() + (m_Contour->GetNumberOfVertices() - 1);
 
     // Go at least one down
     if (newLast != begin)
       --newLast;
 
     // Search next active control point
     while (newLast != begin && !((*newLast)->IsControlPoint))
       --newLast;
 
     // Set position of start point for LiveWire filter to coordinates of the new last point
     m_LiveWireFilter->SetStartPoint((*newLast)->Coordinates);
 
     auto it = m_Contour->IteratorBegin();
 
     // Fll new Contour
     while (it <= newLast)
     {
       newContour->AddVertex((*it)->Coordinates, (*it)->IsControlPoint, t);
       ++it;
     }
 
     newContour->SetClosed(m_Contour->IsClosed());
 
     m_ContourNode->SetData(newContour);
     m_Contour = newContour;
 
     mitk::RenderingManager::GetInstance()->RequestUpdate(interactionEvent->GetSender()->GetRenderWindow());
   }
 }
 
 template <typename TPixel, unsigned int VImageDimension>
 void mitk::LiveWireTool2D::FindHighestGradientMagnitudeByITK(itk::Image<TPixel, VImageDimension> *inputImage,
                                                              itk::Index<3> &index,
                                                              itk::Index<3> &returnIndex)
 {
   typedef itk::Image<TPixel, VImageDimension> InputImageType;
   typedef typename InputImageType::IndexType IndexType;
 
   const auto MAX_X = inputImage->GetLargestPossibleRegion().GetSize()[0];
   const auto MAX_Y = inputImage->GetLargestPossibleRegion().GetSize()[1];
 
   returnIndex[0] = index[0];
   returnIndex[1] = index[1];
   returnIndex[2] = 0.0;
 
   double gradientMagnitude = 0.0;
   double maxGradientMagnitude = 0.0;
 
   // The size and thus the region of 7x7 is only used to calculate the gradient magnitude in that region,
   // not for searching the maximum value.
 
   // Maximum value in each direction for size
   typename InputImageType::SizeType size;
   size[0] = 7;
   size[1] = 7;
 
   // Minimum value in each direction for startRegion
   IndexType startRegion;
   startRegion[0] = index[0] - 3;
   startRegion[1] = index[1] - 3;
   if (startRegion[0] < 0)
     startRegion[0] = 0;
   if (startRegion[1] < 0)
     startRegion[1] = 0;
   if (MAX_X - index[0] < 7)
     startRegion[0] = MAX_X - 7;
   if (MAX_Y - index[1] < 7)
     startRegion[1] = MAX_Y - 7;
 
   index[0] = startRegion[0] + 3;
   index[1] = startRegion[1] + 3;
 
   typename InputImageType::RegionType region;
   region.SetSize(size);
   region.SetIndex(startRegion);
 
   typedef typename itk::GradientMagnitudeImageFilter<InputImageType, InputImageType> GradientMagnitudeFilterType;
   typename GradientMagnitudeFilterType::Pointer gradientFilter = GradientMagnitudeFilterType::New();
   gradientFilter->SetInput(inputImage);
   gradientFilter->GetOutput()->SetRequestedRegion(region);
 
   gradientFilter->Update();
   typename InputImageType::Pointer gradientMagnitudeImage;
   gradientMagnitudeImage = gradientFilter->GetOutput();
 
   IndexType currentIndex;
   currentIndex[0] = 0;
   currentIndex[1] = 0;
 
   // Search max (approximate) gradient magnitude
   for (int x = -1; x <= 1; ++x)
   {
     currentIndex[0] = index[0] + x;
 
     for (int y = -1; y <= 1; ++y)
     {
       currentIndex[1] = index[1] + y;
       gradientMagnitude = gradientMagnitudeImage->GetPixel(currentIndex);
 
       // Check for new max
       if (maxGradientMagnitude < gradientMagnitude)
       {
         maxGradientMagnitude = gradientMagnitude;
         returnIndex[0] = currentIndex[0];
         returnIndex[1] = currentIndex[1];
         returnIndex[2] = 0.0;
       }
     }
 
     currentIndex[1] = index[1];
   }
 }
diff --git a/Modules/Segmentation/Interactions/mitkPaintbrushTool.cpp b/Modules/Segmentation/Interactions/mitkPaintbrushTool.cpp
index f3bb9b4500..de9837ba8d 100644
--- a/Modules/Segmentation/Interactions/mitkPaintbrushTool.cpp
+++ b/Modules/Segmentation/Interactions/mitkPaintbrushTool.cpp
@@ -1,594 +1,587 @@
 /*============================================================================
 
 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 "mitkPaintbrushTool.h"
 
 #include "ipSegmentation.h"
 #include "mitkAbstractTransformGeometry.h"
 #include "mitkBaseRenderer.h"
 #include "mitkImageDataItem.h"
 #include "mitkOverwriteSliceImageFilter.h"
 #include "mitkToolManager.h"
 
 #include "mitkContourModelUtils.h"
-#include "mitkLabelSetImage.h"
 #include "mitkLevelWindowProperty.h"
 
 int mitk::PaintbrushTool::m_Size = 1;
 
 mitk::PaintbrushTool::PaintbrushTool(int paintingPixelValue)
   : FeedbackContourTool("PressMoveReleaseWithCTRLInversionAllMouseMoves"),
     m_PaintingPixelValue(paintingPixelValue),
     m_LastContourSize(0) // other than initial mitk::PaintbrushTool::m_Size (around l. 28)
 {
   m_MasterContour = ContourModel::New();
   m_MasterContour->Initialize();
   m_CurrentPlane = nullptr;
 
   m_WorkingNode = DataNode::New();
   m_WorkingNode->SetProperty("levelwindow", mitk::LevelWindowProperty::New(mitk::LevelWindow(0, 1)));
   m_WorkingNode->SetProperty("binary", mitk::BoolProperty::New(true));
 }
 
 mitk::PaintbrushTool::~PaintbrushTool()
 {
 }
 
 void mitk::PaintbrushTool::ConnectActionsAndFunctions()
 {
   CONNECT_FUNCTION("PrimaryButtonPressed", OnMousePressed);
   CONNECT_FUNCTION("Move", OnPrimaryButtonPressedMoved);
   CONNECT_FUNCTION("MouseMove", OnMouseMoved);
   CONNECT_FUNCTION("Release", OnMouseReleased);
   CONNECT_FUNCTION("InvertLogic", OnInvertLogic);
 }
 
 void mitk::PaintbrushTool::Activated()
 {
   Superclass::Activated();
 
   FeedbackContourTool::SetFeedbackContourVisible(true);
   SizeChanged.Send(m_Size);
   m_ToolManager->WorkingDataChanged +=
     mitk::MessageDelegate<mitk::PaintbrushTool>(this, &mitk::PaintbrushTool::OnToolManagerWorkingDataModified);
 }
 
 void mitk::PaintbrushTool::Deactivated()
 {
   FeedbackContourTool::SetFeedbackContourVisible(false);
   if (m_ToolManager->GetDataStorage()->Exists(m_WorkingNode))
     m_ToolManager->GetDataStorage()->Remove(m_WorkingNode);
   m_WorkingSlice = nullptr;
   m_CurrentPlane = nullptr;
   m_ToolManager->WorkingDataChanged -=
     mitk::MessageDelegate<mitk::PaintbrushTool>(this, &mitk::PaintbrushTool::OnToolManagerWorkingDataModified);
 
   Superclass::Deactivated();
 }
 
 void mitk::PaintbrushTool::SetSize(int value)
 {
   m_Size = value;
 }
 
 mitk::Point2D mitk::PaintbrushTool::upperLeft(mitk::Point2D p)
 {
   p[0] -= 0.5;
   p[1] += 0.5;
   return p;
 }
 
 void mitk::PaintbrushTool::UpdateContour(const InteractionPositionEvent *positionEvent)
 {
   // MITK_INFO<<"Update...";
   // examine stateEvent and create a contour that matches the pixel mask that we are going to draw
   // mitk::InteractionPositionEvent* positionEvent = dynamic_cast<mitk::InteractionPositionEvent*>( interactionEvent );
   // const PositionEvent* positionEvent = dynamic_cast<const PositionEvent*>(stateEvent->GetEvent());
   if (!positionEvent)
     return;
 
   // Get Spacing of current Slice
   // mitk::Vector3D vSpacing = m_WorkingSlice->GetSlicedGeometry()->GetPlaneGeometry(0)->GetSpacing();
 
   //
   // Draw a contour in Square according to selected brush size
   //
   int radius = (m_Size) / 2;
   float fradius = static_cast<float>(m_Size) / 2.0f;
 
   ContourModel::Pointer contourInImageIndexCoordinates = ContourModel::New();
 
   // estimate center point of the brush ( relative to the pixel the mouse points on )
   // -- left upper corner for even sizes,
   // -- midpoint for uneven sizes
   mitk::Point2D centerCorrection;
   centerCorrection.Fill(0);
 
   // even --> correction of [+0.5, +0.5]
   bool evenSize = ((m_Size % 2) == 0);
   if (evenSize)
   {
     centerCorrection[0] += 0.5;
     centerCorrection[1] += 0.5;
   }
 
   // we will compute the control points for the upper left quarter part of a circle contour
   std::vector<mitk::Point2D> quarterCycleUpperRight;
   std::vector<mitk::Point2D> quarterCycleLowerRight;
   std::vector<mitk::Point2D> quarterCycleLowerLeft;
   std::vector<mitk::Point2D> quarterCycleUpperLeft;
 
   mitk::Point2D curPoint;
   bool curPointIsInside = true;
   curPoint[0] = 0;
   curPoint[1] = radius;
   quarterCycleUpperRight.push_back(upperLeft(curPoint));
 
   // to estimate if a pixel is inside the circle, we need to compare against the 'outer radius'
   // i.e. the distance from the midpoint [0,0] to the border of the pixel [0,radius]
   // const float outer_radius = static_cast<float>(radius) + 0.5;
 
   while (curPoint[1] > 0)
   {
     // Move right until pixel is outside circle
     float curPointX_squared = 0.0f;
     float curPointY_squared = (curPoint[1] - centerCorrection[1]) * (curPoint[1] - centerCorrection[1]);
     while (curPointIsInside)
     {
       // increment posX and chec
       curPoint[0]++;
       curPointX_squared = (curPoint[0] - centerCorrection[0]) * (curPoint[0] - centerCorrection[0]);
       const float len = sqrt(curPointX_squared + curPointY_squared);
       if (len > fradius)
       {
         // found first Pixel in this horizontal line, that is outside the circle
         curPointIsInside = false;
       }
     }
     quarterCycleUpperRight.push_back(upperLeft(curPoint));
 
     // Move down until pixel is inside circle
     while (!curPointIsInside)
     {
       // increment posX and chec
       curPoint[1]--;
       curPointY_squared = (curPoint[1] - centerCorrection[1]) * (curPoint[1] - centerCorrection[1]);
       const float len = sqrt(curPointX_squared + curPointY_squared);
       if (len <= fradius)
       {
         // found first Pixel in this horizontal line, that is outside the circle
         curPointIsInside = true;
         quarterCycleUpperRight.push_back(upperLeft(curPoint));
       }
 
       // Quarter cycle is full, when curPoint y position is 0
       if (curPoint[1] <= 0)
         break;
     }
   }
 
   // QuarterCycle is full! Now copy quarter cycle to other quarters.
 
   if (!evenSize)
   {
     std::vector<mitk::Point2D>::const_iterator it = quarterCycleUpperRight.begin();
     while (it != quarterCycleUpperRight.end())
     {
       mitk::Point2D p;
       p = *it;
 
       // the contour points in the lower right corner have same position but with negative y values
       p[1] *= -1;
       quarterCycleLowerRight.push_back(p);
 
       // the contour points in the lower left corner have same position
       // but with both x,y negative
       p[0] *= -1;
       quarterCycleLowerLeft.push_back(p);
 
       // the contour points in the upper left corner have same position
       // but with x negative
       p[1] *= -1;
       quarterCycleUpperLeft.push_back(p);
 
       it++;
     }
   }
   else
   {
     std::vector<mitk::Point2D>::const_iterator it = quarterCycleUpperRight.begin();
     while (it != quarterCycleUpperRight.end())
     {
       mitk::Point2D p, q;
       p = *it;
 
       q = p;
       // the contour points in the lower right corner have same position but with negative y values
       q[1] *= -1;
       // correct for moved offset if size even = the midpoint is not the midpoint of the current pixel
       // but its upper rigt corner
       q[1] += 1;
       quarterCycleLowerRight.push_back(q);
 
       q = p;
       // the contour points in the lower left corner have same position
       // but with both x,y negative
       q[1] = -1.0f * q[1] + 1;
       q[0] = -1.0f * q[0] + 1;
       quarterCycleLowerLeft.push_back(q);
 
       // the contour points in the upper left corner have same position
       // but with x negative
       q = p;
       q[0] *= -1;
       q[0] += 1;
       quarterCycleUpperLeft.push_back(q);
 
       it++;
     }
   }
 
   // fill contour with poins in right ordering, starting with the upperRight block
   mitk::Point3D tempPoint;
   for (unsigned int i = 0; i < quarterCycleUpperRight.size(); i++)
   {
     tempPoint[0] = quarterCycleUpperRight[i][0];
     tempPoint[1] = quarterCycleUpperRight[i][1];
     tempPoint[2] = 0;
     contourInImageIndexCoordinates->AddVertex(tempPoint);
   }
   // the lower right has to be parsed in reverse order
   for (int i = quarterCycleLowerRight.size() - 1; i >= 0; i--)
   {
     tempPoint[0] = quarterCycleLowerRight[i][0];
     tempPoint[1] = quarterCycleLowerRight[i][1];
     tempPoint[2] = 0;
     contourInImageIndexCoordinates->AddVertex(tempPoint);
   }
   for (unsigned int i = 0; i < quarterCycleLowerLeft.size(); i++)
   {
     tempPoint[0] = quarterCycleLowerLeft[i][0];
     tempPoint[1] = quarterCycleLowerLeft[i][1];
     tempPoint[2] = 0;
     contourInImageIndexCoordinates->AddVertex(tempPoint);
   }
   // the upper left also has to be parsed in reverse order
   for (int i = quarterCycleUpperLeft.size() - 1; i >= 0; i--)
   {
     tempPoint[0] = quarterCycleUpperLeft[i][0];
     tempPoint[1] = quarterCycleUpperLeft[i][1];
     tempPoint[2] = 0;
     contourInImageIndexCoordinates->AddVertex(tempPoint);
   }
 
   m_MasterContour = contourInImageIndexCoordinates;
 }
 
 /**
   Just show the contour, get one point as the central point and add surrounding points to the contour.
   */
 void mitk::PaintbrushTool::OnMousePressed(StateMachineAction *, InteractionEvent *interactionEvent)
 {
   if (m_WorkingSlice.IsNull())
     return;
 
   auto *positionEvent = dynamic_cast<mitk::InteractionPositionEvent *>(interactionEvent);
   if (!positionEvent)
     return;
 
   m_WorkingSlice->GetGeometry()->WorldToIndex(positionEvent->GetPositionInWorld(), m_LastPosition);
 
   // create new working node
   // a fresh node is needed to only display the actual drawing process for
   // the undo function
   if (m_ToolManager->GetDataStorage()->Exists(m_WorkingNode))
     m_ToolManager->GetDataStorage()->Remove(m_WorkingNode);
   m_WorkingSlice = nullptr;
   m_CurrentPlane = nullptr;
 
   m_WorkingNode = DataNode::New();
   m_WorkingNode->SetProperty("levelwindow", mitk::LevelWindowProperty::New(mitk::LevelWindow(0, 1)));
   m_WorkingNode->SetProperty("binary", mitk::BoolProperty::New(true));
 
   this->m_WorkingNode->SetVisibility(true);
 
   m_LastEventSender = positionEvent->GetSender();
   m_LastEventSlice = m_LastEventSender->GetSlice();
 
   m_MasterContour->SetClosed(true);
   this->MouseMoved(interactionEvent, true);
 }
 
 void mitk::PaintbrushTool::OnMouseMoved(StateMachineAction *, InteractionEvent *interactionEvent)
 {
   MouseMoved(interactionEvent, false);
 }
 
 void mitk::PaintbrushTool::OnPrimaryButtonPressedMoved(StateMachineAction *, InteractionEvent *interactionEvent)
 {
   MouseMoved(interactionEvent, true);
 }
 
 /**
   Insert the point to the feedback contour,finish to build the contour and at the same time the painting function
   */
 void mitk::PaintbrushTool::MouseMoved(mitk::InteractionEvent *interactionEvent, bool leftMouseButtonPressed)
 {
   auto *positionEvent = dynamic_cast<mitk::InteractionPositionEvent *>(interactionEvent);
 
   CheckIfCurrentSliceHasChanged(positionEvent);
 
   if (m_LastContourSize != m_Size)
   {
     UpdateContour(positionEvent);
     m_LastContourSize = m_Size;
   }
 
   Point3D worldCoordinates = positionEvent->GetPositionInWorld();
   Point3D indexCoordinates;
 
   m_WorkingSlice->GetGeometry()->WorldToIndex(worldCoordinates, indexCoordinates);
 
   // round to nearest voxel center (abort if this hasn't changed)
   if (m_Size % 2 == 0) // even
   {
     indexCoordinates[0] = std::round(indexCoordinates[0]);
     indexCoordinates[1] = std::round(indexCoordinates[1]);
   }
   else // odd
   {
     indexCoordinates[0] = std::round(indexCoordinates[0]);
     indexCoordinates[1] = std::round(indexCoordinates[1]);
   }
 
   static Point3D lastPos; // uninitialized: if somebody finds out how this can be initialized in a one-liner, tell me
   if (fabs(indexCoordinates[0] - lastPos[0]) > mitk::eps || fabs(indexCoordinates[1] - lastPos[1]) > mitk::eps ||
       fabs(indexCoordinates[2] - lastPos[2]) > mitk::eps || leftMouseButtonPressed)
   {
     lastPos = indexCoordinates;
   }
   else
   {
     return;
   }
 
   int t = positionEvent->GetSender()->GetTimeStep();
 
   auto contour = ContourModel::New();
   contour->SetClosed(true);
 
   auto it = m_MasterContour->Begin();
   auto end = m_MasterContour->End();
 
   while (it != end)
   {
     auto point = (*it)->Coordinates;
     point[0] += indexCoordinates[0];
     point[1] += indexCoordinates[1];
 
     contour->AddVertex(point);
     ++it;
   }
 
   if (leftMouseButtonPressed)
   {
     const double dist = indexCoordinates.EuclideanDistanceTo(m_LastPosition);
     const double radius = static_cast<double>(m_Size) / 2.0;
 
     DataNode *workingNode(m_ToolManager->GetWorkingData(0));
-    Image::Pointer image = dynamic_cast<Image *>(workingNode->GetData());
-    auto *labelSetImage = dynamic_cast<LabelSetImage *>(image.GetPointer());
-
-    int activePixelValue = 1;
-    if (nullptr != labelSetImage)
-    {
-      activePixelValue = labelSetImage->GetActiveLabel(labelSetImage->GetActiveLayer())->GetValue();
-    }
+    auto workingImage = dynamic_cast<Image*>(workingNode->GetData());
+    int activePixelValue = ContourModelUtils::GetActivePixelValue(workingImage);
 
     // m_PaintingPixelValue only decides whether to paint or erase
     mitk::ContourModelUtils::FillContourInSlice(
-      contour, m_WorkingSlice, image, m_PaintingPixelValue * activePixelValue);
+      contour, m_WorkingSlice, workingImage, m_PaintingPixelValue * activePixelValue);
 
     m_WorkingNode->SetData(m_WorkingSlice);
     m_WorkingNode->Modified();
 
     // if points are >= radius away draw rectangle to fill empty holes
     // in between the 2 points
     if (dist > radius)
     {
       const mitk::Point3D &currentPos = indexCoordinates;
       mitk::Point3D direction;
       mitk::Point3D vertex;
       mitk::Point3D normal;
 
       direction[0] = indexCoordinates[0] - m_LastPosition[0];
       direction[1] = indexCoordinates[1] - m_LastPosition[1];
       direction[2] = indexCoordinates[2] - m_LastPosition[2];
 
       direction[0] = direction.GetVnlVector().normalize()[0];
       direction[1] = direction.GetVnlVector().normalize()[1];
       direction[2] = direction.GetVnlVector().normalize()[2];
 
       // 90 degrees rotation of direction
       normal[0] = -1.0 * direction[1];
       normal[1] = direction[0];
 
       contour->Clear();
 
       // upper left corner
       vertex[0] = m_LastPosition[0] + (normal[0] * radius);
       vertex[1] = m_LastPosition[1] + (normal[1] * radius);
 
       contour->AddVertex(vertex);
 
       // upper right corner
       vertex[0] = currentPos[0] + (normal[0] * radius);
       vertex[1] = currentPos[1] + (normal[1] * radius);
 
       contour->AddVertex(vertex);
 
       // lower right corner
       vertex[0] = currentPos[0] - (normal[0] * radius);
       vertex[1] = currentPos[1] - (normal[1] * radius);
 
       contour->AddVertex(vertex);
 
       // lower left corner
       vertex[0] = m_LastPosition[0] - (normal[0] * radius);
       vertex[1] = m_LastPosition[1] - (normal[1] * radius);
 
       contour->AddVertex(vertex);
 
-      mitk::ContourModelUtils::FillContourInSlice(contour, m_WorkingSlice, image, m_PaintingPixelValue * activePixelValue);
+      mitk::ContourModelUtils::FillContourInSlice(contour, m_WorkingSlice, workingImage, m_PaintingPixelValue * activePixelValue);
       m_WorkingNode->SetData(m_WorkingSlice);
       m_WorkingNode->Modified();
     }
   }
   else
   {
     // switched from different renderwindow
     // no activate hover highlighting. Otherwise undo / redo wont work
     this->m_WorkingNode->SetVisibility(false);
   }
 
   m_LastPosition = indexCoordinates;
 
   // visualize contour
   ContourModel::Pointer displayContour = FeedbackContourTool::GetFeedbackContour();
   displayContour->Clear();
 
   ContourModel::Pointer tmp =
     FeedbackContourTool::BackProjectContourFrom2DSlice(m_WorkingSlice->GetGeometry(), contour);
 
   // copy transformed contour into display contour
   it = tmp->Begin();
   end = tmp->End();
 
   while (it != end)
   {
     Point3D point = (*it)->Coordinates;
 
     displayContour->AddVertex(point, t);
     it++;
   }
 
   m_FeedbackContourNode->GetData()->Modified();
 
   assert(positionEvent->GetSender()->GetRenderWindow());
 
   RenderingManager::GetInstance()->RequestUpdate(positionEvent->GetSender()->GetRenderWindow());
 }
 
 void mitk::PaintbrushTool::OnMouseReleased(StateMachineAction *, InteractionEvent *interactionEvent)
 {
   // When mouse is released write segmentationresult back into image
   auto *positionEvent = dynamic_cast<mitk::InteractionPositionEvent *>(interactionEvent);
   if (!positionEvent)
     return;
 
   this->WriteBackSegmentationResult(positionEvent, m_WorkingSlice->Clone());
 
   // deactivate visibility of helper node
   m_WorkingNode->SetVisibility(false);
 
   RenderingManager::GetInstance()->RequestUpdate(positionEvent->GetSender()->GetRenderWindow());
 }
 
 /**
   Called when the CTRL key is pressed. Will change the painting pixel value from 0 to 1 or from 1 to 0.
   */
 void mitk::PaintbrushTool::OnInvertLogic(StateMachineAction *, InteractionEvent *)
 {
   // Inversion only for 0 and 1 as painting values
   if (m_PaintingPixelValue == 1)
   {
     m_PaintingPixelValue = 0;
     FeedbackContourTool::SetFeedbackContourColor(1.0, 0.0, 0.0);
   }
   else if (m_PaintingPixelValue == 0)
   {
     m_PaintingPixelValue = 1;
     FeedbackContourTool::SetFeedbackContourColorDefault();
   }
   mitk::RenderingManager::GetInstance()->RequestUpdateAll();
 }
 
 void mitk::PaintbrushTool::CheckIfCurrentSliceHasChanged(const InteractionPositionEvent *event)
 {
   const PlaneGeometry *planeGeometry((event->GetSender()->GetCurrentWorldPlaneGeometry()));
   const auto *abstractTransformGeometry(
     dynamic_cast<const AbstractTransformGeometry *>(event->GetSender()->GetCurrentWorldPlaneGeometry()));
   DataNode *workingNode(m_ToolManager->GetWorkingData(0));
 
   if (!workingNode)
     return;
 
   Image::Pointer image = dynamic_cast<Image *>(workingNode->GetData());
 
   if (!image || !planeGeometry || abstractTransformGeometry)
     return;
 
   if (m_CurrentPlane.IsNull() || m_WorkingSlice.IsNull())
   {
     m_CurrentPlane = planeGeometry;
     m_WorkingSlice = SegTool2D::GetAffectedImageSliceAs2DImage(event, image)->Clone();
     m_WorkingNode->ReplaceProperty("color", workingNode->GetProperty("color"));
     m_WorkingNode->SetData(m_WorkingSlice);
   }
   else
   {
     bool isSameSlice(false);
     isSameSlice = mitk::MatrixEqualElementWise(planeGeometry->GetIndexToWorldTransform()->GetMatrix(),
                                                m_CurrentPlane->GetIndexToWorldTransform()->GetMatrix());
     isSameSlice = mitk::Equal(planeGeometry->GetIndexToWorldTransform()->GetOffset(),
                               m_CurrentPlane->GetIndexToWorldTransform()->GetOffset());
     if (!isSameSlice)
     {
       m_ToolManager->GetDataStorage()->Remove(m_WorkingNode);
       m_CurrentPlane = nullptr;
       m_WorkingSlice = nullptr;
       m_WorkingNode = nullptr;
       m_CurrentPlane = planeGeometry;
       m_WorkingSlice = SegTool2D::GetAffectedImageSliceAs2DImage(event, image)->Clone();
 
       m_WorkingNode = mitk::DataNode::New();
       m_WorkingNode->SetProperty("levelwindow", mitk::LevelWindowProperty::New(mitk::LevelWindow(0, 1)));
       m_WorkingNode->SetProperty("binary", mitk::BoolProperty::New(true));
 
       m_WorkingNode->SetData(m_WorkingSlice);
 
       // So that the paintbrush contour vanished in the previous render window
       RenderingManager::GetInstance()->RequestUpdateAll();
     }
   }
 
   if (!m_ToolManager->GetDataStorage()->Exists(m_WorkingNode))
   {
     m_WorkingNode->SetProperty("outline binary", mitk::BoolProperty::New(true));
     m_WorkingNode->SetProperty("color", workingNode->GetProperty("color"));
     m_WorkingNode->SetProperty("name", mitk::StringProperty::New("Paintbrush_Node"));
     m_WorkingNode->SetProperty("helper object", mitk::BoolProperty::New(true));
     m_WorkingNode->SetProperty("opacity", mitk::FloatProperty::New(0.8));
     m_WorkingNode->SetProperty("includeInBoundingBox", mitk::BoolProperty::New(false));
     m_WorkingNode->SetVisibility(
       false, mitk::BaseRenderer::GetInstance(mitk::BaseRenderer::GetRenderWindowByName("stdmulti.widget3")));
 
     m_ToolManager->GetDataStorage()->Add(m_WorkingNode);
   }
 }
 
 void mitk::PaintbrushTool::OnToolManagerWorkingDataModified()
 {
   // Here we simply set the current working slice to null. The next time the mouse is moved
   // within a renderwindow a new slice will be extracted from the new working data
   m_WorkingSlice = nullptr;
 }
diff --git a/Modules/Segmentation/Interactions/mitkRegionGrowingTool.cpp b/Modules/Segmentation/Interactions/mitkRegionGrowingTool.cpp
index 5bcc0fa99a..7a46716569 100644
--- a/Modules/Segmentation/Interactions/mitkRegionGrowingTool.cpp
+++ b/Modules/Segmentation/Interactions/mitkRegionGrowingTool.cpp
@@ -1,664 +1,650 @@
 /*============================================================================
 
 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 "mitkRegionGrowingTool.h"
 #include "mitkApplicationCursor.h"
 #include "mitkBaseRenderer.h"
 #include "mitkImageDataItem.h"
 #include "mitkImageToContourModelFilter.h"
 #include "mitkOverwriteSliceImageFilter.h"
 #include "mitkRegionGrowingTool.xpm"
 #include "mitkRenderingManager.h"
 #include "mitkToolManager.h"
 
 #include "mitkExtractDirectedPlaneImageFilterNew.h"
 #include "mitkLabelSetImage.h"
 #include "mitkOverwriteDirectedPlaneImageFilter.h"
 
 // us
 #include <usGetModuleContext.h>
 #include <usModule.h>
 #include <usModuleContext.h>
 #include <usModuleResource.h>
 
 // ITK
 #include "mitkITKImageImport.h"
 #include "mitkImageAccessByItk.h"
 #include <itkConnectedComponentImageFilter.h>
 #include <itkConnectedThresholdImageFilter.h>
 #include <itkImageRegionIteratorWithIndex.h>
 #include <itkNeighborhoodIterator.h>
 
 #include <itkImageDuplicator.h>
 
 #include <limits>
 
 namespace mitk
 {
   MITK_TOOL_MACRO(MITKSEGMENTATION_EXPORT, RegionGrowingTool, "Region growing tool");
 }
 
 #define ROUND(a) ((a) > 0 ? (int)((a) + 0.5) : -(int)(0.5 - (a)))
 
 mitk::RegionGrowingTool::RegionGrowingTool()
   : FeedbackContourTool("PressMoveRelease"),
     m_SeedValue(0),
     m_ScreenYDifference(0),
     m_ScreenXDifference(0),
     m_MouseDistanceScaleFactor(0.5),
     m_PaintingPixelValue(0),
     m_FillFeedbackContour(true),
     m_ConnectedComponentValue(1)
 {
 }
 
 mitk::RegionGrowingTool::~RegionGrowingTool()
 {
 }
 
 void mitk::RegionGrowingTool::ConnectActionsAndFunctions()
 {
   CONNECT_FUNCTION("PrimaryButtonPressed", OnMousePressed);
   CONNECT_FUNCTION("Move", OnMouseMoved);
   CONNECT_FUNCTION("Release", OnMouseReleased);
 }
 
 const char **mitk::RegionGrowingTool::GetXPM() const
 {
   return mitkRegionGrowingTool_xpm;
 }
 
 us::ModuleResource mitk::RegionGrowingTool::GetIconResource() const
 {
   us::Module *module = us::GetModuleContext()->GetModule();
   us::ModuleResource resource = module->GetResource("RegionGrowing_48x48.png");
   return resource;
 }
 
 us::ModuleResource mitk::RegionGrowingTool::GetCursorIconResource() const
 {
   us::Module *module = us::GetModuleContext()->GetModule();
   us::ModuleResource resource = module->GetResource("RegionGrowing_Cursor_32x32.png");
   return resource;
 }
 
 const char *mitk::RegionGrowingTool::GetName() const
 {
   return "Region Growing";
 }
 
 void mitk::RegionGrowingTool::Activated()
 {
   Superclass::Activated();
 }
 
 void mitk::RegionGrowingTool::Deactivated()
 {
   Superclass::Deactivated();
 }
 
 // Get the average pixel value of square/cube with radius=neighborhood around index
 template <typename TPixel, unsigned int imageDimension>
 void mitk::RegionGrowingTool::GetNeighborhoodAverage(const itk::Image<TPixel, imageDimension> *itkImage,
                                                      const itk::Index<imageDimension>& index,
                                                      ScalarType *result,
                                                      unsigned int neighborhood)
 {
   // maybe assert that image dimension is only 2 or 3?
   auto neighborhoodInt = (int)neighborhood;
   TPixel averageValue(0);
   unsigned int numberOfPixels = (2 * neighborhood + 1) * (2 * neighborhood + 1);
   if (imageDimension == 3)
   {
     numberOfPixels *= (2 * neighborhood + 1);
   }
 
   MITK_DEBUG << "Getting neighborhood of " << numberOfPixels << " pixels around " << index;
 
   itk::Index<imageDimension> currentIndex;
 
   for (int i = (0 - neighborhoodInt); i <= neighborhoodInt; ++i)
   {
     currentIndex[0] = index[0] + i;
 
     for (int j = (0 - neighborhoodInt); j <= neighborhoodInt; ++j)
     {
       currentIndex[1] = index[1] + j;
 
       if (imageDimension == 3)
       {
         for (int k = (0 - neighborhoodInt); k <= neighborhoodInt; ++k)
         {
           currentIndex[2] = index[2] + k;
 
           if (itkImage->GetLargestPossibleRegion().IsInside(currentIndex))
           {
             averageValue += itkImage->GetPixel(currentIndex);
           }
           else
           {
             numberOfPixels -= 1;
           }
         }
       }
       else
       {
         if (itkImage->GetLargestPossibleRegion().IsInside(currentIndex))
         {
           averageValue += itkImage->GetPixel(currentIndex);
         }
         else
         {
           numberOfPixels -= 1;
         }
       }
     }
   }
 
   *result = (ScalarType)averageValue;
   *result /= numberOfPixels;
 }
 
 // Check whether index lies inside a segmentation
 template <typename TPixel, unsigned int imageDimension>
 void mitk::RegionGrowingTool::IsInsideSegmentation(const itk::Image<TPixel, imageDimension> *itkImage,
                                                    const itk::Index<imageDimension>& index,
                                                    bool *result)
 {
   if (itkImage->GetPixel(index) > 0)
   {
     *result = true;
   }
   else
   {
     *result = false;
   }
 }
 
 // Do the region growing (i.e. call an ITK filter that does it)
 template <typename TPixel, unsigned int imageDimension>
 void mitk::RegionGrowingTool::StartRegionGrowing(const itk::Image<TPixel, imageDimension> *inputImage,
                                                  const itk::Index<imageDimension>& seedIndex,
                                                  const std::array<ScalarType, 2>& thresholds,
                                                  mitk::Image::Pointer &outputImage)
 {
   MITK_DEBUG << "Starting region growing at index " << seedIndex << " with lower threshold " << thresholds[0]
              << " and upper threshold " << thresholds[1];
 
   typedef itk::Image<TPixel, imageDimension> InputImageType;
   typedef itk::Image<DefaultSegmentationDataType, imageDimension> OutputImageType;
 
   typedef itk::ConnectedThresholdImageFilter<InputImageType, OutputImageType> RegionGrowingFilterType;
   typename RegionGrowingFilterType::Pointer regionGrower = RegionGrowingFilterType::New();
 
   // perform region growing in desired segmented region
   regionGrower->SetInput(inputImage);
   regionGrower->SetSeed(seedIndex);
 
   regionGrower->SetLower(thresholds[0]);
   regionGrower->SetUpper(thresholds[1]);
 
   try
   {
     regionGrower->Update();
   }
   catch (...)
   {
     return; // Should we do something?
   }
 
   typename OutputImageType::Pointer resultImage = regionGrower->GetOutput();
 
   // Smooth result: Every pixel is replaced by the majority of the neighborhood
   typedef itk::NeighborhoodIterator<OutputImageType> NeighborhoodIteratorType;
   typedef itk::ImageRegionIterator<OutputImageType> ImageIteratorType;
 
   typename NeighborhoodIteratorType::RadiusType radius;
   radius.Fill(2); // for now, maybe make this something the user can adjust in the preferences?
 
   typedef itk::ImageDuplicator< OutputImageType > DuplicatorType;
   typename DuplicatorType::Pointer duplicator = DuplicatorType::New();
   duplicator->SetInputImage(resultImage);
   duplicator->Update();
 
   typename OutputImageType::Pointer resultDup = duplicator->GetOutput();
 
   NeighborhoodIteratorType neighborhoodIterator(radius, resultDup, resultDup->GetRequestedRegion());
   ImageIteratorType imageIterator(resultImage, resultImage->GetRequestedRegion());
 
   for (neighborhoodIterator.GoToBegin(), imageIterator.GoToBegin(); !neighborhoodIterator.IsAtEnd();
        ++neighborhoodIterator, ++imageIterator)
   {
     DefaultSegmentationDataType voteYes(0);
     DefaultSegmentationDataType voteNo(0);
 
     for (unsigned int i = 0; i < neighborhoodIterator.Size(); ++i)
     {
       if (neighborhoodIterator.GetPixel(i) > 0)
       {
         voteYes += 1;
       }
       else
       {
         voteNo += 1;
       }
     }
 
     if (voteYes > voteNo)
     {
       imageIterator.Set(1);
     }
     else
     {
       imageIterator.Set(0);
     }
   }
 
   if (resultImage.IsNull())
   {
     MITK_DEBUG << "Region growing result is empty.";
   }
 
   // Can potentially have multiple regions, use connected component image filter to label disjunct regions
   typedef itk::ConnectedComponentImageFilter<OutputImageType, OutputImageType> ConnectedComponentImageFilterType;
   typename ConnectedComponentImageFilterType::Pointer connectedComponentFilter =
     ConnectedComponentImageFilterType::New();
   connectedComponentFilter->SetInput(resultImage);
   connectedComponentFilter->Update();
   typename OutputImageType::Pointer resultImageCC = connectedComponentFilter->GetOutput();
   m_ConnectedComponentValue = resultImageCC->GetPixel(seedIndex);
 
   outputImage = mitk::GrabItkImageMemory(resultImageCC);
 }
 
 template <typename TPixel, unsigned int imageDimension>
 void mitk::RegionGrowingTool::CalculateInitialThresholds(const itk::Image<TPixel, imageDimension>*)
 {
   LevelWindow levelWindow;
   m_ToolManager->GetReferenceData(0)->GetLevelWindow(levelWindow);
 
   m_ThresholdExtrema[0] = static_cast<ScalarType>(std::numeric_limits<TPixel>::lowest());
   m_ThresholdExtrema[1] = static_cast<ScalarType>(std::numeric_limits<TPixel>::max());
 
   const ScalarType lowerWindowBound = std::max(m_ThresholdExtrema[0], levelWindow.GetLowerWindowBound());
   const ScalarType upperWindowBound = std::min(m_ThresholdExtrema[1], levelWindow.GetUpperWindowBound());
 
   if (m_SeedValue < lowerWindowBound)
   {
     m_InitialThresholds = { m_ThresholdExtrema[0], lowerWindowBound };
   }
   else if (m_SeedValue > upperWindowBound)
   {
     m_InitialThresholds = { upperWindowBound, m_ThresholdExtrema[1] };
   }
   else
   {
     const ScalarType range = 0.1 * (upperWindowBound - lowerWindowBound); // 10% of the visible window
 
     m_InitialThresholds[0] = std::min(std::max(lowerWindowBound, m_SeedValue - 0.5 * range), upperWindowBound - range);
     m_InitialThresholds[1] = m_InitialThresholds[0] + range;
   }
 }
 
 void mitk::RegionGrowingTool::OnMousePressed(StateMachineAction *, InteractionEvent *interactionEvent)
 {
   auto *positionEvent = dynamic_cast<mitk::InteractionPositionEvent *>(interactionEvent);
   if (!positionEvent)
     return;
 
-  MITK_DEBUG << "OnMousePressed";
-
   m_LastEventSender = positionEvent->GetSender();
   m_LastEventSlice = m_LastEventSender->GetSlice();
   m_LastScreenPosition = positionEvent->GetPointerPositionOnScreen();
 
   // ReferenceSlice is from the underlying image, WorkingSlice from the active segmentation (can be empty)
   m_ReferenceSlice = FeedbackContourTool::GetAffectedReferenceSlice(positionEvent);
   m_WorkingSlice = FeedbackContourTool::GetAffectedWorkingSlice(positionEvent);
 
   if (m_WorkingSlice.IsNotNull()) // can't do anything without a working slice (i.e. a possibly empty segmentation)
   {
-    MITK_DEBUG << "OnMousePressed: got working slice";
-
     // 2. Determine if the user clicked inside or outside of the segmentation/working slice (i.e. the whole volume)
     mitk::BaseGeometry::Pointer workingSliceGeometry;
     workingSliceGeometry = m_WorkingSlice->GetGeometry();
     workingSliceGeometry->WorldToIndex(positionEvent->GetPositionInWorld(), m_SeedPoint);
     itk::Index<2> indexInWorkingSlice2D;
     indexInWorkingSlice2D[0] = m_SeedPoint[0];
     indexInWorkingSlice2D[1] = m_SeedPoint[1];
 
     if (workingSliceGeometry->IsIndexInside(m_SeedPoint))
     {
       MITK_DEBUG << "OnMousePressed: point " << positionEvent->GetPositionInWorld() << " (index coordinates "
                  << m_SeedPoint << ") is inside working slice";
 
       // 3. determine the pixel value under the last click to determine what to do
       bool inside(true);
       AccessFixedDimensionByItk_2(m_WorkingSlice, IsInsideSegmentation, 2, indexInWorkingSlice2D, &inside);
       m_PaintingPixelValue = inside ? 0 : 1;
 
       if (inside)
       {
         MITK_DEBUG << "Clicked inside segmentation";
         // For now, we're doing nothing when the user clicks inside the segmentation. Behaviour can be implemented via
         // OnMousePressedInside()
         // When you do, be sure to remove the m_PaintingPixelValue check in OnMouseMoved() and OnMouseReleased()
         return;
       }
       else
       {
         MITK_DEBUG << "Clicked outside of segmentation";
         OnMousePressedOutside(nullptr, interactionEvent);
       }
     }
   }
 }
 
 // Use this to implement a behaviour for when the user clicks inside a segmentation (for example remove something)
 // Old IpPic code is kept as comment for reference
 void mitk::RegionGrowingTool::OnMousePressedInside()
 {
   //    mitk::InteractionPositionEvent* positionEvent = dynamic_cast<mitk::InteractionPositionEvent*>( interactionEvent
   //    );
   //    //const PositionEvent* positionEvent = dynamic_cast<const PositionEvent*>(stateEvent->GetEvent()); // checked in
   //    OnMousePressed
   //    // 3.1.1. Create a skeletonization of the segmentation and try to find a nice cut
   //    // apply the skeletonization-and-cut algorithm
   //    // generate contour to remove
   //    // set m_ReferenceSlice = nullptr so nothing will happen during mouse move
   //    // remember to fill the contour with 0 in mouserelease
   //    mitkIpPicDescriptor* segmentationHistory = ipMITKSegmentationCreateGrowerHistory( workingPicSlice,
   //    m_LastWorkingSeed, nullptr ); // free again
   //    if (segmentationHistory)
   //    {
   //        tCutResult cutContour = ipMITKSegmentationGetCutPoints( workingPicSlice, segmentationHistory,
   //        initialWorkingOffset ); // tCutResult is a ipSegmentation type
   //        mitkIpPicFree( segmentationHistory );
   //        if (cutContour.cutIt)
   //        {
   //            int timestep = positionEvent->GetSender()->GetTimeStep();
   //            // 3.1.2 copy point from float* to mitk::Contour
   //            ContourModel::Pointer contourInImageIndexCoordinates = ContourModel::New();
   //            contourInImageIndexCoordinates->Expand(timestep + 1);
   //            contourInImageIndexCoordinates->SetClosed(true, timestep);
   //            Point3D newPoint;
   //            for (int index = 0; index < cutContour.deleteSize; ++index)
   //            {
   //                newPoint[0] = cutContour.deleteCurve[ 2 * index + 0 ] - 0.5;//correction is needed because the
   //                output of the algorithm is center based
   //                newPoint[1] = cutContour.deleteCurve[ 2 * index + 1 ] - 0.5;//and we want our contour displayed
   //                corner based.
   //                newPoint[2] = 0.0;
 
   //                contourInImageIndexCoordinates->AddVertex( newPoint, timestep );
   //            }
 
   //            free(cutContour.traceline);
   //            free(cutContour.deleteCurve); // perhaps visualize this for fun?
   //            free(cutContour.onGradient);
 
   //            ContourModel::Pointer contourInWorldCoordinates = FeedbackContourTool::BackProjectContourFrom2DSlice(
   //            m_WorkingSlice->GetGeometry(), contourInImageIndexCoordinates, true ); // true: sub 0.5 for
   //            ipSegmentation correction
 
   //            FeedbackContourTool::SetFeedbackContour( contourInWorldCoordinates );
   //            FeedbackContourTool::SetFeedbackContourVisible(true);
   //            mitk::RenderingManager::GetInstance()->RequestUpdate( positionEvent->GetSender()->GetRenderWindow() );
   //            m_FillFeedbackContour = true;
   //        }
   //        else
   //        {
   //            m_FillFeedbackContour = false;
   //        }
 
   //    }
   //    else
   //    {
   //        m_FillFeedbackContour = false;
   //    }
 
   //    m_ReferenceSlice = nullptr;
 
   //    return true;
 }
 
 void mitk::RegionGrowingTool::OnMousePressedOutside(StateMachineAction *, InteractionEvent *interactionEvent)
 {
   auto *positionEvent = dynamic_cast<mitk::InteractionPositionEvent *>(interactionEvent);
 
   if (positionEvent)
   {
     // Get geometry and indices
     mitk::BaseGeometry::Pointer workingSliceGeometry;
     workingSliceGeometry = m_WorkingSlice->GetGeometry();
     itk::Index<2> indexInWorkingSlice2D;
     indexInWorkingSlice2D[0] = m_SeedPoint[0];
     indexInWorkingSlice2D[1] = m_SeedPoint[1];
 
     mitk::BaseGeometry::Pointer referenceSliceGeometry;
     referenceSliceGeometry =
       m_ReferenceSlice->GetGeometry();
     itk::Index<3> indexInReferenceSlice;
     itk::Index<2> indexInReferenceSlice2D;
     referenceSliceGeometry->WorldToIndex(positionEvent->GetPositionInWorld(), indexInReferenceSlice);
     indexInReferenceSlice2D[0] = indexInReferenceSlice[0];
     indexInReferenceSlice2D[1] = indexInReferenceSlice[1];
 
     // Get seed neighborhood
     ScalarType averageValue(0);
     AccessFixedDimensionByItk_3(m_ReferenceSlice, GetNeighborhoodAverage, 2, indexInReferenceSlice2D, &averageValue, 1);
     m_SeedValue = averageValue;
     MITK_DEBUG << "Seed value is " << m_SeedValue;
 
     // Calculate initial thresholds
     AccessFixedDimensionByItk(m_ReferenceSlice, CalculateInitialThresholds, 2);
     m_Thresholds[0] = m_InitialThresholds[0];
     m_Thresholds[1] = m_InitialThresholds[1];
 
     // Perform region growing
     mitk::Image::Pointer resultImage = mitk::Image::New();
     AccessFixedDimensionByItk_3(
       m_ReferenceSlice, StartRegionGrowing, 2, indexInWorkingSlice2D, m_Thresholds, resultImage);
     resultImage->SetGeometry(workingSliceGeometry);
 
     // Extract contour
     if (resultImage.IsNotNull() && m_ConnectedComponentValue >= 1)
     {
       float isoOffset = 0.33;
 
       mitk::ImageToContourModelFilter::Pointer contourExtractor = mitk::ImageToContourModelFilter::New();
       contourExtractor->SetInput(resultImage);
       contourExtractor->SetContourValue(m_ConnectedComponentValue - isoOffset);
       contourExtractor->Update();
       ContourModel::Pointer resultContour = ContourModel::New();
       resultContour = contourExtractor->GetOutput();
 
       // Show contour
       if (resultContour.IsNotNull())
       {
         ContourModel::Pointer resultContourWorld = FeedbackContourTool::BackProjectContourFrom2DSlice(
           workingSliceGeometry, FeedbackContourTool::ProjectContourTo2DSlice(m_WorkingSlice, resultContour));
 
         // this is not a beautiful solution, just one that works, check T22412 for details
         auto t = positionEvent->GetSender()->GetTimeStep();
 
         FeedbackContourTool::SetFeedbackContour(0 != t
           ? ContourModelUtils::MoveZerothContourTimeStep(resultContourWorld, t)
           : resultContourWorld);
 
         FeedbackContourTool::SetFeedbackContourVisible(true);
         mitk::RenderingManager::GetInstance()->RequestUpdate(m_LastEventSender->GetRenderWindow());
       }
     }
   }
 }
 
 void mitk::RegionGrowingTool::OnMouseMoved(StateMachineAction *, InteractionEvent *interactionEvent)
 {
   // Until OnMousePressedInside() implements a behaviour, we're just returning here whenever m_PaintingPixelValue is 0,
   // i.e. when the user clicked inside the segmentation
   if (m_PaintingPixelValue == 0)
   {
     return;
   }
 
   auto *positionEvent = dynamic_cast<mitk::InteractionPositionEvent *>(interactionEvent);
 
   if (m_ReferenceSlice.IsNotNull() && positionEvent)
   {
     // Get geometry and indices
     mitk::BaseGeometry::Pointer workingSliceGeometry;
     workingSliceGeometry = m_WorkingSlice->GetGeometry();
     itk::Index<2> indexInWorkingSlice2D;
     indexInWorkingSlice2D[0] = m_SeedPoint[0];
     indexInWorkingSlice2D[1] = m_SeedPoint[1];
 
     m_ScreenYDifference += positionEvent->GetPointerPositionOnScreen()[1] - m_LastScreenPosition[1];
     m_ScreenXDifference += positionEvent->GetPointerPositionOnScreen()[0] - m_LastScreenPosition[0];
     m_LastScreenPosition = positionEvent->GetPointerPositionOnScreen();
 
     // Moving the mouse up and down adjusts the width of the threshold window,
     // moving it left and right shifts the threshold window
     m_Thresholds[0] = std::min(m_SeedValue, m_InitialThresholds[0] - (m_ScreenYDifference - m_ScreenXDifference) * m_MouseDistanceScaleFactor);
     m_Thresholds[1] = std::max(m_SeedValue, m_InitialThresholds[1] + (m_ScreenYDifference + m_ScreenXDifference) * m_MouseDistanceScaleFactor);
 
     // Do not exceed the pixel type extrema of the reference slice, though
     m_Thresholds[0] = std::max(m_ThresholdExtrema[0], m_Thresholds[0]);
     m_Thresholds[1] = std::min(m_ThresholdExtrema[1], m_Thresholds[1]);
 
     // Perform region growing again and show the result
     mitk::Image::Pointer resultImage = mitk::Image::New();
     AccessFixedDimensionByItk_3(
       m_ReferenceSlice, StartRegionGrowing, 2, indexInWorkingSlice2D, m_Thresholds, resultImage);
     resultImage->SetGeometry(workingSliceGeometry);
 
     // Update the contour
     if (resultImage.IsNotNull() && m_ConnectedComponentValue >= 1)
     {
       float isoOffset = 0.33;
 
       mitk::ImageToContourModelFilter::Pointer contourExtractor = mitk::ImageToContourModelFilter::New();
       contourExtractor->SetInput(resultImage);
       contourExtractor->SetContourValue(m_ConnectedComponentValue - isoOffset);
       contourExtractor->Update();
       ContourModel::Pointer resultContour = ContourModel::New();
       resultContour = contourExtractor->GetOutput();
 
       // Show contour
       if (resultContour.IsNotNull())
       {
         ContourModel::Pointer resultContourWorld = FeedbackContourTool::BackProjectContourFrom2DSlice(
           workingSliceGeometry, FeedbackContourTool::ProjectContourTo2DSlice(m_WorkingSlice, resultContour));
 
         // this is not a beautiful solution, just one that works, check T22412 for details
         int timestep = positionEvent->GetSender()->GetTimeStep();
         if (0 != timestep)
         {
           int size = resultContourWorld->GetNumberOfVertices(0);
           auto resultContourTimeWorld = mitk::ContourModel::New();
           resultContourTimeWorld->Expand(timestep + 1);
           for (int loop = 0; loop < size; ++loop)
           {
             resultContourTimeWorld->AddVertex(resultContourWorld->GetVertexAt(loop, 0), timestep);
           }
           FeedbackContourTool::SetFeedbackContour(resultContourTimeWorld);
         }
         else
         {
           FeedbackContourTool::SetFeedbackContour(resultContourWorld);
         }
 
         FeedbackContourTool::SetFeedbackContourVisible(true);
         mitk::RenderingManager::GetInstance()->ForceImmediateUpdate(positionEvent->GetSender()->GetRenderWindow());
       }
     }
   }
 }
 
 void mitk::RegionGrowingTool::OnMouseReleased(StateMachineAction *, InteractionEvent *interactionEvent)
 {
   // Until OnMousePressedInside() implements a behaviour, we're just returning here whenever m_PaintingPixelValue is 0,
   // i.e. when the user clicked inside the segmentation
   if (m_PaintingPixelValue == 0)
   {
     return;
   }
 
   auto *positionEvent = dynamic_cast<mitk::InteractionPositionEvent *>(interactionEvent);
 
   if (m_WorkingSlice.IsNotNull() && m_FillFeedbackContour && positionEvent)
   {
     // Project contour into working slice
     ContourModel *feedbackContour(FeedbackContourTool::GetFeedbackContour());
 
     ContourModel::Pointer projectedContour;
 
     // this is not a beautiful solution, just one that works, check T22412 for details
     int timestep = positionEvent->GetSender()->GetTimeStep();
     if (0 != timestep)
     {
       int size = feedbackContour->GetNumberOfVertices(timestep);
       auto feedbackContourTime = mitk::ContourModel::New();
       feedbackContourTime->Expand(timestep + 1);
       for (int loop = 0; loop < size; ++loop)
       {
         feedbackContourTime->AddVertex(feedbackContour->GetVertexAt(loop, timestep), 0);
       }
 
       projectedContour =
         FeedbackContourTool::ProjectContourTo2DSlice(m_WorkingSlice, feedbackContourTime, false, false);
     }
     else
     {
       projectedContour =
         FeedbackContourTool::ProjectContourTo2DSlice(m_WorkingSlice, feedbackContour, false, false);
     }
 
     // If there is a projected contour, fill it
     if (projectedContour.IsNotNull())
     {
-      // Get working data to pass to following method so we don't overwrite locked labels in a LabelSetImage
       mitk::DataNode *workingNode(m_ToolManager->GetWorkingData(0));
-      mitk::LabelSetImage *labelSetImage = workingNode != nullptr
-        ? dynamic_cast<mitk::LabelSetImage*>(workingNode->GetData())
-        : nullptr;
-
-      MITK_DEBUG << "Filling Segmentation";
-
-      if (nullptr != labelSetImage)
+      if (nullptr == workingNode)
       {
-        // m_PaintingPixelValue only decides whether to paint or not
-        // For LabelSetImages we want to paint with the active label value
-        auto activePixelValue = labelSetImage->GetActiveLabel(labelSetImage->GetActiveLayer())->GetValue();
-        mitk::ContourModelUtils::FillContourInSlice(projectedContour,
-                                                    0,
-                                                    m_WorkingSlice,
-                                                    labelSetImage,
-                                                    m_PaintingPixelValue * activePixelValue);
+        return;
       }
-      else
+
+      auto workingImage = dynamic_cast<Image*>(workingNode->GetData());
+      if (nullptr == workingImage)
       {
-        mitk::ContourModelUtils::FillContourInSlice(projectedContour,
-                                                    0,
-                                                    m_WorkingSlice,
-                                                    m_WorkingSlice,
-                                                    m_PaintingPixelValue);
+        return;
       }
+
+      // m_PaintingPixelValue only decides whether to paint or erase
+      int activePixelValue = ContourModelUtils::GetActivePixelValue(workingImage);
+      mitk::ContourModelUtils::FillContourInSlice(
+        projectedContour, 0, m_WorkingSlice, workingImage, m_PaintingPixelValue * activePixelValue);
+
       this->WriteBackSegmentationResult(positionEvent, m_WorkingSlice);
       FeedbackContourTool::SetFeedbackContourVisible(false);
     }
 
     m_ScreenYDifference = 0;
     m_ScreenXDifference = 0;
   }
 }
diff --git a/Modules/Segmentation/Interactions/mitkSetRegionTool.cpp b/Modules/Segmentation/Interactions/mitkSetRegionTool.cpp
index 79fd3f5bc4..bf0bbfe459 100644
--- a/Modules/Segmentation/Interactions/mitkSetRegionTool.cpp
+++ b/Modules/Segmentation/Interactions/mitkSetRegionTool.cpp
@@ -1,181 +1,176 @@
 /*============================================================================
 
 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 "mitkSetRegionTool.h"
 
 #include "mitkToolManager.h"
 
 #include "mitkBaseRenderer.h"
 #include "mitkImageDataItem.h"
 #include "mitkLabelSetImage.h"
 
 #include <mitkITKImageImport.h>
 #include <mitkImagePixelReadAccessor.h>
 #include <mitkImageToContourModelFilter.h>
 
 #include <itkBinaryFillholeImageFilter.h>
 #include <itkConnectedThresholdImageFilter.h>
 
 mitk::SetRegionTool::SetRegionTool(int paintingPixelValue)
   : FeedbackContourTool("PressMoveRelease"), m_PaintingPixelValue(paintingPixelValue)
 {
 }
 
 mitk::SetRegionTool::~SetRegionTool()
 {
 }
 
 void mitk::SetRegionTool::ConnectActionsAndFunctions()
 {
   CONNECT_FUNCTION("PrimaryButtonPressed", OnMousePressed);
   CONNECT_FUNCTION("Release", OnMouseReleased);
   CONNECT_FUNCTION("Move", OnMouseMoved);
 }
 
 void mitk::SetRegionTool::Activated()
 {
   Superclass::Activated();
 }
 
 void mitk::SetRegionTool::Deactivated()
 {
   Superclass::Deactivated();
 }
 
 void mitk::SetRegionTool::OnMousePressed(StateMachineAction *, InteractionEvent *interactionEvent)
 {
   auto *positionEvent = dynamic_cast<mitk::InteractionPositionEvent *>(interactionEvent);
   if (!positionEvent)
     return;
 
   m_LastEventSender = positionEvent->GetSender();
   m_LastEventSlice = m_LastEventSender->GetSlice();
 
   // 1. Get the working image
   Image::Pointer workingSlice = FeedbackContourTool::GetAffectedWorkingSlice(positionEvent);
   if (workingSlice.IsNull())
     return; // can't do anything without the segmentation
 
   // if click was outside the image, don't continue
   const BaseGeometry *sliceGeometry = workingSlice->GetGeometry();
   itk::Index<3> projectedPointIn2D;
   sliceGeometry->WorldToIndex(positionEvent->GetPositionInWorld(), projectedPointIn2D);
   if (!sliceGeometry->IsIndexInside(projectedPointIn2D))
   {
     MITK_WARN << "Point outside of segmentation slice." << std::endl;
     return; // can't use that as a seed point
   }
 
   typedef itk::Image<DefaultSegmentationDataType, 2> InputImageType;
   typedef InputImageType::IndexType IndexType;
   typedef itk::ConnectedThresholdImageFilter<InputImageType, InputImageType> RegionGrowingFilterType;
   RegionGrowingFilterType::Pointer regionGrower = RegionGrowingFilterType::New();
 
   // convert world coordinates to image indices
   IndexType seedIndex;
   sliceGeometry->WorldToIndex(positionEvent->GetPositionInWorld(), seedIndex);
 
   // perform region growing in desired segmented region
   InputImageType::Pointer itkImage = InputImageType::New();
   CastToItkImage(workingSlice, itkImage);
   regionGrower->SetInput(itkImage);
   regionGrower->AddSeed(seedIndex);
 
   InputImageType::PixelType bound = itkImage->GetPixel(seedIndex);
 
   regionGrower->SetLower(bound);
   regionGrower->SetUpper(bound);
   regionGrower->SetReplaceValue(1);
 
   itk::BinaryFillholeImageFilter<InputImageType>::Pointer fillHolesFilter =
     itk::BinaryFillholeImageFilter<InputImageType>::New();
 
   fillHolesFilter->SetInput(regionGrower->GetOutput());
   fillHolesFilter->SetForegroundValue(1);
 
   // Store result and preview
   mitk::Image::Pointer resultImage = mitk::GrabItkImageMemory(fillHolesFilter->GetOutput());
   resultImage->SetGeometry(workingSlice->GetGeometry());
   // Get the current working color
   DataNode *workingNode(m_ToolManager->GetWorkingData(0));
   if (!workingNode)
     return;
 
   mitk::ImageToContourModelFilter::Pointer contourextractor = mitk::ImageToContourModelFilter::New();
   contourextractor->SetInput(resultImage);
   contourextractor->Update();
 
   mitk::ContourModel::Pointer awesomeContour = contourextractor->GetOutput();
   auto t = positionEvent->GetSender()->GetTimeStep();
 
   FeedbackContourTool::SetFeedbackContour(0 != t
     ? ContourModelUtils::MoveZerothContourTimeStep(awesomeContour, t)
     : awesomeContour);
 
   FeedbackContourTool::SetFeedbackContourVisible(true);
   mitk::RenderingManager::GetInstance()->RequestUpdate(positionEvent->GetSender()->GetRenderWindow());
 }
 
 void mitk::SetRegionTool::OnMouseReleased(StateMachineAction *, InteractionEvent *interactionEvent)
 {
   auto *positionEvent = dynamic_cast<mitk::InteractionPositionEvent *>(interactionEvent);
   if (!positionEvent)
     return;
 
   assert(positionEvent->GetSender()->GetRenderWindow());
   // 1. Hide the feedback contour, find out which slice the user clicked, find out which slice of the toolmanager's
   // working image corresponds to that
   FeedbackContourTool::SetFeedbackContourVisible(false);
   mitk::RenderingManager::GetInstance()->RequestUpdate(positionEvent->GetSender()->GetRenderWindow());
 
   int timeStep = positionEvent->GetSender()->GetTimeStep();
 
   DataNode *workingNode(m_ToolManager->GetWorkingData(0));
   if (!workingNode)
     return;
 
   auto *image = dynamic_cast<Image *>(workingNode->GetData());
   const PlaneGeometry *planeGeometry((positionEvent->GetSender()->GetCurrentWorldPlaneGeometry()));
   if (!image || !planeGeometry)
     return;
 
   Image::Pointer slice = FeedbackContourTool::GetAffectedImageSliceAs2DImage(positionEvent, image);
 
   if (slice.IsNull())
   {
     MITK_ERROR << "Unable to extract slice." << std::endl;
     return;
   }
 
   ContourModel *feedbackContour(FeedbackContourTool::GetFeedbackContour());
   ContourModel::Pointer projectedContour = FeedbackContourTool::ProjectContourTo2DSlice(
     slice, feedbackContour, false, false); // false: don't add 0.5 (done by FillContourInSlice)
   // false: don't constrain the contour to the image's inside
   if (projectedContour.IsNull())
     return;
 
-  auto *labelSetImage = dynamic_cast<LabelSetImage *>(image);
-  int activePixelValue = 1;
-  if (nullptr != labelSetImage)
-  {
-    activePixelValue = labelSetImage->GetActiveLabel()->GetValue();
-  }
+  int activePixelValue = ContourModelUtils::GetActivePixelValue(image);
 
   mitk::ContourModelUtils::FillContourInSlice(
     projectedContour, timeStep, slice, image, m_PaintingPixelValue * activePixelValue);
 
   this->WriteBackSegmentationResult(positionEvent, slice);
 }
 
 void mitk::SetRegionTool::OnMouseMoved(mitk::StateMachineAction *, mitk::InteractionEvent *)
 {
 }