Houdini 純帶頂點動態物件輸出給 3ds Max 的效率方式

最近案子遇到要將max的建築物在houdini碎完做好動態再輸出回去,整個流程有幾個需要注意的點是:

  • 建築物本身自帶多種材質,也就是在max裡有上多個material ID
  • 物件只有進行碎裂跟位移,面數、頂點數跟其他屬性都是固定無動態 基於第一點,要在max->houdini->max的流程下保持材質,FBX可以說是最方便的格式之一,連材質名稱都可以保留(對應primitive的shop_materialpath),要對回去很方便。

而第二點可以判定說,我們只要一個有完整資訊的物件,再讓houdini輸出point cache去移動頂點可以做到最有效率跟節省空間的方法。

houdini在原先選單輸出帶point cache的FBX會有許多問題,normal有時會跑掉,而且point cache的容量跟輸出速度都異常的大跟久,甚至在max匯入會有後續影格讀不到的問題,完全沒有point cache該有的優勢。

後來解決的方法是利用原先FBX輸出單一無動態物件,再另外以script輸出給max吃純帶位置資訊的point cache,PC2檔案。

本來還想說研究PC2的格式自己去寫,沒想到已經有大神研究好了,如果有興趣可以參閱這篇文章

在這邊直接引用 glassman3d 大的script:

import sys
import struct


def doCache():
    sf = hou.evalParm("startframe")
    ef = hou.evalParm("endframe")
    sr = 1
    ns = (ef - sf) + 1
    geo = hou.pwd().geometry()
    points = geo.points()
    np = len(points)

    pc2File = open(hou.evalParm("file"), "wb")

    with hou.InterruptableOperation("PC2 Cache",open_interrupt_dialog=True) as operation:


        with hou.InterruptableOperation("Exporting %s" % hou.pwd().name(),open_interrupt_dialog=True) as export:

            # Write header
            headerFormat='<12siiffi'
            #headerStr = struct.pack(headerFormat, 'P','O','I','N','T','C','A','C','H','E','2','\0', 1, np, sf, sr, ns)
            headerStr = struct.pack(headerFormat, "POINTCACHE2\0", 1, np, sf, sr, ns)
            pc2File.write(headerStr)


            for f in range(sf, sf+ns, sr):
                hou.setFrame(f)
                pos = geo.pointFloatAttribValuesAsString("P")
                pc2File.write(pos)
                export.updateProgress( f/ns )
                operation.updateLongProgress(0.5 * (f/ns) )

        with hou.InterruptableOperation("Finishing",open_interrupt_dialog=True) as finish: 


            pc2File.flush()
            pc2File.close()
            finish.updateProgress(1)
            operation.updateLongProgress(1)