nodes_selection¶
This example shows how to select different elements on a node graph. It creates a node material, select ports, print connections and select wires.
nodes_selection.py¶
"""This example shows how to select different elements on a node graph. It creates a node material, select ports, print connections and select wires.
Topics:
* BeginTransaction
* SelectPort
* SelectConnection
"""
__author__ = "Manuel Magalhaes"
__copyright__ = "Copyright (C) 2026 MAXON Computer GmbH"
__license__ = "Apache-2.0 License"
__version__ = "R26"
import c4d
import maxon
def main():
# Create a baseMaterial
mat = c4d.BaseMaterial(c4d.Mmaterial)
if mat is None:
raise ValueError("Cannot create a BaseMaterial")
# Insert the material before casting it to a NodeMaterial
doc.InsertMaterial(mat)
# Retrieve the reference of the material as a node Material.
nodeMaterial = mat.GetNodeMaterialReference()
if nodeMaterial is None:
raise ValueError("Cannot retrieve nodeMaterial reference")
# Retrieve the current node space Id
nodespaceId = c4d.GetActiveNodeSpaceId()
# Add a graph for the space Id
addedGraph = nodeMaterial.CreateDefaultGraph(nodespaceId)
if addedGraph is None:
raise ValueError("Cannot add a graphnode for this nodespace")
# Retrieve the Nimbus reference for a specific nodeSpace
nimbusRef = mat.GetNimbusRef(nodespaceId)
if nimbusRef is None:
raise ValueError("Cannot retrieve the nimbus ref for that node space")
# Retrieve the graph corresponding to that nodeSpace.
graph = nodeMaterial.GetGraph(nodespaceId)
if graph is None:
raise ValueError("Cannot retrieve the graph of this nimbus ref")
# Retrieve the end node of this graph
endNodePath = nimbusRef.GetPath(maxon.NIMBUS_PATH.MATERIALENDNODE)
endNode = graph.GetNode(endNodePath)
if endNode is None:
raise ValueError("Cannot retrieve the endnode of this graph")
# Retrieve the predecessors
predecessor = []
maxon.GraphModelHelper.GetDirectPredecessors(endNode, maxon.NODE_KIND.NODE, predecessor)
bsdfNode = predecessor[0]
if bsdfNode is None:
raise ValueError("Cannot retrieve the node connected to endnode")
# Retrieve the inputs list of the EndNode
endNodeInputs = endNode.GetInputs()
# Retrieve the outputs list of the bsdf node
bsdfNodeOutputs = bsdfNode.GetOutputs()
# Select the BSDF node, selected elements are stored inside the graph,
# so we need a transaction to change it.
with graph.BeginTransaction() as transaction:
maxon.GraphModelHelper.SelectNode(bsdfNode)
transaction.Commit()
def SelectPort(port):
"""
Select a port.
This function is used as a callback parameter of NodesGraphModelInterface.GetChildren.
Args:
port: (maxon.GraphNode): The node to be selected.
Returns:
bool: **True** if the iteration over nodes should continue, otherwise **False**
"""
maxon.GraphModelHelper.SelectNode(port)
return True
# Select all the inputs ports of the end node. For that, a transaction
# need to be created.
with graph.BeginTransaction() as transaction:
endNodeInputs.GetChildren(SelectPort)
transaction.Commit()
def PrintConnection(port):
"""
Prints connection from a port to another, with the flags used to define hte behavior of this connection.
This function is used as a callback parameter of NodesGraphModelInterface.GetChildren.
Args:
port: (maxon.GraphNode): The output port with a connection that should be printed.
Returns:
bool: **True** if the iteration over nodes should continue, otherwise **False**
"""
connections = list()
res = port.GetConnections(maxon.PORT_DIR.OUTPUT, connections)
print(port, res, connections)
for connection in connections:
maxon.GraphModelHelper.SelectConnection(port, connection[0])
return True
# Select the wire between the material node (end node) and the BSDF node
# To modify a graph, modification must be done inside a transaction. After
# modifications are done, the transaction must be committed.
with graph.BeginTransaction() as transaction:
bsdfNodeOutputs.GetChildren(PrintConnection)
transaction.Commit()
# Pushes an update event to Cinema 4D
c4d.EventAdd()
if __name__ == "__main__":
main()