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.
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( C++ | Java | .NET ) 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( C++ | Java | .NET ) is also enabled in the SoRayPickAction( C++ | Java | .NET ) class, which is derived from SoPickAction( C++ | Java | .NET ). Each action class inherits the enabled elements of its parent.
The SoGLRenderAction( C++ | Java | .NET ) enables the SoViewportRegionElement( C++ | Java | .NET ), 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( C++ | Java | .NET ) enables the SoViewportRegionElement( C++ | Java | .NET ):
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.
When a node is traversed, it may need to change the value of certain elements in the state. For the SoDrawStyle( C++ | Java | .NET ) 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:
The element class asks the state for a modifiable instance of the element, passing in its stack index.
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.
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.
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.
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( C++ ).
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):
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( C++ | Java | .NET ) |
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:
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 |