![]() |
構想 目標は;『選択した階層下の全てのJointサイズを変更する GUI を持ったツール』ということで 実際 Maya 上のオブジェクトに動作をする部分とGUIの制御部分に分けて考えます。 前半部分では、こんな風に考えて組み立てましょう。
と書き出すだけでなんとなく構造が見えて来ます。 次に後半のGUIの方も組み立てるものを列挙すると
とすると、かなり具体的に何のコマンドとどういうオプション設定にすれば良いか浮かんで来ます。 ここで覚えておくと良いノウハウ、良くミスをする点、としては、
と、使う側の事まで考えて組み立てられていたらバッチリです。 そんな構想て、実際に Maya で操作実験しながら前半部分から組み立てていきます。 |
jointのサイズ設定と選別処理 まずは Joint のサイズはどこでコマンドは何かをログから見ると、こんな感じです。 ![]() setAttr の Python コマンドで見てみますと、Melと同じですね。 ■ setAttr(Python)http://help.autodesk.com/cloudhelp/2015/JPN/Maya-Tech-Docs/CommandsPython/setAttr.html
で、 joint1 がちっさくなるはずです。 そしたら、今度は選択したトップから下の階層選択するのは 編集>階層の選択 なので、またログから見て cmds.select(hierarchy=True) と解ります。 ■ select(Python)http://help.autodesk.com/cloudhelp/2015/JPN/Maya-Tech-Docs/CommandsPython/select.html 階層選択したものをリストとして取得します。その時使用するのが cmds.ls(sl=True) です。これは色々なケースで良く使用するコマンドです。良く見ると、条件を絞ったリストを返すことも出来ますね。 ■ ls(Python)http://help.autodesk.com/cloudhelp/2015/JPN/Maya-Tech-Docs/CommandsPython/ls.html
![]() このリストにある joint を順番に設定したいサイズ値に設定すればOKですよね。 リストの中を繰り返すには、for in 文が便利です。 ■ for(Python)http://docs.python.jp/2/tutorial/controlflow.html#for
はい、だいたい出来ました。エラーや条件分岐で色々なケース回避をしましょう。 まずは、リストの中に joint じゃないものが混じっていた場合に備えます。 それは、 for in 文内に if 文で選別しましょう。 Python の if 文はとても楽で、カッコでくくることもなく、終わり行に何か書く必要もない、とってもスマートな書き方です。 何々なら、どうって書くだけです。 ■ if(Python)http://docs.python.jp/2/tutorial/controlflow.html#if 何々なら、ってところは、ここでは joint ならになるので、 for in 文内で順番に拾って来たオブジェクトの種類を調べるのは objectType を使います。 ■ objectType(Python)http://help.autodesk.com/cloudhelp/2015/JPN/Maya-Tech-Docs/CommandsPython/objectType.html
ちなみに、他のオブジェクトに実行すると、どんな objectType が返って来るのかと実行してみると... ![]() つまり、 joint だけが 'joint' を返し、あとは'transform' ってなってます。 もし、予想した答えがナーブスの球の場合、nurbsSurfaceだったとしたら、それはシェープノードの事になります。 下図の例をご覧ください。 ![]() ここでは Maya で最初に認識しておくべきことなのですが、 ナーブスの球を作成すると必ずオブジェクト名リストとして、トランスフォームノードとシェイプノードが返されます。 print cmds.sphere() ナーブスの球を作成する文をプリントアウトすると2つ返って来ることが見て取れます。 その状態を、ハイパーグラフ接続ウィンドやノードエディタウィンドで見ると、どういう状態なのかモット良く解るかと思います。 つまり、''nurbsSphere1'のobjectTypeはトランスフォームノードだった、ということになります。 ![]() さて、回り道しましたが、リストから拾って来たものが joint なら、半径を 0.25 にします、というスクリプトです。
もう少し気遣いをしましょう。 もし、何も選択してなくて実行したら・・・のエラーを回避しましょう。 これには、もう上で使った ls を使い、[リストが空じゃない=True じゃ無かったら]、つまり空ならという書き方になります。
後は後半に作るGUIから来る値が 0.25 の所に入って来るようにする記述を最後に書き込みます。 追加の後処理として、このツールを実行した時の最初の状態に戻す、 つまり 階層のトップのオブジェクトを選択した状態に復帰する というような処理をしてあげるとフレンドリーかと思います。 そこまで書いて一旦前半を終わります。
|
PythonでGUIを作る ここからは表示されるウィンドメニューの作成になります。
■ textFieldButtonGrp (Python)http://help.autodesk.com/cloudhelp/2015/JPN/Maya-Tech-Docs/CommandsPython/textFieldButtonGrp.htmlある程度までは何となく作れるのですが、肝心なところで思惑道理にならないなど 細かいところの参考になるかと思います。 ウィンドーを作って表示する、ってのはドキュメントの例に良く載っています。 window のタイトル、テキストと値が書き込める欄、ボタンがセットになった textFieldButtonGrp と window を閉じるのに使う 1つのボタン button を用意してみます。 ■ button (Python)http://help.autodesk.com/cloudhelp/2015/JPN/Maya-Tech-Docs/CommandsPython/button.html
textFieldButtonGrp には、きちんとその固有の名前 'Set_JointSize_Button' を記述しておきます、重要です。 さて、この window にはオブジェクトとしての名前で指定して管理していないので、 このスクリプトを何回も押すと次々と window を作成していってしまいます。 ![]() 同じ名前のウィンドは1枚しか絶対に表示しない、って風にしていきたいのですが、
今度は名前を付けると1枚目は良くても、2枚目の時エラーとなります。(まー、2枚目は表示しなくなりますが...)
![]() エラーの内容は最初に作成した window と同じ名前の window を作成しようとした為既にあるのでエラーになっているだけです。
■ window (Python)http://help.autodesk.com/cloudhelp/2015/JPN/Maya-Tech-Docs/CommandsPython/window.htmlつまり設定している名前で認識はしてくれている、ということになります。 このことから、既に同じ名前の window があったら閉じて、同じ名前の新しいwindow を表示する、という風に解決します。 window のコマンドは作成するだけじゃなく、存在するかもオプションで判別させることが出来ます。 また、既存 window を閉じるのは deleteUI を使用します。 ■ deleteUI (Python)http://help.autodesk.com/cloudhelp/2015/JPN/Maya-Tech-Docs/CommandsPython/deleteUI.html
これでもうエラーも無く、1枚しか表示しません。 そして、閉じるボタンに設定するコマンドも解ったことになります。
少し追加の情報も書きます。 この window を閉じるっていう設定というのは思いの外重要で、window 内に別の形で用意できることを知っておくといいかも知れません。 その1つにメニューバーを紹介します。 window コマンド内に追加のオプションとして、 menuBar=True を追加し、 メニューに例えば File というラベルを設定し、その中に exit という項目を作り、そこに閉じるコマンドを設定します。
![]() 大きなメニュー画面の時に使えそうな方法で、メニューやタブも作れることが分ります。
さて続きです。
■ columnLayout (Python) http://help.autodesk.com/cloudhelp/2015/JPN/Maya-Tech-Docs/CommandsPython/columnLayout.htmltextFieldButtonGrp と button の2つの表示物が今は縦に並んでいます。 縦並びに設定しているのは columnLayout で、もう1つ横並びにする rowLayout を追記し、横に並べます。 ■ rowLayout (Python) http://help.autodesk.com/cloudhelp/2015/JPN/Maya-Tech-Docs/CommandsPython/rowLayout.html
rowLayout の numberOfColumns というオプションにきちんと個数を入れないとエラーになります。ここでは2個。 ![]() 整って来たところで、どうも textFieldButtonGrp の3つの要素のうち、 最初のテキストの左側、値を記入する欄の大きさがイマイチなので値を設定して好みに合わせます。 columnWidth3 というオプションを使用します。
かなりいい感じになってきましたが、実はこの winodw 端っこがつまめて、 びよ~んと伸びてしまいます。しかも次に表示した時は伸ばした状態で表示されます。 ![]()
window コマンド内に追加のオプションとして、 sizeable=False でサイズを固定、topLeftCorner=[200, 200] で最初に表示した時の位置、
widthHeight=(250, 30) でサイズを設定します。 ![]() 以上で表示系は完成しました。
残りの作業は、 textFieldButtonGrp のボタンを押したら上部のスクリプトが動くようにコマンドを埋め込みます。 前半部分の 関数の飛び先 def set_joint_size(*args): ともう書いてあります。 そこに行くように buttonCommand=set_joint_size というオプションを追加します。
後半部分はこれで本当に終了です。
ただし、問題が残ってます。 この textFieldButtonGrp の値を記入する欄はテキスト=文字列です。 joint のサイズを記入するところは数値であり、尚且つ小数点を扱う float型にしなくてはなりません。 このことを踏まえつつ、最後の仕上げといきましょう。 |
完成へ さて、上記で書いた、取得して来た値の型がなんの タイプか調べるのには type を使用します。 ここは一旦出来上がった前半部分を少し崩して、textFieldButtonGrp の値を記入する欄の取得の仕方と合わせて タイプを確認したいと思います。 実はもう一度 textFieldButtonGrp のコマンドを設定した固有名と共にquery=True, text=Trueというオプションを書けば取得出来ます。 cmds.textFieldButtonGrp('Set_JointSize_Button',query=True, text=True) となります。 この値のタイプをプリントしてみます。 ■ type(Python)http://docs.python.jp/2/library/types.html
結果はもちろん
ですよね。ここで面白い書き方としてこうしてしまいます。
ちょっと強引ですかね。結果は
となって、joint の大きさを扱えるデータになりました。 が、またまた意地悪出来ますとね。そうテキスト欄だから数字じやないもの記入出来てしまいます。 それを float型にしようとしたらエラーで出るに決まってます。 ![]() 値を取得するところを try とし、エラーが出たら except で数値を入れてくれよとプリントしてみます。 ■ try except(Python)http://docs.python.jp/2/tutorial/errors.html?highlight=try%20except#tut-handling
これでエラーを回避してみました。 これを途中まで作っていた前半部分と、GUIを組み合わせて .py ファイルを完成させます。 |
ri_set_joint_size.py
ちっさい GUIに、ちょっとしたツールでも、Python学ぶにはもってこいの内容でした。 完成した .py はシェルフに登録 する場合はユーザーディレクトリーにコピーして、 例 C:\Users\ユーザー名\Documents\maya\2015-x64\ja_JP\prefs\scripts (MAYA_APP_DIR がある場合はそちら) 以下のコマンドで立ち上げます。OKなら、これをシェルフに登録します。
プルダウンのメニューに登録する方法もあります。 参照 > Maya; Python で カスタム・グラフエディタ を作ろう!!https://www.itec.daikin.co.jp/DC/UsersNotes/Ritaro/tutorial/maya_02/#Shelf
|
という訳で、次回 は ... What's Next ... 乞う、ご期待!! Stay tuned ..
|