Python for Maya DCC工具插件开发学习记录(一)

Python for Maya DCC工具插件开发学习记录(一)

参考学习链接 代码和上手难度比较简单,但是没有字幕… 18版的Maya官方API文档 关于python中的中文使用解决方法

写在最前面

干到啥就写点啥,不过也是从入门开始啦,暂定为第一篇吧。本次记录和往常一样用于自己复习,但如果能对别人有所帮助,那荣幸至极;

Maya默认的脚本支持Mel与python,写工具则需要使用C++或者C#或者Python,其中C++与C#不能直接使用,需要编译,且仅能写工具,但速度来说较Python好,但Python 上手简单且兼顾工具和脚本编写,故在此选择使用Python进行学习;

下面两张图大致讲了下关于各种API相关的介绍,看不懂可以使用有道翻译词典拍摄翻译! 另外,python对于格式的把握非常的严格,最好用Tab来控制缩进,否则一直报错,明明看起来写的一样,结果就是疯狂报错,调了一晚上,气的想骂人…

一.简单尝试及简单语法

1.使用Python脚本第一步,先在脚本里输入如下:

from maya import cmds

给我的感觉类似于#include的用法;

2.一串简易的代码,包括:创建物体,设置父子集,锁定

from maya import cmds#创建物体mysphere = cmds.polySphere()mysphereShape = mysphere[0]circle = cmds.circle()circleShape = circle[0]#父子集cmds.parent(mysphereShape,circleShape)#锁定cmds.setAttr(mysphereShape+”.translate”,lock=True)cmds.setAttr(mysphereShape+”.rotate”,lock=True)cmds.setAttr(mysphereShape+”.scale”,lock=True)cmds.select(circleShape)

3.python中的if esle

如下图 下面的代码是通过判断是否选择了物体,如果选择物体的话,输出选择的物体名,否则,输出场景内所有物体,结果看下面的图;

from maya import cmds selection = cmds.ls(selection=True)if len(selection) == 0: selection = cmds.ls(dag=True,long=True)print selection

4.排序

sort排序,reverse用来倒序

from maya import cmds selection = cmds.ls(selection=True)if len(selection) == 0: selection = cmds.ls(dag=True,long=True)selection.sort(key=len,reverse=False)#sort排序,reverse用来倒序print selection

5.for循环 下面两个代码的区别在于最后一句话,两个都是用来输出场景中物体的名称的

from maya import cmds selection = cmds.ls(selection=True)if len(selection) == 0: selection = cmds.ls(dag=True,long=True)selection.sort(key=len,reverse=True)for obj in selection: print obj.split()

from maya import cmds selection = cmds.ls(selection=True)if len(selection) == 0: selection = cmds.ls(dag=True,long=True)selection.sort(key=len,reverse=True)for obj in selection: print obj.split(“|”)[-1]

6.while循环

用于输出物体的属性

from maya import cmds selection = cmds.ls(selection=True)if len(selection) == 0: selection = cmds.ls(dag=True,long=True)selection.sort(key=len,reverse=True)for obj in selection: shortName = obj.split(“|”)[-1] children = cmds.listRelatives(obj,children=True,fullPath=True)or[]if len(children) == 1: child = children[0] objType = cmds.objectType(child)else: objType = cmds.objectType(obj)print objType

7.int to string,python中的强制转换 参考下图 8.另外三种字符串加减法

分别是创建字典和利用标识符% 以及.format,可以玩出很多花来

9.变量

全局变量,内部变量等,和往常其他语言一样就是了; 10.类

python中的类,和其他语言类似

python类的继承

当我们在子类里定义了新的同名函数,会覆盖原来的函数,否则就继承父类的其他函数

二.环境安装

1.pycharm安装第一步设置 百度直接搜索就好了,安装基本点下一步,完事后,需要改动的地方在设置里,如下图,找到Maya安装目录下的mayapy.exe;

2.pycharm安装第二步设置

需要我们先下载Devkit这个玩意,但是,根据视频里的git搜过去官方下载链接是404…然后,我是在csdn上找到的,可以搜下找找看别人整理好的; 下载好并解压后,我们将如下图的四个文件夹放入到Maya安装目录下,相同的文件我选择的是保留原来的,看了下大致应该不会有影响;

接下来在如下图的路径里手动添加devkit底下的py文件夹,并移除site-packages那个路径,之后就可以愉快的使用了!

三.物体重命名脚本

