Hello,

I managed to solve the BUG. I had to modify MITK source code, concretely:

   - mitkPointSetVtkMapper3D.h
   - mitkPointSetVtkMapper3D.cpp
   - mitkSplineVtkMapper3D.cpp

Problem was that for 2D PointSet mapper you contemplated the scenario for
one or more 2D render windows, but for 3D PointSet mapper you didn't, and
it was coded for only one 3D render window in the interface. So, following
how you managed the mappers for different render windows in 2D, I added a
Local Storage Handler class in mitkPointSetVtkMapper3D class and now it
works perfectly.

I attach you the modified files, in case you want to add it to the next
release. You just would need to replace the existing files with the ones I
send and re-compile from scratch. I tested it with the last release
mitk2018 but it also solves it for mitk2016 (in this version you should
comment header #include <vtk_glew.h> I think).

I hope this is useful for someone!

Best,

Rocío

El mié., 7 nov. 2018 a las 16:53, LOPEZ VELAZCO, ROCIO (<rocio.lo...@upf.edu>)
escribió:

> I changed the subjet of the mail to a more specific one.
>
> I went deeper in the problem. It comes when rendering the PointSet Node
> into a second independent 3D QmitkRenderWindow... could it be a problem
> whith the PointSetVtkMapper3D and how it is managed by the rendering
> pipeline? it has a conflict when updating two different render windows
> (RW), but it does not happens for rendering a Surface in two RW, only with
> PointSets.
>
> I carefully read the MITK Rendering Pipeline
> <http://docs.mitk.org/nightly/QVTKRendering.html>, paying special
> attention to "Setting up a distinct Rendering-Pipeline". And I think I am
> not missing anything in my code... I use the global Rendering manager and I
> only have one data storage... My app is not a MITK plugin but an
> independent MITK-based app and I create
> different render windows which are not the conventional
> QmitkStdMultiWidget (you might find a code example in previous mails in
> this message thread).
>
> Would some of the rendering experts have any idea on what might be
> happening? Maybe I'm missing some rendering step...
>
> Thank you very much in advance!
> Best,
>
>
>
> El mié., 31 oct. 2018 a las 15:55, Kalali, Amir (<
> a.kal...@dkfz-heidelberg.de>) escribió:
>
>> Hey Rocio,
>>
>>
>>
>> So how is your setup then: If you have a single data storage you only
>> have the point set loaded once? The StdMultiWidget has four render windows
>> so the point set should be visible in four render windows.
>>
>> Or do you mean two “multi widget editors” (e.g. two StdMultiWidgets)?
>>
>>
>>
>> Is it useful to create a screenshot for visualization?
>>
>>
>>
>> Best,
>>
>>
>>
>> Amir
>>
>>
>>
>> *From:* LOPEZ VELAZCO, ROCIO [mailto:rocio.lo...@upf.edu]
>> *Sent:* Wednesday, 31 October, 2018 14:09
>> *To:* Kalali, Amir
>> *Cc:* mitk-users@lists.sourceforge.net
>> *Subject:* Re: [mitk-users] PointSet Node problem when adding to two
>> Data Storages mitk2018
>>
>>
>>
>> Hello Amir,
>>
>>
>>
>> I advanced a little bit with this, I now found it also happens in
>> mitk2016, and it is not related with having two data storages but with two
>> render windows... Might it be related with qt version? and gtk (linux,
>> fedora)? If you could do a test in your environment I would be very
>> grateful!
>>
>>
>>
>> Thank you very much in advance.
>>
>>
>>
>> Best,
>>
>>
>>
>> Rocio
>>
>>
>>
>> El mié., 24 oct. 2018 a las 11:21, LOPEZ VELAZCO, ROCIO (<
>> rocio.lo...@upf.edu>) escribió:
>>
>> Hi Amir,
>>
>>
>>
>> Thank you very much for your fast reply!
>>
>>
>>
>> - So, this does not happens with other nodes, I can add same Surface Node
>> to both data storages and everything runs perfectly.
>>
>> - If I create two separate pointsets and add each to a data storage, it
>> works fine. However this is not a solution to me... since I am creating a
>> pointset from points introduced by the user and I need this same pointset
>> in another data storage, only to show it.
>>
>>
>>
>> - Yes, sorry that I didn't put the version. I am using version
>> T24059-IGTRelease-2018.03.
>> <https://phabricator.mitk.org/source/mitk/browse/T24059-IGTRelease-2018.03/>
>> I could test it with the last version, could you pass me the link to the
>> last stable version 2018? :)
>>
>> - There are no error messages in console when the render crashes..
>>
>>
>>
>> Thank you very much again.
>>
>> Best,
>>
>>
>>
>> Rocío
>>
>>
>>
>> El mié., 24 oct. 2018 a las 8:56, Kalali, Amir (<
>> a.kal...@dkfz-heidelberg.de>) escribió:
>>
>> Hey Rocio,
>>
>>
>>
>> does this also happen with other Nodes, that you add twice, to two
>> different data storages?
>>
>> What happens if you create two separate pointsets and add each to a data
>> storage?
>>
>>
>>
>> You said it didn’t happen with the MITK 2016. Which version / commit are
>> you currently using?
>>
>> Is there any error message / console output when the render crashes?
>>
>>
>>
>> Best,
>>
>> Amir
>>
>>
>>
>> *From:* LOPEZ VELAZCO, ROCIO [mailto:rocio.lo...@upf.edu]
>> *Sent:* Tuesday, 23 October, 2018 12:52
>> *To:* mitk-users@lists.sourceforge.net
>> *Subject:* [mitk-users] PointSet Node problem when adding to two Data
>> Storages mitk2018
>>
>>
>>
>> Hello,
>>
>>
>>
>> I have a (rendering) problem when adding a DataNode which contains a
>> PointSet into a different Data Storage. It is a very simple scenario:
>>
>>
>>
>> The UI are two 3D render windows, each one with one Data Storage.
>>
>> 1) I create a pointset and add points into it. *Error! Filename not
>> specified.*
>>
>> 2) I create its corresponding Data Node and add it to the Data storage in
>> order to see it in the render window 1. *Error! Filename not specified.*
>>
>> 3) I add this data node into the second data storage in order to see it
>> in the render window 2, BUT just in this moment the render crashes.*Error!
>> Filename not specified.*
>>
>>
>>
>> Can it be related with the pointsetInteractor? I think it shouldn't be a
>> problem...
>>
>>
>>
>> Any help with this would be awesome since I am using a lot of PointSets
>> in my app....
>>
>> This didn't happened with last mitk version 2016. Could someone please
>> check  this problem with last release?
>>
>>
>>
>> Thank you very much in advance!
>>
>>
>>
>> Best regards,
>>
>>
>>
>> Rocío
>>
>>
>>
>>
>>
>> --
>>
>> Rocío López Velazco
>>
>> *SimbioSYS group, BCN MedTech*
>>
>> *UniversityPompeu Fabra*
>>
>> *Department of Information and Communication Technologies *
>>
>> *Roc Boronat, 122 (Tànger Building),  08018 Barcelona
>> Office 55 119 *
>> *https://bcn-medtech.upf.edu/ <https://bcn-medtech.upf.edu/>*
>>
>>
>>
>>
>>
>>
>>
>> --
>>
>> Rocío López Velazco
>>
>> *SimbioSYS group, BCN MedTech*
>>
>> *UniversityPompeu Fabra*
>>
>> *Department of Information and Communication Technologies *
>>
>> *Roc Boronat, 122 (Tànger Building),  08018 Barcelona
>> Office 55 119 *
>> *https://bcn-medtech.upf.edu/ <https://bcn-medtech.upf.edu/>*
>>
>>
>>
>>
>>
>>
>>
>> --
>>
>> Rocío López Velazco
>>
>> *SimbioSYS group, BCN MedTech*
>>
>> *UniversityPompeu Fabra*
>>
>> *Department of Information and Communication Technologies *
>>
>> *Roc Boronat, 122 (Tànger Building),  08018 Barcelona
>> Office 55 119 *
>> *https://bcn-medtech.upf.edu/ <https://bcn-medtech.upf.edu/>*
>>
>>
>>
>>
>>
>
>
> --
>
> Rocío López Velazco
>
> *SimbioSYS** group, BCN MedTech*
>
> *UniversityPompeu Fabra*
>
>
>
>
> *Department of Information and Communication Technologies Roc Boronat, 122
> (Tànger Building),  08018 Barcelona                    Office 55 119
> https://bcn-medtech.upf.edu/ <https://bcn-medtech.upf.edu/>*
>
>
>
>

