前言

  开发这个工具的时候,张峥的意思是说将多张图片合成成视频,然后通过RV播放器播放视频来切换不同的帧画面。
  所以需要我渲染出多张不同的图片然后合成成视频

检查功能开发

最近开发检查工具,需要固定好摄像机并且拍屏,拍出来的图片还需要合成成视频。
在这个期间遇到了不少的坑,在这里总结一波。

ffmpeg 视频合成

因为检查功能需要将图片合成为视频,前辈给我提供了两个方案,一个是RV播放器的视频合成,另一个则是万能的 ffmpeg
前辈其实更推荐使用 RV 播放器,我也根据他的思路去学习观摩了 RV 播放器的大概
RV播放器提供了大量命令行命令 可以实现很多复制的操作 (本质上和 ffmpeg 差不多)
后面的二次开发也可以大量借助 RV播放器的功能实现更友好的交互。
不过我考虑到 RV播放器的合成功能 需要安装,产线上并不能保证所有人都安装 RV 播放器
因此最后还是 ffmpeg 真香,毕竟只需要放在服务器上就可以顺利合成,何乐而不为。

其实 ffmpeg 并不坑,网上有大量的使用案例,可以参考学习。

ffmpeg

matadata 处理

前段时间和张峥前辈讨论如何给视频添加上一下备注信息
我们预期不要额外的信息存储文件,直接写到视频当中,可以读取出来。
那么数据不仅在视频当中,还不影响视频的播放,就涉及到下面的metadata的写入了。

最初我原以为给文件写入meta信息是非常简单的事情,毕竟在windows的文件详情下面都可以轻松修改文件的描述内容
那么我相信通过一些工具,是可以添加自定义的描述,甚至是扩展更多的信息。

经过一个下午的搜索之后,我就陷入了巨坑之中。
最初其实前辈只需要在视频当中嵌入信息即可,但是我觉得meta信息很简单,应该任何的文件都可以嵌入信息。
然而经过努力之后我发现网上并没有很好处理 metadata 的工具。
图片的 meta 信息 、 视频的 meta 信息 都是有相关的规定标准的,所有的信息都是按照这个标准来的。
在图片领域中这个标准还是日本指定的 exif
换而言之,除此之外的文件因为没有标准是无法直接嵌入 meta 信息的(其实网上有通过C#实现的方案,但是python这边找不到)
同样 python os 库 里面可以获取文件的修改时间,但是却无法修改这个 meta 信息

当然万能的python什么都有,第三方库也少不了,但是经过一番摸索之后,在youtube上找到了个视频,称python库只能获取极其少量的信息。
视频推荐使用 exiftool 工具,这个工具类似于 ffmpeg ,直接敲命令行获取数据。
于是我开始研究 exiftool 工具的使用方法,在网上还找到了 exiftoolGUI 的图形化界面。
不过这个界面从2012年到现在就没有更新过了。
然而搞了好长一段时间之后,居然发现 exiftool 无法修改视频的meta信息。

最后的最后只好绕回来按照前辈的说法 使用 ffmpeg 添加视频的 meta 信息
而且前辈也补充道 我们目前压根用不上图片的信息

exiftool

不过话说回来 exiftool 也可以获取到视频的信息,而且获取的信息比 ffmpeg 详细很多,可以先记录着,说不定以后管用。

Arnold 渲染输出

拍屏这个操作其实并不困难,就是maya playblast 命令
然而除了 playblast 之外 还需要 Arnold 的渲染输出,这个着实是个难题。
这次遇到的问题和过去的maya命令问题大不相同。
当你使用arnold渲染的时候,你会发现压根就没有任何相关的 Arnold 命令回显
于是我尝试查找关于 渲染输出 的 cmds 命令回显
我发现了 render 命令,然而这个坑爹的命令是给 maya software 渲染用的
尽管这个坑有点大,也并非完全无从下手的。
虽然 Arnold 专属的渲染窗口完全没有代码回显,而且 Arnold 貌似有它自己的API
不过在 Maya 的渲染窗口当中还是可以看到输出的痕迹的,只是这个痕迹让人奔溃得很。

Arnold渲染

Arnold渲染

Arnold渲染

Arnold渲染

这里面有很多无关的代码参杂其中。
经过我长时间的研究提炼 最后 我成功将渲染的核心代码提取了出来

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
path = "输出路径"
# Note 用 Arnold 渲染
if cmds.getAttr("defaultRenderGlobals.currentRenderer") != "arnold":
cmds.setAttr("defaultRenderGlobals.currentRenderer", "arnold", type="string")
# Note 找到当前渲染窗口
editor = cmds.renderWindowEditor(q=True, editorName=True )
# Note 开启渲染
cmds.RenderIntoNewWindow()

# Note 以jpg的格式存储图片
import maya.app.general.createImageFormats as createImageFormats
formatManager = createImageFormats.ImageFormats()
formatManager.pushRenderGlobalsForDesc("JPEG")
# Note 从渲染窗口输出图片
cmds.renderWindowEditor(editor, e=True ,com=1,wi=path)
formatManager.popRenderGlobals()

# Note 刷新 - 避免影响到拍屏操作
cmds.refresh()

效果总结

Arnold渲染

最后和徐思建他们对接之后 就不再需要 Arnold 渲染的部分
只需要拍屏出视频即可,比之前还要简单

模型穿插检查

昨天我开始开发模型穿插相关的工具
原本 Maya 是有 cleanup 工具 ,已经非常全面地涵盖了很多检查相关的内容
但是如果模型有穿插的情况是无法检测出来的

穿插

虽然上面的截图稍微极端了
不过这种效果是无法通过 cleanup 解决的

于是我在网上查找 intersect 相关的解决方案,查了很多也没有好的idea
虽然我找到了一篇关于 intersect 的说明文章,但是实现的效果似乎和我们预期的大相径庭
于是我尝试自己研究
经过我昨晚的不懈努力,我研究出了一个方案,遍历物体所有的边,并从边上选取点发射射线,如果边与模型其他的面有交点,那就可以说明这条边和模型是由穿插了。
我认为思路是正确的,然而问题在于射线的方向无法确定
我将这个问题反馈给师兄,师兄建议我用叉乘来解决角度
经过我的测试,我发现问题并不在这个地方。

OpenMaya 有 AllIntersecions 命令 通过定义 光线发射源和光线方向 来定义碰撞
我从 MItMeshEdge 获取的迭代器 可以获取到边相连的两个顶点
然而这两个顶点的次序是没有办法判断,我每次都是固定 第一个点的坐标 减去 第二个点坐标 获取方向
然而发射源有可能导致这个方向完全相反
我思考了很长时间也没有结果,于是亲自找师兄解决问题,不过还是无果。
最后我想到了可以获取边上的中点来辅助判断方向,用一个点减去中点获取方向那么发射源就必然是另一个点

穿插