Maya工作流从2017升级到2022

python,2.7,devkit

Updated on May 26, 2022 Posted by elmagnifico on May 10, 2022

Forward

最近业务需求把Maya从2017升级到了2022,弄出来了一堆问题,总结一下

Maya2023

2023版本已经出了,但是2023彻底抛弃了python2.7,继承者是python3.9,这就导致以前的Cython基本就不能用了,要重新找新的环境新的包重新编译。

并且老的python代码中其实也有很多东西,已经和3.9的python语法、库等等不兼容了,都需要一个个去修改,工作量还是非常大的。

除了pyton这里发生了改变,C++的部分依赖也发生了改变,那么对应的库都需要重新编译了。

直接适配最新2023太过麻烦了,所以退而求其次选择了2022。

(看了一下比较有名的工具,劲爆羊也没有做最新的python3的适配,而且也只推荐到2020版本)

Maya2022

2022版本默认的是python3,但是可以通过命令行,切换成python2.7。这个python2.7和maya2017的2.7是一模一样的,所以Cython并不需要重新编译。而C++的版本有所升级,需要Visual Studio 2019的相关库来编译了,还好问题不大。

python2.7启动

在启动的快捷方式上加上 -pythonver 2来启动python2.7的maya,这样老版本的很多功能都能正常适配了。

image-20220510142821399

还有一些其他办法

创建环境变量

MAYA_PYTHON_VERSION

并且将其值设置为2,就可以实现任何方式启动Maya2022都是python2.7的版本

写一个bat脚本,实现直接修改环境变量

setx MAYA_PYTHON_VERSION 2 /m 

缓存播放

从maya2019开始就有了缓存播放,为了让viewport显示加载更加流程,也省去每次人为给每个东西设置缓存的方式,直接一步到位,但是这对很多老脚本不太友好。

脚本中有很多跳帧,然后获取对象属性,之后进行烘焙或者渲染或者导出之类的操作,这种代码遇到缓存播放,会导致maya卡爆,相当于每次修改场景时间,都会导致缓存重新加载,所以如果有这种问题地方,最好直接关闭整个缓存播放

cmds.currentTime(cur_time)

image-20220510165910766

同理,粒子的重新模拟运动也会受到这个影响,可以通过取消缓存动力学来解决。

Maya修改语言

额,一直以来我都用的是错误的方法,汗颜。错误的方法会有一个好处,那就是你代码中只要用了unicode的字符,那么显示起来都没问题。而如果真的改了maya的语言,反而有可能会造成部分字符在其他语言环境中无法正确显示。

错误的方法:

通过修改汉化文件夹(C:\Program Files\Maya20XX\resources\l10n\zh_CN)变成的英文maya

只是因为maya读取不到中文界面的资源而被迫显示成为英文界面 只是看起来界面是英文版而已,并不算是真正的英文环境,它仍然披着英文界面的皮的中文版maya 而只有通过修改环境变量,才是真正英文环境的maya。

正确的方法: 关闭maya,新建一个系统环境变量

MAYA_UI_LANGUAGE

值是en_US,就可以把中文maya环境改成英文maya环境

插件分发流程

默认如果是单文件插件,直接plug-in启动就完事了,不需要很麻烦的去设置路径什么的。后来我自己弄了一个安装流程来安装插件,用起来也没啥问题。不过看了一下劲爆羊的,发现还有这种方式,流程和我的也不一样,官方的推荐方式,不过官方没说清楚,有的链接已经失效了,看起来并不完整。

https://help.autodesk.com/view/MAYAUL/2022/CHS/?guid=Maya_SDK_Distributing_Maya_Plug_ins_DistributingUsingModules_html

官方推荐的目录安排模式,比较好理解,plug-ins里面是插件的核心部分,而scripts中其实应该是启动或者加载插件的部分文件

/yourplugin/
- icons
- plug-ins
- presets
- scripts

userSetup.py

scripts中有一个很核心的东西,不知道为什么官方没说,我从羊盒的代码中猜出来的。一定会有一个userSetup.py文件,这个文件就是加载插件或者插件启动前的一些准备性工作,都应该在这里完成。(羊盒的UI按钮啥的都是从这里加载的,我说我怎么找老半天那个ScriptButton存储到了哪个配置文件,怎么都找不到)

userSetup.py

userSetup.py内容

import maya.cmds as mayaCmds
import pymel.core as pmc
import maya.mel as mel
import sys


if not pmc.about(batch=True):
    print("test if it is the first start up func")

可以从Output Window看到实际启动的输出

