二度目ぶりまして。
この記事はMaya Advent Calendarの11日目の記事になります。
今回は急遽Twitter上で募集した「Mayaをクラッシュ|フリーズ|無限ループさせる方法」を紹介します。
(快くネタを提供して下さった皆様にはこの場を借りて御礼申し上げます。)
件の募集ツイートはこちら
【急募】Maya、こうやればクラッシュ|フリーズ|無限ループするよっていう小ネタを募集します
— 甘夏ニット (@amanatsu_knit) December 9, 2020
このツイートにリプ下さいオネシャス!
1. リファレンスの空文字ネームスペースをリネームしようとする
僕からは「リファレンス読み込み時のネームスペースを空文字( : )にして読み込んで、そしてすかさずリファレンスエディタでネームスペースを変更しようとすると無限ループする」というネタを提供するぜ!
— 甘夏ニット (@amanatsu_knit) December 9, 2020
こちらは私が投稿したネタです。
以下の画像のようにネームスペースに:
を指定すると、
アウトライナ上などでネームスペースが付かないような形で読み込むことが可能になります。
実際、この状態で読み込まれたオブジェクトはcmds.select('pCube1')
のように見た目通りの文字列を指定することで選択できてしまうので、ノード名の文字列からはリファレンスデータなのかどうか区別がつかなくなってしまいます。
さて、本命の問題はここからです。
このネームスペースを別名に変更してみましょう。
↓
固まります。(Maya2015~2020で確認済み)
これだけでは実際に固まっているか分かりづらいと思うのでこの時のタスクマネージャーの状況を見てみると...
CPUがとても頑張っていますが応答なしになっています。Mayaがフリーズしたときの鉄板パターンですね。
こうなってしまうとタスクマネージャーから強制終了するほかなくなります。
たまに仕事でもこの:
ネームスペースが用いられた行儀の悪いデータを見る機会がありますが、上記のような問題を引き起こしてしまううえに修正もかなりめんどくさかったりします。
そもそもノード名の衝突を避ける目的であるネームスペースをこのような使い方をしてしまうのは考え物なので、
どうしても使いたい方は責任を持ってルールを整備するなどの対応を心がけて欲しいところです。
2. melでSkinClusterを生成する際にジオメトリをインフルエンスとして指定すると落ちる
こちらは初耳学認定の内容でした。 確かにjoint以外がインフルエンスに指定されていると気分が落ち込みますよね。Mayaの気持ちも分かります。スキンクラスターをmelで実行するときに、
— 単式シュールストレミング (@9boz) December 9, 2020
ジオメトリをスキンクラスター作成時にインフルエンスとして登録して実行すると オチルヨ!
ただ、残念(?)なことにMaya2019ぐらいからは落ちなくなってしまったみたいですね。
手元では再現できませんでした。残念(?)
2016あたりだとskinClusterがサイクル起こして落ちてました
— 単式シュールストレミング (@9boz) December 9, 2020
2019だと直ってるっぽいですね
3. melの引数に,
を紛れ込ませる
global proc hoge(,string $arg)
— 石子晃之 (@terish312) December 9, 2020
{
print($arg);
}
hoge("test");
確かこんな感じで。
引数の部分の余分なカンマがクラッシュさせます。
ビューティフォー
少なくともMaya2018~2020でも改善されていない事を確認しました。非常に美しい致命的なエラーです。
本当にありがとうございました。
4. MCommandMessage.addCommandOutputCallbackに渡した関数内でPrintしたりすると無限ループで死ぬ
当然と言えば当然なんですが、MCommandMessage.addCommandOutputCallbackに渡した関数内でPrintしたりすると無限ループで死にますね!
— 赤城 巧 (@takumi_akashiro) December 10, 2020
まあ、これは使う側の問題なんで若干募集意図とは違うかもですが……
MCommandMessage.addCommandOutputCallbackはMELコマンドがコマンドウィンドウに出力されるような出力を生成するたびにコールバックを登録するようなメソッドです。
そんなメソッドの中でprintをすると、当たり前ですが無限ループします。
これはネタを提供してくださったご自身も指摘されてる通りどちらかというとバグというよりはwhile Trueのようなものでなるべくして無限ループしているのですが、printデバッガーな私にとってはいつかやってしまいそうなので要注意ですね。
5. menu直下に登録したmenuItemに親のmenuを削除&再登録するようなコマンドを登録して実行すると致命的なエラーで落ちる
これは私も体験したことがあります。 UIの内容を更新するための機能を持ったメニューを作っている時に同様の問題に直面しました。>Mayaのバグ
— 赤城 巧 (@takumi_akashiro) December 10, 2020
古いバージョンに定住してるので、別バージョンでも確定してクラッシュを起こせるネタを出すのは難しい……
今使ってるバージョンだと、MenuItemから実行した関数で親ウィンドウ消すとクラッシュするけど、流石に次かその次のバージョンでは直ってる(と思いたい)し……
大体こんな感じです。
import maya.cmds as cmds
def deleteMenu():
cmds.deleteUI('TestMenu', m=True)
createMenu()
def createMenu():
cmds.menu('TestMenu', label='TestMenu', parent='MayaWindow')
cmds.menuItem('ParentKiller', label='ParentKiller', command='deleteMenu()')
createMenu()
見事な落ちっぷりです。
Maya2017~2018あたりで試すと致命的なエラーで確実に落ちるのですが、
Maya2020では非常に残念(?)なことに致命的なエラーが出なくなっており意図通りmenuItemから親menuを削除&再構築ようになっていました。
治ってないと思っていただけに非常に悔しい(?)思いです。
その他、時間が無くて検証できなかったり、検証するまでもなく治っちゃってたりした作品たち
ここからは時間がなくて試せなかった作品や私が試すまでもなく治っちゃってたりした作品を紹介します。
リファレンスがらみのデータは落ちやすい印象ですがこの例では改善されたみたいですね。残念(?)です。Maya2018でIK設定したシーンをリファレンスした状態でさらにIK設定をして、後者のIKがリファレンス由来のIKRPsolverとかに接続しているとき、リファレンスをアンロードするとしにますがMaya2019で試してみたらしななくてかなしい(かなしい?)
— トモハラ (@tm8r) December 10, 2020
ユーザーがうっかり触れてしまう場所にクラッシュが潜んでいるのは非常に恐ろしい事です。Undoしまくると落ちますよね。
— yamadaaaaaaa (@yamada41052185) December 10, 2020
あとはレンダラー系のプラグインアンロードすると落ちる。これ自体はやむなしとしても、ユーザーがイジれないようにするやさしさは欲しい
終わりに
いかがでしたでしょうか。
実はこのテーマ、苦し紛れの思い付きではなくて2年以上前から考えていたネタでした。
なかなか記事化する機会がありませんでしたが、今回はアドベントカレンダーのバトンを繋ぐという名目で記事化することができました。
くだらないネタ記事ですが何かの参考になれば幸いです。
明日の記事はshigehiroさんの「Maya Python API 2.0 のプラグインをC++で書きかえる」です。