Python 编写Maya插件,从0到1(二)

本文承接上一篇文章,着重讲述Maya插件编写的从0到1的过程。结构大纲如下:

一,实现简单的Maya命令

二,安装脚本的编写

三,安装脚本的编译exe

插件最终效果:

一,实现简单的Maya命令

如视频所示,我们实现了两个功能。第一个功能就是把mesh的坐标强制回归到世界中心(0,0,0),这个功能非常有用,但是Maya中并没有(吐槽)。第二个功能就是把坐标回归到模型中心并且把模型带着坐标一起回归到世界中心(0,0,0)。

这两个功能非常简单,复杂的功能以后再讨论(有时间的话,手动狗头)。

废话不多说,上代码

#/usr/bin/env python# -*- coding: UTF-8 -*-import maya.cmds as cmdimport sysreload(sys)sys.setdefaultencoding(‘utf-8’)#解决中文问题def utf_8String(StringT): utf_8String = StringT utf_8String.encode(‘utf-8’) utf_8String = unicode(utf_8String, “utf-8”) return utf_8String

这几行代码主要是导入了Maya的命令,顺便解决下中文编码的问题。因为MayaPython只支持Python2.x,不支持3.x,所以中文编码非常蛋疼,期待下一代可以全面支持3.x,毕竟Python官方都停止维护2.x了……

def checkSelect(): list_select = [] if cmd.ls(sl = True) != []: list_select = cmd.ls(sl=True) return list_select else: return []

这个函数解决的是输入问题,cmd.ls(sl = True)就是捕获玩家在Maya中的选择(划重点!!这行代码是最常用的没有之一!!)。比如你选中了一个模型,那么这行代码获得你选中的那个模型。我们把玩家选中的所有模型信息都储存在一个叫list_select的列表里。

#坐标回归中心def centerPivot(): for i in checkSelect(): cmd.xform(i, centerPivots=True)#坐标回归到世界中心def pivotMoveToWorldPositon000(): for i in checkSelect(): Name = i cmd.move(0, 0, 0, Name+’.rotatePivot’, Name+’.scalePivot’, rpr=True) cmd.makeIdentity(Name, a=True)#强制把一切归零,毁灭吧万物凋零def meshMoveToWorldPosition000AndClean(): centerPivot() for i in checkSelect(): cmd.move(0, 0, 0, i,rpr=True) cmd.makeIdentity(i, a=True)

这几行就是实现我们视频中功能的代码。(看着简单是不……我查了半天api才写出来的orz)

def mainGui(): windowName = ‘CC_Tool’ windowTitle = ‘CC_Tool1.0’ #防止重复创建窗口 try: cmd.deleteUI(windowName) except: pass cmd.window(windowName,title = windowTitle) cmd.columnLayout(adj = True) #鼠标悬浮按钮上,会飘出来的解释说明 explain_ZeroPivot = utf_8String(‘坐标轴回归网格中心’) explain_Clean = utf_8String(‘坐标归到模型中心,模型归到网格中心’) #按钮 cmd.button(l=’ZeroPivot’,ann = explain_ZeroPivot, h=60, w=20, c=’pivotMoveToWorldPositon000()’) cmd.button(l=’ZeroMeshClean’, ann=explain_Clean, h=60, w=20, c=’meshMoveToWorldPosition000AndClean()’) #显示GUI cmd.showWindow(windowName)

这是Gui模块,我们的Gui就是……最简单的没有布局的Gui,当然,为了方便使用还是加了一个高级功能的,比如鼠标悬浮在按钮上,会飘出来功能解释说明。

mainGui()

然后就是主要代码了,就一句话,调出Gui就好了。

按一下Alt+A,就会实现视频中的效果。

二,安装脚本的编写

这里要新建一个pycharm的工程!!和Maya没啥关系,终于可以使用Python3.x了,随心所欲编写了!!

一般来说,脚本写完了,复制到脚本编辑器里,点击运行就OK了,

但是!!!这会增加美术的理解成本!!美术只关心一键安装!!降低美术的操作成本=提高美术的效率!所以这个一键安装的问题必须解决。

网上查了很久,官方成熟的插件是用c++编译的,emmm……我肯定是要自己想法子了,如何简单便捷地一键安装Python写的插件。幸好我找到了方案!!

Maya有个地方叫做工具架,你直接把自己的工具架保存好,然后找到那个工具架的位置(是个shelf.mel),用你的保存好插件的工具架,替换美术的工具架就OK了!

这个有个坏处,就是美术如果自定义一些工具,会把美术的工具栏完全覆盖掉。我之所以用这个方案,是因为美术(大多)都是Max转Maya过来的,Maya对他们来说是新工具,他们不会自定义一些工具,我去覆盖他们完全合理。但是如果有些Maya大神,自定义了很多Maya工具,那么这个解决办法仍然适用,就是会变得麻烦一些。你要用Python去读写那个shlef.mel,主动把脚本写进去。

所以接下来的问题就简单了。找到你的工具架shlef,然后复制出来,把他当做一个拷贝文件。写个脚本拷贝到美术的对应文件夹,就万事大吉了。

