前言

  最近迷之忙碌,因为回学校考试等各种原因,拖更了半个月了
  有些东西本来老早打算要写下记录的,奈何就是没有行动起来。

  主要是前段时间花了大量的时间开发 Maya 的 CommandLauncher
  然而我开发完了之后其实并没有怎么使用起来,只能说新的使用方式我还是不怎么习惯。
  有时间一定要完善一下 github 的仓库,并且记录一下开发过程遇到的坑。


  上次我有提到第一次使用 3ds Max 的 Python Pyside 写了一个工具界面 链接
  然而 3ds Max 对python的支持果然非常不友好
  制作人员经常向我反馈插件导致 3ds Max 崩溃 (:з」∠)
  按照之前的经验,删掉 Max 的用户配置就好了 视频

  但是这样只是治标不治本,没有办法从根本上解决问题,于是还需要我进一步研究到底是哪一个操作导致 Max 的崩溃。

崩溃截图

Max 崩溃查找

  这种不稳定的崩溃问题对我来说做难受的就是没有办法复现问题。
  的确每次去到制作人员那里发现 插件一打开就导致 Max 崩溃了
  为了找到问题,我干脆让制作人员将他电脑的 Max 配置发送给我
  然而当我将他的配置拷贝到我自己的电脑上时,却又是一切正常的,真的让我跪了

  因此没办法,我只好占用了制作人员的电脑进行测试。
  既然删掉所有配置可以正常使用,我有理由相信应该是有些配置文件有问题。
  于是删除的过程中,发现个人文件夹有的文件被 Max 占用了,无法处理。
  只好将所有的 Max 程序关闭,然后清理文件。
  结果打开 Max 之后,插件就正常了,于是我强烈怀疑是文件夹有什么有问题的配置。

  于是我找回之前发送给我的配置压缩包,看看运行会不会报错。
  可是气人的情况出现了,居然还原了配置之后运行时一切正常的(:з」∠)

alt

  真的是迷惑行为大赏。
  我也不知道自己是怎么的就想到了,刚才的崩溃的时候 Max 是多开的
  于是我问了制作人员,制作人员居然反馈只有多开的 Max 才会崩溃!

  纳尼!~
  于是我立马多开了个Max,测试运行python,崩溃复现,破案了(:з」∠)

  这大概率是 Max 2017 的BUG,我在自己的 Max 2017 上测试也是一样的问题
  这就让人难受了,没想到 Max 对 python 的操作有这么多问题,还是 Maya 香啊~!

MaxScript 解决方案

  知道是 Python 的问题就好办了,将插件改写为 MaxScript 就好了
  而且 Max 老一点的版本(3dsMax 2014)都不支持 Python 写插件,真的是太落后(:з」∠)
  这可能好 Max 的框架不是使用 Qt 有关,官方貌似更加推荐使用 C# 的 .Net 框架来编写插件
  不过这方面还不甚了解,基本上依靠官方文档的说明来解决 MaxScript 的问题吧,起码还能凑合着用。

  这次重新翻了官方文档,总算是发现 Max 的索引目录
  虽然Max没有mel文档的搜索来得那么方便,不过这个 API 文档还算是清晰了,各个模块分类都很齐全。
  基本上有问题就在上面查就对了。

  用 MaxScript 重写 Pyside 界面遇到的问题就是没有办法UI 修改大小。
  默认 CreateDialog 连 resize 都没有加上,需要手动添加,而且只能修改窗口大小,UI组件大小不变,真的是上个世纪的组件开发逻辑了,莫名回想起 VB 的时代。

