前回の記事で、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自体複雑な戻り値とか返せませんしね。
コメント