Managing attribute inheritance

The PRC assembly tree is hierarchical. As such, certain attributes may be inherited from parent node to child node. Inheritable attributes include visibility, color, transparency, layer, line pattern, and line width. Each type of attribute may be inherited independently. Collectively, all the attributes make up the entity's behavior. HOOPS Exchange uses the concepts of father inheritance and son inheritance to determine how attributes are propagated down the tree.

Inheritance always propagates in one direction - from parent to child. Each type of inheritance has a certain strength that determines whether or not the attribute is passed to child nodes.

Let's look at a few examples that show how inheritance works in an assembly tree. For this example, we'll use color because it is easy to visualize. In the diagrams below, the colored boxes represent nodes. The color in the top half of each box is the color that was set locally on that node. The color in the bottom half is the color that is actually expressed in the geometry due to the rules of inheritance.

In this diagram, son inheritance in the first box overrides the father inheritance in box 2. The orange color continues to propagate down the tree; however, the blue box also has son inheritance. Thus, orange stops and blue is propagated.

Here, father inheritance overrides the color for the boxes in which inheritance is not set at all. Even though the box at the bottom of the tree has father inheritance and sets the color to red, the box is orange because attributes in the topmost node with father inheritance will override attributes in any child nodes with father inheritance.

If no inheritance is set, color will only inherit to child nodes with no color of their own. However, the red box has father inheritance, so red is used for that box.

How does this look in code? Well, behaviors are always associated with an entity's graphical data. Thus, if you need to find the inheritance type for a product occurrence node, you could do something like the following:

// get root-base-with-graphics data from 'myProductOccurrence' node
A3DRootBaseWithGraphicsData rootBaseWithGraphics;
A3D_INITIALIZE_DATA(A3DRootBaseWithGraphicsData, rootBaseWithGraphics);
A3DRootBaseWithGraphicsGet(myProductOccurrence, &rootBaseWithGraphics);
// get graphics data associated with the root-base-with-graphics
A3DGraphicsData graphicsData;
A3D_INITIALIZE_DATA(A3DGraphicsData, graphicsData);
A3DGraphicsGet(rootBaseWithGraphics.m_pGraphics, &graphicsData);
// graphicsData.m_usBehaviour has the behavior information

You may have noticed that the field graphicsData.m_usBehaviour is a simple type - A3DUns16, and is used as a bit field. Thus, to get the value for color, you need to perform bitwise operations:

A3DUns16 colorInheritance = graphicsData.m_usBehaviour & kA3DGraphicsSonHeritColor;
if (colorInheritance)
// it is of type kA3DGraphicsSonHeritColor
colorInheritance = graphicsData.m_usBehaviour & kA3DGraphicsFatherHeritColor;
if (colorInheritance)
// it is of type kA3DGraphicsFatherHeritColor
// test for other behavior types

You can see all possible values for the behavior bit field in A3DSDKGraphics.h.

Entity references

As mentioned previously, attributes such as color and transform are usually computed for an entire entity after considering the effects of the inheritance. In some cases, however, it would be useful to be able to completely override the computed attribute and replace it with another. Additionally, it is not possible to apply an attribute to a single subentity - such as a face - at the product occurrence level. Entity references solve these problems.

The product occurrence node has an entity reference field of type A3DMiscEntityReference. If this field is not NULL, this indicates the node's attributes should be supplanted by the attributes in the entity reference. You can use this mechanism to redefine color, transparency, visibility, and transformation. Attributes defined in this way are inheritable to child entities.

Subentity attributes

The same pattern is used to apply attributes at the subentity level. For example, when a face has a different color than the rest of the model, it will use an entity reference. Doing so requires the model to have a B-rep definition, because tessellation alone does not have a concept of individual faces. This type of reference is of type A3DMiscReferenceOnTopology.

Other behaviors

This section mainly dealt with color, but the same concepts apply to all behaviors. One behavior that may require special consideration is the kA3DGraphicsShow flag, which controls entity visibility. Unlike other behaviors, the value is ignored if a kA3DGraphicsSonHeritShow or kA3DGraphicsFatherHeritShow flag is set. Therefore, an invisible entity must have its graphics data set up like this:

A3DGraphicsData sGraphicData;
A3D_INITIALIZE_DATA(A3DGraphicsData, sGraphicData);
sGraphicData.m_usBehaviour &= ~kA3DGraphicsShow;
top_level:1 prog_guide:3