Connecting Nodes

Adding and Removing Ports

Katana recipes are created by adding and connecting nodes in the Node Graph. Nodes are connected through their input and output ports. Some node types have a fixed number of ports, while others allow for an arbitrary number. The Merge nodes, for example, takes any number of inputs and combines them into a single output. To create a Merge node and add two input ports enter the following:

rootNode = NodegraphAPI.GetRootNode()
mergeNode = NodegraphAPI.CreateNode('Merge', rootNode)
firstPort = mergeNode.addInputPort("First")
secondPort = mergeNode.addInputPort("Second")

Ports can be added by index as well as by name, which allows direct control of their ordering. For example, to add an input port to the merge node created above, add the following:

newPort = mergeNode.addInputPortAtIndex("BetweenFirstAndSecond", 1)
Node.addInputPort(name) → Port

Creates a new input port with the given name, and returns it.

Node.addOutputPort(name) → Port

Creates a new output port with the given name, and returns it.

Node.addInputPortAtIndex(name, index) → Port

Creates a new input port at a specific index, and returns it.

Node.addOutputPortAtIndex(name, index) → Port

Creates a new output port at a specific index, and returns it.

Node.removeInputPort(name)

Deletes an input port by name, breaking any connections it had.

Node.removeOutputPort(name)

Deletes an output port by name, breaking any connections it had.

Retrieving Ports

Node.getNumInputPorts() → int

Returns the number of input ports on the node.

Node.getNumOutputPorts() → int

Returns the number of output ports on the node.

Node.getInputPort(name) → Port

Returns an input port from the node by name. Returns None if not found.

Node.getOutputPort(name) → Port

Returns an output port from the node by name. Returns None if not found.

Node.getInputPortByIndex(index) → Port

Returns one of the input ports by index. Returns None if out of range.

Node.getOutputPortByIndex(index) → Port

Returns one of the output ports by index. Returns None if out of range.

Node.getInputPorts() → list of Port

Returns a new list containing all the input ports.

Node.getOutputPorts() → list of Port

Returns a new list containing all the output ports.

Node.getSourcePort(port, graphState) → tuple or None

Returns the output port that produces the data of the given port (which may be an upstream output port in the case of nodes being bypassed) as a tuple of (port, graphState). Port will be None if not found.

Node.getInputSource(name, graphState) → Port, GraphState

Returns the port connected to an input port by name as a (Port, GraphState) tuple. Port will by None if not found.

Node.getInputPortAndGraphState(port, graphState) -> (Port, GraphState)

Returns the input port of this node that is used in producing the data of the given port as a tuple of (port, graphState). Port will be None if not found.

Renaming Ports

The renameInputPort() and renameOutputPort() methods rename ports. For example, to rename the input port named “i0” and the output port named “out” on the Merge node from earlier, enter the following:

mergeNode.renameInputPort("i0", "input")
mergeNode.renameOutputPort("out", "output")
Node.renameInputPort(name, newName)

Renames an input port. Returns the resulting unique name

Node.renameOutputPort(name, newName)

Renames an output port. Returns the resulting unique name.

Connecting and Disconnecting Ports

The connect() method links ports. For example, to take an output port on a PrimitiveCreate node and connect it to an input port on a Merge node enter the following:

primOutPort = primNode.getOutputPort("out")
mergeInPort = mergeNode.getInputPort("i0")
primOutPort.connect(mergeInPort)
# or...
mergeInPort.connect(primOutPort)

The disconnect() method unlinks two ports. For example, to unlink the two ports connected above enter the following:

mergeInPort.disconnect(primOutPort)
# or...
primOutPort.disconnect(mergeInPort)
Port.isConnected(otherPort) → bool

True if the port is connected to otherPort.

Port.getNumConnectedPorts() → int

The number of other ports this port is connected to, can be zero or greater.

Port.getConnectedPort(index) → Port

Gets one of the other ports this is connected to, or None if index is out of range.

Port.getConnectedPorts() → list of Port

Returns a new list of all the ports connected to this one.

Port.connect(otherPort) → bool

