1.2. Actions, State, and Elements

The Inventor database maintains a traversal state that is used when an action is applied to a scene graph. As described in The Inventor Mentor , the traversal state is a class (SoState) used by Inventor to store state information during execution of an action. Typically, the scene graph is traversed from top to bottom and from left to right. The traversal state is modified by the nodes encountered during this traversal. State is the way nodes in the scene graph communicate with each other. For example, shape nodes need to know whether the draw style is INVISIBLE in order to know whether to draw themselves. They use the draw-style element in the state to find out.

For simplicity and extensibility, each integral piece of information in the state is stored in a separate element . For example, the current diffuse color of the material is stored in an instance of the SoDiffuseColorElement class.

Enabling Elements

Each action class has its own notion of enabling certain elements. These elements are enabled when an instance of the action is created. By default, all elements in the state are disabled, which means that they can't be set or inquired. Both nodes and actions can enable the elements they require in the state for a particular action class. The list of elements to enable is set up ahead of time, typically in the initClass() method for the node or action before instances of either are constructed. The macro SO_ENABLE() provides a convenient way for nodes to enable elements for a particular action class. For example, the SoPickStyle SoPickStyle SoPickStyle node requires the pick-style element when picking, so its initClass() method enables this element in the pick action as follows:

SO_ENABLE(SoPickAction, SoPickStyleElement);

A side effect of this call is that SoPickStyleElement SoPickStyleElement SoPickStyleElement is also enabled in the SoRayPickAction SoRayPickAction SoRayPickAction class, which is derived from SoPickAction SoPickAction SoPickAction . Each action class inherits the enabled elements of its parent.

