Posted at

Maya `Cannot find procedure "look"` への対処方法

皆様ごきげんよう。全国一千万のmaya界では7.31.2019で話題フットー中であるがいかがお過ごしだろうか。閑話休題、つい先日筆者は maya で作業中、特定のシーンデータを開きアウトライナを操作すると Cannot find procedure "look" というエラーが発生する現象、 https://qiita.com/ti_ni_ta/items/bdbf30d0236addb267a2https://qiita.com/mono-g/items/457b1c80147daa059eb2 にかかれている現象に遭遇した。この記事ではとくに表題のエラーへの対象法について紹介したい。


なにがおきるのか

詳しくはリンクを参照していただきたいが、mayaシーンファイルを媒介とした感染性のエラーである。表題のエラーは アウトライナ で要素を選択した際に逐一エラーとなるコールバックが発火している。

具体的にはシーンファイル中に UI設定が記述されており、そのなかにアウトライナのコールバックが設定されている。このUI設定がシーンを開いた際、ローカルのmayaの設定に転写され、以降そのローカルマシンで保存するシーンファイルにも記述される。この設定がエラーを引き起こす。もうなんか非常にアレ。


対応

シーンに記述されたコールバックがエラーを起こすのであれば、そのコールバックを上書きする、さらにはそのような設定を保存しない、ことが免疫として機能すると考えるのは妥当だ。実際 modelEditor については機能するのだが、実は OutlinerEditorselectCommand コールバックにかぎっては前掲のリンクの対応では不十分である。ここではそれへの対処を記述する。


コールバックの空文字での上書きが不十分な理由と対応

空文字を渡してもコールバックが削除されず、空文字を実行しようと?する。設定したそのセッションではそれで充分なのであるが、なぜか次セッションでは mel的にはエラーとなる。興味がある方は workspace の保存を有効にした状態で cmds.outlinerEditor("outlinerPanel1", e=True, selectCommand="") を実行し何が起きるかを試してみるとよい。

なので空文字の設定ではなく outlinerEditor 自体消し飛ばすことにする。以下コードを示す

def eliminate_outliner_callback(client_data):

all_panels = cmds.getPanel(type="outlinerPanel") or []
for panel in all_panels:

sc = cmds.outlinerEditor(panel, q=True, selectCommand=True)
if sc is not None: # if there are selectCommand set...

print("KILL INFECTED outliner!!!")

cmds.outlinerPanel(panel, e=True, unParent=True) # remove infected panel
cmds.file(uiConfiguration=False) # mark as do not save ui info within scene file

if (
cmds.optionVar(exists="useScenePanelConfig") and
cmds.optionVar(q="useScenePanelConfig") == 0
):
mel.eval("$gOutlinerPanelNeedsInit = 1;") # flag to restore later

mel.eval("initOutlinerPanel();") # restore outliner if flagged

のようなコマンドを

    om.MSceneMessage.addCallback(

om.MSceneMessage.kAfterOpen,
eliminate_outliner_callback
)

シーンオープンに引っ掛けるなどしておくとよいだろう。上記のコードでは、シーンを開いた際コールバックの設定された outlinerがある場合はいったん閉じ、必要に応じてアウトライナの再初期化を行っている。必要に応じて、というのはつまり、表題のエラーがおきるトリガが各ローカルの設定に依存しているからだ。無害であるのであればそれ以上の感染拡大を cmds.file(uiConfiguration=False) で防ぎつつ素通ししている。


おわりに

この記事では対処療法をしめしたが、そもそもこのようなことが起きないようなシステムを望みたい。シーン中にこのようなコールバックの記述および読み取りを含むのは明らかに不要だ。また maya ではないがしばらく前にはシーンファイルを媒介とした攻撃意図をもったファイルの存在が話題になった。各ベンダには安全な設計を願いたい。