CG・コンテンツ制作
  1. CG・コンテンツ制作トップ
  2. DAIKIN CG Channel
  3. UsersNotes
  4. スクリプト
  5. Maya;Python で Clip 保存ツールを作ろう!!
SUITE USERS NOTES
Maya;Python で Clip 保存ツールを作ろう!!
Maya; Let's Make a SaveClip Tool with Python
(Used Maya 2014, 2015)
プロローグ;Prologue
Maya の標準機能でClipを保存するツールは ブラウザが表示 されるものです。
TraxEditorで ファイル > アニメーションクリップの書き出しです。
また、バイザーでは、右マウスクリック > 書き出し もあります。

そこで思うのです。
TraxEditor 上に配置された Clip を直接保存するツールをスクリプトで作れないかなー
って、いざ挑戦してみると・・・意外に・・・ハマります!!
(Mayaの書き込みフォーラムでも沢山の人がハマってます~)

今回は、MELの解き方と合わせて、
上記機能を実現するスクリプトを Pythonで組んでみたいと思います。

さ~、どんな困難に直面しするのか、皆さんも謎解きに御参加してください。

あ、ツールだけ使いたい、でもOKなんですがね。

なお、このサイトで掲載している事例の決まり事ですが、
使用に関しては自己責任でよろしくお願い申し上げます。
(Maya2014、2015で動作確認しています)

Please use it as your own risk.
Windows7 Professional 64Bit、Intel Core i7-3930K(3.20GHz,6コア/12スレッド)
メモリ16GB、NVIDIA GeForce GTX560 Ti 2GB(メモリ2GB)
save_clip_00

izt_ritaro_ml



標準機能
まずは、Mayaの標準機能で TraxEditor 上の Clip を保存して、そのログを見てみましょう。
Clip だけを選択状態にし、ファイル > アニメーションクリップの書き出し を実行します。
save_clip_01
するとdoExportClipArgList 1 {"clipEditorPanel2ClipEditor"};という Melコマンド を発見できます。

では、もう1つの方法はどうでしょうか。
バイザーでは、右マウスクリック > 書き出し を実行します。
save_clip_02
するとdoExportClipArgList 2 { "", "joint_1anmSource"};というMelコマンド を発見できます。

なんだ、同じコマンドじゃん、となります。

doExportClipArgList の後の数字は、だいたいMelの場合 バージョン番号で、
の時はClipが選択されている状態で実行する
の時は出力するClipの名前で実行する
・・のではないかと推測できます。

では、Melの探検準備OK、覗いてみることにしましょう。



doExportClipArgList って?
さて、doExportClipArgListどこにあるかのはいつもの呪文whatIs を使います。
スクリプトエディタのMELタブにてwhatIs doExportClipArgListを実行します。
save_clip_03
すると、C:/Program Files/Autodesk/Maya2015/scripts/others/doExportClipArgList.melだって分ります。

では、doExportClipArgList.melを手持ちのWindows用スクリプトエディタ開いてみます。
だいたい、先頭部分にフラグの説明が書いてあります。思っていた感じの番号の説明が書いてありますね。
save_clip_04
そこまで分ったので、doExportClipArgListクリップ名を渡している部分を探してみましょう。 
doExportClipArgListを実行している部分です。
save_clip_05
バージョン番号文字列 doExportClipArgListに渡しています。
そして、ブラウサー fileBrowser を立ち上げてclipEditorExportClipを実行している部分があります。

次はこの clipEditorExportClip が何をしているかが分れば良いことになります。
save_clip_06
すると、出力するファイルの種類はClipの場合、Asciiの ma って分っていて、
file コマンド と フラグ が書いてあるので、おお、しめしめ これで求めるスクリプトを想像してみることが出来ます。
file -f -type "mayaAscii" -exportSelected -channels true -constructionHistory true "F:/user_maya/Maya2015/clips/joint_1anm2.ma";

Python 的に書き直すと、

cmds.file('F:/user_maya/Maya2015/clips/joint_1anm2.ma',type='mayaAscii',force=True,exportSelected=True,channels=True, constructionHistory=True)

でしょうか。

いざ実行!結果、エラーも無く、あっと言う間に終わるので、OKか??って思うじゃん。

出力されたファイルの大きさを、Mayaの標準機能で出力した ma ファイルと比べると、少ない事に気が付きます。
そして、実際に TraxEditor に今スクリプトで保存したClipを読み込もうとすると・・・失敗します!!

Why? なぜでしょう・・・



clipLibrary
出力される Clipのデータは ASCIIファイルなので、テキストエディターで開いて違う部分を見てみることにしましょう。
save_clip_07
すると、12行目ではやくも違いを見つけることが出来ます。

Mayaの標準ツールで保存した .ma には、clipLibrary の項目があり、その中に 各ノードのデータが記述されています。
この部分がごっそり無いのに気が付きます。これじゃ動かないわけです。

では、改めてdoExportClipArgList.melclipEditorExportClip部分、先に発見したfile コマンドの少し上あたりに注目します。
すると Clip に関する記述が2つあるのが解ります。
save_clip_08
下のはsourceClip と書いてあるので、ソースのClipも追加選択した状態で出力するのかとわかります。
もう1つ、clipisolate フラグを立てた値を渡しています。ここでピンと来た方は Clip のコマンド表を見た事のある人ですね。見てみましょう。

