<commit_before>/*=========================================================================
 *
 *  Copyright Insight Software Consortium
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0.txt
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 *=========================================================================*/
#ifndef __itkColorTable_hxx
#define __itkColorTable_hxx

#include "itkColorTable.h"
#include "itkNumericTraits.h"
#include "vnl/vnl_sample.h"

#include <sstream>
#include <iomanip>

namespace itk
{
template< typename TPixel >
ColorTable< TPixel >
::ColorTable()
{
  m_NumberOfColors = 0;
}

template< typename TPixel >
void
ColorTable< TPixel >
::DeleteColors()
{
  m_Color.resize(0);
  m_ColorName.resize(0);
}

template< typename TPixel >
void
ColorTable< TPixel >
::PrintSelf(std::ostream & os, Indent indent) const
{
  Superclass::PrintSelf(os, indent);

  os << indent << "NumberOfColors = " << m_NumberOfColors << std::endl;
  for ( unsigned int i = 0; i < m_NumberOfColors; i++ )
    {
    os << indent
       << "ColorName[" << i << "] = " << m_ColorName[i] << ", "
       << "Color[" << i << "] = " << m_Color[i] << std::endl;
    }
}

template< typename TPixel >
void
ColorTable< TPixel >
::UseDiscreteColors(void)
{
  this->DeleteColors();

  m_NumberOfColors = 8;
  m_Color.resize(m_NumberOfColors);
  m_ColorName.resize(m_NumberOfColors);

  typename NumericTraits< TPixel >::RealType scale;
  typename NumericTraits< TPixel >::RealType shift;
  if (NumericTraits<TPixel>::is_integer)
    {
    scale =
      static_cast< typename NumericTraits< TPixel >::RealType>(NumericTraits< TPixel >::max()) -
      static_cast<  typename NumericTraits< TPixel >::RealType>(NumericTraits< TPixel >::NonpositiveMin());
    shift =
      static_cast<  typename NumericTraits< TPixel >::RealType>(NumericTraits< TPixel >::NonpositiveMin());
    }
  else
    {
    scale = NumericTraits< TPixel >::One;
    shift = NumericTraits< TPixel >::Zero;
    }

  m_Color[0].Set((TPixel)(0.9 * scale + shift),
                 (TPixel)(              shift),
                 (TPixel)(              shift) );
  m_ColorName[0] = "Red";

  m_Color[1].Set((TPixel)(0.8 * scale + shift),
                 (TPixel)(              shift),
                 (TPixel)(0.8 * scale + shift));
  m_ColorName[1] = "Purple";

  m_Color[2].Set((TPixel)(              shift),
                 (TPixel)(0.8 * scale + shift),
                 (TPixel)(0.8 * scale + shift));
  m_ColorName[2] = "Aqua";

  m_Color[3].Set((TPixel)(0.8 * scale + shift),
                 (TPixel)(0.8 * scale + shift),
                 (TPixel)(              shift));
  m_ColorName[3] = "Yellow";

  m_Color[4].Set((TPixel)(              shift),
                 (TPixel)(0.9 * scale + shift),
                 (TPixel)(              shift));
  m_ColorName[4] = "Green";

  m_Color[5].Set((TPixel)(              shift),
                 (TPixel)(              shift),
                 (TPixel)(0.9 * scale + shift));
  m_ColorName[5] = "Blue";

  m_Color[6].Set((TPixel)(0.7 * scale + shift),
                 (TPixel)(0.7 * scale + shift),
                 (TPixel)(0.7 * scale + shift));
  m_ColorName[6] = "Grey0.70";
  //
  // to avoid numeric exception, need to make
  // sure that the value assigned is clamped at
  // max for TPixel.  Exceptions were happening
  // on this assignment, even if realMax was
  // set to NumericTraits<TPixel>::max().
  typename NumericTraits< TPixel >::RealType
    realMax(1.0 * scale + shift);
  TPixel pixelMax(NumericTraits< TPixel >::max());
  if(realMax < NumericTraits< TPixel >::max())
    {
    pixelMax = static_cast< TPixel >(realMax);
    }
  m_Color[7].Set(pixelMax,pixelMax,pixelMax);
  m_ColorName[7] = "White";
}

template< typename TPixel >
void
ColorTable< TPixel >
::UseGrayColors(unsigned int n)
{
  unsigned int i;

  this->DeleteColors();

  m_NumberOfColors = n;
  m_Color.resize(m_NumberOfColors);
  m_ColorName.resize(m_NumberOfColors);

  typename NumericTraits< TPixel >::RealType range;
  typename NumericTraits< TPixel >::RealType minimum;
  if (NumericTraits<TPixel>::is_integer)
    {
    range =
      static_cast< typename NumericTraits< TPixel >::RealType>(NumericTraits< TPixel >::max()) -
      static_cast<  typename NumericTraits< TPixel >::RealType>(NumericTraits< TPixel >::NonpositiveMin());
    minimum = NumericTraits< TPixel >::NonpositiveMin();
    }
  else
    {
    range = NumericTraits< TPixel >::One;
    minimum = NumericTraits< TPixel >::Zero;
    }
  typename NumericTraits< TPixel >::RealType delta;
  if (m_NumberOfColors > 1)
    {
    delta = range / ( m_NumberOfColors - 1 );
    }
  else
    {
    delta = 0.0;
    }

  for ( i = 0; i < m_NumberOfColors; i++ )
    {
    typename NumericTraits< TPixel >::RealType
      realGray( minimum + i * delta );

    TPixel gray = NumericTraits< TPixel >::max();
    if( realGray < NumericTraits< TPixel >::max() )
      {
      gray = static_cast< TPixel >(realGray);
      }

    m_Color[i].Set(gray, gray, gray);
    std::ostringstream name;
    name << "Gray" << std::fixed << std::setprecision(2)
         << static_cast<float>(gray);
    m_ColorName[i] = name.str();
    }
}

template< typename TPixel >
void
ColorTable< TPixel >
::UseHeatColors(unsigned int n)
{
  unsigned int i;

  this->DeleteColors();

  m_NumberOfColors = n;
  m_Color.resize(m_NumberOfColors);
  m_ColorName.resize(m_NumberOfColors);

  typename NumericTraits< TPixel >::RealType scale;
  typename NumericTraits< TPixel >::RealType shift;
  if (NumericTraits<TPixel>::is_integer)
    {
    scale =
      static_cast< typename NumericTraits< TPixel >::RealType>(NumericTraits< TPixel >::max()) -
      static_cast<  typename NumericTraits< TPixel >::RealType>(NumericTraits< TPixel >::NonpositiveMin());
    shift =
      static_cast<  typename NumericTraits< TPixel >::RealType>(NumericTraits< TPixel >::NonpositiveMin());
    }
  else
    {
    scale = NumericTraits< TPixel >::One;
    shift = NumericTraits< TPixel >::Zero;
    }
  for ( i = 0; i < n / 2.0; i++ )
    {
    //
    // avoid overflow
    typename NumericTraits < TPixel >::RealType
      realR((( i + 1 ) / ( n / 2.0 + 1 ) ) * scale + shift);
    TPixel r(NumericTraits< TPixel >::max());
    if(realR < NumericTraits< TPixel >::max())
      {
      r = static_cast< TPixel >(realR);
      }
    TPixel g(static_cast<TPixel>( shift));
    TPixel b(static_cast<TPixel>( shift));
    m_Color[i].Set(r,g,b);
    std::ostringstream name;
    name << "Heat" << std::fixed << std::setprecision(2)
         << i / static_cast<float>(n);
    m_ColorName[i] = name.str();
    }

  for ( i = 0; i < n / 2; i++ )
    {
    typename NumericTraits< TPixel >::RealType
      rdouble(1.0 * scale + shift);
    TPixel r(NumericTraits<TPixel>::max());
    if( rdouble < NumericTraits<TPixel>::max() )
      {
      r = static_cast<TPixel>(rdouble);
      }
    TPixel g = static_cast<TPixel>((( i + 1 ) / ( n / 2.0 + 1 )) * scale + shift);
    TPixel b = static_cast<TPixel>((( i + 1 ) / ( n / 2.0 + 1 )) * scale + shift);
    m_Color[(size_t)(i + n / 2.0 )].Set(r,g,b);
    std::ostringstream name;
    name << "Heat" << std::fixed << std::setprecision(2)
         << ( i + n / 2.0 ) / (float)n;
    m_ColorName[static_cast<size_t>(( i + n / 2.0 ))] = name.str();
    }
}

template< typename TPixel >
void
ColorTable< TPixel >
::UseRandomColors(unsigned int n)
{
  unsigned int i;

  this->DeleteColors();

  m_NumberOfColors = n;
  m_Color.resize(m_NumberOfColors);
  m_ColorName.resize(m_NumberOfColors);
  TPixel r, g, b;
  TPixel minimum, maximum;
  if (NumericTraits<TPixel>::is_integer)
    {
    minimum = NumericTraits< TPixel >::NonpositiveMin();
    maximum = NumericTraits< TPixel >::max();
    }
  else
    {
    minimum = NumericTraits< TPixel >::Zero;
    maximum  = NumericTraits< TPixel >::One;
    }
  for ( i = 0; i < n; i++ )
    {
      r = static_cast< TPixel >( vnl_sample_uniform( minimum, maximum));
    m_Color[i][0] = r;
    g = static_cast< TPixel >( vnl_sample_uniform( minimum, maximum));
    m_Color[i][1] = g;
    b = static_cast< TPixel >( vnl_sample_uniform( minimum, maximum));
    m_Color[i][2] = b;
    std::ostringstream name;
    name << "Random(" << std::fixed << std::setprecision(2)
         << static_cast< float >( r ) << ","
         << static_cast< float >( g ) << ","
         << static_cast< float >( b ) << ")";
    m_ColorName[i] = name.str();
    }
}

template< typename TPixel >
bool
ColorTable< TPixel >
::SetColor(unsigned int c, RGBPixel<TPixel> pixel, const char *name)
{
  return this->SetColor(c, pixel[0], pixel[1], pixel[2], name);
}

template< typename TPixel >
bool
ColorTable< TPixel >
::SetColor(unsigned int c, TPixel r, TPixel g, TPixel b, const char *name)
{
  if ( c < m_NumberOfColors )
    {
    m_Color[c][0] = r;
    m_Color[c][1] = g;
    m_Color[c][2] = b;
    m_ColorName[c] = name;
    return true;
    }
  return false;
}

template< typename TPixel >
RGBPixel< TPixel >
ColorTable< TPixel >
::GetColor(unsigned int c)
{
  if ( c < m_NumberOfColors )
    {
    return m_Color[c];
    }
  else
    {
    RGBPixel<TPixel> pixel;
    pixel.Set(0, 0, 0);
    return pixel;
    }
}

template< typename TPixel >
TPixel
ColorTable< TPixel >
::GetColorComponent(unsigned int c, char rgb)
{
  if ( c < m_NumberOfColors )
    {
    switch ( rgb )
      {
      case 'r':
        {
        return m_Color[c][0];
        }
      case 'g':
        {
        return m_Color[c][1];
        }
      case 'b':
        {
        return m_Color[c][2];
        }
      default:
        {
        return 0;
        }
      }
    }
  else
    {
    return 0;
    }
}

template< typename TPixel >
std::string
ColorTable< TPixel >
::GetColorName(unsigned int c)
{
  if ( c < m_NumberOfColors )
    {
    return m_ColorName[c];
    }
  else
    {
    return NULL;
    }
}

template< typename TPixel >
unsigned int
ColorTable< TPixel >
::GetClosestColorTableId(TPixel r, TPixel g, TPixel b)
{
  double       match;
  double       bestMatch = 0;
  unsigned int bestMatchColor = 0;

  for ( unsigned int i = 0; i < m_NumberOfColors; i++ )
    {
    match = ( r - (double)m_Color[i].GetRed() )
            * ( r - (double)m_Color[i].GetRed() );
    match += ( g - (double)m_Color[i].GetGreen() )
             * ( g - (double)m_Color[i].GetGreen() );
    match += ( b - (double)m_Color[i].GetGreen() )
             * ( b - (double)m_Color[i].GetBlue() );
    if ( i == 0 || match < bestMatch )
      {
      bestMatch = match;
      bestMatchColor = i;
      }
    }
  return bestMatchColor;
}
} // namespace itk

