始めに
今年はscriptノードの被害が多い一年だったようですね!
知り合いのTAからも、送られてきたシーンに変なデータが含まれていて色々大変だったと聞きました。
自分は運よく遭遇せずに済んで、件のデータを見てないので何も言えないですが
(まあ見てても言えないですけど)
今日はそんなシーンをどうにかする方法を考えます。
今回想定したファイルは、シーンを開いたときにpolyCubeを一つ作るscriptノードですね。
今回のコンセプトについて
たしかscriptノードのイベント発火はscriptJobなどと同じく、MayaのIdle時だった気がする1ので、
そのイベント発生前にノードを削除すればいいわけです。
今回はscriptノードを削除するコールバックをOpenMayaのMMessageに登録してみましょう!!!
闇には闇をぶつけんだよ!って発想ですね。
(こういう発想するから変なシーンが産まれ、送られてくるんだろうなあ……)
今回はMCommandMessage
を使います!
MCommandMessage
はMayaのコマンド、プロシージャが走るたびに発生するイベントで、
addCallback
して関数オブジェクトを登録すれば、Mayaのコマンドが走った直後に関数が実行されます!
やってみた
def remove_script_node_cbk(message, *args, **kwargs):
if message.startswith('createNode "script"'):
# 可読性が悪い!!!
node = message.strip().split(" ")[-1].replace(";", '').strip('"')
cmds.delete(node)
id_ = OpenMaya.MCommandMessage.addCommandCallback(remove_script_node_cbk)
# 登録を解除するときはこれ。
# OpenMaya.MCommandMessage.removeCallback(id_)
はい、.ma
を開くときにノードの復元するためにcreateNode
コマンドが走り、
走ったコマンドを読んで、createNode "script"
コマンドを拾って、
拾ったノードをdeleteすれば無害化できますね。
これで手元のシーンもpolyCubeを作られませんでした!
ですがコレ、maya ascii
シーンでは動くんですが、maya binary
シーンでは動きませんね。
やっぱり駄目だったよ……まあでも、納品物を全部.ma
にすればいいか……
では次鋒!MSceneMessage
!
def delete_script_node(*args, **kwargs):
cmds.delete(cmds.ls(type="script") or [])
id_ = OpenMaya.MSceneMessage.addCallback(OpenMaya.MSceneMessage.kAfterOpen, delete_script_node)
# OpenMaya.MCommandMessage.removeCallback(id_)
ma, mb共に、手元のデータでは上手く動きましたね!やったね!!
あとはプロジェクトごとに許可するscriptノードのリストを用意して、
それ以外の不正なscriptノードは削除すればよさそうですね!
明日はpaty-6991さんの記事です。楽しみですね!
-
未検証 ↩