-- 

Rocío López Velazco

*SimbioSYS** group, BCN MedTech*

*UniversityPompeu Fabra*




*Department of Information and Communication Technologies Roc Boronat, 122
(Tànger Building),  08018 Barcelona                    Office 55 119
https://bcn-medtech.upf.edu/ <https://bcn-medtech.upf.edu/>*
/*===================================================================

The Medical Imaging Interaction Toolkit (MITK)

Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.

This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.

See LICENSE.txt or http://www.mitk.org for details.

===================================================================*/

#include "mitkSplineVtkMapper3D.h"
#include <mitkPointSet.h>
#include <mitkProperties.h>
#include <vtkActor.h>
#include <vtkCardinalSpline.h>
#include <vtkCellArray.h>
#include <vtkPoints.h>
#include <vtkPolyData.h>
#include <vtkPolyDataMapper.h>
#include <vtkProp.h>
#include <vtkPropAssembly.h>
#include <vtkPropCollection.h>
#include <vtkProperty.h>
#include <vtkTubeFilter.h>

mitk::SplineVtkMapper3D::SplineVtkMapper3D() : m_SplinesAvailable(false), m_SplinesAddedToAssembly(false)
{
  m_SplinesActor = vtkActor::New();
  m_SplineAssembly = vtkPropAssembly::New();
  m_SplineResolution = 500;
}

mitk::SplineVtkMapper3D::~SplineVtkMapper3D()
{
  m_SplinesActor->Delete();
  m_SplineAssembly->Delete();
}

vtkProp *mitk::SplineVtkMapper3D::GetVtkProp(mitk::BaseRenderer * /*renderer*/)
{
  return m_SplineAssembly;
}

void mitk::SplineVtkMapper3D::UpdateVtkTransform(mitk::BaseRenderer * /*renderer*/)
{
  vtkLinearTransform *vtktransform = this->GetDataNode()->GetVtkTransform(this->GetTimestep());

  m_SplinesActor->SetUserTransform(vtktransform);
}

void mitk::SplineVtkMapper3D::GenerateDataForRenderer(mitk::BaseRenderer *renderer)
{
  LocalStorage *ls = m_LSH.GetLocalStorage(renderer);

  // only update spline if UpdateSpline has not been called from
  // external, e.g. by the SplineMapper2D. But call it the first time when m_SplineUpdateTime = 0 and m_LastUpdateTime =
  // 0.
  if (m_SplineUpdateTime < ls->GetLastGenerateDataTime() || m_SplineUpdateTime == 0)
  {
    this->UpdateSpline();
    this->ApplyAllProperties(renderer, m_SplinesActor);
  }

  if (m_SplinesAvailable)
  {
    if (!m_SplinesAddedToAssembly)
    {
      m_SplineAssembly->AddPart(m_SplinesActor);
      m_SplinesAddedToAssembly = true;
    }
  }
  else
  {
    if (m_SplinesAddedToAssembly)
    {
      m_SplineAssembly->RemovePart(m_SplinesActor);
      m_SplinesAddedToAssembly = false;
    }
  }

  bool visible = true;
  GetDataNode()->GetVisibility(visible, renderer, "visible");

  if (!visible)
  {
    m_SplinesActor->VisibilityOff();
    m_SplineAssembly->VisibilityOff();
  }
  else
  {
    m_SplinesActor->VisibilityOn();
    m_SplineAssembly->VisibilityOn();

    // remove the PointsAssembly if it was added in superclass. No need to display points and spline!
    if (m_SplineAssembly->GetParts()->IsItemPresent(ls->m_PointsAssembly))
      m_SplineAssembly->RemovePart(ls->m_PointsAssembly);
  }
  // if the properties have been changed, then refresh the properties
  if ((m_SplineUpdateTime < this->m_DataNode->GetPropertyList()->GetMTime()) ||
      (m_SplineUpdateTime < this->m_DataNode->GetPropertyList(renderer)->GetMTime()))
    this->ApplyAllProperties(renderer, m_SplinesActor);
}

void mitk::SplineVtkMapper3D::ApplyAllProperties(BaseRenderer *renderer, vtkActor *actor)
{
  Superclass::ApplyColorAndOpacityProperties(renderer, actor);

  // vtk changed the type of rgba during releases. Due to that, the following convert is done
  double rgba[4] = {1.0f, 1.0f, 1.0f, 1.0f}; // white

  // getting the color from DataNode
  float temprgba[4];
  this->GetDataNode()->GetColor(&temprgba[0], nullptr);
  // convert to rgba, what ever type it has!
  rgba[0] = temprgba[0];
  rgba[1] = temprgba[1];
  rgba[2] = temprgba[2];
  rgba[3] = temprgba[3];
  // finaly set the color inside the actor
  m_SplinesActor->GetProperty()->SetColor(rgba);

  float lineWidth;
  if (dynamic_cast<mitk::IntProperty *>(this->GetDataNode()->GetProperty("line width")) == nullptr)
    lineWidth = 1.0;
  else
    lineWidth = dynamic_cast<mitk::IntProperty *>(this->GetDataNode()->GetProperty("line width"))->GetValue();
  m_SplinesActor->GetProperty()->SetLineWidth(lineWidth);

  m_SplineUpdateTime.Modified();
}

bool mitk::SplineVtkMapper3D::SplinesAreAvailable()
{
  return m_SplinesAvailable;
}

vtkPolyData *mitk::SplineVtkMapper3D::GetSplinesPolyData()
{
  if (m_SplinesAvailable)
    return (dynamic_cast<vtkPolyDataMapper *>(m_SplinesActor->GetMapper()))->GetInput();
  else
    return nullptr;
}

vtkActor *mitk::SplineVtkMapper3D::GetSplinesActor()
{
  if (m_SplinesAvailable)
    return m_SplinesActor;
  else
    return vtkActor::New();
}