#endif
<commit_msg>STYLE: 14th Ann Reduce variable scope.<commit_after>/*=========================================================================
 *
 *  Copyright Insight Software Consortium
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0.txt
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 *=========================================================================*/
#ifndef __itkColorTable_hxx
#define __itkColorTable_hxx

#include "itkColorTable.h"
#include "itkNumericTraits.h"
#include "vnl/vnl_sample.h"

#include <sstream>
#include <iomanip>

namespace itk
{
template< typename TPixel >
ColorTable< TPixel >
::ColorTable()
{
  m_NumberOfColors = 0;
}

template< typename TPixel >
void
ColorTable< TPixel >
::DeleteColors()
{
  m_Color.resize(0);
  m_ColorName.resize(0);
}

template< typename TPixel >
void
ColorTable< TPixel >
::PrintSelf(std::ostream & os, Indent indent) const
{
  Superclass::PrintSelf(os, indent);

  os << indent << "NumberOfColors = " << m_NumberOfColors << std::endl;
  for ( unsigned int i = 0; i < m_NumberOfColors; i++ )
    {
    os << indent
       << "ColorName[" << i << "] = " << m_ColorName[i] << ", "
       << "Color[" << i << "] = " << m_Color[i] << std::endl;
    }
}

template< typename TPixel >
void
ColorTable< TPixel >
::UseDiscreteColors(void)
{
  this->DeleteColors();

  m_NumberOfColors = 8;
  m_Color.resize(m_NumberOfColors);
  m_ColorName.resize(m_NumberOfColors);

  typename NumericTraits< TPixel >::RealType scale;
  typename NumericTraits< TPixel >::RealType shift;
  if (NumericTraits<TPixel>::is_integer)
    {
    scale =
      static_cast< typename NumericTraits< TPixel >::RealType>(NumericTraits< TPixel >::max()) -
      static_cast<  typename NumericTraits< TPixel >::RealType>(NumericTraits< TPixel >::NonpositiveMin());
    shift =
      static_cast<  typename NumericTraits< TPixel >::RealType>(NumericTraits< TPixel >::NonpositiveMin());
    }
  else
    {
    scale = NumericTraits< TPixel >::One;
    shift = NumericTraits< TPixel >::Zero;
    }

  m_Color[0].Set((TPixel)(0.9 * scale + shift),
                 (TPixel)(              shift),
                 (TPixel)(              shift) );
  m_ColorName[0] = "Red";

  m_Color[1].Set((TPixel)(0.8 * scale + shift),
                 (TPixel)(              shift),
                 (TPixel)(0.8 * scale + shift));
  m_ColorName[1] = "Purple";

  m_Color[2].Set((TPixel)(              shift),
                 (TPixel)(0.8 * scale + shift),
                 (TPixel)(0.8 * scale + shift));
  m_ColorName[2] = "Aqua";

  m_Color[3].Set((TPixel)(0.8 * scale + shift),
                 (TPixel)(0.8 * scale + shift),
                 (TPixel)(              shift));
  m_ColorName[3] = "Yellow";

  m_Color[4].Set((TPixel)(              shift),
                 (TPixel)(0.9 * scale + shift),
                 (TPixel)(              shift));
  m_ColorName[4] = "Green";

  m_Color[5].Set((TPixel)(              shift),
                 (TPixel)(              shift),
                 (TPixel)(0.9 * scale + shift));
  m_ColorName[5] = "Blue";

  m_Color[6].Set((TPixel)(0.7 * scale + shift),
                 (TPixel)(0.7 * scale + shift),
                 (TPixel)(0.7 * scale + shift));
  m_ColorName[6] = "Grey0.70";
  //
  // to avoid numeric exception, need to make
  // sure that the value assigned is clamped at
  // max for TPixel.  Exceptions were happening
  // on this assignment, even if realMax was
  // set to NumericTraits<TPixel>::max().
  typename NumericTraits< TPixel >::RealType
    realMax(1.0 * scale + shift);
  TPixel pixelMax(NumericTraits< TPixel >::max());
  if(realMax < NumericTraits< TPixel >::max())
    {
    pixelMax = static_cast< TPixel >(realMax);
    }
  m_Color[7].Set(pixelMax,pixelMax,pixelMax);
  m_ColorName[7] = "White";
}

template< typename TPixel >
void
ColorTable< TPixel >
::UseGrayColors(unsigned int n)
{
  unsigned int i;

  this->DeleteColors();

  m_NumberOfColors = n;
  m_Color.resize(m_NumberOfColors);
  m_ColorName.resize(m_NumberOfColors);

  typename NumericTraits< TPixel >::RealType range;
  typename NumericTraits< TPixel >::RealType minimum;
  if (NumericTraits<TPixel>::is_integer)
    {
    range =
      static_cast< typename NumericTraits< TPixel >::RealType>(NumericTraits< TPixel >::max()) -
      static_cast<  typename NumericTraits< TPixel >::RealType>(NumericTraits< TPixel >::NonpositiveMin());
    minimum = NumericTraits< TPixel >::NonpositiveMin();
    }
  else
    {
    range = NumericTraits< TPixel >::One;
    minimum = NumericTraits< TPixel >::Zero;
    }
  typename NumericTraits< TPixel >::RealType delta;
  if (m_NumberOfColors > 1)
    {
    delta = range / ( m_NumberOfColors - 1 );
    }
  else
    {
    delta = 0.0;
    }

  for ( i = 0; i < m_NumberOfColors; i++ )
    {
    typename NumericTraits< TPixel >::RealType
      realGray( minimum + i * delta );

    TPixel gray = NumericTraits< TPixel >::max();
    if( realGray < NumericTraits< TPixel >::max() )
      {
      gray = static_cast< TPixel >(realGray);
      }

    m_Color[i].Set(gray, gray, gray);
    std::ostringstream name;
    name << "Gray" << std::fixed << std::setprecision(2)
         << static_cast<float>(gray);
    m_ColorName[i] = name.str();
    }
}

template< typename TPixel >
void
ColorTable< TPixel >
::UseHeatColors(unsigned int n)
{
  unsigned int i;

  this->DeleteColors();

  m_NumberOfColors = n;
  m_Color.resize(m_NumberOfColors);
  m_ColorName.resize(m_NumberOfColors);

  typename NumericTraits< TPixel >::RealType scale;
  typename NumericTraits< TPixel >::RealType shift;
  if (NumericTraits<TPixel>::is_integer)
    {
    scale =
      static_cast< typename NumericTraits< TPixel >::RealType>(NumericTraits< TPixel >::max()) -
      static_cast<  typename NumericTraits< TPixel >::RealType>(NumericTraits< TPixel >::NonpositiveMin());
    shift =
      static_cast<  typename NumericTraits< TPixel >::RealType>(NumericTraits< TPixel >::NonpositiveMin());
    }
  else
    {
    scale = NumericTraits< TPixel >::One;
    shift = NumericTraits< TPixel >::Zero;
    }
  for ( i = 0; i < n / 2.0; i++ )
    {
    //
    // avoid overflow
    typename NumericTraits < TPixel >::RealType
      realR((( i + 1 ) / ( n / 2.0 + 1 ) ) * scale + shift);
    TPixel r(NumericTraits< TPixel >::max());
    if(realR < NumericTraits< TPixel >::max())
      {
      r = static_cast< TPixel >(realR);
      }
    TPixel g(static_cast<TPixel>( shift));
    TPixel b(static_cast<TPixel>( shift));
    m_Color[i].Set(r,g,b);
    std::ostringstream name;
    name << "Heat" << std::fixed << std::setprecision(2)
         << i / static_cast<float>(n);
    m_ColorName[i] = name.str();
    }

  for ( i = 0; i < n / 2; i++ )
    {
    typename NumericTraits< TPixel >::RealType
      rdouble(1.0 * scale + shift);
    TPixel r(NumericTraits<TPixel>::max());
    if( rdouble < NumericTraits<TPixel>::max() )
      {
      r = static_cast<TPixel>(rdouble);
      }
    TPixel g = static_cast<TPixel>((( i + 1 ) / ( n / 2.0 + 1 )) * scale + shift);
    TPixel b = static_cast<TPixel>((( i + 1 ) / ( n / 2.0 + 1 )) * scale + shift);
    m_Color[(size_t)(i + n / 2.0 )].Set(r,g,b);
    std::ostringstream name;
    name << "Heat" << std::fixed << std::setprecision(2)
         << ( i + n / 2.0 ) / (float)n;
    m_ColorName[static_cast<size_t>(( i + n / 2.0 ))] = name.str();
    }
}

template< typename TPixel >
void
ColorTable< TPixel >
::UseRandomColors(unsigned int n)
{
  unsigned int i;

  this->DeleteColors();

  m_NumberOfColors = n;
  m_Color.resize(m_NumberOfColors);
  m_ColorName.resize(m_NumberOfColors);
  TPixel r, g, b;
  TPixel minimum, maximum;
  if (NumericTraits<TPixel>::is_integer)
    {
    minimum = NumericTraits< TPixel >::NonpositiveMin();
    maximum = NumericTraits< TPixel >::max();
    }
  else
    {
    minimum = NumericTraits< TPixel >::Zero;
    maximum  = NumericTraits< TPixel >::One;
    }
  for ( i = 0; i < n; i++ )
    {
      r = static_cast< TPixel >( vnl_sample_uniform( minimum, maximum));
    m_Color[i][0] = r;
    g = static_cast< TPixel >( vnl_sample_uniform( minimum, maximum));
    m_Color[i][1] = g;
    b = static_cast< TPixel >( vnl_sample_uniform( minimum, maximum));
    m_Color[i][2] = b;
    std::ostringstream name;
    name << "Random(" << std::fixed << std::setprecision(2)
         << static_cast< float >( r ) << ","
         << static_cast< float >( g ) << ","
         << static_cast< float >( b ) << ")";
    m_ColorName[i] = name.str();
    }
}

template< typename TPixel >
bool
ColorTable< TPixel >
::SetColor(unsigned int c, RGBPixel<TPixel> pixel, const char *name)
{
  return this->SetColor(c, pixel[0], pixel[1], pixel[2], name);
}

template< typename TPixel >
bool
ColorTable< TPixel >
::SetColor(unsigned int c, TPixel r, TPixel g, TPixel b, const char *name)
{
  if ( c < m_NumberOfColors )
    {
    m_Color[c][0] = r;
    m_Color[c][1] = g;
    m_Color[c][2] = b;
    m_ColorName[c] = name;
    return true;
    }
  return false;
}

template< typename TPixel >
RGBPixel< TPixel >
ColorTable< TPixel >
::GetColor(unsigned int c)
{
  if ( c < m_NumberOfColors )
    {
    return m_Color[c];
    }
  else
    {
    RGBPixel<TPixel> pixel;
    pixel.Set(0, 0, 0);
    return pixel;
    }
}

template< typename TPixel >
TPixel
ColorTable< TPixel >
::GetColorComponent(unsigned int c, char rgb)
{
  if ( c < m_NumberOfColors )
    {
    switch ( rgb )
      {
      case 'r':
        {
        return m_Color[c][0];
        }
      case 'g':
        {
        return m_Color[c][1];
        }
      case 'b':
        {
        return m_Color[c][2];
        }
      default:
        {
        return 0;
        }
      }
    }
  else
    {
    return 0;
    }
}

template< typename TPixel >
std::string
ColorTable< TPixel >
::GetColorName(unsigned int c)
{
  if ( c < m_NumberOfColors )
    {
    return m_ColorName[c];
    }
  else
    {
    return NULL;
    }
}

template< typename TPixel >
unsigned int
ColorTable< TPixel >
::GetClosestColorTableId(TPixel r, TPixel g, TPixel b)
{
  double       bestMatch = 0.0;
  unsigned int bestMatchColor = 0;

  for ( unsigned int i = 0; i < m_NumberOfColors; i++ )
    {
    double match;
    match = ( r - (double)m_Color[i].GetRed() )
            * ( r - (double)m_Color[i].GetRed() );
    match += ( g - (double)m_Color[i].GetGreen() )
             * ( g - (double)m_Color[i].GetGreen() );
    match += ( b - (double)m_Color[i].GetGreen() )
             * ( b - (double)m_Color[i].GetBlue() );
    if ( i == 0 || match < bestMatch )
      {
      bestMatch = match;
      bestMatchColor = i;
      }
    }
  return bestMatchColor;
}
} // namespace itk

