Chapter 3: Nodes and Groups

This chapter explains the concept of a scene graph, and shows how to build scenes out of groups, properties and shapes. It also describes the concepts of actions, traversal, and traversal state.

Some notes: The phrase "Inventor supports" is used to indicate the features that are built-in to Inventor. Programmers can extend the toolkit to support almost anything. Also, I will be showing the ASCII file format for the examples in the book, even though the book doesn't present them this way (it shows examples of building scenes through C++ code). I've also gone a little beyond just summarizing the book here, adding my own comments as notes.

Up to Summary of The Inventor Mentor
Back to Chapter 2 - An Inventor Sampler
On to Chapter 4 - Cameras and Lights


Scene Graphs

Inventor programs store their scenes in structures called "scene graphs". A scene graph is made up of "nodes", which represent 3D objects that are drawn (shapes), properties of the 3D objects (properties), nodes that contain other nodes and are used for hierarchical grouping (groups), and others (cameras, lights, etc).

What Happens When You Apply an Action to a Node?

Inventor defines a standard set of "actions" that can be applied to a scene, such as rendering, getting the world-space bounding box of the scene, or picking (finding out what objects are underneath the mouse pointer). Each node implements its own action behavior.

What's in a Node?

Each node contains one or more pieces of information stored in "fields". For example, the Sphere node contains only its radius, stored in its "radius" field. Each field class defines methods to get and set its values. Side note: well-behaved nodes (all standard Inventor nodes are well-behaved) use only the contents of their fields and their position in the scene to determine how they behave when traversed during an action.

Shape Nodes

Inventor supports the following different types of shapes:

Property Nodes

The way shapes are drawn is affected by property nodes in the scene. Inventor supports the following properties:

Groups

The order in which the shapes are drawn is determined by group nodes which contain other nodes known as the groups "children". Inventor supports the following kinds of group nodes: Inventor draws the scene graph in a recursive fashion starting by drawing the first (root) node, then drawing its children (if it is a group). A property must be drawn before a shape node to affect it.

The simplest kind of group node is "Group", which just draws its children in order.

Separators

Separator nodes are used to isolate parts of the scene from the rest of the scene. A property node inside a Separator will not affect any nodes outside the Separator. For example, a robot's head and body might be specified in the file format like this:

#Inventor V2.0 ascii
Separator {
    Separator { # Body
	Transform { translation 0 3 0 }
	Material { # A bronze color:
	    ambientColor .33 .22 .27
	    diffuseColor .78 .57 .11
	    specularColor .99 .94 .81
	    shininess .28
	}
	Cylinder { radius 2.5 height 6 }
    }
    Separator { # Head
	Transform { translation 0 7.5 0 }
	Material { # A silver color:
	    ambientColor .2 .2 .2
	    diffuseColor .6 .6 .6
	    specularColor .5 .5 .5
	    shininess .5
	}
	Sphere { }
    }
}
The use of Separator nodes keeps the translation of the body from affecting the translation of the head.

Other Subclasses of SoGroup

Switch is a kind of group with a field that specifies which children should be drawn. It can be set to draw only one child, to draw no children, or to draw all of the children (in which case it acts like a Group node).

LevelOfDetail is a kind of group that draws only one of its children based on how big the object appears on the screen. It can be used to draw a simpler version of the object with fewer polygons when the object is far away.

Shared Instancing of Nodes

Adding the same node to more than one group creates a "shared instance". Instancing is useful for geometry that is shared; only one copy of the geometry needs to be read in and stored in memory. For example, we can modify the robot scene graph to add legs, like this:

#Inventor V2.0 ascii
Separator {
    Separator { # Body
	Transform { translation 0 3 0 }
	Material { # A bronze color:
	    ambientColor .33 .22 .27
	    diffuseColor .78 .57 .11
	    specularColor .99 .94 .81
	    shininess .28
	}
	Cylinder { radius 2.5 height 6 }

	Separator { # Left leg
	    Transform { translation 1 -4.25 0 }
	    DEF +0 Group { # Shared leg geometry
		Cube { width 1.2 height 2.2 depth 1.1 }
		Transform { translation 0 -2.25 0 }
		Cube { width 1 height 2.2 depth 1 }
		Transform { translation 0 -2 .5 }
		Cube { width .8 height .8 depth 2 }
	    }
	}
	Separator { # Right leg
	    Transform { translation -1 -4.25 0 }
	    USE +0 # Use the leg geometry again
	}
    }
    Separator { # Head
	Transform { translation 0 7.5 0 }
	Material { # A silver color:
	    ambientColor .2 .2 .2
	    diffuseColor .6 .6 .6
	    specularColor .5 .5 .5
	    shininess .5
	}
	Sphere { }
    }
}
The DEF/USE +0 syntax is used to refer to the same node more than once; if several nodes were multiply instanced, Inventor would write out each with a unique number after the '+'.