void mitk::SplineVtkMapper3D::UpdateSpline()
{
  mitk::PointSet::Pointer input = const_cast<mitk::PointSet *>(this->GetInput());
  //  input->Update();//already done in superclass

  // Number of points on the spline
  unsigned int numberOfOutputPoints = m_SplineResolution;
  unsigned int numberOfInputPoints = input->GetSize();

  if (numberOfInputPoints >= 2)
  {
    m_SplinesAvailable = true;
    vtkCardinalSpline *splineX = vtkCardinalSpline::New();
    vtkCardinalSpline *splineY = vtkCardinalSpline::New();
    vtkCardinalSpline *splineZ = vtkCardinalSpline::New();
    unsigned int index = 0;
    mitk::PointSet::DataType::PointsContainer::Pointer pointsContainer = input->GetPointSet()->GetPoints();
    for (mitk::PointSet::DataType::PointsContainer::Iterator it = pointsContainer->Begin();
         it != pointsContainer->End();
         ++it, ++index)
    // for ( unsigned int i = 0 ; i < numberOfInputPoints; ++i )
    {
      mitk::PointSet::PointType point = it->Value();
      splineX->AddPoint(index, point[0]);
      splineY->AddPoint(index, point[1]);
      splineZ->AddPoint(index, point[2]);
    }
    vtkPoints *points = vtkPoints::New();
    vtkPolyData *profileData = vtkPolyData::New();

    // Interpolate x, y and z by using the three spline filters and
    // create new points
    double t = 0.0f;
    for (unsigned int i = 0; i < numberOfOutputPoints; ++i)
    {
      t = ((((double)numberOfInputPoints) - 1.0f) / (((double)numberOfOutputPoints) - 1.0f)) * ((double)i);
      points->InsertPoint(i, splineX->Evaluate(t), splineY->Evaluate(t), splineZ->Evaluate(t));
    }

    // Create the polyline.
    vtkCellArray *lines = vtkCellArray::New();
    lines->InsertNextCell(numberOfOutputPoints);
    for (unsigned int i = 0; i < numberOfOutputPoints; ++i)
      lines->InsertCellPoint(i);

    profileData->SetPoints(points);
    profileData->SetLines(lines);

    // Add thickness to the resulting line.
    // vtkTubeFilter* profileTubes = vtkTubeFilter::New();
    // profileTubes->SetNumberOfSides(8);
    // profileTubes->SetInput(profileData);
    // profileTubes->SetRadius(.005);

    vtkPolyDataMapper *profileMapper = vtkPolyDataMapper::New();
    profileMapper->SetInputData(profileData);

    m_SplinesActor->SetMapper(profileMapper);
  }
  else
  {
    m_SplinesAvailable = false;
  }
  m_SplineUpdateTime.Modified();
}
/*===================================================================

The Medical Imaging Interaction Toolkit (MITK)

Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.

This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.

See LICENSE.txt or http://www.mitk.org for details.

===================================================================*/

#include "mitkPointSetVtkMapper3D.h"
#include "mitkColorProperty.h"
#include "mitkDataNode.h"
#include "mitkPointSet.h"
#include "mitkProperties.h"
#include "mitkVtkPropRenderer.h"

#include <vtkActor.h>
#include <vtkAppendPolyData.h>
#include <vtkCellArray.h>
#include <vtkConeSource.h>
#include <vtkCubeSource.h>
#include <vtkCylinderSource.h>
#include <vtkPolyDataAlgorithm.h>
#include <vtkPolyDataMapper.h>
#include <vtkPropAssembly.h>
#include <vtkProperty.h>
#include <vtkRenderer.h>
#include <vtkSphereSource.h>
#include <vtkTransform.h>
#include <vtkTransformPolyDataFilter.h>
#include <vtkTubeFilter.h>
#include <vtkVectorText.h>

#include <stdlib.h>

//#include <vtkgl.h>

#include <mitkPropertyObserver.h>
#include <vtk_glew.h>


// constructor LocalStorage
mitk::PointSetVtkMapper3D::LocalStorage::LocalStorage()
{
   /// All point positions, already in world coordinates
   m_WorldPositions = vtkSmartPointer<vtkPoints>::New();
   /// All connections between two points (used for contour drawing)
   m_PointConnections = vtkSmartPointer<vtkCellArray>::New(); // m_PointConnections between points

   
  m_vtkSelectedPointList = vtkSmartPointer<vtkAppendPolyData>::New();
  m_vtkUnselectedPointList = vtkSmartPointer<vtkAppendPolyData>::New();
 
  m_VtkSelectedPolyDataMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
  m_VtkUnselectedPolyDataMapper = vtkSmartPointer<vtkPolyDataMapper>::New();

   // creating actors to be able to set transform
  m_SelectedActor = vtkSmartPointer<vtkActor>::New();
  m_UnselectedActor = vtkSmartPointer<vtkActor>::New();
  m_ContourActor = vtkSmartPointer<vtkActor>::New();

  // propassembly
  m_PointsAssembly = vtkSmartPointer<vtkPropAssembly>::New();
  m_NumberOfSelectedAdded = 0;
  m_NumberOfUnselectedAdded = 0;
}

// destructor LocalStorage
mitk::PointSetVtkMapper3D::LocalStorage::~LocalStorage()
{
}

const mitk::PointSet *mitk::PointSetVtkMapper3D::GetInput()
{
  return static_cast<const mitk::PointSet *>(GetDataNode()->GetData());
}

mitk::PointSetVtkMapper3D::PointSetVtkMapper3D()
  : 
    m_vtkTextList(nullptr),
    m_PointSize(1.0),
    m_ContourRadius(0.5)
    //m_VertexRendering(false)
{
}

mitk::PointSetVtkMapper3D::~PointSetVtkMapper3D()
{
}

/*void mitk::PointSetVtkMapper3D::ReleaseGraphicsResources(vtkWindow *renWin)
{
  m_PointsAssembly->ReleaseGraphicsResources(renWin);

  m_SelectedActor->ReleaseGraphicsResources(renWin);
  m_UnselectedActor->ReleaseGraphicsResources(renWin);
  m_ContourActor->ReleaseGraphicsResources(renWin);
}*/

void mitk::PointSetVtkMapper3D::ReleaseGraphicsResources(mitk::BaseRenderer *renderer)
{

  LocalStorage *ls = m_LSH.GetLocalStorage(renderer);
  ls->m_PointsAssembly->ReleaseGraphicsResources(renderer->GetRenderWindow());

  ls->m_SelectedActor->ReleaseGraphicsResources(renderer->GetRenderWindow());
  ls->m_UnselectedActor->ReleaseGraphicsResources(renderer->GetRenderWindow());
  ls->m_ContourActor->ReleaseGraphicsResources(renderer->GetRenderWindow());
}

