MAYAはPythonでスクリプトを書けますが、MAYAのデフォルトのスクリプトはMELです。
MAYAでPythonでスクリプトを書けるようになってから大分たつので今はなくなりましたが、Python対応し始めた頃はまだMELと同等のコマンドが使えなかったり、同じコマンドでMELだと問題ないのにPythonだと動かない等のバグがありました。
MAYAのPythonにはMELスクリプトを実行可能にする方法が備わっているのでその様にPythonスクリプトでは実行できない場合はPythonのコードの中にMELを組み込んで対応していました。
しかし現在のMAYAのMELとPythonはバグ対応ではなくMELとPythonそれぞれの固有機能を互いに補完する有効な使い方ができると思います。
この記事では、Pythonスクリプトの中にMELスクリプトを組み込む書き方を紹介したいと思います。
Pythonでベクトル型を扱う場合は numpyモジュールを使うのが一般的ですがMAYAのPythonに標準では入っていません。モジュールをMAYAで使えるようにする事は可能ですが、素のMAYAのPythonでもベクトル計算ができる方法として紹介します。※あくまでも3DCGツールとしてのMAYAの中でのみ成立する方法です。
|
PythonでMELスクリプトを使えるようにmaya.melモジュールをインポートする
MAYAのロケーションパスをプリントで出力表示するスクリプトです。Pythonの中でMELコマンドを実行してMAYAのロケーションパスを取得しています。
import maya.mel as mm
maya_location = mm.eval("getenv MAYA_LOCATION")
print(maya_location)
説明:
import maya.mel as mm
MAYAのPythonスクリプトで使用できるMELのモジュールをインポートします。
maya_location = mm.eval("getenv MAYA_LOCATION")
MELで書かれたMAYAのロケーションパスを取得する(env)エンブコードをPythonのMELモジュールで実行
print(maya_location)
受け取ったパスをプリントで出力表示します。
結果:
MAYAのロケーションパスが出力表示されました。
型の設定は必要ない
セレクトしたオブジェクトの名前をリスト化して3番目の名前をプリントするスクリプトコードをMEL Python Python+MEL それぞれの方法で書きました。
MEL:
string $select_Obj_list[] = `ls -sl`;
print($select_Obj_list[2]);
説明:
MELは型の設定が必要です。このコードではstring型を設定しています。
Python:
import maya.cmds as cmds
select_Obj_list = cmds.ls(sl=True)
print(select_Obj_list[2])
説明:
Pythonなので型の設定は必要ありません。
Python + MEL:
import maya.mel as mm
select_Obj_list = mm.eval("ls -sl;")
print(select_Obj_list[2])
説明:
MELスクリプトを実行して値を返されますが、受け取り側はPythonなので型の設定は必要ありません。
実行:
ポリゴンのプリミティブを生成して選択して、それぞれ実行しました。
結果:
3つのコードすべて同じ結果になりました。
|
外部ファイルのMELスクリプトをPythonで実行する
ボタンが並んだウィンドウが生成されるMELスクリプトを
test_mel_code.mel
の名前で保存しました。
MEL:
global proc test_mel_code()
{
window -width 150;
columnLayout -adjustableColumn true;
button -label "Button test1";
button -label "Button test2";
button -label "Button test3";
showWindow;
}
このMELスクリプトをPythonスクリプトで実行します。
Python:
import maya.mel as mm
maya_location = mm.eval("test_mel_code;")
実行:
ボタンが並んだウィンドウが生成されました。
|
PythonにMELスクリプトを組み込んでベクトル計算をする
MEL にはベクトル計算ができるvector型があります。
MAYAのベクトルは 3 つのfloat値を関連付けてグループ化したものでMAYAのみで成立する独自の概念ですが、他のプログラミング言語では数学の知識を必要とするベクトル計算を簡単に扱えます。※一般的にベクトルは方向と力を表す用法で使いますが、MAYAのvectorはfloat値を3つ並べた集まりを指します。
MELでベクトルは
<<float,float,float>>
で表します。
vector型の変数に代入するには
vector $vec = <<2.3,6.8,1.6>>;
加算減算などの計算も一度に行えます。
例:
2つのベクトルを乗算します
vector $vec_multi = <<3.6,8.3,4.1>> * <<52.8,1.2001,7.30000>>;
print($vec_multi);
結果:
3.6*52.8 8.3*1.2001 4.1*7.30000
3つの計算が一回で終わりました。
上記を踏まえて今度はPythonスクリプトにMELのベクトルを組み込んだのが以下のコードです。
MEL と Python+MEL の両方で書きました。
MEL:
vector $vec ;
$vec=<<1.2, 2.3, 3.4>> + <<2.6, 3.4, 5.4>>;
float $vecX_float = $vec.x;
float $vecY_float = $vec.y;
float $vecZ_float = $vec.z;
print($vecX_float);
print($vecY_float);
print($vecZ_float);
説明:
vector $vec ;
$vec=<<1.2, 2.3, 3.4>> + <<2.6, 3.4, 5.4>>;
2つのベクトルを加算してvector型の変数「$vec」に代入しました
float $vecX_float = $vec.x;
float $vecY_float = $vec.y;
float $vecZ_float = $vec.z;
加算したベクトル「$vec」のXYZそれぞれの要素をfloat型の変数に代入
print($vecX_float);
print($vecY_float);
print($vecZ_float);
取得した値をprintで出力
これと同じ事をPythonにMELを組み込んで書いたのが以下のコードです。
Python+MEL:
import maya.mel as mm
mm.eval("vector $py_vec ;")
mm.eval("$py_vec=<<1.2, 2.3, 3.4>> + <<2.6, 3.4, 5.4>>;")
mm.eval("float $py_vecX_float = $py_vec.x;")
mm.eval("float $py_vecY_float = $py_vec.y;")
mm.eval("float $py_vecZ_float = $py_vec.z;")
vector_x = mm.eval("min $py_vecX_float $py_vecX_float;")
vector_y = mm.eval("min $py_vecY_float $py_vecY_float;")
vector_z = mm.eval("min $py_vecZ_float $py_vecZ_float;")
print(vector_x)
print(vector_y)
print(vector_z)
説明:
mm.eval("vector $py_vec ;")
mm.eval("$py_vec=<<1.2, 2.3, 3.4>> + <<2.6, 3.4, 5.4>>;")
2つのベクトルを加算してvector型の変数「$py_vec」に代入しました
mm.eval("float $py_vecX_float = $py_vec.x;")
mm.eval("float $py_vecY_float = $py_vec.y;")
mm.eval("float $py_vecZ_float = $py_vec.z;")
加算したベクトル「$py_vec」のXYZそれぞれの要素をfloat型の変数に代入
vector_x = mm.eval("min $py_vecX_float $py_vecX_float;")
vector_y = mm.eval("min $py_vecY_float $py_vecY_float;")
vector_z = mm.eval("min $py_vecZ_float $py_vecZ_float;")
Pythonの変数で値を取得するため、何らかのMELコマンドで実行結果を戻り値として受ける様にします。※この辺りがPython+MELで書く場合のマイナス点ですね。
このコードではMELコマンドの min を使いました。
min float値 float値
で小さい方の値を戻り値として返します。両方同じ値でもエラーにはならずに戻り値を返します。
print(vector_x)
print(vector_y)
print(vector_z)
取得した値をPythonスクリプトのprintで出力
結果:
5.7
8.8
1.2+2.6 , 2.3+3.4 , 3.4+5.4 の結果が表示されました。
MAYAの為に作られたMELのvectorなので3次元を扱う事にも長けてます
次は2本の頂点法線のベクトル値をPythonスクリプトで取得してMELスクリプトで2本のベクトルの間の角度を取得します。
import maya.cmds as cmds
import maya.mel as mm
vertex_normal = cmds.polyNormalPerVertex( query=True, xyz=True )
mm.eval("vector $vertex_normal_1 = << %s , %s , %s >>; " % (vertex_normal[0],vertex_normal[1],vertex_normal[2]))
mm.eval("vector $vertex_normal_2 = << %s , %s , %s >>; " % (vertex_normal[3],vertex_normal[4],vertex_normal[5]))
mm.eval("float $rad = `angle $vertex_normal_1 $vertex_normal_2`;")
deg = mm.eval("rad_to_deg($rad);")
print(deg)
説明:
vertex_normal = cmds.polyNormalPerVertex( query=True, xyz=True )
Pythonスクリプトで選択したバーテックスフェースの法線のXYZ値を取得
mm.eval("vector $vertex_normal_1 = << %s , %s , %s >>; " % (vertex_normal[0],vertex_normal[1],vertex_normal[2]))
mm.eval("vector $vertex_normal_2 = << %s , %s , %s >>; " % (vertex_normal[3],vertex_normal[4],vertex_normal[5]))
Python+MELスクリプトで2本の法線の値をそれぞれvector変数に代入
mm.eval("float $rad = `angle $vertex_normal_1 $vertex_normal_2`;")
Python+MELスクリプトで2本のベクトルの間の角度をラジアンで取得。その値をfloat変数に代入
deg = mm.eval("rad_to_deg($rad);")
Python+MELスクリプトでラジアンから角度に変換
print(deg)
Pythonで角度の値をprint出力表示
実行:
バーテックスフェースを2つ選択して実行
結果:
2本の法線の間の角度が表示されました。
|
まとめ
Pythonスクリプトの中にMELスクリプトを組み込む書き方
及び
PythonにMELスクリプトを組み込んでベクトル計算をする方法
を紹介しました。
import maya.mel as mm
MELで得た戻り値を受け取る時の変数は通常のPython同様に型は必要ない
select_Obj_list = mm.eval(“ls -sl;”)
MELのvector型を使った計算をPythonスクリプトでも使える
maya_location = mm.eval(“angle <<0,0,-1>> <<0,1,0>>;”)
MAYAのスクリプトにPythonを使っているとMELの事を気にする事はありませんがたまにMELのリファレンスを覗いてみるとMELにしかない便利なコマンドが見つかるかも。
以上です
|
豊富なカスタマイズメニューで、あなた好みの1台が購入できます。
人気の秘密は何と言ってもコスパの高さ。
最新のCPU・GPUパーツを搭載したモデルを驚きの価格で提供。
山口県の自社工場で組み立てられ徹底した試験・検査後に出荷。
無償修理サービスもありサポート体制も安心。
コスパに徹底的にこだわる方は公式サイトへ >> 【FRONTIER】
|
|
BTOパソコンの草分け的ブランドFRONTIER(フロンティア) 3DCG/動画編集/ゲーム用途に合わせてCPUやGPUなどパーツを自由に選べてコスパにもこだわる方にオススメ。 |
|
|
|
|
|