void vesKiwiDataConversionTools::GenericConvertTriangles(vtkPolyData* input,
  vesSharedPtr<vesGeometryData> output)
{
  vesSourceDataP3N3f::Ptr sourceData (new vesSourceDataP3N3f());

  double inPoint[3];
  for (int i = 0; i < input->GetNumberOfPoints(); ++i){
    input->GetPoint(i, inPoint);

    vesVertexDataP3N3f vertexData;
    vertexData.m_position = vesVector3f(inPoint[0], inPoint[1], inPoint[2]);
    sourceData->pushBack(vertexData);
  }

  // copy triangles in place to ves structure
  vtkCellArray* polys = input->GetPolys();
  vtkIdType num;
  vtkIdType* vertices;

  vesSharedPtr< vesIndices<T> > indicesObj =
    std::tr1::static_pointer_cast< vesIndices<T> >
    (output->triangles()->getVesIndices());

  typename vesIndices<T>::Indices* triangleIndices
    = indicesObj->indices();

  triangleIndices->clear();
  triangleIndices->resize(polys->GetNumberOfCells());

  T* outIndex = &triangleIndices->front();
  for (int i = 0; i < polys->GetNumberOfCells(); ++i)
  {
    // there are 4 elements for each triangle cell in the array (count, i1, i2, i3)
    polys->GetCell(4*i, num, vertices);
    *outIndex++ = vertices[0];
    *outIndex++ = vertices[1];
    *outIndex++ = vertices[2];
  }

  if (input->GetPointData()->GetNormals())
  {
    vtkDataArray* normals = input->GetPointData()->GetNormals();
    for (int i = 0; i < input->GetNumberOfPoints(); ++i)
    {
      sourceData->arrayReference()[i].m_normal[0] = normals->GetTuple(i)[0];
      sourceData->arrayReference()[i].m_normal[1] = normals->GetTuple(i)[1];
      sourceData->arrayReference()[i].m_normal[2] = normals->GetTuple(i)[2];
    }
  }
  else
  {
    output->computeNormals<T>();
  }

  output->computeBounds();
  output->addSource(sourceData);
}
//----------------------------------------------------------------------------
void vesKiwiDataConversionTools::SetTextureCoordinates(vtkDataArray* tcoords,
  vesSharedPtr<vesGeometryData> geometryData)
{
  if (geometryData) {
    vesSourceDataT2f::Ptr tcoordSourceData = ConvertTCoords(tcoords);
    if (tcoordSourceData) {
      geometryData->addSource(tcoordSourceData);
    }
  }
}
//----------------------------------------------------------------------------
void vesKiwiDataConversionTools::SetVertexColors(vtkDataArray* scalars,
  vtkScalarsToColors* scalarsToColors, vesSharedPtr<vesGeometryData> geometryData)
{
  if (geometryData) {
    vesSourceData::Ptr colorSourceData = ConvertScalarsToColors(scalars, scalarsToColors);
    if (colorSourceData) {
      geometryData->addSource(colorSourceData);
    }
  }
}
//----------------------------------------------------------------------------
void vesKiwiDataConversionTools::SetVertexColors(
  vtkUnsignedCharArray* colors, vesSharedPtr<vesGeometryData> geometryData)
{
  if (geometryData) {
    vesSourceData::Ptr colorSourceData = ConvertColors(colors);
    if (colorSourceData) {
      geometryData->addSource(colorSourceData);
    }
  }
}
//----------------------------------------------------------------------------
void vesKiwiDataConversionTools::SetTextureCoordinates(vtkDataArray* tcoords,
  vesSharedPtr<vesGeometryData> geometryData)
{
  assert(tcoords);
  assert(tcoords->GetNumberOfComponents() == 2);
  assert(geometryData);

  const size_t nTuples = tcoords->GetNumberOfTuples();

  vesSourceDataT2f::Ptr texCoordSourceData (new vesSourceDataT2f());

  for (size_t i = 0; i < nTuples; ++i)
    {
    double* values = tcoords->GetTuple(i);
    vesVertexDataT2f textureCoordinate;
    textureCoordinate.m_textureCoordinate = vesVector2f(values[0], values[1]);
    texCoordSourceData->pushBack(textureCoordinate);
    }

  geometryData->addSource(texCoordSourceData);
}
//----------------------------------------------------------------------------
void vesKiwiDataConversionTools::SetVertexColors(
  vtkUnsignedCharArray* colors, vesSharedPtr<vesGeometryData> geometryData)
{
  assert(geometryData);
  assert(colors);
  assert(colors->GetNumberOfComponents() == 3);

  unsigned char rgb[3];
  const size_t nTuples = colors->GetNumberOfTuples();

  vesSourceDataC3f::Ptr colorSourceData (new vesSourceDataC3f());
  for (size_t i = 0; i < nTuples; ++i)
    {
    colors->GetTupleValue(i, rgb);
    vesVertexDataC3f color;
    color.m_color = vesVector3f(rgb[0]/255.0, rgb[1]/255.0, rgb[2]/255.0);
    colorSourceData->pushBack(color);
    }

  geometryData->addSource(colorSourceData);
}
//----------------------------------------------------------------------------
void vesKiwiDataConversionTools::SetVertexColors(vtkDataArray* scalars,
  vtkScalarsToColors* scalarsToColors, vesSharedPtr<vesGeometryData> geometryData)
{
  assert(scalars);
  assert(scalars->GetNumberOfComponents() == 1);
  assert(geometryData);

  double rgb[3];
  const size_t nTuples = scalars->GetNumberOfTuples();

  vesSourceDataC3f::Ptr colorSourceData (new vesSourceDataC3f());

  for (size_t i = 0; i < nTuples; ++i)
    {
    scalarsToColors->GetColor(scalars->GetComponent(i, 0), rgb);
    vesVertexDataC3f color;
    color.m_color = vesVector3f(rgb[0], rgb[1], rgb[2]);
    colorSourceData->pushBack(color);
    }

  geometryData->addSource(colorSourceData);
}