Olarn's DevBlog
Using Pymel's NodeTracker
Sorry, failed to load main article image
Bantukul Olarn
    
Dec 08 2018 18:24
  

Tracking new dependency nodes the easy way.

Problem

maya nodetracker start.JPG

Before

maya nodetracker with new nodes.jpg

A new material have been created and assigned, which also spawns some non-obvious utility nodes

Suppose a script/ user(via gui) have created some new node, and those nodes creates some other utility nodes that might not be obvious at the first glance. For example, user assign a new phong material to a mesh, which also spawn materialinfo utility node. Or animation key that spawns conversion nodes.

What's the most convenient way to ls newly created node and all it's new utility nodes?

Solution 1 - manually traversing DG connection/ using DG functions

# manually traversing DG connection
...
new_phong_node = ... # type: pymel.core.nodetypes.Phong
# assume it's connected to a sg node
sg_node = new_phong_node.outColor.outputs()[0].node()
# assume it's connected to a materialinfo node
mi_node = sg_node.message.outputs()[0].node()
# you can also get it this way but we go through sg_node for demonstration
# mi_node = sg_node.message.outputs[0].node()

print(new_phong_node, sg_node, mi_node)
...

Sure, you can list new connection this way but what if it's a large and deep network? and workflow changes constantly it's impractical to write code this way? perhaps one can try to use cmds, or OpenMaya MItDependencyNodes to get those new nodes.

#eg:
new_nodes_and_their_util_nodes = some_node.futures()

Solution 2 - Use API callback to catch an unseen new nodes

But what if some new nodes aren't directly connected on this node's network? You possibly have to check EVERY nodes in the scene to locate an unseen new nodes.

MDGMessage Class Reference

A smarter solution would be to use addNodeAddedCallback callback from MDGMessage class to catch those nodes.

_buf = set()

def _catcher(om1_mobj, client_data):
    _buf.add(
        pm.PyNode(om1_mobj)
    )

_cbid = om.MDGMessage.addNodeAddedCallback(_catcher)

try:
    # create new node etc here
    .... 
    pm.createNode("lambert")
    ....


finally:
    om.MDGMessage.removeCallback(_cbid)

print(_buf)

Solution 3 - Using Pymel's NodeTracker

with pm.NodeTracker() as pm_nodetrack:
    pm.createNode("lambert")

print(pm_nodetrack.getNodes())

Fortunately, pymel has already provided us with convenient wrapper to accomplish what we just did above so we don't have to write boilerplate code every time we wish to use this functionality.

pymel.core.general.NodeTracker

Git, NodeTracker

Tags: