【Maya】cmdsから実行できる!?
結構便利なRuntimeCommand

こんにちは!田中です。
夏ですね!スイカがおいしい季節ですね!
そして取り込んだ洗濯物にセミがついている恐怖がよみがえる季節でもあります(経験済)

今回はRuntimeCommandを使ってカスタムコマンドを作ってみる方法について紹介します。
先日うちのTAチームの中で、「RuntimeCommandってcmdsから実行できるんだよ~」と教えてもらい、衝撃を受けて調べてみたことを共有できればと思います。

 

目次

 

RuntimeCommandとは

RuntimeCommandは、MEL・Mayaコマンド(cmds)・MELプロシージャなどのスクリプトをまとめて短いコマンドラインで実行できる処理です。
簡単にいうと大量のpythonやMELコマンドで記述された長い処理をたった一行のコマンドラインで実行できるようになります。

詳細はMayaヘルプ ランタイムコマンドを作成するをチェックしてください!

そもそも「スクリプトとは何ぞ」という方は【Maya】DCCツールを作ってみよう -入門編-に簡単なリネームツールをもとに書き方を紹介していますので、チェックしてみてください!

 

RuntimeCommandは、HotkeyEditorウィンドウから一覧・編集・追加をすることができます。
HotkeyEditorウィンドウは、Windowsメニュー > Settings/Preferences > Hotkey Editorから開くことができます。

HotkeyEditorウィンドウでは、ツールのショートカットを設定できるだけではなく、RuntimeCommandの設定もできます。
Edit Hotkeys For:横のプルダウンを「Menu item」に設定してみると、
皆さんがいつも見かけるMayaの画面上部のメニューに並んでいるツール類を実行するRuntimeCommandがあることが確認できます。

右側上部のRuntimeCommand Editorタブに切り替え、左のメニューツール名の選択を切り替えると、
選択ツールに応じてRuntimeCommandを確認することができます。
下の画像の例では、New Scene(新規シーンを開く)の実行はperformNewScene 0;という実行処理で行われていることがわかりますね。

この実行処理をまとめて(…といっても一行だけですが)、NewSceneというRuntimeCommand一行で実行できます。
試しに下のコマンドラインを「MEL」に設定してNewSceneと打ち込んでEnterキーを押してみると、新規シーンを立ち上げることができますね。

 

RuntimeCommandってcmdsで実行できるの!?

本題です。今まで個人的にRuntimeCommandはMEL的に使用することしかできないと考えていましたが…cmdsでも実行できるようなんです。
試しに先ほどの「NewScene」を実行してみようと思います。

スクリプトエディタを開きpythonタブにて、

cmds.NewScene()

と入れてみましょう。そうすると…RuntimeCommandが青色にハイライト化されるではありませんか!!!

そのままctrl+Aで処理を全選択 > ctrl+Enterで実行すると…MELから実行したのと同様に新規シーンが開かれることがわかります。

ということは、メニューにあるRuntimeCommandは、

cmds.{RuntimeCommand名}()

で実行できるということですね!
(ただしオブジェクト選択してないとダメなど…ややクセがあるものもあるので注意!)

今まで個人的にRuntimeCommandはツールを作成する上のヒントとして活用することがメインだったのですが、
cmdsから実行できるのであれば色々な用途に使えるかもしれません。

 

カスタムRuntimeCommandを作ってみる

上で紹介した通り、Mayaのデフォルトツールを実行するRuntimeCommandは実行できました!
もちろん自己流のカスタムRuntimeCommandも作成して実行できます。作ってみましょう。

数行のコマンドだと寂しいので、せっかくなのでシンプルなキャプチャツールを作ってみましょう。
キャプチャツールの仕様的は、以下のようにしようと思います。

    ・シーン全てのオブジェクトメッシュに対してそれぞれキャプチャを撮ります
    ・撮影に邪魔になる他のオブジェクトを一時的に非表示にします。撮影角度は今回は考えません。
    ・あらかじめ非表示になっているものがあれば、キャプチャの時だけ表示→元の状態に戻す

とりあえず上記の仕様に則って作成したものがこちらです。結構長いですね
(jointやLocatorもキャプチャされたりするなどの問題もあるので改良は必要です…今回は細かい仕様については考えないことにします)


import maya.cmds as cmds

def main():
    """mainの実行処理"""

    # !!!!!フォルダパスを設定してください!!!!!
    capture_export_dir = u"キャプチャを書き出すフォルダパス"

    # この書き方だとjointやLocatorなども含まれるのでご注意ください!
    all_obj_list = cmds.ls(type="transform", long=True)

    # シーンにオブジェクトがなければ撮影しません
    if not all_obj_list:
        print(u"シーンにオブジェクトがないのでキャプチャしませんでした")
        return
    
    exclude_obj_list = ["|persp", "|top", "|front", "|side"]
    all_obj_list = set(all_obj_list) - set(exclude_obj_list) # カメラオブジェクトを除く
    
    # {"オブジェクト名":TrueまたはFalse}のdictを取得
    visible_dict = get_is_visibility_dict(all_obj_list)

    # キャプチャを撮影
    capture_scene_object(all_obj_list, capture_export_dir)

    # オブジェクトの表示状態をもとに戻します
    revert_object_visibility(visible_dict)


