本文转自公众号:十二只熊
CG流程尤其是Houdini用户,文件缓存的规范一直是一个比较容易被忽视的问题,如果不加注意,随着迭代的版本数量增加、各种缓存和备份文件的逐渐堆积,整个工程目录很可能就会变成一座屎山,臃肿杂乱,无从整理。
好的目录规范在于有一个好的命名习惯,好的命名习惯应该从工程文件命名开始,工程文件的名称前缀各有标准,而后缀则往往都以版本号结尾,如:
Prj_Sc01_shot01_fx_V001.hip
但是实际工作中,如果要更清晰的保留每一个内部版本,那么只靠单个版本号显然是不够的,所以进一步的命名规范可能是这样:
Prj_Sc01_shot01_fx_V001_v001.hip
其中第一个大V表示大版本,用于标记如客户反馈、跨部门提交的外部版本;第二个小v则表示小版本,比如内部自审或自己制作过程中,为了保留不同参数设置而记录的内部版本。
大小版本号应该是常识性的命名规范,而很多用户似乎还是习惯单版本号,如果没有更完善或自动化的流程管理系统,我很好奇大家是怎么区分内外版本并进行管理的。
让我们假设一个情况——你要缓存一套数据,通过
FileCache节点
设置了一个相对路径,或者保持默认设置:
假设当前的Hip文件位置为:
C:\work\job\
vfx_test_v01.hip
那么根据以上设置,最终的缓存文件序列会存储如下:
C:\work\job\geo\
vfx_test_v01.CacheA\v01\vfx_test_v01.CacheA.v1.0001.bgeo.sc
个人习惯的原因,我其实不太喜欢这种层级结构。
首先
缓存目录层级有必要记录当前hip文件的名称
,而由于hip文件命名本身包含版本号,如果在这个基础上再加一个单独的Version层级,则目录层级内的版本信息难免过多,后续随着缓存版本和工程版本的不断增加,文件存放路径就容易变得极其混乱,难以管理:
所以我个人的默认路径设置(临时数据)如下,仅供参考:
假设当前的Hip文件路径为:
C:\work\job\
vfx_test_v01.hip
那么根据以上设置,最终的缓存文件序列路径为:
C:\work\job\
geo\temp\
CacheA\vfx_test_v01\CacheA.0001.bgeo.sc
目录层级结构如下:
如上图所示,缓存文件的版本信息会完全继承自工程文件的命名。这样的话,
缓存数据版本与工程文件版本一一对应
。相对于第一种默认设置,这种层级结构更为清晰简洁,也更便于后续的版本回溯和文件整理。
无论哪种层级规范,都会面临版本回溯的问题
。
比如某个效果在同一个工程文件内修改了N次,每次都输出了相应的缓存数据,最后发现还是第一个版本比较理想,但是此时参数调整的历史记录太多,第一个版本的具体参数设置已经丢失掉了。
这时候很多人可能干脆选择不去管它,直接把先前的缓存数据读取进来,继续下游的制作,
寄希望于交片之后再也不去动它
。
我在过手其它Houdini工程文件的时候,这种缓存文件与参数设置无法对应的问题时有出现——即
工程内部下游工作区读取的缓存文件
,与
保存下来的上游工作设置
完全对应不上,而对应的工程版本又没有保留,此时一旦需要在下游依赖版本的基础上返回上游修改,就不得不根据缓存文件的时间记录,去backup里面挨个查找自动保存的备份,如果找不到,那整个工程就相当于报废掉了。
所以这里涉及到一个
及时另存
的问题,即每次缓存完毕继续调整参数之前,最好先将工程另存,保留对应上一次缓存的工程设置记录,
这一点非常重要,也非常基础
。
当然,有时候一些微调的临时缓存好像没有必要另存太多工程版本,但是直接覆盖历史记录又有风险。所以我这里写了几行简单的代码示例,用于在每次缓存开始之前,把当前的工程文件自动拷贝到缓存文件的同级目录下,作为一对一的工程备份。
import hou
import os, shutil, time
# file_path获取缓存文件的绝对路径
file_parm = hou.parm("sopoutput")
file_path = file_parm.eval()
# 判断缓存目录是否存在
file_dir = os.path.dirname(file_path)
if(os.path.exists(file_dir)==0):
os.makedirs(file_dir)
# 保存并将hip文件拷贝到缓存目录下
hou.hipFile.save()
hip_path = hou.hipFile.path()
shutil.copy2(hip_path, file_dir)
用法是将以上代码保存为一个.py文件,放在任意位置,在