image-20220510164947665

需要注意不同插件的userSetup.py运行顺序是不同,他们都晚于maya\2022\scripts\userSetup.py

比如
maya/2022/scripts/userSetup.py
plugin1/userSetup.py
plugin2/userSetup.py
plugin3/userSetup.py

必然是maya的最先执行,之后才是其他的

mod

有了以上的安排目录以后,基本就可以了,剩下的就是如何告诉maya从哪里加载插件。

默认情况下,maya是没有modules这个文件夹的,需要自己创建一个

image-20220510163450321

然后将一个xxx.mod文件放入其中,maya每次启动就会扫描这个文件夹,并加载其中文件中对应的插件内容。

mod文件格式也非常简单

+ 插件名 版本号 目录

比如:

+ customplugins 1.2 ../plug-ins/
+ MS_Toolkit 5.0 C:/JBY_soft/MS_Toolkit/

mod文件可以写多个modules的加载,并且可以根据操作系统自动选择加载哪里的文件,指定加载的maya版本

+ MAYAVERSION:2020 PLATFORM:win64 <ModuleName> <ModuleVersion> <ModulePath> 
MY_PLUGIN_LOCATION:= myPlugin
PATH+:=bin
MAYA_SCRIPT_PATH+:=scripts

+ MAYAVERSION:2020 PLATFORM:linux <ModuleName> <ModuleVersion> <ModulePath> 
MY_PLUGIN_LOCATION:= myPlugin
PATH+:=bin
MAYA_SCRIPT_PATH+:=scripts

+ MAYAVERSION:2020 PLATFORM:mac <ModuleName> <ModuleVersion> <ModulePath> 
MY_PLUGIN_LOCATION:= myPlugin
PATH+:=bin
MAYA_SCRIPT_PATH+:=scripts

也可以指定系统语言,对应语言的插件

+ MAYAVERSION:2019 PLATFORM:win64 LOCALE:ja_JP CustomModule 3.10.5 ..\CustomModule\Modules\win64

mod中自定义环境变量也是可以的

MYVAR=MYVALUE

maya python命令中有以下三个可以用来获取mod文件中的信息。

getModulePath
loadModule
moduleInfo

启动问题

可能有些时候直接执行userSetup.py可能会报错statusFieldButton,因为实际的时候可能这个UI还没创建呢,这会插件已经加载了,所以需要稍微延后一些插件的加载时间。这就需要用到evalDeferred在空闲时间加载,从而避免UI还没创建的问题。

import os
import maya.cmds as cmds
import maya.mel as mel
import pymel.core as pmc


def test():
    plugin_paths = mel.eval("getenv MAYA_PLUG_IN_PATH")
    plugin_path = plugin_paths.split(';')[0]
    plugin_path = os.path.abspath(os.path.join(plugin_path, ".."))
    getProgramName = 'test'
    if cmds.iconTextButton(getProgramName, ex=True):
        cmds.deleteUI(getProgramName)
    plugin_path = plugin_path.replace('\\', '/')
    print(plugin_path)
    print(cmds.iconTextButton('statusFieldButton', q=True, p=True))
    cmds.iconTextButton(getProgramName, hi=plugin_path + '/test/icons/logo.ico', i=plugin_path + '/test/icons/logo.ico',
                        c='print("' + str(
                            plugin_path) + '");execfile(\'' + plugin_path + '/test/plug-ins/test.py\')',
                        stp='python', p=cmds.iconTextButton('statusFieldButton', q=True, p=True))


if not pmc.about(batch=True):
    print("test if there is the first start up funcs")
    pmc.general.evalDeferred('test()')

Maya快速退出带来的加载问题

Maya2022基本上都是秒退了,但是这种秒退带来了新问题,退的太快了,导致实际上插件可能并没有真的退出,文件还在被占用(经常是需要5-15s以后才能真的删除文件)。

同时还使用了pmc.general.evalDeferred延迟启动,来执行更新流程,就会出现,文件被占用无法删除替换。+

就算不使用延迟启动,而是直接处理,也会出现文件占用的问题。

这种情况下只能将处理逻辑移动到maya\2022\scripts\userSetup.py中,他是最先启动的,所以不会受到这个文件占用的影响。

Summary

先总结到这里,后面还有问题继续更新

Quote

https://help.autodesk.com/view/MAYAUL/2022/CHS/?guid=Maya_SDK_Distributing_Maya_Plug_ins_DistributingUsingModules_html

http://t.zoukankan.com/ibingshan-p-9786721.html