Controller

class omni.graph.core.Controller(*args, **kwargs)

Bases: GraphController, NodeController, DataView, ObjectLookup

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.

Here is a summary of the interface methods you can access through this class, grouped by interface class. The ones marked with an “!” indicate that they have both a classmethod version and an object method version. In those cases the methods use object member values which have corresponding arguments in the classmethod version. (e.g. if the method uses the “update_usd” member value then the method will also have a “update_usd:bool” argument)

Controller
  • ! edit Perform a collection of edits on a graph (the union of all interfaces)

  • evaluate Runs async 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_graph Creates a new og.Graph

  • ! 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

  • ! promote_attribute Promote a node attribute in a compound graph on the parenting compound 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

__graph_id

Graph on which the operations are to be performed.

__path_to_object_map

Dictionary of relative paths mapped on to their full path after creation so that future function calls can use either full paths or short-forms to specify the nodes.

__update_usd

If True then update the USD after the operations that affect it

__undoable

If True the operation is added to the undo queue, else it is done immediately and forgotten

__allow_exists_attr

If True then attribute creation operation won’t fail when the attribute already exists on the node it was being added to (default False)

__allow_exists_node

If True then node creation operation won’t fail when the node already exists in the scene graph (default False)

__allow_exists_prim

If True then prim creation operation won’t fail when the prim already exists in the scene graph (default False)

Raises

OmniGraphError – If the requested operation could not be performed

Methods

__init__(*args, **kwargs)

Set up state information.

edit(*args, **kwargs)

Edit and/or create an OmniGraph from the given description.

evaluate(*args, **kwargs)

Wait for the next Graph evaluation cycle - await this function to ensure it is finished before returning.

evaluate_sync(*args, **kwargs)

Run the next Graph evaluation cycle immediately.

Attributes

PrimCreationData_t(*args, **kwargs)

alias of Union[Tuple[str | Path, dict[str | tuple[str | Type, any]]], Tuple[str | Path, str], Tuple[str | Path, dict[str | tuple[str | Type, any]], str]]

TYPE_CHECKING

If True then verbose type checking will happen in various locations so that more legible error messages can be emitted.

__init__(*args, **kwargs)

Set up state information. You only need to create an instance of the Controller if you are going to use the edit() function more than once, when it needs to remember the node mapping used for creation. Args are passed on to the parent classes who have inits and interpreted by them as they see fit.

Parameters
  • graph_id – If specified then operations are performed on this graph_id unless it is overridden in a particular function call. See GraphController.create_graph() for the data types accepted for the graph description.

  • path_to_object_map – Dictionary of relative paths mapped on to their full path after creation so that the edit_commands can use either full paths or short-forms to specify the nodes.

  • update_usd – If specified then override whether to update the USD after the operations (default False)

  • undoable – If True the operation is added to the undo queue, else it is done immediately and forgotten (default True)

  • allow_exists_attr – If True then attribute creation operation won’t fail when the attribute already exists on the node it was being added to (default False)

  • allow_exists_node – If True then node creation operation won’t fail when the node already exists in the scene graph (default False)

  • allow_exists_prim – If True then prim creation operation won’t fail when the prim already exists in the scene graph (default False)

Check the help information for GraphController.__init__(), NodeController.__init__(), DataView.__init__(), and ObjectLookup.__init__() for details on what other constructor arguments are accepted.

Keys

alias of GraphSetupKeys

classmethod edit(*args, **kwargs) Tuple[Graph, List[Node], List[Prim], Dict[str, Union[Node, Prim]]]

Edit and/or create an OmniGraph from the given description.

This function provides a single call that will make a set of modifications to an OmniGraph. It can be used to create a new graph from scratch or to make changes to an existing graph.

If the “undoable” mode is not set to False then a single undo will revert everything done via this call.

The description below contains different sections that perform different operations on the graph. They are always done in the order listed to minimize conflicts. If you need to execute them in a different order then use multiple calls to edit().

This function can be called either from the class or using an instantiated object. When calling from an object context the arguments passed in will take precedence over the arguments provided to the constructor. Here are some of the legal ways to call the edit function:

# For example purposes "cmds()" is a function that returns a dictionary of editing commands

(graph, _, _, _) = og.Controller.edit("/TestGraph", cmds())

