什么是
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的区别
string $sel[] = `ls -sl`;
string $shapes[] = `listRelatives -s $sel[0]`;
string $conn[] = `listConnections -s 1 -d 0 $shapes[0]`;
setAttr ( $conn[0] + ".radius") 3;
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)
from pymel import *
selected()[0].getShape().inputs()[0].radius.set(3)
WO...
对于Mel用户来说可能(应该)根本看不明白,但对于十分熟悉python的用户就再熟悉不过了,或是说python的代码就应该这样写。
PyMel有很多很强大的类,Maya里的每个节点都有一个节点类,如摄像机:
camTrans, cam = camera() # 创建一个新相机
cam.setFocalLength(100)
fov = cam.getHorizontalFieldOfView()
cam.dolly( -3 )
cam.track(left=10)
cam.addBookmark('new')
一个属性类组织所有的属性命令
s = polySphere()[0]
if s.visibility.isKeyable() and not s.visibility.isLocked():
s.visibility.set( True )
s.visibility.lock()
print s.visibility.type()
操纵文件路径更简单
#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") )
再用长点的代码来对比一下(注释我就先不翻译了,太累了要睡了)
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 );
}
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]) )
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绝对是你最好的选择。