void mitk::PointSetVtkMapper3D::CreateVTKRenderObjects(mitk::BaseRenderer *renderer)
{
    LocalStorage *ls = m_LSH.GetLocalStorage(renderer);
    ls->m_PointsAssembly->VisibilityOn();

    if (ls->m_PointsAssembly->GetParts()->IsItemPresent(ls->m_SelectedActor))
      ls->m_PointsAssembly->RemovePart(ls->m_SelectedActor);
    if (ls->m_PointsAssembly->GetParts()->IsItemPresent(ls->m_UnselectedActor))
      ls->m_PointsAssembly->RemovePart(ls->m_UnselectedActor);
    if (ls->m_PointsAssembly->GetParts()->IsItemPresent(ls->m_ContourActor))
      ls->m_PointsAssembly->RemovePart(ls->m_ContourActor);

    // exceptional displaying for PositionTracker -> MouseOrientationTool
    int mapperID;
    bool isInputDevice = false;
    if (this->GetDataNode()->GetBoolProperty("inputdevice", isInputDevice) && isInputDevice)
    {
      if (this->GetDataNode()->GetIntProperty("BaseRendererMapperID", mapperID) && mapperID == BaseRenderer::Standard3D)
        return; // The event for the PositionTracker came from the 3d widget and  not needs to be displayed
    }

    ls->m_vtkSelectedPointList =  vtkSmartPointer<vtkAppendPolyData>::New();
    ls->m_vtkUnselectedPointList = vtkSmartPointer<vtkAppendPolyData>::New();

    // get and update the PointSet
    mitk::PointSet::Pointer input = const_cast<mitk::PointSet *>(this->GetInput());
    
    /* only update the input data, if the property tells us to */
    bool update = true;
    this->GetDataNode()->GetBoolProperty("updateDataOnRender", update);
    if (update == true)
      input->Update();

    int timestep = this->GetTimestep();

    mitk::PointSet::DataType::Pointer itkPointSet = input->GetPointSet(timestep);

    if (itkPointSet.GetPointer() == nullptr)
    {
      ls->m_PointsAssembly->VisibilityOff();
      return;
    }

    // now fill selected and unselected pointList
    // get size of Points in Property
    m_PointSize = 2;
    mitk::FloatProperty::Pointer pointSizeProp =
      dynamic_cast<mitk::FloatProperty *>(this->GetDataNode()->GetProperty("pointsize"));
    if (pointSizeProp.IsNotNull())
      m_PointSize = pointSizeProp->GetValue();

    // get the property for creating a label onto every point only once
    bool showLabel = true;
    this->GetDataNode()->GetBoolProperty("show label", showLabel);
    const char *pointLabel = nullptr;
    if (showLabel)
    {
      if (dynamic_cast<mitk::StringProperty *>(this->GetDataNode()->GetPropertyList()->GetProperty("label")) != nullptr)
        pointLabel =
          dynamic_cast<mitk::StringProperty *>(this->GetDataNode()->GetPropertyList()->GetProperty("label"))->GetValue();
      else
        showLabel = false;
    }

    // whether or not to creat a "contour" - connecting lines between all the points
    int nbPoints = itkPointSet->GetPointData()->Size();
    bool makeContour = false;
    this->GetDataNode()->GetBoolProperty("show contour", makeContour);

    bool closeContour = false;
    this->GetDataNode()->GetBoolProperty("close contour", closeContour);
    int contourPointLimit = 0; // NO contour
    if (makeContour)
    {
      if (closeContour)
        contourPointLimit = nbPoints;
      else
        contourPointLimit = nbPoints - 1;
    }

    // build list of all positions for later transform in one go
    mitk::PointSet::PointsContainer::Iterator pointsIter;
    int ptIdx;

    ls->m_NumberOfSelectedAdded = 0;
    ls->m_NumberOfUnselectedAdded = 0;
    vtkSmartPointer<vtkPoints> localPoints = vtkSmartPointer<vtkPoints>::New();
    ls->m_WorldPositions = vtkSmartPointer<vtkPoints>::New();
    ls->m_PointConnections = vtkSmartPointer<vtkCellArray>::New(); // m_PointConnections between points    
    for (ptIdx = 0, pointsIter = itkPointSet->GetPoints()->Begin(); pointsIter != itkPointSet->GetPoints()->End();
         pointsIter++, ptIdx++)
    {
      itk::Point<float> currentPoint = pointsIter->Value();
      localPoints->InsertPoint(ptIdx, currentPoint[0], currentPoint[1], currentPoint[2]);

      if (makeContour && ptIdx < contourPointLimit)
      {
        vtkIdType cell[2] = {(ptIdx + 1) % nbPoints, ptIdx};
        ls->m_PointConnections->InsertNextCell(2, cell);
      }
    }

    vtkSmartPointer<vtkLinearTransform> vtktransform = this->GetDataNode()->GetVtkTransform(this->GetTimestep());
    vtktransform->TransformPoints(localPoints, ls->m_WorldPositions);

      // create contour
    if (makeContour)
    {
      this->CreateContour(ls->m_WorldPositions, ls->m_PointConnections, renderer);
    }

    // check if the list for the PointDataContainer is the same size as the PointsContainer. Is not, then the points were
    // inserted manually and can not be visualized according to the PointData (selected/unselected)
    bool pointDataBroken = (itkPointSet->GetPointData()->Size() != itkPointSet->GetPoints()->Size());
    
    // now add an object for each point in data
    mitk::PointSet::PointDataContainer::Iterator pointDataIter = itkPointSet->GetPointData()->Begin();
  for (ptIdx = 0; ptIdx < nbPoints; ++ptIdx) // pointDataIter moved at end of loop
  {
    double currentPoint[3];
    
    ls->m_WorldPositions->GetPoint(ptIdx, currentPoint);
    vtkSmartPointer<vtkPolyDataAlgorithm> source;

    // check for the pointtype in data and decide which geom-object to take and then add to the selected or unselected
    // list
    int pointType;
    if (itkPointSet->GetPointData()->size() == 0 || pointDataBroken)
      pointType = mitk::PTUNDEFINED;
    else
      pointType = pointDataIter.Value().pointSpec;

    switch (pointType)
    {
      case mitk::PTUNDEFINED:
      {

        vtkSmartPointer<vtkSphereSource> sphere = vtkSmartPointer<vtkSphereSource>::New();
        sphere->SetRadius(m_PointSize / 2.0f);
        sphere->SetCenter(currentPoint);
        // sphere->SetCenter(pointsIter.Value()[0],pointsIter.Value()[1],pointsIter.Value()[2]);

        // MouseOrientation Tool (PositionTracker)
        if (isInputDevice)
        {
          sphere->SetThetaResolution(10);
          sphere->SetPhiResolution(10);
        }
        else
        {
          sphere->SetThetaResolution(20);
          sphere->SetPhiResolution(20);
        }
        source = sphere;
      }
      break;
      case mitk::PTSTART:
      {

        vtkSmartPointer<vtkCubeSource> cube = vtkSmartPointer<vtkCubeSource>::New();
        cube->SetXLength(m_PointSize / 2);
        cube->SetYLength(m_PointSize / 2);
        cube->SetZLength(m_PointSize / 2);
        cube->SetCenter(currentPoint);
        source = cube;
      }
      break;
      case mitk::PTCORNER:
      {
        
        vtkSmartPointer<vtkConeSource> cone = vtkSmartPointer<vtkConeSource>::New();
        cone->SetRadius(m_PointSize / 2.0f);
        cone->SetCenter(currentPoint);
        cone->SetResolution(20);
        source = cone;
      }
      break;
      case mitk::PTEDGE:
      {

        vtkSmartPointer<vtkCylinderSource> cylinder = vtkSmartPointer<vtkCylinderSource>::New();
        cylinder->SetRadius(m_PointSize / 2.0f);
        cylinder->SetCenter(currentPoint);
        cylinder->SetResolution(20);
        source = cylinder;
      }
      break;
      case mitk::PTEND:
      {

        vtkSmartPointer<vtkSphereSource> sphere = vtkSmartPointer<vtkSphereSource>::New();
        sphere->SetRadius(m_PointSize / 2.0f);
        // no SetCenter?? this functionality should be explained!
        // otherwise: join with default block!
        sphere->SetThetaResolution(20);
        sphere->SetPhiResolution(20);
        source = sphere;
      }
      break;
      default:
      {
        vtkSmartPointer<vtkSphereSource> sphere = vtkSmartPointer<vtkSphereSource>::New();
        sphere->SetRadius(m_PointSize / 2.0f);
        sphere->SetCenter(currentPoint);
        sphere->SetThetaResolution(20);
        sphere->SetPhiResolution(20);
        source = sphere;
      }
      break;
    }

    if (pointDataIter.Value().selected && !pointDataBroken)
    {
      ls->m_vtkSelectedPointList->AddInputConnection(source->GetOutputPort());
      ++ls->m_NumberOfSelectedAdded;
    }
    else
    {

      ls->m_vtkUnselectedPointList->AddInputConnection(source->GetOutputPort());
      ++ls->m_NumberOfUnselectedAdded;
    }
    if (showLabel)
    { 
      char buffer[20];
      std::string l = pointLabel;
      if (input->GetSize() > 1)
      {
        sprintf(buffer, "%d", ptIdx + 1);
        l.append(buffer);
      }
      // Define the text for the label
      vtkSmartPointer<vtkVectorText> label = vtkSmartPointer<vtkVectorText>::New();
      label->SetText(l.c_str());

      //# Set up a transform to move the label to a new position.
      vtkSmartPointer<vtkTransform> aLabelTransform = vtkSmartPointer<vtkTransform>::New();
      aLabelTransform->Identity();
      aLabelTransform->Translate(currentPoint[0] + 2, currentPoint[1] + 2, currentPoint[2]);
      aLabelTransform->Scale(5.7, 5.7, 5.7);

      //# Move the label to a new position.
      vtkSmartPointer<vtkTransformPolyDataFilter> labelTransform = vtkSmartPointer<vtkTransformPolyDataFilter>::New();
      labelTransform->SetTransform(aLabelTransform);
      labelTransform->SetInputConnection(label->GetOutputPort());

      // add it to the wright PointList
      if (pointType)
      {
        ls->m_vtkSelectedPointList->AddInputConnection(labelTransform->GetOutputPort());
        ++ls->m_NumberOfSelectedAdded;
      }
      else
      {
        ls->m_vtkUnselectedPointList->AddInputConnection(labelTransform->GetOutputPort());
        ++ls->m_NumberOfUnselectedAdded;
      }
    }

    if (pointDataIter != itkPointSet->GetPointData()->End())
      pointDataIter++;
  } // end FOR

  // now according to number of elements added to selected or unselected, build up the rendering pipeline
  if (ls->m_NumberOfSelectedAdded > 0)
  {
    ls->m_VtkSelectedPolyDataMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
    ls->m_VtkSelectedPolyDataMapper->SetInputConnection(ls->m_vtkSelectedPointList->GetOutputPort());

    // create a new instance of the actor
    ls->m_SelectedActor = vtkSmartPointer<vtkActor>::New();

    ls->m_SelectedActor->SetMapper(ls->m_VtkSelectedPolyDataMapper);
    ls->m_PointsAssembly->AddPart(ls->m_SelectedActor);
  }

  if (ls->m_NumberOfUnselectedAdded > 0)
  {    
    ls->m_VtkUnselectedPolyDataMapper = vtkSmartPointer<vtkPolyDataMapper>::New();

    ls->m_VtkUnselectedPolyDataMapper->SetInputConnection(ls->m_vtkUnselectedPointList->GetOutputPort());

    // create a new instance of the actor
    ls->m_UnselectedActor = vtkSmartPointer<vtkActor>::New();

    ls->m_UnselectedActor->SetMapper(ls->m_VtkUnselectedPolyDataMapper);
    ls->m_PointsAssembly->AddPart(ls->m_UnselectedActor);
  }
}

