Mayaをテクニカルに落とす

二度目ぶりまして。

この記事は[Maya Advent Calendar](https://qiita.com/advent-calendar/2020/maya)の11日目の記事になります。

今回は急遽Twitter上で募集した「Mayaをクラッシュ|フリーズ|無限ループさせる方法」を紹介します。
（快くネタを提供して下さった皆様にはこの場を借りて御礼申し上げます。）

件の募集ツイートはこちら
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">【急募】Maya、こうやればクラッシュ|フリーズ|無限ループするよっていう小ネタを募集します<br>このツイートにリプ下さいオネシャス！</p>&mdash; 甘夏ニット (@amanatsu_knit) <a href="https://twitter.com/amanatsu_knit/status/1336592071390466048?ref_src=twsrc%5Etfw">December 9, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

## 1. リファレンスの空文字ネームスペースをリネームしようとする
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">僕からは「リファレンス読み込み時のネームスペースを空文字（ : ）にして読み込んで、そしてすかさずリファレンスエディタでネームスペースを変更しようとすると無限ループする」というネタを提供するぜ！</p>&mdash; 甘夏ニット (@amanatsu_knit) <a href="https://twitter.com/amanatsu_knit/status/1336592727455092736?ref_src=twsrc%5Etfw">December 9, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

こちらは私が投稿したネタです。
以下の画像のようにネームスペースに`:`を指定すると、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212052/707f53a9-b5ba-5b12-e848-c9c3cc13c460.png)
アウトライナ上などでネームスペースが付かないような形で読み込むことが可能になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212052/75b6b736-22e6-e30d-88bf-722acee6a6cc.png)
実際、この状態で読み込まれたオブジェクトは`cmds.select('pCube1')`のように見た目通りの文字列を指定することで選択できてしまうので、ノード名の文字列からはリファレンスデータなのかどうか区別がつかなくなってしまいます。

さて、本命の問題はここからです。
このネームスペースを別名に変更してみましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212052/d4db2ee9-f602-f6c7-f75a-ecbb19ea41c6.png)
↓
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212052/fea44bf9-092c-3dbe-a124-cf01e8d05164.png)

固まります。(Maya2015~2020で確認済み)
これだけでは実際に固まっているか分かりづらいと思うのでこの時のタスクマネージャーの状況を見てみると...
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212052/44f084c8-fbf8-a164-1cbf-facf377a7735.png)
CPUがとても頑張っていますが応答なしになっています。Mayaがフリーズしたときの鉄板パターンですね。
こうなってしまうとタスクマネージャーから強制終了するほかなくなります。

たまに仕事でもこの`:`ネームスペースが用いられた行儀の悪いデータを見る機会がありますが、上記のような問題を引き起こしてしまううえに修正もかなりめんどくさかったりします。

そもそもノード名の衝突を避ける目的であるネームスペースをこのような使い方をしてしまうのは考え物なので、
どうしても使いたい方は責任を持ってルールを整備するなどの対応を心がけて欲しいところです。

## 2. melでSkinClusterを生成する際にジオメトリをインフルエンスとして指定すると落ちる
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">スキンクラスターをmelで実行するときに、<br>ジオメトリをスキンクラスター作成時にインフルエンスとして登録して実行すると　ｵﾁﾙﾖ！</p>&mdash; 単式シュールストレミング (@9boz) <a href="https://twitter.com/9boz/status/1336593927571263490?ref_src=twsrc%5Etfw">December 9, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
こちらは初耳学認定の内容でした。
確かにjoint以外がインフルエンスに指定されていると気分が落ち込みますよね。Mayaの気持ちも分かります。  

ただ、残念(?)なことにMaya2019ぐらいからは落ちなくなってしまったみたいですね。
手元では再現できませんでした。残念(?)
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">2016あたりだとskinClusterがサイクル起こして落ちてました<br>2019だと直ってるっぽいですね</p>&mdash; 単式シュールストレミング (@9boz) <a href="https://twitter.com/9boz/status/1336609971253874689?ref_src=twsrc%5Etfw">December 9, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

## 3. melの引数に`,`を紛れ込ませる
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">global proc hoge（,string $arg）<br>{<br> print（$arg）;<br>}<br><br>hoge（&quot;test&quot;）;<br><br>確かこんな感じで。<br>引数の部分の余分なカンマがクラッシュさせます。</p>&mdash; 石子晃之 (@terish312) <a href="https://twitter.com/terish312/status/1336627085767413760?ref_src=twsrc%5Etfw">December 9, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212052/90c32897-877d-b641-07f8-163adc8efa37.png)
**ビューティフォー**
少なくともMaya2018~2020でも改善されていない事を確認しました。非常に美しい致命的なエラーです。
本当にありがとうございました。