def get_is_visibility_dict(all_obj_list):
    """オブジェクトの表示状態を辞書にまとめて返す処理"""

    # 非表示になっているものもあるので、表示状態とオブジェクト名を保持しておきます。
    visible_dict = {}
    for obj_name in all_obj_list:
        is_visibility = cmds.getAttr("{0}.visibility".format(obj_name))
        visible_dict[obj_name] = is_visibility # オブジェクト名をキー、表示状態を格納
    
    return visible_dict

def capture_scene_object(all_obj_list, capture_export_dir):
    """シーンのオブジェクトのキャプチャを撮ります"""

    for obj_name in all_obj_list:
        cmds.hide(all_obj_list) # 全てのオブジェクトを非表示にします

        cmds.setAttr("{0}.visibility".format(obj_name), True) 
        cmds.viewFit(obj_name, fitFactor=1.0) # 指定のモデルにフォーカスします

        obj_name = obj_name.split("|")[-1] # オブジェクト名をフルパスから短い名前にする
        export_full_path = "{0}/{1}.jpg".format(capture_export_dir, obj_name)
        cmds.refresh(filename=export_full_path) # 現在のビューをキャプチャ画像として指定のフォルダへ出力

def revert_object_visibility(visible_dict):
    """オブジェクトの表示状態を戻します"""

    for obj_name, is_visiblity in visible_dict.items():
        cmds.setAttr("{0}.visibility".format(obj_name), is_visiblity) 


# main関数の実行
main()

まずは上記のスクリプトがちゃんと動くかどうかをテストしてみます。初めにシーンに何もオブジェクトがなければ何か置きましょう。
今回はシーンに「コーン、キューブ、トーラス」の3つを置いてキャプチャを撮ることにします。

スクリプトを全部コピーして、スクリプトエディタのPythonタブの中にペーストします。
次にキャプチャを書き出すフォルダパスをこの部分(7、8行あたり)に設定してください。今回はテストなので中身が空っぽのフォルダパスを強くお勧めします。

最後にctrl+Aでスクリプトを全選択 > ctrl+Enterで処理を実行します。

キャプチャを書き出すフォルダの中身にシーン全てのオブジェクトのキャプチャが出力されれば正しく実行できています!

ここまで出来たらRuntimeCommandに登録します。
先ほどのHotkeyEditorウィンドウを開き、以下の順序で登録しましょう。

    Newボタンから新規のRuntimeCommandを追加します
    ・Nameをcapture_testと付けます
    ・Languageを「Python」に設定します
    ・実行できたスクリプトをすべて選択コピーし、こちらにペーストします
    ・Save RuntimeCommandボタンを実行します

登録が終わったら早速スクリプトエディタで
cmds.capture_test()
と入れてみます。画像のようにハイライト化したことがわかります!
(ハイライト化しなかった場合はスクリプトエディタを再起動してください)

ctrl+Aで処理を全選択 > ctrl+Enterで実行できたことが確認できたかと思います!

ちなみに…
登録したカスタムRuntimeCommandはHotKeyEditorのCustom Scriptsに切り替えると確認できます。

登録されたカスタムRuntimeCommandは、Mayaを閉じた際にデフォルトで
C:\Users\{ユーザー名}\Documents\maya\{Mayaのバージョン}\prefs
userRunTimeCommands.melに登録されます。

このように長いコードもRuntimeCommandに登録するとたったの一行で実行できるということがわかりましたね!
「ツール化するまでもないけど、頻繁に使うちょっと長いコードもあるしなあ…」といった場合に登録しておくと個人の作業が捗りますし、ホットキーと合わせて登録しておくとより便利そうですね!他のコマンドとの組み合わせもできそうです。
ここまで読んでいただきありがとうございます!お疲れさまでした!

tanaka rika

新卒からTAになりました。MayaのツールとHoudini関連の仕事をしています。
フェレットと暮らして10幾年。動物かわいいフェレットかわいい。

投稿者記事

  1. 【Maya】DCCツールを作ってみよう -入門編-

    2024-01-26

関連記事

  1. 【Maya】MELのスクリプトに作業単位で変更しない値がある

    2019-07-09

  2. 【Maya】キャラクタライズのID番号とジョイント

    2020-12-08

  3. 【Maya】コントローラーの一時的なワールド挙動化

    2019-05-28

  4. 【TANight】無料配布Maya便利ツール徹底紹介
    資料公開

    2023-05-30

スキルレーダーチャート

テクニカルアーティスト専用
スキルレーダーチャート
どなたでも無料でご利用いただけます。

ABOUT

TECH COYOTE​

テクニカルアーティストの為のまとめサイトです。​
本サイトでは、ツール開発、業務効率化等について情報発信をしていきます。

COYOTE 3DCG STUDIO

C&R Creative Studios

難易度別

RECENT TWEET

ページ上部へ戻る