void Geometry2DDataVtkMapper3D::GenerateDataForRenderer(BaseRenderer* renderer)
  {
    SetVtkMapperImmediateModeRendering(m_EdgeMapper);
    SetVtkMapperImmediateModeRendering(m_BackgroundMapper);

    // Remove all actors from the assembly, and re-initialize it with the
    // edge actor
    m_ImageAssembly->GetParts()->RemoveAllItems();

    if ( !this->IsVisible(renderer) )
    {
      // visibility has explicitly to be set in the single actors
      // due to problems when using cell picking:
      // even if the assembly is invisible, the renderer contains
      // references to the assemblies parts. During picking the
      // visibility of each part is checked, and not only for the
      // whole assembly.
      m_ImageAssembly->VisibilityOff();
      m_EdgeActor->VisibilityOff();
      return;
    }

    // visibility has explicitly to be set in the single actors
    // due to problems when using cell picking:
    // even if the assembly is invisible, the renderer contains
    // references to the assemblies parts. During picking the
    // visibility of each part is checked, and not only for the
    // whole assembly.
    m_ImageAssembly->VisibilityOn();
    m_EdgeActor->VisibilityOn();

    Geometry2DData::Pointer input = const_cast< Geometry2DData * >(this->GetInput());

    if (input.IsNotNull() && (input->GetGeometry2D() != NULL))
    {
      SmartPointerProperty::Pointer surfacecreatorprop;
      surfacecreatorprop = dynamic_cast< SmartPointerProperty * >(GetDataNode()->GetProperty("surfacegeometry", renderer));

      if ( (surfacecreatorprop.IsNull())
        || (surfacecreatorprop->GetSmartPointer().IsNull())
        || ((m_SurfaceCreator = dynamic_cast<Geometry2DDataToSurfaceFilter*>
             (surfacecreatorprop->GetSmartPointer().GetPointer())).IsNull() ) )
        {
        m_SurfaceCreator->PlaceByGeometryOn();
        surfacecreatorprop = SmartPointerProperty::New( m_SurfaceCreator );
        GetDataNode()->SetProperty("surfacegeometry", surfacecreatorprop);
      }

      m_SurfaceCreator->SetInput(input);

      int res;
      if (GetDataNode()->GetIntProperty("xresolution", res, renderer))
      {
        m_SurfaceCreator->SetXResolution(res);
      }
      if (GetDataNode()->GetIntProperty("yresolution", res, renderer))
      {
        m_SurfaceCreator->SetYResolution(res);
      }

      double tubeRadius = 1.0; // Radius of tubular edge surrounding plane

      // Clip the Geometry2D with the reference geometry bounds (if available)
      if ( input->GetGeometry2D()->HasReferenceGeometry() )
      {
        Geometry3D *referenceGeometry =
            input->GetGeometry2D()->GetReferenceGeometry();

        BoundingBox::PointType boundingBoxMin, boundingBoxMax;
        boundingBoxMin = referenceGeometry->GetBoundingBox()->GetMinimum();
        boundingBoxMax = referenceGeometry->GetBoundingBox()->GetMaximum();

        if ( referenceGeometry->GetImageGeometry() )
        {
          for ( unsigned int i = 0; i < 3; ++i )
          {
            boundingBoxMin[i] -= 0.5;
            boundingBoxMax[i] -= 0.5;
          }
        }

        m_SurfaceCreatorPointsContainer->CreateElementAt( 0 ) = boundingBoxMin;
        m_SurfaceCreatorPointsContainer->CreateElementAt( 1 ) = boundingBoxMax;

        m_SurfaceCreatorBoundingBox->ComputeBoundingBox();

        m_SurfaceCreator->SetBoundingBox( m_SurfaceCreatorBoundingBox );

        tubeRadius = referenceGeometry->GetDiagonalLength() / 450.0;
      }

      // If no reference geometry is available, clip with the current global
      // bounds
      else if (m_DataStorage.IsNotNull())
      {
        m_SurfaceCreator->SetBoundingBox(m_DataStorage->ComputeVisibleBoundingBox(NULL, "includeInBoundingBox"));
        tubeRadius = sqrt( m_SurfaceCreator->GetBoundingBox()->GetDiagonalLength2() ) / 450.0;
      }

      // Calculate the surface of the Geometry2D
      m_SurfaceCreator->Update();
      Surface *surface = m_SurfaceCreator->GetOutput();

      // Check if there's something to display, otherwise return
      if ( (surface->GetVtkPolyData() == 0 )
        || (surface->GetVtkPolyData()->GetNumberOfCells() == 0) )
        {
        m_ImageAssembly->VisibilityOff();
        return;
      }

      // add a graphical representation of the surface normals if requested
      DataNode* node = this->GetDataNode();
      bool displayNormals = false;
      bool colorTwoSides = false;
      bool invertNormals = false;
      node->GetBoolProperty("draw normals 3D", displayNormals, renderer);
      node->GetBoolProperty("color two sides", colorTwoSides, renderer);
      node->GetBoolProperty("invert normals", invertNormals, renderer);

      //if we want to draw the display normals or render two sides we have to get the colors
      if( displayNormals || colorTwoSides )
      {
        //get colors
        float frontColor[3] = { 0.0, 0.0, 1.0 };
        node->GetColor( frontColor, renderer, "front color" );
        float backColor[3] = { 1.0, 0.0, 0.0 };
        node->GetColor( backColor, renderer, "back color" );

        if ( displayNormals )
        {
          m_NormalsTransformer->SetInput( surface->GetVtkPolyData() );
          m_NormalsTransformer->SetTransform(node->GetVtkTransform(this->GetTimestep()) );

          m_FrontHedgeHog->SetInput( m_NormalsTransformer->GetOutput() );
          m_FrontHedgeHog->SetVectorModeToUseNormal();
          m_FrontHedgeHog->SetScaleFactor( invertNormals ? 1.0 : -1.0 );

          m_FrontNormalsActor->GetProperty()->SetColor( frontColor[0], frontColor[1], frontColor[2] );

          m_BackHedgeHog->SetInput( m_NormalsTransformer->GetOutput() );
          m_BackHedgeHog->SetVectorModeToUseNormal();
          m_BackHedgeHog->SetScaleFactor( invertNormals ? -1.0 : 1.0 );

          m_BackNormalsActor->GetProperty()->SetColor( backColor[0], backColor[1], backColor[2] );

          //if there is no actor added yet, add one
          if ( !m_NormalsActorAdded )
          {
            m_Prop3DAssembly->AddPart( m_FrontNormalsActor );
            m_Prop3DAssembly->AddPart( m_BackNormalsActor );
            m_NormalsActorAdded = true;
          }
        }
        //if we don't want to display normals AND there is an actor added remove the actor
        else if ( m_NormalsActorAdded )
        {
          m_Prop3DAssembly->RemovePart( m_FrontNormalsActor );
          m_Prop3DAssembly->RemovePart( m_BackNormalsActor );
          m_NormalsActorAdded = false;
        }

        if ( colorTwoSides )
        {
          if ( !invertNormals )
          {
            m_BackgroundActor->GetProperty()->SetColor( backColor[0], backColor[1], backColor[2] );
            m_BackgroundActor->GetBackfaceProperty()->SetColor( frontColor[0], frontColor[1], frontColor[2] );
          }
          else
          {
            m_BackgroundActor->GetProperty()->SetColor( frontColor[0], frontColor[1], frontColor[2] );
            m_BackgroundActor->GetBackfaceProperty()->SetColor( backColor[0], backColor[1], backColor[2] );
          }
        }
      }

      // Add black background for all images (which may be transparent)
      m_BackgroundMapper->SetInput( surface->GetVtkPolyData() );
      m_ImageAssembly->AddPart( m_BackgroundActor );

      LayerSortedActorList layerSortedActors;

      // Traverse the data tree to find nodes resliced by ImageMapperGL2D
      mitk::NodePredicateOr::Pointer p = mitk::NodePredicateOr::New();
      //use a predicate to get all data nodes which are "images" or inherit from mitk::Image
      mitk::TNodePredicateDataType< mitk::Image >::Pointer predicateAllImages = mitk::TNodePredicateDataType< mitk::Image >::New();
      mitk::DataStorage::SetOfObjects::ConstPointer all = m_DataStorage->GetSubset(predicateAllImages);
      //process all found images
      for (mitk::DataStorage::SetOfObjects::ConstIterator it = all->Begin(); it != all->End(); ++it)
      {

        DataNode *node = it->Value();
        if (node != NULL)
          this->ProcessNode(node, renderer, surface, layerSortedActors);
      }

      // Add all image actors to the assembly, sorted according to
      // layer property
      LayerSortedActorList::iterator actorIt;
      for ( actorIt = layerSortedActors.begin(); actorIt != layerSortedActors.end(); ++actorIt )
      {
        m_ImageAssembly->AddPart( actorIt->second );
      }

      // Configurate the tube-shaped frame: size according to the surface
      // bounds, color as specified in the plane's properties
      vtkPolyData *surfacePolyData = surface->GetVtkPolyData();
      m_Cleaner->SetInput(surfacePolyData);
      m_EdgeTransformer->SetTransform(this->GetDataNode()->GetVtkTransform(this->GetTimestep()) );

      // Adjust the radius according to extent
      m_EdgeTuber->SetRadius( tubeRadius );

      // Get the plane's color and set the tube properties accordingly
      ColorProperty::Pointer colorProperty;
      colorProperty = dynamic_cast<ColorProperty*>(this->GetDataNode()->GetProperty( "color" ));
      if ( colorProperty.IsNotNull() )
      {
        const Color& color = colorProperty->GetColor();
        m_EdgeActor->GetProperty()->SetColor(color.GetRed(), color.GetGreen(), color.GetBlue());
      }
      else
      {
        m_EdgeActor->GetProperty()->SetColor( 1.0, 1.0, 1.0 );
      }

      m_ImageAssembly->SetUserTransform(this->GetDataNode()->GetVtkTransform(this->GetTimestep()) );
    }

    VtkRepresentationProperty* representationProperty;
    this->GetDataNode()->GetProperty(representationProperty, "material.representation", renderer);
    if ( representationProperty != NULL )
      m_BackgroundActor->GetProperty()->SetRepresentation( representationProperty->GetVtkRepresentation() );
  }
  void Geometry2DDataVtkMapper3D::ProcessNode( DataNode * node, BaseRenderer* renderer,
                                               Surface * surface, LayerSortedActorList &layerSortedActors )
  {
    if ( node != NULL )
    {
      //we need to get the information from the 2D mapper to render the texture on the 3D plane
      ImageVtkMapper2D *imageMapper = dynamic_cast< ImageVtkMapper2D * >( node->GetMapper(1) ); //GetMapper(1) provides the 2D mapper for the data node

      //if there is a 2D mapper, which is not the standard image mapper...
      if(!imageMapper && node->GetMapper(1))
      { //... check if it is the composite mapper
        std::string cname(node->GetMapper(1)->GetNameOfClass());
        if(!cname.compare("CompositeMapper")) //string.compare returns 0 if the two strings are equal.
        {
          //get the standard image mapper.
          //This is a special case in MITK and does only work for the CompositeMapper.
          imageMapper = dynamic_cast<ImageVtkMapper2D* >( node->GetMapper(3) );
        }
      }

      if ( (node->IsVisible(renderer)) && imageMapper )
      {
        WeakPointerProperty::Pointer rendererProp =
            dynamic_cast< WeakPointerProperty * >(GetDataNode()->GetPropertyList()->GetProperty("renderer"));

        if ( rendererProp.IsNotNull() )
        {
          BaseRenderer::Pointer planeRenderer = dynamic_cast< BaseRenderer * >(rendererProp->GetWeakPointer().GetPointer());
          // Retrieve and update image to be mapped
          const ImageVtkMapper2D::LocalStorage* localStorage = imageMapper->GetLocalStorage(planeRenderer);

          if ( planeRenderer.IsNotNull() )
          {
            // perform update of imagemapper if needed (maybe the respective 2D renderwindow is not rendered/update before)
            imageMapper->Update(planeRenderer);

            // If it has not been initialized already in a previous pass,
            // generate an actor and a texture object to
            // render the image associated with the ImageVtkMapper2D.
            vtkActor *imageActor;
            vtkDataSetMapper *dataSetMapper = NULL;
            vtkTexture *texture;
            if ( m_ImageActors.count( imageMapper ) == 0 )
            {
              dataSetMapper = vtkDataSetMapper::New();
              //Enable rendering without copying the image.
              dataSetMapper->ImmediateModeRenderingOn();

              texture = vtkTexture::New();
              texture->RepeatOff();

              imageActor = vtkActor::New();
              imageActor->SetMapper( dataSetMapper );
              imageActor->SetTexture( texture );

              // Make imageActor the sole owner of the mapper and texture
              // objects
              dataSetMapper->UnRegister( NULL );
              texture->UnRegister( NULL );

              // Store the actor so that it may be accessed in following
              // passes.
              m_ImageActors[imageMapper].Initialize(imageActor, imageMapper, m_ImageMapperDeletedCommand);
            }
            else
            {
              // Else, retrieve the actor and associated objects from the
              // previous pass.
              imageActor = m_ImageActors[imageMapper].m_Actor;
              dataSetMapper = (vtkDataSetMapper *)imageActor->GetMapper();
              texture = imageActor->GetTexture();
            }

            // Set poly data new each time its object changes (e.g. when
            // switching between planar and curved geometries)
            if ( (dataSetMapper != NULL) && (dataSetMapper->GetInput() != surface->GetVtkPolyData()) )
            {
              dataSetMapper->SetInput( surface->GetVtkPolyData() );
            }

            //Check if the m_ReslicedImage is NULL.
            //This is the case when no image geometry is met by
            //the reslicer. In that case, the texture has to be
            //empty (black) and we don't have to do anything.
            //See fixed bug #13275
            if(localStorage->m_ReslicedImage != NULL)
            {
              bool binaryOutline = node->IsOn( "outline binary", renderer );
              if( binaryOutline )
              {
                texture->SetInput( localStorage->m_ReslicedImage );
              }
              else
              {
                texture->SetInput( localStorage->m_Texture->GetInput() );
              }
              // VTK (mis-)interprets unsigned char (binary) images as color images;
              // So, we must manually turn on their mapping through a (gray scale) lookup table;
              texture->SetMapColorScalarsThroughLookupTable( localStorage->m_Texture->GetMapColorScalarsThroughLookupTable() );

              //re-use properties from the 2D image mapper
              imageActor->SetProperty( localStorage->m_Actor->GetProperty() );
              imageActor->GetProperty()->SetAmbient(0.5);

              // Set texture interpolation on/off
              bool textureInterpolation = node->IsOn( "texture interpolation", renderer );
              texture->SetInterpolate( textureInterpolation );

              //get the lookuptable from the 2D image mapper
              texture->SetLookupTable( localStorage->m_Texture->GetLookupTable() );

              // Store this actor to be added to the actor assembly, sort
              // by layer
              int layer = 1;
              node->GetIntProperty( "layer", layer );
              layerSortedActors.insert(std::pair< int, vtkActor * >( layer, imageActor ) );
            }
          }
        }
      }
    }
  }
  void PlaneGeometryDataVtkMapper3D::ProcessNode(DataNode *node,
                                                 BaseRenderer *renderer,
                                                 Surface *surface,
                                                 LayerSortedActorList &layerSortedActors)
  {
    if (node != nullptr)
    {
      // we need to get the information from the 2D mapper to render the texture on the 3D plane
      ImageVtkMapper2D *imageMapper =
        dynamic_cast<ImageVtkMapper2D *>(node->GetMapper(1)); // GetMapper(1) provides the 2D mapper for the data node

      // if there is a 2D mapper, which is not the standard image mapper...
      if (!imageMapper && node->GetMapper(1))
      { //... check if it is the composite mapper
        std::string cname(node->GetMapper(1)->GetNameOfClass());
        if (!cname.compare("CompositeMapper")) // string.compare returns 0 if the two strings are equal.
        {
          // get the standard image mapper.
          // This is a special case in MITK and does only work for the CompositeMapper.
          imageMapper = dynamic_cast<ImageVtkMapper2D *>(node->GetMapper(3));
        }
      }

      if ((node->IsVisible(renderer)) && imageMapper)
      {
        WeakPointerProperty::Pointer rendererProp =
          dynamic_cast<WeakPointerProperty *>(GetDataNode()->GetPropertyList()->GetProperty("renderer"));

        if (rendererProp.IsNotNull())
        {
          BaseRenderer::Pointer planeRenderer =
            dynamic_cast<BaseRenderer *>(rendererProp->GetWeakPointer().GetPointer());
          // Retrieve and update image to be mapped
          const ImageVtkMapper2D::LocalStorage *localStorage = imageMapper->GetLocalStorage(planeRenderer);

          if (planeRenderer.IsNotNull())
          {
            // perform update of imagemapper if needed (maybe the respective 2D renderwindow is not rendered/update
            // before)
            imageMapper->Update(planeRenderer);

            // If it has not been initialized already in a previous pass,
            // generate an actor and a texture object to
            // render the image associated with the ImageVtkMapper2D.
            vtkActor *imageActor;
            vtkDataSetMapper *dataSetMapper = nullptr;
            vtkTexture *texture;
            if (m_ImageActors.count(imageMapper) == 0)
            {
              dataSetMapper = vtkDataSetMapper::New();
              // Enable rendering without copying the image.
              dataSetMapper->ImmediateModeRenderingOn();

              texture = vtkNeverTranslucentTexture::New();
              texture->RepeatOff();

              imageActor = vtkActor::New();
              imageActor->SetMapper(dataSetMapper);
              imageActor->SetTexture(texture);
              imageActor->GetProperty()->SetOpacity(
                0.999); // HACK! otherwise VTK wouldn't recognize this as translucent
                        // surface (if LUT values map to alpha < 255
              // improvement: apply "opacity" property onle HERE and also in 2D image mapper. DO NOT change LUT to
              // achieve
              // translucent images (see method ChangeOpacity in image mapper 2D)

              // Make imageActor the sole owner of the mapper and texture
              // objects
              dataSetMapper->UnRegister(nullptr);
              texture->UnRegister(nullptr);

              // Store the actor so that it may be accessed in following
              // passes.
              m_ImageActors[imageMapper].Initialize(imageActor, imageMapper, m_ImageMapperDeletedCommand);
            }
            else
            {
              // Else, retrieve the actor and associated objects from the
              // previous pass.
              imageActor = m_ImageActors[imageMapper].m_Actor;
              dataSetMapper = (vtkDataSetMapper *)imageActor->GetMapper();
              texture = imageActor->GetTexture();
            }

            // Set poly data new each time its object changes (e.g. when
            // switching between planar and curved geometries)
            if ((dataSetMapper != nullptr) && (dataSetMapper->GetInput() != surface->GetVtkPolyData()))
            {
              dataSetMapper->SetInputData(surface->GetVtkPolyData());
            }

            dataSetMapper->Update();

            // Check if the m_ReslicedImage is nullptr.
            // This is the case when no image geometry is met by
            // the reslicer. In that case, the texture has to be
            // empty (black) and we don't have to do anything.
            // See fixed bug #13275
            if (localStorage->m_ReslicedImage != nullptr)
            {
              texture->SetInputConnection(localStorage->m_LevelWindowFilter->GetOutputPort());

              // do not use a VTK lookup table (we do that ourselves in m_LevelWindowFilter)
              texture->MapColorScalarsThroughLookupTableOff();

              // re-use properties from the 2D image mapper
              imageActor->SetProperty(localStorage->m_Actor->GetProperty());
              imageActor->GetProperty()->SetAmbient(0.5);

              // Set texture interpolation on/off
              bool textureInterpolation = node->IsOn("texture interpolation", renderer);
              texture->SetInterpolate(textureInterpolation);

              // Store this actor to be added to the actor assembly, sort
              // by layer
              int layer = 1;
              node->GetIntProperty("layer", layer);
              layerSortedActors.insert(std::pair<int, vtkActor *>(layer, imageActor));
            }
          }
        }
      }
    }
  }