Click or drag to resize
SoVolumeSkin Class

Draws a data volume skin.

Inheritance Hierarchy

Namespace: OIV.VolumeViz.Nodes
Assembly: OIV.VolumeViz (in OIV.VolumeViz.dll) Version: 2024.1.0.0 (2024.1.0)
Syntax
public class SoVolumeSkin : SoSlice

The SoVolumeSkin type exposes the following members.

Constructors
  NameDescription
Public methodSoVolumeSkin

Constructor.

Top
Methods
  NameDescription
Public methodAffectsState

Overrides default method on OIV.Inventor.Nodes.SoNode.

(Inherited from SoShape.)
Public methodBeginShape(SoAction, SoShapeTriangleShapes)
Calls BeginShape(action, shapeType, (OIV.Inventor.Details.SoFaceDetail ^)nullptr).
(Inherited from SoShape.)
Public methodBeginShape(SoAction, SoShapeTriangleShapes, SoFaceDetail)

These methods can be used by subclasses to generate triangles more easily when those triangles are part of a larger structure, such as a triangle strip, triangle fan, or triangulated polygon, according to the TriangleShape enumerated type.

(Inherited from SoShape.)
Public methodCallback

Implements primitive generation for all shapes.

(Inherited from SoShape.)
Public methodComputeBBox(SoAction, SbXfBox3d, SbVec3d)

Compute object oriented bounding box (OOB) for subclass using information in the given action (which may not necessarily be an OIV.Inventor.Actions.SoGetBoundingBoxAction).

(Inherited from SoShape.)
Public methodComputeBBox(SoAction, SbBox3f, SbVec3f)

Compute bounding box.

(Overrides SoVolumeShapeComputeBBox(SoAction, SbBox3f, SbVec3f).)
Public methodCopy
Calls Copy(false).
(Inherited from SoNode.)
Public methodCopy(Boolean)

Creates and returns an exact copy of the node.

(Inherited from SoNode.)
Public methodCopyFieldValues(SoFieldContainer)
Calls CopyFieldValues(fc, false).
(Inherited from SoFieldContainer.)
Public methodCopyFieldValues(SoFieldContainer, Boolean)

Copies the contents of fc's fields into this object's fields.

(Inherited from SoFieldContainer.)
Public methodDispose
Releases all resources used by SoDisposable.
(Inherited from SoDisposable.)
Public methodDistribute
(Inherited from SoNode.)
Public methodDoAction
(Inherited from SoNode.)
Public methodEnableNotify

Notification at this Field Container is enabled (if flag == true) or disabled (if flag == false).

(Inherited from SoFieldContainer.)
Public methodEndShape

end shape previously started with OIV.Inventor.Nodes.SoShape.BeginShape(OIV.Inventor.Actions.SoAction, OIV.Inventor.Nodes.SoShape.TriangleShapes, OIV.Inventor.Details.SoFaceDetail).

(Inherited from SoShape.)
Public methodEquals
Determines whether the specified Object is equal to the current Object.
(Inherited from Object.)
Public methodFieldsAreEqual

Returns true if this object's fields are exactly equal to fc's fields.

(Inherited from SoFieldContainer.)
Public methodGet

Returns the values of the fields of this object in the Open Inventor ASCII file format in the given string.

(Inherited from SoFieldContainer.)
Public methodGetAllFields

Returns a list of fields, including the eventIn's and eventOut's.

(Inherited from SoFieldContainer.)
Public methodGetAlternateRep

Returns an alternate represention for this node.

(Overrides SoNodeGetAlternateRep(SoAction).)
Public methodGetBoundingBox

Implements bounding box method using virtual OIV.VolumeViz.Nodes.SoVolumeShape.ComputeBBox(OIV.Inventor.Actions.SoAction, OIV.Inventor.SbBox3f@, OIV.Inventor.SbVec3f@) method.

(Inherited from SoVolumeShape.)
Public methodGetEventIn

Returns a the eventIn with the given name.

(Inherited from SoFieldContainer.)
Public methodGetEventOut

Returns the eventOut with the given name.

(Inherited from SoFieldContainer.)
Public methodGetField

Returns a the field of this object whose name is fieldName.

(Inherited from SoFieldContainer.)
Public methodGetFieldName

Returns the name of the given field in the fieldName argument.

(Inherited from SoFieldContainer.)
Public methodGetFields

Appends references to all of this object's fields to resultList, and returns the number of fields appended.

(Inherited from SoFieldContainer.)
Public methodGetHashCode
Overrides GetHashCode().
(Inherited from SoNetBase.)
Public methodGetMatrix
(Inherited from SoNode.)
Public methodGetName

Returns the name of an instance.

(Inherited from SoBase.)
Public methodGetPrimitiveCount

