public class SoOrthoSlice extends SoSlice
SoVolumeData
node. The slice orientation and position are defined by the axis
and sliceNumber
fields.
For a non-RGBA (scalar valued) volume, each voxel's RGBA value is determined by the current SoDataRange
and SoTransferFunction
. The current diffuse color and transparency (set, for example, with an SoMaterial
node) modifies the appearance of the slice. This means that, for example, the current transparency can be used as a
global alpha value to modulate the overall opacity of the slice. For an RGBA volume each voxel's RGBA value comes directly from the volume data.
The interpolation
field controls how the texture is interpolated.
The alphaUse
field (SoSlice
) controls how the voxel's alpha component is used when drawing the slice.
Optionally a bump mapping effect may be applied. Normal vectors are automatically computed from the data value gradient. The enableBumpMapping
and bumpScale
fields (SoSlice
) control whether bump mapping is active and the intensity of the effect.
Notes:
SoOrthoSlice
geometry passes through the center of the voxels in the specified slice. So, for example, an ortho slice with sliceNumber = 0 will be drawn one-half voxel size (on the slice axis) in from the bounding box of the volume. This is slightly different than SoVolumeSkin
. A volume skin is approximately the same as six ortho slices, but each face of the skin is drawn at the outer edge of the voxel.
SoOrthoSliceDetail
class allows you to get the voxel position and value after picking.
SoTranslate1Dragger
. However the dragger's position in XYZ space must be converted to a slice number. For a dragger that is specific to ortho slices, see the class SoOrthoSliceDragger
.
interpolation
field. The default (LINEAR) does bi-linear interpolation between voxel values. The NEAREST value can be used to display individual voxels. For best image quality we recommend using the MULTISAMPLE_12 value.
SoDataRange
node to specify the actual (or desired) range of data values to be mapped. Also use an SoDataRange
node to implement brightness/contrast control like the Window/Level setting commonly used with medical images.
SoROI
), geometry (SoVolumeClippingGroup
) and/or height fields (SoUniformGridClipping
). They are also clipped by OpenGL clipping planes (SoClipPlane
), but we recommend using the VolumeViz clipping nodes instead. SoClipPlane
, this clipping plane affects all subsequent geometry, including SoVolumeRender
, but does not of course affect the ortho slice itself. The clipping
and clippingSide
fields control whether clipping is active and which half-space is clipped. Clipping side FRONT means that the clip plane (removes) clips away geometry in the positive direction on the slice axis.
SoMaterial
node before the slice and setting its diffuseColor field to full white (1,1,1).
SoTransferFunction
) used for volume rendering (SoVolumeRender
) assigns transparency (alpha < 1) to some voxel values. If you want to use the same color map for slice rendering, but render the slice completely opaque, set the alphaUse
field to ALPHA_OPAQUE. This overrides the alpha values in the color map (or an RGBA volume). However it does not affect transparency assigned using an SoMaterial
node. SoMaterial
node and set its transparency field (keeping alphaUse set to ALPHA_AS_IS). Effectively a scale factor 1-transparency is applied to each voxel's alpha value. SoGLRenderAction
.
SoVolumeRenderingQuality
node.
SoVolumeShader
node, if any, allows custom shaders to be defined for special computation or rendering effects, including blending multiple volumes.
SoSlice.largeSliceSupport
), if all the required full resolution tiles have already been loaded, then the slice data is taken from LDM system memory cache as usual. But if some required tiles are not currently in memory, the required slice data will be loaded directly from the volume reader
without loading the complete tiles. This reduces disk I/O and reduces the amount of system memory required to display the slice at full resolution, so larger (or more) slices can be displayed. The required tiles are then scheduled to be loaded asynchronously in case adjacent slices are displayed later. For example, loading a 1024x1024 SoOrthoSlice
from an 8-bit dataset with 128x128x128 tiles would normally require loading 1024x1024x128 bytes of data (as complete tiles). With largeSliceSupport enabled, only 1024x1024 bytes (maximum) of data need to be loaded (in the worst case where no high resolution data is currently in memory).
SoDataRange
). For smaller volumes, like 512^3, it can be efficient to set the tile size large enough to contain the entire volume. For very large volumes, larger tile sizes are efficient for SoVolumeRender
but somewhat inefficient for slice rendering because complete tiles must be loaded even though the slice only uses part of the data. Applications should experiment. SoConverter
and the "-t" option). For other data data formats the tile size can be specified using the SoVolumeData
node's
ldmResourceParameters field, but only after setting the
filename field or calling the setReader() method. SoDataRange
). We recommend setting this variable to false (see SoPreferences
) unless saving CPU memory is critical. SoOrthoSlice
accumulates small textures into a bigger one. When using compressed RGBA textures (via SoDataSet
's field useCompressedTexture), this optimization cannot be done. If you want to favor performance rather than memory usage, you should disable compression (enabled by default if supported by the graphic card)
For simple data sets, a basic VolumeViz rendering could be achieved with only a few nodes: minimally an SoVolumeData
node to identify the data set and one rendering node. However most data sets need at least some of the additional nodes shown here in order to get a correct and useful rendering. Most applications will need additional nodes to take advantage of region of interest, interaction, clipping and other VolumeViz features. Please consider the code shown here as simply a guideline and a starting point for exploring the many powerful features available in Open Inventor.
Note that some of the property nodes (data, material, color map, etc) will typically be shared by multiple rendering nodes. In other words the volume usually only needs to be loaded once, using a single SoVolumeData
node, then multiple slices and/or regions can be rendered using that data node.
Also note that this example is for a data volume, where each voxel can be considered a discrete sample from a continuous data field and interpolation should be used to compute values between voxel centers. If you are rendering a label volume, then each voxel is an "id" assigning that voxel to a specific material, object, etc. In this case, set the interpolation field to NEAREST to disable interpolation.
// Default setting can be a performance bottleneck SoPreferences.setValue( "LDM_USE_IN_MEM_COMPRESSION", "0" ); // Keep volume viz separate from geometry SoSeparator volSep = new SoSeparator(); root.addChild(volSep); // Load volume data SoVolumeData volData = new SoVolumeData(); volData.fileName.setValue( "$OIVJHOME/data/VolumeViz/3DHead.vol" ); volSep.addChild( volData ); // Set range of data values to visualize. // Not required for 8-bit voxels, critical for larger data types. // The getMinMax() call may be expensive for non-LDM file formats. SoDataRange volRange = new SoDataRange(); if (volData.getDatumSize() > 1) { double[] minmax; minmax = volData.getDoubleMinMax(); volRange.min.setValue( minmax[0] ); volRange.max.setValue( minmax[1] ); } volSep.addChild( volRange ); // Load opaque intensity ramp SoTransferFunction volTF = new SoTransferFunction(); volTF.predefColorMap.setValue( SoTransferFunction.PredefColorMaps.INTENSITY ); volSep.addChild( volTF ); // Display slice at full intensity SoMaterial volMat = new SoMaterial(); volMat.diffuseColor.setValue( 1, 1, 1 ); volSep.addChild( volMat ); // Remove tile boundary artifacts while moving. SoVolumeShader volShader = new SoVolumeShader(); volShader.interpolateOnMove.setValue( true ); volSep.addChild( volShader ); // Display a Z axis slice at center of volume SoOrthoSlice slice = new SoOrthoSlice(); SbVec3i32 voldim = volData.data.getSize(); slice.axis.setValue( SoOrthoSlice.AxisType.Z ); slice.sliceNumber.setValue( voldim.getZ() / 2 ); slice.interpolation.setValue( SoVolumeShape.Interpolations.MULTISAMPLE_12 ); volSep.addChild( slice );
File format/default:
OrthoSlice {
sliceNumber | 0 |
axis | Z |
interpolation | LINEAR |
alphaUse | ALPHA_BINARY |
useRGBA | false |
clipping | false |
clippingSide | BACK |
alternateRep | NULL |
enableBumpMapping | false |
bumpScale | 1.0 |
Action behavior:
SoGLRenderAction
Draws a textured rectangle based on current SoVolumeData
, SoTransferFunction
, and SoROI
nodes. Sets: SoClipPlaneElement
SoGetBoundingBoxAction
Computes the bounding box that encloses the slice.
See also:
SoDataRange
, SoObliqueSlice
, SoOrthoSliceDragger
, SoROI
, SoSlice
, SoTransferFunction
, SoVolumeData
Modifier and Type | Class and Description |
---|---|
static class |
SoOrthoSlice.AxisType
Slice Axis (see discussion of medical data axes in the class description)
|
static class |
SoOrthoSlice.ClippingSides
Clipping Side mode.
|
SoSlice.AlphaUses
SoVolumeShape.Compositions, SoVolumeShape.Interpolations
SoShape.ShapeTypes
Inventor.ConstructorCommand
Modifier and Type | Field and Description |
---|---|
SoSFEnum<SoOrthoSlice.AxisType> |
axis
Slice axis (X, Y, or Z).
|
static int |
BACK
Deprecated.
Use
SoOrthoSlice.ClippingSides.BACK instead. |
SoSFBool |
clipping
Activate/deactivate a clipping plane on a per-slice basis.
|
SoSFEnum<SoOrthoSlice.ClippingSides> |
clippingSide
Specify the clipping side.
|
static int |
FRONT
Deprecated.
Use
SoOrthoSlice.ClippingSides.FRONT instead. |
SoSFUInt32 |
sliceNumber
Slice number.
|
static int |
X
Deprecated.
Use
SoOrthoSlice.AxisType.X instead. |
static int |
Y
Deprecated.
Use
SoOrthoSlice.AxisType.Y instead. |
static int |
Z
Deprecated.
Use
SoOrthoSlice.AxisType.Z instead. |
ALPHA_AS_IS, ALPHA_BINARY, ALPHA_OPAQUE, alphaUse, alternateRep, bumpScale, enableBumpMapping, largeSliceSupport, useRGBA
ALPHA_BLENDING, composition, COMPOSITION_LAST, CUBIC, interpolation, LINEAR, MAX_INTENSITY, MIN_INTENSITY, MULTISAMPLE_12, NEAREST, SUM_INTENSITY, TRILINEAR
boundingBoxIgnoring, LINES, POINTS, POLYGONS, TEXT
VERBOSE_LEVEL, ZeroHandle
Constructor and Description |
---|
SoOrthoSlice()
Constructor.
|
intersect
getShapeType, isPrimitiveRestartAvailable, isPrimitiveRestartAvailable
affectsState, callback, copy, copy, distribute, doAction, getAlternateRep, getBoundingBox, getByName, getMatrix, getPrimitiveCount, getRenderUnitID, GLRender, GLRenderBelowPath, GLRenderInPath, GLRenderOffPath, grabEventsCleanup, grabEventsSetup, handleEvent, isBoundingBoxIgnoring, isOverride, pick, rayPick, search, setOverride, touch, write
copyFieldValues, copyFieldValues, enableNotify, fieldsAreEqual, get, getAllFields, getEventIn, getEventOut, getField, getFieldName, hasDefaultValues, isNotifyEnabled, set, setToDefaults
dispose, getEXTERNPROTO, getName, getPROTO, isDisposable, isSynchronizable, setName, setSynchronizable
getAddress, getNativeResourceHandle, startInternalThreads, stopInternalThreads
@Deprecated public static final int X
SoOrthoSlice.AxisType.X
instead.@Deprecated public static final int Y
SoOrthoSlice.AxisType.Y
instead.@Deprecated public static final int Z
SoOrthoSlice.AxisType.Z
instead.@Deprecated public static final int FRONT
SoOrthoSlice.ClippingSides.FRONT
instead.@Deprecated public static final int BACK
SoOrthoSlice.ClippingSides.BACK
instead.public final SoSFUInt32 sliceNumber
public final SoSFEnum<SoOrthoSlice.AxisType> axis
public final SoSFEnum<SoOrthoSlice.ClippingSides> clippingSide
These figures show an ortho slice clipping a data volume.
Right:
Bottom left:
Bottom right:
| ![]() |
![]() | ![]() |
public final SoSFBool clipping
SoClipPlane
, this clipping plane affects all subsequent geometry, including SoVolumeRender
, but does not of course affect the ortho slice itself. The clippingSide
field controls which half-space is clipped.Generated on January 23, 2025, Copyright © Thermo Fisher Scientific. All rights reserved. http://www.openinventor.com