Hide menu
Scene Graph
Warning
This page describes functionality that is part of Visualization Toolkit add-on, which is licensed separately from the base CAD Exchanger SDK.

Key principles

Visualization scene graph is a hierarchical definition of a 3D model to be rendered.

The scene graph concept has been deliberately chosen to efficiently map CAD-tailored data to visualization semantics. Therefore ModelData_Model used to provide a (mathematical) definition of a 3D model (via assemblies and parts, B-Reps and meshes) so naturally maps to the visualization scene graph. However, the scene graph can also be created directly from custom user’s data, without initial mathematical model.

Scene graph encapsulated by a scene

The scene graph consists of scene nodes and is acyclical (i.e. is a tree). Thus each node may have a single parent and zero, one or more children. A node without a parent is a root node. A scene may have multiple roots.

A scene node is represented by a single class ModelPrs_SceneNode and thus is not typed. Semantics of the node (e.g. whether it corresponds to original part or assembly, or any user-specific data) is application-specific.

A scene node has various data attributes that define visual presentation of the object or the sub-tree the node represents. By convention, geometrical data should only be attached to leaf nodes, whereas other attributes (such as transformations or visual appearances) can be attached to the interim nodes in the hierarchy (see Node attributes inheritance).

A scene node may have attributes that affect display of a sub-tree it represents. These attributes can contain:

  • Mesh or geometrical definition (triangles, polylines, points)
  • Visual appearance (colors, materials, textures, line styles, etc)
  • Transformations (e.g. 3x4 or 4x4 matrices)
  • Display modes (shading or wireframe, semi-transparent or full hiding, etc)

Scene nodes may not be shared among parents, sharing of heavy-weight data (e.g. geometry) is provided via shareable attributes. A scene node is represented by a single class ModelPrs_SceneNode and thus is not typed. Semantics of the node (e.g. whether it corresponds to original part or assembly, or any user-specific data) is application-specific and can be, for instance, defined by attached attributes.

Creating a scene graph

A node (and its sub-graph) is created with the help of ModelPrs_SceneNodeFactory.

Create a scene graph in one call

The following example demonstrates how to create a scene graph from a model:

ModelData_Model aModel = ...;
ModelPrs_SceneNodeFactory aFactory;
// Use B-Rep representations when creating scene nodes from model
ModelPrs_SceneNode aRootNode = aFactory.CreateGraph (aModel, {ModelData_RM_BRep});
ModelPrs_Scene aScene;
aScene.AddRoot (aRootNode);
aScene.Update();

The following diagram demonstrates mapping of a mathematical definition (via ModelData_Model) to the scene graph of the assembly:

Scene graph of an assembly model
Resulting visualization scene graph

The scene node's names on second diagram (blue rectangles) written here for more clear understanding and doesn't store in scene node actually.

Create a scene graph manually

If you need to control the construction of the scene graph, you can manually create the scene nodes and the relationships between them.

The following example demonstrates how to create a scene graph manually from ModelData_Model:

// 1. Visitor for ModelData_Model that creates scene nodes
class ModelVisitor : public ModelData_Model::CombinedElementVisitor
{
public:
ModelVisitor (const ModelPrs_SceneNode& theRoot, const ModelPrs_SceneNodeFactory& theFactory)
: myFactory (theFactory)
{
myNodes.push_back (theRoot);
}
void VisitLeave (const ModelData_SceneGraphElement& /*theSGE*/) override
{
myNodes.pop_back();
}
bool VisitEnter (const ModelData_SceneGraphElement& theSGE) override
{
auto anSGENode = myFactory.CreateNode (theSGE);
myNodes.back().AddChildNode (anSGENode);
myNodes.push_back (anSGENode);
return true;
}
void operator() (const ModelData_Part& thePart) override
{
auto aPartNode = myFactory.CreateNode (thePart);
myNodes.back().AddChildNode (aPartNode);
auto aRep = thePart.BRepRepresentation();
auto aRepNode = myFactory.CreateNode (aRep);
aPartNode.AddChildNode (aRepNode);
}
private:
std::deque<ModelPrs_SceneNode> myNodes;
ModelPrs_SceneNodeFactory myFactory;
};
// 2. Usage of the visitor
ModelPrs_SceneNodeFactory aFactory;
ModelPrs_SceneNode aRoot = ...; // should be initialized
ModelVisitor aVisitor (aRoot, aFactory);
ModelData_Model aModel = ...;
aModel.Accept (aVisitor); // now aRoot has children

Traversing scene graph

Visualization Scene Graph can be traversed with the help of visitors.

Each scene node accepts a visitor which must be a subclass of an abstract class ModelPrs_SceneNodeVisitor with overridden methods. If the redefined VisitEnter() method returns false then the respective subgraph will not be visited.

The following example demonstrates how to count of all scene nodes:

class SceneNodeCounter : public ModelPrs_SceneNodeVisitor
{
public:
SceneNodeCounter() : myNodeCount (0) { }
bool VisitEnter (const ModelPrs_SceneNode& /*theNode*/) override { ++myNodeCount; return true; }
void VisitLeave (const ModelPrs_SceneNode& /*theNode*/) override { }
size_t NodeCount() const { return myNodeCount; }
private:
size_t myNodeCount;
};
SceneNodeCounter aCounter;
aNode.Accept (aCounter);
std::cout << "Node count: " << aCounter.NodeCount() << std::endl;

Node attributes inheritance

The following rules determine how attributes redefined in sub-nodes (i.e. downward when traversing the scene graph) are taken into account:

AtrributeRule
AppearanceCombine with parent's
Display modeOverrides parent’s if defined, or inherited from parent otherwise.
GeometryUsed wherever explicitly defined.
Selection modeOverrides parent’s if defined, or inherited from parent otherwise.
TransformationMultiplication
Visibility modeBoolean AND. Thus, if the node is invisible then its sub-graph is invisible.