簡易な新規ノード追跡
課題
スクリプト・ユーザーで(UIで)新規ノードを作成、直後何らか処理を行った後、生成するつもりノードの他に何かユーティリティノードも一緒できてしまうケースは結構あります。もちろんこの中に一見しただけではわからないノードもあります。
さて新規ノード+一緒に出てきたユーティリティノードらをどうしたら一番楽で取得できるでしょう?
方法1:手動でDGコネクションを巡る
# 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)
...
サクッと書いたらたぶんこんなスクリプトになるでしょう。
もちろんこの方法では問題なく取得はできるが、深いネットワーク、複数なコネクションまたワークフローが頻繁に変わり規模が大きくなければなるほどそれなりに管理が辛くなると思います。
そんな状況になってくると、次にcmds機能とかOpenMayaのMItDependencyNodesを試したくなるでしょう。
#eg:
new_nodes_and_their_util_nodes = some_node.futures()
方法2:APIのCallback機能でキャッチ
ところかコネクションを巡るだけでは直接にネットワークに繋いでいる補助ノードしか取得できないのです。ネットワークの外にある場合、シーンの中の全ノードを確認せざるを得なくなるでしょう。。
が、APIでならDGノード作成にCallback登録することは可能です。
それを利用すれば全く関係ないネットワークに現れるノードを取得することも可能になります。
_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)
方法3:PymelのNodeTrackを使う
with pm.NodeTracker() as pm_nodetrack:
pm.createNode("lambert")
print(pm_nodetrack.getNodes())
機能としては方法2と相当するが、もっと便利、読みやすく安全で使える機能はPymelに用意されてあります。
pymel.core.general.NodeTracker
裏では同じ機能を使っていた。
これで新規ノード取得が楽になりますね!