#endif
<|endoftext|>


<commit_before>// For conditions of distribution and use, see copyright notice in license.txt

#include "StableHeaders.h"
#include <Ogre.h>
#include <OgreTextAreaOverlayElement.h>

#include "EC_OgreConsoleOverlay.h"
#include "OgreRenderingModule.h"
#include "Renderer.h"

namespace OgreRenderer
{
    EC_OgreConsoleOverlay::EC_OgreConsoleOverlay(Foundation::ModuleInterface* module) :
        EC_OgreConsoleOverlayInterface(module->GetFramework())
        , overlay_element_(NULL)
        , container_(NULL)
        , overlay_(NULL)
        , renderer_(checked_static_cast<OgreRenderingModule*>(module)->GetRenderer())
        , height_(module->GetFramework()->GetDefaultConfig().DeclareSetting("DebugConsole", "height", 0.4f))
//        , char_height_(0.0175f)
        , char_height_(module->GetFramework()->GetDefaultConfig().DeclareSetting("DebugConsole", "font_height", 0.0175f))
        , visible_(false)
        , max_visible_lines_( height_ / char_height_ * 0.91876f )
        , position_(0)
        , speed_(3.0f)
        , active_(visible_)
    {
        CreateOverlay();
    }

    EC_OgreConsoleOverlay::EC_OgreConsoleOverlay(const EC_OgreConsoleOverlay &other) :
        EC_OgreConsoleOverlayInterface(other)
        , height_(other.height_)
        , char_height_(other.char_height_)
        , max_visible_lines_(other.max_visible_lines_)
        , speed_(3.0f)
    {
        // not meant to be used but still needed, since components are generally meant to be copyable
        assert (false);
    }

    EC_OgreConsoleOverlay::~EC_OgreConsoleOverlay()
    {
        // Funny thing, Ogre manual says not to destroy overlay elements while
        // they are still contained in some Overlay but doing this in any other
        // way seems to cause crashes.
        if (renderer_.expired() == false)
        {
            Ogre::OverlayManager::getSingleton().destroyOverlayElement("ConsoleText");
            Ogre::OverlayManager::getSingleton().destroyOverlayElement("ConsoleContainer");
            Ogre::OverlayManager::getSingleton().destroy("Console");
        }
    }

    void EC_OgreConsoleOverlay::CreateOverlay()
    {
        // Creating second console overlay component is a programming error in any case,
        // so we let Ogre throw exception if that happens.

        if (renderer_.expired())
            return;

        overlay_element_ = checked_static_cast<Ogre::TextAreaOverlayElement*>(Ogre::OverlayManager::getSingleton().createOverlayElement("TextArea", "ConsoleText"));
        overlay_element_->setCaption("Console");
        overlay_element_->setColour(Ogre::ColourValue::Black);
        overlay_element_->setDimensions(0.98f, height_);

        overlay_element_->setPosition(0.01f, 0.01f);
        overlay_element_->setFontName("Console");
        overlay_element_->setCharHeight(char_height_);
        overlay_element_->show();

        overlay_ = Ogre::OverlayManager::getSingleton().create("Console");

        container_ = checked_static_cast<Ogre::OverlayContainer*>(Ogre::OverlayManager::getSingleton().createOverlayElement("Panel", "ConsoleContainer"));
        container_->setPosition(0.f, -height_);
        container_->setDimensions(1.f, height_);
        container_->setMaterialName("Console");
        container_->addChild(overlay_element_);
        container_->show();

        overlay_->add2D(container_);
        if (visible_)
            overlay_->show();
        else
            overlay_->hide();

        overlay_->setZOrder(500);
    }

    void EC_OgreConsoleOverlay::Display(const std::string &text)
    {
        //! \todo render mutex here -cm

        if (renderer_.expired())
            return;
        overlay_element_->setCaption(text);
    }

    void EC_OgreConsoleOverlay::SetVisible(bool visible)
    {
        visible_ = visible;
        if (visible && !renderer_.expired())
            overlay_->show();

        active_ = visible;
    }

    bool EC_OgreConsoleOverlay::IsVisible() const
    {
        if (renderer_.expired())
            return false;

        return overlay_->isVisible();
    }

    void EC_OgreConsoleOverlay::Update(Core::f64 frametime)
    {
        if (renderer_.expired())
            return;

        if (visible_ && position_ < Ogre::Math::HALF_PI)
        {
            position_ += frametime * speed_;
            if (position_ > Ogre::Math::HALF_PI)
                position_ = Ogre::Math::HALF_PI;

            container_->setTop( -height_ + Ogre::Math::Sin(position_) * height_);
        }
        else if (visible_ == false && abs(position_) > 0.001f)
        {
            position_ -= frametime * speed_;
            if (position_ <= 0.f)
            {
                position_ = 0.f;
                overlay_->hide();
            }

            container_->setTop( -height_ + Ogre::Math::Sin(position_) * height_);
        }
    }
}
<commit_msg>Ogre console overlay speed is now defined in configuration file rather than being hardcoded.<commit_after>// For conditions of distribution and use, see copyright notice in license.txt

#include "StableHeaders.h"
#include <Ogre.h>
#include <OgreTextAreaOverlayElement.h>

#include "EC_OgreConsoleOverlay.h"
#include "OgreRenderingModule.h"
#include "Renderer.h"

namespace OgreRenderer
{
    EC_OgreConsoleOverlay::EC_OgreConsoleOverlay(Foundation::ModuleInterface* module) :
        EC_OgreConsoleOverlayInterface(module->GetFramework())
        , overlay_element_(NULL)
        , container_(NULL)
        , overlay_(NULL)
        , renderer_(checked_static_cast<OgreRenderingModule*>(module)->GetRenderer())
        , height_(module->GetFramework()->GetDefaultConfig().DeclareSetting("DebugConsole", "height", 0.4f))
//        , char_height_(0.0175f)
        , char_height_(module->GetFramework()->GetDefaultConfig().DeclareSetting("DebugConsole", "font_height", 0.0175f))
        , visible_(false)
        , max_visible_lines_( height_ / char_height_ * 0.91876f )
        , position_(0)
        , speed_(module->GetFramework()->GetDefaultConfig().DeclareSetting("DebugConsole", "appear_speed", 3.0f))
        , active_(visible_)
    {
        CreateOverlay();
    }

    EC_OgreConsoleOverlay::EC_OgreConsoleOverlay(const EC_OgreConsoleOverlay &other) :
        EC_OgreConsoleOverlayInterface(other)
        , height_(other.height_)
        , char_height_(other.char_height_)
        , max_visible_lines_(other.max_visible_lines_)
        , speed_(3.0f)
    {
        // not meant to be used but still needed, since components are generally meant to be copyable
        assert (false);
    }

    EC_OgreConsoleOverlay::~EC_OgreConsoleOverlay()
    {
        // Funny thing, Ogre manual says not to destroy overlay elements while
        // they are still contained in some Overlay but doing this in any other
        // way seems to cause crashes.
        if (renderer_.expired() == false)
        {
            Ogre::OverlayManager::getSingleton().destroyOverlayElement("ConsoleText");
            Ogre::OverlayManager::getSingleton().destroyOverlayElement("ConsoleContainer");
            Ogre::OverlayManager::getSingleton().destroy("Console");
        }
    }

    void EC_OgreConsoleOverlay::CreateOverlay()
    {
        // Creating second console overlay component is a programming error in any case,
        // so we let Ogre throw exception if that happens.

        if (renderer_.expired())
            return;

        overlay_element_ = checked_static_cast<Ogre::TextAreaOverlayElement*>(Ogre::OverlayManager::getSingleton().createOverlayElement("TextArea", "ConsoleText"));
        overlay_element_->setCaption("Console");
        overlay_element_->setColour(Ogre::ColourValue::Black);
        overlay_element_->setDimensions(0.98f, height_);

        overlay_element_->setPosition(0.01f, 0.01f);
        overlay_element_->setFontName("Console");
        overlay_element_->setCharHeight(char_height_);
        overlay_element_->show();

        overlay_ = Ogre::OverlayManager::getSingleton().create("Console");

        container_ = checked_static_cast<Ogre::OverlayContainer*>(Ogre::OverlayManager::getSingleton().createOverlayElement("Panel", "ConsoleContainer"));
        container_->setPosition(0.f, -height_);
        container_->setDimensions(1.f, height_);
        container_->setMaterialName("Console");
        container_->addChild(overlay_element_);
        container_->show();

        overlay_->add2D(container_);
        if (visible_)
            overlay_->show();
        else
            overlay_->hide();

        overlay_->setZOrder(500);
    }

    void EC_OgreConsoleOverlay::Display(const std::string &text)
    {
        //! \todo render mutex here -cm

        if (renderer_.expired())
            return;
        overlay_element_->setCaption(text);
    }

    void EC_OgreConsoleOverlay::SetVisible(bool visible)
    {
        visible_ = visible;
        if (visible && !renderer_.expired())
            overlay_->show();

        active_ = visible;
    }

    bool EC_OgreConsoleOverlay::IsVisible() const
    {
        if (renderer_.expired())
            return false;

        return overlay_->isVisible();
    }

    void EC_OgreConsoleOverlay::Update(Core::f64 frametime)
    {
        if (renderer_.expired())
            return;

        if (visible_ && position_ < Ogre::Math::HALF_PI)
        {
            position_ += frametime * speed_;
            if (position_ > Ogre::Math::HALF_PI)
                position_ = Ogre::Math::HALF_PI;

            container_->setTop( -height_ + Ogre::Math::Sin(position_) * height_);
        }
        else if (visible_ == false && abs(position_) > 0.001f)
        {
            position_ -= frametime * speed_;
            if (position_ <= 0.f)
            {
                position_ = 0.f;
                overlay_->hide();
            }

            container_->setTop( -height_ + Ogre::Math::Sin(position_) * height_);
        }
    }
}
<|endoftext|>


<commit_before>#include <OpenSim/OpenSim.h>

namespace OpenSim {

class ComponentContainer : public ModelComponent {
    OpenSim_DECLARE_CONCRETE_OBJECT(ComponentContainer, Component);

public:
    OpenSim_DECLARE_LIST_PROPERTY(components, Component,
                                  "List of serialized internal components");

    ComponentContainer() {
        constructInfrastructure();
    }

    void adopt(Component* comp) {
        // add it the property list of components that owns and serializes them
        updProperty_components().adoptAndAppendValue(comp);
        finalizeFromProperties();
    }

private:
    void constructProperties() override {
        constructProperty_components();
    }
};

/**
 * This produces a control signal k * a, where `k` is the gain property, and
 * `a` is the activation input. This is intended to model proportional
 * myoelectric device controllers. This Controller can control any
 * ScalarActuator. The ScalarActuator that this control controls is set using
 * the `device` connector.
 *
 * http://en.wikipedia.org/wiki/Proportional_Myoelectric_Control
 */
class PropMyoController : public OpenSim::Controller {
    OpenSim_DECLARE_CONCRETE_OBJECT(PropMyoController, OpenSim::Controller);
public:
    OpenSim_DECLARE_PROPERTY(gain, double,
                             "Gain used in converting muscle activation into a"
                             " control signal (units depend on the device)");

    PropMyoController() {
        constructInfrastructure();
    }

    void computeControls(const SimTK::State& s,
                         SimTK::Vector& controls) const override {
        double activation = getInputValue<double>(s, "activation");

        // Compute the control signal.
        double signal = get_gain() * activation;

        // Add in this control signal to controls.
        const auto& device = getConnectee<Actuator>("device");
        SimTK::Vector thisActuatorsControls(1, signal);
        device.addInControls(thisActuatorsControls, controls);
    }

private:

    void constructProperties() override {
        constructProperty_gain(1.0);
    }

    void constructConnectors() override {
        // The ScalarActuator for which we're computing a control signal.
        constructConnector<Actuator>("device");
    }

    void constructInputs() override {
        // The control signal is proportional to this input.
        constructInput<double>("activation", SimTK::Stage::Model);
    }

    void constructOutputs() override {
        constructOutput<double>("constant",
                                [] (const SimTK::State&) {
                                    return 2;},
                                SimTK::Stage::Model);
    }
};

} // namespace OpenSim

int main() {
    using SimTK::Vec3;
    using SimTK::Inertia;
    using SimTK::Pi;

    // Create a sphere geometry to reuse later.
    OpenSim::Sphere sphere{0.1};
    sphere.setName("sphere");

    // Create the device to hold the components.
    //-------------------------------------------------------------------------
    auto device = new OpenSim::ComponentContainer{};
    device->setName("device");

    // Two body(s), with mass of 1 kg, center of mass at the
    // origin of their respective frames, and moments/products of inertia of
    // zero.
    auto massA   = new OpenSim::Body("massA",    1, Vec3(0), Inertia(1));
    auto massB   = new OpenSim::Body("massB",    1, Vec3(0), Inertia(1));
    // Add the masses to the device.
    device->adopt(massA);
    device->adopt(massB);

    // Sphere geometry for the masses.
    sphere.setFrameName("massA");
    massA->append_geometry(sphere);
    sphere.setFrameName("massB");
    massB->append_geometry(sphere);

    // Joint from something in the environment to massA.
    auto anchorA = new OpenSim::WeldJoint();
    anchorA->setName("anchorA");
    // Set only the child now. Parent will be in the environment.
    anchorA->setChildFrameName("massA");
    device->adopt(anchorA);

    // Joint from something in the environment to massB.
    auto anchorB = new OpenSim::WeldJoint();
    anchorB->setName("anchorB");
    // Set only the child now. Parent will be in the environment.
    anchorB->setChildFrameName("massB");
    device->adopt(anchorB);

    // Actuator connecting the two masses.
    auto pathActuator = new OpenSim::PathActuator();
    pathActuator->setName("cableAtoB");
    pathActuator->addNewPathPoint("point1", *massA, Vec3(0));
    pathActuator->addNewPathPoint("point2", *massB, Vec3(0));
    device->adopt(pathActuator);

    // A controller that specifies the excitation of the biceps muscle.
    auto controller = new OpenSim::PropMyoController();
    controller->setName("controller");
    controller->getInput("activation").
                connect(controller->getOutput("constant"));
    controller->updConnector<OpenSim::Actuator>("device").
                connect(*pathActuator);
    device->adopt(controller);

    // Build a test environment for the device.
    //-------------------------------------------------------------------------
    OpenSim::Model model;
    model.setUseVisualizer(true);
    model.setGravity(Vec3(0));

    // Create a load of mass 10kg.
    auto load = new OpenSim::Body("load", 10, Vec3(0), Inertia(1));
    // Set properties of the sphere geometry to be used for the load.
    sphere.setFrameName("load");
    sphere.set_radius(0.2);
    sphere.setOpacity(0.5);
    sphere.setColor(Vec3{0, 0, 1});
    load->append_geometry(sphere);
    model.addBody(load);

    auto grndToLoad = new OpenSim::FreeJoint("grndToLoad", "ground", "load");
    // Set the location of the load to (1, 0, 0).
    grndToLoad->getCoordinateSet()[3].setDefaultValue(1);
    model.addJoint(grndToLoad);

    // Connect device to/from the environment.
    //-------------------------------------------------------------------------
    // Set parent of anchorA as ground.
    anchorA->setParentFrameName("ground");
    // Set parent of anchorB as load.
    anchorB->setParentFrameName("load");

    // Add bodies and joints to the model.
    model.addModelComponent(device);

    // Print the model.
    model.print("exampleHopperDevice.xml");

    // Configure the model.
    auto& state = model.initSystem();

    // Add display geometry.
    model.updMatterSubsystem().setShowDefaultGeometry(true);
    auto& viz = model.updVisualizer().updSimbodyVisualizer();

    // Simulate.
    SimTK::RungeKuttaMersonIntegrator integrator(model.getSystem());
    OpenSim::Manager manager(model, integrator);
    manager.setInitialTime(0);
    manager.setFinalTime(10.0);
    manager.integrate(state);
};
<commit_msg>Segrate calls into simulate method.<commit_after>#include <OpenSim/OpenSim.h>

namespace OpenSim {

class ComponentContainer : public ModelComponent {
    OpenSim_DECLARE_CONCRETE_OBJECT(ComponentContainer, Component);

public:
    OpenSim_DECLARE_LIST_PROPERTY(components, Component,
                                  "List of serialized internal components");

    ComponentContainer() {
        constructInfrastructure();
    }

    void adopt(Component* comp) {
        // add it the property list of components that owns and serializes them
        updProperty_components().adoptAndAppendValue(comp);
        finalizeFromProperties();
    }

private:
    void constructProperties() override {
        constructProperty_components();
    }
};

/**
 * This produces a control signal k * a, where `k` is the gain property, and
 * `a` is the activation input. This is intended to model proportional
 * myoelectric device controllers. This Controller can control any
 * ScalarActuator. The ScalarActuator that this control controls is set using
 * the `device` connector.
 *
 * http://en.wikipedia.org/wiki/Proportional_Myoelectric_Control
 */
class PropMyoController : public OpenSim::Controller {
    OpenSim_DECLARE_CONCRETE_OBJECT(PropMyoController, OpenSim::Controller);
public:
    OpenSim_DECLARE_PROPERTY(gain, double,
                             "Gain used in converting muscle activation into a"
                             " control signal (units depend on the device)");

    PropMyoController() {
        constructInfrastructure();
    }

    void computeControls(const SimTK::State& s,
                         SimTK::Vector& controls) const override {
        double activation = getInputValue<double>(s, "activation");

        // Compute the control signal.
        double signal = get_gain() * activation;

        // Add in this control signal to controls.
        const auto& device = getConnectee<Actuator>("device");
        SimTK::Vector thisActuatorsControls(1, signal);
        device.addInControls(thisActuatorsControls, controls);
    }

private:

    void constructProperties() override {
        constructProperty_gain(1.0);
    }

    void constructConnectors() override {
        // The ScalarActuator for which we're computing a control signal.
        constructConnector<Actuator>("device");
    }

    void constructInputs() override {
        // The control signal is proportional to this input.
        constructInput<double>("activation", SimTK::Stage::Model);
    }

