4000-520-616
欢迎来到免疫在线!(蚂蚁淘生物旗下平台)  请登录 |  免费注册 |  询价篮
主营:原厂直采,平行进口,授权代理(蚂蚁淘为您服务)
咨询热线电话
4000-520-616
当前位置: 首页 > 新闻动态 >
新闻详情
dcc python - CSDN
来自 : CSDN技术社区 发布时间:2021-03-25

MY BLOG DIRECTORY:

YivanLee:专题概述及目录​zhuanlan.zhihu.com\"图标\"

INTRODUCTION:

对于天天使用C++的人来说,学习和使用Maya脚本我觉得完全就像砍瓜切菜一般容易,唯一的难点在于记各种API以及熟练度上。下面我将记录一些maya里的脚本代码,也方便我日后Ctrl+C/V,我觉得三个小时学会Maya python脚本编程完全足够了。

C++派系出身的人写python的时候需要注意以下几点:

(1)请忘记类型这个概念,python中一切皆对象

(2)‘=’不是赋值,而是绑定一个名字

FORWARD DECLARATION:

下面是文章内容目录:

Maya scripting basic conceptsCreate a polyMove, Scale, RotateCreate instanceLoop Create InstanceRandom positionHide ObjectGroup ObjectsReset pivotSelect ObjectsObject TypeCreate ConstraintAnimation key operationsCreate a window UIAdd UI Elements Into WindowAdd/Get/Set AttributeReconstruct Name StringAdd ExpressionCreate a file or read write itGet vertex array in mesh object modeWrite Vertex Data into fileSave the file to the specified location and call out the selection path windowSave maya fileSnap shotLoop search Children or parent

MAIN CONTENT:

【1】Maya scripting basic concepts

在开始Maya编程之前一定要知道的是Maya的设计思想就是节点式。

\"v2-c7e9080940b8698a3f20a241c0e554b1_b.jpg\"

这个和Unity很类似,一个Transform下面装一个Shape,Transform节点里包含了物体的位置,缩放,旋转等信息。ShapeNode里包含了顶点,UV等模型形状信息。

Transform:

\"v2-732b2fa68580424b79ffdc1a37c96379_b.jpg\"

Shape:

\"v2-66740ff14120a1c281f1faeb3c48ea32_b.jpg\"

而一个Cube就是一个表,拿场景中的盒子为例

\"Cube


【2】Create a poly

