//  Try.C
//  Steven Matuszek, UMBC
//
//  A vtk volume rendering program for the Visible Human data set.
//
//  The recommended call for our density data is
//
//  Try 400 175 42 1280 1.0 1.0 3.0 0 2000 0 255

#include "all.h"
/*
#include "vtkObject.h"
#include "vtkRenderer.h"
#include "vtkRenderWindow.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkPNMReader.h"
#include "vtkVolume16Reader.h"
#include "vtkPiecewiseFunction.h"
#include "vtkVolumeProperty.h"
#include "vtkVolumeRayCastCompositeFunction.h"
#include "vtkVolumeRayCastMapper.h"
#include "vtkVolume.h"
#include "vtkOutlineFilter.h"
#include "vtkPolyDataMapper.h"
#include "vtkActor.h"
#include "vtkCamera.h"
*/

#define fileprefix "vh/d_vm"
#define pattern "%s%d.pgm"
#define winname "Slice-o-person"


void main(int argc, char *argv[])
{
/*
   int xsize = 400;
   int ysize = 175;
   int zsize = 42;
   int zstart = 1280;
   float xspacing = 1.0;
   float yspacing = 1.0;
   float zspacing = 1.0;
*/
   int xsize, ysize, zsize, zstart;
   float xspacing, yspacing, zspacing;
   int cpwf0, cpwf1, opwf0, opwf1;

   if (argc < 12) 
   {
	printf("Usage: Try xsize ysize zsize zstart xspacing yspacing zspacing\n");
	printf("  colorpiecewisefunctionmin colorpiecewisefunctionmax\n");
	printf("  opacitypiecewisefunctionmin opacitypiecewisefunctionmax\n");
	exit(0);
   }

   xsize = atoi(argv[1]);
   ysize = atoi(argv[2]);
   zsize = atoi(argv[3]);
   zstart = atoi(argv[4]);
   xspacing = atof(argv[5]);
   yspacing = atof(argv[6]);
   zspacing = atof(argv[7]);
   cpwf0 = atoi(argv[8]);
   cpwf1 = atoi(argv[9]);
   opwf0 = atoi(argv[10]);
   opwf1 = atoi(argv[11]);

  // create the renderer stuff
  vtkRenderer *aRenderer = vtkRenderer::New();
  vtkRenderWindow * renWin = vtkRenderWindow::New();
    renWin->SetWindowName(winname);
    renWin->AddRenderer(aRenderer);
  vtkRenderWindowInteractor *iren = vtkRenderWindowInteractor::New();
    iren->SetRenderWindow(renWin);

  // read the volume
  vtkPNMReader *pnmr = vtkPNMReader::New();
//    pnmr->SetDataDimensions(xsize,ysize);
//    pnmr->SetImageRange(zstart, zstart + zsize - 1);

    pnmr->SetDataExtent(0, xsize-1, 0, ysize-1, zstart, zstart+zsize-1);
    pnmr->SetDataByteOrderToBigEndian();
    pnmr->SetFilePrefix (fileprefix);
    pnmr->SetFilePattern(pattern);
    pnmr->SetDataSpacing (xspacing, yspacing, zspacing);

/*
  // read the volume
  vtkVolume16Reader *v16 = vtkVolume16Reader::New();
    v16->SetDataDimensions(xsize,ysize);
    //v16->SetDataByteOrderToLittleEndian();
    v16->SetDataByteOrderToBigEndian();
    v16->SetFilePrefix (fileprefix);
    v16->SetFilePattern(pattern);
    v16->SetImageRange(zstart, zstart + zsize - 1);
    v16->SetDataSpacing (xspacing, yspacing, zspacing);
*/

    vtkPiecewiseFunction *white_tfun = vtkPiecewiseFunction::New();
      white_tfun->AddPoint(cpwf0,1.0);
      white_tfun->AddPoint(cpwf1,1.0);

    vtkPiecewiseFunction *tfun = vtkPiecewiseFunction::New();
      tfun->AddPoint(opwf0,0.0);
      tfun->AddPoint((opwf1-opwf0)/2,0.8);
      tfun->AddPoint(opwf1,1.0);

    vtkVolumeProperty *vol_prop = vtkVolumeProperty::New(); 
      vol_prop->SetColor(white_tfun);
//      vol_prop->SetColor(pnmr->GetOutput());
      vol_prop->SetScalarOpacity(tfun);
      vol_prop->SetInterpolationTypeToLinear();
      vol_prop->ShadeOn();

    vtkVolumeRayCastCompositeFunction *comp_func 
      = vtkVolumeRayCastCompositeFunction::New();

    vtkVolumeRayCastMapper *volmap = vtkVolumeRayCastMapper::New();
      volmap->SetVolumeRayCastFunction( comp_func);
//      volmap->SetScalarInput(v16->GetOutput());
      volmap->SetScalarInput(pnmr->GetOutput());
      volmap->SetSampleDistance(1.0);

    vtkVolume *vol = vtkVolume::New();
      vol->SetVolumeProperty(vol_prop);
      vol->SetVolumeMapper(volmap);

    aRenderer->AddVolume(vol);

  // get an outline
  vtkOutlineFilter *outlineData = vtkOutlineFilter::New();
    outlineData->SetInput(pnmr->GetOutput());
  vtkPolyDataMapper *mapOutline = vtkPolyDataMapper::New();
    mapOutline->SetInput(outlineData->GetOutput());
  
    vtkActor *outline = vtkActor::New();
    outline->SetMapper(mapOutline);
    outline->GetProperty()->SetColor(0,0,0);

    // create a camera with the correct view up
    vtkCamera *aCamera = vtkCamera::New();
    aCamera->SetViewUp (0, 0, -1);
    // aCamera->SetPosition (viewpos[0], viewpos[1], viewpos[2]);
    aCamera->SetFocalPoint (0, 0, 0);
    aCamera->ComputeViewPlaneNormal();

  // now, tell the renderer our actors
//  aRenderer->AddActor(outline);

  aRenderer->SetActiveCamera(aCamera);
  aRenderer->ResetCamera ();
  aCamera->Dolly(1.5);
  aRenderer->SetBackground(0,0,.5);

  // interact with data
  renWin->SetSize(300, 300);
  //renWin->Render();
  iren->Initialize();


  cout<<"Start interactive viewing...\n"<<flush;
  iren->Start();
}