Python,当你会其他语言时,这个就感觉很容易了,省去了变量声明时要加变量类型等操作,写起来类似伪代码一样的,这就是Python,简单易懂,最主要的是跟着视频到这了…

1.根据物体属性重命名工具

逻辑较为简单,如果选中物体,就更改该物体的名字,如果没有选物体,则改变全体的名字,但存在问题是:没有判断是否已经改名,会存在二次命名的情况;

from maya import cmds selection = cmds.ls(selection=True)if len(selection) == 0: selection = cmds.ls(dag=True,long=True)selection.sort(key=len,reverse=True)for obj in selection: shortName = obj.split(“|”)[-1] children = cmds.listRelatives(obj,children=True,fullPath=True) or [] if len(children) == 1: child = children[0] objType = cmds.objectType(child) else: objType = cmds.objectType(obj) if objType==”mesh”: suffix=”geo” elif objType==”joint”: suffix=”jit” elif objType==”camera”: print “Skip!!” continue else: suffix=”grp” newName=shortName+”_”+suffix cmds.rename(obj,newName)

2.在pycharm中写代码并在Maya中运用 还是之前的代码,稍微加了一句用于判断是否已经重命名过;同时定义了类;

from maya import cmdsdef rename(): selection = cmds.ls(selection=True) if len(selection) == 0: selection = cmds.ls(dag=True, long=True) selection.sort(key=len, reverse=True) for obj in selection: shortName = obj.split(“|”)[-1] children = cmds.listRelatives(obj, children=True, fullPath=True) or [] if len(children) == 1: child = children[0] objType = cmds.objectType(child) else: objType = cmds.objectType(obj) if objType == “mesh”: suffix = “geo” elif objType == “joint”: suffix = “jit” elif objType == “camera”: print “Skip!!” continue else: suffix = “grp” if obj.endswith(suffix): continue newName = shortName + “_” + suffix cmds.rename(obj, newName)

3.一个完整的代码 虽然写了中文注释,但是由于没有加字符转编码,直接复制到Maya的脚本编辑器是会报错的!!!使用时,删掉处理最合适!

from maya import cmdsSUFFIXES={ “mesh”:”geo”, “joint”:”jnt”, “camera” : None, “ambientLight”:”lgt”}DEFAULT_SUFFIX=”grp”def rename(isselection=False):#总之用六个双引号隔开的是和#一样的注释 “”” This funcition is used to change objects name Args: isselection:Wheather use the orignl selection Returns: changed series of objects “”” #获取当前选择 objects = cmds.ls(selection=isselection,dag=True,long=True) # 如果没有选择任何东西 就报错“打咩达内”并停止代码 if isselection and not objects: raise RuntimeError(“Da! Me! Da! Ne!”) if len(objects) == 0: objects = cmds.ls(dag=True, long=True) #依靠长度对物体序列进行排序 objects.sort(key=len, reverse=True) for obj in objects:# 根据长度对选中的物体由长到短进行排序 shortName = obj.split(“|”)[-1] # 检查是否还有子对象 # 如果有的话获取 当前对象类型 children = cmds.listRelatives(obj, children=True, fullPath=True) or [] if len(children) == 1: child = children[0] objType = cmds.objectType(child) else: objType = cmds.objectType(obj) # 依据字典根据对象类型获取后缀名称 如果没有则获取默认名称 suffix=SUFFIXES.get(objType,DEFAULT_SUFFIX) # 如果 suffix 为空 跳过当前循环对象 if not suffix: continue if obj.endswith(‘_’+suffix): continue # 重新命名对象 newName = “%s_%s”%(shortName,suffix) cmds.rename(obj, newName) #获取对象循环序号 index=objects.index(obj) # 将当前循环的对象的数组 替换为 新命名的名称 objects[index] = obj.replace(shortName,newName) # 返回数组 从而可以从外部获取到重命名的对象 return objects 四.创建齿轮脚本

基于管道的模型,每隔一个面挤出一次,然后给定外围细分数以及挤出长度,根据该思路,获得一个简易的函数来创建齿轮

1.基础的创建齿轮

from maya import cmdsdef creatGear(teeth=10,length=0.3): “”” This funcition weill create a gear Args: teeth: the number of teeth tocreate length: the length of the teeth Returns: A tuple of the transform,construct and extrude node “”” spans=teeth*2 #create a pipe with spans transform,construct=cmds.polyPipe(subdivisionsAxis=spans) sideFaces = range(spans*2,spans*3,2) cmds.select(clear=True) for face in sideFaces: #’%s.f[%s]’%(transform,face)等价于transform.face cmds.select(‘%s.f[%s]’%(transform,face),add=True) extrude=cmds.polyExtrudeFacet(localTranslateZ=length)[0] return transform,construct,extrude