Counts number of primitives produced by this shape.

(Inherited from SoShape.)
Public methodGetRenderEngineMode

Returns the supported Render engine mode.

(Inherited from SoNode.)
Public methodGetRenderUnitID
(Inherited from SoVolumeShape.)
Public methodGetShapeType

Gets the current shape Full Scene Antialiasing type.

(Inherited from SoShape.)
Public methodGetStringName (Inherited from SoBase.)
Public methodGetType
Gets the Type of the current instance.
(Inherited from Object.)
Public methodGLRender
Public methodGLRenderBelowPath
(Inherited from SoNode.)
Public methodGLRenderInPath
(Inherited from SoNode.)
Public methodGLRenderOffPath
(Inherited from SoNode.)
Public methodGrabEventsCleanup
(Inherited from SoNode.)
Public methodGrabEventsSetup
(Inherited from SoNode.)
Public methodHandleEvent
(Inherited from SoNode.)
Public methodHasDefaultValues

Returns true if all of the object's fields have their default values.

(Inherited from SoFieldContainer.)
Public methodIsBoundingBoxIgnoring

Used by BoundingBoxAction to know if bounding box computation should be ignored or not.

(Inherited from SoShape.)
Public methodIsNotifyEnabled

Notification is the process of telling interested objects that this object has changed.

(Inherited from SoFieldContainer.)
Public methodIsOverride

Returns the state of the override flag.

(Inherited from SoNode.)
Public methodIsSynchronizable

Gets the ScaleViz synchronizable state of this object.

(Inherited from SoBase.)
Public methodPick
(Inherited from SoNode.)
Public methodRayPick

Implements picking along a ray by intersecting the ray with each primitive generated by subclass.

(Inherited from SoShape.)
Public methodSearch
(Inherited from SoNode.)
Public methodSet

Sets one or more fields in this object to the values specified in the given string, which should be a string in the Open Inventor file format.

(Inherited from SoFieldContainer.)
Public methodSetName (Inherited from SoBase.)
Public methodSetOverride

Turns the override flag on or off.

(Inherited from SoNode.)
Public methodSetRenderProgress

Set an application defined OIV.Inventor.SoProgressIndicator object which will raise an event before and after the rendering task, before and after each subtask (in this case: Texture creation and Geometry creation) and after each step in the subtasks which represents in most cases individual tiles of data.

(Inherited from SoVolumeShape.)
Public methodSetShapeType

set the antialiasing type for this shape.

(Inherited from SoShape.)
Public methodSetSynchronizable

Sets this to be a ScaleViz synchronizable object.

(Inherited from SoBase.)
Public methodSetToDefaults

Sets all fields in this object to their default values.

(Inherited from SoFieldContainer.)
Public methodShapeVertex

add a primitive vertex to the shape prevously started with OIV.Inventor.Nodes.SoShape.BeginShape(OIV.Inventor.Actions.SoAction, OIV.Inventor.Nodes.SoShape.TriangleShapes, OIV.Inventor.Details.SoFaceDetail).

(Inherited from SoShape.)
Public methodToString
Converts this SoBase structure to a human readable string.
(Inherited from SoBase.)
Public methodTouch

Marks an instance as modified, simulating a change to it.

(Inherited from SoNode.)
Public methodWrite
(Inherited from SoNode.)
Top
Properties
  NameDescription
Public propertyalphaUse

Specifies how to use the alpha component of each voxel's RGBA value.

(Inherited from SoSlice.)
Public propertyalternateRep

This field optionally holds a subgraph containing only core Open Inventor nodes that can be used for rendering when VolumeViz is not available.

(Inherited from SoSlice.)
Public propertyboundingBoxIgnoring

Whether to ignore this node during bounding box traversal.

(Inherited from SoShape.)
Public propertybumpScale

Specifies the intensity of the bump mapping effect.

(Inherited from SoSlice.)
Public propertycomposition Obsolete.

Specifies color composition mode.

(Inherited from SoVolumeShape.)
Public propertydataSetId

Specifies the OIV.VolumeViz.Nodes.SoVolumeData node to use.

Public propertyenableBumpMapping

Specifies if a bump mapping effect will be applied to the slice.

(Inherited from SoSlice.)
Public propertyfaceMode

Display front (facing the camera) faces or back faces.

Public propertyinterpolation

Interpolation mode.

(Inherited from SoVolumeShape.)
Public propertyIsDisposable
ISafeDisposable interface implementation.
(Inherited from SoDisposable.)
Public propertylargeSliceSupport

Activate/deactivate direct loading of full resolution slice data.

(Inherited from SoSlice.)
Public propertyUserData
Gets or sets the user data to be contained by the field container.
(Inherited from SoFieldContainer.)
Public propertyuseRGBA

