OmniGraph Controller Class

The primary interface you can use for interacting with OmniGraph is the Controller class. It is in the main module so you can access it like this:

import omni.graph.core as og
keys = og.Controller.Keys
controller = og.Controller()

Note

For future examples these two lines will be assumed to be present.

Structure

The Controller class is an amalgam of several other classes with specific subsets of functionality. It derives from each of them, so that all of their functionality can be accessed through the one Controller class.

  • GraphController handles operations that affect the structure of the graph

  • NodeController handles operations that affect individual nodes

  • ObjectLookup provides a generic set of interfaces for finding OmniGraph objects with a flexible set of inputs

  • DataView lets you get and set attribute values

For the most part the controller functions can be accessed as static class members:

og.Controller.edit("/World/MyGraph", {keys.CREATE_NODES: ("MyNode", "omni.graph.tutorials.SimpleData")})
og.Controller.edit("/World/MyGraph", {keys.SET_VALUES: ("/World/MyGraph/MyNode.inputs:a_bool", False)})

A second way to do it is to instantiate the controller so that the relative paths are all remembered:

controller.edit("/World/MyGraph", {keys.CREATE_NODES: ("MyNode", "omni.graph.tutorials.SimpleData")})
controller.edit("/World/MyGraph", {keys.SET_VALUES: ("MyNode.inputs:a_bool", False)})

Or you can remember the return values of the first call yourself and reuse them:

(graph, nodes, _, _) = og.Controller.edit("/World/MyGraph", {keys.CREATE_NODES: ("MyNode", "omni.graph.tutorials.SimpleData")})
og.Controller.edit(graph, {keys.SET_VALUES: (("inputs:a_bool", nodes[0]), False))

The exceptions are when using the omni.graph.core.DataView functions, as that class requires an attribute in order to perform its operations. For those you can pass an Attribute or AttributeValue identifier to construct a controller that can handle those operations:

controller = og.Controller(og.Controller.attribute("/World/MyGraph/MyNode.inputs:myInput"))
print(f"My attribute value is {controller.get()}")
    """Class to provide a simple interface to a variety OmniGraph manipulation functions.

    Provides functions for creating nodes, making and breaking connections, and setting values.
    Graph manipulation functions are undoable, value changes are not.

    Functions are set up to be as flexible as possible, accepting a wide variety of argument variations.
    Most functions are class methods, though return values can be retained for passing in to other functions
    (e.g. the edit() function returns a list of graphs that can later be passed in to the evaluate() function to
    ensure all related graphs upate).

    The one exception is the edit() function, which is a regular method as it needs to retain state information.
    See its description for more details.

    Here is a summary of the interface methods you can access through this class, grouped by interface class

    Controller
        edit             Perform a collection of edits on a graph (the union of all interfaces)
        async evaluate   Runs evaluation on one or more graphs as a waitable (typically called from async tests)
        evaluate_sync    Runs evaluation on one or more graphs immediately

    ObjectLookup
        attribute        Looks up an og.Attribute from a description
        attribute_path   Looks up an attribute string path from a description
        attribute_type   Looks up an og.Type from a description
        graph            Looks up an og.Graph from a description
        node             Looks up an og.Node from a description
        node_path        Looks up a node string path from a description
        prim             Looks up an Usd.Prim from a description
        prim_path        Looks up a Usd.Prim string path from a description
        split_graph_from_node_path  Separate a graph and a relative node path from a full node path

    GraphController
        connect          Makes connections between attribute pairs
        create_node      Creates a new og.Node
        create_prim      Creates a new Usd.Prim
        create_variable  Creates a new og.IVariable
        delete_node      Deletes a list of og.Nodes
        disconnect       Breaks connections between attribute pairs
        disconnect_all   Breaks all connections to and from specific attributes
        expose_prim      Expose a USD prim to OmniGraph through an importing node

    NodeController
        create_attribute Create a new dynamic attribute on a node
        remove_attribute Remove an existing dynamic attribute from a node
        safe_node_name   Get a node name in a way that's safe for USD

    DataView
        get              Get the value of an attribute's data
        get_array_size   Get the number of elements in an array attribute's data
        set              Set the value of an attribute's data

    Class Attributes:
        class Keys: Helper for managing the keywords needed for the edit() function

    Attributes:
        __path_to_object_map: Mapping from the node or prim path specified to the created node or prim

    Raises:
        OmniGraphError: If the requested operation could not be performed

    """

Controller Functions

In addition to the functions inherited from the other classes the Controller has a couple of key functions itself. There is a coroutine to evaluate one or more graphs:

async def my_function():
    await og.Controller.evaluate()

The evaluate() method takes an optional parameter with a graph or list of graphs to be evaluated. By default it evaluates all graphs in the scene.

If you want to evaluate but are not in a coroutine then you can use the synchronous version evaluate_sync()

def my_normal_function():
    og.Controller.evaluate_sync()

The evaluate_sync() method also takes an optional parameter with a graph or list of graphs to be evaluated. By default it evaluates all graphs in the scene.

The workhorse of the controller class is the edit() method. It provides simple access to a lot of the underlying functionality for manipulating the contents of OmniGraph.

It should be noted here that this method can be accessed as both a class method and an object method. The reason you would create an instance of a Controller object is if you wish to preserve the internal mapping of node names to instantiated node paths for future use.

For example, this code sequence could be used to create a node and then set a value on one of its attributes:

og.Controller.edit("/World/PushGraph",
    {
        og.Controller.Keys.CREATE_NODES: ("NewNode", "omni.graph.nodes.Add"),
        og.Controller.Keys.SET_VALUES: ("NewNode.inputs:a", {"type": "float", "value": 1.0})
    }
)

In this example the extended version of value setting is used, where both the type and value are provided so that the extended attribute type in omni.graph.nodes.Add can resolve its type.

ObjectLookup

This class contains the functions you will probably use the most. It provides an extremely flexible method for looking up OmniGraph objects from the information you have on hand. The specs it accepts as arguments can be seen in the class documentation.

Here’s a quick summary of the most useful methods on this class:

Other methods will be added as they become useful.

GraphController

This class contains the functions that manipulate the structure of the graph, including creating a graph. The class documentation describe the details of what it can do.

Here’s a quick summary of the most useful methods in the class. All but the last of them can be accessed through different keywords in the dictionary passed to og.Controller.edit().

NodeController

This class contains the functions that manipulate the contents of a node. It only has a few functions. The class documentation outlines its areas of control.

Here’s a quick summary of the most useful methods in the class:

Note

A dynamic attribute in this context means an attribute that can be added to the node that does not exist in the node’s .ogn file.

DataView

This class contains the functions to get and set attribute values. It has a flexible __init__ function that can optionally take an “attribute” parameter to specify either an og.Attribute or og.AttributeData to which the data operations will apply. The class documentation shows the available functionality.

Here’s a quick summary of the most useful methods in the class:

  • get() gets the current value of the attribute

  • get_array_size() gets the number of elements in an array attribute

  • set() sets a new value on the attribute

All of these methods are set up to work either as class methods or as object methods. The difference is that when called as a class method you have add an extra parameter at the beginning that is the attribute whose value is being processed.

These two calls, for example, are equivalent:

attribute = og.Controller.attribute("/World/PushGraph/Add:inputs:a")

# As a class method
value = og.DataView.get(attribute)
# or value = og.Controller.get(attribute)

# As an object method
value = og.DataView(attribute=attribute).get()
# or value = og.Controller(attribute=attribute).get()