2.使用类

下面的类里定义了三个函数,第一个是用来初始化参数,第二个用来创建齿轮,第三个则用来改变参数;

from maya import cmdsclass Gear(object): def __int__(self): self.transform=None self.extrude=None self.construct=None def createGear(self,teeth=10,length=0.3): spans=2*teeth self.transform,self.construct=cmds.polyPipe(subdivisionsAxis=spans) sideFaces=range(spans*2,spans*3,2) cmds.select(clear=True) for face in sideFaces: cmds.select(‘%s.f[%s]’ % (self.transform, face), add=True) self.extrude = cmds.polyExtrudeFacet(localTranslateZ=length)[0] #return transform, construct, extrude def changeTeeth(self,teeth=10, length=0.2): spans = teeth * 2 cmds.polyPipe(self.construct, edit=True, subdivisionAxis=spans) sideFaces = range(spans * 2, spans * 3, 2) faceNames = [] for face in sideFaces: faceName = ‘f[%s]’ % (face) faceNames.append(faceName) cmds.setAttr(‘%s.inputComponents’ % (self.extrude), len(faceNames), *faceNames, type=”componentList”) cmds.polyExtrudeFacet(self.extrude, edit=True, ltz=length)

配套的Maya中的代码如下

import Class_CreateGear as GearCreatorreload(GearCreator)gear=GearCreator.Gear()gear.createGear()print gear.extrude 五.时间轴插入脚本

1.Pycharm中的代码

from maya import cmdsdef tween(percentage,obj=None,attrs=None,selection=True): “”” 该函数根据前后帧以及占比,绘制中间帧 Args: percentage:百分比占比 Returns: 设置中间关键帧 “”” #若无参数且没有选择对象的话报错 if not obj and not selection: raise ValueError(“No object given to tween”) #若无参数,选择当前所在的帧 if not obj: obj = cmds.ls(selection=True)[0] #若无参数列表,设置关键帧属性 if not attrs: attrs=cmds.listAttr(obj,keyable=True) #获取当前帧 currentTime=cmds.currentTime(query=True) #遍历参数列表 for attr in attrs: #Construct the full name of the attribute with its object attrFull = ‘%s.%s’%(obj,attr) # Get the keyframes of yhe attribute on this object keyframes=cmds.keyframe(attrFull,query=True) #if there are no keyframes,then continue if not keyframes: continue #存储当前帧以前的帧 previousKeyframes = [] # 循环所有的关键帧 获取当前时间以前所有的关键帧 for frame in keyframes: if framecurrentTime] #获取离当前帧最近的前一个帧 if not previousKeyframes and not laterKeyframes: continue if previousKeyframes: previousFrame=max(previousKeyframes) else: previousFrame=None nextFrame = min(laterKeyframes) if laterKeyframes else None if not previousFrame or not nextFrame: continue # 获取前后帧的关键帧信息 previousValue=cmds.getAttr(attrFull,time=previousFrame) nextValue=cmds.getAttr(attrFull,time=nextFrame) difference=nextValue-previousValue weightDifference=(difference*percentage)/100.0 currentValue = previousValue+weightDifference #根据前后帧设置当前帧 cmds.setKeyframe(attrFull,time=currentTime,value=currentValue)

Maya中的代码

import twennerUIreload(twennerUI)#这里是设置百分比为20twennerUI.tween(20)

2.Maya中的UI编写

下面的代码是从help里摘来的一段

import maya.cmds as cmds#第一行用来创建窗口,窗口名称,icon和初始宽高window = cmds.window( title=”Long Name”, iconName=’Short Name’, widthHeight=(200, 55) )#用来设置排布的布局cmds.columnLayout( adjustableColumn=True )#设置按钮UIcmds.button( label=’Do Nothing’ )cmds.button( label=’Close’, command=(‘cmds.deleteUI(”‘ + window + ‘”, window=True)’) )#设置父节点用‘..’表示cmds.setParent( ‘..’ )#展示窗口cmds.showWindow( window )

其效果如下:

3.创建时间轴脚本的UI