/*
void mitk::PointSetVtkMapper3D::VertexRendering(mitk::BaseRenderer *renderer)
{
  LocalStorage *ls = m_LSH.GetLocalStorage(renderer);
  // get and update the PointSet
  mitk::PointSet::Pointer input = const_cast<mitk::PointSet *>(this->GetInput());
*/
  /* only update the input data, if the property tells us to */
 /* bool update = true;
  this->GetDataNode()->GetBoolProperty("updateDataOnRender", update);
  if (update == true)
    input->Update();
  int timestep = this->GetTimestep();

  mitk::PointSet::DataType::Pointer itkPointSet = input->GetPointSet(timestep);

  // turn off standard actors
  ls->m_UnselectedActor->VisibilityOff();
  ls->m_SelectedActor->VisibilityOff();

  // point size
  m_PointSize = 2.0;
  mitk::FloatProperty::Pointer pointSizeProp =
    dynamic_cast<mitk::FloatProperty *>(this->GetDataNode()->GetProperty("pointsize"));
  if (pointSizeProp.IsNotNull())
    m_PointSize = pointSizeProp->GetValue();

  double *color = ls->m_UnselectedActor->GetProperty()->GetColor();
  double opacity = ls->m_UnselectedActor->GetProperty()->GetOpacity();

  glClearColor(0.0, 0.0, 0.0, 0.0);
  glDisable(GL_COLOR_MATERIAL);
  glDisable(GL_LIGHTING);
  glEnable(GL_POINT_SMOOTH);

  glPointSize(m_PointSize);
  glBegin(GL_POINTS);

  glColor4d(color[0], color[1], color[2], opacity);

  for (auto pointsIter = itkPointSet->GetPoints()->Begin(); pointsIter != itkPointSet->GetPoints()->End(); pointsIter++)
  {
    const itk::Point<mitk::ScalarType> &point = pointsIter->Value();
    glVertex3d(point[0], point[1], point[2]);
  }

  glEnd();

  // reset context
  glPointSize(1.0);
  glDisable(GL_POINT_SMOOTH);
  glEnable(GL_COLOR_MATERIAL);
  glEnable(GL_LIGHTING);
}*/

