2020年1月27日月曜日

メインメニューに自作のメニューを追加する

MELを大量に作成していくと、スクリプトをメニューから実行したくなってきます。
まぁ、シェルフとかに登録もできますけど、バージョンが変わったり、言語設定を変えたりと、数種類の maya を起動する場合、シェルフでは小回りが利きません。

ということで、メインメニューへ自作ツール用のメニューを追加してみようと思います。


と、その前に

自作の MEL をコマンドとして使うためには、mayaが起動した時に.melファイルがコンパイルされ、スクリプトがコマンドとして認識されていないといけません。
そこで、source を実行して、エラーが出たらメニューを無効化、エラーがなければ有効化するプロシージャが必要になります。

global proc trySource(
    string $script)
/***************************************************************************//**
    @brief source できたかを返す。
    @param source するスクリプト名
    @retval 1 できた
    @retval 0 できなかった
 ******************************************************************************/
{
    return ( !catch(`eval("source \""+$script+".mel\"")`) );
}

ダブルミーニングでカッコいいんですが、そんなに長くはないので、改めて.melファイルにしなくて良いか・・・
スクリプトを大雑把な種類別にフォルダを分けるとなると、source に渡す時にフォルダ名も一緒に渡すことになります。

グダグダ説明するよりはサンプルコードを見た方が早いので、
//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
/// @file tryMenuCreate.mel
/// @brief メインメニューへ tryTools メニューを追加する。
/// @author Teruyuki Ishiko
/// @date since 2017/01/08
//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/



proc int _isSource(
    string $cmd )                       ///< sourceするスクリプト名
/***************************************************************************//**
    @brief source できたかを返す。
    @retval 1 できた
    @retval 0 できなかった
 ******************************************************************************/
{
    return ( !catch(`eval("source \""+$cmd+".mel\"")`) );
    
}


proc _buildMenu.scene(
    string $parent )                    ///< 親のレイアウト名
/***************************************************************************//**
    @protected
    @brief Scene のメニューを作成する
 ******************************************************************************/
{
    setParent -m $parent;
    int $isDN = _isSource("tryUtils/tryDeleteNode");
    
    
    menuItem -l "Delete nodeGraphEditorInfo"
        -en $isDN
        -ann ""
        -ec true
        -c "tryDeleteNode (\"nodeGraphEditor*\")";
    
    menuItem -l "Find Duplicates"
        -en `_isSource "tryUtils/tryFindDuplicates"`
        -ann "重複名のノードを調べる"
        -ec true
        -c "tryFindDuplicates";
    
}


proc _buildMenu.node(
    string $parent )                    ///< 親のレイアウト名
/***************************************************************************//**
    @protected
    @brief Node のメニューを作成する
 ******************************************************************************/
{
    setParent -m $parent;
    
    menuItem -l "Get Attr Names"
        -en `_isSource "tryUtils/tryGetAttrName"`
        -ann "選択しているノードが持っているアトリビュート名を調べる"
        -ec true
        -c "tryGetAttrName.call";
    
}


proc _buildMenu.poly(
    string $parent )
/***************************************************************************//**
    @protected
    @brief Porigons メニューの編集
 ******************************************************************************/
{
    setParent -m $parent;
    
    menuItem -l "Switch Mesh Visible..."
        -en `_isSource "tryTools/trySwitchMeshVisible"`
        -ann "メッシュオブジェクトのビジビリティを制御します。"
        -c ("trySwitchMeshVisible");
    
}


proc _buildMenu.skin(
    string $parent )
/***************************************************************************//**
    @protected
    @brief Skin メニューの編集
 ******************************************************************************/
{
    setParent -m $parent;
    
    
    menuItem -l "Round Skin Weight..."
        -en `_isSource "tryTools/tryRoundWeightTool"`
        -ann "ウェイト値の端数を調整する"
        -ec true
        -c "tryRoundWeightTool";
    menuItem -l "Weight Tool..."
        -en `_isSource "tryTools/tryWeightTool"`
        -ann ""
        -ec true
        -c "tryWeightTool";
    
}


proc _buildMenu.curve(
    string $parent )                    ///< 親のレイアウト名