Specifies whether to create RGBA textures.

(Inherited from SoSlice.)
Top
Remarks

This node draws the "skin" (outer faces) of the data volume defined by the current OIV.VolumeViz.Nodes.SoVolumeData node. This skin is a set of textured polygons similar to ortho slices.

The current OIV.VolumeViz.Nodes.SoVolumeData node can be specified with OIV.VolumeViz.Nodes.SoVolumeSkin.dataSetId. When this field is set to 0, the last OIV.VolumeViz.Nodes.SoVolumeData node on state is used.

For a non-RGBA (scalar valued) volume, each voxel's RGBA value is determined by the current OIV.LDM.Nodes.SoDataRange and OIV.LDM.Nodes.SoTransferFunction. The current diffuse color and transparency (set, for example, with an OIV.Inventor.Nodes.SoMaterial node) modify the appearance of the voxels. This means that, for example, the current transparency can be used as a global alpha value to modulate the overall opacity. For an RGBA volume each voxel's RGBA value comes directly from the volume data.

When using an opaque transfer function (no alpha values < 1), this node generates the same image as OIV.VolumeViz.Nodes.SoVolumeRender, but with much higher performance, because only slices are rendered. A common pattern is to put an OIV.VolumeViz.Nodes.SoVolumeRender node and an OIV.VolumeViz.Nodes.SoVolumeSkin node under an OIV.Inventor.Nodes.SoSwitch node. This makes it easy to switch between skin rendering and volume rendering.

The interpolation field controls how the texture is interpolated.

Optionally a bump mapping effect may be applied. Normal vectors are automatically computed from the data value gradient. The enableBumpMapping and bumpScale fields control whether bump mapping is active and the intensity of the effect.

The entire skin is pickable, even where it is transparent as a result of the current transfer function. The OIV.VolumeViz.Details.SoVolumeSkinDetail class allows you to get the voxel position and value after picking.

