Maya command代码段

动画相关

获取物体有多少个关键帧

cmds.keyframe(name, q=True, keyframeCount=True)

获取物体第一个动画帧帧数

cmds.findKeyframe(name, which='first')

获取物体最后一个动画帧帧数

cmds.findKeyframe(name, which='last')

修复乱轴曲线

cmds.filterCurve(name_list)

复制粘贴单个指定属性动画

1
2
3
# 这里是复制摄像机焦距动画
cmds.copyKey(cam, at='fl')
cmds.pasteKey(dup_cam, at='fl')

显示层

设置显示层的颜色

1
2
3
cmds.setAttr(layerName+'.color', index)
cmds.setAttr(dag+'.overrideEnabled', True)
cmds.setAttr(dag+'.overrideColor', index)

列出跟物体连接的显示层

cmds.listConnections(dag, s=True, t='displayLayer')

物体对象

求不规则物体的长宽高

1
2
3
4
box = cmds.exactWorldBoundingBox(cmds.ls(sl=1))
width_x = box[3] - box[0]
height_y = box[4] - box[1]
depth_z = box[5] - box[2]

创建一条曲线

1
2
3
# 需提供一个点位置列表
position = cmds.xform(obj, q=True, t=True, worldSpace=True)
cmds.curve(p=position, d=True)

求曲线长度

cmds.arclen(curve)

根据两条曲线创建模型

1
2
cmds.nurbsToPolygonsPref(f=3)
cmds.loft(curve1, curve2, ch=0, d=1, po=1, rsn=1, name=name+'_path')

获取物体属性列表

1
2
cmds.findKeyframe(obj, curve=True)
cmds.listAttr(obj, k=True, u=True)

获取选中模型点的位置

1
2
sel_vtx = cmds.ls(sl=1)
vtx_position = cmds.pointPosition(sel_vtx)

获取Group下所有mesh类型

1
2
3
4
5
6
maya.cmds.listRelatives(cmds.ls(sl=1)[0],
allDescendents=True,
noIntermediate=True,
fullPath=True,
type="mesh",
path=True)

视图

获取拍屏激活的视图名

1
2
cmds.playblast(activeEditor=True)
cmds.playblast(activeEditor=True).split('|')[-1] # 得到实际名称

命名空间

获取命名空间列表

namespace_list = cmds.namespaceInfo(recurse=True, listOnlyNamespace=True)

删除指定的命名空间

cmds.namespace(moveNamespace=(':' + namespace_list[-1], ':'), force=True)

摄像机

为摄像机添加素材

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 1.得到摄像机的名字和形状节点
cam = cmds.ls(sl=1)[0], camShape = listRelatives(cam, s=1)[0]

# 2.得到指定物所有连接节点的列表
image_plane = cmds.listConnections(camShape, t='imagePlane')

# 3.检查是否有image节点,如果没有创建
if image_plane:
imp = image_plane[0]
else:
imp = cmds.shadingNode('imagePlane', asUtility=True)

# 4.连接属性到摄像机
cmds.connectAttr(imp + '.message', camShape + '.imagePlane', nextAvailable=True)
cmds.imagePlane(imp, edit=True, camera=camShape)

# 5.素材指定给摄像机, 开启素材帧序列动画
cmds.setAttr(imp+ '.imageName', image_seq, tyoe='string')
cmds.setAttr(imp + '.useFrameExtension', True)

摄像机额外属性设置

1
2
3
4
5
6
7
8
9
10
cmds.setAttr(imp+'.lockedToCamera', 1)
cmds.setAttr(imp+'.sizeX', cmds.getAttr(camShape+'.horizontalFilmAperture'))
cmds.setAttr(imp+'.sizeY', cmds.getAttr(camShape+'.verticalFilmAperture'))
cmds.setAttr(imp+'.width', cmds.getAttr(camShape+'.orthographicWidth'))
cmds.setAttr(imp+'.height', cmds.getAttr(camShape+'.orthographicHeight'))
cmds.setAttr(imp+'.depth', 5000)
cmds.setAttr(imp+'.displayOnlyIfCurrent', True)
cmds.setAttr(imp+'.displayMode', 2)
cmds.setAttr(imp+'.frameCache', seq_time+50)
cmds.setAttr(imp+'.fit', 4)