/***************************************************************************//**
    @protected
    @brief Node のメニューを作成する
 ******************************************************************************/
{
    setParent -m $parent;
    
    menuItem -l "Create Curve Object Tool..."
        -en `_isSource "tryTools/tryCurveTools/tryCurveObjectTool"`
        -ann "カーブオブジェクトを作成する"
        -ec true
        -c "tryCurveObjectTool";
    menuItem -d true;
    menuItem -l "Sew Curve EP..."
        -en `_isSource "tryTools/tryCurveTools/trySewCurveEP"`
        -ann "Edit Point を縫合する"
        -ec true
        -c "trySewCurveEP";
    menuItem -l "Mirror Curve EP..."
        -en `_isSource "tryTools/tryCurveTools/tryMoveToSymmetricEP"`
        -ann "Edit Point をミラーリングする"
        -ec true
        -c "tryMoveToSymmetricEP";
    menuItem -d true;
    
}


proc _buildMenu.anim(
    string $parent )                    ///< 親のレイアウト名
/***************************************************************************//**
    @protected
    @brief Animation メニューの編集
 ******************************************************************************/
{
    setParent -m $parent;
    
    
}


global proc tryTools.info()
/***************************************************************************//**
    @todo ブログへ飛ぶ。
 ******************************************************************************/
{
    showHelp -a "https://dcc-scripts.blogspot.com/";
    
}


global proc tryMenuCreate()
/***************************************************************************//**
    @brief main procedure.
 ******************************************************************************/
{
    global string $gMainWindow;
    setParent $gMainWindow;
    
    /// 旧メニュー削除
    string $tryMenu ="tryTool_in_mainMenu";
    if(`menu -q -ex $tryMenu`) deleteUI $tryMenu;/* for debug. */
    
    
    //------------------------------------------------------------------------------
    /// メニュー作成
    menu -p $gMainWindow -l "Try Tools"   -to true $tryMenu;
        string $menu0 =`menuItem -sm true -to true -l "Scene"`;     setParent -m ..;
        string $menu1 =`menuItem -sm true -to true -l "node"`;      setParent -m ..;
        menuItem -d true;
        string $menu2 =`menuItem -sm true -to true -l "Polygon"`;   setParent -m ..;
        string $menu3 =`menuItem -sm true -to true -l "Skin"`;      setParent -m ..;
        string $menu4 =`menuItem -sm true -to true -l "Curve"`;     setParent -m ..;
        string $menu5 =`menuItem -sm true -to true -l "Animation"`; setParent -m ..;
        menuItem -d true;
        string $about =`menuItem
            -l "About Try Tools"
            -ann "ブログへ"
            -ec true
            -c "tryTools.info"
            `;
    
    
    //------------------------------------------------------------------------------
    /// サブメニュー作成
    _buildMenu.scene( $menu0 );
    _buildMenu.node(  $menu1 );
    _buildMenu.poly(  $menu2 );
    _buildMenu.skin(  $menu3 );
    _buildMenu.curve( $menu4 );
    _buildMenu.anim(  $menu5 );
    
}




200行とけっこう長いですが、サブメニューを作成する部分は、どのプロシージャもほとんど同じで、やっていることは、
・メニューのラベルを設定(-label)
・source でメニューを有効/無効化(-enable)
・そのメニューの説明(-annotation)
・メニューの実行コマンド付加(-command)
これを登録したい.melファイルの数だけ書き込んでいく感じなのでどんどん増えていきます。

-echoCommand(-ec) はメニューを実行したときの -commandを履歴に表示させるかのフラグなので、特になくても良いですね。

メニューの構築中は何回もデバッグすることになるので、スクリプトエディタへ以下のコードを記述しておくとはかどります。
source "tryMenuCreate.mel";
tryMenuCreate;
171行目でメニューを削除しているので、毎回作り替えられます。

これを実行すると当然メニューが作成されます。


で、_isSource の効果でこうなります。


source できたメニューだけ有効になるので、環境を移植するとかに.melファイルのコピー忘れとかを発見しやすくなるという按配。
source するファイル名を間違えると変なコマンドが実行されてしまうので、コピペは慎重に!

上のスクリプトエディタで書いたコードを userSetup.mel とかに追記しておけば、mayaを起動すればメニューが追加されます。

0 件のコメント:

コメントを投稿