CG・コンテンツ制作
  1. CG・コンテンツ制作トップ
  2. DAIKIN CG Channel
  3. UsersNotes
  4. スクリプト
  5. カスタム オブジェクト ビューア for Maya
SUITE USERS NOTES

カスタムオブジェクトビューア for Maya
Custom ObjectViewer for Maya

プロローグ;Prologue
maya_13_Custom_ObjectViewer_00s
MayaPythonの試作段階で、昔、Softimage XSIに有ったObject Viewという
指定したオブジェクトをずっと表示してくれる画面があり、
それのMaya版を作ってみたら、興味あるかな・・・?と問うたところ......!?
予想に反して大きな反響がありました!!!<応援ありがとうございます>

そこでカスタム オブジェクト ビューアとしてここに記事にして公開することにしました。

もちろん、Pythonの機能紹介を基本としたページですが、ツールだけをダウンロードして利用することも可能です。

また、前回からツール自体をGitHubにて スクリプトを公開し、より皆さんに良いものが出来上がったら良いな~、という思いで試みていますが、今回も。GitHubを利用したいと思います。

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

Please use this information asyour own risk.
Windows7 Professional 64Bit、Intel Core i7-3930K(3.20GHz,6コア/12スレッド)
メモリ16GB、NVIDIA GeForce GTX970 4GB

maya_13_ritaro_ml



Softimage XSI の Object View ってなんだっけ?

すっかり操作を忘れてしまった感のあるSoftimageXSIの画面とその機能ですが、
Object Viewは、指定したオブジェクト (例えばキャラ全体や頭・手と言った特定の一部分)を
ずっと表示してくれる画面で、そのオブジェクトがどんなに動いても常に中央に表示し続けてくれるウィンドウでした。
その部分の動きの確認やアニメーションを付ける際に非常に便利な画面でした。
maya_13_object_view_s

■ドキュメントBasics(基本) > ビューイングとナビゲーション > Object View



どんな使い方の時便利?
すぐに思い付くObject Viewの使い方としては、
アクションやダンスモーション中の手のアニメーションやフェイシャルアニメーションの
検証用または設定用の表示画面として使えそう、と思い浮かべるかと思うのですが、
実はある条件での作業でその機能がとても役立つことを知りました。

それは、こんな場合です。
キャラクターのアニメーションが原点で動いているのではなく、どんどんと原点から遠ざかって行ったり、
原点の場所を全く無視したアクションを作っていたりする場合です。
そして、それはどんな時に起こるか、といえば・・・・
UnityUE4を利用したリアルタイムのシーケンスとして実機映像やムービーを作成している場合などです。
各キャラクターのモーションはオフセット値を使った配置型にするのではなく、
その場の演技モーションとして作成して登録した方が作業的にも都合が良く、
また、キャラクターのアニメーションも各カットシーン用に作成するものなので、
使い回しを気にするデータではありません。

そんな、途方も無く原点から遠い場所でアニメーションを作成している場合、
どこに居ようがオブジェクトに追従して指定した部分をずっと表示してくれる画面である
Object Viewは凄く重宝するウィンドウになることが予想されます。




Viewウィンドウの用意何のパネル?

いつものごとく、カメラを選択出来るウィンドウは Mayaだと何のパネルを使っているかを調べるところから始めます。
いつも何気なく使っているMayaの画面で、カメラがあるウィンドウと言えば、
そう、前面ビュー や 側面ビュー のウィンドウです。ここから紐解けそうです。

今回の調べ方も、ちょっと違う方法から見てみましょう。
Mayaにはパネルエディタというウィンドウがあります。
日本語UIにしていると日本語の表記の一覧になっています。
maya_13_cov_001
Mayaのデフォルトの状態でもたくさんのパネルが用意されていることがわかります。
Pythonを使ってデータをこの順番で表示するには以下の方法で出来たりします。
all_panels = cmds.getPanel(allPanels=True)
for o_panel in all_panels:
    o_type = cmds.getPanel(typeOf=o_panel)
    if o_type != 'emptyPanel':
        o_label = cmds.panel(o_panel, q=True,label=True )
        print o_label
#結果
上面ビュー
側面ビュー
前面ビュー
パース ビュー
ToggledOutliner
アウトライナ
グラフ エディタ
ドープシート
タイム エディタ
Trax エディタ
カメラ シーケンサ
ハイパーグラフ階層
ハイパーシェード
バイザー
ノード エディタ
ノードの作成
UV エディタ
レンダー ビュー
シェイプ エディタ
ポーズ エディタ
ダイナミック リレーションシップ エディタ
リレーションシップ エディタ
リファレンス エディタ
コンポーネント エディタ
ペイント エフェクト
スクリプト エディタ
プロファイラ
コンテンツ ブラウザ