Connects a port to the given port. If the nodes to which the ports belong are not part of the same parent node, in-between connections along the way are created. Returns True if the port connection was successfully established, otherwise False if recursion was detected, nodes were locked or if other problems occurred.

Port.disconnect(otherPort) → bool

Disconnects a port from the given port. Does nothing if the ports are not directly connected. Returns True if the ports were successfully disconnected, otherwise False.

Port Information

Port.getIndex() → int

Returns the index of this port inside its node.

Port.getName() → str

Get the name that refers to this port.

Port.getDisplayName() → str

Get a UI-friendly name for this port that may consist of a label and the names of pages as defined in metadata on this port.

Port.getType() → int

Returns the type of this port (Port.TYPE_PRODUCER, Port.TYPE_CONSUMER).

Port.getNode() → Node or None

Return the node that owns this port, or None if this port is orphaned.

Physical Source

A physical connection is determined by which output ports any given input port is directly connected. The physical connections are those you see represented by connection arrows in the Node Graph.

To find the physical source from a given port, use getConnectedPorts(). For example, create a PrimitiveCreate node and a Merge node, connect the output of the PrimitiveCreate node to an input on the Merge node, then get the source of the connection into the Merge node:

# Get the root node
rootNode = NodegraphAPI.GetRootNode()

# Create a PrimitiveCreate node at root level
primNode = NodegraphAPI.CreateNode('PrimitiveCreate', rootNode)

# Create a Merge node at root level
mergeNode = NodegraphAPI.CreateNode('Merge', rootNode)

# Add an output port to the PrimitiveCreate node
primOutPort = primNode.addOutputPort("newOutputPort")

# Add an input to the Merge node
mergeInPort = mergeNode.addInputPort("fromPrim")

# Connect PrimitiveCreate to Merge
primOutPort.connect(mergeInPort)

# Use getConnectedPorts to find connections on mergeInPort
mergeInConnectedPorts = mergeInPort.getConnectedPorts()

# Print the connected port
print(mergeInConnectedPorts)

Logical Source

Logical connections are those used to traverse up the node graph at render time. Conditional logic, parameter values and time are used to determine the next relevant source of data, and this is represented by a logical connection between the current node and the next.

The diagram below shows an example of physical and logical connections in the Node Graph tab. Nodes A and B have physical connections to inputs on the Switch node, and node C has a physical connection to the output of the Switch.

The logical connection from node A or B to node C, depends on the setting of the switch. When the Switch node’s in parameter is set to 0, there is a logical connection from node A, to node C, passing through the Switch. When the Switch’s in parameter is set to 1, there is a logical connection from node B to node C, passing through the Switch.

../../_images/LogicalConnection.png

To find the logical source of an input node use getLogicalSource(), which takes the name of the port and a time as arguments, and returns a tuple containing the source port and the time. If no port is found, it returns None.

For example, recreate the scene shown above then find the input source at the output:

root = NodegraphAPI.GetRootNode()

# Create TheInputSourceNode at root level
primANode = NodegraphAPI.CreateNode('PrimitiveCreate', root)
primBNode = NodegraphAPI.CreateNode('PrimitiveCreate', root)
primANode.setName("A")
primBNode.setName("B")
primAOutPort = primANode.getOutputPort("out")
primBOutPort = primBNode.getOutputPort("out")

# Create the Switch node at root level
switchNode = NodegraphAPI.CreateNode('Switch', root)
switchInPort1 = switchNode.addInputPort("input1")
switchInPort2 = switchNode.addInputPort("input2")
switchOutPort = switchNode.getOutputPort("output")

# Create a Render node at root level
renderNode = NodegraphAPI.CreateNode('Render', root)
renderInPort = renderNode.getInputPort("input")

# Connect the primitive to the switch, and switch to render
primAOutPort.connect(switchInPort1)
primBOutPort.connect(switchInPort2)
switchOutPort.connect(renderInPort)

# Get the logical input of the render.input port
inputPort, inputTime = renderNode.getInputSource("input", TIME)

# Get hold of the source node so that we can print its name.
inputNode = inputPort.getNode()
inputNodeName = inputNode.getName()

# Print the name of the source node
print(inputNodeName)