2020年1月27日月曜日

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

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

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


と、その前に

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

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

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

グダグダ説明するよりはサンプルコードを見た方が早いので、
tryMenuCreate.mel
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
/// @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 件のコメント:

コメントを投稿