ここで注目するところは、全ての空でないパネルから
実はパネルのラベルを表示するとパネルエディタの表示と同じになる、ってところです。
しかも日本語で返って来ます。
で、その時の各パネルのタイプは、上記スクリプトでもう取得しているので、それを表示してみると。

all_panels = cmds.getPanel(allPanels=True)
for o_panel in all_panels:
    o_type = cmds.getPanel(typeOf=o_panel)
    if o_type != 'emptyPanel':
      print o_type
#結果
modelPanel
modelPanel
modelPanel
modelPanel
outlinerPanel
outlinerPanel
scriptedPanel
scriptedPanel
scriptedPanel
scriptedPanel
scriptedPanel
scriptedPanel
scriptedPanel
scriptedPanel
scriptedPanel
scriptedPanel
scriptedPanel
scriptedPanel
shapePanel
posePanel
scriptedPanel
scriptedPanel
scriptedPanel
scriptedPanel
scriptedPanel
scriptedPanel
scriptedPanel
scriptedPanel

という結果を表示していることから、前面ビューなどはmodelPanelであり、
デフォルトの状態で既に4枚あることが理解出来ます。

と、ここまで来れば、modelPanelを作れば良いので、このコマンドもmodelPanelです。

modelPanel
http://help.autodesk.com/cloudhelp/2018/JPN/Maya-Tech-Docs/CommandsPython/modelPanel.html

modelPanelを作成する時、上記のようにラベルに名前を付けるとパネル名になり、
表示に使うカメラも同時に設定することができます。
パネルはformLayoutを使ってUI的に表示制御しますので、今はこんな感じで書くと想定して次に行きましょう。

c_model= cmds.modelPanel(label='ObjectView_ModelPanel', camera=o_cam)




追加するカメラどんなカメラ?

さて、カメラの設定のあるパネルは用意出来たところで、今度はそのカメラについてです。
通常、Mayaのカメラは、注目点の設定の無いカメラ単体のカメラですが、
ここでは制御がしやすいカメラ、エイム、アップを使いたいと思います。
メニューから作成すると、グループノードの下にカメラと_aim、_up の制御が付いたカメラが作成されます。
maya_13_cov_002
camera
http://help.autodesk.com/cloudhelp/2018/JPN/Maya-Tech-Docs/CommandsPython/camera.html

このカメラが作成される時の ログを[レ]すべてのコマンドのエコーを有効にして、スクリプトエディタを見てみると、
maya_13_cov_003
camera から始まるログ行を Python化 出来そう
・・・・なのですが、意外にもスクリプト化が面倒なのです。(特に cameraMakeNode のあたりなど・・・・)
そこで、今回は最初のMelコマンド行をそのまま使うことにしたいと思います。

mel.eval('CreateCameraAimUp;')

この Melコマンド'CreateCameraAimUp;' を実行後は、カメラgroup以下の3つのノードが選択状態になっていることから、
続いて選択 lsコマンドを使って、各要素の設定するようにしてみます。

カメラ自身は、ニアクリップ10ファークリップ30とし、
_aim の注目点の位置を0,0,0に設定します。

mel.eval('CreateCameraAimUp;')
aimup_list = cmds.ls( sl=True )
cmds.select(clear=True)

for n_camdata in aimup_list:
    cmds.select(n_camdata,r=True)
    n_dataShape = cmds.listRelatives(n_camdata, children=True)[0]
    n_cam_type = cmds.objectType(n_dataShape)
    if n_cam_type == 'camera':
        n_number = n_camdata[len('camera'):]
        cmds.setAttr( n_dataShape + '.nearClipPlane', 10 )
        cmds.setAttr( n_camdata + '.translateZ', 30)
        o_cam = n_camdata
    if '_aim' in n_camdata:
        cmds.setAttr( n_camdata + '.translateX', 0)
        cmds.setAttr( n_camdata + '.translateY', 0)                
        cmds.setAttr( n_camdata + '.translateZ', 0)
    cmds.select(clear=True)



カメラのコンストレイント設定

