Volume Rendering with Direct Graphics

Visualizing volume data using IDL's Direct graphics routines (as opposed to the iTools) requires some additional work, but may be desirable if you are incorporating the volume visualization into a larger widget-based application. The following sections will guide you through the process of setting up a volume visualization using Direct graphics routines.

3-D Transformations in Direct Graphics

When creating three-dimensional plots (surface or volume visualizations, for example) using IDL Direct graphics, you must apply a three-dimensional transformation matrix to the data before display. The transformation applies a specified translation, rotation, and scaling to the three-dimensional data array before displaying it on the two-dimensional computer screen.

Three-dimensional transformations are especially important when using the POLYSHADE routine to display volume data. Unless the transformation is set up so that the entire volume is visible, the volume will not be rendered correctly. Once a 3-D transformation has been established, most IDL plotting routines can be made to use it by including the T3D keyword.

There are a number of ways to set up a transformation matrix in IDL:

In the following example, we will use the SCALE3 routine to update the !P.T transformation matrix.

Displaying an Isosurface

Two IDL routines, SHADE_VOLUME and POLYSHADE, are used together to create and display an isosurface. SHADE_VOLUME generates a list of polygons that define a 3-D surface given a volume data set and a contour (or density) level. The function POLYSHADE creates a shaded-surface representation of the isosurface defined by those polygons.

Like many other IDL commands, POLYSHADE accepts the T3D keyword that makes POLYSHADE use a user-defined 3D transformation. Before you can use POLYSHADE to render the final image, you need to set up an appropriate three-dimensional transformation. The XRANGE, YRANGE, and ZRANGE keywords accept two-element vectors, representing the minimum and maximum axis values, as arguments. POLYSHADE returns an image based upon the list of vertices, V, and list of polygons, P. The T3D keyword tells POLYSHADE to use the previously-defined 3D transformation. The TV procedure displays the shaded-surface image.

Enter the following lines at the IDL command prompt:

  1. If you created the data variable in the previous section, you can skip this step. If you have not yet created a head_data variable, read some volume data with the following commands:
  2. file = FILEPATH('head.dat', SUBDIRECTORY = ['examples', 'data'])
    head_data = READ_BINARY(file, DATA_DIMS = [80, 100, 57])

  3. Since we are using Direct graphics, tell IDL to use a maximum of 256 colors. Load a simple grayscale colormap.
  4. DEVICE, RETAIN=2, DECOMPOSED=0
    LOADCT, 0

  5. Create the polygons and vertices that define the isosurface with a value of 50. Return the vertices in the variable V and the polygons in the variable P:
  6. SHADE_VOLUME, head_data, 50, V, P, /LOW

  7. Set up an appropriate 3-D transformation matrix using the SCALE3 procedure:
  8. SCALE3, XRANGE=[0,80], YRANGE=[0,100], ZRANGE=[0,57]

  9. Display a shaded-surface representation of the previously generated arrays of vertices and polygons:
    gsvol02.gif
  10. TV, POLYSHADE(V, P, /T3D)

This is the same isosurface created using the iVolume tool in "Displaying an Isosurface" on page 88.

Displaying an Image Plane

To display an image plane taken from volume data, use IDL's array indexing syntax to specify a "slice" through the three-dimensional data array.

  1. The head_data array is 80 x 100 x 57 elements; to extract an X-Y slice from this array roughly in the middle:
    gsvol05.gif
  2. head_slice = head_data[40,*,*]

    This command creates a new variable named head_slice containing a 1 x 100 x 57 element array.

  3. Reformat the 1 x 100 x 57 element array as a two-dimensional array with 100 x 57 elements:
  4. head_slice = REFORM(head_slice)

  5. Resize the array to 500 x 400 elements, using cubic interpolation:
  6. head_slice = CONGRID(head_slice, 500, 400, CUBIC=-0.7)

  7. Display the image:
  8. TV, head_slice

This is essentially the same process used by the iVolume tool in "Displaying Image Planes" on page 89.