Paths

When programming Inventor, the concept of a "Path" is important. A path is a chain of nodes, from parent to child, through the scene graph. Paths are returned from picking and searching; for example, if the user clicks the mouse on the left foot of the robot, a path from the root of the scene, through the body separator, the left-leg separator, through the leg group, and finally down to the last cube in the leg group would be returned. Paths are necessary because nodes may be multiply instanced; the cube representing the foot cannot be returned when the user picks on the left foot, because the same cube is used for both the left and right feet.

Fields within a Node

The next few sections of the book discuss how to set and get the value of single and multiple-valued fields of various types. Each type of field has its own set of methods for getting and setting its value(s). For example, MFFloat, which is a type of field that contains zero or more floating point values, has methods for setting one value, for deleting a range of values, for returning the number of values currently being stored, etc.

Fields have an "ignored" flag that can be set and queried. Fields in nodes that are marked ignored will have no effect. The ignore flag is written to file as a "~" character after (or in place of) the field's value.

Nodes have an "override" flag that can be used to force temporary changes to the scene. For example, to draw everything as lines a program might put a

DrawStyle { style LINES }
near the beginning of the scene and set its ignored flag; any subsequent DrawStyle nodes in the scene will be ignored. The override flag is not written to (or read from) file.

References and Deletion

Nodes are managed while in memory with a reference counting mechanism that allows a node to be created, added to a scene, and then forgotten; the node gets properly deleted when the scene is deleted, even if it is multiply instanced.

Node Types

Inventor provides programmers with a run-time type mechanism for its node, engine, action, detail and event classes, that allows programmers to find out if an object is of a given type, to find out what class an object is derived from, etc.

Naming Nodes

Nodes can be given names. Once given a name, they can be quickly looked up by name. Names follow the rules for C++ identifiers ([a-zA-Z_][a-zA-Z0-9_]*

Side note: we will probably relax this to be any sequence of characters not containing the characters +'"\{} because Inventor 2.0 does not check to see if names are valid, and because some Inventor customers already have programs that give their nodes names like "Object1:foo[1,14]"). Names are read and written to files using the 'DEF' keyword; for example, a cube named Joe would be written as:

DEF Joe Cube { }
Side note: if multiply instanced, it might be written as Joe+18, but its name is still just Joe.


Glossary

Action
An operation on a scene. In Inventor, actions are derived from the SoAction abstract base class. Actions include the GLRenderAction, RayPickAction, WriteAction, SearchAction, GetMatrixAction, HandleEventAction and GetBoundingBoxAction.
Bounding Box
An axis-aligned box that is guaranteed to contain some part of the scene. Inventor uses bounding boxes to optimize certain operations.
Field
One or more pieces of data stored in a node or engine.
Group
A node that contains other nodes as children.
Node
The generic name for any object that is part of the scene, such as lights, cameras, shapes.
Path
A series of nodes, each of which is a parent of the next node in the series. Paths are returned as the result of pick and search actions.
Picking
The process of determining which objects intersect a line shooting through the scene. Typically, this line is the projection of the 2D mouse cursor into the 3D scene.
Property
A node that affects other nodes in the scene.
Scene, Scene Graph
A set of nodes grouped together that represent a virtual environment or 3D world.
Shape
A node that represents a visible object, like a cube, sphere, or set of polygons.
Traversal
The process of allowing each node in the scene to perform some action (for example, to draw itself).
Type
The class of an object; what kind of thing an object is. For example, all cubes are of type Cube. They are also of type Shape and Node.

Author/Summarizer:
Gavin Bell


Up to Summary of The Inventor Mentor
Back to Chapter 2 - An Inventor Sampler
On to Chapter 4 - Cameras and Lights