AriToolsランチャーメニュー自動生成
こちらはMaya Python Advent Calendar 2017の23日目の記事です。
こんにちは、アドカレ初参加します。
この記事ではMayaPythonを使って、多くのMaya使いの方々が
お世話になってるであろう(私もお世話になってます)、
CG自習部屋 Mayaの時間 さんのスクリプト群をファイル・フォルダ構成を
スキャンしてランチャーメニューをMayaに自動追加します。
すでにpythonにてツールを作られている方には比較的易しい内容かと思われます。
仕様を決める
ランチャーメニュー作成ツールは外部ファイルで所定の書式を決めて
それに従って作るなど実装方法は色々あるかと思いますが、今回はCG自習部屋さんの新しいスクリプトがリリースされた際に、新しいファイルを所定の場所に配置するだけで
メニューも自動で更新されるように、ファイル・フォルダ構成を
スキャンして自動生成する仕様にしました。
scriptフォルダ以下にこのようなフォルダ構成でスクリプト群を格納します。
- フォルダ名をサブメニュー名(カテゴリ名)とする
- カテゴリフォルダ以下には以下のファイルを配置
スクリプト(mel) アイコン(png) 注釈テキスト(txt)
ファイル名はすべてmelツール名と同じ
※アイコン、注釈の追加はツールにより任意とする
- スクリプトファイル毎に実行メニューを作成する
実装
gistb9ee4e691438d733e7ac2de130ce7ec6
最初にフォルダ・ファイルをスキャンして
カテゴリ名をキーとして各スクリプトパスを格納した辞書を作成。
アルファベット順に表示させる為、標準の辞書ではなく、
collections.OrderedDictを使用しています。
scriptのロード
melの為、サブフォルダ格納になるとscriptパスが通ってない為、
sourceコマンドでロードしておく必要があります。
以下のように相対パスで書けば読み込めます。
ただし、一気にsourceをすることになるので、ツール側のグローバル変数名や関数名被りがあると危ないことにはなります。
source "AriTools/Modeling/AriMirror.mel";
menuItemの登録
ツール側がmelの場合、cmdsでmenuItemを作ってしまうと
実行メニューからシェルフへの登録時のコードがPythonObjectとなってしまうために
melコマンドのほうでmenuItemを登録します。
これでシェルフへの登録も楽ちんに。
アイコン・注釈
アイコン、注釈用のテキストがあれば登録します。
注釈用のテキストは1行目に入ってるテキストのみを読み取って利用します。
menuItemのAnnotationとして設定します。
Maya画面左下にメニューを選択した際にツール内容の注釈が表示されます。
また、Annotationを設定しておくとシェルフに登録した際も
注釈がポップアップされます。
Annotationは気づきにくいのでメニュー名に読み取った注釈を足す方法もあります。
ただし、メニューのウィンドウが長くなるので
この辺は好みかと思います。
popupMenu版
Maya本体へのメニュー登録ではなく、ビューポート上での
popup menu方式にすることもできます。
cmds.popupMenu(menuName, ctl=True, button=2, markingMenu=True, p="viewPanes", allowOptionBoxes=1)
cmds.menuをこちらに切り替えることで、Ctrl+マウス中クリックにて
メニューがポップアップされます。
usersetup.pyへの登録
Maya起動時にメニューを自動登録するように、usersetup.pyで実行させます。
色んなツールを導入されている方は
すでにusersetup.pyが存在しているかもしれません。
その場合はそちらに組み込む必要があります。
サンプルのusersetup.pyもアップしていますので参考にしてください。
応用編1 ダウンロード&インストーラー
CG自習さんから新たなツールやバージョンアップがあった際に
ツールのzipへのurlをコピペして、プルダウンメニューから各カテゴリの
フォルダを選択してダウンロード&zip解凍して、メニューを再作成する
ようなツールを作れば、Maya再起動することなく
自動インストール&メニュー更新もできそうです。
import os, urllib, zipfile url = 'http://file.blog.fc2.com/vectrix/mel/AriAnimationCopy.zip' fileName = os.path.basename(url) urllib.urlretrieve(url, fileName) with zipfile.ZipFile(filename, 'r') as myzip: myzip.extractall()
これでダウンロード、解凍することができます。
応用編2 pythonツールにも対応する
今はmelにしか対応していませんが、自作のpythonツールにも対応してみます。
フォルダ構成は特に変更ありませんが、
各カテゴリフォルダには__init__.pyを配置しておきます。
また各スクリプトは以下のルールに合わせておきます。
- Pythonの実行関数はmainとする
- melの実行関数はmelファイル名と同名
実装
変わっている部分はフォルダ・ファイルのスキャン部分で
.mel .pyを含めて取得しています。
またmelかpyかでメニューへの登録で処理を分けました。
menuItemの登録
ツールがpythonの場合、こちらもシェルフへの登録を考慮して
melからpythonを実行する形としてます。
おわりに
いかがでしたでしょうか。
AdventCalendar記事を書かれているような猛者の方々には
少々物足らない内容だったかもしれませんが、
何か参考になれば幸いです。
Pysideポップアップメニュー版も作りたかったのですが
重複起動バグがあるのでまた機会があれば