CG・コンテンツ制作
  1. CG・コンテンツ制作トップ
  2. DAIKIN CG Channel
  3. UsersNotes
  4. スクリプト
  5. Maya;Python でカスタム・ハイパーグラフを作ろう!! Version 4
SUITE USERS NOTES
Maya; Python で カスタム・ハイパーグラフ を作ろう!!!
Version 4
(Maya 2014、2015、2016
Maya; Let's Make a Custom HyperGraph with Python Version 4
プロローグ;Prologue
CustomHyperGraph_V4_00s
引き続き、Pythonについてのページになります。

カスタム・グラフエディタと同じ方法で ハイパーグラフ カスタマイズが可能だったので
便利と思われる機能を追加して公開してみます。

便利になるかな~と思った機能としては・・・
階層選択、選択以下の階層展開、
選択したものを2番目に選択したものの位置/回転/縮尺を一致するツール、
各種コンストレイントの実行、コネクトエディタとエクスプレッションエディタの表示、
色設定ツールです。名前の置換とネームスペースエディタを追加してます。

更新 Version 2
表示設定をするGUIとその設定を保存する仕組みを追加しました。

更新 Version 3
未使用パネルの削除対応とWindow化
パネルがドンドンと溜まるのを防ぐ対応等々
更新 Version 4(Maya2014以上)
接続表示のオプション機能に対応

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

Only Japanese , at the moment. If you want this page to be in English please Tweet or Mail me hard ^ _^ ;;
Windows7 Professional 64Bit、Intel Core i7-3930K(3.20GHz,6コア/12スレッ)
メモリ16GB、NVIDIA GeForce GTX560 Ti 2GB(メモリ2GB)

ritaro_ml



パネルについての注意 >> この問題は Version 3で解消されました。
Maya パネルについては、全ページを参照してください。
Maya;Python でカスタム・グラフエディタを作ろう!!



HyperGraph について ; Python
カスタム・グラフエディタからの引き続きなのでお分かりの通り、Maya HyperGraphも、scripted panelである、ということです。

scriptedPanelhttp://help.autodesk.com/cloudhelp/2015/JPN/Maya-Tech-Docs/CommandsPython/scriptedPanel.html

従って、何枚かHyperGraphをティアオフコピーした後に、
何枚HyperGraphのスクリプト・パネルが存在しているかを調べるには

import maya.cmds as cmds
import maya.mel as mel

cmds.getPanel( scriptType='hyperGraphPanel' )

# 結果: [u'hyperGraphPanel1', u'hyperGraphPanel2', u'hyperGraphPanel3'] # 

となります。
GraphEditorの時と同じで、次に作るハイパーグラフの番号を計算して、その番号で HyperGraph を作成している部分が以下の通りです。
複数のカスタム・ハイパーグラフを表示しても動作するように、ユニークな名前をこの番号で作ります。

hyper_panel_no_a = str( len(cmds.getPanel( scriptType='hyperGraphPanel' )) + 1 )
hyper_panel_name = "hyperGraphPanel" + hyper_panel_no_a
mel.eval('string $hyper_panel_name = "%s"' % hyper_panel_name)
mel.eval('tearOffPanel $hyper_panel_name "hyperGraphPanel" true;')

例の如く、GUI系のコマンドはMELしかないものが多く、mel.evalを使っているところがあります。
Pythonから$hyper_panel_nameに値を引き渡し、tearOffPanelコマンドに使っています。

その下の部分は、作成されるHyperGraphの設定を、やはりmel.evalを使って行っています。

cmds.paneLayout( width=800)
mel.eval('string $hie[] = `getPanel -sty "hyperGraphPanel"`;')
mel.eval('string $schem = $hie[size($hie)-1] + "HyperGraphEd";')
mel.eval('checkOrientCollection schematic $schem;')
mel.eval('checkFreeformCollection On $schem;')
mel.eval('hyperGraph -edit -showConstraints on $schem;')
mel.eval('hyperGraph -edit -showExpressions on $schem;')
mel.eval('hyperGraph -edit -useDrawOverrideColor on $schem;')

例えば、HyperGraph 表示内の
オプション > 向き > スケマティックに設定していたり、
オプション > レイアウト > フリーフォームレイアウトに設定していたり、
オプション > ディスプレイ > [レ] コンストレイント接続にチェックを入れたり、
オプション > ディスプレイ > [レ] エクスプレッション接続にチェックを入れたり、
オプション > [レ]ノード表示のオーバーライドカラーにチェックを入れたりしています。

特に、最後のオーバーライド表示を有効にしないと、色表示してくれません。
好みに応じて設定を変更してみてください。



UnfoldHierarchy = 階層構造の展開;Python
HyperGraph画面内にも、編集 > すべて展開という機能はあるのですが、
それは選択したもの以下の階層構造を"展開"してくれるツールです。(以下画像参照↓)

maya06_02

キャラクター製作など階層構造が広い場合、選択しているものの構造が展開する構造の一番上とは限りません。
例えば、小指の先のノードを選択してその構造を見たい時、
そのはるか上の構造から"折り畳み"されていたらどうでしょう。(以下画像参照↓)

maya06_03

[UnfoldHierarchy] ボタンで用意した機能は、この一番下の構造体が選択されている場合でも"展開"するツールです。


さて、スクリプトの解説です。
それを実現するには、すごく特徴的なMelコマンドを利用します。

rootOfhttp://help.autodesk.com/cloudhelp/2015/JPN/Maya-Tech-Docs/Commands/rootOf.htm

一番下のものが選択されていたとして、その親にたどり着くまでループ処理をするのではなく(処理負担だったかかるし)
rootOf( $o_selected );とするだけでOKです。
一番上を見つけたら、展開とするので、階層構造全部を展開します。
ただし、ここで億劫なのは、展開を実行するパイパーグラフの名前(パネル名)を取得しなければならないところでしょうかね。

def unfold_hierarchy_from_obj(*args):
    if not cmds.ls( sl=True ):
        print 'Nothing is selected'
    else:
        o_selected = cmds.ls(sl=True)[0]
        hyper_panel_name = str( cmds.getPanel( withFocus=True))
        mel.eval('string $o_selected = "%s"' % o_selected)
        robj = mel.eval('string $robj = `rootOf( $o_selected )`;' )
        cmds.select(robj,r=True)
        cmds.hyperGraph( hyper_panel_name + 'HyperGraphEd',edit=True,fold=False,unfoldAllShapes=True)
        cmds.select(o_selected,r=True)


追加情報として、何も選択していない状態で、シーンのルートを全部選択出来る方法(コマンド)があります。

selectMode http://help.autodesk.com/cloudhelp/2015/JPN/Maya-Tech-Docs/CommandsPython/selectMode.html

このコマンドで、選択モードというものがあり、rootとするとMayaシーン上の一番上のものを全て選択可能な状態にしてくれます。
そこで・・・

cmds.selectMode(root=True)
cmds.select( all=True )

と実行すると、一番上のもの全部を選択するので、そこから編集 > 全てを展開を実行すれば、シーン全部の階層構造を展開します。



SetSameSRT = 位置/回転/スケールの一致;Python
さて、お次は位置/回転/スケールを一致させてくれるツールを作りました。
これは、Softimageにある、(位置/回転/スケールの一致)させるツールに似せた動きになればいいなという発想です。
スクリプトとしては何てことない、目標物のグローバル値を取得して、動かしたいものにそのグローバル値を設定すれば良いのです。

Mayaには修正 > オブジェクトのスナップ位置合わせ > ブジェクトの位置合わせがあるのですが、
何故か Joint に効かない・・みたいでした。
[SetSameSRT]は、Locator、Joint、Group,CameraなんでもTranslate値 が取得/設定出来る限り動きます。
maya06_04
[上図解説;位置を合わせたいものは黄色のLocatorや水色のJointで、
目標地点は、同じルート上の紫色のLocatorや階層途中の肌色のJointだったりします。
オブジェクトの位置合わせではこの場合Locator同士しかうまく動作しないみたいでした(Maya2015SP5
[SetSameSRT]ではどれでも、しかも回転/スケールにも対応します。
(注意;JointのScale値は設定されていても単独だと見た目が変わりません~)]


さて、スクリプトの解説です。
それを実現するには、おなじみのxformを利用します。

xformhttp://help.autodesk.com/cloudhelp/2015/JPN/Maya-Tech-Docs/CommandsPython/xform.html

xformのオプションにはworldSpaceというフラグがあり、グローバル値で移動/回転/スケール値を扱います。
取得も設定もこれ1つで出来、しかも3軸いっぺんに設定出来るので大変便利です。
移動値設定の時は、2つのノードを選択した状態で、


a_sel = cmds.ls( selection=True )[1]
a_sel_w = cmds.xform(a_sel, worldSpace=True,q=True,translation=True)
b_sel = cmds.ls( selection=True )[0]
cmds.xform(b_sel, translation=a_sel_w,worldSpace=True,absolute=True )

となります。
回転値はrotation=True、スケール値はscale=Trueです。


移動/回転/スケール値を設定するコマンドは、実は他にもあります。

movehttp://help.autodesk.com/cloudhelp/2015/JPN/Maya-Tech-Docs/CommandsPython/move.html
rotatehttp://help.autodesk.com/cloudhelp/2015/JPN/Maya-Tech-Docs/CommandsPython/rotate.html
scalehttp://help.autodesk.com/cloudhelp/2015/JPN/Maya-Tech-Docs/CommandsPython/scale.html

move を使って移動値を設定する場合はこのようになります。

a_sel = cmds.ls( selection=True )[1]
a_sel_w_x = cmds.xform(a_sel, worldSpace=True,q=True,translation=True)[0]
a_sel_w_y = cmds.xform(a_sel, worldSpace=True,q=True,translation=True)[1]
a_sel_w_z = cmds.xform(a_sel, worldSpace=True,q=True,translation=True)[2]
b_sel = cmds.ls( selection=True )[0]
cmds.move(a_sel_w_x, a_sel_w_y, a_sel_w_z,b_sel, worldSpace=True,absolute=True )

X,Y,Z軸用に個別に取得してから、moveで値を設定します、この時のオプションもworldSpaceを使います。
これでも良かったのですが、scaleworldSpace の設定が無い?みたい
で正確な値が設定出来ない場合があるので、xform 一択になりました。

あとは、GUIのメニューの方ですが、プルダウン式の選択になっています。
これの作成はoptionMenuというコマンドを使います。

optionMenuhttp://help.autodesk.com/cloudhelp/2015/JPN/Maya-Tech-Docs/CommandsPython/optionMenu.html

最初の2行は、作成されるHyperGraphのパネル名を取得しているだけです。
そのパネル名をoptionMenu名に追加することで、ユニークな名前にしています。
menuItemプルダウンのメニューに追加したい名前を列挙します。

hyper_panel_no_a = str( len(cmds.getPanel( scriptType='hyperGraphPanel' )) + 1 )
hyper_panel_name = "hyperGraphPanel" + hyper_panel_no_a

cmds.optionMenu(hyper_panel_name + 'set_srt', label='  SetSameSRT>', changeCommand=setsame_srt )
cmds.menuItem( label='Potition' )
cmds.menuItem( label='Rotation' )
cmds.menuItem( label='Scale' )

それを受けて、グローバル値を取得/設定する方法は、以下の通りです。

def setsame_srt( o_same_srt ):
    if o_same_srt == 'Potition':
        try:
            a_sel = cmds.ls( selection=True )[1]
            a_sel_w = cmds.xform(a_sel, worldSpace=True,q=True,translation=True)
            b_sel = cmds.ls( selection=True )[0]
            cmds.xform(b_sel, translation=a_sel_w,worldSpace=True,absolute=True )
        except:
            print "Select 2 node, to Move and to Where"
    if o_same_srt == 'Rotation':
        try:
            a_sel = cmds.ls( selection=True )[1]
            a_sel_w = cmds.xform(a_sel, worldSpace=True,q=True,rotation=True)
            b_sel = cmds.ls( selection=True )[0]
            cmds.xform(b_sel, rotation=a_sel_w,worldSpace=True,absolute=True )
        except:
            print "Select 2 node, to Rotate and to Which"
    if o_same_srt == 'Scale':
        try:
            a_sel = cmds.ls( selection=True )[1]
            a_sel_w = cmds.xform(a_sel, worldSpace=True,q=True,scale=True)
            b_sel = cmds.ls( selection=True )[0]
            cmds.xform(b_sel, scale=a_sel_w,worldSpace=True,absolute=True )
        except:
            print "Select 2 node, to Scale and to Which"

try文は以前に説明した通り、ノードを2つちゃんと選択しなかった場合のエラーを
except文で用意したPrint文を出力にして、エラーを回避しています。



ConstraintOp = 全種のコンストレイント;Python
さて、お次はMayaのメインメニューのコンストレイント項目の機能(オプション画面)を起動しているだけです。
階層構造が見えているハイパーグラフ画面でコンストレイントを設定出来た方が解り易いと思ったからです。
プルダウン式の選択は上記optionMenuを使い、実行側はif文で分岐を沢山作っただけです。

def const_types( o_const_types ):
    if o_const_types == 'Point':
        mel.eval('PointConstraintOptions;')
    elif o_const_types == 'Aim':
        mel.eval('AimConstraintOptions;')
    elif o_const_types == 'Orient':
        mel.eval('OrientConstraintOptions;')
    elif o_const_types == 'Scale':
        mel.eval('ScaleConstraintOptions;')
    elif o_const_types == 'Parent':
        mel.eval('ParentConstraintOptions;')
    elif o_const_types == 'Geometry':
        mel.eval('GeometryConstraintOptions;')
    elif o_const_types == 'Normal':
        mel.eval('NormalConstraintOptions;')
    elif o_const_types == 'PointOnPoly':
        mel.eval('PointOnPolyConstraintOptions;')
    elif o_const_types == 'ClosestPoint':
        mel.eval('ClosestPointOnOptions;')
    elif o_const_types == 'PoleVector':
        mel.eval('PoleVectorConstraintOptions;')
    elif o_const_types == 'RemoveConstraint':
        mel.eval('RemoveConstraintTargetOptions;')
    elif o_const_types == 'SetRestPosition':
        mel.eval('setConstraintRestPosition;')
    elif o_const_types == 'ModifyAxis':
        mel.eval('ModifyConstraintAxisOptions;')

MayaはGUIにからむコマンドはMelになりますので、mel.evalを使って実行しています。



カラーのスクロールバーと色設定;Python
次に用意したのが、ワイヤーカラーの設定ツールです。
カラーの表示とスライダーが設定出来るコマンドが用意されていて、便利に使えそうです・・一見・・・ね。(どハマリする事うけあいです!)

colorIndexSliderGrphttp://help.autodesk.com/cloudhelp/2015/JPN/Maya-Tech-Docs/CommandsPython/colorIndexSliderGrp.html

Mayaの標準機能と比較して見てみましょう。
maya06_05
選択しているものが Locator だった場合、ワイヤーカラーはトランスフォームアトリビュート > ディスプレイ > 描画オーバーライド項目で、
[レ]オーバーライド有効化オンにして、下のカラー色付きスライダーで設定します。
このスライダーは、調べると 32色のインデックスカラーだと解ります。
32階調ってことは1から始まって32で終わるcolorIndexSliderGrpを作ればOKです、なーんだ簡単と。

cmds.window()
cmds.columnLayout()
cmds.colorIndexSliderGrp( label='Select Color', min=1, max=32, value=1)
cmds.showWindow()

作成された window の色スライダーを動かすと色が変わり右端まで行くと赤紫色まで行って、
Mayaの標準の描画オーバーライドにある色スライダーと同じ色になります。やった~っと。

では、この値を、選択した例えばLocatorオーバーライドをオンに設定して、色を設定してみます。
スライダーの値の取得方法も一般的なq=True を使うとします。

def color_index(*args):
    value = cmds.colorIndexSliderGrp('SelectColors',q=True,value=True)
    o_selected = (cmds.ls(selection = True,objectsOnly=True )[0]).encode('utf-8')
    cmds.setAttr(o_selected + ".overrideEnabled", 1)
    cmds.setAttr(o_selected + ".overrideColor", value) 

cmds.window()
cmds.columnLayout()
cmds.colorIndexSliderGrp('SelectColors', label='Select Color', min=1, max=32, value=1,dragCommand=color_index)
cmds.showWindow()

Locatorを選択して実行します。するとおお、良さげ・・・、人間のサガらしく、スライダーだと左右に動かしたくなりますね。
右端まで行って左に戻した瞬間、なにやらエラーが出ます。
# エラー: RuntimeError: file <maya console> line 5: setAttr: アトリビュート 'locator4.overrideColor' は最大値 31 より大きく設定できません。 #
maya06_06
そしてそれ以降は、表示している色と Locator の色は 違っていきます。
これ、数値をPrintすると解るのですが、どうやら colorIndexSliderGrp のスライダーは
右端に行って左に動かした瞬間、次の数値が折り返した最後の値に1を追加するみたいなんです。
つまり右端だった場合Max値を超えてエラーが出るようです。
かと言って、31までのスライダー範囲にしたら、それは window 上に表示している色がずれてしまいます。
q=True を使って値を取り出す方法も数値が合わないような気もします。~つみます。

そこで、考えたのは、colorIndexSliderGrp の色表示部分は使いますが、スライダーは捨てます。
スライダー部分は intSlider を使って 32階調 の数値を作り、lambda関数を使って正確な値を Locator に伝えます。

cmds.colorIndexSliderGrp(hyper_panel_name + 'hyp_color',label='Select Color ',min=0,max=32,value=0,columnWidth3=[77,70,0])
cmds.intSlider(hyper_panel_no_a + 'hyp_color_index', min=0, max=31, value=0, step=1,dragCommand=lambda x:color_index(int(x)) )
cmds.button(label='SetColorToSelected',command=set_color_selected)

colorIndexSliderGrp のオプションでcolumnWidth3=[77,70,0]としているので3番目のスライダー部分は表示されません。
colorIndexSliderGrp では 0 ~ 32 の範囲に設定し、intSlider では0 ~ 31 に設定しています。
色を設定している側はこの通りです。

def color_index(value):
    hyper_panel_name = str( cmds.getPanel( withFocus=True))
    set_color_index = value + 1
    cmds.colorIndexSliderGrp(hyper_panel_name + 'hyp_color', edit=True,value=set_color_index)
    if cmds.ls( sl=True ):
        o_selected = (cmds.ls(selection = True,objectsOnly=True )[0]).encode('utf-8')
        cmds.setAttr(o_selected + ".overrideEnabled", 1)
        cmds.setAttr(o_selected + ".overrideColor", value) 

設定する値はintSlider から来る値に1足し算してcolorIndexSliderGrp に改めて色設定をしています。(色をそろえている)
次の if 文は、選択しているものがあればそれに色を設定します。
何にも選択してない場合は、表示色だけが変わる、という仕組みです。

選択しているもの全てに色を設定するのが[SetColorToSelected]というボタンです。
階層構造の途中のものだけ色を変えたいという事案もあり、
選択した階層構造以下を全部ではなく、選択しているものだけ色が変わる、に変更しました。

def set_color_selected(*args):
    if not cmds.ls( sl=True ):
        print 'Nothing is selected'
    else:
        hyper_panel_name = str( cmds.getPanel( withFocus=True))
        first_selected = cmds.ls(sl=True)[0]
        selected_object = cmds.ls(sl=True)
        set_h_color_index =cmds.colorIndexSliderGrp(hyper_panel_name + 'hyp_color', q=True,value=True) - 1
        for node in selected_object:
            cmds.setAttr(node + ".overrideEnabled", 1)
            cmds.setAttr(node + ".overrideColor", set_h_color_index )
        cmds.select( clear=True )
        cmds.select( first_selected, replace=True )

今度は、あえてcolorIndexSliderGrp の値から色を設定しているのですが、q=True を使って取り出した値から1引いてます。
そうすると表示している色と合います。変?ですかね。いや~。

色設定ツールを作ろうとして colorIndexSliderGrp の不思議にはまった人の参考になればと思います。
ツールを使っている方は、まさか、裏でこんな苦労があるなんて、・・・知りませんよね。普通 ^_^ ;;

余談ですが、カラーのスライダーで最初の色はグレー表示になってますが、あれ、グレー色なんじゃなくデフォルトの色なんですよね。
番号で言うと1番です。で、0番は少し明るいグレー表示になるのですが、設定される色は黒ですかね。余談でした~。
maya06_07



Version 2;表示設定;Python optionVar
使ってくれるユーザーの好みが幅広く、また用途によっても異なるものが、階層構造の表示方法と表示するものの設定でした。
そこで、間単に設定出来て、次回Mayaが起動する時にもその設定で表示するようにしました。
CustomHyperGraph_V2_00s
用意したのは、表示方法を選択出来る画面と設定を保存する仕組み、は、optionVarです。

optionVarhttp://help.autodesk.com/cloudhelp/2015/JPN/Maya-Tech-Docs/CommandsPython/optionVar.html

設定したい項目は6項目とし、6個の文字、例えば上から '112211' という文字で各設定がなされ、
それを optionVar で保存しておく、としました。名前は'chg_setup_var'としました。

cmds.optionVar( stringValue=('chg_setup_var', '112211' ))

最初の起動時は、この値('chg_setup_var')のoptionVarは無いので、無ければ初期値を設定する、って書きます。

if cmds.optionVar( exists='chg_setup_var' ) == False:
    cmds.optionVar( stringValue=('chg_setup_var', '112211' )

次からは、この値('chg_setup_var')のoptionVar はあるので、値を引き出すには q を使います。

cmds.optionVar( q='chg_setup_var' )

例えば、最初の項目の
Hierarchy ◎ Skematic ○ Horizontal ○ Vertical
という部分は

if cmds.optionVar( exists='chg_setup_var' ) == False:
    cmds.optionVar( stringValue=('chg_setup_var', '112211' )

    load_chg_setup_var = cmds.optionVar( q='chg_setup_var' )
    if int(load_chg_setup_var[:1])== '1':
        mel.eval('checkOrientCollection schematic $schem;')
    elif int(load_chg_setup_var[:1])== '2':
        mel.eval('checkOrientCollection horiz $schem;')
    elif int(load_chg_setup_var[:1])== '3':
        mel.eval('checkOrientCollection vert $schem;')

って書けば、6文字の先頭がならスケマティック、なら水平、 なら垂直となります。

Pythonは文字遊びが得意です。インデクシングスライシングはとっても便利、以下例を把握しましょう。

スライス表記: コロンで区切られた二つのインデクスで指定http://docs.python.jp/2/tutorial/introduction.html#tut-strings

var = '112211'
new_var = '2' + var[1:]
print new_var
結果 212211

var = '112211'
new_var = var[:1] + '2' + var[2:]
print new_var
結果 122211


ポップアップする設定GUIの方は、もちろんラジオボタンですが、

radioButtonGrphttp://help.autodesk.com/cloudhelp/2015/JPN/Maya-Tech-Docs/CommandsPython/radioButtonGrp.html

cmds.radioButtonGrp(labelArray3=['Skematic', 'Horizontal', 'Vertical'],numberOfRadioButtons=3,columnWidth3=[70,80,60],
    select=int(exist_chg_setup_var[:1]),
    onCommand1=lambda x:radio_button_hierarchy(1),
    onCommand2=lambda x:radio_button_hierarchy(2),
    onCommand3=lambda x:radio_button_hierarchy(3))

それを受け取るコマンド側は、もちろん optionVarに値を設定するようにします。

def radio_button_hierarchy(value):
    if value == 1:
        old_chg_setup_var = cmds.optionVar( q='chg_setup_var' )
        new_chg_setup_var = '1' + old_chg_setup_var[1:]
        cmds.optionVar( stringValue=('chg_setup_var', new_chg_setup_var ) )
    elif value == 2:
        old_chg_setup_var = cmds.optionVar( q='chg_setup_var' )
        new_chg_setup_var = '2' + old_chg_setup_var[1:]
        cmds.optionVar( stringValue=('chg_setup_var', new_chg_setup_var ) )
    elif value == 3:
        old_chg_setup_var = cmds.optionVar( q='chg_setup_var' )
        new_chg_setup_var = '3' + old_chg_setup_var[1:]
        cmds.optionVar( stringValue=('chg_setup_var', new_chg_setup_var ) )


尚、このoptionVar の値が Maya起動時に有効になるには、デフォルト設定ではあるのですが、
ウィンドウ > 設定/プリファレンス > プリファレンス内の設定 > 保存時のアクション > プリファレンスと設定項目の
[レ]Maya終了時すべてのプレファレンスと設定を保存が有効である必要があります。
maya06_08



Version 3;Panel対処とWindow化
カスタム・グラフエディタのV20でも記述しています通り、こちらも作成されるパネルをWindow内にちゃんと管理して配置し、
併せて使われなくなったパネルを削除して、パネルが増殖し続けるのを防ぐ対応をしました。
枠に表示されるラベル名も、New CustomHyperGraph* となりました。(また、Maya2016で作業を開始しました)
maya06_10
さて、ものすごく進歩したにも関わらず、機能的に新しく解説できるものは、何もありません。
使う方としては、勝手にドンドンパネルが蓄積していくようなことは無くなり安心して使えるようになった、ということになります。



Python 解説

では、こちらの Pythonについての解説はというと、カスタム・グラフエディタの記述とほぼ同じになります。
まずは、数枚ハイパーグラフ を作成(ティアオフのコピー)した場合、そのリストを取得するには、こう書きます。

hyphpanels = cmds.getPanel(scriptType='hyperGraphPanel')
print hyphpanels

// 結果: [u'hyperGraphPanel1', u'hyperGraphPanel2', u'hyperGraphPanel3', u'hyperGraphPanel4']

最初のhyperGraphPanel1はデフォルトのパネル名なので、このリストから外しておきます。

hyphpanels.remove('hyperGraphPanel1')
print hyphpanels

// 結果: [u'hyperGraphPanel2', u'hyperGraphPanel3', u'hyperGraphPanel4']

表示してないパネルのリストから、ハイパーグラフがあったらそのパネルを消します。

invis_panel = cmds.getPanel(invisiblePanels=True)

for o_hyphpanel in hyphpanels:
        if o_hyphpanel in invis_panel:
            cmds.deleteUI(o_hyphpanel,panel=True)


さて、もう1つの進歩として、ハイパーグラフというスクリプトパネルをちゃんとWindowコマンドの中に入れて表示する、というところです。
こちらもカスタム・グラフエディタの記述とほぼ同じになります。

hyper_panel_no_a = str( len(cmds.getPanel( scriptType='hyperGraphPanel' )) + 1 )

win1 = cmds.window('custom_HyperGraph'+ hyper_panel_no_a,
    title='New CustomHyperGraph'+ hyper_panel_no_a,resizeToFitChildren=True, widthHeight=(800, 500))
hyper_panel_name = "hyperGraphPanel" + hyper_panel_no_a

pane1 = cmds.paneLayout(configuration='horizontal2', paneSize=[2,1,1], parent=win1)
hypergraphmenu = 'hyperGraphPanel' + hyper_panel_no_a
cmds.scriptedPanel(hypergraphmenu, label=hypergraphmenu ,type='hyperGraphPanel', parent=pane1)
cmds.setParent('..')



あとは、window の名前の重複とか、
パネルの番号を各ボタンにも使って複数のグラフエディタが表示された時にボタン名がユニークになるようにしたりとか・・
と、かなりの変更がありました。興味がある方は スクリプトの中身を見てみてください。

以上です。



Version 4;接続表示のオプション機能に対応(動作確認Maya2014以上)
Maya 2015 から、Hypergraphの接続表示にオプションが追加されたので、その機能のON/OFFを設定画面から
行えるように工夫しました。
オプション > ディスプレイ > フィルター接続 > ●すべての接続を表示(デフォルト)
○選択項目への/選択項目からの接続を表示
○選択項目への接続を表示
○選択項目からの接続を表示
ただし、メニュー表示は変わったのですが、Maya2014にある機能とは変わりがないので、Maya2014でも動作します。
CustomHyperGraph_V4_01s
左下の[ Setup ] ボタンから表示設定画面が表示され、●NoFilter○to/From ○To○Fromが設定出来ます。
●to/Fromは選択項目への/選択項目からの接続を表示になり、
たくさんのコンストレイントが設定されている場合に水色の接続線が選択されたものだけになり、表示が見やすくなります。

また、今回、横に並ぶボタン数を減らし、縦表示にしてハイパーグラフを使う時に横幅がおさえられるようにしました。



Python 解説

というか機能解説になります。
まず、Maya2015からオプション > ディスプレイ > フィルター接続 > ●すべての接続を表示(デフォルト)
というメニューになって、Maya2014とどう変わったのかを Mel から見てみました。

★ Maya2015の場合 > updateFilterConnFromMenu
// 結果: Mel procedure found in: C:/Program Files/Autodesk/Maya2015/scripts/others/HyperGraphEdMenu.mel //
するとsetFilterSettings( $editor, $name, ($toFrom || $from), ($toFrom || $to));がみてとれますが、
これって、Maya2014で行っている
hyperGraph -edit -showConnectionFromSelected off hyperGraphPanel2HyperGraphEd
hyperGraph -edit -showConnectionToSelected off hyperGraphPanel2HyperGraphEd
の事だって解ったのです。
確かにMelの記載はかわっているのですが、動作としては変わらないのです。
(ちなみにMaya2012ではないオプションコマンドなのでエラーになりました。)
これをPythonで書くと、以下のようになります。

cmds.hyperGraph( 'hyperGraphPanel2HyperGraphEd', edit=True, showConnectionFromSelected=True )
cmds.hyperGraph( 'hyperGraphPanel2HyperGraphEd', edit=True, showConnectionToSelected=True )


ところが、既存の mel.eval から名前を引っ張って来て代入するPython記述に追加するかたちにしたかったので、

mel.eval('string $hie[] = `getPanel -sty "hyperGraphPanel"`;')
mel.eval('string $schem = $hie[size($hie)-1] + "HyperGraphEd";')

    def showconnect(value):
        if value == 1:
            old_chg_setup_var = cmds.optionVar( q='chg_setup_var' )
            new_chg_setup_var = old_chg_setup_var[:6] + '1'
            mel.eval('hyperGraph -edit -showConnectionFromSelected off $schem;')
            mel.eval('hyperGraph -edit -showConnectionToSelected off $schem;')
            cmds.optionVar( stringValue=('chg_setup_var', new_chg_setup_var ) )
        elif value == 2:
            old_chg_setup_var = cmds.optionVar( q='chg_setup_var' )
            new_chg_setup_var = old_chg_setup_var[:6] + '2'
            mel.eval('hyperGraph -edit -showConnectionFromSelected on $schem;')
            mel.eval('hyperGraph -edit -showConnectionToSelected on $schem;')
            cmds.optionVar( stringValue=('chg_setup_var', new_chg_setup_var ) )
        elif value == 3:
            old_chg_setup_var = cmds.optionVar( q='chg_setup_var' )
            new_chg_setup_var = old_chg_setup_var[:6] + '4'
            mel.eval('hyperGraph -edit -showConnectionFromSelected off $schem;')
            mel.eval('hyperGraph -edit -showConnectionToSelected on $schem;')
            cmds.optionVar( stringValue=('chg_setup_var', new_chg_setup_var ) )
        elif value == 4:
            old_chg_setup_var = cmds.optionVar( q='chg_setup_var' )
            new_chg_setup_var = old_chg_setup_var[:6] + '3'
            mel.eval('hyperGraph -edit -showConnectionFromSelected on $schem;')
            mel.eval('hyperGraph -edit -showConnectionToSelected off $schem;')
            cmds.optionVar( stringValue=('chg_setup_var', new_chg_setup_var ) )

として4つの場合をmel.evalで列挙して実行させました。
また、optionVarとして記憶されておく桁が1つ増えました。
そこで、従来から使っている人は6桁で、まったく新しく使う人は無い訳で、こんな分岐を書いてみました。

if cmds.optionVar( exists='chg_setup_var' ) == False:
    cmds.optionVar( stringValue=('chg_setup_var', '1122111' ) )
if len(cmds.optionVar( q='chg_setup_var' )) == 6:
    old_chg_setup_var = cmds.optionVar( q='chg_setup_var' )
    new_chg_setup_var = old_chg_setup_var[:6] + '1'
    cmds.optionVar( stringValue=('chg_setup_var', new_chg_setup_var ) )

万が一、optionVarが壊れてしまっていたら、消すしかないのですが・・・。いや、無いと思いたいです。

cmds.optionVar( remove='chg_setup_var' )


横のボタン数が変わったのは、途中で setParent('..')を挟んで、残りの数をrowLayoutに書いただけです。

cmds.setParent('..')
cmds.rowLayout(numberOfColumns=4)

以上です。



CustomHyperGraph.py と既知の制限・注釈
という訳で現在のところまでのカスタム・ハイパーグラフ のファイルを公開します。
(Pyファイルは シェルフにボタン登録するか、プルダウンメニューに登録して実行します。)
あくまでも自己責任でお使いください。Use as your own risk.
既知の制限・注釈
・・なくなりました。めでたしめでたし・・

起動コマンドは以下の通りになりました。

import CustomHyperGraph
CustomHyperGraph.custom_hypergraph()




twitter ware @SI_UsersNotes

CustomHyperGraph(Maya2012,2014,2015,2016)
V3 CustomHyperGraph_V3.zip10.2 KB 2015/05/01


CustomHyperGraph(Maya2014,2015,2016)
V4 CustomHyperGraph_V4.zip10.5 KB 2015/11/03


という訳で、次回はまたMayaでしょうかね。
乞う、ご期待!! Stay tuned ..
戻る 次へ

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

Daikin CG News お申し込み

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

Twitter

ページの先頭へ