Controller

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

Bases: omni.graph.core._impl.graph_controller.GraphController, omni.graph.core._impl.node_controller.NodeController, omni.graph.core._impl.data_view.DataView, omni.graph.core._impl.object_lookup.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)

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_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

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

__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

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[Union[str, pxr.Sdf.Path], Dict[str, Tuple[Union[str, omni.graph.core._omni_graph_core.Type], Any]]], Tuple[Union[str, pxr.Sdf.Path], str], Tuple[Union[str, pxr.Sdf.Path], Dict[str, Tuple[Union[str, omni.graph.core._omni_graph_core.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 – Must be by keyword. If specified then operations are performed on this graph_id unless it is overridden in a particular function call.

Check the help information for :py:meth:`GraphController.__init__`, :py:meth:`NodeController.__init__`, :py:meth:`DataView.__init__`, and :py:meth:`ObjectLookup.__init__` for details on what constructor arguments are accepted.

Keys

alias of omni.graph.tools._impl.node_generator.keys.GraphSetupKeys

classmethod edit(*args, **kwargs) Tuple[omni.graph.core._omni_graph_core.Graph, List[omni.graph.core._omni_graph_core.Node], List[pxr.Usd.Prim], Dict[str, Union[omni.graph.core._omni_graph_core.Node, pxr.Usd.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 callling 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_NODES: [(Path_t, NodeType_t)]

    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))] }

  • 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.PRIMS: [(“/World/Prim”, {“speed”: (“double”, 1.0)}),

    (“/World/Cube”, “Cube”), (“RootPrim”, { “mass”: (Type(BaseDataType.DOUBLE), 3.0), “force:gravity”: (“double”, 32.0) })]}

  • 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.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.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”] }

  • keys.CREATE_VARIABLES: [(VariableName_t, VariableType_t)]

    Constructs a variable on the graph with the given name and type. 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.INT))] }

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")
    ]
    }
)

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 :py:meth:`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_node – If True then node creation operation won’t fail when node already exists in the scene graph (default False)

  • allow_exists_prim – If True then prim creation operation won’t fail when 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

A 4-tuple consisting of

Raises
  • og.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

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

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.