Python 具有许多有用的内置库和数据结构。大多数情况下,可以使用一个现有的库来完成常规的编程任务,这样不必与 MEL 脚本一样创建自定义工具。可在 http://docs.python.org 中找到内置 Python 库的文档。该网站还针对常规 Python 编程提供了一个很好的初级教程。
其中一个方便的 Python 函数是 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 脚本的一个优点是可以在开发过程中使用调试器。这在解决脚本问题时可以节省大量时间。
Python 在 PDB 模块中附带一个内置的调试器。PDB 的文本界面适用于快速调试会话。如果在从“脚本编辑器”(Script Editor)调用的脚本中使用 PDB,则每当 PDB 需要输入时都会出现输入对话框。使用 PDB 与导入 PDB 并按如下方式设定断点一样简单:
import pdb pdb.set_trace()
执行达到第二行时,将显示输入对话框,您可以使用标准命令来继续、跳过、输出值等。
可以在 http://docs.python.org/library/pdb.html 上找到 PDB 的完整文档。
对于复杂调试任务,可能更易于使用外部图形调试器。存在多个免费的和商业的 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\Maya2014\Python\lib\site-packages\maya\mel
import maya.mel help(maya.mel.createMelWrapper)
以下示例说明如何使用 createMelWrapper 函数将 Python 函数注册为 MEL 程序,以便使用“asset”(以前称为 container)节点中的“鼠标右键命令”(Rmb Command)属性。
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;
可以使用以下 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()
可以在 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)
om.MUserEventMessage.postUserEvent('myEvent')
om.MUserEventMessage.removeCallback(callbackId)