Friday, October 1, 2010

Maya Python API (一) Motion Trace

轉換心情想要體驗一下用 Python 來寫 plug-in 的感覺,在 Maya/devkit 的目錄底下有一些 plug-in 的範例,在還沒開始之前,我稍稍的思考了一下使用 Python 來寫 plug-in 的好處或壞處有那些,這些都只是我腦中模擬的情況,實際上也許會有些出入,先說說好處,最大的好處應該是穩定,什麼是穩定呢,寫過程式的人都應該都能同意未經過測試的程式 99% 都會有 bug,小 bug 如錯誤的結果,大 bug 就會導至整個程式的當掉,

一般人使用 Maya 可能用了好幾個月都不會把 Maya 用到當掉,但開發過 plug-in 的人 (我!) 可能不到一小時就會看到好幾次的 Maya 錯誤回報視窗 (當然不能回報,因為都是自已用當的 lol ),但如果用 Python 來寫的話,這種情況應該就會大大的減低,頂多被報怨訊息給塞爆 (應該吧),印象中 script 開發的最大好處就是 exception 都被處理的很好,空指標的存取或是 out ○f index 的錯誤都不會把整個程式用當,這可能也跟寫 script 很少會用到指標有關,再來就是修改方便,壞處應該就是效能會比較低,必竟是多透過一層來執行,再來就是開發大型 plug-in 可能不是那麼好用,對於這一點,不是那麼確定,我只是直覺的想到假設一個 plug-in 由 50個 py 檔或是 50 個 cpp 檔組成,但只會有一個 mll,可是可能還是有 50 個 pyc?

OK,廢話說完了,所有的假設在沒經過實際驗證前都只是假設,第一個實驗的對象是 motionTraceCmd 這一個 plug-in,plug-in 可大可小,我個人感覺像這種 command 型的用 Python 來做似乎剛剛好,可以快速修改和測試,先選定的個帶有 animation 的物件,再執行

import pymel.core as pm
pm.mel.spMotionTrace(s=1, e=100, b=2) 

會畫出一條路徑代表物件所經過的位置,script 如下

# Initialize the script plug-in
def initializePlugin(mobject):
 mplugin = OpenMayaMPx.MFnPlugin(mobject, "Autodesk", "1.0", "Any")
 try:
  mplugin.registerCommand(kPluginCmdName, cmdCreator, syntaxCreator)
 except:
  sys.stderr.write("Failed to register command: %s\n" % kPluginCmdName)
  raise


# Uninitialize the script plug-in
def uninitializePlugin(mobject):
 mplugin = OpenMayaMPx.MFnPlugin(mobject)
 try:
  mplugin.deregisterCommand(kPluginCmdName)
 except:
  sys.stderr.write("Failed to unregister command: %s\n" % kPluginCmdName)
  raise

# Creator
def cmdCreator():
 return OpenMayaMPx.asMPxPtr(motionTrace())


# Syntax creator
def syntaxCreator():
 syntax = OpenMaya.MSyntax()
 syntax.addFlag(kStartFlag, kStartLongFlag, OpenMaya.MSyntax.kLong)
 syntax.addFlag(kEndFlag, kEndLongFlag, OpenMaya.MSyntax.kLong)
 syntax.addFlag(kByFlag, kByLongFlag, OpenMaya.MSyntax.kLong)
 return syntax

class motionTrace(OpenMayaMPx.MPxCommand):
 def __init__(self):
  OpenMayaMPx.MPxCommand.__init__(self)
  # setup private data members

 def doIt(self, args):
      省略
 def redoIt(self):
      省略


整體架構其實和用 C++ 寫還蠻類似的,就是需要定義 initializePlugin,uninitializePlugin,doIt,redoIt 等,然後如果不熟 Python 的話,可能需要對一些語法上的改變,物件的使用做一個調整,原本定義在 library 中的 function 都以 module 型式出現,例如 MPlug => OpenMaya.MPlug,MPxCommand => OpenMayaMPx.MPxCommand。

No comments: