This is the simplest method for loading volume data, assuming that the volume is stored on disk and there exists an SoVolumeReader( C++ | Java | .NET ) class for the file format. This is true of course for the formats for which VolumeViz has a built-in reader, however applications can create their own volume reader classes (described later). VolumeViz will try to automatically select a volume reader class based on the file extension. For example VolumeViz will automatically use the SoVRLdmFileReader( C++ | Java | .NET ) class for files with the extension ".ldm" (the LDM file format defined by FEI). VolumeViz supports a number of common formats including DICOM and SEGY (discussed in more detail later). In addition to single data files, some VolumeViz readers support loading a volume stored as a stack of separate image files. We have already seen a simple example of setting SoVolumeData( C++ | Java | .NET )’s filename field in the Section 1.1.4, “Quick Start”.
Note that the application can also query the volume reader using the getReader() method. If called after the filename field has been set, this method will return a pointer to the instance of the SoVolumeReader( C++ | Java | .NET ) sub-class that VolumeViz selected to load this file (or the reader specified using the setReader() method). This can be useful in order to call data format specific methods provided by that volume reader class, for example to get custom XML tags from an LDM file header. |
In this section we will discuss:
The following table shows the built-in VolumeViz file readers and the file name extension(s) associated with each reader class. The filename extension is not case sensitive
File extension | Reader class | Description |
---|---|---|
.am | SoVRAmFileReader( C++ | Java | .NET ) | Avizo Mesh file format |
.dc3, .dic, .dicom | SoVRDicomFileReader( C++ | Java | .NET ) | DICOM file format |
.fld | SoVRAvsFileReader( C++ | Java | .NET ) | AVS field file format |
.ldm | SoVRLdmFileReader( C++ | Java | .NET ) | Large Data Management file format |
.sgy or .segy | SoVRSegyFileReader( C++ | Java | .NET ) | SEG Y revision 1 file format |
.vol | SoVRVolFileReader( C++ | Java | .NET ) | Vol file format |
.vox | SoVRVoxFileReader( C++ | Java | .NET ) | Vox file format |
.lst | SoVRRasterStackReader( C++ | Java | .NET ) | Lst file format |
.tiff, .tif | SoVRTiffFileReader( C++ | Java | .NET ) | Tiff file format |
.mrc | SoVRMrcFileReader( C++ | Java | .NET ) | Mrc file format |
Avizo mesh:
Avizo mesh is a general purpose file format that can contain many different kinds of data. The VolumeViz file reader can load Avizo mesh files containing a 3-dimensional “Lattice” data object with uniform coordinates and any data type.
AVS field:
AVS field is a general purpose file format that can contain many different kinds of data. The VolumeViz file reader can load AVS field files containing 3-dimensional, uniform data of type “byte”.
DICOM:
A widely used format for storing medical image data (CT, MRI, etc), defined by the National Electrical Manufacturers Association (NEMA) ( medical.nema.org). The VolumeViz file reader can load a DICOM volume in a single file or in a set of files (one slice per file).
LDM:
LDM is a format defined by FEI for storing tiled, hierarchical multi-resolution volume data. VolumeViz includes a utility program that can convert other formats (for which there is a VolumeViz reader) into this format. Preprocessing volume data into this format provides the maximum benefits from the VolumeViz large data management (LDM) features.
LST:
A simple format for loading a stack of images. Specify the names of the image files in a .lst file.
SEGY:
A widely used format for storing seismic trace data, defined by the Society of Exploration Geophysicists publication “Digital Tape Standards” ( www.seg.org ). The VolumeViz reader supports all sizes of integer and float data, and can correctly determine the number of samples per trace in most cases. The reader has many options to adapt to differences in SEGY file headers.
VOL:
A simple volume interchange format (see “Introduction to Volume Rendering”, Lichtenbelt, Crane, Naqvi, 1998). The VolumeViz reader can load files containing 8 or 16 bit voxels.
VOX:
A volume interchange format defined by TeraRecon Inc. ( www.terarecon.com ). The VolumeViz reader can load “Vox1999a” files containing 8 or 16 bit voxels (first volume only).
TIFF:
Variable-resolution bitmapped image format developed by Aldus (now part of Adobe) in 1986 ( http://www.adobe.com/ ). The VolumeViz reader loads slices from a single multi-image TIFF file.
MRC:
Binary file format widely used in the three-dimensional electron microscopy field for storing image and volume data ( http://www.ccpem.ac.uk/mrc_format/mrc_format.php ). The VolumeViz reader loads slices from a single multi-image MRC file.
If the filename does not have an extension or does not have the appropriate extension, the application can still use a specific volume reader to load the file, but must set the volume reader explicitly using the SoVolumeData( C++ | Java | .NET ) node’s setReader() method. For example, if we know the volume file contains data in the VOL format, but the filename does not have the appropriate extension, the following code will force VolumeViz to read the data as VOL format.
// Load volume in VOL format SoVRVolFileReader* pReader = new SoVRVolFileReader; pReader->setFilename( "myVolData.xxx" ); SoVolumeData* pVolData = new SoVolumeData(); pVolData->setReader( *pReader );
// Load volume in VOL format SoVRVolFileReader reader = new SoVRVolFileReader(); reader.SetFilename( "myVolData.xxx" ); SoVolumeData VolData = new SoVolumeData(); VolData.Reader = reader;
// Load volume in VOL format SoVRVolFileReader reader = new SoVRVolFileReader(); reader.setFilename( " myVolData.xxx " ); SoVolumeData volData = new SoVolumeData(); volData.setReader( reader, false );
The C++ and Java versions of setReader() have a second parameter called takeOwnership. When this parameter is false (the default), the volume reader object is owned by the application and must be managed by the application. When this parameter is true, VolumeViz manages the reader object. |
If the file is not in a format directly supported by VolumeViz, but contains volume data in a contiguous block of values organized row-by-row, you can use the generic reader SoVRGenericFileReader( C++ | Java | .NET ). This is useful to load so-called “raw” data files. You will need to specify the volume characteristics extent, data type and dimensions. This information may be in a separate text file associated with the data file or it may be specified in a “header” at the beginning of the data file. The application can optionally specify the size of the file header (if any), in other words the number of bytes to skip over before starting to load values. For example we know that a VOL format file normally contains a 40 byte header followed by the data values. So knowing that the Syn_64 example data set is 64x64x64 with unsigned byte data values, the following code will load that data using the generic reader.
SbBox3f extent(-1, -1, -1, 1, 1, 1 ); SbVec3i32 dimensions(64,64,64); SoDataSet::DataType dataType = SoDataSet::UNSIGNED_BYTE; int headerSize = 40; SoVRGenericFileReader* pReader = new SoVRGenericFileReader; pReader->setFilename( “$OIVHOME/src/VolumeViz/Data/Syn_64.vol” ); pReader->setDataChar( extent, dataType, dimensions, headerSize ); SoVolumeData* pVolData = new SoVolumeData(); pVolData->setReader( *pReader );
SbBox3f extent = new SbBox3f(-1, -1, -1, 1, 1, 1 ); SbVec3i32 dimensions = new SbVec3i32(64,64,64); SoDataSet.DataTypes dataType = SoDataSet.DataTypes.UNSIGNED_BYTE; int headerSize = 40; SoVRGenericFileReader Reader = new SoVRGenericFileReader(); Reader.SetFilename( “$OIVHOME/src/VolumeViz/Data/Syn_64.vol” ); Reader.SetDataChar( extent, out dataType, dimensions, headerSize ); SoVolumeData VolData = new SoVolumeData(); VolData.Reader = Reader;
SbBox3f extent = new SbBox3f( -1, -1, -1, 1, 1, 1 ); SbVec3i32 dimensions = new SbVec3i32(64,64,64); SoDataSet.DataTypes dataType = SoDataSet.DataTypes.UNSIGNED_BYTE; int headerSize = 40; SoVRGenericFileReader reader = new SoVRGenericFileReader(); reader.setFilename( "$OIVHOME/src/VolumeViz/Data/Syn_64.vol" ); reader.setDataChar( extent, dataType, dimensions, headerSize ); SoVolumeData volData = new SoVolumeData(); volData.setReader( reader );
If the volume is stored as multiple image files, one slice per image, you can use the SoVRRasterStackReader( C++ | Java | .NET ) class. This is useful to load a so-called “stack of images”. The individual image files may be in any image format supported by Open Inventor, for example JPEG, PNG or TIFF. See the FileType enumeration in the SoTexture node for a complete list of supported image file formats. The images can even be in different formats, but all the images must be the same size. The X and Y dimensions of the volume are determined by the image size. The Z dimension is determined by the number of slices.
DICOM data may also be delivered as multiple images, but there is a separate reader class specifically for this data format which we will discuss in a later section. |
In order to load a stack of images there must exist a file containing a list of the image file names. If necessary the application can create this file “on the fly”. The image file names may be simple file names or complete file paths. If an image file name is a simple file name VolumeViz will try to open it in the directory that contains the list file. The order of the file names in the list file determines how the slices are loaded. VolumeViz assumes the first image is slice zero, at the “back” of the volume, and subsequent slices are loaded in order of increasing Z value.
The list file may also contain an optional header that specifies characteristics of the volume that cannot be inferred from the image files. See the SoVRRasterStackReader( C++ | Java | .NET ) for a complete list of parameters that can be specified. This is useful to specify the volume extent in 3D or for color images to specify that the data values should be taken from a specific channel, for example the Red values in the image.
For the classic TeddyBear example data (not included with VolumeViz but available on the web), the list file might look like this, where the “Size” parameter really means “extent” in this context:
Parameters { Size 10.000000 10.000000 10.000000 1250.000000 1250.000000 500.000000 } teddybear000.jpg teddybear001.jpg teddybear002.jpg teddybear003.jpg teddybear004.jpg ...
Once we have a list file, loading the data is essentially the same as the previous simple example of setting a specific volume reader:
SoVRRasterStackReader* pReader = new SoVRRasterStackReader; pReader->setFilename( "/MyData/teddybear/teddybear.lst" ); SoVolumeData* pVolData = new SoVolumeData; pVolData->setReader( *pReader );
SoVRRasterStackReader Reader = new SoVRRasterStackReader(); Reader.SetFilename( "/MyData/teddybear/teddybear.lst" ); SoVolumeData VolData = new SoVolumeData(); VolData.Reader = Reader;
SoVRRasterStackReader reader = new SoVRRasterStackReader(); reader.setFilename( "/MyData/teddybear/teddybear.lst" ); SoVolumeData volData = new SoVolumeData(); volData.setReader(reader);
Voxels in an RGBA volume are UNSIGNED_INT32 values, containing 8 bits each of Red, Green, Blue and Alpha. All rendering nodes (slices, volume rendering, etc) work with RGBA volumes. Region of Interest, clipping and other features also work with RGBA volumes. However because the volume already specifies the colors to be used for rendering, the data range and transfer function are ignored. Lighting works with RGBA volumes using gradient vectors computed from the luminance value of the voxels.