new_controller = og.Controller(graph)
new_controller.edit(cmds())

og.Controller.edit(graph, cmds())
new_controller.edit(graph, cmds())
new_controller.edit(graph, cmds(), undoable=False)  # Overrides the normal undoable state of new_controller

Below is the list of the allowed operations, in the order in which they will be performed.

The parameters are described as lists, though if you have only one parameter for a given operation you can pass it without it being in a list.

{ OPERATION: [List, Of, Arguments] }
{ OPERATION: SingleArgument }

For brevity the shortcut “keys = og.Controller.Keys” is assumed to exist.

  • keys.DELETE_NODES: NodeSpecs_t

    Deletes a node or list of nodes. If the node specification is a relative path then it must be in the list of full paths that the controller created in a previous call to edit().

    { keys.DELETE_NODES: ["NodeInGraph", "/Some/Other/Graph/Node", my_omnigraph_node] }
    
  • keys.CREATE_VARIABLES: [(VariableName_t, VariableType_t)] or [(VariableName_t, VariableType_t, Any)]

    Constructs a variable on the graph with the given name and type and an optional default value. The type can be specified as either a ogn type string (e.g. “float4”), or as an og.Type (e.g. og.Type(og.BaseDataType.FLOAT))

    { keys.CREATE_VARIABLES: [("velocity", "float3"), ("count", og.Type(og.BaseDataType.FLOAT), 4)] }
    
  • keys.CREATE_NODES: [(Path_t, Union[NodeType_t, dict])]

    Constructs a node of the given type at the given path. If the path is a relative one then it is added directly under the graph being edited. A map is remembered between the given path, relative or absolute, and the node created at it so that further editing functions can refer to the node by that name directly rather than trying to infer the final full name.

    { keys.CREATE_NODES: [("NodeInGraph", "omni.graph.tutorial.SimpleData"),
                          ("Inner/Node/Path", og.NodeType(node_type_name))] }
    

    The node type can also be a dictionary of editing commands. In that scenario, the created node becomes a compound node which uses the commands to construct a subgraph that defines its execution.

    { keys.CREATE_NODES: [("CompoundNode", {
                            keys.CREATE_NODES: ("NodesInCompound", "omni.graph.tutorial.SimpleData")
                         })
    ]}
    
  • keys.CREATE_PRIMS: [(Path_t, {ATTR_NAME: (AttributeType_t, ATTR_VALUE)}, Optional(PRIM_TYPE))]

    Constructs a prim at path “PRIM_PATH” containing a set of attributes with specified types and values. Only those attribute types supported by USD can be used here, though the type specification can be in OGN form - invalid types result in an error. Whereas relative paths on nodes are treated as being relative to the graph, for prims a relative path is relative to the stage root. Prims are not allowed inside an OmniGraph and attempts to create one there will result in an error.

    Note that the PRIM_TYPE can appear with or without an attribute definition. (Many prim types are part of a schema and do not require explicit attributes to be added.)

    { keys.CREATE_PRIMS: [("/World/Prim", {"speed": ("double", 1.0)}),
                          ("/World/Cube", "Cube"),
                          ("RootPrim", {
                              "mass": (Type(BaseDataType.DOUBLE), 3.0),
                              "force:gravity": ("double", 32.0)
    })]}
    
  • keys.EXPOSE_PRIMS: [(cls.PrimExposureType, Prim_t, NewNode_t)]

    Exposes a prim to OmniGraph through creation of one of the node types designed to do that. The first member of the tuple is the method used to expose the prim. The prim path is the second member of the tuple and it must already exist in the USD stage. The third member of the tuple is a node name with the same restrictions as the name in the CREATE_NODES edit.

    { keys.EXPOSE_PRIMS: [(cls.PrimExposureType.AS_BUNDLE, "/World/Cube", "BundledCube")] }
    
  • keys.CREATE_ATTRIBUTES: [(AttributeSpec_t, AttributeTypeSpec_t)]

    Constructs one or more new dynamic attributes on nodes. The first argument of the tuple defines the location of the new attribute by path and/or node. The second argument of the tuple defines the type and port of the attribute in a flexible way (see the type definition for more details). Any combination of specifications can be used to define new attributes. Unspecified ports default the attribute to being an input.

    { keys.CREATE_ATTRIBUTES: [
        ("NewNode.inputs:new_float_attribute", "float"),
        (
            ("new_attribute", new_node),
            (og.Type(og.BaseDataType.INT), og.AttributePortType.ATTRIBUTE_PORT_TYPE_INPUT),
        ),
        (
            "/World/Graph/Node.new_union_output",
            (["float", "double"], og.AttributePortType.ATTRIBUTE_PORT_TYPE_OUTPUT),
        ),
        ("/World/Graph/Node.new_any_input", "any"),
    }
    
  • keys.CONNECT: [(AttributeSpec_t, AttributeSpec_t)]

    Makes a connection between the given source and destination attributes. The local name of a newly created node may be made as part of the node in the spec, or the node portion of the attribute path:

    { keys.CONNECT: [("NodeInGraph.outputs:value", ("inputs:value", "NodeInGraph"))]}
    
  • keys.DISCONNECT: [(AttributeSpec_t, AttributeSpec_t)]

    Breaks a connection between the given source and destination attributes. The local name of a newly created node may be made as part of the node in the spec, or the node portion of the attribute path:

    { keys.DISCONNECT: [("NodeInGraph.outputs:value", ("inputs:value", "NodeInGraph"))]}
    
  • keys.DISCONNECT_ALL: [AttributeSpec_t]

    Breaks all connections to and from the given attributes. The local name of a newly created node may be made as part of the node in the spec, or the node portion of the attribute path:

    { keys.DISCONNECT_ALL: ["NodeInGraph.outputs:value", ("inputs:value", "NodeInGraph")]}
    
  • keys.PROMOTE_ATTRIBUTES: [(AttributeSpec_t, str)]

    Promotes attributes on a node in a compound graph instance as attributes on the parent compound node with the given name. Only input and output attributes on a node in a compound graph can be promoted. The prefix of the promoted name is optional; the ‘inputs’ prefix will be prepended for input attributes, and the ‘outputs’ prefix will be prepended for output attributes if necessary.

    {keys.PROMOTE_ATTRIBUTES :[("NodeInGraph.inputs:value", "inputs:new_name"),
                              ("OtherNodeInGraph.outputs:value", "result")
    
    ]}
    
  • keys.SET_VALUES: [AttributeSpec_t, Any] or [AttributeSpec_t, Any, AttributeType_t]

    Sets the value of the given list of attributes.

    { keys.SET_VALUES: [("/World/Graph/Node.inputs:attr1", 1.0), (("inputs:attr2", node), 2.0)] }
    

    In the case of extended attribute types you may also need to supply a data type, which is the type the attribute will resolve to when the value is set. To supply a type, add it as a third parameter to the attribute value:

    { keys.SET_VALUES: [("inputs:ext1", node), 2.0, "float"] }
    

Here’s a simple call that first deletes an existing node “/World/PushGraph/OldNode”, then creates two nodes of type “omni.graph.tutorials.SimpleData”, connects their “a_int” attributes, disconnects their “a_float” attributes and sets the input “a_int” of the source node to the value 5. It also creates two unused USD Prim nodes, one with a float attribute named “attrFloat” with value 2.0, and the other with a boolean attribute named “attrBool” with the value true.

controller = og.Controller()
keys = og.Controller.Keys
(graph, nodes_constructed, prims_constructed, path_to_object_map) = controller.edit("/World/PushGraph", {
    keys.DELETIONS: [
        "OldNode"
    ],
    keys.CREATE_NODES: [
        ("src", "omni.graph.tutorials.SimpleData"),
        ("dst", "omni.graph.tutorials.SimpleData")
        ],
    keys.CREATE_PRIMS: [
        ("Prim1", {"attrFloat": ("float", 2.0)}),
        ("Prim2", {"attrBool": ("bool", True)}),
        ],
    keys.CONNECT: [
        ("src.outputs:a_int", "dst.inputs:a_int")
        ],
    keys.DISCONNECT: [
        ("src.outputs:a_float", "dst.inputs:a_float")
        ],
    keys.SET_VALUES: [
        ("src.inputs:a_int", 5)
        ]
    keys.CREATE_VARIABLES: [
        ("a_float_var", og.Type(og.BaseDataType.FLOAT)),
        ("a_bool_var", "bool", True)
    ]
    }
)

Note

The controller object remembers where nodes are created so that you can use short forms for the node paths for convenience. That’s why in the above graph the node paths for creation and the node specifications in the connections just says “src” and “dst”. As they have no leading “/” they are treated as being relative to the graph path and will actually end up in “/World/PushGraph/src” and “/World/PushGraph/dst”.

Node specifications with a leading “/” are assumed to be absolute paths and must be inside the path of an existing or created graph. e.g. the NODES reference could have been “/World/PushGraph/src”, however using “/src” would have been an error.

This node path mapping is remembered across multiple calls to edit() so you can always use the shortform so long as you use the same Controller object.

Parameters
  • obj – Either cls or self depending on how edit() was called

  • graph_id – Identifier that says which graph is being edited. See GraphController.create_graph() for the data types accepted for the graph description.

  • edit_commands – Dictionary of commands and parameters indicating what modifications are to be made to the specified graph. A strict set of keys is accepted. Each of the values in the dictionary can be either a single value or a list of values of the proscribed type.

  • path_to_object_map – Dictionary of relative paths mapped on to their full path after creation so that the edit_commands can use either full paths or short-forms to specify the nodes.

  • update_usd – If specified then override whether to update the USD after the operations (default False)

  • undoable – If True the operation is added to the undo queue, else it is done immediately and forgotten (default True)

  • allow_exists_attr – If True then attribute creation operation won’t fail when the attribute already exists on the node it was being added to (default False)

  • allow_exists_node – If True then node creation operation won’t fail when the node already exists in the scene graph (default False)

  • allow_exists_prim – If True then prim creation operation won’t fail when the prim already exists in the scene graph (default False)

Returns

  • the og.Graph being used for the operation

  • the list of og.Nodes created by the operation

  • the list of Usd.Prims created by the operation

  • the map of node/prim path name to the created og.Node/Usd.Prim objects. Can usually be ignored; it will be used internally to manage the shortform names of the paths used in multiple commands.

Return type

(Graph, list[Node], list[Usd.Prim], dict[str, str])

Raises

OmniGraphError – if any of the graph creation instructions could not be fulfilled The graph will be left in the partially constructed state it reached at the time of the error

async classmethod evaluate(*args, **kwargs)

Wait for the next Graph evaluation cycle - await this function to ensure it is finished before returning.

This function can be called either from the class or using an instantiated object. The first argument is positional, being either the class or object.

await og.Controller.evaluate()  # Evaluates all graphs
controller = og.Controller.edit("/TestGraph", {})
await controller.evaluate()  # Evaluates only "/TestGraph"
await og.Controller.evaluate("/TestGraph")  # Evaluates only "/TestGraph"
controller.evaluate(graph_id="/OtherGraph")  # Evaluates only "/OtherGraph" (not its own "/TestGraph")
Parameters
  • obj – Either cls or self depending on how the function was called

  • graph_id (GraphSpecs_t) – Graph or list of graphs to evaluate - None means all existing graphs

Raises

OmniGraphError – If the graph evaluated explicitly does not exist or if it is a pre-render or post-render graph.

classmethod evaluate_sync(*args, **kwargs)

Run the next Graph evaluation cycle immediately.

This function can be called either from the class or using an instantiated object. The first argument is positional, being either the class or object.

og.Controller.evaluate_sync()  # Evaluates all graphs
controller = og.Controller.edit("/TestGraph", {})
controller.evaluate_sync()  # Evaluates only "/TestGraph"
og.Controller.evaluate_sync("/TestGraph")  # Evaluates only "/TestGraph"
controller.evaluate_sync(graph_id="/OtherGraph")  # Evaluates only "/OtherGraph" (not its own "/TestGraph")
Parameters
  • obj – Either cls or self depending on how evaluate_sync() was called

  • graph_id (GraphSpecs_t) – Graph or list of graphs to evaluate - None means all existing graphs

Raises

OmniGraphError – If the graph evaluated explicitly does not exist or if it is a pre-render or post-render graph.

TYPE_CHECKING = True

If True then verbose type checking will happen in various locations so that more legible error messages can be emitted. Set it to False to run a little bit faster, with errors just reporting raw Python error messages.