void mitk::PointSetVtkMapper3D::GenerateDataForRenderer(mitk::BaseRenderer *renderer)
{
  LocalStorage *ls = m_LSH.GetLocalStorage(renderer);
  bool visible = true;
  GetDataNode()->GetVisibility(visible, renderer, "visible");
  if (!visible)
  {
    ls->m_UnselectedActor->VisibilityOff();
    ls->m_SelectedActor->VisibilityOff();
    ls->m_ContourActor->VisibilityOff();
    return;
  }

  // create new vtk render objects (e.g. sphere for a point)

  //SetVtkMapperImmediateModeRendering(ls->m_VtkSelectedPolyDataMapper);
  //SetVtkMapperImmediateModeRendering(ls->m_VtkUnselectedPolyDataMapper);

  //BaseLocalStorage *ls = m_LSH.GetLocalStorage(renderer);
  bool needGenerateData = ls->IsGenerateDataRequired(renderer, this, GetDataNode());

  /*if (!needGenerateData)
  {
    mitk::FloatProperty *pointSizeProp =
      dynamic_cast<mitk::FloatProperty *>(this->GetDataNode()->GetProperty("pointsize"));
    mitk::FloatProperty *contourSizeProp =
      dynamic_cast<mitk::FloatProperty *>(this->GetDataNode()->GetProperty("contoursize"));

    bool useVertexRendering = false;
    this->GetDataNode()->GetBoolProperty("Vertex Rendering", useVertexRendering);

    // only create new vtk render objects if property values were changed
    if (pointSizeProp && m_PointSize != pointSizeProp->GetValue())
      needGenerateData = true;
    if (contourSizeProp && m_ContourRadius != contourSizeProp->GetValue())
      needGenerateData = true;

    // when vertex rendering is enabled the pointset is always
    // drawn with opengl, thus we leave needGenerateData always false
    if (useVertexRendering && m_VertexRendering != useVertexRendering)
    {
      needGenerateData = false;
      m_VertexRendering = true;
    }
    else if (!useVertexRendering && m_VertexRendering)
    {
      m_VertexRendering = false;
      needGenerateData = true;
    }
  }

  if (needGenerateData)
  {
    this->CreateVTKRenderObjects(renderer);
    ls->UpdateGenerateDataTime();
  }*/
  
    if (!needGenerateData)
  {
    if (this->GetDataNode()->GetPropertyList()->GetMTime() > ls->GetLastGenerateDataTime() ||
        this->GetDataNode()->GetPropertyList(renderer)->GetMTime() > ls->GetLastGenerateDataTime())
    {
      needGenerateData = true;
    }
  }

  if (needGenerateData)
  {
    this->CreateVTKRenderObjects(renderer);
    ls->UpdateGenerateDataTime();
  }

  this->ApplyAllProperties(renderer, ls->m_ContourActor);

  bool showPoints = true;
  this->GetDataNode()->GetBoolProperty("show points", showPoints);

  ls->m_UnselectedActor->SetVisibility(showPoints);
  ls->m_SelectedActor->SetVisibility(showPoints);

  if (false && dynamic_cast<mitk::FloatProperty *>(this->GetDataNode()->GetProperty("opacity")) != nullptr)
  {
    mitk::FloatProperty::Pointer pointOpacity =
      dynamic_cast<mitk::FloatProperty *>(this->GetDataNode()->GetProperty("opacity"));
    float opacity = pointOpacity->GetValue();
    ls->m_ContourActor->GetProperty()->SetOpacity(opacity);
    ls->m_UnselectedActor->GetProperty()->SetOpacity(opacity);
    ls->m_SelectedActor->GetProperty()->SetOpacity(opacity);
  }

  bool showContour = false;
  this->GetDataNode()->GetBoolProperty("show contour", showContour);
  ls->m_ContourActor->SetVisibility(showContour);

  // use vertex rendering
  /*if (m_VertexRendering)
  {
    (VertexRendering)(renderer);
    ls->UpdateGenerateDataTime();
  }*/
}

void mitk::PointSetVtkMapper3D::ResetMapper(BaseRenderer * renderer)
{
  LocalStorage *ls = m_LSH.GetLocalStorage(renderer);
  ls->m_PointsAssembly->VisibilityOff();
}

vtkProp *mitk::PointSetVtkMapper3D::GetVtkProp(mitk::BaseRenderer * renderer)
{
  LocalStorage *ls = m_LSH.GetLocalStorage(renderer);
  return ls->m_PointsAssembly;
}

void mitk::PointSetVtkMapper3D::UpdateVtkTransform(mitk::BaseRenderer * /*renderer*/)
{
}

