Web Analytics Made Easy - Statcounter
Skip to content

Data Graph#

The data graph is the central object model of SAMSON.

If your extension creates objects, modifies them, renders them, serializes them, or reacts to their changes, you are working with the data graph. Most of the rest of the SDK makes more sense once this model is clear.

Everything directly or indirectly added by the user, SAMSON, or a SAMSON Extension lives in the data graph as a node.

All data graph nodes derive from SBDDataGraphNode. That includes atoms (SBAtom), bonds (SBBond), models, simulators, controllers, folders, and many other runtime objects.

The figure below shows the document view, which is one way to see the graph structure.

Document data graph

Topology#

The data graph is a directed hierarchy:

  • each node has at most one parent
  • a node may have children
  • documents are roots and have no parent

The parent of a node is retrieved with SBDDataGraphNode::getParent. Child relationships are managed through functions such as SBDDataGraphNode::addChild and SBDDataGraphNode::removeChild, usually reimplemented by derived classes.

In practice, documents organize many node families:

Multiple documents may be opened simultaneously in SAMSON. See User guide: Documents for more information.

Node lifecycle#

A data graph node typically goes through four lifecycle stages:

  • C++ object creation (e.g. with a new operator)
  • Node creation (using the create function)
  • Node destruction (using the erase function)
  • C++ object destruction (usually automatically, or forced with a call to deleteReferenceTarget)

This distinction matters because data graph nodes are also reference targets. In other words, lifetime is tied to the SAMSON referencing system, not to raw pointer ownership.

As a result, nodes should not be destroyed with delete. When a node really needs to be deleted at the C++ level, use a SAMSON pointer:

SBPointer<SBAtom> nodePointer = new SBAtom();

// ...

// Remove all references to the atom, and delete it
nodePointer.deleteReferenceTarget();

Node identity#

Each node has a type, retrievable with api/classSBDDataGraphNode.md#function-gettype.

For example:

SBNode::getTypeString is a convenience helper when you need a textual representation.

Types are often the fastest first filter when searching the graph:

// Find all atoms
SBNodeIndexer nodeIndexer;
SAMSON::getActiveDocument()->getNodes(nodeIndexer, SBNode::Atom);

Each node also has a unique internal index managed by SAMSON. These indices are contiguous and unstable: when nodes are removed, indices may be reused. They are useful for internal tasks such as viewport picking, but they are not a persistent identity you should serialize or store as a long-term external reference.

The index is available through api/classSBDDataGraphNode.md#function-getnodeindex.

See also

SBDDataGraphNode

Flags#

Each data graph node has four commonly used flags:

These flags are accessed through SBDDataGraphNode. Except for the highlighting flag, which is typically temporary, changing them is generally undoable.

api/classSBDDataGraphNode.md#function-getflags returns a combined unsigned int representation of the highlighting and selection flags.

See also

SBDDataGraphNode

Materials and color schemes#

Each data graph node may have a material, which influences its rendering in the viewport. Each material is associated with a color scheme, which determines how colors are assigned to nodes or positions.

When a material is attached to a node, it affects that node and its descendants unless a descendant defines its own material.

See also

SBDDataGraphNode

Node predicates#

SBDDataGraphNode defines node predicates, which are functors used to collect nodes based on conditions.

Common examples:

  • SBNode::IsType(...) to filter by node type
  • SBNode::IsSelected() to filter by selection state

Predicates can be combined through logical operators. For example, collecting selected atoms can be written as:

// Find all selected nodes
SBNodeIndexer nodeIndexer;
SAMSON::getActiveDocument()->getNodes(nodeIndexer,
    SBNode::IsType(SBNode::Atom) && SBNode::IsSelected());

See also

Please refer to Getting Nodes: Node predicates for more information.

Node getters#

The same class also defines node getters, which are functors that retrieve properties and can be combined into predicates.

For example, SBNode::GetType retrieves the type of a node:

// Get the type of a node
SBPointer<SBAtom> nodePointer = new SBAtom();
SBNode::GetType()(nodePointer()); // returns SBNode::Atom

Because getters can participate in comparisons, they can build node predicates. Collecting all atoms can therefore also be written as:

// Find all atoms
SBNodeIndexer nodeIndexer;
SAMSON::getActiveDocument()->getNodes(nodeIndexer,
    SBNode::GetType() == SBNode::Atom);

The expression SBNode::GetType() == SBNode::Atom creates a predicate that is then passed to getNodes.

In general, node getters mirror ordinary getter functions but use an initial capital letter because they are classes. For example:

  • SBNode::GetType corresponds to SBNode::getType
  • SBAtom::GetTemperatureFactor corresponds to api/classSBMStructuralModelNodeAtom.md#function-gettemperaturefactor

See also

Please refer to Getting Nodes: Node getters for more information.

Serialization#

Data graph nodes support serialization through api/classSBDDataGraphNode.md#function-serialize and api/classSBDDataGraphNode.md#function-unserialize.

Serialization is what allows SAMSON to copy, paste, save, load, and otherwise persist node state.

See also

Please refer to Serialization for more information.