cliphttp://download.autodesk.com/global/docs/maya2014/ja_jp/CommandsPython/clip.html

isolate(i)
このフラグは name フラグと一緒に使用し、1つまたは複数のクリップを新規のクリップライブラリにコピーするように指定します。
このフラグの最も一般的な用途は、キャラクタのすべてのクリップではなく、特定のクリップのみの書き出しです。

これです。!!
つまり、クリップのライブラリーを取得して、Clipのソースと共に選択した状態で file コマンドで出力する ようなんです。

Melをもっと簡単に書くと、

string $clipName = "joint_1anm";
string $sourceClipName = `clip -q -scn $clipName`;
string $result[] = `clip -isolate -name $sourceClipName`;
select -clear;
select $result[0];
select -add $sourceClipName;
file -f -type "mayaAscii" -exportSelected -channels true -constructionHistory true "F:/user_maya/Maya2015/clips/joint_1anm2.ma";

です。
Python に書き直し、Clipのみを選択した状態で、実行します。

selected_clip = cmds.ls( sl=True )[0]
selected_clip_source = cmds.clip(selected_clip,query=True,sourceClipName=True,allAbsolute=True)
selected_clip_library = cmds.clip(isolate=True,name=selected_clip_source,allAbsolute=True)
print selected_clip_library
cmds.select(clear=True)
cmds.select(selected_clip_library[0],replace=True)
cmds.select(selected_clip_source,add=True)
cmds.file('F:/user_maya/Maya2015/clips/joint_1anm2.ma',type='mayaAscii',force=True,exportSelected=True, channels=True, constructionHistory=True)

結果
[u'clipLibrary1', u'joint_1anmSource']


これで書き出された.ma ファイルは見事に動きます。大成功です。

途中に print 文を挟んでいます。
すると2つの文字がリストで出力されるのを認識して欲しかったからと、もう1つの理由は後で説明します。

1つ目は、その2つ下の行でわざわざselected_clip_library[0]と書いているのは
この2つのデータの内、最初のクリップ ライブラリを設定したかったからだと気が付きます。

2つ目の理由は・・・・
同じClipを選択した状態から何度か上のスクリプトを実行してみてください。

結果
[u'clipLibrary4', u'clipLibrary5', u'clipLibrary6', u'clipLibrary7', u'joint_1anmSource']


ん?どんどん増えるぞ、やばくね?



後処理
またまた、doExportClipArgList.melclipEditorExportClip部分、先に発見したfile コマンドの下あたりに注目します。
するとclipLibraryに関する記述が続いているのがわかります。
save_clip_09
ファイルを出力した後、クリップライブラリーを消しているのです。
そこで、記述も真似て、もし1つ以上あったらその分だけ全部消すというスクリプトを追加します。

lib = cmds.ls(selected_clip_library,type='clipLibrary')
if len(lib) != 0:
    for i in range(len(lib)):
        cmds.delete(lib[i])

これで完成か!? と思い、先に出力したClipをTraxEditorに乗せてみます。
そこで気が付くのは、1つ目の元のClipと同じっぽいけど違う動きの結果になったりしています。

Why? なぜでしょう・・・



絶対値の処理
Clipを配置し、そのアトリビュートのチャンネルオフセット 項目を見ます。
save_clip_10
すると、全ての値が 相対値 になっています。
追加される動きの時には相対値は便利ですが、通常のアニメーション編集の時は 絶対値 でないと理解できなくなります。
元のClipを見ると絶対値になっているので、これは保存の仕方や前処理があるに違いないと考えます。

またまた、doExportClipArgList.melclipEditorExportClip部分もっと最初の部分に注目します。
ClipとソースClipに何やら前処理をしている部分があることに気が付きます。
save_clip_11
このcopyAbsoluteChannelsClipDataも別Melファイルのコマンドです。(C:/Program Files/Autodesk/Maya2014/scripts/others/copyAbsoluteChannelsClipData.mel)
今回はこのまま利用してしまいます。

if selected_clip_source != selected_clip:
    mel.eval('copyAbsoluteChannelsClipData("%s","%s")' % (selected_clip_source,selected_clip))

これを通して作成したClipをTraxEditor に配置してみると絶対値 になっていて、元のClipを同じ動きをするようになりました。
save_clip_12
めでたしめでたし。

以上です。



save_clip.py
という訳でClipを直接TraxEditorから保存するツールsave_clip.pyを公開します。
(Pyファイルはシェルフにボタン登録するか、プルダウンメニューに登録して実行します。)
あくまでも自己責任でお使いください。 use as your own risk.

Clipを直接TraxEditorから保存するツール
(Maya2014,2015)

save_clip.zip 1.15 KB2015/03/19 現在


という訳で、次回は...What's Next ...
乞う、ご期待!!Stay tuned ..
戻る 次へ

お気軽にお問い合わせください

Daikin CG News お申し込み

CGクリエイター向けのセミナー・イベントやキャンペーン、製品情報をメールマガジンでお届けします。(登録無料)

Twitter

ページの先頭へ