LoginSignup
12
10

More than 3 years have passed since last update.

年末大掃除! 対 謎のcallbackエラー

Last updated at Posted at 2018-12-27

いやぁクリスマスまであと何日ですかね…

はい茶番はどうでもいいですね。アドカレ過ぎてますけど空いてるとこを埋めさせていただきます。
 

今回はネタを詰める時間もないので、最近あったエラー事例を解決までの道のりをレポート形式で。

"CgAbBlastPanelOptChangeCallback"このエラーについて。

きっと、ググってたどり着いてきた人ばかりでしょう…

■追記■
以下の方の記事の方が真に迫ってると思うのでそちらの方を参照していただくのが安全かと思われます。
https://qiita.com/ti_ni_ta/items/bdbf30d0236addb267a2

その上でまだ興味ある方は読み進めていただければと。

解決法だけ知りたい方はさくっとまとめの項に飛んじゃってください。

とにかくエラー出してくるやべぇヤツ

あるとき、あるシーンを開いてみるとこんなエラーが。

 dispCallBackErr_01.png

// Error: line 1: Cannot find procedure "CgAbBlastPanelOptChangeCallback". //

最初は特に気にしなかったのですが、だんだんとこれを頻繁に見かけるように…

TA/TDやってると何気ないエラーも気になります。

というのも、エラーがツールやプラグインによる要因だった場合死活問題だからです。

しかし、それ以前にこのエラーかなり奇妙です。

シーンを開いたときに出るので、シーン依存のエラーかと思いきや…

dispCallBackErr_03.PNG
 

new sceneしても何故か出てくる…

dispCallBackErr_03.PNG 

エラーの量も増えとる…
 
 

とりあえずググってみる

結果だけ言うとほとんど出てきません。

出てきてもmaいじれよという例ばかり。

となるともう自分で調査するしかないですね。

というわけで、該当シーンをmaで保存して…って保存できません

unknown nodeとかでシーンが汚くてあれやこれやのせいなんですが、

ここら辺はさくっと自分で作っておいたツールできれいにしていざma。

dispCallBackErr_04.png

なんやらかんやらのmelの間に目的の"CgAbBlastPanelOptChangeCallback"があるようです…

単純じゃなさそうですね。

ちなみに、試しにこの長ったらしいのを消して保存して、再オープンしてみると…

dispCallBackErr_03.PNG
 

消えないやんけ!

すいません。取り乱しました…

いや、本当どういうことなの…

一応念のためMayaを再起動してシーン開いてみると、なんとか消えました。

うーむ、これは記述されていた部分が怪しいのは当たり前として、何か更にありそうですね。
 

おのれレイアウト保存機能

というわけで、該当記述部分を調べてみると、どうやらシーンのレイアウトを保存している部分のようです。

というわけで、試しにレイアウトを保存する機能をオフってみます。

dispCallBackErr_06.png

この状態でシーンを保存してmaを見てみると、該当部分の記述がちゃんと消えてます

これでもう安心ですね!一応シーンを開いて確認してみましょう。

dispCallBackErr_03.PNG

消えとらんやんけ!

どういうこったよ…

正直頭を抱えるしかありません。

思わず、「なんでやねん」とこの世の理不尽に声を出して突っ込んでしまう始末(実話)

またも、ダメ元でMayaを再起動してシーン開いてみると、なんとか消えてました。
 

もしかして…callback

さて、まだ、完全解決には遠いですが、とりあえずの対処は見えてきました。

・ maで該当部分を消す
or
・ レイアウト保存機能を切って再保存
 ↓
・mayaを再起動

これで一旦の対処はできそうです。

しかし、アーティスト陣に、このエラー出たらmaいじらせて、さらにはmayaを再起動させるのは酷です。

もっと工程少なく対処をしたいです。

というわけで、調査続行。

今まで出てきた条件から推測するに一度このエラーが出るとシーンではなく、mayaにエラーが残る様子。

となると、考えられるのはscriptJobやその他スクリプトによるcallbackです。

"CgAbBlastPanelOptChangeCallback"と名前からもあるように、callbackであるのは一目瞭然なのですが、

さてどこのcallbackなのか。

さらに、エラー部分のmelを解読してみるとどうやらpanelEditorのcallbackというのがわかります。

試しに、一度エラーが出たMayaでpanelを1viewレイアウトから4viewレイアウトに変えてみます。

すると、

dispCallBackErr_03.PNG
 

ヤツが出てきます。どうやら間違いないようです。
 

そのcallbackをぶち壊す

エラーの内容からして、"CgAbBlastPanelOptChangeCallback"このコマンドあらへんよってことですから、

なんかしら同名の関数を用意してしまえばいいとも言えます。

しかし、そもそもが必要なさそうなものなのにわざわざ用意するのもあれですし、

シーンには残り続けるので根本的な対処にはなりません。

