LoginSignup
0

More than 1 year has passed since last update.

Maya scriptノードに対抗する闇の魔術 を書きたかった

Last updated at Posted at 2020-12-17

始めに

今年は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さんの記事です。楽しみですね!


  1. 未検証 

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
0