#include "vtkRenderWindow.h"
#include "vtkCamera.h"
#include "vtkActor.h"
#include "vtkRenderer.h"
#include "vtkStructuredPointsReader.h"
#include "vtkPiecewiseFunction.h"
#include "vtkColorTransferFunction.h"
#include "vtkVolumeProperty.h"
#include "vtkVolumeRayCastCompositeFunction.h"
#include "vtkVolumeRayCastMapper.h"
#include "vtkVolume.h"
#include "vtkDataSetTriangleFilter.h"
#include "vtkUnstructuredGridVolumeRayCastMapper.h"

int main()
{

  vtkStructuredPointsReader *reader = vtkStructuredPointsReader::New();
  reader->SetFileName("/usr/share/VTKData/Data/ironProt.vtk");

  vtkDataSetTriangleFilter *tetraFilter = vtkDataSetTriangleFilter::New();
  tetraFilter->SetInputConnection(reader->GetOutputPort());
  
  vtkPiecewiseFunction *opacityTransferFunction = vtkPiecewiseFunction::New();
  opacityTransferFunction->AddPoint(20,0.0);
  opacityTransferFunction->AddPoint(255,0.2);

  vtkColorTransferFunction *colorTransferFunction = vtkColorTransferFunction::New();
  colorTransferFunction->AddRGBPoint(0.0, 0.0, 0.0, 0.0);
  colorTransferFunction->AddRGBPoint(64.0, 1.0, 0.0, 0.0);
  colorTransferFunction->AddRGBPoint(128.0, 0.0, 0.0, 1.0);
  colorTransferFunction->AddRGBPoint(192.0, 0.0, 1.0, 0.0);
  colorTransferFunction->AddRGBPoint(255.0, 0.0, 0.2, 0.0);

  vtkVolumeProperty *volumeProperty = vtkVolumeProperty::New();
  volumeProperty->SetColor(colorTransferFunction);
  volumeProperty->SetScalarOpacity(opacityTransferFunction);
  volumeProperty->ShadeOn();
  volumeProperty->SetInterpolationTypeToLinear();

  vtkVolumeRayCastCompositeFunction *compositeFunction = vtkVolumeRayCastCompositeFunction::New();
  vtkUnstructuredGridVolumeRayCastMapper *volumeMapper = vtkUnstructuredGridVolumeRayCastMapper::New();
  volumeMapper->SetImageSampleDistance(25);
  volumeMapper->SetInputConnection(tetraFilter->GetOutputPort());
  volumeMapper->IntermixIntersectingGeometryOff();
  volumeMapper->AutoAdjustSampleDistancesOff();

  vtkVolume *volume = vtkVolume::New();
  volume->SetMapper(volumeMapper);
  volume->SetProperty(volumeProperty);
  
  vtkRenderer *ren1= vtkRenderer::New();
  ren1->AddVolume(volume);
  ren1->SetBackground( 0.1, 0.2, 0.4 );

  //
  // Finally we create the render window which will show up on the screen.
  // We put our renderer into the render window using AddRenderer. We also
  // set the size to be 300 pixels by 300.
  //
  vtkRenderWindow *renWin = vtkRenderWindow::New();
  renWin->AddRenderer( ren1 );
  renWin->SetSize( 300, 300 );
  renWin->SetDesiredUpdateRate(5);
  //
  // Now we loop over 360 degreeees and render each time.
  //
  int i;
  for (i = 0; true; ++i)
  {
    // cause the pipeline to re-execute
    reader->Modified();
    renWin->Render();
    ren1->GetActiveCamera()->Azimuth( 3 );
  }
  
  ren1->Delete();
  renWin->Delete();

  return 0;
}