    void constructOutputs() override {
        constructOutput<double>("constant",
                                [] (const SimTK::State&) {
                                    return 2;},
                                SimTK::Stage::Model);
    }
};

} // namespace OpenSim

void simulate(OpenSim::Model& model) {
    // Configure the model.
    auto& state = model.initSystem();

    model.updMatterSubsystem().setShowDefaultGeometry(true);

    // Simulate.
    SimTK::RungeKuttaMersonIntegrator integrator(model.getSystem());
    OpenSim::Manager manager(model, integrator);
    manager.setInitialTime(0);
    manager.setFinalTime(10.0);
    manager.integrate(state);
}

int main() {
    using SimTK::Vec3;
    using SimTK::Inertia;
    using SimTK::Pi;

    // Create a sphere geometry to reuse later.
    OpenSim::Sphere sphere{0.1};
    sphere.setName("sphere");

    // Create the device to hold the components.
    //-------------------------------------------------------------------------
    auto device = new OpenSim::ComponentContainer{};
    device->setName("device");

    // Two body(s), with mass of 1 kg, center of mass at the
    // origin of their respective frames, and moments/products of inertia of
    // zero.
    auto massA   = new OpenSim::Body("massA",    1, Vec3(0), Inertia(1));
    auto massB   = new OpenSim::Body("massB",    1, Vec3(0), Inertia(1));
    // Add the masses to the device.
    device->adopt(massA);
    device->adopt(massB);

    // Sphere geometry for the masses.
    sphere.setFrameName("massA");
    massA->append_geometry(sphere);
    sphere.setFrameName("massB");
    massB->append_geometry(sphere);

    // Joint from something in the environment to massA.
    auto anchorA = new OpenSim::WeldJoint();
    anchorA->setName("anchorA");
    // Set only the child now. Parent will be in the environment.
    anchorA->setChildFrameName("massA");
    device->adopt(anchorA);

    // Joint from something in the environment to massB.
    auto anchorB = new OpenSim::WeldJoint();
    anchorB->setName("anchorB");
    // Set only the child now. Parent will be in the environment.
    anchorB->setChildFrameName("massB");
    device->adopt(anchorB);

    // Actuator connecting the two masses.
    auto pathActuator = new OpenSim::PathActuator();
    pathActuator->setName("cableAtoB");
    pathActuator->addNewPathPoint("point1", *massA, Vec3(0));
    pathActuator->addNewPathPoint("point2", *massB, Vec3(0));
    device->adopt(pathActuator);

    // A controller that specifies the excitation of the biceps muscle.
    auto controller = new OpenSim::PropMyoController();
    controller->setName("controller");
    controller->getInput("activation").
                connect(controller->getOutput("constant"));
    controller->updConnector<OpenSim::Actuator>("device").
                connect(*pathActuator);
    device->adopt(controller);

    // Build a test environment for the device.
    //-------------------------------------------------------------------------
    OpenSim::Model testBed;
    testBed.setUseVisualizer(true);
    testBed.setGravity(Vec3(0));

    // Create a load of mass 10kg.
    auto load = new OpenSim::Body("load", 10, Vec3(0), Inertia(1));
    // Set properties of the sphere geometry to be used for the load.
    sphere.setFrameName("load");
    sphere.set_radius(0.2);
    sphere.setOpacity(0.5);
    sphere.setColor(Vec3{0, 0, 1});
    load->append_geometry(sphere);
    testBed.addBody(load);

    auto grndToLoad = new OpenSim::FreeJoint("grndToLoad", "ground", "load");
    // Set the location of the load to (1, 0, 0).
    grndToLoad->getCoordinateSet()[3].setDefaultValue(1);
    testBed.addJoint(grndToLoad);

    // Connect device to/from the environment.
    //-------------------------------------------------------------------------
    // Set parent of anchorA as ground.
    anchorA->setParentFrameName("ground");
    // Set parent of anchorB as load.
    anchorB->setParentFrameName("load");

    // Add bodies and joints to the testBed.
    testBed.addModelComponent(device);

    // Print the testBed.
    testBed.print("exampleHopperDevice.xml");

    simulate(testBed);
};
<|endoftext|>


<commit_before><commit_msg>Storytelling: Retire notification as we have customized UI now.<commit_after><|endoftext|>


<commit_before>
#include "pch.h"
#include "slackapp.h"
#include "utils.h"

using namespace utility;              // Common utilities like string conversions
using namespace web;                  // Common features like URIs.
using namespace web::http;            // Common HTTP functionality
using namespace web::http::client;    // HTTP client features
using namespace concurrency::streams; // Asynchronous streams

//web::http::client::http_client::~http_client() noexcept {}

pplx::task<bool> slack_app::test_access_token(const string_t &access_token)
{
    printf("authing\n");
    auto path = U("auth.test?token=") + access_token;

    return _client.request(methods::POST, path)
        .then([=](http_response response) {
        return response.extract_json();
    })
        .then([=](json::value json) {
        return json.as_object()
            .at(U("ok"))
            .as_bool();
    });
}

pplx::task<utility::string_t> slack_app::get_userid(const string_t &access_token)
{
    auto path = U("auth.test?token=") + access_token;

    return _client.request(methods::POST, path)
        .then([=](http_response response) {
        return response.extract_json();
    })
        .then([=](json::value json) {
        return json.as_object()
            .at(U("user_id"))
            .as_string();
    });
}

pplx::task<web::uri> slack_app::get_ws_url()
{
    auto path = U("rtm.connect?token=") + _bot_access_token;

    return _client.request(methods::POST, path)
        .then([=](http_response response) {
        return response.extract_json();
    })
        .then([=](json::value json) {
        auto obj = json.as_object();
        auto isok = obj.at(U("ok")).as_bool();

        if (isok)
        {
            auto url = obj.at(U("url")).as_string();
            return web::uri{ url };
        }
        else
        {
            throw std::runtime_error(N(obj.at(U("error")).as_string()));
        }
    });
}

pplx::task<void> slack_app::verify_access_tokens()
{
    printf("verifying\n");
    std::array<pplx::task<bool>, 2> tasks
    {
        test_access_token(_access_token),
        test_access_token(_bot_access_token)
    };

    pplx::task<void> combined = pplx::when_all(std::begin(tasks), std::end(tasks))
        .then([](std::vector<bool> results) {
        printf("checking\n");
        auto at_ok = results[0];
        auto bat_ok = results[1];
        if (!at_ok || !bat_ok)
        {
            std::string messages("Could not authenticate");

            if (!at_ok)
            {
                messages += "\n  Problem with access token";
            }
            if (!bat_ok)
            {
                messages += "\n  Problem with bot access token";
            }

            throw std::runtime_error(messages);
        }
    });

    return combined;
}

pplx::task<void> slack_app::listen()
{
    pplx::task_completion_event<void> tce;
    pplx::task<void> completed(tce);

    return async_do_while([=]() {
        return _rtm_client.receive().then([=](web::websockets::client::websocket_incoming_message in_msg) {

            return in_msg.extract_string().then([=](std::string msg_str) {

                string_t msg_str_t = W(msg_str);
                json::value json_val = json::value::parse(msg_str_t);
                handle_message(json_val);
            });

        }).then([=](pplx::task<void> end_task) {
            try
            {
                end_task.get();
                return true;
            }
            catch (std::exception &e)
            {
                printf("ws error: %s\n", e.what());
            }
            catch (...)
            {
                printf("unkown error\n");
            }

            // We are here means we encountered some exception.
            // Return false to break the asynchronous loop.

            return false;
        });
    });
}

pplx::task<void> slack_app::handle_message(web::json::value message)
{
    printf("message:\n%s\n", N(message.serialize()).c_str());
    auto vtype = message[U("type")];
    auto vreply = message[U("reply_to")];

    if(vtype.is_string())
    {
        auto type = message[U("type")].as_string();

        if (type == U("hello"))
        {
            printf("received hello message\n");
        }
        else if (type == U("reconnect_url"))
        {
            auto new_url = message[U("url")].as_string();
            _rtm_url = new_url;

            printf("received new connect URL\n");
        }
        else if (type == U("message"))
        {
            auto text = message[U("text")].as_string();
            auto channel = message[U("channel")].as_string();
            auto from = message[U("user")].as_string();

            printf("got message: %s from %s\n", N(text).c_str(), N(from).c_str());

            if(from != _bot_userid)
            {
                auto emojis = get_emojis_in_message(N(text));

                sequential_transform(emojis.begin(), emojis.end(),
                    [=] (std::string p) -> pplx::task<std::pair<std::string, std::string>>
                {
                    return get_emoji_url(p).then([=](std::string url)
                    {
                        return std::make_pair(p, url);
                    });
                })
                .then([=] (std::vector<std::pair<std::string, std::string>> urls) {
                    std::string replymsg;

                    if (urls.size())
                    {
                        replymsg = "you specified these emojis: \n";
                        for (auto&pair : urls)
                        {
                            std::string url;
                            if(pair.second.empty())
                            {
                                url = ":question:";
                            }
                            else
                            {
                                url = pair.second;
                            }

                            replymsg += "  " + pair.first + " -> " + url + "\n";
                        }
                    }
                    else
                    {
                        replymsg = "you did not specify any emojis";
                    }

                    return send_message(W(replymsg), channel);
                });
            }
        }
        else if (type == U("presence_change") || type == U("desktop_notification"))
        {

        }
        else
        {

        }
    }
    else if(vreply.is_number())
    {

    }

    return pplx::task_from_result();
}

pplx::task<void> slack_app::send_message(const utility::string_t &text, const utility::string_t &channel)
{
    auto obj = json::value::object();
    obj[U("id")] = json::value::number(++_messageid);
    obj[U("type")] = json::value::string(U("message"));
    obj[U("channel")] = json::value::string(channel);
    obj[U("text")] = json::value::string(text);

    websockets::client::websocket_outgoing_message message;
    message.set_utf8_message(N(obj.serialize()));

    return _rtm_client.send(message);
}

static std::regex rx_emoji(":([-a-zA-Z0-9_+]+):");
std::vector<std::string> slack_app::get_emojis_in_message(const std::string &s) const
{
    std::vector<std::string> result;
    auto emojis_begin = std::sregex_iterator(s.begin(), s.end(), rx_emoji);
    auto emojis_end = std::sregex_iterator();

    for (std::sregex_iterator i = emojis_begin; i != emojis_end; ++i)
    {
        std::smatch match = *i;
        std::string match_str = match.str(1);
        result.push_back(match_str);
    }

    std::sort(result.begin(), result.end());
    auto last = std::unique(result.begin(), result.end());
    result.erase(last, result.end());

    return result;
}

