Alembic/Particle support from Houdini

Hello -

I work for a small visual effects company that primarily uses Blender for 3D projects, and we have just recently been starting to work Houdini into our pipeline for simulations and crowds.

The ideal scenario would be importing Alembic data for the simulation (which Houdini natively exports) or any sort of transferable particle data, then finishing and rendering through Cycles. Unfortunately, support for this is not currently available. Alembic support was allegedly in development for Project Gooseberry, but nothing has been released and it’s hard to find any recent information on their progress.

Another option is to mesh the simulations in Houdini then export them via OBJ sequence to Blender. There are currently two OBJ sequence add-ons: Importing the sequence to Shapekeys, and Meshfoot. Unfortunately, importing to Shapekeys cannot support non-rational meshes (with vertices spawning and dying, as in any particle system); Meshfoot is reported to have support for that, but we cannot find a version that’s compatible with any recent version of Blender. Whatever the solution ends up being, it must support non-rational meshes to really be usable.

Some questions for you experts:

  1. Does this request even seem possible? I admit outright that I know very little about the internal workings of Blender, so the hope for Alembic (or a similar interchange format) may just be a pipe dream.

  2. If it seems possible and one of you would like to step forward, what kind of cost can we expect? Please PM me with rate details.

Thanks in advance. I’ll try to answer questions, concerns, or suggestions as able.

Moved from “Jobs > Paid Work” to “Support > Particles and Physics Simulations”

This seemed more like a support request than an offer for a job. Please PM me if I’ve misunderstood.

If you’ve tested Meshfoot on a compatible version of Blender and it works with Houdini you shouldn’t have any issues saving the .blend from an older version of Blender and importing it into the newest version of Blender.

Fweeb - It’s sort of a combination of both. If there’s not a solution through typical support, we are willing to pay a freelancer (or freelancers) to help us develop a solution for our pipeline.

Shajuke - We have tried locating old versions of Meshfoot but the download links appear to have been removed. I tried following link trails through Atom’s threads and they all loop back around to eachother. If you know of a place where it’s still available for download, please let me know!

Lumpengnom - I will certainly check out your add-on, but I’m a little confused about the instructions, which begin with importing the OBJ. One of our primary issues is that we currently do not have a way to import an OBJ sequence with differing vertices per frame. Am I misunderstanding?

Thanks everyone for your replies.

If you import your OBJ sequence you have to either import every sinlge file by hand or via script. You will have one mesh per frame in your scene. This can result in obsenely large .blend files as things like fluids can have very large vertex counts.

The point of the addon is to:

  • import the obj sequence somehow
  • run the script which turns the sequences into fluid cache file
  • delete the obj sequence.

This makes the scene vastly faster, smaller and a lot better to handle.

For importing the obj sequence itself you can run the following script. Note that you will have to modify it regarding start, end, file name and some other things.
Esspecially the filepadding is important or else the script won´t work. So if your obj sequence files are called: yourOBJ_001.obj, yourOBJ_002.obj, yourOBJ_003.obj … you would have to put a 3 in the file padding line. At the moment it says {0:0>6} and you´d have to change it to {0:0>3}.
If your obj sequence files are called: yourOBJ_0001.obj, yourOBJ_0002.obj, yourOBJ_0003.obj…
you have to change the line to {0:0>4}


import bpy
framestart = 150
frameend = 200
filepath = "C:\work\Blender\\" 
filename = "MyFileName_"
filesource = filepath + filename
objectname = "MyFile.000"
objectscale = 0.01

print (filesource)

for i in range(framestart,frameend):
    mystring = str(i)
    mypadstring = "{0:0>6}".format(mystring) # Where it says: {0:0>6} the 6 is tells the scrit how much paddidng your filename has e.g.: enter 4 if your naming convention is: frame_0001 
    #print (filesource+mypadstring+".obj")
    
    bpy.ops.import_scene.obj (filepath = filesource+mypadstring+".obj", axis_forward='X', axis_up='Y', filter_glob="*.obj;*.mtl", use_edges=True, use_smooth_groups=True, use_split_objects=True, use_split_groups=True, use_groups_as_vgroups=False, use_image_search=True, split_mode='ON', global_clamp_size=0)
    bpy.context.selected_objects[0].name = objectname
    bpy.context.selected_objects[0].scale = [objectscale,objectscale,objectscale]
    bpy.ops.object.transform_apply(scale=True)

Here is also a script which automatically animates the visibilty of an obj sequence. It simply makes all meshes invisible and turns the first mesh visible on frame 1 and invisible again on frame 2. It turns the second mesh visible on frame 2 and invislbe on frame 3. And so on.
It is possible to use this but I recommend turning your sequence into fluid cache files with the addon because of the before mentioned file sizes.
After importing your obj sequence with the script above you will have a whole bunch of objects in your scene. They will all be called MyFile.000, MyFile.001, MyFile.002 and so on. If you changed the object name in the import script from MyFile to something else you will have to change the object name in this script as well. You do that in the second line of the script bellow.


import bpy

selectNameStart = "MyFile" # Enter Object Name here
myAnimList =[]
mycounter = 0

myAnimList = [obj for obj in bpy.context.scene.objects if obj.name.startswith(selectNameStart)]

#myAnimList.reverse()

print (len(myAnimList))
bpy.context.scene.frame_set(frame=0)

for i in range (0, len(myAnimList)):
    myAnimList[i].hide = True
    myAnimList[i].keyframe_insert(data_path="hide", index=-1, frame=0)
    myAnimList[i].hide_render = True
    myAnimList[i].keyframe_insert(data_path="hide_render", index=-1, frame=0)

for i in range(0, len(myAnimList)):
    print (myAnimList[i].name)
    bpy.context.scene.frame_set(frame=i)
    myAnimList[i].hide = False
    myAnimList[i].keyframe_insert(data_path="hide", index=-1, frame=i)
    myAnimList[i].hide_render = False
    myAnimList[i].keyframe_insert(data_path="hide_render", index=-1, frame=i)
    myAnimList[i].hide = True
    myAnimList[i].keyframe_insert(data_path="hide", index=-1, frame=i+1)       
    myAnimList[i].hide_render = True
    myAnimList[i].keyframe_insert(data_path="hide_render", index=-1, frame=i+1)