Open Search
    HierarchyObjectInterface Manual

    About

    maxon::HierarchyObjectInterface is a base interface used to create elements that can be organized in a tree like structure. A parent element can have one or many child elements. A child element can have only one parent but none, one or many siblings.

    A parent object can organize its child elements in multiple sub-branches.

    Hierarchy Interface

    The hierarchy interface provides functions to insert an element into a given tree structure:

    // This example creates several elements and inserts them under the "root" element.
    // At the end, the order of elements is checked.
    // create "root" element
    const TreeElementRef root = TreeElementFactory().Create("root"_s) iferr_return;
    // create child elements
    const TreeElementRef elementA = TreeElementFactory().Create("Element A"_s) iferr_return;
    const TreeElementRef elementB = TreeElementFactory().Create("Element B"_s) iferr_return;
    const TreeElementRef elementC = TreeElementFactory().Create("Element C"_s) iferr_return;
    // insert first element under the root element
    elementC.InsertAsLastChildOf(root) iferr_return;
    // insert second element as a sibling under the root element
    elementB.InsertBefore(elementC) iferr_return;
    // insert third element under the root element
    root.InsertChildAsFirst(elementA) iferr_return;
    // check element order
    const auto children = root.GetChildren() iferr_return;
    for (const auto& child : children)
    {
    const TreeElementRef treeElement = maxon::Cast<TreeElementRef>(child);
    const maxon::String name = treeElement.GetName();
    DiagnosticOutput("Child Element: @", name);
    }
    const char const char * name
    Definition: abstract.h:195
    Definition: string.h:1235
    #define DiagnosticOutput(formatString,...)
    Definition: debugdiagnostics.h:176
    #define iferr_return
    Definition: resultbase.h:1519

    Child elements can be replaced or removed:

    // This example creates multiple elements, inserts them as
    // child elements of the "root" element and removes them again.
    // create "root" element
    const TreeElementRef root = TreeElementFactory().Create("root"_s) iferr_return;
    // create child elements
    const TreeElementRef elementA = TreeElementFactory().Create("Element A"_s) iferr_return;
    const TreeElementRef elementB = TreeElementFactory().Create("Element B"_s) iferr_return;
    const TreeElementRef elementC = TreeElementFactory().Create("Element C"_s) iferr_return;
    // insert child elements
    root.InsertChildAsFirst(elementA) iferr_return;
    root.InsertChildAsFirst(elementB) iferr_return;
    // replace element
    elementB.Replace(elementC) iferr_return;
    // remove element
    elementA.Remove();
    // check remaining element
    const maxon::HierarchyObjectRef<> firstChild = root.GetFirstChild();
    const TreeElementRef firstElement = maxon::Cast<TreeElementRef>(firstChild);
    DiagnosticOutput("First Child: @", firstElement.GetName());
    Definition: hierarchyobject.h:18

    Within a given hierarchy level one can navigate with:

    // This example gets the first child element of the given "root" element
    // and loops through all remaining child elements.
    // get first child element
    maxon::HierarchyObjectRef<> child = root.GetFirstChild();
    while (child)
    {
    // check type of child
    if (child.IsInstanceOf<TreeElementRef>())
    {
    const TreeElementRef treeElement = maxon::Cast<TreeElementRef>(child);
    DiagnosticOutput("Tree Element: @", treeElement.GetName());
    }
    // get next child
    child = child.GetNext();
    }

    The parent of an element is accessed with:

    The child elements of a parent object are accessed with:

    // This example inserts and accesses child elements in different branches.
    // define branch IDs
    const maxon::ConstDataPtr branchA = maxon::ConstDataPtr("a"_s);
    const maxon::ConstDataPtr branchB = maxon::ConstDataPtr("b"_s);
    // insert child elements into branches
    root.InsertChildAsFirst(elementA, branchA) iferr_return;
    root.InsertChildAsFirst(elementB, branchB) iferr_return;
    // get child elements from branches
    const maxon::HierarchyObjectRef<> childA = root.GetFirstChild(branchA);
    const maxon::HierarchyObjectRef<> childB = root.GetFirstChild(branchB);
    Definition: datatypebase.h:1800

    These observables are called on certain events:

    • ObservableHierarchyInsert: Is called when an element was inserted in the hierarchy.
    • ObservableHierarchyRemove: Is called when an element was removed from the hierarchy.

    To navigate through a given hierarchy one can use these utility functions:

    // This example traverses over all child elements of the given root element and the root element itself.
    maxon::TraverseMeAndChildren<TreeElementRef>(root,
    [](const TreeElementRef& child, const TreeElementRef& parent, const maxon::ConstDataPtr& branch, maxon::Int depth) -> maxon::Result<maxon::Bool>
    {
    DiagnosticOutput("Tree Element: @", child.GetName());
    return true;
    // This example traverses over all child elements of the given root element but not the root element itself.
    maxon::TraverseChildren<TreeElementRef>(root,
    [](const TreeElementRef& child, const TreeElementRef& parent, const maxon::ConstDataPtr& branch, maxon::Int depth) -> maxon::Result<maxon::Bool>
    {
    DiagnosticOutput("Tree Element: @", child.GetName());
    return true;
    Definition: resultbase.h:766
    Int64 Int
    signed 32/64 bit int, size depends on the platform
    Definition: apibase.h:188

    It is also possible to iterate over all elements of a hierarchy using maxon::HierarchyObjectIterator:

    // This example uses the HierarchyObjectIterator template to iterate over
    // all child elements of the given root element and the root element itself.
    for (const TreeElementRef& element : maxon::HierarchyObjectIterator<TreeElementRef>(root))
    {
    DiagnosticOutput("Tree Element: @", element.GetName());
    }
    Definition: hierarchyobject.h:410
    PyObject * element
    Definition: unicodeobject.h:1016

    Custom Implementations

    A custom interface can be based on maxon::HierarchyObjectInterface. The resulting reference object can be organized in a tree. The default implementation of maxon::HierarchyObjectInterface is maxon::HierarchyObjectClass.

    An interface based on maxon::HierarchyObjectInterface can implement maxon::HierarchyObjectInterface::ParentChanged() to be informed when the parent of the element has changed. This function must not be called by user code.

    // This example shows an implementation of an interface based on HierarchyObjectInterface.
    // It implements ParentChanged() and accesses the hierarchy in GetParentName().
    // implementation of TreeElementInterface
    class TreeElementImplementation : public maxon::Component<TreeElementImplementation, TreeElementInterface>
    {
    // use the default implementation "HierarchyObjectClass"
    MAXON_COMPONENT(NORMAL, maxon::HierarchyObjectClass);
    public:
    {
    _name = name;
    }
    MAXON_METHOD maxon::String GetName() const
    {
    return _name;
    }
    // function that returns the name of the parent element
    {
    // access parent element
    const auto parentObject = super.GetParent();
    if (!parentObject)
    return maxon::String();
    // check type of parent element
    if (!parentObject.IsInstanceOf<TreeElementRef>())
    return maxon::UnexpectedError(MAXON_SOURCE_LOCATION, "Parent object is no TreeElementRef."_s);
    // get name of parent element
    const TreeElementRef treeElement = maxon::Cast<TreeElementRef>(parentObject);
    return treeElement.GetName();
    }
    MAXON_METHOD void ParentChanged(maxon::Bool removed)
    {
    if (removed)
    return;
    // if a new parent is assigned, print the parent's name
    const auto parentObject = super.GetParent();
    if (parentObject.IsInstanceOf<TreeElementRef>())
    {
    const TreeElementRef treeElement = maxon::Cast<TreeElementRef>(parentObject);
    DiagnosticOutput("New Parent is @", treeElement.GetName());
    }
    }
    // Factory method
    maxon::Result<void> FactoryInit(maxon::FactoryInterface::ConstPtr, maxon::String name)
    {
    self.SetName(name);
    return maxon::OK;
    }
    private:
    maxon::String _name;
    };
    Definition: objectbase.h:2651
    bool Bool
    boolean type, possible values are only false/true, 8 bit
    Definition: apibase.h:181
    return OK
    Definition: apibase.h:2690
    @ NORMAL
    Samples the surface as the user moves over it the SculptObject and returns a new hit point and normal...
    #define MAXON_SOURCE_LOCATION
    Definition: memoryallocationbase.h:67
    #define MAXON_COMPONENT(KIND,...)
    Definition: objectbase.h:2212
    #define MAXON_METHOD
    Definition: interfacebase.h:1001

    Further Reading