void mitk::PointSetVtkMapper3D::ApplyAllProperties(mitk::BaseRenderer *renderer, vtkActor *actor)
{
  LocalStorage *ls = m_LSH.GetLocalStorage(renderer);

  Superclass::ApplyColorAndOpacityProperties(renderer, actor);
  // check for color props and use it for rendering of selected/unselected points and contour
  // due to different params in VTK (double/float) we have to convert!

  // vars to convert to
  double unselectedColor[4] = {1.0f, 1.0f, 0.0f, 1.0f}; // yellow
  double selectedColor[4] = {1.0f, 0.0f, 0.0f, 1.0f};   // red
  double contourColor[4] = {1.0f, 0.0f, 0.0f, 1.0f};    // red

  // different types for color!!!
  mitk::Color tmpColor;
  double opacity = 1.0;

  // check if there is an unselected property
  if (dynamic_cast<mitk::ColorProperty *>(
        this->GetDataNode()->GetPropertyList(renderer)->GetProperty("unselectedcolor")) != nullptr)
  {
    tmpColor = dynamic_cast<mitk::ColorProperty *>(
                 this->GetDataNode()->GetPropertyList(renderer)->GetProperty("unselectedcolor"))
                 ->GetValue();
    unselectedColor[0] = tmpColor[0];
    unselectedColor[1] = tmpColor[1];
    unselectedColor[2] = tmpColor[2];
    unselectedColor[3] = 1.0f; //!!define a new ColorProp to be able to pass alpha value
  }
  else if (dynamic_cast<mitk::ColorProperty *>(
             this->GetDataNode()->GetPropertyList(nullptr)->GetProperty("unselectedcolor")) != nullptr)
  {
    tmpColor =
      dynamic_cast<mitk::ColorProperty *>(this->GetDataNode()->GetPropertyList(nullptr)->GetProperty("unselectedcolor"))
        ->GetValue();
    unselectedColor[0] = tmpColor[0];
    unselectedColor[1] = tmpColor[1];
    unselectedColor[2] = tmpColor[2];
    unselectedColor[3] = 1.0f; //!!define a new ColorProp to be able to pass alpha value
  }
  else
  {
    // check if the node has a color
    float unselectedColorTMP[4] = {1.0f, 1.0f, 0.0f, 1.0f}; // yellow
    m_DataNode->GetColor(unselectedColorTMP, nullptr);
    unselectedColor[0] = unselectedColorTMP[0];
    unselectedColor[1] = unselectedColorTMP[1];
    unselectedColor[2] = unselectedColorTMP[2];
    // unselectedColor[3] stays 1.0f
  }

  // get selected property
  if (dynamic_cast<mitk::ColorProperty *>(
        this->GetDataNode()->GetPropertyList(renderer)->GetProperty("selectedcolor")) != nullptr)
  {
    tmpColor =
      dynamic_cast<mitk::ColorProperty *>(this->GetDataNode()->GetPropertyList(renderer)->GetProperty("selectedcolor"))
        ->GetValue();
    selectedColor[0] = tmpColor[0];
    selectedColor[1] = tmpColor[1];
    selectedColor[2] = tmpColor[2];
    selectedColor[3] = 1.0f;
  }
  else if (dynamic_cast<mitk::ColorProperty *>(
             this->GetDataNode()->GetPropertyList(nullptr)->GetProperty("selectedcolor")) != nullptr)
  {
    tmpColor =
      dynamic_cast<mitk::ColorProperty *>(this->GetDataNode()->GetPropertyList(nullptr)->GetProperty("selectedcolor"))
        ->GetValue();
    selectedColor[0] = tmpColor[0];
    selectedColor[1] = tmpColor[1];
    selectedColor[2] = tmpColor[2];
    selectedColor[3] = 1.0f;
  }

  // get contour property
  if (dynamic_cast<mitk::ColorProperty *>(
        this->GetDataNode()->GetPropertyList(renderer)->GetProperty("contourcolor")) != nullptr)
  {
    tmpColor =
      dynamic_cast<mitk::ColorProperty *>(this->GetDataNode()->GetPropertyList(renderer)->GetProperty("contourcolor"))
        ->GetValue();
    contourColor[0] = tmpColor[0];
    contourColor[1] = tmpColor[1];
    contourColor[2] = tmpColor[2];
    contourColor[3] = 1.0f;
  }
  else if (dynamic_cast<mitk::ColorProperty *>(
             this->GetDataNode()->GetPropertyList(nullptr)->GetProperty("contourcolor")) != nullptr)
  {
    tmpColor =
      dynamic_cast<mitk::ColorProperty *>(this->GetDataNode()->GetPropertyList(nullptr)->GetProperty("contourcolor"))
        ->GetValue();
    contourColor[0] = tmpColor[0];
    contourColor[1] = tmpColor[1];
    contourColor[2] = tmpColor[2];
    contourColor[3] = 1.0f;
  }

  if (dynamic_cast<mitk::FloatProperty *>(this->GetDataNode()->GetPropertyList(renderer)->GetProperty("opacity")) !=
      nullptr)
  {
    mitk::FloatProperty::Pointer pointOpacity =
      dynamic_cast<mitk::FloatProperty *>(this->GetDataNode()->GetPropertyList(renderer)->GetProperty("opacity"));
    opacity = pointOpacity->GetValue();
  }
  else if (dynamic_cast<mitk::FloatProperty *>(this->GetDataNode()->GetPropertyList(nullptr)->GetProperty("opacity")) !=
           nullptr)
  {
    mitk::FloatProperty::Pointer pointOpacity =
      dynamic_cast<mitk::FloatProperty *>(this->GetDataNode()->GetPropertyList(nullptr)->GetProperty("opacity"));
    opacity = pointOpacity->GetValue();
  }
  // finished color / opacity fishing!

  // check if a contour shall be drawn
  bool showContour = false;
  this->GetDataNode()->GetBoolProperty("show contour", showContour, renderer);
  if (showContour && (ls->m_ContourActor != nullptr))
  { 
    this->CreateContour(ls->m_WorldPositions, ls->m_PointConnections, renderer);
    ls->m_ContourActor->GetProperty()->SetColor(contourColor);
    ls->m_ContourActor->GetProperty()->SetOpacity(opacity);
  }

  ls->m_SelectedActor->GetProperty()->SetColor(selectedColor);
  ls->m_SelectedActor->GetProperty()->SetOpacity(opacity);

  ls->m_UnselectedActor->GetProperty()->SetColor(unselectedColor);
  ls->m_UnselectedActor->GetProperty()->SetOpacity(opacity);
}

void mitk::PointSetVtkMapper3D::CreateContour(vtkPoints *points, vtkCellArray *PointConnections, mitk::BaseRenderer *renderer)
{
  LocalStorage *ls = m_LSH.GetLocalStorage(renderer);
  vtkSmartPointer<vtkAppendPolyData> vtkContourPolyData = vtkSmartPointer<vtkAppendPolyData>::New();
  vtkSmartPointer<vtkPolyDataMapper> vtkContourPolyDataMapper = vtkSmartPointer<vtkPolyDataMapper>::New();

  vtkSmartPointer<vtkPolyData> contour = vtkSmartPointer<vtkPolyData>::New();
  contour->SetPoints(points);
  contour->SetLines(PointConnections);

  vtkSmartPointer<vtkTubeFilter> tubeFilter = vtkSmartPointer<vtkTubeFilter>::New();
  tubeFilter->SetNumberOfSides(12);
  tubeFilter->SetInputData(contour);

  // check for property contoursize.
  m_ContourRadius = 0.5;
  mitk::FloatProperty::Pointer contourSizeProp =
    dynamic_cast<mitk::FloatProperty *>(this->GetDataNode()->GetProperty("contoursize"));

  if (contourSizeProp.IsNotNull())
    m_ContourRadius = contourSizeProp->GetValue();

  tubeFilter->SetRadius(m_ContourRadius);
  tubeFilter->Update();

  // add to pipeline
  vtkContourPolyData->AddInputConnection(tubeFilter->GetOutputPort());
  vtkContourPolyDataMapper->SetInputConnection(vtkContourPolyData->GetOutputPort());

  ls->m_ContourActor->SetMapper(vtkContourPolyDataMapper);
  ls->m_PointsAssembly->AddPart(ls->m_ContourActor);
}

void mitk::PointSetVtkMapper3D::SetDefaultProperties(mitk::DataNode *node, mitk::BaseRenderer *renderer, bool overwrite)
{
  node->AddProperty("line width", mitk::IntProperty::New(2), renderer, overwrite);
  node->AddProperty("pointsize", mitk::FloatProperty::New(1.0), renderer, overwrite);
  node->AddProperty("selectedcolor", mitk::ColorProperty::New(1.0f, 0.0f, 0.0f), renderer, overwrite); // red
  node->AddProperty("color", mitk::ColorProperty::New(1.0f, 1.0f, 0.0f), renderer, overwrite);         // yellow
  node->AddProperty("opacity", mitk::FloatProperty::New(1.0f), renderer, overwrite);
  node->AddProperty("show contour", mitk::BoolProperty::New(false), renderer, overwrite);
  node->AddProperty("close contour", mitk::BoolProperty::New(false), renderer, overwrite);
  node->AddProperty("contourcolor", mitk::ColorProperty::New(1.0f, 0.0f, 0.0f), renderer, overwrite);
  node->AddProperty("contoursize", mitk::FloatProperty::New(0.5), renderer, overwrite);
  node->AddProperty("show points", mitk::BoolProperty::New(true), renderer, overwrite);
  node->AddProperty("updateDataOnRender", mitk::BoolProperty::New(true), renderer, overwrite);
  node->AddProperty("Vertex Rendering", mitk::BoolProperty::New(false), renderer, overwrite);
  Superclass::SetDefaultProperties(node, renderer, overwrite);
}
/*===================================================================

The Medical Imaging Interaction Toolkit (MITK)

Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.

This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.

See LICENSE.txt or http://www.mitk.org for details.

===================================================================*/

#ifndef MITKPointSetVtkMAPPER3D_H_HEADER_INCLUDED_C1907273
#define MITKPointSetVtkMAPPER3D_H_HEADER_INCLUDED_C1907273