The SoGLRenderAction SoGLRenderAction SoGLRenderAction enables the SoViewportRegionElement SoViewportRegionElement SoViewportRegionElement , because the action is responsible for setting up this element in the state (the viewport region is specified in the action's constructor). This is how the SoGLRenderAction SoGLRenderAction SoGLRenderAction enables the SoViewportRegionElement SoViewportRegionElement SoViewportRegionElement :

enableElement(SoViewportRegionElement::getClassTypeId());

(Nodes typically use the SO_ENABLE() macro, and actions use the enableElement() method, since it's simple.) It doesn't hurt to enable an element in the state more than once (for example, a node and an action might enable the same element). If you are using the debugging library and you try to set or inquire an element that has not been enabled, an error message is printed. (See Appendix A, Error Handling.)

When an action is applied to a scene graph, the action builds an instance of SoState and passes a list of enabled elements to the state constructor. (If the list changes after an action is constructed, the action automatically rebuilds its state to include the newly enabled elements the next time the action is applied.)

Adding new element classes to Inventor is described in Chapter 5.

Setting Elements in the State

When a node is traversed, it may need to change the value of certain elements in the state. For the SoDrawStyle SoDrawStyle SoDrawStyle node, the code to change the current value of the lineWidth element looks like this:

if (! lineWidth.isIgnored())
   SoLineWidthElement::set(action->state, this,
                           lineWidth.getValue());

In this fragment, this is the node that is setting the value, and lineWidth.getValue() is the new value for the element.

Each enabled element has its own stack in the state with a unique stack index. Separators save and restore the state by pushing and popping these element stacks. The top element in the stack contains the current value for that element during traversal. Here is a brief summary of what happens behind the scenes when a node sets the value of an element in the state:

  1. The element class asks the state for a modifiable instance of the element, passing in its stack index.

  2. The state looks into the appropriate stack and creates a new instance on top of the stack, if necessary. It first checks whether the current value of the element was set by a node with its Override flag set to TRUE. If this flag is set, it returns NULL, since you can't modify the value.

    If the Override flag is not set, the new top instance of the element is returned to the element class.

  3. The element changes the value in this instance.

Figure 1.3, “ Nodes, Actions, Elements, and State summarizes the relationship among nodes, actions, elements, and the state.

Nodes, Actions, Elements, and State

Figure 1.3.  Nodes, Actions, Elements, and State



Getting Elements in the State

Each element provides a static get() method that returns its value from the top element in the stack. For example,

width = SoLineWidthElement::get(state);

returns the line width from the top element in the stack. Elements with multiple values provide a different sequence of get() methods, as described in Chapter 2.

State Elements

Supported element classes are listed here. The class name of each listed element is preceded by So and followed by Element. For brevity, the names are abbreviated in this list. Thus, the first item is SoAmbientColorElement .

These elements store information about the current set of materials:

AmbientColor

ambient color of current material

DiffuseColor

diffuse color of current material

EmissiveColor

emissive color of current material

Shininess

shininess value of current material

SpecularColor

specular color of current material

Transparency

transparency of current material

These elements store information about the current lighting model and light source:

LightAttenuation

amount of attenuation of light sources over distance

LightModel

current lighting model

These elements store information relevant to textures:

TextureBlendColor

color used when blending texture

TextureCoordinateBinding

how to bind texture coordinates to shapes

TextureCoordinate

current set of texture coordinates

TextureImage

current texture image

TextureMatrix

current cumulative texture transformation matrix

TextureModel

how texture is applied to material component

TextureWrapS

how image wraps in s (horizontal) direction

TextureWrapT

how image wraps in t (vertical) direction

These elements contain information about how to draw and interact with shapes:

ClipPlane

current set of clipping planes

Complexity

current complexity

ComplexityType

how to interpret complexity: screen-space metric, bounding box, and so on

Coordinate

current set of coordinates

CreaseAngle

cutoff crease angle for smoothing when computing default normals

DrawStyle

current drawing style (filled, lines, and so on)

MaterialBinding

how to bind materials to shapes

NormalBinding

how to bind surface normals to shapes

Normal

current set of surface normals

PickStyle

current pick style

These elements store profile information (for 3D text and NURBS surfaces):

ProfileCoordinate

current coordinates used in profiles

Profile

set of current profiles

These elements store information about transformations:

BBoxModelMatrix

current cumulative object transformation matrix

LocalBBoxMatrix

transformation matrix from object space to local coordinate space during application of an SoGetBoundingBoxAction SoGetBoundingBoxAction SoGetBoundingBoxAction

ModelMatrix

current cumulative object transformation matrix

ProjectionMatrix

current projection matrix

Units

current factor for converting between units of measure

ViewingMatrix

current camera viewing transformation matrix

These elements are related to text objects:

FontName

name of current font

FontSize

size of current font

These elements hold information about current GL modes:

LinePattern

current dash pattern for drawing lines

LineWidth

current width for drawing lines

PointSize

current point size

ShapeHints

current shape hints

These elements hold information about viewing:

CullVolume

current culling volume

FocalDistance

current focal distance of the camera

PickRay

current ray to use for picking

ViewVolume

current viewing volume

ViewportRegion

current viewport region

These elements hold traversal information:

Cache

whether caching is active, whether cache is valid, and currently open caches (see Section 1.4, “Caching”)

Switch

current child to traverse in switch nodes

Many of the elements named above have GL-specific versions that are used only for rendering. The following elements have only GL versions:

GLCacheContext

cache context

GLColorIndex

index into the current GL color map of the base color of the current surface material

CurrentGLMateria

l current state of GL materials (indices of last values sent to GL plus a flag indicating whether lighting is currently active); used to optimize the calls made to OpenGL

GLLightId

integer identifier of current source (counts from 0)

GLMaterialIndex

indices into the current GL material map of the ambient, diffuse, and specular components of the current surface material, as defined by GL's color index lighting model

GLRenderPass

current rendering pass for multi-pass rendering (an integer)

GLTextureEnabled

whether textures are currently enabled

GLTextureQuality

current shape GLTextureQuality

GLUpdateArea

rectangular area within the current viewport region that needs to be updated when rendering