このスクリプトの実行条件として、"選択したものを注目する画面"にしたいので、
選択したものを親とした _aim と _up の付いたカメラを作成した後、
Mayaのシーンのトップに 作成されたカメラグループを移動させて、
元あった親とのParentコンストレイント を設定します。
こうすることで、最初に選択したものの階層構造内に作ったカメラが介在しないようにしておきます。

上のスクリプトで、
作成したカメラを特定していて (o_cam ) 、そのカメラについている番号 (n_number 例;1,2,3) を利用します。

上のスクリプトの続きで、
カメラの親である カメラの groupノード を特定して、その名前を変更しておきます。(例;"ObjectViewCamera_group1")
それをMayaのシーンルートに移動したいのですが、
これはparent コマンドで 、world=True とすると簡単に設定出来るところが面白いところです。
後は、元の親とMayaのシーンルートに移したGroupノード間に parentConstraint を設定します。

o_pregrp = cmds.listRelatives(o_cam,parent=True )[0]
cmds.select(o_pregrp,r=True)
o_grp = cmds.rename('ObjectViewCamera_group' +n_number )
cmds.parent(o_grp, first_selected_node, relative=True )

cmds.select(clear=True)
cmds.select(o_grp,r=True)
pre_parent = cmds.listRelatives(o_grp,parent=True )[0]
cmds.parent(o_grp,world=True)
const_node = cmds.parentConstraint(pre_parent,o_grp,maintainOffset=True)[0]
cmds.select(clear=True)





UIの用意formLayoutの設定

カメラの設定が出来るmodel パネルと、
通常良く使うcolumnLayoutを 一緒に1つの window に表示させるにはformLayout を利用します。

formLayout
http://help.autodesk.com/cloudhelp/2018/JPN/Maya-Tech-Docs/CommandsPython/formLayout.html


また、model パネルの表示設定は、modelEditorというコマンドから行います。

modelEditor
http://help.autodesk.com/cloudhelp/2018/JPN/Maya-Tech-Docs/CommandsPython/modelEditor.html

modelEditorのオプション displayAppearance で 外観を設定し (例; 'smoothShaded' )、
グリッド表示やテキスチャー表示の有無も設定出来ます。
この部分だけを完成したスクリプトから抜粋すると、以下のようになっています。

try:
    cmds.window()
    window = cmds.window('CustomObjectViewer' + n_number,
        title='Custom ObjectViewer' + n_number, sizeable=True, 
        topLeftCorner=[200, 200], widthHeight=(400,470))
    form = cmds.formLayout()
    c_model= cmds.modelPanel(label='CustomObjectViewer_Panel' + n_number, camera=o_cam)

except:
    print 'Check Panel Editor & CleanUp Unused Panels !!'

cmds.setParent('..')

column = cmds.columnLayout()

.....<中略> 

cmds.setParent('..')

cmds.formLayout(form,edit=True,
    attachForm=[
        (c_model,'left',5),(c_model,'top',0),(c_model,'right',5),(c_model,'bottom',80),
        (column,'left',5),(column,'top',400),(column,'right',0),(column,'bottom',0)
        ],
    attachPosition=[(column,'right',0,100)],
    attachNone=[(column,'top')]
    )
cmds.modelEditor(c_model,edit=True,grid=False,
    displayAppearance='smoothShaded',activeOnly=False, displayTextures=True )

cmds.showWindow( window )


さて、完成しているUIの方を見ると、
maya_13_cov_004
幾つかのスライダーカメラの ニア/ファークリップや位置/回転値のオフセット値が変更出来るようにしています。
このスライダーを動かすと値が瞬時に反映するようにするには
floatSliderGrpコマンドのオプションでdragCommandchangeCommandの設定を利用するのですが、
ここでも面白い python らしい設定を仕込みます。
以前に紹介している Python ツールにも登場しているのですが、無名関数lambdaを使います。とても便利です!!

無名関数: ラムダ式
https://docs.pyq.jp/python/library/lambda.html

仕組みとしては、スライダーを動かして得た値 (つまり dragCommand か changeCommand が発生した時の値)を、
別の式にその値をそのまま送って結果を反映するようにしたい訳です。
以下完成スクリプトからの抜粋では、カメラの FarClipPlane のスライダーを動かしたら
即座にカメラの FarClipPlane の値が変更がされる、というスクリプト部分になります。

defcam_far_slider(value,n_cam):
    n_cameraShape = cmds.listRelatives(n_cam, children=True)[0]
    cmds.setAttr( n_cameraShape + '.farClipPlane', value )

.....<中略>