ということで、このcallbackごと消してしまえば、ma改変、レイアウト機能オフ、再起動しなくても根本的な対処ができそうです。

さて、どうしたものか…

というわけで調理したのがこちらになります。

import pymel.core as pm
# ---------------------------------------------------------
# clean up PanelCallback
# ---------------------------------------------------------
def cleanupPanelCallback():
    for item in pm.lsUI(editors=True):
        if type(item) == pm.ui.ModelEditor:
            pm.modelEditor(item, e=True, ec='')

まぁ、これは要するに、Maya内のmodelEditorのeditorChanged callbackを強制的に上書くという力業です。

正直なところスマートではないです。

もしかしたら、editorChangedに消したくない情報が入っているかもだからです。

とはいえ、このcallbackを使うような事項が思いつかなかったので結局こういう形に落ち着きました。

あとは、これをエラーが出たら叩いてもらえればいいので、ワンクリックで解決できるようになります。

一応、試してみると…
 
dispCallBackErr_07.png

消えとるやんけ!

よかったです。正直また天丼くらうのかとドキドキしてました。

いやでも、エラーが出る度に叩かせるというのはもやもやします。

絶対叩かない人が出てきます。
 

目には目をcallbackにはcallback

バケモノにはバケモノをぶつけんだよ!という精神で、callbackにはcallbackをぶつけることにします。

正確には、callbackscriptJobをぶつけます。

maya起動の際に、SceneOpenedのジョブに対してcleanupPanelCallback()を叩くscriptJobを仕込みます。

本当はSceneSavedの時に叩けるといいんですけど、SceneSavedscriptJobってセーブした後に発動するので意味ないのです…

ちなみに、私の場合は既にシーン内の不要プラグインをきれいにする自作のpluginクリーンナップを仕込んでいたので、

これに追記する感じで入れました。
 

ここがやべぇよやべぇヤツ

さて、一応これにて解決となるのですが、このエラーのやばいとこをまとめておきましょう。

アーティスト目線だと一見エラーが出るだけで実害がないように思えるのですが、そんなことありません。

〇new sceneしてもエラー

〇どんなシーン開いてもエラー

〇エラー内包しているシーンを再び開くとエラー増殖

〇その状態で無事なシーンを気にせず保存するとそのシーンも感染

さながらウィルスです。

これに似た事例として、pluginがないことによるエラーがあります。

ただ、それは該当シーンのオープンだけにエラーが出る状態なので幾分かマシです。(正直それでも感染するので嫌なんですけど)

これを放置すると、他のツールを使ったときに出るエラーがどれか追い難くなり、お手上げとなります。

解決法まとめ

A.手作業で解決

1. maで"CgAbBlastPanelOptChangeCallback"が記述されている部分を含むコマンドを削除する。
もしくは、
1. レイアウト保存機能を切って再保存
dispCallBackErr_06.png

2. Mayaを再起動。

B.スクリプトで解決

import pymel.core as pm
# ---------------------------------------------------------
# clean up PanelCallback
# ---------------------------------------------------------
def cleanupPanelCallback():
    for item in pm.lsUI(editors=True):
        if type(item) == pm.ui.ModelEditor:
            pm.modelEditor(item, e=True, ec='')
cleanupPanelCallback()

これを実行します。

徹底策としてSceneOpenedのジョブに対してcleanupPanelCallback()を叩くscriptJobを仕込んでおきます。
 

根本原因の予測

さて、これが起きた要因なんですが、正直確定的な証拠がないので推測しかありません。

どうやら、Mayaのバージョンが怪しいもので保存されたシーンを、現行バージョンで読んだときに残るっぽいです。

今のところ、今の仕事のプロジェクト内で作られたものに関しては起きておらず、

外部からのデータでのみ起きていました。

なのでそうではないかと。

しかし、何度も言いますが、あくまで推測ですのであしからず。

おわりに

まぁ、あんまりきれいな解決方法ではありませんが、

一度きれいにしてしまえば正常な環境では起きない問題なので、とりあえずはこの対処で満足しています。

ちなみにこの解決方法

// Error: line 1: Cannot find procedure "onModelChange3dc". //

こういった、別のpanel callback系エラーにも効きます。

これはなんかのハードウェアシェーダー系のpluginで呼んでると出るようになるみたいです。

例に挙げたpluguinごみエラーとの併用系エラーですね。

というわけで、シーンエラーはほっとかないでおきましょうというお話でした。

疑問に思ったら近くのTA/TDに聞いてみてください。

stresslessなシーンの作成に役立つはずです。

ということでここまで(:3ノシ )ヘ
 
 
 
 
 ※免責事項※
本記事内で公開しているコードの安全性について、当方は一切の保証を与えておりません。
これらのコードを使用したことによって引き起こる損害に対し、当方は一切責任を負うものではありません。
自己責任でご使用ください。
 

12
10
0

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
  3. You can use dark theme
What you can do with signing up
12
10