1.4.4. Oblique Slice

The SoObliqueSlice( C++ | Java | .NET ) node defines an oblique (arbitrarily oriented) slice which is the intersection of the volume data defined by an SoVolumeData( C++ | Java | .NET ) node and the plane defined by the plane field. The plane is defined by an SbPlane( C++ | Java ) which allows the plane to be defined several different ways. As shown below, the standard definition is a normal vector and the distance from the origin (0,0,0). The normal vector does not need to be normalized (this is done internally). For example, if the 3D extent of the volume is centered on zero, then the plane defined by the vector (0,0,1) and the distance 0 is a Z axis slice at the center of the volume, approximately the same as the first example SoOrthoSlice( C++ | Java | .NET ). The difference is that ortho slices are positioned at a specified voxel and are drawn through the center of that voxel, but oblique slices are positioned in 3D coordinates and do not necessarily pass through the center of any voxel. Similarly if the Z extent of the volume is -1..1, then the plane defined by vector (0,0,1) and distance 1 specifies a Z axis slice on the front face of the volume, similar to (part of) what SoVolumeSkin( C++ | Java | .NET ) would draw. The sample code below specifies an oblique slice at an arbitrary orientation within the volume.


C++
SoObliqueSlice* pObSlice = new SoObliqueSlice;
pObSlice->plane = SbPlane( SbVec3f(0.4f, 0.4f, 0.8f), 0 );

.NET
SoObliqueSlice obSlice = new SoObliqueSlice();
obSlice.plane.Value = new SbPlane( new SbVec3f(0.4f,0.4f,0.8f), 0 );

Java
SoObliqueSlice obSlice = new SoObliqueSlice();
obSlice.plane.setValue( new SbPlane( new SbVec3f(0.4f,0.4f,0.8f), 0 ) );
Oblique slice

Figure 1.34. Oblique slice


An SbPlane( C++ | Java ) may also specified using three points that lie on the plane or using a normal vector and a point on the plane. In addition an SbPlane( C++ | Java ) object may be rotated and translated by a matrix using the transform method. Because an oblique slice is positioned and oriented in 3D coordinates, standard Open Inventor draggers can be easily used to interact with the slice. For example an SoTranslate1Dragger( C++ | Java | .NET ) can be used to move the slice along its normal vector and an SoTrackballDragger( C++ | Java | .NET ) can be used to rotate the slice.

All the usual slice properties for appearance and clipping apply to oblique slices. Like other slices, SoObliqueSlice( C++ | Java | .NET ) is rendered by extracting data values from the intersected voxels on the CPU and generating a 2D texture which is stored on the GPU. Unlike other slices, SoObliqueSlice( C++ | Java | .NET ) supports the interpolation option TRILINEAR, which is used during the data extraction process. By interpolating from neighboring voxels along all three axes, this generally produces more accurate and higher quality images when the slice is rotated away from the primary axes of the volume.

VolumeViz does not support thickness as a slice property. However a "thick slice" (also known as "thin slab") rendering equivalent to an oblique slice can be achieved using volume rendering (SoVolumeRender( C++ | Java | .NET )), a flat uniform clipping grid with thickness (SoUniformGridClipping( C++ | Java | .NET )) and a transform node (for example SoTransform( C++ | Java | .NET )) to position and orient the clipping grid. See Section 1.7.3, “Height field clipping”

It is also possible to extract the voxel values intersected by an oblique slice. For example an application doing Multiplanar Reconstruction (MPR) could extract the voxel values corresponding to an oblique slice and display the slice as a 2D image in a separate window using SoColorMap( C++ | Java | .NET ) and SoIndexedTexture2( C++ | Java | .NET ). SoLDMDataAccess( C++ | Java | .NET ) provides a getData() method that takes an SbPlane( C++ | Java ) and can be used to extract the data on an oblique slice. This is explained further in Section 1.10, “Data Access and Computing”