邗江建设局网站资料下载,微信页面设计网站,沈阳旅游团购网站建设,怎么访问被禁止的网站胡泳滨MayaPython简易教程#xff0c;如需转载#xff0c;请标明出处地址#xff1a;http://huyongbin.blogbus.com/c3363976/谢谢配合#xff01;MayaPython第一篇 - 介绍大家好#xff0c;这是一个简易的MAYA PYTHON学习教程。简易教程的目的是可以让更多的人快速掌握这…胡泳滨MayaPython简易教程如需转载请标明出处地址http://huyongbin.blogbus.com/c3363976/谢谢配合MayaPython第一篇 - 介绍大家好这是一个简易的MAYA PYTHON学习教程。简易教程的目的是可以让更多的人快速掌握这些知识而不是拘泥于理论的研究。最好的学习方式无疑是实践我会提供简单实用的代码来帮助学习者了解脚本的实际运用。如果你是初学MAYA PYTHON特别是非程序员的初学者不妨先看一下下面的内容以帮助你对MAYA PYTHON有一个大致的了解。为什么要学习简易教程简易教程的特点就是尽可能做到简单容易理解。我的文档会涉及到尽可能多的内容但不会说的很深。因为很多复杂的应用往往是许多简单部分的组合学会如何组合是更重要的事情)另外任何学习都需要一个很好的getting started好的入门往往决定今后深入学习的质量。万事开头难但是一个好的开始就是成功的一半。希望我的简易教程可以带大家进入MAYA PYTHON的大门。这个文档的适用人群是哪些·具有一定MAYA操作经验但无编写脚本经验的用户·具有一定MEL基础的用户·始终徘徊在MAYA脚本门口但找不到切入点的初级用户什么是MAYA PYTHON?简单来说MAYA PYTHON就是用PYTHON语言包裹起来的MEL命令。什么是PYTHONPYTHON是一门简单易学但功能又非常强大的编程语言。(我会在下一篇中提供简单实用的PYTHON入门教程)为什么要学习MAYA PYTHON大幅度地提高工作效率挖掘MAYA隐藏功能更全面地掌握MAYA快速开发脚本插件如何学习MAYA PYTHON最好的方法是学习别人写的源代码。而最好的代码资源其实就在你的电脑里你的MAYA帮助文档。如果你有良好的英语阅读能力这样你可以充分理解帮助文档里所说的内容。但是如果英语能力不是很理想的朋友也千万不要着急我的文档会帮助你学习MAYA PYTHON。另外MAYA的帮助文档中的脚本部分对每条命令的参数以及每个节点的属性解释的都非常详细个人认为学会使用MAYA的帮助文档是学习PYTHON脚本的制胜法宝。---第一篇完---MayaPython第二篇 - PYTHON (点击标题阅读全文)如果你是PYTHON高手可以跳过这篇)因为节下来我要讲述PYTHON的基本应用。由于我的PYTHON教程主要是针对MAYA的应用所以PYTHON基本应用的介绍主要会涵盖MAYA环境中经常会使用到的PYTHON功能。学习过程中尽量运用已学到的知识自己也试着编写一些代码发挥主观能动性。这样学习效果会十分显著。该篇主要含盖以下内容2.1 脚本编辑器(Script Editor)2.2 PYTHON常用数据类型和操作符2.3 流程语句2.4 定义函数2.5 常用模块2.1 脚本编辑器(Script Editor)MAYA界面中有2处地方可以编辑PYTHON脚本一处是左下角的快速命令行这个命令行可以在PYTHON和MEL间快速切换如下图一处是右下角的Script Editor按钮点开窗口如下我们的PYTHON代码就是写在PYTHON选项卡中如果PYTHON脚本在MEL选项卡中执行将会出错vice versa。我们在MAYA中执行的操作会通过MEL语言打印在上面灰色区域也就是输出区域。这些MEL语言都可以非常快地转化成PYTHON代码。这个数据输出区域同时也会打印PYTOHN脚本的执行结果以及出错信息。现在我们来执行一条简单的PYTHON语句来一个初体验PYTHON页面中输入print hello maya然后按数字键盘上的小回车(注意小回车是执行代码大回车是换行)。我们看到输出区域的打印结果如下print hello! My name is Hu Yongbinhello! My name is Hu Yongbin第一行是告诉用户你执行了print hello! My name is Hu Yongbin这条命令第二行hello! My name is Hu Yongbin是执行这条命令的结果这里的执行结果就是hello! My name is Hu Yongbin被打印出来了。命令执行成功。但是我们发觉PYTHON页面里的代码也消失了。如果需要反复执行代码可以选中需要执行的代码然后按小回车这样我们可以在执行代码的同时保留页面里的代码。(建议使用第二种方法执行代码)接下来再举个简单的例子来说明输出窗口中的报错信息。随意在命令行中输入一些字母HuYongbin然后执行出现如下信息HuYongbin# Error: NameEror: name HuYongbin is not defined #这是个简单的报错信息说明HuYongbin没有被定义电脑无法识辨。这条命令是无效的。最后就是#符号#后的所有的代码(换行前)都被看作注释不参与运算。例如# print hellomaya : )虽然也是print命令但是前面有#所以无视。现在我们终于知道如何在PYTHON中执行代码以及辨别代码是否有效。在下面的教程中我将会用一些简单的实例来展示PYTHON的常用功能2.2 PYTHON常用数据类型和操作符数据类型就是数据的类型- -U就是不同类型的数据数据类型包括整型浮点字符列表元组字典。整型(INT)就是整数比如13211000……浮点(FLOAT)就是带小数点的数字比如1.124.5……字符(STRING)就是文字需要用单或双引号比如HuYongbin123.1415#_%)列表(LIST)就是一系列数据的组合用中括号比如[23][tomjerry][marry14]元组(TUPLE)用小括号和列表的区别是他是不可变的(23)(tomjerry)(marry14)操作符形象的说就是用来操作数据的工具包括数学操作符比较操作符逻辑操作符。数学操作符(加) -(减) *(乘) /(除)%(取除法余数)**(乘方)比较操作符(大于)(大于等于)(等于)!(不等于)逻辑操作符and or not下面来做一些热身在实际运用中体会不同数据类型之间的配合2.2.1 整数a1 # 定义变量a 把整数1赋予给ab3 # 定义变量b 把整数3赋予给bab运行结果为3其他整数小数的加减乘除这里就不熬述了~2.2.2 字符name1tom # 定义变量name1把字符tom赋予给name1注意双引号name2jerry # 定义变量name2把字符jerry赋予给name2注意这里是单引号都可以表示name1name2运行结果为tomjerry这里说明字符之间可以相加。但是不同数据类型之间不可以相加变量a和变量name1就不可以相加因为一个是整数一个是字符。字符单引号和双引号的不同用法我会再之后的实例中写出。2.2.3 列表list1[123] # 定义列表list1包含3个整型数字list2[cube,sphere,plane] #定义列表list2包含3个字符listlist1list2 # 把list1和list2的相加结果赋予新的变量listprint list运行结果为[1,2,3,cube,sphere,plane]可见包含不同数据类型的列表之间可以相加我们可以对列表中的数据进行访问操作。执行以下命令list[0]list[2]运行结果为4因为list[0]指的是list列表中的第一项list[2]指的是list列表中的第3项。(注意PYTHON数数是用0开始的)依次类推list[4]指的就是“sphere”。list[3]*list[1]运行结果为cubecube其效果等同于cube*2可见字符和整数间可以做乘法运算。同样如果c*5的运算结果就是ccccc。user1[tom,cat]user2[jerry,mouse]userInfo[user1,user2] # 定义列表userInfo该列表内又嵌套了2个列表print userInfo # 打印userInfo运行结果为[ [tom,cat][jerry,mouse] ]我们看到大列表中包含了2个小列表我们同样可以访问嵌套列表userInfo[0]表示userInfo中的第一个列表user1userInfo[0][1]表示user1中的第2个值cat。同样如果要访问jerry你可以通过userInfo[1][0]来访问。我们还可以对列表里的内容进行添加或移除userInfo.append([jack,male])这样我们再次打印userInfo的时候得到的结果应该为[ [tom,cat][jerry,mouse][jack,male] ]userInfo.remove([tom,cat])这样我们再次打印userInfo的时候得到的结果应该为[ [jerry,mouse][jack,male] ]列表和字符还可以访问其区间的数据a[1,2,3,4,5,6,7,8] # 定义列表ababcdefg # 定义字符ba[35] # 返回的值是[456]是列表a的第4位到第6位b[1:4] # 返回的值是bcdea[3:] # 返回的值[4,5,6,7,8]从第4位一直到结尾b[:-4] # 返回的值是abc从第1位到倒数第4位2.2.4 常用工具接下来我给大家介绍一些不同数据类型中的常用工具2.2.4.1 操作符号a1a1 # 等同于aa1运行结果为2因为a1a1等于2然后把2这个数字赋予给原来的a这样2就替换掉原来的1了a就等于22.2.4.2 pow()乘方命令xpow(4,3) # 就是4的3次方ypow(4,-2) # 也就开根号2.2.4.3 len()获取长度命令len()命令能够返回字符和列表的长度如下len(tommy) # 返回结果是5len([1,2,6]) # 返回结果是3len([[1,2,7],[lock,jack],[bach,davinci,vivaldi]]) # 返回结果为3因为里面包含3个列表2.2.4.4 int()str()数据类型转换命令int()的str()是字符和整数转换的命令非常实用a256bint(256) # 把字符256转换成整数256a-b # 运行结果为0cmayadstr(2011) # 把整数2011转换成字符2011cd # 运行结果是maya20112.2.4.5 max()min()最大值最小值命令max()和min()可以用来比较数字的大小max(1,7) # 结果为7两个取大的值min(3,6) # 结果为3两个取小的值2.3 流程语句2.3.1 if语句if就是如果的意思是条件判断语句的关键词一般可以和elif或else语句结合使用。接下来我会用一些简单实用的例子来说明if语句的用法age17 # 定义age等于17if age18: # 假设第一种情况,注意要用冒号print you are not adult # 注意代码缩进else: # 假设第二种情况注意冒号print you are adult这里的运行结果是you are nod adult因为假设第一种情况是成立的。这里提一提代码缩进缩进就相当于写作文时每小节开头要空2字代码缩进就是指被缩进的代码是上一行代码的子代码。nametom # 定义name变量if nametom: # 注意这里是“”不是“”print Hello,tom运行结果是打印Hello,tom。“”和“”的区别是“”相当于是个动词把tom这个字符值传递给变量name“”表示一种状态。if nametom这句话翻译成人类的语言就是假设name的值等于tom这个状态是成立的。(一旦成立就执行后面的语句……)a3if a1: # 假设1print a1elif a1: # 这里出现了假设2print a1else: # 如果两种假设都不成立的话……就执行下面的语句print a1运行结果是a1。很显然a不小于1也不等于1那就只有执行else后面的语句了。2.3.2 for循环语句for语句的操作对象一般是一个序列对序列中的每一个成员进行操作举例seq[1,2,3] # 定义一个列表for i in seq: # for即将对列表seq中的每个成员进行操作成员我们用i来代替(这里成员变量可以自定义)print i1 # 操作的内容给每个成员1执行结果如下234我们给每个成员都1了说到for循环语句我们不得不提一下range()内置函数。range()可以针对数字提供一个序列范围range(10)运行结果就是[0123456789]range(5,10)运行结果就是[5,6,7,8,9]range(0,10,2)运行结果就是[02468]结合for语句我们可以尝试执行以下代码x[a,b,c,d,e,f,g,h]for i in range(0,10,2): # 操作范围[02468]print x[i] # i 将会被[02468]中的每一项依次替代替代后再执行print语句。运行结果aceg2.4 定义函数在PYTHON中我们可以自己定义一个函数定义函数的命令是def如下def MyFirstFunction():print this is my first function这里我们用def命令定义了一个函数名字叫MyFirstFunction后面括号里面是用来填写参数的如果没参数就留空。定义函数内的代码需要缩进。如果要执行函数操作如下MyFirstFunction() # 这样输入就可以执行函数函数内的所有命令都会被执行执行后结果会打印this is my first function说明定义函数内的代码被正确执行了。函数还有一种定义方式就是在括号里加上一些参数def MySecondFunc(a, b): # 该函数包含了a和b两个参数print ab然后我们来执行这个函数MySecondFunc(2, 5) # 把2和5分别代入a和b然后执行函数内的print命令会被执行。运行结果为7MySecondFunc(first,second)运行结果为firstsecond两个字符串被相加了。函数还可以签套函数如下def func1():a1print adef func2():b2print bfunc1()定义好func1和func2后执行func2()结果为21因为func2先执行打印b在执行func1func1会打印a2.5 常用模块简单说模块就是一个打包的命令集合以文件的形式存在。模块的使用方法是“导入”。我们直接针对MAYA PYTHON的模块来具个简单的例子吧。2.5.1 maya模块import maya.cmds # 导入maya模块中的cmds命令集这样我们就在MAYA中导入了cmds命令集里面包含了所有可以在PYTHON环境中使用的MAYA命令。现在我们来初试这个cmds命令集import maya.cmds # 导入模块maya.cmds.polyCube() # 调用模块中的polyCube()命令。发觉场景里生成了一个方块命令执行成功。但是这样打命令太长了我们在导入maya.cmds时加上import maya.cmds as mc这样maya.cmds就作为mc导入了我们就不用再打长长的maya.cmds了。我们再创建一个Cubemc.polyCube()短很多了吧。接下来介绍几个常用的模块import maya.mel # 导入这个可以调用所有的mel命令2.5.2 os模块import osos模块也是用的比较多的。我经常会使用os.system()括号中间可以写一些DOS命令os.system(md c:\\MyFolder)这样就可以用PYTHON来调用DOS命令了。os.listdir(C:\\)listdir可以以列表的形式列出路径中的所有的文件和文件夹(注意是列表的形式像这样[a.py, AUTOEXEC.BAT, boot.ini])。接下来再介绍一个re模块我经常用它来做字符的切割工具2.5.3 re模块import reaHello_Worldre.split(_,a) # split就是切割工具有2个参数 _就是切割的根据a是我们定义的变量返回结果是一个列表[Hello,World]还有个是替换命令re.sub()amy4name4is4HuYongbinre.sub(4,_,a) # 就是说把4替换成_输出结果my_name_is_HuYongbin2.5.4 time模块import time # 时间模块time.ctime()执行结果# Result : Fri Jun 11 22:52:16 2010 # 。也就是当前的时间。OKPYTHON简易教程就写到这里简易教程的内容肯定不是很完整这里只是罗列出一些实战中比较常用的功能。(也是我比较常用的)初学者可以抛弃理论先玩起来再说。实践太重要了。在下一篇中我们将正式进入MAYA PYTHON实际应用。---第二篇完---MayaPython第三篇 - 实战演习 (点击标题阅读全文)在上一篇中我主要介绍PYTHON的一些基础知识以及常用语法。在这一篇中我们要结合MAYA中的命令来编写一些基本PYTHON脚本。其实在上一篇接近尾声的时候我已经举例了如何导入模块的方法这是真正使用PYTHON在MAYA中编写脚本的第一步。import maya.cmds as mc # 这里应该不用解释了吧有疑问可以看第二篇的结尾“模块”部分。)这里顺便提一提as mc可以用任何名词来代替as cc也可以。这样如果要调用polyCube()命令的话就必须有cc.polyCube()作为前缀。基于笔者的个人习惯我们这里还是用mc3.1 MEL命令和PYTHON命令之间的转化我们导入MAYA的模块现在要运用模块中的命令编写一些东西了。但是大家可能会很疑惑写什么呢我们总不见得整天在MAYA里做小学数学题吧- -现在我们需要学习一些MAYA的实用命令(比如上一篇提到的polyCube()创建一个立方体)学习实用命令的最好的途径是通过执行手动操作命令来获取MEL命令语句然后把MEL命令转换成PYTHON命令。比如我们在MAYA3D视图中用传统的方法建立一个polygon的立方体我会在脚本编辑器的输出部分得到以下输出信息polyCube -ch on -o on -w 9.9 -h 7.1 -d 10 -cuv 4; //注意大小写这是一句MEL命令描述了如何创建一个Polycube。MEL命令的结构十分简单开头的polyCube就是这句MEL命令的主命令后面的部分全部是参数。其中带“-”的是参数名称没有“-”的是该参数的值。一般都是一个带“-”号的参数名称后面再跟一个不带“-”的值。有时后面会不跟值这说明这个参数不需要值它只是一个开关带这个参数说明这个开关开着不带说明关着。现在我们就把这句MEL命令转换成PYTHON可以执行的命令(我们暂时不去理会具体参数的作用只是学习一个转换过程)mc.polyCube(ch1, o1, w9.9, h7.1, d10, cuv4)执行代码后同样得到了一个立方体。我们对比一下可以发现PYTHON可以完全把MEL的命令转化过来只是格式不一样。格式不同体现在一下几点·有mc前缀(MEL没有前缀)·所有的参数信息需要放在主命令后的括号中(MEL没有括号)·参数名和它的值之间用等号隔开(MEL是用空格)·每个参数之间用逗号隔开(MEL用空格)·有些参数的值是1而ME是on关于最后一条其实MEL的on也可以写成1原因是在PYTHON(包括其他程序语言)1这个值往往表示True,on等肯定意义的值而0则表示False, off等否定意义的值。这样的值叫做布尔值(boolean)这种数据类型只有2种答案要么1要么0要么真要么假要么ON要么OFF。例子中的1就是on说明这个参数是可用的。关于布尔值(其实你在MAYA中也可以把它理解成一个开关)以后还会讲到它的用法。节下来我们举一反三熟练掌握MAYA命令转换的方法。拖一个球出来得到以下命令polySphere -ch on -o on -r 3;转成PYTHON代码就是mc.polySphere(ch1, o1, r3)还有一中转化形式我们如果在场景中选择了pCube1这个物体会得到以下MEL命令select -r pCube1;这里我们就不能写成mc.select(rpCube1)了因为现在这个命令基本上属于一个动作一个动词既然是动词就必须有一个动作施与的对象这里这个对象就是pCube1而r这个参数其实replace的简写。注意这个r不是布尔值它没有任何数据类型只是一个开关而已。在MEL中这个开关是不需要值的但在PYTHON中需要像布尔值那样给一个1的值表示这个开关开启mc.select(pCube1, r1) # 注意PYTHON中选择对象放在最前面。# 注意名字的数据类型是字符所以必须有双引号如果要同时选择pCube1和pSphere1的话需要用到列表如下mc.select([pCube1,pSphere]) # 注意如果是选择集合的话要用列表来表示# r参数在这里我就不加了但是不影响执行体会下“可选”的作用3.2 读取场景中信息的常用命令刚才我们知道了一些如何创建物体以及如何选择物体的PYTHON命令。下面咱们要学习如何准确获取场景中你想要得到的信息对于即将要编写的代码而言是十分重要的。比如你要用命令对“所选的顶点”进行操作那你就必须先要得到这些顶点信息比如这些点的ID号是那些同样如果要对“所选的MESH”进行操作那你至少得让MAYA知道是哪些MESH。3.2.1 得到所选物体的名字列表那我们先来得到所选择的物体信息吧这里用到一个新的命令ls(我这里提到命令绝对是常用的)mc.select([pCube1,pSphere]) # 选择场景中的两个物体mc.ls(sl1) # ls就是list的简写我们要list一些信息# sl1表示我们要列出sl(select)的信息“1”就是一个开关我们打开了它。执行后我们会从输出框中得到一个列表[pCube1,pSphere]。假如我们把第2行命令的结果赋予一个变量那这个变量将继承这个命令执行的结果如下selmc.ls(sl1)print sel我们同样会得到[pCube1,pSphere]这个结果并且我们保存了这个列表结果到sel变量中去。假如你选择了N个物体那你执行这句命令后会得到N个物体的列表。3.2.1 得到和设置物体的属性getAttr()和setAttr()下面再介绍2个非常有用的命令getAttr()和setAttr()。前面那个是得到节点属性后面那个是设置节点属性。我们同样可以借助MEL命令来获取一些命令信息。3.2.1.1 setAttr()我们选中刚才创建的pCube1然后CtrlA打开属性窗口找到pCube1节点中的Transform Attributes栏我们把Translate行中的第一个值打成0回车。现在我们在输出窗口中得到了一条MEL命令setAttr pCube1.translateX 0;pCube1.translateX就是表示这个节点的TranslateX参数后面的0表示它的值。这样我们也就可以把它转成PYTHON可以用的命令mc.setAttr(pCube1.translateX, 4) # 现学现用我们把这个值再改成4在PYTHON面板中执行后发觉Translate行中的第一个值神奇地变成了4。同样视图中的立方体也沿X轴平移了4个单位。同理我们可以通过改变其他参数来获取其动作的MEL命令然后把它转换成PYTHON可以用的命令。3.2.1.2 getAttr()下面我给出如果获取属性值的命令mc.getAttr(pCube1.translateX) # 获取pCube1的translateX参数的值。执行后我们得到4也就是前面我们所设的那个数。同样我们可以把这个值赋给一个变量a mc.getAttr(pCube1.translateX)print a打印a的结果就是mc.getAttr(pCube1.translateX)的结果。3.2.1.3 询问开关q还有一种查寻其属性的方式就是利用询问参数q。这里我们以xform命令来举例如下mc.select(pCube1)mc.xform(q1, translation1)执行结果返回一个包含了pCube1的XYZ位置信息的列表。我们看到xform命令的参数表中有2个参数一个是q一个是translation。其中q1表示当前这个命令已经进入询问状态改命令不会对所选的物体进行任何操作只会询问translation1表示我们要询问的参数是translation“1”相当于一个开关说明我们要询问这个“1”的参数值。假如我们的命令是mc.xform(q1, translation1, rotation1)这样会出错因为询问状态下只返回一个参数的值。相反如果 mc.xform(q1, translation1, rotation0)也就是把rotation改成0返回结果仍然会正确。3.3 帮助文档的使用(灰常重要)有的人可能回问我如何才可以知道一个操作命令有多少个参数可以使用一个节点到底有多少个属性可以设置接下来我会给大家介绍下MAYA帮助文档的使用方式。按F1打开MAYA帮助文档。在Content中找到Technical Documentation(技术文档)在这个技术文档中我们需要用到的就是CommandsPython和Nodes。CommandsPython中包含了所有MAYA中的PYTHON命令以及其参数的使用方法Nodes列出了MAYA中所有的节点以及其属性的用法。现在我们列举一个xform命令来了解如何结合帮助文档来完成你的操作3.3.1 Python命令点CommandsPython进入页面在By substring中输入xform命令在下面出现的SubString列表中选择xform我们就可以进入xform命令页面。我们把该页面往下拖跳过NotesRelated的内容在Flags下有个长长表格表格由3列组成Long name(short name)长名(缩写), Argument types(数据类型), Properties(属性)。长名(缩写)的意思就是比如mc.xform(q1, translation1) 这条语句中translation是一个参数我们可以在Flags下的列表中找到这个参数我们观察它的长名(缩写)一列translation后有一个(t)这个(t)就是他的缩写我们可以用缩写来替代长名如mc.xform(q1, t1)效果完全一样。数据类型就是这个参数所支持的数据类型如果它的数据类型是Int的话说明它只能支持整数你只能把整数作为它的参数或者在询问时只能得到整数的输出。同样如果是个boolean值的话它只能支持0或1。属性指的是这个参数的性能。这里的性能有4种在MAYA帮助文档中用这4个字母表示 。其中C表示这个参数可以在该命令执行操作的时候使用Q表示这个参数可以在询问状态下使用E表示这个参数可以在编辑状态下使用M表示这个参数可以拥有多种数据类型。一般情况下C Q E用得最多。比如mc.xform(q1, t1)这句命令就是典型的询问状态Q询问内容是t也就是translation。3.3.2 Nodes信息现在我们进入Nodes页面来了解下如何使用MAYA节点中的属性。Nodes页面中所罗列出来的其实是MAYA中的所有节点类型。MAYA中充满着节点我们任意选种场景中的某个节点它都是属于某个Nodes页面中所罗列出来的类型。比如我们选择之前在场景里创建的pCube1它是属于什么类型的节点是pCube节点吗不是我们无法在Nodes页面中搜索到。我们可以通过以下命令来询问节点的类型mc.objectType(pCube1) # objectType命令可以得到节点类型实用推荐执行后得到结果transform。说明pCube1这个节点是transform节点。同样我们询问mc.objectType(pSphere)执行后同样得到结果transform。所以虽然pCube1和pSphere节点名称不同但是他们都是属于transform节点千万不要认为他们是pCube类型或pSphere节点类型。得到节点类型后我们到Nodes页面输入transform。找到transform点入。找到Attributes下的长长列表。我们可以看到transform中有的参数。这些参数都可以通过getAttr()和setAttr()来获取和设置。我们来做下测试吧)mc.getAttr(pSphere.rz) # rz就是rotationZ的缩写返回0.0我们就得到了他的信息了。关于文档使用的小结其实我平时用的比较多的还是CommandsPython命令查询页面因为在场景中很难找到命令及其参数的完整信息(当然我们可以通过输出窗口中的MEL记录但这些信息远远不够……)。关于Nodes当我们需要知道某个节点的类型时可以用到objectType来查询或者当我们需要得到节点中某些属性的时候也会用的到这个页面。3.4 一个简单的脚本实例这一节中我要结合前三篇所讲的一些知识来作一个综合的小范例并加上适当的注解以便学习。import maya.cmds as mc # 导入MAYA模块def height(h): # 定义函数heighth为这个函数的一个参数selmc.ls(sl1) # 定义变量sel把当前所选的内容赋予这个变量for i in range(0,len(sel)): # 在sel这个选集范围里对其中的每一个对象进行操作mc.setAttr(sel[i].ty, h*i) # 所做的操作是把每个对象的Y轴移动一个量。# 这个量是这个函数的h参数乘以这个for循环的成员变量i先执行以上这写代码。现在我们在场景中创建一个立方体然后按CtrlD水平复制出若干个成一直线全部选中这些立方体。如下图然后执行height(2)执行height函数后发现这些立方体的高度会发生一些变化形成一斜线。并且height的斜率会根据h的值的不同而不同。代码的简单分析代码的结构不是很复杂只有5行前面3行应该不用作过多的解释应该是很好理解的。我主要分析下最后的2行for循环语句。(看下面的文字时请注意对照源代码)第一行for假设我的场景里有5个pCube分别叫pCube1, pCube2, pCube3, pCube4, pCube5如果我选择的他们的话那么sel变量会是这样一个列表[pCube1, pCube2, pCube3, pCube4, pCube5]len(sel)的值就是5range(0,len(sel)) 就等于range(0,5)也就是[0,1,2,3,4]这样一个列表。所以说成员变量i的取值范围就在这个列表中i将逐个被列表中的每一个成员替代。第二行for由于i有5个值可以取所以setAttr会执行5次每次执行时就会把range范围列表中的值代入i。比如当i0的时候sel[0]就是指范围列表中的第一个值也就是pCube1sel[i].ty指的就是pCUbe1.ty也就是pCube1的Y轴的移动值h*i指的就是这个移动值的具体数字其中i是在这里就是0h的值取决于你在调用函数时在参数中所输入的数字把整句话连接起来就是当i0时并且h2时(h值在我们调用函数时得到)执行mc.setAttr(pCube1.ty, 2*0)pCube1的Y的位移值等于0以次类推当i4时并且h2时执行mc.setAttr(pCube5.ty, 2*5)pCube5的Y的位移值等于10。如果你有一定编程经验相信这些代码理解起来不会很困难。如果你是初学着建议多练习for循环语句的使用多尝试自己写一些代码得以巩固。在下一篇中我们会有更多的代码演示及其分析进入实战。---第三篇完---MayaPython第四篇 - 实战篇 (点击标题阅读全文)上一篇我们结束了演习在这一篇中我们将进入实战我们将学习写一些实用的代码以使我们的工作高效化。作为简易教程我的范例代码的难度不会很大学习者也可以触类旁通重组这些简单的“零件”发挥自己的“组合能力”。其实这个世界上真正复杂的“东西”很少但是复杂的“组合”却是很多。复杂的“组合”往往需要自己创造发挥自己的想象力吧。4.1 自制吸附工具事实上MAYA自己也有吸附工具可以吸附很多场景中的元素。我们下面的代码的主要是用来吸附中心点位置的。在MAYA场景中如果遇到有很多物体时MAYA自带吸附功能可能会有点不太好使(会吸到别的物体)。但也有可能是我MAYA掌握不全面- -U。(事实上操作上我更习惯MAX因为学的比较早但从软件结构上更偏爱MAYA)OK不废话了先看看下面的代码吧# 执行代码前请大家在自己的场景里建2个物体(任意)我这里是pCube1和pSphere1def snap():selectionmc.ls(sl1) # 把所选的物体命令存入变量selectionposmc.xform(selection[1], q1, t1, ws1) # 询问所选的第2个物体的位置信息并存入变量posmc.xform(selection[0], tpos, ws1) # 把这个pos变量的值给所选的第一个物体先执行以上代码什么也不会发生因为我们现在已经定义了一个函数这个函数叫snap接下来我们要执行这个函数了。先选pCube1然后按Shift加选pSphere1执行函数snap()我们看到pCube1的位置完全移到pSphere1的位置上去了。如果我们撤消操作先选pSphere1再加选pCube1执行函数后结果就成了pSphere1的位置完全移到pCube1的位置上去了。这里我们看到选择的顺序对最终的执行结果形成了直接的影响。所以我们先要测试MAYA中的选择顺序和mc.ls(sl1)命令之间的关系。再次选pCube1然后按Shift加选pSphere1然后执行mc.ls(sl1)我们看到MAYA返回了一个列表[pCube1,pSphere1]。然后同样反过来操作先选pSphere1再加选pCube1执行mc.ls(sl1)得到的列表结果是[pSphere1,pCube1]。所以得出结论加选的物体会追加到列表的结尾。selection[0]就是先选的物体selection[1]就是后选的物体。如果我们想要把后选的物体作为目标位置的话那我们就要获取后选物体的位置信息posmc.xform(selection[1], q1, t1, ws1)。我们再次用到了询问开关qt就不用多说了吧如有疑问可以参考上一篇3.3.1ws(worldspace)是世界空间的意思打开ws说明你所要获取或设置的参数是基于世界坐标的而不是局部坐标(可以在帮助文档中找到)。这样我们就把后选的那个物体selection[1]的位置信息记录到了pos变量里。随后我们把这个位置信息用mc.xform(selection[0], tpos, ws1)命令赋予给先选的物体selection[0]这样selection[0]的位置就看上去像“吸”到selection[1]上去了。扩展由于字数限制扩展部分介绍请参阅我的博客4.2 自制重命名工具MAYA自带也有类似的工具。但是功能比较简陋我们可以自制一个功能更强的重命名工具。先看下代码吧def addpre(pre):selectionmc.ls(sl1)for i in selection:mc.rename(i, prei)我们先执行以上代码这样就定义了addpre()函数然后我们选中刚才创建的pCube1和pSphere1执行该函数如下addpre(prefix_)执行后看到我们所选择的物体名字前就加上了前缀变成了prefix_pCube1和prefix_pSphere1。现在我来解释代码。定义函数中我们增加了pre变量作为该函数的参数用来输入你需要的前缀字符。函数主体中第一行大家应该明白这里就不多说了主要还是稍微解释下for循环。for循环的范围是你的选择范围selection不管selection列表里多少值都是循环范围。每次循环所执行的语句是mc.rename(i, prei)其中rename是重命名的命令我们可以通过手动给物体重命名在MEL输出窗口得到MEL命令然后转成PYTHON或者到帮助里查找这里我推荐第一个方法因为比较快捷。rename中有2个参数第一个是要rename的原始名字第二个是修改后的名字。i是selection列表里的的每个成员也就是你所选择的物体。执行命令后for循环会逐个对你所选的每一个物体执行rename命令把i(原始名字)变成prei。其中pre是一个预设的变量在调用函数的时候pre需要被设定成一个字符比如addpre(prefix_)这样pre就等于prefix_了那prei就等于在原始名字前加上一个叫做prefix_的字符。扩展由于字数限制扩展部分介绍请参阅我的博客4.3 对文本进行操作这里我写个小小的实例这个实例可以将当前所选择的物体的位置坐标导出成文本文件。接下来我们在脚本编辑器中输入以下代码import maya.cmds as mcselmc.ls(sl1)info[]for i in sel: #获取每个选择物体的名字和它的位置信息posxmc.getAttr(i.tx)posymc.getAttr(i.ty)poszmc.getAttr(i.tz)iposInfo[i,posx,posy,posz]info.append(iposInfo)info_strfor i in info:info_strinfo_stri[0]\r\nposX: str(i[1])\r\nposY: str(i[2])\r\nposZ: str(i[3])\r\n\r\nfopen(D:\\posInfo.txt,w) # w表示写入f.write(info_str) # 把info_str写入文件f.close()然后我们在视图中创建3个立方体然后随意放置他们的位置如下图最后全选上面的代码按小回车执行它们完了我们打开资源管理器找到D盘的根目录下多了一个叫posInfo.txt的文件打开它可以看到文本文件的内容如下这个文件记录了我们所选择的物体的坐标位置信息。现在我为大家分析以下这段脚本谈谈我对写类似脚本的思路首先我先要想我如果要记录一个文本文件要记录哪些信息这里作为范例我只记录最简单的信息那就是所选物体的名字以及该物体的XYZ位置信息。所以这里创建了一个空的列表Info然后使用for循环对每一个所选择的物体进行getAttr()以获得它的XYZ位置坐标然后把[物体的名字坐标X坐标Y坐标Z]以列表的形式给一个临时的变量iposInfo把每个物体的iposInfo再添加给Info列表。这个时候Info得到的数据应该是这样的[[立方体1POSXPOSYPOSZ],[立方体2POSXPOSYPOSZ],[立方体3POSXPOSYPOSZ]]现在我们以列表的形式暂时保存了想要储存的数据这个列表叫做Info。然后我们需要用到PYTHON的文件读写命令open()和写入命令write()。但是写入文本文件的数据类型是字符所以我们需要把列表转成字符而且是带格式的字符因为带格式的字符可以方便我们浏览文件。这里我们再次使用了for循环我们对Info列表进行循环把列表中的信息以特定的格式累积到空字符info_str中去最后把info_str写入文本。扩展由于字数限制扩展部分介绍请参阅我的博客一些隐藏的命令由于字数限制部分内容介绍请参阅我的博客在PYTHON中使用MEL语句由于字数限制部分内容介绍请参阅我的博客MayaPython第五篇 - 界面篇 (点击标题阅读全文)学习写界面的最好方法是看帮助文档帮助文档里拥有大量的学习资源并且大多都很实用。我基本就是直接把帮助文档里的范例直接拿过来用然后修改其中的参数边改边学。这里我基本也是拿来主义在接下来的篇幅中我会选择性地解释一些基本控件的用法。5.1 按钮和文字按钮和文字是界面中常用的元素接下来我们先尝试用最简单的代码来生成一个带按钮的界面。5.1.1 按钮import maya.cmds as mcmc.window()mc.columnLayout()mc.button()mc.showWindow()执行后看到一个只有一个按钮的窗口点击按钮什么也不会发生。接下来我们在mc.button()中添加一些参数mc.button(labelHu Yongbin) # 添加按钮标签再次执行所有代码看到窗口中按钮上的文字变成了label参数后的值。接下来我们继续添加参数mc.button(labelHu Yongbin, w100, h100) # 添加宽度和高度参数执行后看到按钮变成100*100的方形接下来我们要让这个按钮执行些命令比如打印一句话mc.button(labelHu Yongbin, w100, h100 commandprint hello, my name is Hu Yongbin) # command 参数执行所有代码点Hu Yongbin按钮观察输出窗口看到了hello, my name is Hu Yongbin。我们看到command参数其实包含的是命令。同样我们也可以定义一个函数def printer(whatever):print whatever然后把函数放在command参数后mc.button(labelHu Yongbin, w100, h100 commandprinter(12312))执行后点Press Me看到输出窗口返回12312这个值。mc.button(labelHu Yongbin, w100, h100bgc[1,0,1] ) # bgc就是backgroundcolor执行后看到按钮变成了难看的粉红色。更多的参数请参考帮助文档)5.1.2 文字文字在UI中起着说明解释的作用import maya.cmds as mcmc.window()mc.columnLayout()mc.text(labelwelcome to Hu Yongbin blog - http://huyongbin.blogbus.com)mc.button()mc.showWindow()执行代码后看到按钮上方出现welcome to Hu Yongbin blog - http://huyongbin.blogbus.com如果把mc.text(labelwelcome to Hu Yongbin blog - http://huyongbin.blogbus.com)放到mc.button()下面的话welcome to Hu Yongbin blog - http://huyongbin.blogbus.com就会在按钮的下面。我们还可以改变字体mc.text(labelwelcome to Hu Yongbin blog - http://huyongbin.blogbus.com fnboldLabelFont )执行后看到字体变成了黑体。更多的参数请参考帮助文档)5.2 输入框输入框也是一个非常实用的功能我们可以在框中输入一些文本然后再执行相关的命令我们可以把上一篇的简单命名工具拿来扩展一下def addpre(pre): # 定义加前缀函数selmc.ls(sl1)for i in sel:mc.rename(i, prei)mc.window()mc.columnLayout()a mc.textField(txdefault) # 文本输入框我们定义了默认文本defaultmc.button(labelPress Me, w100, h100, commandbmc.textField(a, q1, tx1); addpre(b))mc.showWindow()执行以上代码看到按钮上方多了一个文本输入框里面有个默认的文本内容default这个值是我们在创建时定义的。现在我们在场景中随意创建一些几何体然后全部选中点Press Me按钮看到所选的几何体的名字前全部自己加上了default。当然你也可以把默认defualt删除打入任何字符这些字符将成为所选物体的前缀。--相信addpre()函数大家应该很熟悉了吧在上一篇中我介绍过接下来我分析一下textField命令的用法。a mc.textField(txdefault)就是创建一个文本输入框其默认值是一个字符default。我们把定义了的输入框赋予一个具体实例a因为我们在之后要用到这个实例。一般来说如果控件需要用到询问模式(q)和编辑模式(e)都要指定一个具体实例这个具体实例为之后的编辑提供了具体的操作对象。我们看到button行的command参数里包含了这个实例对象amc.textField(a, q1, tx1)表示询问实例对象a关于参数tx的值(这里tx是默认的你也可以通过改变输入窗口中的默认值来得到新的tx值)然后我们把这个值赋给了变量b最后把这个得到的变量b的值填入addpre()函数的pre预设变量并且执行addpre()函数。这样我们就把tx的值加在了所选物体的前面。所以整体流程就是在输入窗口输入文本按Press Me后通过询问得到文本信息tx然后传给b把b填如addpre(pre)这样就得到了最后的结果。5.3 选项菜单选项菜单是一个菜单并且是可选的。import maya.cmds as mcmc.window()mc.columnLayout()omc.optionMenu( labeltest) # 创建菜单mc.menuItem( labelcat ) # 加入菜单内容catmc.menuItem( labeldog ) # 加dogmc.button(labelPress Me, commandamc.optionMenu(o, q1, v1);print a)mc.showWindow()执行后得到一个窗口上面是一个选项菜单下面是一个按钮。点Press Me看到输出窗口返回cat我们把选项菜单中的选项改成dog再点Press Me看到输出窗口返回dog。可见选项菜单中选什么点Press Me后就打印什么。原理很简单和上文提到的输入窗口类似我们在定义选项菜单时要注意设置一个实例o以便之后再获取菜单中的值。点PressMe后执行amc.optionMenu(o, q1, v1)mc.optionMenu(o, q1, v1)的意思就是询问实例o的v参数v参数就是value的意思也就是指当前optionMenu的值。把获得的值给a然后打印a。5.4 列表框接下来我结合选项菜单来写一段简单的有关列表框的代码import maya.cmds as mcimport os # 导入OS模块常用功能见第二篇。def changeList():cdirmc.optionMenu(op, v1,q1)mylsos.listdir(cdir)mc.textScrollList(directoryList , e1, removeAll1)mc.textScrollList(directoryList , e1, appendmyls)mc.window()mc.columnLayout()opmc.optionMenu( labelDirectory, ccchangeList()) # 定义选项菜单mc.menuItem( labelC:\\ )mc.menuItem( labelD:\\ )directoryList mc.textScrollList(numberOfRows8, appendos.listdir(C:\\))mc.showWindow()执行后看到一个窗口上边是选项菜单里面有C:\和D:\两个选项。如果你切换盘附你的列表会显示该盘附里的所有文件和文件夹。如何实现我慢慢道来...由于字数限制列表框的分析内容介绍请参阅我的博客5.5 进度条进度条主要用在脚本运算量很大的情况下的为了避免用户以为死机进度条可以很好的让脚本使用者了解到当前脚本执行的进度。这里我引用了文档里的一个例子import maya.cmds as cmdswindow cmds.window()cmds.columnLayout()progressControl cmds.progressBar(maxValue10, width300)cmds.button(labelMake Progress!,commandcmds.progressBar(progressControl,editTrue, step1))cmds.showWindow( window )执行后看到一个窗口里面有一个进度条和一个按钮每点下按钮进度条会升10%点10下进度条就满了。进度条命令其实很简单。progressControl cmds.progressBar(maxValue10, width300)定义了一个进度条最大值10宽300。按钮命令中command参数里cmds.progressBar(progressControl, editTrue, step1)表示对进度条值的修改注意editTrue等同于e1step1表示每执行一次进度条前进一格。一般在for循环里用进度条比较多我一般惯用格式如下for i in alist: # 假定有个列表叫alist执行命令 # 这只是一个例子大家可以自己代命令进去cmds.progressBar(progressControl, editTrue, step1)这样每作一次循环进度条就会前进。5.6 勾选框勾选框是可以任意勾选自己想要的选项这么一个UI控件示范代码如下import maya.cmds as cmds#以下定义3个初始值v10v20v30def test():print value 1 is str(v1)print value 2 is str(v2)print value 3 is str(v3)print ---window cmds.window()cmds.columnLayout( adjustableColumnTrue )#三个勾选框cmds.checkBox( labelvalue 1, alignleft, vv1, onCommandv11, offCommandv10)cmds.checkBox( labelvalue 2, alignleft, vv2, onCommandv21, offCommandv20)cmds.checkBox( labelvalue 3, alignleft, vv3, onCommandv31, offCommandv30)cmds.button( labelPress Me, commandtest()) # 定义按钮cmds.showWindow( window )执行后看到一个窗口有3个勾选框分别叫做value 1,value 2,value 3还有一个按钮勾选1、3项2项不要勾选点press me看到输出窗口输出信息如下value 1 is 1value 2 is 0value 3 is 1---如果勾2、3项关闭1项再点press me输出如下value 1 is 0value 2 is 1value 3 is 1---可见打印结果的0和1取决于勾选框是否被勾上勾上的为1否则为0。这段代码我将不再作过多的分析希望大家可以自己理解其运作原理。)界面篇的内容就到此为止更多的界面元素以及其用法我不一一熬述大家要多参考帮助文档多分析。发挥主观能动性才是学习的王道。(本教程完)