public abstract class SoVolumeReader extends SoFieldContainer
Application developers may implement custom reader classes. Custom reader classes allow VolumeViz to access data stored in other file formats. This is particularly useful for converting data to LDM format. A custom reader class could also allow VolumeViz to access data through a proprietary data manager or data stored in application memory.
Minimum implementation:
The application must implement a class derived from SoVolumeReader
, and must implement the methods getDataChar()
and getSubSlice(). In addition, the optional methods getNumSignificantBits()
and getMinMax()
can be implemented. If getNumSignificantBits()
is not implemented (or returns 0), then the number of significant bits depends on the data type. If getMinMax()
is not implemented (or returns false), then VolumeViz will find the min and max voxel values. Note that this requires loading all the data and could take a lot of time for a large volume.
VolumeViz always calls getDataChar()
and getNumSignificantBits()
before requesting any data from the reader.
If the isDataConverted()
method is not implemented (or returns false), then VolumeViz will only call getSubSlice() to request data and will build the LDM tile hierarchy in memory, using the slice data. In this case, note that:
SoLDMResourceParameters
object associated with the SoVolumeData
node. This field can be set by the application, but VolumeViz will not automatically set it (as it does in the case of an LDM reader). Of course a custom reader could implement the getTileSize()
method for the application to call, even though VolumeViz doesn't use it.
SoVolumeData
node, VolumeViz will build the histogram. This requires loading all the data and could take a lot of time for a large volume. However if VolumeViz builds the histogram, it also finds the min and max values, so there is no extra time required for that query.
LDM (tiled) volume reader:
In addition to the usual requirements for an application-defined reader, e.g., implementing the getDataChar()
method, an application-defined reader for LDM data is required to:
isDataConverted()
method and return true. SoVolumeData
to ensure that LDM manager classes are correctly initialized.
readTile()
method. readTile()
method, be aware that how the SoCpuBuffer object is created affects how its memory will be managed. In general you should create the object using the constructor with no parameters, then allocate memory inside the object using the setSize() method. In this case the buffer object owns the memory and the memory will be freed when LDM no longer needs this tile. This implies for example that to avoid data copying when reading tile data from a file, you should create and allocate the buffer object, map the buffer object, then read the data into the buffer object. If you create the buffer object "wrapping" an existing block of memory, that memory will not be freed when LDM releases the buffer object. The application owns that memory and is responsible for freeing it.
SoCpuBufferObject
that use less system memory:
SoCpuBufferUniform
: This buffer contains a "uniform" tile in which all the voxels have the same value. It is stored efficiently as a single value until needed.
SoCpuBufferCompressed
: This buffer contains a compressed tile. It is stored efficiently in its compressed form until needed.
SoCpuBufferBasicProperty
: This buffer contains a standard tile, but can also store the tile's min and max data values for use in various optimizations.
getTileSize()
method
An application-defined LDM reader may optionally:
getMinMax()
method SoDataRange
node. If this method is not implemented, and the application calls SoVolumeData.getMinMax() is called, then VolumeViz must
load every tile to compute the volume min and max. This can cause a long delay.
getTileMinMax()
method SoLDMGlobalResourceParameters.setIgnoreFullyTransparentTiles
. If this method is not implemented, VolumeViz will automatically compute the min and max values for each tile when it is loaded. Automatic computation works fine for volume data, but we
strongly recommend implementing this method for height field data.
General information:
Starting with Open Inventor 7.0, general rectilinear grids are supported. This feature allows non-uniform voxel spacing along each axis of the volume. The AmiraMesh reader (.am file), the in-memory reader, and the LDM reader support rectilinear coordinates. Call the method setRectilinearCoordinates to specify rectilinear coordinates (if they are not already stored in the data file and set by the reader).
Starting with Open Inventor 7.0, SoVolumeReader
is derived from SoFieldContainer
. This allows client classes like SoVolumeData
to be automatically notified when the reader's state changes, and update their own state appropriately. Any reader method that changes the volume properties (dimension, size, data type, etc) should trigger notification by calling the reader's touch()
method. If this notification is not done, client node fields, for example SoDataSet.extent
, won't be updated correctly. For example, a reader with a method setData(SbVec3i32 size, void* data) that loads a new data set should call touch()
at its end. This reader could also be implemented using an SoSFArray3D
field instead of the setData method. Modifying this field will automatically trigger notification.
Applications should subclass from SoVolumeReader
when creating any type of custom volume reader, including an LDM (tiled) volume reader. The classes SoLDMReader
and SoVRLdmFileReader
are internal classes which are specific to the VSG defined LDM file format.
This class cannot be instantiated directly.
File extension | Reader class | Description |
.am | SoVRAmFileReader | Avizo Mesh file format |
.dc3, .dic, .dicom | SoVRDicomFileReader | DICOM file format |
.fld | SoVRAvsFileReader | AVS field file format |
.lda or .ldm | SoVRLdmFileReader | LDM file format |
.sgy or .segy | SoVRSegyFileReader | SEG Y rev 1 file format |
.vol | SoVRVolFileReader | Vol file format |
.vox | SoVRVoxFileReader | Vox file format |
.lst | SoVRRasterStackReader | Lst file format (stack of images) |
File format notes:
SoVRAmFileReader
for limitations.
SoVRAvsFileReader
.
SoVRDicomFileReader
SoVolumeConverter
). Preprocessing volume data into this format provides the maximum benefits from the VolumeViz large data management (LDM) features. See SoVRLdmFileReader
.
SoVRSegyFileReader
.
SoVRVolFileReader
.
SoVRRasterStackReader
for details and limitations.
Note: '3D TIFF' files (multiple images in one file) are not currently supported.
See also:
Modifier and Type | Class and Description |
---|---|
static class |
SoVolumeReader.Axis
Which axis to handle.
|
static class |
SoVolumeReader.CoordinateTypes
Coordinate type used by this data set.
|
static class |
SoVolumeReader.DataInfo |
static class |
SoVolumeReader.ReadErrors
Read error.
|
static class |
SoVolumeReader.ReaderTypes
Available reader type.
|
Inventor.ConstructorCommand
VERBOSE_LEVEL, ZeroHandle
Modifier and Type | Method and Description |
---|---|
void |
closeAllHandles()
Close all resources that are locked by the reader.
|
static SoVolumeReader |
getAppropriateReader(java.lang.String filename)
Returns a preconfigured
SoVolumeReader instance that can be used to load the given file (based on the filename extension). |
int |
getBorderFlag()
Deprecated.
As of Open Inventor 9000 No longer used. Only kept to read old file format that contains borderFlag.
|
SoVolumeWriter |
getConfiguredWriter()
Returns a volume writer that corresponds to this reader
(same format, parameters, etc). |
SoVolumeReader.CoordinateTypes |
getCoordinateType()
Returns coordinate type used by the data set.
|
SoVolumeReader.DataInfo |
getDataChar()
Gets the characteristics (file header) of the data volume.
|
boolean |
getDirectCoordSys()
Return whether the coordinate system used is direct or not.
|
boolean |
getDirectCoordSysAutoDetection()
Return automatic detection value.
|
double[] |
getDoubleMinMax()
Returns min max for float data type, if available.
|
java.lang.String |
getFilename()
Returns the path of the file.
|
int[] |
getIntMinMax()
Deprecated.
As of Open Inventor 9500 Use getMinMax(int64_t & min, int64_t & max) instead.
|
long[] |
getMinMax()
Returns min and max for integer data type, if available.
|
int |
getNumSignificantBits()
This method is optional.
|
SbVec3i32 |
getNumVoxels(SbVec3i32 realSize,
SbVec3i32 subsamplingLevel)
Utility function provided by
SoVolumeReader for subclass readers to call. |
java.lang.String |
getOriginalFilename()
Returns original file name from which the data has been converted to LDM format if stored in file.
|
SoVolumeReader.ReaderTypes |
getReaderType()
Returns the reader type.
|
SbVec3i32 |
getSizeToAllocate(SbVec3i32 realSize,
SbVec3i32 subsamplingLevel)
Utility function provided by
SoVolumeReader for subclass readers to call. |
void |
getSubSlice(SbBox2i32 subSlice,
int sliceNumber,
SoBufferObject bufferObject)
This method is called by Open Inventor during an LDM conversion or during volume loading.
|
SbVec2d |
getTileMinMax(int fileId)
Returns the minimum and maximum data values for the given tile.
|
SbVec3i32 |
getTileSize()
Returns tile dimensions in voxels when using data stored in tiles.
|
boolean |
isDataConverted()
Returns true if the data is already organized in tiles for the LDM module.
|
boolean |
isRGBA()
Returns true if the data set contains RGBA color values.
|
boolean |
isThreadSafe()
Should return true if the reader is thread safe.
|
SoBufferObject |
readTile(int index,
SbBox3i32 tilePosition)
Given an index, reads a tile if the data is organized in tiles (for LDM).
|
boolean |
readTile(int index,
SoBufferObject buffer,
SbBox3i32 tilePosition)
Deprecated.
As of Open Inventor 8500 Use SoBufferObject* readTile(int index, const SbBox3i32& tilePosition) instead.
|
void |
restoreAllHandles()
Restore resources that were closed by
closeAllHandles() . |
boolean |
setDirectCoordSysAutoDetection(boolean autoValue)
Sets whether or not the reader should automatically try to detect if the coordinate system used is direct or not.
|
boolean |
setDirectCoorSys(boolean directCoord)
Specify if the coordinate system used is direct or not.
|
int |
setFilename(java.lang.String filename)
Specifies the path of the file.
|
boolean |
setInputDataRange(boolean doChange,
double min,
double max)
Requests that the input be converted from the specified range to the range depending on the output data type.
|
boolean |
setOutputDataType(boolean doChange,
SoDataSet.DataTypes outputType)
Sets the output data type.
|
void |
setRectilinearCoordinates(float[] x,
float[] y,
float[] z)
Sets rectilinear coordinates for the data set.
|
void |
setRGBA(boolean flag)
Specifies if data must be considered as RGBA.
|
copyFieldValues, copyFieldValues, enableNotify, fieldsAreEqual, get, getAllFields, getEventIn, getEventOut, getField, getFieldName, hasDefaultValues, isNotifyEnabled, set, setToDefaults
dispose, getName, isDisposable, isSynchronizable, setName, setSynchronizable, touch
getNativeResourceHandle
public boolean isDataConverted()
public java.lang.String getFilename()
public int setFilename(java.lang.String filename)
public SbVec3i32 getTileSize()
public SoBufferObject readTile(int index, SbBox3i32 tilePosition)
index
- specifies a fileID, the id of an existing tile (fileID=tileID in a cubical volume).
tilePosition
- specifies the position of the data in the associated volume data of the tile corresponding to the given index. In the default SoVRLdmFileReader
, the tilePosition isn't actually used but it is passed as a convenience for customized readers (can be used for mapping to a different index scheme).
Returns the pointer to a buffer (allocated by the reader) containing data.public SbVec3i32 getSizeToAllocate(SbVec3i32 realSize, SbVec3i32 subsamplingLevel)
SoVolumeReader
for subclass readers to call.
If the reader uses the NO_COPY policy, this method returns the size to allocate for the brick. For each axis of the brick, this size is:
(first power of 2 greater than realSize) / ( 2** subsamplingLevel)
public SoVolumeReader.DataInfo getDataChar()
setFilename()
to specify the file location, in which case you will not have to open the file yourself. Then you can use the convenience method getBuffer() to read the header in order to get the requested information.
NOTE: We strongly recommend that readers implement this version of getDataChar
, introduced in VolumeViz 5.1, because it uses SbVec3i32
for the volume dimension.
public boolean setOutputDataType(boolean doChange, SoDataSet.DataTypes outputType)
public SoVolumeReader.ReaderTypes getReaderType()
public static SoVolumeReader getAppropriateReader(java.lang.String filename)
SoVolumeReader
instance that can be used to load the given file (based on the filename extension).
For example, would return an instance of SoVRDicomFileReader
for a file named "data.dic".
If no SoVolumeReader
is associated to this extension through registerVolumeReaderExtension() then NULL is returned.
public boolean setInputDataRange(boolean doChange, double min, double max)
public void getSubSlice(SbBox2i32 subSlice, int sliceNumber, SoBufferObject bufferObject)
When loading or converting a large volume data, the size of the given bufferObject may exceed 2^31 elements. In that case, it is not possible to get the Java array that backs the bufferObject because an array cannot contain more than 2^31 elements in Java. That may lead to generate a Java.lang.IllegalArgumentException with a negative capacity message.
That occurs in the following situation: In order to build the root tile of the model, LDM call getSubSlice with a buffer of size S = Si * Sj * data type size. Si is the lowest power of 2 bigger than the I dimension of the volume. Sj is the lowest power of 2 bigger than the J dimension of the volume. For instance if the volume contains 17000*35000*1500 short values, a buffer of size 32768*65536*2 bytes is requested. This example will lead to an exception.
subSlice
- 2D region of the slice to return.
sliceNumber
- Slice number on the volume Z axis (first slice is 0).
bufferObject
- The target buffer to be filled.public SbVec3i32 getNumVoxels(SbVec3i32 realSize, SbVec3i32 subsamplingLevel)
SoVolumeReader
for subclass readers to call.
Returns the size of the brick the reader must use, based on subsamplingLevel and realSize of the brick. If the subsampling level is greater than 0 on an axis, the corresponding size is computed as follows:
For example, if subsamplingLevel[0]=1 and realSize[0]=21, then the returned readerSize[0]=16.
If subsamplingLevel is 0, the corresponding size is the realSize.
public int getNumSignificantBits()
If it is not implemented, the default return value is 0, meaning the number of bits depends on the data type. See the last parameter of SoVolumeData.setVolumeData(). This method is called immediately after getDataChar()
. For float data type, number of bits is forced to 32.
@Deprecated public int getBorderFlag()
public boolean isRGBA()
public void setRectilinearCoordinates(float[] x, float[] y, float[] z)
@Deprecated public int[] getIntMinMax()
getMinMax(int64_t & min, int64_t & max)
instead. public void closeAllHandles()
SoVolumeWriter
associated with the same file can re-open it in write mode. The reader remembers the resources that were closed, so they can re-opened by calling restoreAllHandles()
.public void restoreAllHandles()
closeAllHandles()
.@Deprecated public boolean readTile(int index, SoBufferObject buffer, SbBox3i32 tilePosition)
SoBufferObject
(allocated by LDM) as the target of the data.
If not reimplemented then the version with "unsigned char*" parameter is calledDeprecated since Open Inventor 8500. readTile(int index, const SbBox3i32& tilePosition)
instead. public void setRGBA(boolean flag)
public SoVolumeReader.CoordinateTypes getCoordinateType()
public double[] getDoubleMinMax()
SoDataRange
node. If this method is not implemented, and the application calls SoVolumeData.getMinMax() is called, then VolumeViz must load every tile to compute the volume min and max. This can cause a long delay.public boolean setDirectCoordSysAutoDetection(boolean autoValue)
public long[] getMinMax()
SoDataRange
node. If this method is not implemented, and the application calls SoVolumeData.getMinMax() is called, then VolumeViz must load every tile to compute the volume min and max. This can cause a long delay.public boolean isThreadSafe()
public java.lang.String getOriginalFilename()
public SbVec2d getTileMinMax(int fileId)
SoLDMGlobalResourceParameters.setIgnoreFullyTransparentTiles
.
VolumeViz will only call this method if the data is organized in tiles like the LDM file format. In other words, if isDataConverted()
returned true. The LDM Converter program automatically computes this information and stores it in the LDM header file. Custom volume readers that implement tiled data, i.e. return true when isDataConverted
is called, should implement this method if possible, but it is not mandatory. If this method is not implemented, VolumeViz will automatically compute the min and max values for each tile when it is loaded.
NOTE: Automatic computation of tile min/max values works fine for actual volume data. But we
strongly recommend implementing this method for height field data (see SoHeightFieldGeometry
etc). Because of the way the height field algorithm works, if tile min/max info is not available, VolumeViz must load
all height field tiles before the first render. This can cause a long delay before the first rendering appears.
Default implementation returns new SbVec2d
(Double.MAX_VALUE, -Double.MAX_VALUE)
fileId
- The fileId of the tile.public SoVolumeWriter getConfiguredWriter()
Notes:
For example:
MyVolumeReader reader = new MyVolumeReader(); reader.setFilename( "someFile.dat" ); MyVolumeWriter writer1 = (MyVolumeWriter)reader.getConfiguredWriter(); // This writer will write to "someFile.dat" reader.setFilename( "someOtherFile.dat" ); // The writer will still write to "someFile.dat" writer1.setFilename( "stillAnotherFile.dat" ); SoVolumeWriter writer2 = reader.getConfiguredWriter(); // writer2 will write to "someOtherFile.dat", because // the reader is configured to read from "someOtherFile.dat"
public boolean getDirectCoordSys()
public boolean getDirectCoordSysAutoDetection()
public boolean setDirectCoorSys(boolean directCoord)
Generated on July 31, 2019, Copyright © Thermo Fisher Scientific. All rights reserved. http://www.openinventor.com