为摄像机创建地平线

1
2
3
4
5
6
horizon = cmds.circle(normal=(0,1,0), name='horizon_curve1', constructionHistory=False)[0]
cmds.pointConstraint(cam, horizon)
cmds.addAttr(horizon, longName='camera', attributeType='message')
cmds.setAttr(horizon + '.overrideEnabled', True)
cmds.setAttr(horizon + '.overrideColor', 16)
cmds.connectAttr(cam + '.message', horizon + '.camera')

操作

记录撤销操作还原

1
2
cmds.undoInfo(openChunk=True)
cmds.undoInfo(closeChunk=True)

窗口

打印出maya中所有窗口名称和类型

1
2
3
4
5
from PySide2 import QtWidgets

all_ui = {w.objectName(): w for w in QtWidgets.QApplication.allWidgets()}
for k,v in all_ui.items():
print k, v.__class__

给Maya添加一个全局按钮

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import maya.OpenMayaUI as omUI
from PySide2 import QtCore, QtGui, QtWidgets
import shiboken2,time
from functools import partial

def getMayaWindow():
ptr = omUI.MQtUtil.mainWindow()
return shiboken2.wrapInstance(long(ptr), QtWidgets.QMainWindow)

class Project_Display:
def __init__(self):
self.mayaWin = getMayaWindow()

def myShow(self):
self.projectBtn = QtWidgets.QPushButton(self.mayaWin)
self.projectBtn.setGeometry(QtCore.QRect(500, 210, 100, 23))
self.projectBtn.setObjectName("pushButton")
self.projectBtn.setText( "PushButton")
self.projectBtn.clicked.connect(lambda *args: self.test1())
self.projectBtn.show()

def test1(self):
print 'test'

def main():
aa = Project_Display()
aa.myShow()
main()

PySide2 例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import maya.cmds as cmds
from PySide2 import QtWidgets as QtGui
from shiboken2 import wrapInstance
import maya.OpenMayaUI as omui

DIALOGNAME = "My Dialog"

def getMayaMainWin():
pointer = omui.MQtUtil.mainWindow()
return wrapInstance(long(pointer), QtWidgets.QMainWindow)

mayaWindow = getMayaMainWin()
mayaWindow.setWindowOpacity(1)

class MyDialog(QtGui.QDialog):
def __init__(self, parent=None):
super(MyDialog, self).__init__(parent)
layout = QtWidgets.QVBoxLayout()
copy_bt = QtWidgets.QPushButton('Copy')
paste_bt = QtWidgets.QPushButton('Paste')
layout.addWidget(copy_bt)
layout.addWidget(paste_bt)
self.setLayout(layout)

self._initUI()

def _initUI(self):
self.setObjectName(DIALOGNAME)

if __name__ == "__main__":
if cmds.window(DIALOGNAME, exists=True, query=True):
cmds.deleteUI(DIALOGNAME)

dialog = MyDialog(parent=mayaWindow)
dialog.show()

环境和配置

获取maya预设路径

1
2
import os
_dir = os.environ.get('MAYA_APP_DIR')

阿诺德渲染设置

1
2
3
4
5
6
7
8
9
10
11
12
mc.setAttr('defaultRenderGlobals.currentRenderer', 'arnold', typ='string')
mtoa.core.createOption()

mc.setAttr('defaultArnoldRenderOptions.AASamples', 4)
mc.setAttr('defaultArnoldRenderOptions.GIDiffuseSamples', 4)
mc.setAttr('defaultArnoldRenderOptions.GISpecularSamples', 2)
mc.setAttr('defaultArnoldRenderOptions.GITransmissionSamples', 2)
mc.setAttr('defaultArnoldRenderOptions.GISssSamples', 8)
mc.setAttr('defaultArnoldRenderOptions.GIVolumeSamples', 2)
mc.setAttr('defaultArnoldRenderOptions.lock_sampling_noise', 1)
mc.setAttr('defaultArnoldRenderOptions.use_sample_clamp', 1)
mc.setAttr('defaultArnoldRenderOptions.AASampleClamp', 5)