class TweenWindow(object): #定义窗口的名称 windowName = “TweenWindow” #用于展示UI的函数 def show(self): #判断是否存在该名称的窗口,有则删除 if cmds.window(self.windowName, query=True, exists=True): cmds.deleteUI(self.windowName) #创建窗口 cmds.window(self.windowName) #在窗口的面板里面添加一些其他UI self.buildUI() #展示UI cmds.showWindow() #构建其他UI的函数 def buildUI(self): column=cmds.columnLayout() cmds.text(label=”使用这个滑条来调节参数”) row=cmds.rowLayout(numberOfColumns=2) self.slider=cmds.floatSlider(min=0,max=100,value=50,step=1,changeCommand=tween) cmds.button(label=”重置”,command=self.reset) cmds.setParent(column) cmds.button(label=”关闭”,command=self.close) #重置的函数 def reset(self,*args): cmds.floatSlider(self.slider,edit=True,value=50) tween(50) #窗口关闭函数 def close(self,*args): cmds.deleteUI(self.windowName)

效果如下图

六.工具保存

1.完善制作齿轮的工具

首先根据前面学到的UI的写法,完善了下之前的齿轮创建的工具,给它加上了UI相关的代码,效果如下

新建了一个管控UI的脚本,然后其主要代码如下,引用到了之前写的齿轮函数,然后比起视频稍微改了一部分,使得UI看起来舒服些,然后使效果更符合每个按钮,问题是在点击重置按钮后,再继续调节滑条好像变得容易闪退了:

还有就是参数由于添加了些,命名可能稍微有点乱(就那么一点点)

# coding=gbkfrom maya import cmdsfrom Class_CreateGear import Gearclass GearUI(Basewindow): windowName = “齿轮制作” def __int__(self): self.gear= None def buildUI(self): column=cmds.columnLayout() cmds.text(label=”使用该工具来设定齿轮”) cmds.rowLayout(numberOfColumns=3) self.label1 = cmds.text(label=”齿数”) self.slider=cmds.intSlider(min=5,max=30,value=10,step=1,dragCommand=self.modifyGear) self.label = cmds.text(label=”10″) cmds.setParent(column) cmds.rowLayout(numberOfColumns=3) self.label1 = cmds.text(label=”齿轮伸出长度”) self.slider1 = cmds.floatSlider(min=0, max=10, value=0.2, step=0.01, dragCommand=self.modifyGear1) self.label2 = cmds.text(label=”0.2″) cmds.setParent(column) cmds.rowLayout(numberOfColumns=2) cmds.button(label=”制作齿轮”,command=self.makeGear) cmds.button(label=”重置”,command=self.reset) cmds.setParent(column) cmds.rowLayout(numberOfColumns=2) cmds.button(label=”完成”, command=self.finish) cmds.button(label=”关闭”, command=self.close) #根据滑条制作齿轮的函数 def makeGear(self,*args): teeth = cmds.intSlider(self.slider, query=True, value=True) length = cmds.floatSlider(self.slider1, query=True, value=True) self.gear =Gear() self.gear.createGear(teeth=teeth,length=length) #修改齿轮齿数 def modifyGear(self, teeth): cmds.text(self.label, edit=True, label=teeth) length = cmds.floatSlider(self.slider1, query=True, value=True) if self.gear: self.gear.changeTeeth(teeth=teeth,length=length) # 修改齿轮伸出长度 def modifyGear1(self, length): teeth = cmds.intSlider(self.slider, query=True, value=True) cmds.text(self.label2, edit=True, label=length) if self.gear: self.gear.changeTeeth(teeth=teeth,length=length) #重置 def reset(self,*args): #self.gear=None cmds.intSlider(self.slider,edit=True,value=10) cmds.floatSlider(self.slider1, edit=True, value=0.2) cmds.text(self.label,edit=True,label=10) cmds.text(self.label2, edit=True, label=0.2) self.gear.changeTeeth(teeth=10,length=0.2) def finish(self,*args): self.gear = None cmds.deleteUI(self.windowName)

2.保存到工具架

首先文件->将脚本保存至工具架选项

输入名称后,并选择Python保存后,它显示到了当前工具栏的最后面

右键图标,选择编辑,进入面板,命令填对应的代码,其他设置则是在工具架那里进行编辑

然后我们的第一个完整的工具就算完成了!

最后,在学习过程中也有看到有大佬早已完成的笔记,不过还是自己手过了一遍,自己再记录下比较能加深印象。如果感觉本篇有不足,可以参考下大佬的。 这里把链接贴到最后 https://blog.l0v0.com/posts/5c26d29c.html https://www.cnblogs.com/3lina/p/11727793.html


比丘资源网 » Python for Maya DCC工具插件开发学习记录(一)

发表回复

提供最优质的资源集合

立即查看 了解详情