AcademySoftwareFoundation / MaterialX

MaterialX is an open standard for the exchange of rich material and look-development content across applications and renderers.
http://www.materialx.org/
Apache License 2.0
1.79k stars 326 forks source link

Support updating references when renaming a node or nodegraph #1847

Open kwokcb opened 1 month ago

kwokcb commented 1 month ago

Issue

This was raised by @dgovil in Slack that there is no such API in existence. Element::setName() will just the name but not update references resulting in breaking connections.

Proposal

Implementation

This is what I cam up with as the logic required.

 def renameNode(node, newName : str, updateReferences : bool = True):

    if not node or not newName:
        return
    if not (node.isA(mx.Node) or node.isA(mx.NodeGraph)):
        print('A non-node or non-nodegraph was passed to renameNode()')
        return 
    if node.getName() == newName:
        return

    parent = node.getParent()
    if not parent:
        return

    newName = parent.createValidChildName(newName)

    if updateReferences:
        downStreamPorts = node.getDownstreamPorts()
        if downStreamPorts:
            for port in downStreamPorts:
                #if (port.getNodeName() == node.getName()): This is assumed from getDownstreamPorts()
                oldName = port.getNodeName()
                if (port.getAttribute('nodename')):
                    port.setNodeName(newName)
                    print('  > Update downstream port: "' + port.getNamePath() + '" from:"' + oldName + '" to "' + port.getAttribute('nodename') + '"')
                elif (port.getAttribute('nodegraph')):
                    port.setAttribute('nodegraph', newName)
                    print('  > Update downstream port: "' + port.getNamePath() + '" from:"' + oldName + '" to "' + port.getAttribute('nodegraph') + '"')
                elif (port.getAttribute('interfacename')):
                    port.setAttribute('interfacename', newName)
                    print('  > Update downstream port: "' + port.getNamePath() + '" from:"' + oldName + '" to "' + port.getAttribute('interfacename') + '"')

    node.setName(newName)

It might be "nice" to add in a renameConnection() which would check the usage of interfacename or nodename or nodegraph. Long term it would better to just use 1 connection string identifier.

dgovil commented 1 month ago

Thanks, @kwokcb!