前回の記事で、PyMELからMELプロシージャを定義するメソッドを探したけど見つからなかった、と書きましたが、折角なので自分で作ってみました。
追記: やっぱりありました。
実装の中身はPythonで、ガワ(proc)だけMELという構成を自動で作る関数です。
ライセンス等は特に設定しませんので、自由に使って頂いて結構です。
(コメント欄等で「使ったよー」等、一言報告頂けると管理人が喜びます。)
自分で作っていて、何か途中からよく分からなくなってきましたが、多分動きます。
これで、グローバルプロシージャ "testMelProc" が定義されます。
各引数の意味は、makeMelProcのdocstringを参照してください。
後は、通常のMELプロシージャと同じように、MELコマンドとして呼び出してやれば、登録されたPython関数 "myFunc" が呼び出され、戻り値もMELプロシージャへと返されます。
現状では使用出来る型に制限がありますが、それなりに実用出来る範囲かなとは思います。
というか、MEL自体複雑な戻り値とか返せませんしね。
追記: やっぱりありました。
実装の中身はPythonで、ガワ(proc)だけMELという構成を自動で作る関数です。
ライセンス等は特に設定しませんので、自由に使って頂いて結構です。
(コメント欄等で「使ったよー」等、一言報告頂けると管理人が喜びます。)
import pymel.core as pm
def makeMelProc(func, procName, retType=None, argTypes=[]):
u"""グローバルMELプロシージャを定義します。
注意: 引数にfloatまたはfloat[]を指定した場合、値がちょうど整数だった時にint型に
強制変換される問題があります。
:param function func: Pythonファンクションオブジェクト。
:param str procName: MELプロシージャの名前。
:param str retType: MELプロシージャの戻り値の型。指定出来る型はargTypesと同じ。
:param list argTypes: MELプロシージャの引数の型のリスト。
使用可能な型は string, int, float, string[], int[], float[]。
"""
modName = func.__module__
funcName = func.__name__
# MEL変数をPython引数に変換する
pyArgs = []
append = pyArgs.append
for i, t in enumerate(argTypes):
if t == "string":
append('"\\"" + $arg%d + "\\""' % i)
elif t == "string[]":
append('"(\\"" + stringArrayToString($arg%d, "\\",\\"") + "\\")"' % i)
elif t == "int[]":
append('"(" + intArrayToString($arg%d, ",") + ")"' % i)
elif t == "float[]":
append('"(" + floatArrayToString($arg%d, ",") + ")"' % i)
else:
append("$arg%d" % i)
pyArgStr = ' + "," + '.join(pyArgs)
# MELプロシージャが呼び出すPythonコマンド
pyCmd = '"import %s; %s.%s(" + %s + ")"' % (modName, modName, funcName, pyArgStr)
# MELプロシージャの引数
melArgs = []
append = melArgs.append
for i, t in enumerate(argTypes):
if t == "string[]":
append("string $arg%d[]" % i)
elif t == "int[]":
append("int $arg%d[]" % i)
elif t == "float[]":
append("float $arg%d[]" % i)
else:
append("%s $arg%d" % (t, i))
melArgStr = ', '.join(melArgs)
# MELプロシージャ定義
if retType:
melCmd = ('global proc %s %s(%s) { return `python(%s)`; }' %
(retType, procName, melArgStr, pyCmd))
else:
melCmd = 'global proc %s(%s) { python(%s); }' % (procName, melArgStr, pyCmd)
pm.mel.eval(melCmd) # @UndefinedVariable
自分で作っていて、何か途中からよく分からなくなってきましたが、多分動きます。
使い方
import pymel.core as pm
def myFunc(baseName, values):
return [baseName + str(v) for v in values]
makeMelProc(myFunc, "testMelProc", retType="string[]", argTypes=("string", "int[]"))
これで、グローバルプロシージャ "testMelProc" が定義されます。
各引数の意味は、makeMelProcのdocstringを参照してください。
後は、通常のMELプロシージャと同じように、MELコマンドとして呼び出してやれば、登録されたPython関数 "myFunc" が呼び出され、戻り値もMELプロシージャへと返されます。
// MELコマンドとして実行
testMelProc("test", {1, 2, 3});
// Result: test1 test2 test3 //
現状では使用出来る型に制限がありますが、それなりに実用出来る範囲かなとは思います。
というか、MEL自体複雑な戻り値とか返せませんしね。
コメント