alt

  从上图可以看到我用 MaxScript 改写了之后,Maxscript在界面开发还是不太友好的,而官方的FBX设置窗口却是支持的。
  FBX插件的设置窗口我自己没有考证过,但是大概率是基于 .Net 编写的,因此要解决这些零碎的交互问题还是需要进阶的工具支持。
  Maxscript 对 .Net 的支持还是比较有好的,甚至可以将 .Net 的库转换为 MaxScript 的对象, 文档

  所以用 max 开发界面需要学习 Windows 的界面开发 WPF 才行。
  因为是完全基于 Windows 平台的,导致没法借助 Qt 实现跨平台,Max目前只支持 Windows 平台(:з」∠) 参考1 参考2
  当然跨平台技术其实并非做不到,这口锅还是需要 自动桌 去背,我只能表示 Maya 真香!~


  折腾了一番之后,还是回到 MaxScript 的界面编写上。
  虽然 Maxscript 的界面写起来各种别扭,但是好歹还是有自己的界面开发工具,比 Mel 写起来要舒服一点。
  这个部分还是 Digital Tutors 的教程非常有用,我也是看教程学习的

alt

  界面其实基本上就按照上面的 rollout编辑 就可以解决了
  Python 转 Maxscript 还遇到了个问题,就是需要实现文件的读写,以及一些字符串的操作

  借助上面文档基本上解决了我大部分的开发问题。
  文档也和Mel一样比较友好,都有代码示例可以参考,不懂可以运行测试来理解。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
MF_FBXEXP_FILE = (GetDir #temp) + "/MF_FBXEXP.txt"
content = ""
if (doesFileExist MF_FBXEXP_FILE) then(
temp_stream = openFile MF_FBXEXP_FILE mode:"r"
content = readLine temp_stream
close temp_stream
)

-- 防止窗口多开
try(DestroyDialog FBX_Export)catch()
rollout FBX_Export "MoreFun - FBX Export Tool" width:293 height:104
(
button 'Options_BTN' "FBX Output Options" pos:[18,16] width:257 height:21 align:#left
edittext 'Path_LE' "Output_Path" text:content pos:[18,42] width:203 height:21 align:#left
button 'Select_BTN' "select" pos:[226,41] width:47 height:21 align:#left
button 'Export_BTN' "FBX export" pos:[18,67] width:253 height:21 align:#left

on Options_BTN pressed do
(
OpenFbxSetting()
)
on Select_BTN pressed do
(
path = getSavePath caption:"get Output Folder"
Path_LE.text = path
temp_stream = openFile MF_FBXEXP_FILE mode:"w+"
format "%" path to:temp_stream
close temp_stream
)
on Export_BTN pressed do
(
path = Path_LE.text
flag = doesFileExist path
if flag != true then(
messageBox "current directory not exist,please select a new directory"
return true
)


if selection.count != 0 then(
sel_list = selection as array
deselect sel_list
for obj in sel_list do(
select obj
path_name = path + "/" + obj.name + ".fbx"
exportFile path_name #noPrompt selectedOnly:True using:FBXEXP
)
) else (
file_name = getFilenameFile maxfilename
if file_name == '' then (
messageBox "current scene need to save as file"
return true
)
path_name = path + "/" + file_name + ".fbx"
exportFile path_name #noPrompt selectedOnly:False using:FBXEXP
)
)
)
createDialog FBX_Export

  原本代码就这么简单就可以了。
  而且那个时候写代码还不知道 rollout 有 open 事件,可以让代码更加精炼的 参考

  基本上开发到这里也就把 Max BUG 的问题规避了。

后续进阶

  然而制作上的问题总是神出鬼没,制作人员居然换了 Max 2014 使用我的插件
  结果插件还是出问题了,只能说我图样图森破了。

  代码出错的地方是 OpenFbxSetting 这一行
  我又查了文档,好吧,这东西从 2017 才开始支持,旧版本都用不了(:з」∠) 参考

alt

  为了实现支持,只好自己编写个 UI 界面来解决问题
  另外还需要考虑到设置存储的问题,我将他们统统设置到存储路径的文本当中。
  具体代码可以参照 github的仓库脚本

  基本上参考上面的文档进行操作

alt

总结

  虽然文章标题是进阶版,但是其实用 Maxscript 来写插件不如说是一种倒退吧(:з」∠)
  为了稳定和兼容所做出的妥协,不过研究一下还是受益良多。

  今天抽空上传了 3dsMax 的官方教程
  不知道自己会不会抽时间去学习。
  用了 Max 之后还是觉得 Maya 香,不知道 Houdini 是否会更香。