pplx::task<std::map<std::string, std::string>> slack_app::get_custom_emojis()
{
    auto path = U("emoji.list?token=") + _access_token;

    return _client.request(methods::POST, path)
        .then([=](http_response response) {
        return response.extract_json();
    }).then([=](json::value json) {
        std::map<std::string, std::string> obj_emoji;
        auto emojis = json[U("emoji")].as_object();

        for(auto i = emojis.begin(); i != emojis.end(); ++i)
        {
            auto kvp = *i;
            auto key = N(kvp.first);
            auto val = N(kvp.second.as_string());

            obj_emoji[key] = val;
        }

        return obj_emoji;
    });
}

pplx::task<void> slack_app::process_loop()
{
    pplx::task<void> at_verified
    {
        _access_ok ? pplx::task_from_result() : verify_access_tokens()
    };

    // the task will resolve on disconnect
    return at_verified.then([=] {
        if(_bot_userid.empty())
        {
            return get_userid(_bot_access_token).then([=](string_t userid) {
                printf("my user id: %s\n", N(userid).c_str());
                _bot_userid = userid;
            });
        }
        else
        {
            return pplx::task_from_result();
        }
    }).then([=] {
        _access_ok = true;
        printf("verified\n");

        //get url
        if(_rtm_url.is_empty())
        {
            return get_ws_url().then([=](web::uri wsurl) {
                printf("got ws url\n");
                _rtm_url = wsurl;
            });
        }
        else
        {
            return pplx::task_from_result();
        }

    }).then([=] {

        //get emojis
        return get_custom_emojis().then([=](std::map<std::string, std::string> emojis) {
            for(auto &i : emojis)
            {
                _emojis.insert_or_assign(i.first, i.second);
            }
        });
    }).then([=] {

        //connect
        return _rtm_client.connect(_rtm_url);
    }).then([this](pplx::task<void> task) {

        try
        {
            task.get();
            printf("connected.\n");
        }
        catch (...)
        {
            printf("connection error.\n");

            // force re-getting url
            _rtm_url = U("");
            _access_ok = false;

            return pplx::task_from_result();
        }

        return listen();
    }).then([] {
        printf("listen over\n");
    });
}

pplx::task<const void*> slack_app::get_emoji_data(const std::string &emoji)
{
    return pplx::task_from_result<const void*>(nullptr);
}

pplx::task<std::string> slack_app::get_emoji_url(const std::string &emoji)
{
    //try cached emoji
    auto found = _emojis.find(emoji);
    if(found != _emojis.end())
    {
        return pplx::task_from_result(found->second);
    }
    else
    {
        //get emojis again
        return get_custom_emojis().then([this,emoji](std::map<std::string, std::string> emojis) {

            // cache new custom emojis
            for (auto &i : emojis)
            {
                _emojis.insert_or_assign(i.first, i.second);
            }

            // find from custom emojis
            auto found2 = _emojis.find(emoji);
            if (found2 != _emojis.end())
            {
                return found2->second;
            }
            else
            {
                return std::string();
            }
        });
    }
}

void slack_app::run()
{
    printf("enteing\n");

    auto task = async_do_while([=] {
        return process_loop().then([=] {
            return true;
        });
    });

    task.wait();

}<commit_msg>Fixed a problem where modifying past messages cause a crash<commit_after>
#include "pch.h"
#include "slackapp.h"
#include "utils.h"

using namespace utility;              // Common utilities like string conversions
using namespace web;                  // Common features like URIs.
using namespace web::http;            // Common HTTP functionality
using namespace web::http::client;    // HTTP client features
using namespace concurrency::streams; // Asynchronous streams

//web::http::client::http_client::~http_client() noexcept {}

pplx::task<bool> slack_app::test_access_token(const string_t &access_token)
{
    printf("authing\n");
    auto path = U("auth.test?token=") + access_token;

    return _client.request(methods::POST, path)
        .then([=](http_response response) {
        return response.extract_json();
    })
        .then([=](json::value json) {
        return json.as_object()
            .at(U("ok"))
            .as_bool();
    });
}

pplx::task<utility::string_t> slack_app::get_userid(const string_t &access_token)
{
    auto path = U("auth.test?token=") + access_token;

    return _client.request(methods::POST, path)
        .then([=](http_response response) {
        return response.extract_json();
    })
        .then([=](json::value json) {
        return json.as_object()
            .at(U("user_id"))
            .as_string();
    });
}

pplx::task<web::uri> slack_app::get_ws_url()
{
    auto path = U("rtm.connect?token=") + _bot_access_token;

    return _client.request(methods::POST, path)
        .then([=](http_response response) {
        return response.extract_json();
    })
        .then([=](json::value json) {
        auto obj = json.as_object();
        auto isok = obj.at(U("ok")).as_bool();

        if (isok)
        {
            auto url = obj.at(U("url")).as_string();
            return web::uri{ url };
        }
        else
        {
            throw std::runtime_error(N(obj.at(U("error")).as_string()));
        }
    });
}

pplx::task<void> slack_app::verify_access_tokens()
{
    printf("verifying\n");
    std::array<pplx::task<bool>, 2> tasks
    {
        test_access_token(_access_token),
        test_access_token(_bot_access_token)
    };

    pplx::task<void> combined = pplx::when_all(std::begin(tasks), std::end(tasks))
        .then([](std::vector<bool> results) {
        printf("checking\n");
        auto at_ok = results[0];
        auto bat_ok = results[1];
        if (!at_ok || !bat_ok)
        {
            std::string messages("Could not authenticate");

            if (!at_ok)
            {
                messages += "\n  Problem with access token";
            }
            if (!bat_ok)
            {
                messages += "\n  Problem with bot access token";
            }

            throw std::runtime_error(messages);
        }
    });

    return combined;
}

pplx::task<void> slack_app::listen()
{
    pplx::task_completion_event<void> tce;
    pplx::task<void> completed(tce);

    return async_do_while([=]() {
        return _rtm_client.receive().then([=](web::websockets::client::websocket_incoming_message in_msg) {

            return in_msg.extract_string().then([=](std::string msg_str) {

                string_t msg_str_t = W(msg_str);
                json::value json_val = json::value::parse(msg_str_t);
                handle_message(json_val);
            });

        }).then([=](pplx::task<void> end_task) {
            try
            {
                end_task.get();
                return true;
            }
            catch (std::exception &e)
            {
                printf("ws error: %s\n", e.what());
            }
            catch (...)
            {
                printf("unkown error\n");
            }

            // We are here means we encountered some exception.
            // Return false to break the asynchronous loop.

            return false;
        });
    });
}

pplx::task<void> slack_app::handle_message(web::json::value message)
{
    printf("message:\n%s\n", N(message.serialize()).c_str());
    auto vtype = message[U("type")];
    auto vreply = message[U("reply_to")];

    if(vtype.is_string())
    {
        auto type = message[U("type")].as_string();

        if (type == U("hello"))
        {
            printf("received hello message\n");
        }
        else if (type == U("reconnect_url"))
        {
            auto new_url = message[U("url")].as_string();
            _rtm_url = new_url;

            printf("received new connect URL\n");
        }
        else if (type == U("message"))
        {
            auto text = message[U("text")];
            std::string stext;
            if(text.is_string() && !(stext = N(text.as_string())).empty())
            {
                auto channel = message[U("channel")].as_string();
                auto from = message[U("user")].as_string();

                printf("got message: %s from %s\n", stext.c_str(), N(from).c_str());

                if(from != _bot_userid)
                {
                    auto emojis = get_emojis_in_message(stext);

                    sequential_transform(emojis.begin(), emojis.end(),
                        [=] (std::string p) -> pplx::task<std::pair<std::string, std::string>>
                    {
                        return get_emoji_url(p).then([=](std::string url)
                        {
                            return std::make_pair(p, url);
                        });
                    })
                    .then([=] (std::vector<std::pair<std::string, std::string>> urls) {
                        std::string replymsg;

                        if (urls.size())
                        {
                            replymsg = "you specified these emojis: \n";
                            for (auto&pair : urls)
                            {
                                std::string url;
                                if(pair.second.empty())
                                {
                                    url = ":question:";
                                }
                                else
                                {
                                    url = pair.second;
                                }

                                replymsg += "  " + pair.first + " -> " + url + "\n";
                            }
                        }
                        else
                        {
                            replymsg = "you did not specify any emojis";
                        }

                        return send_message(W(replymsg), channel);
                    });
                }
            }
        }
        else if (type == U("presence_change") || type == U("desktop_notification"))
        {

        }
        else
        {

        }
    }
    else if(vreply.is_number())
    {

    }

    return pplx::task_from_result();
}

pplx::task<void> slack_app::send_message(const utility::string_t &text, const utility::string_t &channel)
{
    auto obj = json::value::object();
    obj[U("id")] = json::value::number(++_messageid);
    obj[U("type")] = json::value::string(U("message"));
    obj[U("channel")] = json::value::string(channel);
    obj[U("text")] = json::value::string(text);

    websockets::client::websocket_outgoing_message message;
    message.set_utf8_message(N(obj.serialize()));

    return _rtm_client.send(message);
}

static std::regex rx_emoji(":([-a-zA-Z0-9_+]+):");
std::vector<std::string> slack_app::get_emojis_in_message(const std::string &s) const
{
    std::vector<std::string> result;
    auto emojis_begin = std::sregex_iterator(s.begin(), s.end(), rx_emoji);
    auto emojis_end = std::sregex_iterator();

    for (std::sregex_iterator i = emojis_begin; i != emojis_end; ++i)
    {
        std::smatch match = *i;
        std::string match_str = match.str(1);
        result.push_back(match_str);
    }

    std::sort(result.begin(), result.end());
    auto last = std::unique(result.begin(), result.end());
    result.erase(last, result.end());

    return result;
}

pplx::task<std::map<std::string, std::string>> slack_app::get_custom_emojis()
{
    auto path = U("emoji.list?token=") + _access_token;

    return _client.request(methods::POST, path)
        .then([=](http_response response) {
        return response.extract_json();
    }).then([=](json::value json) {
        std::map<std::string, std::string> obj_emoji;
        auto emojis = json[U("emoji")].as_object();

        for(auto i = emojis.begin(); i != emojis.end(); ++i)
        {
            auto kvp = *i;
            auto key = N(kvp.first);
            auto val = N(kvp.second.as_string());

            obj_emoji[key] = val;
        }

        return obj_emoji;
    });
}

