Python で初めてスクリプトを記述する場合のヒントとコツ

Python ビルトイン ライブラリ

Python には、多数の便利なビルトイン ライブラリやデータ構造があります。一般的なプログラミング タスクに使用できる既存のライブラリが用意されているため、ほとんどの場合、MEL スクリプトと同様にカスタム ユーティリティを作成する必要はありません。Python のビルトイン ライブラリに関する文書は、http://docs.python.org を参照してください。このサイトには、一般的な Python プログラミングの入門ガイドとして適したチュートリアルも提供されています。

Python クラスを使用したカスタム UI

使いやすい 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()

Maya で Python スクリプトをデバッグする

任意のデバッガを使用して、Python スクリプトをデバッグできます。Eclipse や Wing IDE など、いくつかの IDE には独自のデバッガが付属しています。これらは、スクリプトのデバッグに便利なグラフィカル インタフェースを備えています。デバッグセッションを開始する方法については、該当する IDE のドキュメントを参照してください。

Python には独自のビルトイン デバッガ pdb も付属しています。pdb にはテキスト インタフェースがあり、スクリプト エディタ(Script Editor)のスクリプト内から直接呼び出すことができます。pdb モジュールを読み込み、pdb.set_trace() を使用してブレークポイントを設定する必要があります。

import pdb
pdb.set_trace()

実行が pdb.set_trace() に達すると、入力ダイアログが表示されます。標準コマンドを使用して、続行、ステップイン、値の出力、その他のデバッグ操作を行うことができます。pdb が入力を必要とする場合は、常に入力ダイアログ ボックスが表示されます。

pdb の使用方法の詳細については、「Python デバッガ」を参照してください。

Python 関数を MEL プロシージャとして登録する

createMelWrapper 関数を使用して、Python 関数を MEL プロシージャとして登録することができます。次に、MEL プロシージャをコールすると、Python 関数をコールし、これが受け取る引数を渡して関数の結果を返します。

この関数の詳細については、Maya のインストール ディレクトリの ..¥Python¥lib¥site-packages¥maya¥mel フォルダ内にある melutils.py ファイルを参照してください。

または、スクリプト エディタ(Script Editor)で以下を実行します。

import maya.mel
help(maya.mel.createMelWrapper)

この関数の利点:

次の例は、createMelWrapper 関数を使用して Python 関数を MEL プロシージャとして登録し、Rmb コマンド(Rmb Command)アトリビュートを asset ノード(以前の container ノード)で使用する方法を示しています。

  1. プリファレンス フォルダの scripts ディレクトリに rmbScript.py として保存します。
    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")
    
  2. スクリプト エディタ(Script Editor)の Python タブから以下を実行します。これによって、必要な MEL ラッパ(wrapper)スクリプトが作成されます。
    from rmbScript import *
    import maya.cmds as cmds
    import maya.mel as mel
    mel.createMelWrapper(rmbMyContainerScript,retType='string[]')
    mel.createMelWrapper(exCoNotes)
    mel.createMelWrapper(setThisContainerCurrent)
    
  3. オブジェクトを作成します。
  4. アセット > 高度なアセット > 作成(Assets > Advanced Assets > Create)を選択して、rmbMyContainerScript を asset の Rmb コマンド(Rmb Command)アトリビュートに追加します。
    注:

    このて銃手順は、トランスフォームを含むアセットにも使用できます。ただし、ノード タイプは dagContainer になります。

  5. 以下のコードと同様のものを、asset ノードの注(Notes)セクションに追加します。
    def main(node, container):
        print node
        print container
    
  6. スクリプト エディタ(Script Editor)で MEL タブに以下を入力します。
    rehash;
    
  7. オブジェクトを右クリックして、マーキング メニューからカスタム(Custom)を選択します。これで、カスタムの右マウス ボタン メニューが表示されるようになります。詳細については、「カスタム コマンドまたはメニューをアセットに割り当てる」を参照してください。

アニメートしたカーブのキーフレームの作成

Python のサンプル スクリプトを使用して、アニメートしたカーブを作成してキーフレームを設定することができます。

import maya.OpenMaya as om
import maya.OpenMayaAnim as oma
def addkeys(plugName, times, values, changeCache):
   # Get the plug to be animated.
   sel = om.MSelectionList()
   sel.add(plugName)
   plug = om.MPlug()
   sel.getPlug(0, plug)
   # Create the animCurve.
   animfn = oma.MFnAnimCurve()
   animCurve = animfn.create(plug, oma.MFnAnimCurve.kAnimCurveTL)
   
   # Copy the times into an MTimeArray and the values into an    MDoubleArray.
   timeArray = om.MTimeArray()
   valueArray = om.MDoubleArray()
   for i in range(len(times)):
      timeArray.append(om.MTime(times[i], om.MTime.uiUnit()))
      valueArray.append(values[i])
   # Add the keys to the animCurve.
   animfn.addKeys(
      timeArray,
      valueArray,
      oma.MFnAnimCurve.kTangentGlobal,
      oma.MFnAnimCurve.kTangentGlobal,
      False,
      changeCache
   )

上記のサンプル コードでチャネルにキーフレーム アニメーション(つまりプラグ)が追加されます。変更内容を元に戻す必要がまったくない場合は、以下のようにコールします。

addkeys('pCube1.tx', [1.0, 3.0, 5.0], [0.6, 1.2, 2.4], None)

ただし、変更内容を元に戻せるようにしておく場合は、以下のようにコールします。

changeCache = oma.MAnimCurveChange()
addkeys('pCube1.tx', [1.0, 3.0, 5.0], [0.6, 1.2, 2.4], changeCache)

変更内容を元す場合は、以下の手順を実行します。

changeCache.undoIt()
注:

ここではわかりやすくするために、plugName で指定したプラグは現在アニメートされていないものとします。これは練習問題用で、この条件を不要にするために必要なチェックを追加することもできます。

一般的な情報メッセージ

dgInfo コマンドを使用して DG に関する情報を入手する場合、DIRTY BLOCK、DIRTY PROP といった情報メッセージが表示されることがあります。

ScriptJob を使用してユーザ イベントを作成する

これは、Python スクリプトで、API コールを使用して行うことができます。以下の例は、myEvent という新しいユーザ イベント タイプを登録する方法を示します。

import maya.OpenMaya as om
om.MUserEventMessage.registerUserEvent('myEvent')

イベントが発生するたびに myFunc という関数が実行されるようにするには、次を実行します。

def myFunc(data):
    print('Got a myEvent event!')
callbackId = om.MUserEventMessage.addUserEventCallback('myEvent', myFunc)

myEvent イベントを送信するには、次を実行します。

om.MUserEventMessage.postUserEvent('myEvent')

終了後にコールバック関数を除去するには、次を実行します。

om.MUserEventMessage.removeCallback(callbackId)