void VolumeVisualizationImagePreprocessor::UpdateTransferFunction( TransferFunction::Pointer tf, int treshold  )
{
  double opacity = 0.005;

  //double maskValue = m_OutOfLiverValue;
  //double surfaceValue = m_surfaceValue;
  //double realSurfaceValue = m_realSurfaceValue;

  //double surfaceSteepness = 0.0;

  //VVP_INFO << "changing to threshold of " << treshold << " and opacity of " << opacity;

  // grayvalue->opacity
  {   
    vtkPiecewiseFunction *f=tf->GetScalarOpacityFunction();
    
    f->RemovePoint( m_LastUsedTreshold-1 );
    f->AddPoint(treshold-1,opacity); 
   
    f->RemovePoint( m_LastUsedTreshold+4 );
    f->AddPoint(treshold+4,0.8); 
  }  

  // grayvalue->color
  {  
    vtkColorTransferFunction *ctf=tf->GetColorTransferFunction();

    ctf->RemovePoint( m_LastUsedTreshold-32 );
    ctf->AddRGBPoint( treshold-32, 0.2, 0.0, 0.0 );
    
    ctf->RemovePoint( m_LastUsedTreshold );
    ctf->AddRGBPoint( treshold, 251/255.0, 1.0, 0.0 );
  }

  m_LastUsedTreshold = treshold;
}
TransferFunction::Pointer
VolumeVisualizationImagePreprocessor::GetInitialTransferFunction(  )
{
  int treshold = m_EstimatedThreshold;

  double opacity = 0.005;

  double maskValue = m_OutOfLiverValue;
  double surfaceValue = m_surfaceValue;
  double realSurfaceValue = m_realSurfaceValue;

  //double surfaceSteepness = 0.0;

  VVP_INFO << "using threshold of " << treshold << " and opacity of " << opacity;

  TransferFunction::Pointer tf = TransferFunction::New();

  // grayvalue->opacity
  {   
    vtkPiecewiseFunction *f=tf->GetScalarOpacityFunction();
    f->RemoveAllPoints();
    f->AddPoint(maskValue,0);
    f->AddPoint(maskValue+1,0);
    f->AddPoint(surfaceValue,0.05);
    f->AddPoint(realSurfaceValue,opacity);
    f->AddPoint(treshold-1,opacity); 
    f->AddPoint(treshold+4,0.8); 
    f->AddPoint(m_MaxThreshold+1,0.8); 
    f->ClampingOn();
    f->Modified();
  }  

  // gradient at grayvalue->opacity
  {  
    vtkPiecewiseFunction *f=tf->GetGradientOpacityFunction();
    f->RemoveAllPoints();
    f->AddPoint( -1000.0, 1.0 );
    f->AddPoint( 1000, 1.0 );
    f->ClampingOn();
    f->Modified();
  }

  // grayvalue->color
  {  
    vtkColorTransferFunction *ctf=tf->GetColorTransferFunction();
    ctf->RemoveAllPoints();
    ctf->AddRGBPoint( maskValue, 0.5, 0.0, 0.0 );
    ctf->AddRGBPoint( maskValue+1, 0.5, 0.0, 0.0 );
    ctf->AddRGBPoint( surfaceValue, 1.0, 0.0, 0.0 ); //0.5
    ctf->AddRGBPoint( realSurfaceValue, 0.2, 0.0, 0.0 );

    ctf->AddRGBPoint( treshold-32, 0.2, 0.0, 0.0 );
    ctf->AddRGBPoint( treshold, 251/255.0, 1.0, 0.0 );
    ctf->AddRGBPoint( m_MaxThreshold+1, 251/255.0, 1.0, 0.0 );

    ctf->ClampingOn();
    ctf->Modified();
  }

  m_LastUsedTreshold = treshold;

  return tf;
}
BaseProperty::Pointer mitk::TransferFunctionPropertySerializer::Deserialize(TiXmlElement* element)
{
  if (!element) 
    return NULL;
  
  TransferFunction::Pointer tf = TransferFunction::New();

  // deserialize scalar opacity function
  TiXmlElement* scalarOpacityPointlist = element->FirstChildElement("ScalarOpacity");
  if (scalarOpacityPointlist == NULL)
    return NULL;
    
  tf->ClearScalarOpacityPoints();  
    
  for( TiXmlElement* pointElement = scalarOpacityPointlist->FirstChildElement("point"); pointElement != NULL; pointElement = pointElement->NextSiblingElement("point"))
  {
    double x;
    double y;
    if (pointElement->QueryDoubleAttribute("x", &x) == TIXML_WRONG_TYPE)
      return NULL; // TODO: can we do a better error handling?
    if (pointElement->QueryDoubleAttribute("y", &y) == TIXML_WRONG_TYPE)
      return NULL; // TODO: can we do a better error handling?
    tf->AddScalarOpacityPoint(x, y);
  }

  TiXmlElement* gradientOpacityPointlist = element->FirstChildElement("GradientOpacity");
  if (gradientOpacityPointlist == NULL)
    return NULL;
  
  tf->ClearGradientOpacityPoints();
  
  for( TiXmlElement* pointElement = gradientOpacityPointlist->FirstChildElement("point"); pointElement != NULL; pointElement = pointElement->NextSiblingElement("point"))
  {
    double x;
    double y;
    if (pointElement->QueryDoubleAttribute("x", &x) == TIXML_WRONG_TYPE)
      return NULL; // TODO: can we do a better error handling?
    if (pointElement->QueryDoubleAttribute("y", &y) == TIXML_WRONG_TYPE)
      return NULL; // TODO: can we do a better error handling?
    tf->AddGradientOpacityPoint(x, y);
  }

  TiXmlElement* rgbPointlist = element->FirstChildElement("Color");
  if (rgbPointlist == NULL)
    return NULL;
  vtkColorTransferFunction* ctf = tf->GetColorTransferFunction();
  if (ctf == NULL)
    return NULL;
  
  ctf->RemoveAllPoints();
  
  for( TiXmlElement* pointElement = rgbPointlist->FirstChildElement("point"); pointElement != NULL; pointElement = pointElement->NextSiblingElement("point"))
  {
    double x;
    double r,g,b, midpoint, sharpness;
    if (pointElement->QueryDoubleAttribute("x", &x) == TIXML_WRONG_TYPE)
      return NULL; // TODO: can we do a better error handling?
    if (pointElement->QueryDoubleAttribute("r", &r) == TIXML_WRONG_TYPE)
      return NULL; // TODO: can we do a better error handling?
    if (pointElement->QueryDoubleAttribute("g", &g) == TIXML_WRONG_TYPE)
      return NULL; // TODO: can we do a better error handling?
    if (pointElement->QueryDoubleAttribute("b", &b) == TIXML_WRONG_TYPE)
      return NULL; // TODO: can we do a better error handling?
    if (pointElement->QueryDoubleAttribute("midpoint", &midpoint) == TIXML_WRONG_TYPE)
      return NULL; // TODO: can we do a better error handling?
    if (pointElement->QueryDoubleAttribute("sharpness", &sharpness) == TIXML_WRONG_TYPE)
      return NULL; // TODO: can we do a better error handling?
    ctf->AddRGBPoint(x, r, g, b, midpoint, sharpness);
  }
  return TransferFunctionProperty::New(tf).GetPointer();
}
BaseProperty::Pointer mitk::TransferFunctionPropertySerializer::Deserialize(TiXmlElement* element)
{
  if (!element)
    return nullptr;

  mitk::LocaleSwitch localeSwitch("C");

  TransferFunction::Pointer tf = TransferFunction::New();

  // deserialize scalar opacity function
  TiXmlElement* scalarOpacityPointlist = element->FirstChildElement("ScalarOpacity");
  if (scalarOpacityPointlist == nullptr)
  {
    return nullptr;
  }

  tf->ClearScalarOpacityPoints();

  try
  {
    for( TiXmlElement* pointElement = scalarOpacityPointlist->FirstChildElement("point");
         pointElement != nullptr;
         pointElement = pointElement->NextSiblingElement("point"))
    {
      std::string x;
      std::string y;
      if (pointElement->QueryStringAttribute("x", &x) != TIXML_SUCCESS) return nullptr;
      if (pointElement->QueryStringAttribute("y", &y) != TIXML_SUCCESS) return nullptr;
      tf->AddScalarOpacityPoint(boost::lexical_cast<double>(x), boost::lexical_cast<double>(y));
    }

    TiXmlElement* gradientOpacityPointlist = element->FirstChildElement("GradientOpacity");
    if (gradientOpacityPointlist == nullptr)
    {
      return nullptr;
    }

    tf->ClearGradientOpacityPoints();

    for( TiXmlElement* pointElement = gradientOpacityPointlist->FirstChildElement("point");
         pointElement != nullptr;
         pointElement = pointElement->NextSiblingElement("point"))
    {
      std::string x;
      std::string y;
      if (pointElement->QueryStringAttribute("x", &x) != TIXML_SUCCESS) return nullptr;
      if (pointElement->QueryStringAttribute("y", &y) != TIXML_SUCCESS) return nullptr;
      tf->AddGradientOpacityPoint(boost::lexical_cast<double>(x), boost::lexical_cast<double>(y));
    }

    TiXmlElement* rgbPointlist = element->FirstChildElement("Color");
    if (rgbPointlist == nullptr)
    {
      return nullptr;
    }
    vtkColorTransferFunction* ctf = tf->GetColorTransferFunction();
    if (ctf == nullptr)
    {
      return nullptr;
    }

    ctf->RemoveAllPoints();

    for( TiXmlElement* pointElement = rgbPointlist->FirstChildElement("point");
         pointElement != nullptr;
         pointElement = pointElement->NextSiblingElement("point"))
    {
      std::string x;
      std::string r,g,b, midpoint, sharpness;
      if (pointElement->QueryStringAttribute("x", &x) != TIXML_SUCCESS) return nullptr;
      if (pointElement->QueryStringAttribute("r", &r) != TIXML_SUCCESS) return nullptr;
      if (pointElement->QueryStringAttribute("g", &g) != TIXML_SUCCESS) return nullptr;
      if (pointElement->QueryStringAttribute("b", &b) != TIXML_SUCCESS) return nullptr;
      if (pointElement->QueryStringAttribute("midpoint", &midpoint) != TIXML_SUCCESS) return nullptr;
      if (pointElement->QueryStringAttribute("sharpness", &sharpness) != TIXML_SUCCESS) return nullptr;
      ctf->AddRGBPoint(boost::lexical_cast<double>(x),
                       boost::lexical_cast<double>(r), boost::lexical_cast<double>(g), boost::lexical_cast<double>(b),
                       boost::lexical_cast<double>(midpoint),
                       boost::lexical_cast<double>(sharpness));
    }
  }
  catch ( boost::bad_lexical_cast& e )
  {
    MITK_ERROR << "Could not parse string as number: " << e.what();

    return nullptr;
  }

  return TransferFunctionProperty::New(tf).GetPointer();
}