# MedicalDemo4

VTKExamples/Cxx/Medical/MedicalDemo4

### Code

MedicalDemo4.cxx

    // Derived from VTK/Examples/Cxx/Medical3.cxx
    // This example reads a volume dataset and displays it via volume rendering.
    //

    #include <vtkSmartPointer.h>
    #include <vtkRenderer.h>
    #include <vtkRenderWindow.h>
    #include <vtkRenderWindowInteractor.h>
    #include <vtkMetaImageReader.h>
    #include <vtkVolume.h>
    #include <vtkFixedPointVolumeRayCastMapper.h>
    #include <vtkVolumeProperty.h>
    #include <vtkColorTransferFunction.h>
    #include <vtkPiecewiseFunction.h>
    #include <vtkCamera.h>

    int main (int argc, char *argv[])
    {
      if (argc < 2)
      {
        cout << "Usage: " << argv[0] << "file.mhd" << endl;
        return EXIT_FAILURE;
      }

      // Create the renderer, the render window, and the interactor. The renderer
      // draws into the render window, the interactor enables mouse- and
      // keyboard-based interaction with the scene.
      vtkSmartPointer<vtkRenderer> ren =
        vtkSmartPointer<vtkRenderer>::New();
      vtkSmartPointer<vtkRenderWindow> renWin =
        vtkSmartPointer<vtkRenderWindow>::New();
      renWin->AddRenderer(ren);
      vtkSmartPointer<vtkRenderWindowInteractor> iren =
        vtkSmartPointer<vtkRenderWindowInteractor>::New();
      iren->SetRenderWindow(renWin);

      // The following reader is used to read a series of 2D slices (images)
      // that compose the volume. The slice dimensions are set, and the
      // pixel spacing. The data Endianness must also be specified. The reader
      // uses the FilePrefix in combination with the slice number to construct
      // filenames using the format FilePrefix.%d. (In this case the FilePrefix
      // is the root name of the file: quarter.)
      vtkSmartPointer<vtkMetaImageReader> reader =
        vtkSmartPointer<vtkMetaImageReader>::New();
      reader->SetFileName(argv[1]);

      // The volume will be displayed by ray-cast alpha compositing.
      // A ray-cast mapper is needed to do the ray-casting.
      vtkSmartPointer<vtkFixedPointVolumeRayCastMapper> volumeMapper =
        vtkSmartPointer<vtkFixedPointVolumeRayCastMapper>::New();
      volumeMapper->SetInputConnection(reader->GetOutputPort());

      // The color transfer function maps voxel intensities to colors.
      // It is modality-specific, and often anatomy-specific as well.
      // The goal is to one color for flesh (between 500 and 1000)
      // and another color for bone (1150 and over).
      vtkSmartPointer<vtkColorTransferFunction>volumeColor =
        vtkSmartPointer<vtkColorTransferFunction>::New();
      volumeColor->AddRGBPoint(0,    0.0, 0.0, 0.0);
      volumeColor->AddRGBPoint(500,  1.0, 0.5, 0.3);
      volumeColor->AddRGBPoint(1000, 1.0, 0.5, 0.3);
      volumeColor->AddRGBPoint(1150, 1.0, 1.0, 0.9);

      // The opacity transfer function is used to control the opacity
      // of different tissue types.
      vtkSmartPointer<vtkPiecewiseFunction> volumeScalarOpacity =
        vtkSmartPointer<vtkPiecewiseFunction>::New();
      volumeScalarOpacity->AddPoint(0,    0.00);
      volumeScalarOpacity->AddPoint(500,  0.15);
      volumeScalarOpacity->AddPoint(1000, 0.15);
      volumeScalarOpacity->AddPoint(1150, 0.85);

      // The gradient opacity function is used to decrease the opacity
      // in the "flat" regions of the volume while maintaining the opacity
      // at the boundaries between tissue types.  The gradient is measured
      // as the amount by which the intensity changes over unit distance.
      // For most medical data, the unit distance is 1mm.
      vtkSmartPointer<vtkPiecewiseFunction> volumeGradientOpacity =
        vtkSmartPointer<vtkPiecewiseFunction>::New();
      volumeGradientOpacity->AddPoint(0,   0.0);
      volumeGradientOpacity->AddPoint(90,  0.5);
      volumeGradientOpacity->AddPoint(100, 1.0);

      // The VolumeProperty attaches the color and opacity functions to the
      // volume, and sets other volume properties.  The interpolation should
      // be set to linear to do a high-quality rendering.  The ShadeOn option
      // turns on directional lighting, which will usually enhance the
      // appearance of the volume and make it look more "3D".  However,
      // the quality of the shading depends on how accurately the gradient
      // of the volume can be calculated, and for noisy data the gradient
      // estimation will be very poor.  The impact of the shading can be
      // decreased by increasing the Ambient coefficient while decreasing
      // the Diffuse and Specular coefficient.  To increase the impact
      // of shading, decrease the Ambient and increase the Diffuse and Specular.
      vtkSmartPointer<vtkVolumeProperty> volumeProperty =
        vtkSmartPointer<vtkVolumeProperty>::New();
      volumeProperty->SetColor(volumeColor);
      volumeProperty->SetScalarOpacity(volumeScalarOpacity);
      volumeProperty->SetGradientOpacity(volumeGradientOpacity);
      volumeProperty->SetInterpolationTypeToLinear();
      volumeProperty->ShadeOn();
      volumeProperty->SetAmbient(0.4);
      volumeProperty->SetDiffuse(0.6);
      volumeProperty->SetSpecular(0.2);

      // The vtkVolume is a vtkProp3D (like a vtkActor) and controls the position
      // and orientation of the volume in world coordinates.
      vtkSmartPointer<vtkVolume> volume =
        vtkSmartPointer<vtkVolume>::New();
      volume->SetMapper(volumeMapper);
      volume->SetProperty(volumeProperty);

      // Finally, add the volume to the renderer
      ren->AddViewProp(volume);

      // Set up an initial view of the volume.  The focal point will be the
      // center of the volume, and the camera position will be 400mm to the
      // patient's left (which is our right).
      vtkCamera *camera = ren->GetActiveCamera();
      double *c = volume->GetCenter();
      camera->SetViewUp (0, 0, -1);
      camera->SetPosition (c[0], c[1] - 400, c[2]);
      camera->SetFocalPoint (c[0], c[1], c[2]);
      camera->ComputeViewPlaneNormal();
      camera->Azimuth(30.0);
      camera->Elevation(30.0);

      // Set a background color for the renderer
      ren->SetBackground(.2, .3, .4);

      renWin->SetSize(640, 480);
      // Increase the size of the render window
      renWin->SetSize(640, 480);

      // Interact with the data.
      iren->Initialize();
      iren->Start();

      return EXIT_SUCCESS;
    }

### CMakeLists.txt

    cmake_minimum_required(VERSION 2.8)

    PROJECT(MedicalDemo4)

    find_package(VTK REQUIRED)
    include(${VTK_USE_FILE})

    add_executable(MedicalDemo4 MACOSX_BUNDLE MedicalDemo4.cxx)

    target_link_libraries(MedicalDemo4 ${VTK_LIBRARIES})

### Download and Build MedicalDemo4

Click here to download MedicalDemo4 and its CMakeLists.txt file. Once the tarball MedicalDemo4.tar has been downloaded and extracted,

    cd MedicalDemo4/build

If VTK is installed:

    cmake ..

If VTK is not installed but compiled on your system, you will need to specify the path to your VTK build:

    cmake -DVTK_DIR:PATH=/home/me/vtk_build ..

Build the project:

    make

and run it:

    ./MedicalDemo4

WINDOWS USERS PLEASE NOTE: Be sure to add the VTK bin directory to your path. This will resolve the VTK dll's at run time.