#include "mitkBaseRenderer.h"
#include "mitkVtkMapper.h"
#include <MitkCoreExports.h>
#include <vtkSmartPointer.h>
//#include "mitkLocalStorageHandler.h"

class vtkActor;
class vtkCellArray;
class vtkPropAssembly;
class vtkAppendPolyData;
class vtkPolyData;
class vtkTubeFilter;
class vtkPolyDataMapper;
class vtkTransformPolyDataFilter;

namespace mitk
{
  class PointSet;

  /**
  * @brief Vtk-based mapper for PointSet
  *
  * Due to the need of different colors for selected
  * and unselected points and the facts, that we also have a contour and
  * labels for the points, the vtk structure is build up the following way:
  *
  * We have two AppendPolyData, one selected, and one unselected and one
  * for a contour between the points. Each one is connected to an own
  * PolyDaraMapper and an Actor. The different color for the unselected and
  * selected state and for the contour is read from properties.
  *
  * "unselectedcolor", "selectedcolor" and "contourcolor" are the strings,
  * that are looked for. Pointlabels are added besides the selected or the
  * deselected points.
  *
  * Then the three Actors are combined inside a vtkPropAssembly and this
  * object is returned in GetProp() and so hooked up into the rendering
  * pipeline.

  * Properties that can be set for point sets and influence the PointSetVTKMapper3D are:
  *

  *   - \b "color": (ColorProperty*) Color of the point set
  *   - \b "Opacity": (FloatProperty) Opacity of the point set
  *   - \b "show contour": (BoolProperty) If the contour of the points are visible
  *   - \b "contourSizeProp":(FloatProperty) Contour size of the points


  The default properties are:

  *   - \b "line width": (IntProperty::New(2), renderer, overwrite )
  *   - \b "pointsize": (FloatProperty::New(1.0), renderer, overwrite)
  *   - \b "selectedcolor": (ColorProperty::New(1.0f, 0.0f, 0.0f), renderer, overwrite)  //red
  *   - \b "color": (ColorProperty::New(1.0f, 1.0f, 0.0f), renderer, overwrite)  //yellow
  *   - \b "show contour": (BoolProperty::New(false), renderer, overwrite )
  *   - \b "contourcolor": (ColorProperty::New(1.0f, 0.0f, 0.0f), renderer, overwrite)
  *   - \b "contoursize": (FloatProperty::New(0.5), renderer, overwrite )
  *   - \b "close contour": (BoolProperty::New(false), renderer, overwrite )
  *   - \b "show points": (BoolProperty::New(true), renderer, overwrite )
  *   - \b "updateDataOnRender": (BoolProperty::New(true), renderer, overwrite )



  *Other properties looked for are:
  *
  *   - \b "show contour": if set to on, lines between the points are shown
  *   - \b "close contour": if set to on, the open strip is closed (first point
  *       connected with last point)
  *   - \b "pointsize": size of the points mapped (diameter of a sphere, in world woordinates!)
  *   - \b "label": text of the Points to show besides points
  *   - \b "contoursize": size of the contour drawn between the points
  *       (if not set, the pointsize is taken)
  *
  * @ingroup Mapper
  */
  class MITKCORE_EXPORT PointSetVtkMapper3D : public VtkMapper
  {
  public:
    mitkClassMacro(PointSetVtkMapper3D, VtkMapper);

    itkFactorylessNewMacro(Self) itkCloneMacro(Self)

      virtual const mitk::PointSet *GetInput();

    // overwritten from VtkMapper3D to be able to return a
    // m_PointsAssembly which is much faster than a vtkAssembly
    virtual vtkProp *GetVtkProp(mitk::BaseRenderer *renderer) override;
    virtual void UpdateVtkTransform(mitk::BaseRenderer *renderer) override;

    static void SetDefaultProperties(mitk::DataNode *node, mitk::BaseRenderer *renderer = nullptr, bool overwrite = false);

    /*
    * \deprecatedSince{2013_12} Use ReleaseGraphicsResources(mitk::BaseRenderer* renderer) instead
    */
    //DEPRECATED(void ReleaseGraphicsResources(vtkWindow *renWin));

    void ReleaseGraphicsResources(mitk::BaseRenderer *renderer) override;
    

    /** \brief Internal class holding the mapper, actor, etc. for each of the 3D render windows */
    class LocalStorage : public mitk::Mapper::BaseLocalStorage
    {
    public:
      /* constructor */
      LocalStorage();

      /* destructor */
      ~LocalStorage();

      /// All point positions, already in world coordinates
      vtkSmartPointer<vtkPoints> m_WorldPositions;
      /// All connections between two points (used for contour drawing)
      vtkSmartPointer<vtkCellArray> m_PointConnections;

      vtkSmartPointer<vtkAppendPolyData> m_vtkSelectedPointList;
      vtkSmartPointer<vtkAppendPolyData> m_vtkUnselectedPointList;

      //vtkSmartPointer<vtkPoints> m_VtkPoints;
      //vtkSmartPointer<vtkCellArray> m_VtkPointConnections;

      //vtkSmartPointer<vtkTransformPolyDataFilter> m_VtkPointsTransformer;

      vtkSmartPointer<vtkPolyDataMapper> m_VtkSelectedPolyDataMapper;
      vtkSmartPointer<vtkPolyDataMapper> m_VtkUnselectedPolyDataMapper;

      vtkSmartPointer<vtkActor> m_SelectedActor;
      vtkSmartPointer<vtkActor> m_UnselectedActor;
      vtkSmartPointer<vtkActor> m_ContourActor;


      vtkSmartPointer<vtkPropAssembly> m_PointsAssembly;

      // variables to be able to log, how many inputs have been added to PolyDatas
      unsigned int m_NumberOfSelectedAdded;
      unsigned int m_NumberOfUnselectedAdded;


    };

    /** \brief The LocalStorageHandler holds all (three) LocalStorages for the three 2D render windows. */
    mitk::LocalStorageHandler<LocalStorage> m_LSH;

    //mitk::LocalStorageHandler<BaseLocalStorage> m_LSH;

  protected:
    PointSetVtkMapper3D();

    virtual ~PointSetVtkMapper3D();

    virtual void GenerateDataForRenderer(mitk::BaseRenderer *renderer) override;
    virtual void ResetMapper(BaseRenderer *renderer) override;
    virtual void ApplyAllProperties(mitk::BaseRenderer *renderer, vtkActor *actor);
    virtual void CreateContour(vtkPoints *points, vtkCellArray *connections, mitk::BaseRenderer *renderer);
    virtual void CreateVTKRenderObjects(mitk::BaseRenderer *renderer);
   // virtual void VertexRendering(mitk::BaseRenderer *renderer);

    // help for contour between points
    vtkSmartPointer<vtkAppendPolyData> m_vtkTextList;
    
    // variables to check if an update of the vtk objects is needed
    ScalarType m_PointSize;
    ScalarType m_ContourRadius;
    //bool m_VertexRendering;
  };

} // namespace mitk

#endif /* MITKPointSetVtkMAPPER3D_H_HEADER_INCLUDED_C1907273 */
_______________________________________________
mitk-users mailing list
mitk-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mitk-users

Reply via email to