pplx::task<void> slack_app::process_loop()
{
    pplx::task<void> at_verified
    {
        _access_ok ? pplx::task_from_result() : verify_access_tokens()
    };

    // the task will resolve on disconnect
    return at_verified.then([=] {
        if(_bot_userid.empty())
        {
            return get_userid(_bot_access_token).then([=](string_t userid) {
                printf("my user id: %s\n", N(userid).c_str());
                _bot_userid = userid;
            });
        }
        else
        {
            return pplx::task_from_result();
        }
    }).then([=] {
        _access_ok = true;
        printf("verified\n");

        //get url
        if(_rtm_url.is_empty())
        {
            return get_ws_url().then([=](web::uri wsurl) {
                printf("got ws url\n");
                _rtm_url = wsurl;
            });
        }
        else
        {
            return pplx::task_from_result();
        }

    }).then([=] {

        //get emojis
        return get_custom_emojis().then([=](std::map<std::string, std::string> emojis) {
            for(auto &i : emojis)
            {
                _emojis.insert_or_assign(i.first, i.second);
            }
        });
    }).then([=] {

        //connect
        return _rtm_client.connect(_rtm_url);
    }).then([this](pplx::task<void> task) {

        try
        {
            task.get();
            printf("connected.\n");
        }
        catch (...)
        {
            printf("connection error.\n");

            // force re-getting url
            _rtm_url = U("");
            _access_ok = false;

            return pplx::task_from_result();
        }

        return listen();
    }).then([] {
        printf("listen over\n");
    });
}

pplx::task<const void*> slack_app::get_emoji_data(const std::string &emoji)
{
    return pplx::task_from_result<const void*>(nullptr);
}

pplx::task<std::string> slack_app::get_emoji_url(const std::string &emoji)
{
    //try cached emoji
    auto found = _emojis.find(emoji);
    if(found != _emojis.end())
    {
        return pplx::task_from_result(found->second);
    }
    else
    {
        //get emojis again
        return get_custom_emojis().then([this,emoji](std::map<std::string, std::string> emojis) {

            // cache new custom emojis
            for (auto &i : emojis)
            {
                _emojis.insert_or_assign(i.first, i.second);
            }

            // find from custom emojis
            auto found2 = _emojis.find(emoji);
            if (found2 != _emojis.end())
            {
                return found2->second;
            }
            else
            {
                return std::string();
            }
        });
    }
}

void slack_app::run()
{
    printf("enteing\n");

    auto task = async_do_while([=] {
        return process_loop().then([=] {
            return true;
        });
    });

    task.wait();

}<|endoftext|>


