1.2.6. Converting to LDM

Summary:

The converter is multi-threaded and takes advantage of multiple cores on a single machine.

The converter will incrementally load the input volume, divide the volume into tiles (according to the default or specified tile size), compute the tiles in the lower resolution levels (according to the default or specified subsampling algorithm), compute a histogram for the volume and compute min/max values for the volume (and for each tile). Optionally the converter can compress each tile (according to the default or specified algorithm) and/or convert the data to a different data type. For example converting float data to small integer data to conserve disk space.

[Important]

In the documentation, most of the information appears in the base class SoConverter( C++ | Java | .NET ).

In this section we will discuss:

VolumeViz includes an example command line application (see src/VolumeViz/Converters) to convert other data formats into the LDM file format. Converting data from a format already supported by VolumeViz is straightforward because the converter automatically uses the appropriate volume reader class.

A basic command line converter program would look like this:


C++
int main( int argc, char ** argv)
{
  SoVolumeRendering::init();

  // Create parameter object from command line args
  SoConverterParameters* pParameters = SoConverterParameters::create(argc,argv);

  // Start converter 
  SoVolumeConverter converter;
  int ret = converter.convert( pParameters );

  delete pParameters;
  SoVolumeRendering::finish();
  return ret;
}

.NET
public class CommandLine
{
  public static void Main(string[] args)
  {
    // Create parameter object from command line args
    SoConverterParameters parameters = 
        SoConverterParameters.Create(args.Length, args);

    // Start converter 
    SoVolumeConverter converter = new SoVolumeConverter();
    int result = converter.Convert( parameters );
  }
}

Java
public class Main
{
  public static void main(String[] args)
  {
    // Create parameter object from command line args
    SoConverterParameters parameters = 
        SoConverterParameters.create(args.length, args);

    // Start converter 
    SoVolumeConverter converter = new SoVolumeConverter();
    int result = converter.convert( parameters );
  }
}

The application can convert input files to LDM before loading them into VolumeViz. Use this technique to create custom converter programs or to offer the application user the option to do a one-time conversion to LDM when a new data file is selected. The following code fragment requests conversion of an input file to LDM format with compression enabled. The application can specify the location and name of the output files (there will normally be a .ldm file and a .dat file) using the setHeaderFileName() method. If not specified, the output header file will be the input file name with “.ldm” substituted for the file extension. In other words “MyFile.dcm” becomes “MyFile.ldm”.


C++
// Create parameter object with input file and desired options
SoConverterParameters* pParameters = new SoConverterParameters;
pParameters->setInputFileName( inputFileName );
pParameters->setCompressionName( “gzip” );

// Start converter
SoVolumeConverter converter;
int ret = converter.convert( pParameters );

.NET
// Create parameter object with input file and desired options
SoConverterParameters parameters = new SoConverterParameters();
parameters.SetInputFileName( inputFileName );
parameters.SetCompressionName( “gzip” );

// Start converter 
SoVolumeConverter converter = new SoVolumeConverter();
int result = converter.Convert( parameters );

Java
// Create parameter object with input file and desired options
SoConverterParameters parameters = new SoConverterParameters();
parameters.setInputFileName( inputFileName );
parameters.setCompressionName( “gzip” );

// Start converter 
SoVolumeConverter converter = new SoVolumeConverter();
int result = converter.convert( parameters );

The converter saves the progress of the conversion in case the user wishes to stop converting and start visualizing the converted data or if the conversion fails for any reason. In this case, the LDM files (header and data) are associated with a completion file (name of the header file with an extension of .fcp). When restarting the converter, if the header file points to a .fcp file (XML tag <completionFilename>), the conversion will restart where it previously ended. When visualizing an incompletely converted file, it is possible to know where data actually exists by turning on the topology outlines (using SoLDMGlobalResourceParameters( C++ | Java | .NET )::setVisualFeedbackParam()). Red outlines indicate actual data.

In order to restart an incomplete conversion, the header file must be in synch with the completion file. For this reason when writing the pair of header/completion files, the converter first backs up the pair of files before overwriting them (.ldm and .fcp with .bck extension). If the header file is lost or its size is less than the size of the backed up header file, then you can rename the backed up completion and header files to restart the conversion.

It is often useful to store additional information in the LDM file header using custom XML tags. The standard volume converter does not automatically carry over format specific information that may be important to the application later. For example medical applications typically want to carry over information from DICOM tags and seismic applications typically want to carry over information from the SEGY header like the range of line numbers. In Section 1.2.5, “LDM Data” we explained how to get custom tags from the LDM header when loading a volume. Here we will explain how to put custom tags into the LDM header when converting a volume to LDM format.

For example we could add the following (example) tags to the header file. Note the LDM volume reader’s XML parser is basic and only supports text and additional tags inside a tag. There must be both an open and a close tag for each tag.

<MY_SEISMIC_SURVEY>
  Some text
  <InlineRange>    720 978 3 </InlineRange>
  <CrosslineRange> 460 658 3 </CrosslineRange>
</MY_SEISMIC_SURVEY>
[Important]

It is important that the name of the custom tag section is unique and does not conflict with LDM tag names that exist now or are added in the future. We recommend embedding your company or organization name.

Register a callback function that will write the custom tags with the converter class. This function will be called once, immediately after the opening tag of the header has been written.


C++
SoVolumeConverter converter;
converter.setXmlCallback( xmlCBFunction, NULL );
int ret = converter.convert( pParameters );

Use the standard system file output methods to write the text for the custom tags. A callback function to write the example custom tags could look like this:


C++
 void xmlCB( FILE *fp, void *userData )
{
  fprintf( fp, "<MY_CUSTOM_TAG_SECTION>\n" );
  fprintf( fp, " Some text...\n" );
  fprintf( fp, " <CUSTOM_TAG1>value1</CUSTOM_TAG1>\n" );
  fprintf( fp, " <CUSTOM_TAG1>value1</CUSTOM_TAG1>\n" );
  fprintf( fp, "</MY_CUSTOM_TAG_SECTION>\n" );
}