Jump to content

MDD Export To Blender Mesh Cache


Atom

Recommended Posts

Hi All,

 

I have put together a short script that will convert an animated Houdini geometry network into a MDD file. This only works for geometry that has the same number of vertices throughout it's entire animation, such as RBD simulations.

 

Usage:

Open the attached HIP file and take a look at the network. There is a Python node, which contains the MDD export code, and a ROP Output Driver. Use the ROP Output Driver to export a single OBJ file from the first frame of the animation. Then execute the Python script by advancing to the next frame and it will create a MDD file with all the point cloud animation information. The resulting files end up on the Desktop (english spelling)

 

Inside Blender import the single OBJ file then add a Mesh Cache modifier to it and browse to the MDD file. That's it. This technique is kind of like emulating the File node from Houdini inside of Blender as far as performance is concerned. Most lightweight animations will playback quickly or in real time.

# Export the current geometry as a Lightwave MotionDesigner file. (i.e. MDD).
# This exporter will play the timeline and record all point changes on each frame.
# NOTE: The same number of points are expected to exist on every frame. (The nature of the file format)
# (c) 2016 Atom

import os
from struct import pack

# Construct paths.
node_root_path = '/obj/geo1/OUT_GEO'                    # Could this be fetched from a selection?
export_name = "%s.mdd" % hou.expandString("$HIPNAME")    
home = os.path.dirname(os.path.expanduser("~"))
desktop = os.path.normpath(os.path.join(home, 'Desktop'))
export_dir = os.path.normpath(os.path.join(desktop, 'Houdini2MDD'))
file_output = os.path.normpath(os.path.join(export_dir, export_name))

# Create the export directory if it does not exist.
if not os.path.exists(export_dir):
    os.mkdir(export_dir)

def zero_file(filepath):
    file = open(filepath, 'w')
    file.write('\n')  # apparently macosx needs some data in a blank file?
    file.close()

def check_vertcount(geo, vertcount):
    if len(geo.points()) != vertcount:
        raise Exception('Error, number of verts has changed during animation, cannot export')

def save(node, filepath="", frame_start=1, frame_end=16, fps=24.0):
    orig_frame = int(hou.timeToFrame(hou.time()))                                       # Initial frame we are starting on.
    hou.setFrame(frame_start)

    geo = node.geometry()
    numverts = len(geo.points())                                                        # Save the number of verts on the starting frame.
    numframes = frame_end - frame_start + 1

    f = open(filepath, 'wb')                                                            # no Errors yet:Safe to create file
    f.write(pack(">2i", numframes, numverts))                                           # Write the header
    f.write(pack(">%df" % (numframes), *[frame / fps for frame in range(numframes)]))   # Write the frame times (should we use the time in seconds?)

    #rest frame needed to keep frames in sync
    check_vertcount(geo, numverts)
    f.write(pack(">%df" % (numverts * 3), *[axis for v in geo.points() for axis in v.position()]))

    for frame in range(frame_start, frame_end + 1):                                     # in order to start at desired frame
        hou.setFrame(frame)
        check_vertcount(geo, numverts)
        # Write the vertex data
        f.write(pack(">%df" % (numverts * 3), *[axis for v in geo.points() for axis in v.position()]))

    f.close()
    hou.setFrame(orig_frame)                                                            # Return to the original frame #.

#node_to_evaluate = hou.pwd()               # Note: using self does not seem to transfer animation, use one node up does.
node_to_evaluate = hou.node(node_root_path)
save (node_to_evaluate,file_output,`$FSTART`,`$FEND`,`$FPS`)

ap_MDD_python_export_1b.hipnc

Edited by Atom
Link to comment
Share on other sites

Atom, was speaking about MDD rops as f1480187 said :). Works perfectly well for blender.

 

@Mandrake0: Nice initiative you took with your exporter. Are you aware of the alembic branch being developped (first commit by a company called DwarfLabs).

It's still under review but ll 'maybe' make it for next release and should add basic support for alembic i/o. Here is the diff if you wan't to build : https://developer.blender.org/D1783

 

Happy blending with houdini :)

Edited by boby
Link to comment
Share on other sites

Thanks for the feedback, I feel silly. Oh well, at least I learned a little more about coding between 3D packages.

 

When I export a MDD file using the MDD Point Cache it has the same exact file size as the file I exported using my code. Both of them work but I think the built-in node is a little easier to use.

Edited by Atom
  • Like 1
Link to comment
Share on other sites

Atom, was speaking about MDD rops as f1480187 said :). Works perfectly well for blender.

 

@Mandrake0: Nice initiative you took with your exporter. Are you aware of the alembic branch being developped (first commit by a company called DwarfLabs).

It's still under review but ll 'maybe' make it for next release and should add basic support for alembic i/o. Here is the diff if you wan't to build : https://developer.blender.org/D1783

 

Happy blending with houdini :)

 

thank you boby,

 

yes i know that there will be a alembic importer for blender it wasn't for me sure when it gets public. my target was to make a export that works better for simulated fluid that could be used in blender with the current cache reader. 

the funny or worse one was that i had to create first a importer in houdini because i couldn't find the specification for bobj! and when i have tested my exports blender just crashed so the debugging wasn't a lot of fun (also houdini has crashed sometimes!). 

so most of the time approx. 90% was for the importer and get the information about bobj a working exporter was simple to make. the best one i find if the docs where there a importer could have been made in below 1h of python coding! 

 

i hope that blender gets a good alembic implementation but it is a big task and it looks that this one from Dwarflabs is not completed.

 

there is also the possibility for a houdini engine integration(thanks to thrift) but for that i need more c++ knowledge and much much more time.

 

i try to finalize it next week have got some other task todo.... if somebody wants the current state of code just ask.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...