This is the base class from which all nodekit nodes are derived. Nodekits provide a convenient mechanism for creating groups of scene graph nodes with some larger meaning. When you create a shape node such
as an indexed face set, for example, you almost always precede it with a coordinate node. You may also want to add a transform node or specify properties with material, drawing style, material binding,
etc. Instead of creating each of these nodes individually and then arranging them into a subgraph, you can use a nodekit of the appropriate type (in this case,
SoShapeKit).
Each class of nodekit has a
nodekit catalog (
SoNodekitCatalog) that describes
the nodes in the subgraph, referred to as
parts. The catalog has an entry for each part, with information such as the
partName,
partType, and
nullByDefault (if FALSE the constructor creates it). The catalog also describes the arrangement
of parts in the subgraph. (Other information is described below; a complete description is in the
SoNodekitCatalog reference page.)
If we regard the scene graph arrangement as a branching tree, then the top node (root)
of the arrangement is always the nodekit itself. The leaf nodes are those at the bottom (containing no children). Some leaves of the tree are defined in the catalog to be
public parts, while other leaves
are
private. All non-leaf parts are considered internal to the nodekit structure and are marked private. Public parts are accessible; they may be requested, changed, or set by the programmer with member functions
such as
getPart(). Private parts are not accessible, so methods such as
getPart() will have no effect on them. For example, if you call
getPart() to retrieve a private part,
NULL will be returned even when the part exists.
Every
nodekit reference page has a Parts section describing the function of each public part it adds to those inherited from its parent class. Also, a Catalog Parts section has tables of often-needed information
from the catalog (part type, etc.). These tables include all public parts, both new and inherited. Only the public parts of a nodekit are described in the reference pages. Nodekits take care of the rest
for you; they automatically arrange the subgraph, creating and deleting the private parts when necessary. (The
SoNodekitCatalog reference page has methods for finding out the part names and arrangement of all parts,
both public and private.)
The nodekit catalog is a template shared by all instances of a class. They use the shared catalog as a
guide when creating parts (i.e., constructing actual nodes), but each instance
stores its own parts separately. Moreover, nodekits are
not SoGroup nodes, and parts are added as
hidden children; you can only access parts with the methods of
SoBaseKit and its derived classes.
Any public part may be retrieved with
getPart(),
installed with
setPart(), or removed by giving a
NULL argument to
setPart(). Paths from the nodekit down to a part can be created by
createPathToPart().
By default, parts are not created until the user requests or sets them. This keeps the
subgraph uncluttered and efficient for traversal. Additionally, removing a part (setting it to NULL) has the extra effect of removing any internal parts that are no longer needed.
Since nodekits hide their
children, any
SoPath containing nodekits will end at the topmost nodekit. However, since nodekits may be nested within other nodekits, you may wish to cast an
(SoPath *) into an
(SoNodeKitPath *). The methods of
SoNodeKitPath allow you to view all
nodekits that lie on the path (see the reference page for
SoNodeKitPath).
Public parts in the nodekit catalog fall into three categories:
[1]
regular nodes
[2]
nodekits, or
nested nodekits (which may nest recursively). Any node which is public in a
nested nodekit is accessible to the higher level nodekit(s) that contains it. The description of
getPart() below shows how to refer to nested parts by name (e.g.,
"appearance.material"). This works for any nodekit method that
takes a part name for an argument.
[3]
lists, or
list parts. These parts group together children (
list elements) of a particular type or types. As with nested nodekits, you can refer to individual elements using notation described
in
getPart() (e.g.,
"childList[0]", or if the list elements are in turn nodekits,
"childList[2].transform").
When the catalog denotes that a part is a list, the part itself is always a node of type
SoNodeKitListPart. The catalog specifies a set of permissible
listItemTypes and
a
listContainerType for that part. It gives this information to the
SoNodeKitListPart when it creates it. From then on, the list part will enforce type checking. So even if you retrieve the
SoNodeKitListPart with
getPart(), you will not be able to add illegal
children. (See the
SoNodeKitListPart reference page for more information). As an example, the
callbackList part of
SoBaseKit has an
SoSeparator container and allows only
SoCallback and
SoEventCallback nodes in the list. Children may be added, retrieved, and removed from
an
SoNodeKitListPart node using methods that parallel those of
SoGroup. However, type-checking is strictly enforced.
Note that, although all public parts are leaves in the nodekit catalog, you are free to add children to them
(assuming that they are groups, nodekits, or list parts). A part's status as a leaf in the catalog just means that the nodekit will not manage the part's children. For example,
SoWrapperKit has a part called
contents with
a part type of
SoSeparator. You can put whatever you want underneath the separator, as long as
contents itself is an
SoSeparator.
Thus, a nodekit only controls a section of the scene graph. Above and below that section, anything
goes.
However, when nodekits are nested, they effectively create a larger `known' section of the scene graph. For example, the
appearance part of the
SoSeparatorKit is a leaf node in the
SoSeparatorKit catalog. But
appearance is in turn an
SoAppearanceKit, containing
parts such as
material and
drawStyle. The two nodekits combine to make an even larger template, which the
SoSeparatorKit can examine by looking at the catalogs for both classes. So an
SoSeparatorKit can successfully return a part named
"material"; first it
finds (or creates) the
appearance part, then it gets the
material by calling
getPart() on the
appearance.
When the catalog defines the
listItemTypes of a list part to be nodekits, the name-able space expands further. For example,
SoSeparatorKit has a part
childList which
permits only
SoSeparatorKits, so each list element can be further searched. Hence the name
"childList[0].childList[1].childList[2].material" is perfectly legal.