|
Maya での Python 準備 ■Maya の日本語ドキュメントをダウンロード して HELドキュメント をローカルディスクに用意して、Mayaに認識させましょう。 Download & Install Maya Product Help(日本語Web版はこちら >> http://help.autodesk.com/view/MAYAUL/2015/JPN/) https://www.autodesk.com/support/technical/article/caas/tsarticles/ts/6hGHDwrHzKBq8zd65p4LpK.html 最新の2015版はインストーラーではなく、ZIPで展開するだけのものなので、 インストーラーだった May 2014 版 のディレクトリーを真似て 2015版を置くとしたら C:\Program Files (x86)\Autodesk\Maya2015\docs\Maya2015\ja_JP の下に展開したものをコピーします。 その場所を、プレファレンス > インターフェイス > ヘルプのヘルプの場所項目でカスタムの欄に登録します。 そうしたら、スクリプトエディタ で、選択したコマンド名から > コマンドドキュメント を表示させたり、 ヘルプ > Pythonのヘルプ で ユーザーガイドが素早く表示できたりします。 また、コマンド > クィックヘルプの表示を有効にすると、右側に欄にオプションが表示されます。(狭いよ~^_^;;) コマンド > ツールヒントヘルプの表示はコマンドを書いている途中に情報を表示したりします。 等など、色々と表示される仕組みはあるのですが、あとは好みでお願いします。 |
GraphEditor について;Python Mayaの GraphEditor についてまず言えることは、"複数のツールから組合わさあれた scripted panel である"、ということです。 ドキュメントを見ると、複数のウィンドをまとめて表示しているのがパネルだと解ります。 ■scriptedPanelhttp://help.autodesk.com/cloudhelp/2015/JPN/Maya-Tech-Docs/CommandsPython/scriptedPanel.html 複数のGUIデータからなる GraphEditor ということが良く解る 現象として スクリプトから GraphEditor をうまく綺麗に削除することができず、中身がなくてパネル枠だけで残った状態になったりします。 (パネルエディタからパネルを削除した時のログを見ると、deleteGraphEditor graphEditor2など見られますが、このコマンドだけでは綺麗に削除することができません) つまり、ここで紹介する、ティアオフによる複数表示の GraphEditorは、パネルエディタから削除するが最も無難なようです。(か、開くときをOFFです。) 更に複数ツールから成り立っていることが解ることとして、アニメーションのカーブ部分を扱うコマンドは animCurveEditorになっています。 ■animCurveEditorhttp://help.autodesk.com/cloudhelp/2015/JPN/Maya-Tech-Docs/CommandsPython/animCurveEditor.html さて、これらのことを知りつつ、パネルの情報を得るコマンドとしてはgetPanel というものがあります。 ■getPanelhttp://help.autodesk.com/cloudhelp/2015/JPN/Maya-Tech-Docs/CommandsPython/getPanel.html 以下の記述で黒い枠内に書かれたスクリプトは、下図のようにスクリプトエディタでPythonタブ内に記述して実行したものとします。 実行時にスクリプトを選択して状態で実行(テンキーのEnter)をした場合、実行後に記述が消えません。 getPanel にscriptType というオプションを使い そのタイプが 'graphEditor' のもの って指定出来ます。 新規シーンでは GraphEditor が1つデフォルトで存在します。 また、取得した名前は[u'graphEditor1']とタイプが unicode であることに注目してください。 ティアオフした GraphEditor を追加で4つ作成すると、合計5つの GraphEditor がシーンにあることになります。
何個あるかはlen()で、数値 を 文字にするには str()なので、Python では 一気に書け~! で、こんな風に記述できます。
また、動作を行っている己のパネル(アクティブなパネル)の名前を知るには withFocus というオプションを使います。 スクリプトエディタもパネルなので、実行するとこのスクリプトエディタのパネル名を取得します。
ではでは、とっておきの本命。 ティアオフしてコピーした GraphEditor を表示するようなスクリプトはないのか? はい、実は2つも方法があります。(探してもみつからなかった?) また、 MayaのGUIを作成している部分は Melなので、PythonからはMelを呼び出して実行するというかたちにします。 1つは、その名ものずばりtearOffCopyItemCmd、もう1つはtearOffPanelを使います。 前者は、こう解きます。 >> シーンにデフォルトであるスクリプトパネルの名前は graphEditor1 なので、それをティアオフコピーする。
同じスクリプトを何回でも実行出来て、何個でも GraphEditor を作れます。 パネルエディタで見るとグラフ エディタ2,3,4・・・という名前になっていきます。 このコマンドでは、出来るパネルの名前が設定できないのと、日本語ってどうよ、って感じなのです。 後者は、こう解きます。 >> graphEditorをGraphEditor1 という名前のパネルでティアオフする。
今度は、同じスクリプトを実行しても、最初しか表示しません。それは、既にGraphEditor1という名前のパネルが存在しているからです。 そこで出来るパネルの名前を"GraphEditor2""GraphEditor3"と変えてみると、その名のパネルがドンドンと作成出来ます。 ということで、こう解きます。 既存の GraphEditor の数を得て、それに1を足した数値を文字列に置き換えて"GraphEditor"の後ろに追記していけば 同じスクリプトでドンドンパネルが追加出来ると。 そこで、はっと思い出します。 あー、Melを実行しているコマンド部分にPytonからの変数を渡さなければならない と。
GraphEditor2から始まりますが、同じスクリプトで GraphEditor をどんどん追加表示できます。 ではここで、ティアオフしたGraphEditor2・・・が作成されるコマンドの後で アクティブなパネルの名前を取得しようとprint cmds.getPanel( scriptType='graphEditor' )を記述して実行しても まだスクリプトを実行しているスクリプトエディターがアクティブな状態なので、scriptEditorPanel1しか取得できません。
この章の締めとして、上記内容を1つのファイルCustomGraphEditor.pyとして保存し、Shelfにボタン登録したボタンから起動出来るようにしてみます。 以下のように書き直します。def 内は、4つのスペース(インデント)を設けて記述します。
そしたら、スクリプトエディタの右上のプルダウンメニューから、ファイル > スクリプトの保存を選択します。 保存先がユーザーディレクトリーのscripts 内になっているので、CustomGraphEditor.pyとして保存します。 (MAYA_SCRIPT_PATHがデフォルトで通っているディレクトリーです。) (PCの環境設定にMAYA_APP_DIRを設定している場合は、ユーザーのディレクトリーはそちらになります。) 今度は、そのCustomGraphEditor.pyファイルを実行するスクリプトです。
実行して動くことを確認したら、ボタンを登録したいShelfタブ を表示しておきます。 スクリプトエディタの右上のプルダウンメニューから、ファイル > スクリプトをシェルフに保存...を選択します。
これでもう、ボタンを押せばカスタムのグラフエディタが表示される仕組みは準備できました。 Mayaのメインメニューからのプルダウンを設定して、そこからの起動は、下記のように記述します。
メニュー自体もティアオフ出来ます。 こちらについては、ワークグループの設定を説明する別ページにて解説出来ればと考えています。(お楽しみに ^_^;;) |
カレントフレーム用のスライダーを作る;Python さて、お次はPythonを使ってカレントフレームが変更できる横長のスライダー を作ってみましよう。 幾つか種類あり、今回は整数値の表示部とスライダーのあるintSliderGrpでいきます。
シーンの現在のカレントフレーム値を設定するのはcurrentTime(フレーム数, edit=True)で出来ます。 スライダーが表示される時、シーンの最小値/最大値をplaybackOptionsコマンドのminTime/maxTimeで取得します。 cmds.window()/cmds.showWindow()内のものがウィンド表示されるものです。 rowLayoutコマンドは水平一列に配置できるレイアウトを作成するのですが、 adjustableColumn オプションで横に引き伸ばした時にスライダーも伸びるように設定出来ます。 スライダーの初期値=value は、作成時のシーンのフレーム数currentTime( query=True )を取得しています。 このスクリプトで最もラブリーな書き方になっている所は、 スライダーが変化したり=changeCommand、ドラッグされたり=dragCommand した時に、 スライダー自身の値が取得されるように使っている関数の仕組み lambda x:set_current_frame(int(x))という部分です。(ブレイクスルーでしょ!!)
実行すると、下図のように、スライドすると現在のフレーム値が連動し、数値を入力しても現在のフレーム値になります。 ただし、シーンの最小/最大フレーム値を変化させてもスライダーはリアルタイムには更新しませんので、なんのことはない、再表示してください。 ちなみに、何枚でも表示できます。 さて、ここでのキモだったlambda式 は、ラジオボタンなど多くのところで素晴らしい働きをしてくれますので、ぜひマスターしてください。 この章の締めくくる前に、少しこの lambda式 を解説してみたいと思います。 lambda式 無名関数 ;Pythonhttp://docs.python.jp/2/reference/expressions.html#lambda defステートメントのように関数を作成するが、lambdaは 「式」 を記述する。 defステートメントは関数の名前を記述するが、lambda式 では意図的に代入しない限り名前が無い、無名関数生成式。 defでは記述できないような場所にlambda式 は書くことが出来、とっても便利 です ^ _ ^ ;;
って実行した後に、
って実行すると、
という実行結果が得られるのは、def で書くと、以下と同じことだと解ります。
そうだと気が付けば、下記のように defと同じく キーワード引数 や デフォルト値 が設定出来ます。
上記intSliderGrpで lambda式 を用いた良い点とは、スライダーの値を取得する為に cmds.intSliderGrp('TimeSlider', q=True, value=True) というコマンドを再度実行しなくて済むと同時に 同一スクリプトから複数パネルを作成した場合に スライダーの名前(上例では'TimeSlider')が重複して起こる誤動作を防ぎます。 そして、ここから面白い部分の紹介ですが、 lambda式 は、受け渡すデータが 式 となんら関係の無いものでもOKなんです。 最初の式を見てから、下の式を見て、結果を予想してください。
はい、# 結果: 15 # です。 つまり、何を投げても 15 が返って来るってことは、投げたデータ値とは全く関連性の無い値を返している、ということになります。 例えば、ボタンを押したというコマンドが来たら、決まった値を返すって時に便利ですね。(ボタンを押した事と、返す値には関連性がありません) 次章で、ラジオボタンの作成 を紹介するのですが、先に lambda式 部分を解説しますと、
と書かれている部分は、ラジオのボタン1を押すと 1 という数値を返す、ボタン2 は 2 を、ボタン3 は 3 を返すとなります。 |
ラジオボタンを作る;Python さて、お次は Python を使って3択のラジオボタン を作ってみましよう。 同時に、rowLayout を使って、テキスト入力付きボタン を横一列に配置します。
上記をスクリプトエディタで実行してみると、下図のようなウィンドが表示され、3択と共にプリントが変わり、また3択毎にボタンのプリントも変わります。 上記記述で面白いのは、グローバル値で radio_button_no = 1 と初期値化していて、ボタンの値が来たらグローバル値を置き換えています。 また、ボタンも最初の値は1なんですが、ボタンを押すと必ず2が来るので、そしたらグローバルのradio_button_noの値をプリントしています。 一見良さげなんですが、問題は例えば2つウィンドを作って、動作してみると、ラジオボタンを必ず押した後では良いのですが、 押さないで異なるウィンドのボタンを押すと、その前に選択したウィンドーのラジオボタンの値をプリントしてしまいます。 まー、使えなくは無いですが、ちょっと誤動作が残っている感じです。 先に進みます。 もう少しGUIを増やしつつ、色々と準備していきます。
上記をスクリプトエディタで実行してみると、下図のようなウィンドが表示され、3択と共にプリントが変わり、スライダーと共に数値が変化します。 この値が、接線値として、ラジオボタンの設定によって Both/In/Out に設定されれ良い、ということになります。 Get/Set のボタンは、今はプリントが表示され、動作は確認出来ます。ここは、Getの時は Both/In/Out に設定に従って選択した頂点の接線値を取得し、 Setはその値をBoth/In/Outに設定に従って選択した頂点に設定します。 さーて、いよいよ、GraphEditorにくっ付けたり、カーブからの接線値の所得、そして複数パネル表示時の誤動作をどう解決するかになります。 |
カスタム・グラフエディタ;Python で、 GraphEditor と追加されたGUIはどうやって結合したかというと、なんということはなく、 単に列挙しただけです。 GraphEditor 自身がパネルレイアウトなのです。Version 3
ただし、パネル > パネルで作成したパネル名が残っていますが、そこからパネルを表示させても追加したGUIは含まれていません。 単に新しくパネルを作成してください。 そして、複数枚パネルを作成すると値が新しい方になってしまうグローバル関数の使用をやめて 各パネル毎に値を取って置く方法として Mayaの optionVar コマンドを利用しています。 ■optionVarhttp://help.autodesk.com/cloudhelp/2015/JPN/Maya-Tech-Docs/CommandsPython/optionVar.html optionVar 変数は、userPrefs.mel にプリファレンスの一部として Maya のさまざまな呼び出しに存在する変数を保存します。 cmds.optionVar( list=True ) とするとリストを表示するのですが、既にたくさんの変数が格納されているものなのです。 intValue(iv) [string, int] (文字列から数値を取り出す)、stringValue(sv) [string, string] (文字列から文字列を取り出す)で覚えさせます。
複数ある記述としてgrp_panel_no_b = str( cmds.getPanel( withFocus=True )[11:] )がありますが、 これはアクティブなこのパネルの名前から例えばgraphEditor2の場合、前から11番目の文字から最後の文字、つまり 2 だけを取り出し textFieldButtonGrp のラベル名をこのパネル独自の前としているだけです。(他のパネルと異なるラベル名にすることによって誤動作を防いでいます)
そのほかは、選択したアニメーション・カーブの頂点からタンジェント値を求めるところは、少しややこしいことになっていますね。 設定する方は簡単だったりします。 |
Version 2;Step数の設定と < 、[]、 > スライドバーの横に、3つのボタン < 、 []、 > とStep数入力欄が増設されました!! Step数はデフォルトでは1が入っています。このままですと、[1フレーム前]、[現在]、[1フレーム次]に各ボタンを押すと進みます。 もし、シーンの再生範囲を 1~100 にしていると、100 の次は 1 に戻ってくれます(逆も)。ループアニメーションの作成に便利です。 [現在] ボタンは、複数のカスタムグラフエディターや下のシーンのタイムスライダーでカレントフレームを移動した場合、 残念ながら各スライダーと左の数値は連動しないので、この [現在] ボタンを押すことで今のカレントフレームになる、というものです。 Step数は変更することが出来、2とか 3 とか設定すると、その分を移動するボタンになります。 つまり、Step数2で1フレーム目から > ボタンを押すと、1、3、5、7、9のフレームに移動します。 これはCGアニメなど、毎フレーム再生しないアニメーションを見る時に便利かも知れません。 しかも、このカスタムグラフエディタは複数表示して置けるので、 Step数の異なるカスタムグラフエディタを幾つか用意してコマ送りして見る・・・なんてことが出来ます。 尚、Step数が1以外の時、エンドフレームを超えると最小になる、というのは仕様です(逆も)。(つまり1~100の時、98からStep3だと、開始フレームに行きます。) Python記述として面白い 追加部分 はGUI のところで、 横一列に並ぶcmds.rowLayout( )による スライダーやボタンなどが 2列 ある場合は、その上にcmds.columnLayout( )が必要で、 2列目頭にはcmds.setParent('..')が必要です。 例
|
Version 3;animの保存と読み込み カスタムグラフエディタから直接アニメーションデータの保存形式である .animで保存と読み込みの出来るボタンが増設されました!! 既存のグラフエディタには、表示しているファンクションカーブ、つまりキーアニメーションを 保存/読み込み できる項目はなく、 通常はMayaのメイン画面、ファイル > 選択項目の書き出し...とファイル > 読み込みで行います。 しかも、この .anim ファイル形式を扱えるようにする animImportExport.mll というプラグインは インストール時に用意はされているが、デフォルトでは ロードされていません。(.animファイル形式が無い・・・と書き出そうとした時気が付くとイライラ・・・) そこで、せっかくワークフローを改善しようとして用意してるカスタムグラフエディタ な訳ですので 直接保存と読み込み が出来るようにPythonで作ってみました。 animImportExport.mll プラグインもロードしてなかったら、自動的にロードしてくれるように組みましょう。(ふいにプラグインがロードされていなかったり・・を防ぎます) Python 解説 まずは、animImportExport.mll プラグインがロードされているかの判別はpluginInfo コマンドを使用して出来ます。 ■pluginInfohttp://help.autodesk.com/cloudhelp/2015/JPN/Maya-Tech-Docs/CommandsPython/pluginInfo.html
ロードされてなかったら False が返って来ることが解ったので、 if 文で not を使って逆の意味にしてロードしてなかったらロードしろ・・・と記述すれば完了。
次は、Save/Load用のディレクトリーとファイル名を指定するブラウザとその結果を実際に読み書きするコマンドはfileDialog2とfileを使います。 この2つはかなり便利で奥が深いコマンドなので、知っていると、きっと後々役に立ちます。 ■fileDialog2http://help.autodesk.com/cloudhelp/2015/JPN/Maya-Tech-Docs/CommandsPython/fileDialog2.html ■file http://help.autodesk.com/cloudhelp/2015/JPN/Maya-Tech-Docs/CommandsPython/file.html fileDialog2はそのオプションを見ると、fileModeの番号を変えると Save なのか、Load なのか、を指定できることが解ります。簡単!! fileDialog2(fileMode=0 保存 fileDialog2(fileMode=1 開く fileもオプションが沢山ある中で、保存の時はexportSelectedAnim=True、読み込みの時はi=Trueで行けそうなのは解るとして、 typeってなんだ、と気がつきます。こういう時は、実際に動作する既存方法のログを取ってみるとヒントが出て来ます。 Mayaのメイン画面、ファイル > 選択項目の書き出し...とファイル > 読み込みを実行して(下のMelコマンドでも動くよ)表示される沢山のログの中から
Melのfileオプションに-typ/-typeがあり、保存の時は"animExport"、読み込みの時は"animImport"だと解ります。 そうしたら、Pythonでこんな風にすればSave/Load出来ちゃいます。 [Save]
[Load]
Version 3;幾つかの不具合の解消 カスタムグラフエディタでアニメーションのカーブは表示してはいるのに、どの頂点も選択していない場合に タンジェント角度スライダーを動かしたり、タンジェント角度を取得/設定ボタンを押したりした時に思わぬ誤動作が存在していました。 ここを修正すべく、カーブを選択していなかったら何も動作しないようにtry: except:文を設定しました。 ■例外を処理するhttp://docs.python.jp/2/tutorial/errors.html?highlight=try%20except#tut-handling try: except:文はエラーが発生したら何々する、ということが出来るので、 ここでの場合、カーブのインデックスを選択していなかったらエラー、にしてみました。
|
Version 4;階層アニメーション対応 カスタムグラフエディタから直接保存と読み込みが出来る anim の形式を、階層アニメーション対応にしました。 Mayaにおいて、通常の操作で階層構造のアニメーションを出力するには、 メイン画面から、ファイル > 選択項目の書き出し...の所で、ファイルタイプ特有のオプション > 階層 > 下位に設定するがあります。 そうして出力した anim ファイルでないと、読み込みの時、エラー表示が出て、読み込めないのです。 この設定で出力した時のログを見ると、上記のLog と異なる部分を発見できます。 その部分をそっくり Python で認識する記述に変更しただけになります。(案の定、file は奥が深いってところです。) [Save] (↓ options= の行は本当は1行です)
[Load]
なんと長いオプションなのでしょうか。しかも他の記述方法ではうまくいきませんでした。 |
Version 5;FBXアニメーション対応 カスタムグラフエディタから直接FBXアニメーションの形式を 保存 と 読み込み が出来るボタンと階層の選択 が出来るボタンを追加しました。 V4 にて対応した anim ファイルは、名前に基づかないので、例えば末端のユレ骨のアニメーションを他の骨にコピペする時などには便利です。 ですが、その作成手順の違い等によって内部の関連性が異なるとアニメーションが壊れてしまう、ということになります。 たとえ同じ構造のように見えてもシーンに読み込だ階層構造体に animファイルを Load すると壊れてしまう、ということが発生します。 そこで、今度は逆にガッチリ名前に基づくことになるのですが、FBX形式のアニメーションの利用が考えられます。 FBXはネームスペースまで含んだ名前を見るので、名前の管理はしっかりしないといけません。 そのかわり、今度は、上図のように、あとから頭に骨を追加して内部の関連性が変化したとしても、 名前で解決しているので、ちゃんとアニメーションの読み込みに成功します。 ちなみに、anim ファイルも FBX ファイルも [Save][Load] は、 アニメーションを保存/読み込みたい一番上のボーンを選択するだけでそれ以下の階層もその対象になります。 今回追加した[SelectHierarchy] 階層の選択ボタンは、 選択したボーン以下全てのアニメーションをカスタム・グラフエディタに表示したい とか 削除したい とかいう場合に便利です。 Python 解説 さて、今回も FBX を Pythonで UIなしで ExportとImport を行えるように記述する訳ですが、 FBX関連の書き方が ユーザーガイドに載っています、が、MELなんですね。 Maya MEL スクリプティングデータ交換 > ファイルトランスレーションに FBX を使用する > Maya FBX Plug-in > http://download.autodesk.com/global/docs/maya2014/ja_jp/?url=files/GUID-F48E3B78-3E56-4869-9914-CE0FAB6E3116.htm,topicNumber=d30e149705 なので Pythonからはmel.eval で記述することになります。 まずは、fbxmaya.mll プラグインがロードされているかの判別をまたpluginInfo コマンドを使用して行います。 更に、そもそもプラグイン が無かった場合を想定して例外を処理するtry: except:文にしておきます。
今回もログを参考にしていますが、file コマンドで使用する type が、 出力する時は 'FBX export' なのに、入力の時は 'FBX' なのは、え? ですね。そして,なんと長いオプションなのでしょうか。 また、if fbx_filename: に記述を改善しているのは、 ブラウザまでは表示したのに [キャンセル] した場合に、エラー表示になるのを防いでいます。 FBXExport時のMelオプションとしては ユニット単位を cm にしています。(inch にしたい場合は変えてください) mel.eval('FBXExportConvertUnitString "cm"') [Save](↓options=の行は本当は1行です)
FBXImport時のMelオプションとしては ユニット単位を cm にしています。(inch にしたい場合は変えてください) Merge = シーンに同等のものがないノードは、すべて削除されます。 になっています。 mel.eval('FBXImportSetLockedAttribute -v true') mel.eval('FBXImportMode -v merge') mel.eval('FBXImportConvertUnitString "cm"') [Load]
|
Version 6;カーブから選択対応 カスタムグラフエディタ上に表紙されている任意のアニメーションカーブを選択して[SelectFromCurve]を押すと、 そのアニメーションが付いているオブジェクトのみの表示になります。 [SelectHierarchy]階層の選択ボタンで、キャラクターの階層全てを選択すると、全てのアニメーションカーブがカスタムグラフエディタ 上に表示されます。 表示 > アトリビュート > [レ]移動などにチェックを入れると表示するカーブの種類のフィルタリングが出来ます。 例えばスケースアニメーションが付いているのかとか検索できます。 その後、実際にそのキーアニメーションがどのJointに設定されているのかを表示するのにこの[SelectFromCurve]は役立ちます。 このための追加スクリプト記述はとても簡単です。 何か選択されているかを if 文で検索し、選択されていれば、そのカーブ名から取得して、そのオブジェクト名部分のみの名前を選択しています。 たった6行でした。
|
Version 10 (改6,9); 新GUI、新機能説明 突然バージョンが一桁上がりました。それは、もう以前よりもはるかに完成度の高いツールに仕上がっていったからです。 ここまで到達出来たのも、たくさんの要望と協力があってからこそです。 まずは一気に新機能を説明していきます。 ■タイムラインもうMayaにあるそのものになりました。シーンにあるものとシンクロして動きます。 再生範囲もMayaメイン画面下のものを変更するとすぐに反映されます。 ■再生ボタン等もうMayにあるものと同じボタンなので、もう機能説明も要りません。 Step数の指定で、|< と>| ボタンはそのStep数に分コマ飛ばしが出来ます。 ■[ShowSpeadsheet] 選択したカーブのスプレッドシートを、アトリビュートのコピー画面で表示してくれます。自動的に展開します。 コピー画面なので、何枚でも表示でき、ずっと表示したままでいてくれます。 ■CurveIndexInfo 選択したキーのIn側Out側の Angle と Weight を表示してくれます。 [Set] ボタン は任意に選択したキーに今表示している値を設定することが出来ます。 ■移動/回転/スケール の X/Y/Z と V ボタン 左マウスクリック;これらはまずは、そのカーブを選択するボタンです。 [ V10(9改)仕様変更 ] 中マウスクリック複数ノードを選択して表示している場合、同一のカーブ全てを選択状態にします。例全部の移動X。 Shift + 中マウスクリック;そのカーブのフィルタリングをします。 ■| > と > | ボタン 左マウスクリック;タイムライン上にキーのある、前/次のフレームにカレントフレームが動きます。 中マウスクリック;選択しているそのカーブの前/次のキー(頂点)を選択します。 Shift + 中マウスクリック;カレントフレームから見て前/次のキー(頂点)を選択します。 Python 解説 さて、今回一番大きかったのは、Mayaのメイン画面下にあるタイムラインと同じものをスライダーの代わりに入れ組めたことでしょうか。 これは、なんてことはない、コマンドが用意されていたのです。それは、timePortです。 ■timePorthttp://help.autodesk.com/cloudhelp/2015/JPN/Maya-Tech-Docs/CommandsPython/timePort.html ただし、例として載っている記述だけでは少し足りなくて、きちんとサイズを指定してあけると表示します。
タイムラインの横の再生等のボタンとコマンドを調べてみます。 再生ボタンを押してスクリプトエディタの履歴に出て来る(ヒストリ > すべてのコマンドのエコーを有効にする)のはplayButtonForwardです。 これがどこのMelに書かれているのかwhatIsで調べてみると、
と出て来ます。timeSlider.melをちょっと覗いてみるとこんなコマンド達が再生ボタン回りにあることが分ります。 // playButtonStart, 最初のフレームへ // playButtonStepBackward, ステップ数前フレーム // playButtonBackward // playButtonStop, // playButtonRecord, // playButtonForward 再生 > // playButtonStepForward, ステップ数次フレーム // playButtonEnd 最後のフレームへ global proc playButtonForward() { という文が書かれているところを見ると、symbolButtonにtimeplay.xpmという画像(ICON)で表示してplayButtonForwardコマンドを実行させている ってわかってきます。画像(ICON)達も調べると Mayaのデフォルトアイコン TIMEEND.XPM TIMEFWD.XPM TIMENEXT.XPM TIMEPLAY.XPM キーのある次のフレームへ timenext TIMEPREV.XPM キーのある前のフレームへ timeprev TIMEREV.XPM TIMEREW.XPM TIMESTART.XPM TIMESTOP.XPM あとは、Step数 を入れるとコマ飛ばしになるようにもしたかったのでplayButtonStepBackwardとplayButtonStepForwardだけは値が入るように 独自にPython化してみました。 この辺の周りをwindow にしてPython化するとこんなスクリプトが作成出来ました。 再生時play_forwardは、そのMelコマンドをそのまま使っても良かったのですが、再生すると停止のICONに変化する工夫を入れてみました。 (でも、後で気が付いたのは、Mayaのメイン画面で再生して、カスタムグラフエディタで停止するとアイコンが逆になりますね。もう一回やって戻してください。)
ShowSpeadsheet の表示部分も改めて知ることが多かったです。 またMel解析です。 グラフエディタで1本カーブを選択し、カーブ > スプレッドシート.. を選択するとスプレッドシートが展開するのですが、 ログを見ると、OpenAnimSpreadsheet graphEditor2FromOutliner;と出ます。 これも追うと、 whatIs OpenAnimSpreadsheet; // 結果: Mel procedure found in: C:/Program Files/Autodesk/Maya2015/scripts/others/loadAnimMenuLibrary.mel // と出ます。ではこの中で OpenAnimSpreadsheetはどんなスクリプトかと追うと、 showEditor$animCurvesに気が付きます。 すると、こういう風に組めると思います。
で、最後に□スプレッドシートの展開という所にチェックを入れておきたかったのですが、 ここが最初分りませんでした。ここの使用はMaya2013.5からコマンドが変化しています。 ここは気付かされたのは他の方のご意見からでした(情報ありがとうございます)。 SRTのカーブを選択すると、その種類によってノードタイプが異なることを発見したのです。(え、知ってました・・・) スプレッドシートの選択カーブの左にあります通り、移動;CurveTL回転;CurveTAスケール;CurveTUとなっています。 ついでにウェイトやカスタムアトリビュートのカーブはCurveTUとなっているようです。
そうするとノードタイプに応じてチェックボックスを有効にして展開したシートを表示するというスクリプトを書きます。(Mayaのバージョン分岐もあります。) ほとんどMelですね。
選択されているノードからカーブ選択 やカーブの頂点選択について。 もう1つ大きな追加機能として、移動/回転/スケール の X/Y/Z と V ボタン部分のノードからカーブ選択やカーブから頂点選択部分です。 カーブを選択するコマンドはselectKeyです。 ■selectKeyhttp://help.autodesk.com/cloudhelp/2015/JPN/Maya-Tech-Docs/CommandsPython/selectKey.html ポリゴン球を選択した状態かた移動X軸のカーブを選択してみます。
このボタンでの動作はこれで良かったのですが、後にオブジェクトじゃないもの、そうClip を選択してカーブをの頂点を選択したいとなった時、 これだと選択出来ないことに気がつきました。 確かに、カーソルでカーブの頂点を選択した時のログは
となっていますので、keyframe オプションを使用してみます。
となります。 さて、少し複雑になりますが、選択した頂点の次の頂点選択とかカレントフレームより次の頂点選択とかやってみます。 この時点では、既にカーブの頂点がどこかしたら選択されている、という段階から始まるので、現在のキー値を取得したとします。
そしたら、このリストの中の値が最初に取得した値より大きい時の値を取得すれが良いので、
選択したキーより1つ前のキーを選択は、どうでしょう。 スクリプトでは、リストの中の値が、選択したキー値より同じか超えた時のインデックスから1つ引いた時の値としました。
あ、インデックスだけと求めたい場合はこうなります。
カーブのフィルタリングをご紹介します。 既存のツールは、表示 > アトリビュートの選択..にあります。 でもここにあると表示しずらいのと、カスタムグラフエディタは複数枚表示したいので別ウィンドーツールだと選択が困ります。 コマンドのログを見ると
ということで、現在の表示しているグラフエディタの名前を取得して操作したいカーブ名を書けば良いようなので、
↑このスクリプトはスクリプトエディタで動かしても意味がありません。 最初の行は、今フォーカスしているパネルのデータを取得しているので、スクリプトエディタを取得してしまいます。 最後に、中ボタンクリックを実現しているコマンドはdragControlです。 本来はdropCallbackと合わせて使い、ボタン間のデータをドラッグ&ドロップするために使うボタン系のコマンドにあるオプションです。 ■button dragCallbackhttp://help.autodesk.com/cloudhelp/2015/JPN/Maya-Tech-Docs/CommandsPython/button.html#flagdragCallback この中のキー モディファイアで 0 == モディファイアなし、1 == SHIFT、2 == CTL、3 == CTL + SHIFT を識別できるところを使わせて頂きました。 なお、使わなくてもdropCallback も設定し、選択マニュピレーターが中ボタン操作後に直ぐには動かなくなるという挙動を防いでいます。 この部分を設定した、移動Xボタンの設定は、
コマンド部分は ボタンの色換えも含めて、
以上です。 |
Version 10(改7);ミラー 機能対応 ミラー機能が追加されました。 Mayaデフォルトの機能には不具合があるようですので、それを補う意味でも有用で便利な機能となりました。 ■Mirror ボタン;選択したキーの範囲で ・左マウスボタン;横(時間軸)のミラーになります。 ・中マウスボタン;縦(値の正負)のミラーになります。 Python 解説 さて、ミラー機能を実現してくれるコマンドはscaleKeyです。 ■scaleKeyhttp://help.autodesk.com/cloudhelp/2015/JPN/Maya-Tech-Docs/CommandsPython/scaleKey.html まず、横軸、つまり時間軸のミラーには、そのキーの最初と最後のキー値を変更範囲とします。 選択されたカーブから最初のキー値と最後のキー値を取得します。
そしたら、その最初のキー値と最後のキー値を、newStartTime,newStartFloat,newEndTime,newEndFloatに入れてあげます。
実は、これで終わりだったのですが、ボタンを連続してクリックすると、なにやら不穏な動きをするのです。 そこで、とっても回避策なのですが、doBufferのsnapshotとswapを入れてみることにしてみました。
縦軸、つまり値の正負のミラーは、scaleKeyのvalueScaleに-1 を使えばよいようです。
以上です。 |
Version 10(改9);SelectFromCurve 機能の改良 複数のオブジェクトを選択して表示している時の機能の改善を試みました。 幾つか案を頂き、今出来る範囲の事と照らし合わせて実装してみた機能になります。 ■SelectFromCurveボタン; 複数のオブジェクトを選択表示した状態で、カーブを1つ選択し ・左マウスボタン; > そのアニメーションの付いたオブジェクトが一番上に表示されます。 一番上に表示される事で、移動/回転/スケールのXYZと表示/非表示のボタンで操作が出来るようになります。 ■SelectFromCurveボタン; 複数のオブジェクトを選択表示した状態で、カーブを複数選択し ・中マウスボタン; > そのアニメーションの付いたオブジェクトのみが表示されるようになります。 Python 解説 さて、選択しているアニメーションカーブから オブジェクトを特定するコマンドはlistConnectionsです。 ■listConnectionshttp://help.autodesk.com/cloudhelp/2015/JPN/Maya-Tech-Docs/CommandsPython/listConnections.html 選択しているアニメーションカーブからそのアトリビュートやオブジェクトの情報を得るには、 最初 attributeInfoなどアトリビュートと付くコマンド名なのかと思っていて調べていたのですが、全く良い結果を得られませんでした。 更に、今回、とても悩まされたのは、アニメーションカーブを選択して得られるカーブの名前からは、 オブジェクトの名前を得てはいけないケースが多々あることに気が付いた点です。 (例えば、ClipをマージしてActive化したカーブ名にはアトリビュートに関係する文字は一切ありません。) また厄介だったのは、そのオブジェクトにはネームスペースが付いていたり、キャラクターセット名が付いていたりする場合があり、 通常のオブジェクト名のものと合わせて、幾つかのケースがありそうです。 と、意外な謎解きゲームに突入してしまったのです。 そこに救世主のように探し当てたのが、listConnections コマンドだったのです。 まずは、pCone1 に通常のアニメーションを付け Clip化した後マージを実行しActive化すると、どんなアニメーションカーブ名になるかをご覧ください。 出来たカーブを選択して、そのログをスクリプトエディタで見ます。 すると、animCurveTA4となっていて、pCone1 でも rotateZ でも無いので、選択したカーブ名からオブジェクト名を推測する方法では駄目だと解ります。 また、オブジェクトに設定される名前に関する情報ではどのようなパターンがあるか考えてみますと、以下をご覧ください。 すると、通常のオブジェク名、ネームスペース名、キャラクターセット名、の組み合わせがありそうです。 では早速、listConnectionsを使って情報を引き出してみましょう。 ネームスペースが NewNamespace1 で、 D01 というキャラクターセットの付いた pPipe1 の移動Xのカーブを選択した状態から始めます。 まずは、カーブ名を取得します。
この情報にlistConnections に、plugs=Trueというフラグを立ててみると、
となり、キャラクターセット名まで取得出来ることがわかります。 そこで、同じlistConnections に、type='transform'というタイプ指定で入力すると、
となり、ネームスペースまでのオブジェクト名 がめでたく取得できました。<これが解決のポイントでした。 > ところが、逆にネームスペースもキャラクターセットも無い 普通のオブジェクト、 例えば、pCube1 のpCube1_translateXカーブを選択して上記を実行するとエラーになります。 それは、それらの情報が無いからですよね。 そこで、うまいことにselected_connectで取得した値をnodeTypeに渡すとcharacterと返って来るのが解ったので、 'character'で条件分岐を作成すると、全てのパターンでうまくオブジェクトの名前を取得出来ることになります。
で、ツールの仕上げとしては、複数のオブジェクトが最初選択しているところから始まるので、 一旦全部のオブジェクト名をリストにたくわえ、その中から、今カーブで取得したオブジェクト名を削除して、 一番最初にカーブから取得したオブジェクト名で選択し直して、残りを更新したリストから add フラグで選択し直すことをすれば、 一番上に選択したカーブから得たオブジェクトが来る としました。
中ボタンの方が簡単で、選択したものだけを残せばOKです。 以上です。 |
Version 20(改4);Panel対処とWindow化 突然バージョンがまた一桁上がりました。 作成されるパネルをWindow内にちゃんと管理して配置し、併せて使われなくなったパネルを削除して、 パネルが増殖し続けるのを防ぐ対応をした為です。 外枠に表示される ラベル名 も、New CustomGraphEditor* となりました。(また、Maya2016で作業を開始しました) さて、ものすごく進歩したにも関わらず、機能的に新しく解説できるものは、何もありません。 使う方としては、勝手にドンドンパネルが蓄積していくようなことは無くなり安心して使えるようになった、ということになります。 Python 解説 では、こちらの Pythonについての解説はというと、沢山の変更があります。 まずは、数枚グラフエディタ を作成(ティアオフのコピー)した場合、そのリストを取得するは、
となります。 最初のgraphEditor1はデフォルトのパネル名なので、このリストから外しておきます。
そして表示していたグラフエディタ を全て閉じた後、パネル > パネルを見ると、グラフエディタ2,3,4が残っているのが確認出来ます。 ここで、表示していない全パネルリスト を以下のように取得します。
後は、表示してないパネルのリストから、グラフエディタ があったらそのパネルを削除する、ってスクリプトを書けばOKです。 で、パネルを消すコマンドは・・ 、deleteUI です。 ■deleteUIhttp://help.autodesk.com/cloudhelp/2016/JPN/Maya-Tech-Docs/CommandsPython/deleteUI.html panel (pnl) 削除するオブジェクト名をパネルに限定します。 と書かれています。 つまり、
print した結果を見ると、graphEditor1だけが残っています。 このスクリプトをグラフエディタ が起動する前部分に追記しました。 さて、もう1つの進歩として、グラフエディタというスクリプトパネルをちゃんとWindowコマンドの中に入れて表示する、というところです。 そうすることによってWindowコマンドで表示している内容を制御できるようになります。 記述のポイントは parent= で、設定するモノの親を決めているところです。 つまり、windowをwin1として設定し、次にpane1という縦に2つに分化した paneLayout の親を win1 にし、 scriptedPanelの親はpane1 という風に設定します。
ここでは graphEditor2 というパネル名で表示したので、 閉じた後に再度実行すると、# エラー: line 1: オブジェクト名 'graphEditor2' が固有ではありません。とエラーになります。 そう'graphEditor2' というパネルが残っているからです。 あとは、window の名前の重複にならない設定とか、 パネルの番号を各ボタンにも使って複数のグラフエディタが表示された時にボタン名がユニークになるようにしたりとか・・ と、かなりの変更がありました。興味がある方は スクリプトの中身を見てみてください。 以上です。 |
Version 30 ;Outliner対処 (GTMF2015ネタ) 突然バージョンがまた一桁上がりました。 GTMF2015にて発表したOutlinerが横に表示されるバージョンです。 アニメーションの付いているノード選択をどうにか改善したいと思って設置したものになります。 操作については何も説明は要りませんね。 階層構造内で選択したものがグラフエディタ内にアニメーションカーブ表示します。 このOutliner付きカスタムグラフエディタも複数表示に対応しています。 Python 解説 Pythonについての解説は、paneLayout コマンド のフラグを vertical2 にして、 アウトライナーのパネルを表示した後、グラフエディタを表示するという風にします。
これを実行すると、下図のようになります。 後は、グラフエディタをカスタマイズし、パネルの増殖制御部分を追加して完成としました。 起動コマンドは別名にしてありますので、Outliner 無しバージョンとの併用が可能です。
以上です。 |
CustomGraphEditor.py と既知の制限・注釈 という訳で現在のところまでのカスタム・グラフエディタ のファイルを公開します。 (Pyファイルは シェルフにボタン登録するか、プルダウンメニューに登録して実行します。) あくまでも自己責任でお使いください。use as your own risk.
|
という訳で、次回は Mayaのワークグループ設定についてです。 乞う、ご期待!!
|