但是在我实践的过程中,发现了很多坑,在此分享出来: 1,有的人Maya是中文,有的人Maya是英文,这俩版本的工具栏不在一个位置 2,有的人安装Maya在C盘,有的人安装Maya在D盘,安装不在一个位置 3,我写过一个全盘搜索,坑emmm非常多,因为有些文件夹例如系统文件,会把你弹出来(我加了管理员权限都然并卵,永远有文件夹你访问不了) 4,有的人安装过2018版本或者更早的版本,各种版本的残留文件也会影响你去定位路径……各种坑

好了坑讲完了,现在说说我怎么做的吧。

首先,Maya的shlef文件在这里(中文的,安装在C盘,2019版本)

C:\Users\admin\Documents\maya\2019\zh_CN\prefs\shelves

为了让代码健壮,我在doc内创建了不少干扰项…………以便测试…………

上代码:

#/usr/bin/env python# -*- coding: UTF-8 -*-import osimport shutilimport getpass

getpass模块是为了获得你电脑的名字,一般默认叫admin,但是别人叫啥的都有。为了保证搜索的地址准确,必须获取当前电脑用户名

def search(root, target): items = os.listdir(root) for i in items: Path = root + ‘\\’ + os.path.basename(i) if os.path.isdir(Path)and i != target: temp = search(Path, target) if temp == None: pass else: return temp else: if i == target and ‘zh_CN’in Path: print(Path) return Path else: pass pass pass return None

这个是搜索函数,递归搜索文件夹(不信邪的可以使用这个试试全盘搜索……我加了无数hack都跑不通,永远报权限错误)

搜索中我有一行是if i == target and ‘zh_CN’in Path,这是中文版的匹配方法,英文版的位置会不一样,要根据需求随机应变。

myDir = os.getcwd()print(myDir)#获得用户名,类似于admin这种UserName = getpass.getuser()#定义Maya工具架的位置MayaPath = ”#这个是我们的做好的工具架所在的地方ToolShelfPath = myDir + ‘\\’ + ‘shelf_Polygons.mel’print(ToolShelfPath)#这行代码属于无奈之举,我只能默认安装在C盘,当然如果安装在D盘或者别的盘,#也可以根据具体情况总结规律进行定位查找(不定位随意查会遇到无数权限报错)path_C = ‘C:\\Users\\’+ UserName +’\\Documents\\maya’#这几行代码是为了搜索到Maya工具架所在的文件夹,定位Maya的工具架位置,listDir = os.listdir(path_C)for i in listDir: if os.path.isdir(path_C + ‘\\’ + i): root = path_C + ‘\\’ + i os.chdir(root) target = ‘shelf_Polygons.mel’ s = search(root, target) print(s) if s == None: s = ” else: MayaPath = s else: passprint(MayaPath)#找到了工具架位置,就可以欢快地把准备好的工具复制过去了if os.path.exists(MayaPath): os.remove(MayaPath) shutil.copy(ToolShelfPath, MayaPath[:-19])else: shutil.copy(ToolShelfPath, MayaPath)

这就是主要代码,具体哪行代码是干什么的,我在注释里写的很明白了。

这是我Python工程文件的位置,注意红框里的代码和我提前准备好的工具架的位置,其他的乱七八糟的属于编译之后的东西,暂时不用管,我马上就会分享下编译的东西。

这时候就可以测试下我们的脚本,是不是跑通了。

三,安装脚本的编译exe

为啥要编译exe?因为以上脚本如果想要在别的电脑上运行,首先得安装Python……我们需要的是给美术提供,无与伦比的便利!所以,可以让他们不安装任何额外的东西,一键安装插件,才是重点!!

Pycharm,把所写的代码打包非常简单!(会者不难难者不会)

首先,安装一下Pyinstaller的Packages。

安装好Pyinstaller,我们一个命令就可以编译出exe包了!

首先点击Terminal,进入控制台。

命令如图所示,然后点击回车就可以。

出现successfully就意味着编译成功了!

文件在dist文件夹里!!

这时候运行exe会不对,安装未生效,因为这里还藏着一个坑!!

注意之前的代码!

myDir = os.getcwd()print(myDir)#获得用户名,类似于admin这种UserName = getpass.getuser()#定义Maya工具架的位置MayaPath = ”#这个是我们的做好的工具架所在的地方ToolShelfPath = myDir + ‘\\’ + ‘shelf_Polygons.mel’

我们定义的myDir是当前文件夹的

ToolShelfPath是基于当前文件夹的。这个exe的当前文件夹是空的,没有我们的’shelf_Polygons.mel’。所以安装才会失败。

我们把这个玩意拖出去,和我们的test.py放到一个层级目录,就OK了!!

好啦,现在运行我们的安装exe,就可以实现一键安装了!而且这个exe可以丢到别的没有安装过Python的电脑上无障碍运行!

文章就到这里吧,Maya内写了任何插件,都可以用这个流程实现一键安装,极大方便美术。如果以后有机会的话,我会分享一些关于Maya内好用的一些功能的实现。


比丘资源网 » Python 编写Maya插件,从0到1(二)

发表回复

提供最优质的资源集合

立即查看 了解详情