<commit_before>/*===================================================================

The Medical Imaging Interaction Toolkit (MITK)

Coindex[1]right (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 "itkTractDensityImageFilter.h"

// VTK
#include <vtkPolyLine.h>
#include <vtkCellArray.h>
#include <vtkCellData.h>

// misc
#include <math.h>
#include <boost/progress.hpp>

namespace itk{

template< class OutputImageType >
TractDensityImageFilter< OutputImageType >::TractDensityImageFilter()
    : m_InvertImage(false)
    , m_FiberBundle(NULL)
    , m_UpsamplingFactor(1)
    , m_InputImage(NULL)
    , m_BinaryOutput(false)
    , m_UseImageGeometry(false)
    , m_OutputAbsoluteValues(false)
    , m_UseTrilinearInterpolation(false)
{

}

template< class OutputImageType >
TractDensityImageFilter< OutputImageType >::~TractDensityImageFilter()
{
}

template< class OutputImageType >
itk::Point<float, 3> TractDensityImageFilter< OutputImageType >::GetItkPoint(double point[3])
{
    itk::Point<float, 3> itkPoint;
    itkPoint[0] = point[0];
    itkPoint[1] = point[1];
    itkPoint[2] = point[2];
    return itkPoint;
}

template< class OutputImageType >
void TractDensityImageFilter< OutputImageType >::GenerateData()
{
    // generate upsampled image
  mitk::BaseGeometry::Pointer geometry = m_FiberBundle->GetGeometry();
    typename OutputImageType::Pointer outImage = this->GetOutput();

    // calculate new image parameters
    itk::Vector<double,3> newSpacing;
    mitk::Point3D newOrigin;
    itk::Matrix<double, 3, 3> newDirection;
    ImageRegion<3> upsampledRegion;
    if (m_UseImageGeometry && !m_InputImage.IsNull())
    {
        MITK_INFO << "TractDensityImageFilter: using image geometry";
        newSpacing = m_InputImage->GetSpacing()/m_UpsamplingFactor;
        upsampledRegion = m_InputImage->GetLargestPossibleRegion();
        newOrigin = m_InputImage->GetOrigin();
        typename OutputImageType::RegionType::SizeType size = upsampledRegion.GetSize();
        size[0] *= m_UpsamplingFactor;
        size[1] *= m_UpsamplingFactor;
        size[2] *= m_UpsamplingFactor;
        upsampledRegion.SetSize(size);
        newDirection = m_InputImage->GetDirection();
    }
    else
    {
        MITK_INFO << "TractDensityImageFilter: using fiber bundle geometry";
        newSpacing = geometry->GetSpacing()/m_UpsamplingFactor;
        newOrigin = geometry->GetOrigin();
        mitk::Geometry3D::BoundsArrayType bounds = geometry->GetBounds();
        newOrigin[0] += bounds.GetElement(0);
        newOrigin[1] += bounds.GetElement(2);
        newOrigin[2] += bounds.GetElement(4);

        for (int i=0; i<3; i++)
            for (int j=0; j<3; j++)
                newDirection[j][i] = geometry->GetMatrixColumn(i)[j];
        upsampledRegion.SetSize(0, geometry->GetExtent(0)*m_UpsamplingFactor);
        upsampledRegion.SetSize(1, geometry->GetExtent(1)*m_UpsamplingFactor);
        upsampledRegion.SetSize(2, geometry->GetExtent(2)*m_UpsamplingFactor);
    }
    typename OutputImageType::RegionType::SizeType upsampledSize = upsampledRegion.GetSize();

    // apply new image parameters
    outImage->SetSpacing( newSpacing );
    outImage->SetOrigin( newOrigin );
    outImage->SetDirection( newDirection );
    outImage->SetRegions( upsampledRegion );
    outImage->Allocate();
    outImage->FillBuffer(0.0);

    int w = upsampledSize[0];
    int h = upsampledSize[1];
    int d = upsampledSize[2];

    // set/initialize output
    OutPixelType* outImageBufferPointer = (OutPixelType*)outImage->GetBufferPointer();

    // resample fiber bundle
    float minSpacing = 1;
    if(newSpacing[0]<newSpacing[1] && newSpacing[0]<newSpacing[2])
        minSpacing = newSpacing[0];
    else if (newSpacing[1] < newSpacing[2])
        minSpacing = newSpacing[1];
    else
        minSpacing = newSpacing[2];

    MITK_INFO << "TractDensityImageFilter: resampling fibers to ensure sufficient voxel coverage";
    m_FiberBundle = m_FiberBundle->GetDeepCopy();
    m_FiberBundle->ResampleSpline(minSpacing/10);

    MITK_INFO << "TractDensityImageFilter: starting image generation";
    vtkSmartPointer<vtkPolyData> fiberPolyData = m_FiberBundle->GetFiberPolyData();
    vtkSmartPointer<vtkCellArray> vLines = fiberPolyData->GetLines();
    vLines->InitTraversal();
    int numFibers = m_FiberBundle->GetNumFibers();
    boost::progress_display disp(numFibers);
    for( int i=0; i<numFibers; i++ )
    {
        ++disp;
        vtkIdType   numPoints(0);
        vtkIdType*  points(NULL);
        vLines->GetNextCell ( numPoints, points );

        // fill output image
        for( int j=0; j<numPoints; j++)
        {
            itk::Point<float, 3> vertex = GetItkPoint(fiberPolyData->GetPoint(points[j]));
            itk::Index<3> index;
            itk::ContinuousIndex<float, 3> contIndex;
            outImage->TransformPhysicalPointToIndex(vertex, index);
            outImage->TransformPhysicalPointToContinuousIndex(vertex, contIndex);

            if (!m_UseTrilinearInterpolation)
            {
                if (m_BinaryOutput)
                    outImage->SetPixel(index, 1);
                else
                    outImage->SetPixel(index, outImage->GetPixel(index)+0.01);
                continue;
            }

            float frac_x = contIndex[0] - index[0];
            float frac_y = contIndex[1] - index[1];
            float frac_z = contIndex[2] - index[2];

            if (frac_x<0)
            {
                index[0] -= 1;
                frac_x += 1;
            }
            if (frac_y<0)
            {
                index[1] -= 1;
                frac_y += 1;
            }
            if (frac_z<0)
            {
                index[2] -= 1;
                frac_z += 1;
            }

            frac_x = 1-frac_x;
            frac_y = 1-frac_y;
            frac_z = 1-frac_z;

            // int coordinates inside image?
            if (index[0] < 0 || index[0] >= w-1)
                continue;
            if (index[1] < 0 || index[1] >= h-1)
                continue;
            if (index[2] < 0 || index[2] >= d-1)
                continue;

            if (m_BinaryOutput)
            {
                outImageBufferPointer[( index[0]   + w*(index[1]  + h*index[2]  ))] = 1;
                outImageBufferPointer[( index[0]   + w*(index[1]+1+ h*index[2]  ))] = 1;
                outImageBufferPointer[( index[0]   + w*(index[1]  + h*index[2]+h))] = 1;
                outImageBufferPointer[( index[0]   + w*(index[1]+1+ h*index[2]+h))] = 1;
                outImageBufferPointer[( index[0]+1 + w*(index[1]  + h*index[2]  ))] = 1;
                outImageBufferPointer[( index[0]+1 + w*(index[1]  + h*index[2]+h))] = 1;
                outImageBufferPointer[( index[0]+1 + w*(index[1]+1+ h*index[2]  ))] = 1;
                outImageBufferPointer[( index[0]+1 + w*(index[1]+1+ h*index[2]+h))] = 1;
            }
            else
            {
                outImageBufferPointer[( index[0]   + w*(index[1]  + h*index[2]  ))] += (  frac_x)*(  frac_y)*(  frac_z);
                outImageBufferPointer[( index[0]   + w*(index[1]+1+ h*index[2]  ))] += (  frac_x)*(1-frac_y)*(  frac_z);
                outImageBufferPointer[( index[0]   + w*(index[1]  + h*index[2]+h))] += (  frac_x)*(  frac_y)*(1-frac_z);
                outImageBufferPointer[( index[0]   + w*(index[1]+1+ h*index[2]+h))] += (  frac_x)*(1-frac_y)*(1-frac_z);
                outImageBufferPointer[( index[0]+1 + w*(index[1]  + h*index[2]  ))] += (1-frac_x)*(  frac_y)*(  frac_z);
                outImageBufferPointer[( index[0]+1 + w*(index[1]  + h*index[2]+h))] += (1-frac_x)*(  frac_y)*(1-frac_z);
                outImageBufferPointer[( index[0]+1 + w*(index[1]+1+ h*index[2]  ))] += (1-frac_x)*(1-frac_y)*(  frac_z);
                outImageBufferPointer[( index[0]+1 + w*(index[1]+1+ h*index[2]+h))] += (1-frac_x)*(1-frac_y)*(1-frac_z);
            }
        }
    }

    if (!m_OutputAbsoluteValues && !m_BinaryOutput)
    {
        MITK_INFO << "TractDensityImageFilter: max-normalizing output image";
        OutPixelType max = 0;
        for (int i=0; i<w*h*d; i++)
            if (max < outImageBufferPointer[i])
                max = outImageBufferPointer[i];
        if (max>0)
            for (int i=0; i<w*h*d; i++)
                outImageBufferPointer[i] /= max;
    }
    if (m_InvertImage)
    {
        MITK_INFO << "TractDensityImageFilter: inverting image";
        for (int i=0; i<w*h*d; i++)
            outImageBufferPointer[i] = 1-outImageBufferPointer[i];
    }
    MITK_INFO << "TractDensityImageFilter: finished processing";
}
}
<commit_msg>checking if index is inside image<commit_after>/*===================================================================

The Medical Imaging Interaction Toolkit (MITK)

Coindex[1]right (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 "itkTractDensityImageFilter.h"

// VTK
#include <vtkPolyLine.h>
#include <vtkCellArray.h>
#include <vtkCellData.h>
#include <vtkCell.h>

// misc
#include <math.h>
#include <boost/progress.hpp>

namespace itk{

template< class OutputImageType >
TractDensityImageFilter< OutputImageType >::TractDensityImageFilter()
    : m_InvertImage(false)
    , m_FiberBundle(NULL)
    , m_UpsamplingFactor(1)
    , m_InputImage(NULL)
    , m_BinaryOutput(false)
    , m_UseImageGeometry(false)
    , m_OutputAbsoluteValues(false)
    , m_UseTrilinearInterpolation(false)
{

}

template< class OutputImageType >
TractDensityImageFilter< OutputImageType >::~TractDensityImageFilter()
{
}

template< class OutputImageType >
itk::Point<float, 3> TractDensityImageFilter< OutputImageType >::GetItkPoint(double point[3])
{
    itk::Point<float, 3> itkPoint;
    itkPoint[0] = point[0];
    itkPoint[1] = point[1];
    itkPoint[2] = point[2];
    return itkPoint;
}

template< class OutputImageType >
void TractDensityImageFilter< OutputImageType >::GenerateData()
{
    // generate upsampled image
    mitk::BaseGeometry::Pointer geometry = m_FiberBundle->GetGeometry();
    typename OutputImageType::Pointer outImage = this->GetOutput();

    // calculate new image parameters
    itk::Vector<double,3> newSpacing;
    mitk::Point3D newOrigin;
    itk::Matrix<double, 3, 3> newDirection;
    ImageRegion<3> upsampledRegion;
    if (m_UseImageGeometry && !m_InputImage.IsNull())
    {
        MITK_INFO << "TractDensityImageFilter: using image geometry";
        newSpacing = m_InputImage->GetSpacing()/m_UpsamplingFactor;
        upsampledRegion = m_InputImage->GetLargestPossibleRegion();
        newOrigin = m_InputImage->GetOrigin();
        typename OutputImageType::RegionType::SizeType size = upsampledRegion.GetSize();
        size[0] *= m_UpsamplingFactor;
        size[1] *= m_UpsamplingFactor;
        size[2] *= m_UpsamplingFactor;
        upsampledRegion.SetSize(size);
        newDirection = m_InputImage->GetDirection();
    }
    else
    {
        MITK_INFO << "TractDensityImageFilter: using fiber bundle geometry";
        newSpacing = geometry->GetSpacing()/m_UpsamplingFactor;
        newOrigin = geometry->GetOrigin();
        mitk::Geometry3D::BoundsArrayType bounds = geometry->GetBounds();
        newOrigin[0] += bounds.GetElement(0);
        newOrigin[1] += bounds.GetElement(2);
        newOrigin[2] += bounds.GetElement(4);

        for (int i=0; i<3; i++)
            for (int j=0; j<3; j++)
                newDirection[j][i] = geometry->GetMatrixColumn(i)[j];
        upsampledRegion.SetSize(0, geometry->GetExtent(0)*m_UpsamplingFactor);
        upsampledRegion.SetSize(1, geometry->GetExtent(1)*m_UpsamplingFactor);
        upsampledRegion.SetSize(2, geometry->GetExtent(2)*m_UpsamplingFactor);
    }
    typename OutputImageType::RegionType::SizeType upsampledSize = upsampledRegion.GetSize();

    // apply new image parameters
    outImage->SetSpacing( newSpacing );
    outImage->SetOrigin( newOrigin );
    outImage->SetDirection( newDirection );
    outImage->SetLargestPossibleRegion( upsampledRegion );
    outImage->SetBufferedRegion( upsampledRegion );
    outImage->SetRequestedRegion( upsampledRegion );
    outImage->Allocate();
    outImage->FillBuffer(0.0);

    int w = upsampledSize[0];
    int h = upsampledSize[1];
    int d = upsampledSize[2];

    // set/initialize output
    OutPixelType* outImageBufferPointer = (OutPixelType*)outImage->GetBufferPointer();

    // resample fiber bundle
    float minSpacing = 1;
    if(newSpacing[0]<newSpacing[1] && newSpacing[0]<newSpacing[2])
        minSpacing = newSpacing[0];
    else if (newSpacing[1] < newSpacing[2])
        minSpacing = newSpacing[1];
    else
        minSpacing = newSpacing[2];

    MITK_INFO << "TractDensityImageFilter: resampling fibers to ensure sufficient voxel coverage";
    m_FiberBundle = m_FiberBundle->GetDeepCopy();
    m_FiberBundle->ResampleSpline(minSpacing/10);

    MITK_INFO << "TractDensityImageFilter: starting image generation";

    vtkSmartPointer<vtkPolyData> fiberPolyData = m_FiberBundle->GetFiberPolyData();
    vtkSmartPointer<vtkCellArray> vLines = fiberPolyData->GetLines();
    vLines->InitTraversal();
    int numFibers = m_FiberBundle->GetNumFibers();
    boost::progress_display disp(numFibers);
    for( int i=0; i<numFibers; i++ )
    {
        ++disp;
        vtkIdType   numPoints(0);
        vtkIdType*  points(NULL);
        vLines->GetNextCell ( numPoints, points );

        // fill output image
        for( int j=0; j<numPoints; j++)
        {
            itk::Point<float, 3> vertex = GetItkPoint(fiberPolyData->GetPoint(points[j]));
            itk::Index<3> index;
            itk::ContinuousIndex<float, 3> contIndex;
            outImage->TransformPhysicalPointToIndex(vertex, index);
            outImage->TransformPhysicalPointToContinuousIndex(vertex, contIndex);

            if (!m_UseTrilinearInterpolation && outImage->GetLargestPossibleRegion().IsInside(index))
            {
                if (m_BinaryOutput)
                    outImage->SetPixel(index, 1);
                else
                    outImage->SetPixel(index, outImage->GetPixel(index)+0.01);
                continue;
            }

            float frac_x = contIndex[0] - index[0];
            float frac_y = contIndex[1] - index[1];
            float frac_z = contIndex[2] - index[2];

            if (frac_x<0)
            {
                index[0] -= 1;
                frac_x += 1;
            }
            if (frac_y<0)
            {
                index[1] -= 1;
                frac_y += 1;
            }
            if (frac_z<0)
            {
                index[2] -= 1;
                frac_z += 1;
            }

            frac_x = 1-frac_x;
            frac_y = 1-frac_y;
            frac_z = 1-frac_z;

            // int coordinates inside image?
            if (index[0] < 0 || index[0] >= w-1)
                continue;
            if (index[1] < 0 || index[1] >= h-1)
                continue;
            if (index[2] < 0 || index[2] >= d-1)
                continue;

            if (m_BinaryOutput)
            {
                outImageBufferPointer[( index[0]   + w*(index[1]  + h*index[2]  ))] = 1;
                outImageBufferPointer[( index[0]   + w*(index[1]+1+ h*index[2]  ))] = 1;
                outImageBufferPointer[( index[0]   + w*(index[1]  + h*index[2]+h))] = 1;
                outImageBufferPointer[( index[0]   + w*(index[1]+1+ h*index[2]+h))] = 1;
                outImageBufferPointer[( index[0]+1 + w*(index[1]  + h*index[2]  ))] = 1;
                outImageBufferPointer[( index[0]+1 + w*(index[1]  + h*index[2]+h))] = 1;
                outImageBufferPointer[( index[0]+1 + w*(index[1]+1+ h*index[2]  ))] = 1;
                outImageBufferPointer[( index[0]+1 + w*(index[1]+1+ h*index[2]+h))] = 1;
            }
            else
            {
                outImageBufferPointer[( index[0]   + w*(index[1]  + h*index[2]  ))] += (  frac_x)*(  frac_y)*(  frac_z);
                outImageBufferPointer[( index[0]   + w*(index[1]+1+ h*index[2]  ))] += (  frac_x)*(1-frac_y)*(  frac_z);
                outImageBufferPointer[( index[0]   + w*(index[1]  + h*index[2]+h))] += (  frac_x)*(  frac_y)*(1-frac_z);
                outImageBufferPointer[( index[0]   + w*(index[1]+1+ h*index[2]+h))] += (  frac_x)*(1-frac_y)*(1-frac_z);
                outImageBufferPointer[( index[0]+1 + w*(index[1]  + h*index[2]  ))] += (1-frac_x)*(  frac_y)*(  frac_z);
                outImageBufferPointer[( index[0]+1 + w*(index[1]  + h*index[2]+h))] += (1-frac_x)*(  frac_y)*(1-frac_z);
                outImageBufferPointer[( index[0]+1 + w*(index[1]+1+ h*index[2]  ))] += (1-frac_x)*(1-frac_y)*(  frac_z);
                outImageBufferPointer[( index[0]+1 + w*(index[1]+1+ h*index[2]+h))] += (1-frac_x)*(1-frac_y)*(1-frac_z);
            }
        }
    }

    if (!m_OutputAbsoluteValues && !m_BinaryOutput)
    {
        MITK_INFO << "TractDensityImageFilter: max-normalizing output image";
        OutPixelType max = 0;
        for (int i=0; i<w*h*d; i++)
            if (max < outImageBufferPointer[i])
                max = outImageBufferPointer[i];
        if (max>0)
            for (int i=0; i<w*h*d; i++)
                outImageBufferPointer[i] /= max;
    }
    if (m_InvertImage)
    {
        MITK_INFO << "TractDensityImageFilter: inverting image";
        for (int i=0; i<w*h*d; i++)
            outImageBufferPointer[i] = 1-outImageBufferPointer[i];
    }
    MITK_INFO << "TractDensityImageFilter: finished processing";
}
}
<|endoftext|>