import maya.cmds as cmdcubeList = cmd.ls(\'myCube\')if len(cubeList) 0: cmd.delete(cubeList)pCube = cmd.polyCube(w = 10, h = 10, d = 10, name = \'myCube\')
\"v2-cd1d6552f394b8c4686b3a049bb6dce4_b.jpg\"

首先导入Maya的cmd然后从场景里找到是否存在一个叫myCube的Node列表。如果这个列表有长度,说明这个Cube已经创建了,需要先删除它然后重新创建。polyCube这个返回的是一个列表

\"Cube

创建求或者其它图形同理:

pCube = cmd.polyCube(w = 10, h = 10, d = 10, name = \'myCube\')pSphere = cmd.polySphere(sx = 10, sy = 10, r = 5, name = \'mySphere\')pCylinder = cmd.polyCylinder(sx = 10, sy = 15, sz = 5, r = 5, h = 10, name = \'myCylinder\')pPolyTorus = cmd.polyTorus(r = 10, sr = 1, sx = 20, sy = 4, name = \'myTorus\')

ls方法可以拿到Maya场景里的Node,并且把它存到一个列表里返回。因为Maya中物体的名字是唯一的所以上述代码是通过名字来拿物Node的。还可以通过物体类型来拿场景中的某一类物体,还可以通过选择列表拿物体,这些后面有论述。


【3】Move, Scale, Rotate

import maya.cmds as cmdpCube = cmd.polyCube(w = 10, h = 10, d = 10, name = \'myCube\')cmds.move(0, 10, 0, pCube)cmds.scale(2, 2, 2, pCube)cmds.rotate(45, 45, 0, pCube)
\"v2-afdf78a96eda8d61099eca4d23a74647_b.jpg\"

也可以使用xform来设置一个transform node的属性。


【4】Create instance

import maya.cmds as cmdpCube = cmd.polyCube(w = 10, h = 10, d = 10, name = \'myCube\')pCubeTransform = pCube[0]pCUbeIns = cmd.instance(pCubeTransform, name = pCubeTransform + \'_Instance\')
\"v2-641531da578f542d51c377f64351c05c_b.jpg\"


【5】Loop Create Instance

import maya.cmds as cmdpCube = cmd.polyCube(w = 10, h = 10, d = 10, name = \'myCube\')pCubeTransform = pCube[0]for i in range(0, 50): pCubeIns = cmd.instance(pCubeTransform, name = pCubeTransform + \'_Instance\' + str(i)) cmd.move(0, 10 * i, 0, pCubeIns)
\"v2-1858d744b461732fa3ccebf2049cc26a_b.jpg\"


【6】Random position

import maya.cmds as cmdimport randomrandom.seed(1234)pCube = cmd.polyCube(w = 10, h = 10, d = 10, name = \'myCube\')pCubeTransform = pCube[0]for i in range(0, 50): x = random.uniform(-100, 100) y = random.uniform(0, 100) z = random.uniform(-100, 100) pCubeIns = cmd.instance(pCubeTransform, name = pCubeTransform + \'_Instance\' + str(i)) cmd.move(x, y, z, pCubeIns)
\"v2-a03845707187d169a84baee2b3203784_b.jpg\"


【7】Hide Object

import maya.cmds as cmdpCube = cmd.polyCube(w = 10, h = 10, d = 10, name = \'myCube\')cmds.hide(pCube)


【8】Group Objects

import maya.cmds as cmdimport randomrandom.seed(1234)pCube = cmd.polyCube(w = 10, h = 10, d = 10, name = \'myCube\')pCubeTransform = pCube[0]instGroup = cmd.group(empty = True, name = \'myInstGroup\')for i in range(0, 50): x = random.uniform(-100, 100) y = random.uniform(0, 100) z = random.uniform(-100, 100) pCubeIns = cmd.instance(pCubeTransform, name = pCubeTransform + \'_Instance\' + str(i)) cmd.parent(pCubeIns, instGroup) cmd.move(x, y, z, pCubeIns)
\"v2-a0498bddfc6943856f2d1b003500cef4_b.jpg\"


【9】Reset pivot

import maya.cmds as cmdimport randomrandom.seed(1234)pCube = cmd.polyCube(w = 10, h = 10, d = 10, name = \'myCube\')pCubeTransform = pCube[0]instGroup = cmd.group(empty = True, name = \'myInstGroup\')for i in range(0, 50): x = random.uniform(-100, 100) y = random.uniform(0, 100) z = random.uniform(-100, 100) pCubeIns = cmd.instance(pCubeTransform, name = pCubeTransform + \'_Instance\' + str(i)) cmd.parent(pCubeIns, instGroup) cmd.move(x, y, z, pCubeIns)cmd.xform(instGroup, centerPivots = True)
\"v2-b9caf3a41502a437e24e812507eef402_b.jpg\"


【10】Select Objects

选择在Maya里要分为两部分作用,一个是从选择里获取,一个是把数据设置给当前选择的东西。

要想从外界传数据进脚本,方法之一就是从maya的选择列表里拿物体数据

import maya.cmds as cmdselectObjectList = cmd.ls(orderedSelection = True)print selectObjectList
\"v2-79333da04a0827497f948592d7145275_b.jpg\"

或者也可以使用,有一个fl标志用于展平列表。

selectObjectList = cmd.ls(selection = True)
\"v2-9b66702ec2bbded3275f1617535adeec_b.jpg\"

把属性设置给选择的物体,这时我们需要手动调用select命令,因为有写操作是只能对选择物体生效的,所以在执行这些操作之前需要在代码里先选中这个物体。如果场景里面有个pSphere1物体

import maya.cmds as cmdcmd.select(\'pSphere1\')

清除空选择列表:

import maya.cmds as cmdcmd.select(clear = True)

加选

import maya.cmds as cmdcmd.select(\'pSphere1\')cmd.select(\'pSphere2\', add = True)


【11】Object Type

import maya.cmds as cmdselectObjectList = cmd.ls(selection = True)for obj in selectObjectList: objType = cmd.objectType(obj) print objType
\"v2-3920bbe9dd7fef48650e03c5c198c152_b.jpg\"

在选择物体的时候可以加上Type作为过滤器

\"v2-ed0e4d7c8f60ae79582cb6d1d5e79c02_b.jpg\"
import maya.cmds as cmdselectObjectList = cmd.ls(selection = True, type = \'transform\')for obj in selectObjectList: objType = cmd.objectType(obj) print objType

还可以通过Type拿到场景中全部的模型

allMeshInScene = cmds.ls(type=\'mesh\')


【12】Create Constraint

import maya.cmds as cmdselectObjectList = cmd.ls(orderedSelection = True)if len(selectObjectList) =2: target = selectObjectList[0] object = selectObjectList[1] cmd.aimConstraint(target, object, aimVector = [0, 1, 0])
\"v2-9efb6ea658592dbfd94ba210ce1093b6_b.jpg\"\"v2-d204f09d4cd6ff97868a4c5b471f7d24_b.gif\"

如果为一群物体创建aimConstraint可以得到如下效果:

import maya.cmds as cmdselectObjectList = cmd.ls(orderedSelection = True)if len(selectObjectList) =2: target = selectObjectList[0] selectObjectList.remove(target) for object in selectObjectList: cmd.aimConstraint(target, object, aimVector = [0, 1, 0])
\"v2-467ed3f3bf1abaab2337f47cc77a95e4_b.gif\"

确保Target是第一个被选中的即可。


【13】Animation key operations

import maya.cmds as cmdselectObjectList = cmd.ls(selection = True, type = \'transform\')if len(selectObjectList) = 1: startTime = cmd.playbackOptions(query = True, minTime = True) endTime = cmd.playbackOptions(query = True, maxTime = True) for obj in selectObjectList: cmd.cutKey(obj, time = (startTime, endTime), attribute = \'rotateY\') cmd.setKeyframe(obj, time = startTime, attribute = \'rotateY\', value = 0) cmd.setKeyframe(obj, time = endTime, attribute = \'rotateY\', value = 360) cmd.selectKey(obj, time = (startTime, endTime), attribute = \'rotateY\', keyframe = True) cmd.keyTangent(inTangentType = \'linear\', outTangentType = \'linear\')
\"v2-cf4055d6822c5b48c1c6c1b19fcddcf3_b.jpg\"

cmd.selectKey会先选中一段时间内的关键帧的的某些属性,然后调用cmd.keyTangent。这个函数会对我们选中的属性进行修改。


【14】Create a window UI

import maya.cmds as cmddef createWindow(pWindowTitle): windowID = \'myWindowID\' if cmd.window(windowID, exists = True): cmd.deleteUI(windowID) cmd.window(windowID, title = pWindowTitle, sizeable = False, resizeToFitChildren = True) cmd.showWindow()createWindow(\'MyWindow\')
\"v2-c471d018dec7e108bfe7e5e5a515d75d_b.jpg\"


【15】Add UI Elements Into Window

创建一个窗口以后需要往里面加一些控件,但是在加空间之前需要先对Window进行布局

\"v2-0ef1a1781b62e0932be1752c0c52d490_b.jpg\"
import maya.cmds as cmddef createWindow(pWindowTitle): windowID = \'myWindowID\' if cmd.window(windowID, exists = True): cmd.deleteUI(windowID) cmd.window(windowID, title = pWindowTitle, sizeable = False, resizeToFitChildren = True) cmd.rowColumnLayout(numberOfColumns = 3, columnWidth = {(1, 75), (2, 60), (3, 60)}) cmd.text(label = \'my text one\') cmd.text(label = \'my two\') cmd.text(label = \'my three\') cmd.text(label = \'my text Four\') cmd.intField(\'pIntInput\') cmd.separator(h = 10, style = \'none\') cmd.intField(\'pIntInput2\') cmd.showWindow()createWindow(\'MyWindow\')

rowColumnLayout命令会对窗口进行布局切割numberOfColumns = 3表示横向切三刀,控件会从左往右依次填充,如果横排填满了就自动换行继续填充。

\"v2-d0916bcb0b76813c19ce11ac25e29692_b.jpg\"

创建按钮回调函数

import maya.cmds as cmdsdef create_window(): if cmds.window(\'mywindow\', exists = True): cmds.deleteUI(\'mywindow\') windowvar = cmds.window(\'mywindow\') cmds.columnLayout() cmds.text(label = \'this is my window\') cmds.textField(\'pStatementInput\') cmds.floatField(\'pFloatInput\') cmds.intField(\'pIntInput\') cmds.button(label = \'print statement\', command = \'printFunction()\') cmds.showWindow(\'mywindow\')def printFunction(): pStatement = cmds.textField(\'pStatementInput\', q = True, text = True) pInt = cmds.intField(\'pIntInput\', q = True, value = True) pFloat = cmds.floatField(\'pFloatInput\', q = True, value = True) print(pStatement + str(pInt) + str(pFloat))create_window()



【16】Add/Get/Set Attribute

import maya.cmds as cmdselectObjectList = cmd.ls(selection = True)if len(selectObjectList) = 1: cmd.addAttr(longName = \'NewAttri\', shortName = \'NewA\', attributeType = \'double\', min = 0, max = 100, defaultValue = 100, keyable = True)
\"v2-d0344731ef7626e5e212b2274b901e24_b.jpg\"

获取Attribute的方式如下

\"v2-d1b0c2ddfebf8b2ca272a5b34ed9c5f1_b.jpg\"
import maya.cmds as cmdsMeshList = cmds.ls(sl = True, o = True)Mesh = MeshList[0]Loc = cmds.getAttr(\'%s.translate \' % (Mesh))print Loc

设置方法如下

import maya.cmds as cmdsMeshList = cmds.ls(sl = True, o = True)Mesh = MeshList[0]cmds.setAttr(\'%s.translateX\' % (Mesh), 10)


【17】Reconstruct Name String

import maya.cmds as cmdselectObjectList = cmd.ls(selection = True)objName = \'%s.name\' % selectObjectList[0]print objName
\"v2-adfaa11dff1d05292ffb1c27e6ed42ce_b.jpg\"


【18】Add Expression

\"v2-6901a44f6ea87183fb15f39509180300_b.jpg\"
import maya.cmds as mcmc.expression( s = \'pSphere1.translateX = cos(time/2)*10\' )

在Maya中甚至可以给一个物体的一个属性在脚本里给它加上表达式,s是表达式的值,是字符串。time变量直接能获取滑杆的时间。


【19】Create a file or read write it

\"v2-689726245b26df4a9a53818fef66008d_b.jpg\"
import maya.cmds as mcpathToSave = \'D:\\File\'createTextFile = open(pathToSave + \'aaa.txt\', \'w\')

可以多次调用write函数书写

\"v2-fc7475bc62eb2e65081bf7e8f3ad05db_b.jpg\"

最后close这个文件解除占用即可

import maya.cmds as mcpathToSave = \'D:/\'createdTextFile = open(pathToSave + \'bbb.txt\', \'w\')createdTextFile.write(\'this is my file\\n\')createdTextFile.write(\'this is maya python\\n\')createdTextFile.close()

读取文件也很简单

import maya.cmds as mcpathToSave = \'D:/\'createdTextFile = open(pathToSave + \'bbb.txt\', \'w\')createdTextFile.write(\'this is my file\\n\')createdTextFile.write(\'this is maya python\\n\')createdTextFile.close()readFile = open(pathToSave + \'bbb.txt\', \'r\')textVal = readFile.read()print textValreadFile.close()
\"v2-83165a95004c6b697029963f4e364b09_b.jpg\"


【20】Get vertex array in mesh object mode

上面的几个例子中都是在物体的顶点模式下先选中所有顶点完成的,下面通过脚本直接在顶层Node情况下访问顶点数组

\"v2-cacb3641ba99e1e2edf177f3e33bab42_b.jpg\"
import maya.cmds as cmdsMeshList = cmds.ls(sl = True, o = True)Mesh = MeshList[0]VertexArray = cmds.ls(\'{}.vtx[:]\'.format(Mesh), fl = True)cmds.move(0, 20, sel_vtx[0])


【21】Write Vertex Data into file

在Maya中获取资源的数据实在太简单了,在引擎里想获得一点模型数据简直麻烦到爆炸。在maya中我们能轻松获取到我们想要的数据并且写入文件,这些数据我们可以到引擎去读取它们,这为我们写工具和自定义文件格式提供了方法。

\"v2-2dd07c25cbd3c04e461e5099b2782699_b.jpg\"
import maya.cmds as cmdvertexes = cmd.ls(selection = True, fl = True)File = open(\'D:/MyFile.txt\', \'w\')for vet in vertexes: pos = cmd.xform(vet, query = True, translation = True, worldSpace = True) File.write(str(pos) + \'\\n\')File.close() 

这里要开启flatten标志,这是为了让列表中的元素全部都有数值被初始化。

对代码稍作美化:

\"v2-3f6212b2d557dfdbf25f511f048771b3_b.jpg\"
import maya.cmds as cmdMeshList = cmd.ls(selection = True, o = True)Mesh = MeshList[0]File = open(\"C:\\Users\\Yivanlee\\Desktop/test.txt\", \'w\')VertexArray = cmds.ls(\'{}.vtx[:]\'.format(Mesh), fl = True)for Vert in VertexArray: pos = cmd.xform(Vert, query = True, translation = True, worldSpace = True) X = str(pos[0]) Y = str(pos[1]) Z = str(pos[2]) File.write(X + \",\" + Y + \",\" + Z + \"\\n\")File.close()

ls的oflag是objectsOnly,当 objectsOnly打开时,只有物体的名字会被返回。物体的Components和Attribute都会被忽略


【22】Save the file to the specified location and call out the selection path window

\"v2-e27589d3926b9ccb0d8a212dafc7fd63_b.jpg\"
import maya.cmds as cmdMeshList = cmd.ls(selection = True, o = True)Mesh = MeshList[0]FilePath = \"\"FileFilter = \"*.txt\"FilePath = cmd.fileDialog2(fileFilter = FileFilter, dialogStyle = 2)File = open(FilePath[0], \'w\')VertexArray = cmds.ls(\'{}.vtx[:]\'.format(Mesh), fl = True)for Vert in VertexArray: pos = cmd.xform(Vert, query = True, translation = True, worldSpace = True) X = str(pos[0]) Y = str(pos[1]) Z = str(pos[2]) File.write(X + \",\" + Y + \",\" + Z + \"\\n\")File.close()



【23】Save maya file

import maya.cmds as cmdscmds.file(rename=\"C:/Users/Temp/Desktop/test.ma\")cmds.file(save=True, type=\"mayaAscii\")


【24】Snap shot

\"v2-e00c0aa88aa04b92204f200ee305bcc4_b.jpg\"
import maya.cmds as cmdcmds.sphere(n=\'sphere1\')cmds.currentTime(\'0\')cmds.setKeyframe(\'.t\')cmds.currentTime(\'30\')cmds.move(10,0,1)cmds.setKeyframe(\'.t\')cmds.snapshot( \'sphere1\', constructionHistory=True, startTime=0, endTime=30, increment=10 )

俗称快照,可以用于追踪顶点动画的每帧数据。顶点动画烘焙到纹理插件需要用到这个功能。


【25】Loop search Children or parent

\"v2-88624acacf32e8fd080a33c26f5bf772_b.jpg\"
import maya.cmds as cmdsRoot = cmds.ls(\"joint1\")[0]BoneList = []BoneList.append(Root)while True: Root = cmds.listRelatives(Root) if Root is None: break BoneList.append(Root)print BoneList


SUMMARY AND OUTLOOK:

三个小时入门maya python编程完全够了,后面我会做一些高级插件。这篇文章我也会不断完善,插入各种短小代码的example方便我日后写工具的时候Ctrl+C/V,maya大神可以忽略

Enjoy it

NEXT:

YivanLee:虚幻4渲染编程(DCC工具篇---Maya)【Maya Python Scripting(2)】

收起 \"\" 展开全文 \"\"

本文链接: http://tandcc.immuno-online.com/view-737927.html

发布于 : 2021-03-25 阅读(0)