def object_view_menu(*args):
    if not cmds.ls( sl=True ):
        print 'Nothing is selected'
    else:
        first_selected_node = cmds.ls(sl=True)[0]

        cmds.select(clear=True)

.....<中略> 

        cmds.floatSliderGrp(label=' Far ClipPlane ',field=True,columnWidth3=[85,40,70],
            adjustableColumn=3, minValue=0.1, maxValue=100,fieldMinValue=0.1,
            fieldMaxValue=100, value=70,
            dragCommand=lambda x:cam_far_slider(x,o_cam),
            changeCommand=lambda x:cam_far_slider(x,o_cam))


このような設定をスライダーがある分、行っているだけです。




増殖し続けるパネル対応 未使用パネルの削除

以前にも紹介しているカスタムのツールと同じ対応が必要です。
それは、Mayaのパネルはシーンにどんどんと溜まっていってしまうので、
閉じてしまったパネルの数に気が付かないままSaveして使い続けてしまえる
ことへの対処が必要です。
そこで、新たなパネルを作成する時、以前に作ったパネルを検索し、
それが非表示パネルであれば消す、という仕組みを入れておきます。

今回作っているパネルの種類は "modelPanel" と解っているので、その種類のパネルを全部取得し、
その中から、今回パネル名、つまりラベルとして "CustomObjectViewer" って付いているパネルで、
尚且つそれが 表示していないパネルであるなら そのパネルを削除する、っていう動作をスクリプト化します。

getPanel コマンドを使えば、パネルの種類や非表示のパネルか、が取得でき、
パネルの削除はdeleteUIコマンドを使って行えます。

all_model_panels = cmds.getPanel(type='modelPanel')
m_panel_list =[]
for o_panel in all_model_panels:
    o_label = cmds.panel(o_panel, q=True,label=True)
    if "CustomObjectViewer" in o_label:
        m_panel_list.append(o_panel)

invis_panel_list = cmds.getPanel(invisiblePanels=True)

for d_panel in m_panel_list:
    if d_panel in invis_panel_list:
        cmds.deleteUI(d_panel,panel=True)






使い方

基本的には、すっと見ていたいノードを選択状態にして、スクリプトを実行します。
すると、自動的にその選択したものをずっと追うカメラが設定してあるウィンドウが立ち上がります。
以下の図は、Character1_Head というエンドJointを選択してスクリプトを実行した例になります。
maya_13_cov_005
選択したノードが必ずしも正面に対して プラスのZ方向とは限らず(例;手など)
また、中央に表示したいものだけを表示して見やすくする為に
Near/Farクリップ を設定すると良い感じに活用できます。
maya_13_cov_006
キャラクター自身のJointの方向に合わせて、移動/回転値のオフセットを入れることで
ウィンドウに合わせた方向に設定出来るはずです。
カスタムグラフエディタのカレントフレームを左右に動かすことで、
Mayaシーン と カスタムのウィンドウ のアニメーションが同時に動く様子が見れます。

Near/Farクリップを設定することで、カメラから見て邪魔な前後の表示をカットすることが出来ます。

例えば、Farクリップを設定して、
自分の体で見えにくくなってしまう手だけを表示したい場合に有効です。
maya_13_cov_007
また、Nearクリップを設定することで、腕で隠れてしまった顔だけを表示することが可能です。
maya_13_cov_008
非表示にしたパネルはを必ず削除を実行していますが、
新規作成したカメラのGroupノード以下はMayaのシーンに残っているので任意に削除が必要です。




GitHubを使った公開
という訳で、ツールはGitHubを使って公開しています。

ツールの設定
Pyファイルはシェルフにボタン登録するか、プルダウンメニューに登録して実行します。

既知の制限・注釈
起動コマンドは以下の通りです。
object_view_menu()



GitHubからの取得
Pyファイルは GitHub に公開しています。
GitHub にアカウント登録していなくても ダウンロードは出来ます。
下記リンクページで、右上[ Clone or downlaod ]という緑色のボタンからダウンロードを行います。
ボタンを押すと表示される[ Download ZIP ]という右側のボタンからZipファイルを取得します。

ツィッターウェア(twitter ware)@SI_UsersNotes
あくまでも自己責任でお使いください。Use as your own risk.

https://github.com/O-Ritaro/Maya_CustomObjectViewer

次回もMayaかも?・・・
乞う、ご期待!! Stay tuned ..
戻る 次へ

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

Daikin CG News お申し込み

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

Twitter

ページの先頭へ