PyMel
什么是PyMel?它是python还是mel?一个新的语言?...
也许你会这样不停的追问,Ok,现在就给你们介绍一下PyMel。
PyMel已经存在挺久的了,已经是1.00版本了,支持maya2008, 2009和2010,是一个开源项目。
其实我也一直都在关注PyMel,为什么到现在才给大家介绍呢?因为我到目前为止都没使用PyMel,但为什么现在又要介绍它呢?因为maya2011已经集成了PyMel,你根本就不需要单独安装,所以我觉得是时候使用PyMel了,也是时候给大家介绍一下了。
PyMel是Luma Pictures内部开发的,自从它问世以来的一年内就参与了很多令人映像深刻的电影和游戏项目,如:
- DreamWorks: 功夫熊猫,怪物史瑞克4,怪兽大战外星人,驯龙高手(How to Train Your Dragon,国内4月下旬上映)
- Luma Pictures: 勒比海盗3:世界的尽头,哈利·波特与混血王子,X战警前传-金刚狼
- ImageMovers Digital: 圣诞颂歌(A Christman Carol)
PyMel是一个Maya的Python模块。
PyMel项目的目标是
- 为Maya创建一个开源的Python模块
- 修复Maya的Python模块(maya.cmds和maya.mel)的bug和限制
- 让代码清晰易读
- 通过类的层次结构和子模块加强代码组织
- 通过html和内建函数help()来提供文档
我们来看看PyMel和Mel以及MayaPython的区别
Mel代码:
string $sel[] = `ls -sl`; string $shapes[] = `listRelatives -s $sel[0]`; string $conn[] = `listConnections -s 1 -d 0 $shapes[0]`; setAttr ( $conn[0] + ".radius") 3;
Python代码:
import maya.cmds as cmds sel = cmds.ls(sl=1)[0] shape = cmds.listRelatives(sel,s=1)[0] conn = cmds.listConnections(shape,s=1,d=0)[0] cmds. setAttr((conn + ".radius"),3)
Pymel代码:
from pymel import * selected()[0].getShape().inputs()[0].radius.set(3)
WO...
对于Mel用户来说可能(应该)根本看不明白,但对于十分熟悉python的用户就再熟悉不过了,或是说python的代码就应该这样写。
PyMel有很多很强大的类,Maya里的每个节点都有一个节点类,如摄像机:
Pymel代码:
camTrans, cam = camera() # 创建一个新相机 cam.setFocalLength(100) fov = cam.getHorizontalFieldOfView() cam.dolly( -3 ) cam.track(left=10) cam.addBookmark('new')
一个属性类组织所有的属性命令
Pymel代码:
#backup all mb files in the current scene's directory #备份所有的mb文件到当前场景所在的文件夹 basedir = sceneName().parent backupDir = basedir / "backup" #slash op joins paths("/"操作符代表加入路径) if not backupDir.exists: backupDir.mkdir() for file in basedir.files( '*.mb' ): print "backing up: ", file.name file.copy( backupDir / (file.namebase + ".old") )
再用长点的代码来对比一下
Mel代码:
string $objs[] = `ls -type transform`; for ($x in $objs) { print (longNameOf($x)); print "\n"; // make and break some connections connectAttr( $x + ".sx") ($x + ".sy"); connectAttr( $x + ".sx") ($x + ".sz"); disconnectAttr( $x + ".sx") ($x + ".sy"); string $conn[] = `listConnections -s 0 -d 1 -p 1 ($x + ".sx")`; for ($inputPlug in $conn) disconnectAttr ($x + ".sx") $inputPlug; // add and set a string array attribute with the history of this transform's shape if ( !`attributeExists "newAt" $x`) addAttr -ln newAt -dataType stringArray $x; string $shape[] = `listRelatives -s $x`; string $history[] = `listHistory $shape[0]`; string $elements = ""; for ($elem in $history) $elements += """ + $elem + "" "; eval ("setAttr -type stringArray " + $x + ".newAt " + `size $history` + $elements); print `getAttr ( $x + ".newAt" )`; // get and set some attributes setAttr ($x + ".rotate") 1 1 1; float $trans[] = `getAttr ($x + ".translate")`; float $scale[] = `getAttr ($x + ".scale")`; $trans[0] *= $scale[0]; $trans[1] *= $scale[1]; $trans[2] *= $scale[2]; setAttr ($x + ".scale") $trans[0] $trans[1] $trans[2]; // call some other scripts myMelScript( `nodeType $x`, $trans ); }
Python代码:
objs = cmds.ls( type= 'transform') if objs is not None: # returns None when it finds no matches for x in objs: print mm.eval('longNameOf("%s")' % x) # make and break some connections cmds.connectAttr( '%s.sx' % x, '%s.sy' % x ) cmds.connectAttr( '%s.sx' % x, '%s.sz' % x ) cmds.disconnectAttr( '%s.sx' % x, '%s.sy' % x) conn = cmds.listConnections( x + ".sx", s=0, d=1, p=1) # returns None when it finds no matches if conn is not None: for inputPlug in conn: cmds.disconnectAttr( x + ".sx", inputPlug ) # add and set a string array attribute with the history of this transform's shape if not mm.eval( 'attributeExists "newAt" "%s"' % x): cmds.addAttr( x, ln='newAt', dataType='stringArray') shape = cmds.listRelatives( x, s=1 ) if shape is not None: history = cmds.listHistory( shape[0] ) else: history = [] args = tuple( ['%s.newAt' % x, len(history)] + history ) cmds.setAttr( *args , type= 'stringArray' ) # get and set some attributes cmds.setAttr ( '%s.rotate' % x, 1, 1, 1 ) scale = cmds.getAttr ( '%s.scale' % x ) scale = scale[0] # maya packs the previous result in a list for no apparent reason trans = list( cmds.getAttr ( '%s.translate' % x )[0] ) # the tuple must be converted to a list for item assignment trans[0] *= scale[0] trans[1] *= scale[1] trans[2] *= scale[2] cmds.setAttr ( '%s.scale' % x, trans[0], trans[1], trans[2] ) mm.eval('myMelScript("%s",{%s,%s,%s})' % (cmds.nodeType(x), trans[0], trans[1], trans[2]) )
Pymel代码:
from pymel import * # safe to import into main namespace for x in ls( type='transform'): print x.longName() # object oriented design # make and break some connections x.sx >> x.sy # connection operator x.sx >> x.sz x.sx // x.sy # disconnection operator x.sx.disconnect() # smarter methods -- (automatically disconnects all inputs and outputs when no arg is passed) # add and set a string array attribute with the history of this transform's shape x.setAttr( 'newAt', x.getShape().history(), force=1 ) # get and set some attributes x.rotate.set( [1,1,1] ) trans = x.translate.get() trans *= x.scale.get() # vector math x.translate.set( trans ) # ability to pass list/vector args mel.myMelScript(x.type(), trans) # automatic handling of mel procedures
现在你应该知道为什么那么多nx的公司\工作室都用PyMel了吧,如果你想在Maya里写python脚本,那么PyMel绝对是你最好的选择。
(完。。。)
没有帐号? 立即注册