## 4. MCommandMessage.addCommandOutputCallbackに渡した関数内でPrintしたりすると無限ループで死ぬ
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">当然と言えば当然なんですが、MCommandMessage.addCommandOutputCallbackに渡した関数内でPrintしたりすると無限ループで死にますね！<br><br>まあ、これは使う側の問題なんで若干募集意図とは違うかもですが……</p>&mdash; 赤城 巧 (@takumi_akashiro) <a href="https://twitter.com/takumi_akashiro/status/1336891730495324160?ref_src=twsrc%5Etfw">December 10, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

MCommandMessage.addCommandOutputCallbackはMELコマンドがコマンドウィンドウに出力されるような出力を生成するたびにコールバックを登録するようなメソッドです。
そんなメソッドの中でprintをすると、当たり前ですが無限ループします。
これはネタを提供してくださったご自身も指摘されてる通りどちらかというとバグというよりはwhile Trueのようなものでなるべくして無限ループしているのですが、printデバッガーな私にとってはいつかやってしまいそうなので要注意ですね。

## 5. menu直下に登録したmenuItemに親のmenuを削除&再登録するようなコマンドを登録して実行すると致命的なエラーで落ちる
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">&gt;Mayaのバグ<br>古いバージョンに定住してるので、別バージョンでも確定してクラッシュを起こせるネタを出すのは難しい……<br><br>今使ってるバージョンだと、MenuItemから実行した関数で親ウィンドウ消すとクラッシュするけど、流石に次かその次のバージョンでは直ってる(と思いたい)し……</p>&mdash; 赤城 巧 (@takumi_akashiro) <a href="https://twitter.com/takumi_akashiro/status/1336895732716957697?ref_src=twsrc%5Etfw">December 10, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
これは私も体験したことがあります。
UIの内容を更新するための機能を持ったメニューを作っている時に同様の問題に直面しました。

大体こんな感じです。

```python

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()
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212052/412ea93e-5a25-d286-34d4-a9b512e85327.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212052/32955dbc-d000-937c-e886-c33761b57e89.png)

**見事な落ちっぷりです。**

Maya2017~2018あたりで試すと致命的なエラーで確実に落ちるのですが、
Maya2020では**非常に残念(?)なことに致命的なエラーが出なくなっており意図通りmenuItemから親menuを削除&再構築ようになっていました。**
治ってないと思っていただけに非常に悔しい(?)思いです。

## その他、時間が無くて検証できなかったり、検証するまでもなく治っちゃってたりした作品たち
ここからは時間がなくて試せなかった作品や私が試すまでもなく治っちゃってたりした作品を紹介します。
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">Maya2018でIK設定したシーンをリファレンスした状態でさらにIK設定をして、後者のIKがリファレンス由来のIKRPsolverとかに接続しているとき、リファレンスをアンロードするとしにますがMaya2019で試してみたらしななくてかなしい（かなしい？）</p>&mdash; トモハラ (@tm8r) <a href="https://twitter.com/tm8r/status/1336883577225527298?ref_src=twsrc%5Etfw">December 10, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
リファレンスがらみのデータは落ちやすい印象ですがこの例では改善されたみたいですね。残念(?)です。


<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">Undoしまくると落ちますよね。<br>あとはレンダラー系のプラグインアンロードすると落ちる。これ自体はやむなしとしても、ユーザーがイジれないようにするやさしさは欲しい</p>&mdash; yamadaaaaaaa (@yamada41052185) <a href="https://twitter.com/yamada41052185/status/1336998933369778176?ref_src=twsrc%5Etfw">December 10, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
ユーザーがうっかり触れてしまう場所にクラッシュが潜んでいるのは非常に恐ろしい事です。


## 終わりに
いかがでしたでしょうか。

実はこのテーマ、苦し紛れの思い付きではなくて2年以上前から考えていたネタでした。
なかなか記事化する機会がありませんでしたが、今回はアドベントカレンダーのバトンを繋ぐという名目で記事化することができました。

くだらないネタ記事ですが何かの参考になれば幸いです。
明日の記事はshigehiroさんの「Maya Python API 2.0 のプラグインをC+＋で書きかえる」です。