Python には、多数の便利なビルトイン ライブラリやデータ構造があります。一般的なプログラミング タスクに使用できる既存のライブラリが用意されているため、ほとんどの場合、MEL スクリプトと同様にカスタム ユーティリティを作成する必要はありません。Python のビルトイン ライブラリに関する文書は、http://docs.python.org を参照してください。このサイトには、一般的な Python プログラミングの入門ガイドとして適したチュートリアルも提供されています。
使いやすい Python 関数の 1 つに functools.partial があり、これを使用するとコールバック関数に追加情報を渡すことができます。たとえば、次のクラスでは、クリックすると番号が出力されるボタンをいくつか含むウィンドウが作成されます。
from functools import partial
import maya.cmds as cmds
class ButtonWin(object):
def __init__(self):
self.win = cmds.window()
self.layout = cmds.columnLayout(parent=self.win)
for x in range(10):
cmds.button(label="Click Here %d"%x, parent=self.layout, command=partial(self.report,x))
cmds.showWindow()
def report(self,buttonIndex,value):
print "button %d got %s"%(buttonIndex,value)
f = ButtonWin()
Python スクリプトの利点の 1 つに、開発段階でデバッガとして利用にできることが挙げられます。これによって、スクリプティングのトラブルシューティング時間を大幅に削減できます。
Python では、pdb モジュール内にビルトイン デバッガが装備されています。pdb には、クィック デバッグ セッションに適したテキスト インタフェースがあります。スクリプト エディタ(Script Editor)からコールされたスクリプトで pdb を使用すると、pdb で入力が必要な場合には必ず入力ダイアログボックスが表示されます。pdb の使用方法はシンプルであり、次のようにインポートしてブレークポイントを設定します。
import pdb
pdb.set_trace()
2 行目まで実行すると入力ダイアログが表示されるので、標準コマンドを使用して作業を続行し、ステップイン、値の出力などを行います。
pdb に関する詳細文書は、http://docs.python.org/library/pdb.html を参照してください。
複雑なデバッグ タスクの場合は、外部のグラフィカル デバッガを使用するほうが簡単でしょう。無償または市販の IDE には、以下のようなものがあります。
外部デバッガを使用して Maya に初めてユーティリティ モジュールをインポートすると、IDE への通信ソケットが開きます。IDE が Maya に接続されたら、スクリプト ファイルを開いてブレークポイントの設定や変数値の検査などができます。IDE ごとに独自に必要なワークフローがあります。詳細については、それぞれのマニュアルを参照してください。
Windows で Wing IDE 3.1 を使用して Maya Python スクリプトのデバッグ セッションを開始するには、以下の操作を実行します。
import wingdbstub
createMelWrapper 関数を使用して、Python 関数を MEL プロシージャとして登録することができます。次に、MEL プロシージャをコールすると、Python 関数をコールし、これが受け取る引数を渡して関数の結果を返します。
この関数の詳細については、次の場所にある melutils.py ファイルを参照してください。
C:\Program Files\Autodesk\Maya2010\Python\lib\site-packages\maya\mel
または、スクリプト エディタ(Script Editor)で以下を実行します。
import maya.mel
help(maya.mel.createMelWrapper)
次の例は、createMelWrapper 関数を使用して Python 関数を MEL プロシージャとして登録し、Rmb コマンド(Rmb Command)アトリビュートを container ノードで使用する方法を示しています。
import maya.cmds as cmds
import maya.mel as mel
def exCoNotes(node):
if(cmds.nodeType(node)=='container'):
objCont = node
else:
objCont = cmds.container(q=True, findContainer=node)
exec(cmds.getAttr(objCont+'.notes'))
pyfunction = 'main("'+node+'","'+objCont+'")'
exec(pyfunction)
cmds.select(node, r=True)
def setThisContainerCurrent(node):
if(cmds.nodeType(node)=='container'):
objCont = node
else:
objCont = cmds.container(q=True, findContainer=node)
cmds.container(objCont, e=True, c=True)
cmds.select(node, r=True)
def rmbMyContainerScript():
return ("Execute Container Notes", "exCoNotes",
"Set This Container Current", "setThisContainerCurrent")
from rmbScript import *
import maya.cmds as cmds
import maya.mel as mel
mel.createMelWrapper(rmbMyContainerScript,retType='string[]')
mel.createMelWrapper(exCoNotes)
mel.createMelWrapper(setThisContainerCurrent)
def main(node, container):
print node
print container
rehash;