Notes:

  • Drawing position: An OIV.VolumeViz.Nodes.SoVolumeSkin is approximately the same as six ortho slices, but not exactly. The difference is that each face of the skin is drawn at the outer edge of the voxel slice it intersects. So if there is no OIV.LDM.Nodes.SoROI, or the ROI is identical to the volume dimensions, the volume skin faces will be drawn at the limits of the volume extent (bounding box). For OIV.VolumeViz.Nodes.SoOrthoSlice, the geometry passes through the center of the voxels in the specified slice. So 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.

  • Transformation matrices: The volume size and orientation (like geometry) can be modified by transformation nodes in the scene graph and this in turn modifies the appearance of volume rendering nodes like OIV.VolumeViz.Nodes.SoVolumeSkin. However the same transformation must be applied to the volume data node and all volume rendering nodes associated with that volume. So effectively any transformation nodes that affect the volume must be placed before the volume data node.

  • Picking: The entire skin is pickable, even where it is transparent as a result of the current transfer function. The OIV.VolumeViz.Details.SoVolumeSkinDetail class allows you to get the voxel position and value after picking.

  • Clipping: Volume primitives can be clipped using a region of interest (OIV.LDM.Nodes.SoROI), geometry (OIV.VolumeViz.Nodes.SoVolumeClippingGroup) and/or height fields (OIV.VolumeViz.Nodes.SoUniformGridClipping). They are also clipped by OpenGL clipping planes (OIV.Inventor.Nodes.SoClipPlane), but we recommend using the VolumeViz clipping nodes instead. Note that, in general, clipping does not work well with OIV.VolumeViz.Nodes.SoVolumeSkin because the clipped portions of the skin are not "closed", allowing the user to see inside the skin. However the OIV.LDM.Nodes.SoROI node's EXCLUSION_BOX mode does work well and can be used to exclude a sub-region from the skin, forming what is sometimes called a "chair cut".

  • Dragging: It is possible to interactively translate and resize a skin that is limited to a subset of the volume (sometimes called a "volume probe"). This is done using an Open Inventor dragger, e.g. OIV.Inventor.Draggers.SoTabBoxDragger, to adjust an OIV.LDM.Nodes.SoROI node. This is such a common operation that Open Inventor provides the OIV.LDM.Manips.SoROIManip node.

  • Interpolation: Interpolation is specified using the 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 TRILINEAR or MULTISAMPLE_12 value.

  • Material: The color of each voxel is modulated by the current diffuse color in the traversal state. The default diffuse color is 0.8,0.8,0.8. This results in full intensity values in the color map being displayed as 80% intensity. Therefore we recommend adding an OIV.Inventor.Nodes.SoMaterial node before the skin and setting its diffuseColor field to full white (1,1,1).

  • Transparency: Typically the color map (OIV.LDM.Nodes.SoTransferFunction) used for volume rendering (OIV.VolumeViz.Nodes.SoVolumeRender) assigns transparency (alpha < 1) to some voxel values. If you want to use the same color map for skin 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 OIV.Inventor.Nodes.SoMaterial node.

  • Voxel edges: The edges of the voxels can also be rendered. See options in the OIV.VolumeViz.Nodes.SoVolumeRenderingQuality node.

  • Custom shaders: The current OIV.VolumeViz.Nodes.SoVolumeShader node, if any, allows custom shaders to be defined for special computation or rendering effects, including blending multiple volumes.

  • Composition with Multiple Data: It is possible to compose datasets that have different dimensions, tile sizes and transformations. In order to help fetch the correct data values in custom shaders, texture coordinates conversion functions are provided in the VolumeViz/vvizStructure.h shader include. For instance,

    vec3 VVizTextureToTextureVec(in VVizDataSetId datasetSrc, in VVizDataSetId datasetDst, in vec3 texCoord);
    can be used to convert texture coordinates related to one dataset to texture coordinates related to another dataset. The conversion is based solely on the transformations applied to each dataset, which are defined by their model matrix and their extent. Please note that the model matrix of a dataset is defined by to the OIV.Inventor.Nodes.SoTransformation nodes that are placed before the OIV.LDM.Nodes.SoDataSet node in the order of the traversal.

  • Large Slice mode: When the "large slice" mode is enabled (see OIV.VolumeViz.Nodes.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 OIV.VolumeViz.Nodes.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).

  • Performance:

    • Tile size: For backward compatibility, the default tile size is still only 64. This is quite small for modern CPU/GPU hardware. The smaller the tile size, the larger the total number of tiles that must be managed by VolumeViz. This overhead can be significant, especially for operations that require reloading the data textures on the GPU, for example, changing the data range (OIV.LDM.Nodes.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 OIV.VolumeViz.Nodes.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. For volumes stored in LDM file format, the tile size must be specified when the volume is converted to LDM (see OIV.LDM.Converters.SoConverter and the "-t" option). For other data data formats the tile size can be specified using the OIV.VolumeViz.Nodes.SoVolumeData node's ldmResourceParameters field, but only after setting the filename field or calling the SetReader()method.

    • Tile cache policy: It specifies how the tiles are stored in CPU memory. The selected policy can significantly impact the data loading performance versus the CPU memory footprint. See OIV.LDM.Nodes.SoLDMResourceParameters.tileCachePolicy for detail.

    • Compressed textures: For performance reasons, OIV.VolumeViz.Nodes.SoVolumeSkin accumulates small textures into a bigger one. When using compressed RGBA textures (via OIV.LDM.Nodes.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)

EXAMPLE

For simple data sets, a basic VolumeViz rendering could be achieved with only a few nodes: minimally an OIV.VolumeViz.Nodes.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 OIV.VolumeViz.Nodes.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.

SoSeparator volSep = new SoSeparator();
 root.AddChild( volSep );

SoVolumeData volData = new SoVolumeData();
 volData.fileName.Value = "$OIVNETHOME/src/demos/data/VolumeViz/Colt.vol";
 volSep.AddChild( volData );

SoDataRange volRange = new SoDataRange();
if (volData.GetDatumSize() > 1)
{
   double minVal, maxVal;
   volData.GetMinMax( out minVal, out maxVal);
   volRange.min.Value = minVal;
   volRange.max.Value = maxVal;
}
volSep.AddChild( volRange );

SoTransferFunction volTF = new SoTransferFunction();
 volTF.predefColorMap.Value = SoTransferFunction.PredefColorMaps.BLUE_WHITE_RED;
 volSep.AddChild( volTF );

SoMaterial volMat = new SoMaterial();
 volMat.diffuseColor.SetValue(1, 1, 1);
 volSep.AddChild( volMat );

SoVolumeShader volShader = new SoVolumeShader();
 volShader.interpolateOnMove.Value = true;
 volSep.AddChild( volShader );

SoVolumeSkin volSkin = new SoVolumeSkin();
 volSep.AddChild( volSkin );

FILE FORMAT/DEFAULT

VolumeSkin {
dataSetId 0
interpolation LINEAR
alphaUse ALPHA_AS_IS
useRGBA false
enableBumpMapping false
bumpScale 1.0
faceMode FRONT
}

ACTION BEHAVIOR

OIV.Inventor.Actions.SoGLRenderAction Draws a volume-rendered image based on current OIV.VolumeViz.Nodes.SoVolumeData.

OIV.Inventor.Actions.SoGetBoundingBoxAction Computes the bounding box that encloses the volume.

See Also