Skip to content

Instantly share code, notes, and snippets.

@howiemnet
Created August 22, 2019 15:31
Show Gist options
  • Save howiemnet/f99aa19e1d9a80e23029f2cf465bb565 to your computer and use it in GitHub Desktop.
Save howiemnet/f99aa19e1d9a80e23029f2cf465bb565 to your computer and use it in GitHub Desktop.
Houdini to Blender camera animation exporter
# Houdini to Blender camera exporter thingy
# [email protected] / 22 Aug 2019
#
# v1.0: hacky but seemingly working
#
# Pop this into a toolbar button's script window in Houdini
# Select a camera (or a camera switcher) and press the button
#
# A newly generated python script is now on the clipboard.
#
# Open Blender (tested w 2.79), ensure the Cycles Render mode is
# selected. (This is necessary for DoF / focus distance stuff to
# import correctly - nothing to stop you changing to a different
# renderer after the import though)
#
# In a text window, hit New and then Ctrl-V to paste the script in
#
# Rename the text block so it has ".py" on the end of its name
# Hit the Execute Script button
#
# A camera will be created and keyframes created. Should match the
# camera from the Houdini scene perfectly.
#
# Notes:
# - you'll need to set up the other parts of the scene, frame rate
# and range, resolution etc.
#
#
# Todo:
# - error checking
# - perhaps create separate cams when a switcher is in use?
import hou
# convenience degree-to-radians factor
dtr = 3.141592654 / 180.0
theNodes = hou.selectedNodes()
h = theNodes[0]
startFrame = int(hou.playbar.playbackRange()[0])
endFrame = int(hou.playbar.playbackRange()[1])
# scale = 100.0 -oops - not implemented in this version
camNode = h
if h.type().name() == 'switcher':
camNode = h.inputs()[h.parm("camswitch").evalAsIntAtFrame(startFrame)]
# spew out all the headery stuff first
myOutputString = "# script created by h's Houdini to Blender script\n\n"
myOutputString = myOutputString + "import bpy\n\n"
myOutputString = myOutputString + "# create a camera and camobject\n"
myOutputString = myOutputString + "camdata = bpy.data.cameras.new(\"theCamData\")\n"
myOutputString = myOutputString + "camobj = bpy.data.objects.new(\"theCamObj\", camdata)\n\n"
myOutputString = myOutputString + "# link into scene and make active\n"
myOutputString = myOutputString + "bpy.context.scene.objects.link(camobj)\n"
myOutputString = myOutputString + "bpy.context.scene.camera = camobj\n\n"
myOutputString = myOutputString + "bpy.data.scenes[0].update()\n\n"
myOutputString = myOutputString + "# set up camera stuff\n"
myOutputString = myOutputString + "camdata.sensor_width = " + str(camNode.parm("aperture").evalAsFloatAtFrame(startFrame)) + "\n"
myOutputString = myOutputString + "camdata.cycles.aperture_type = 'FSTOP'\n\n"
myOutputString = myOutputString + "# create some animation data for the cam (lens stuff) and the object (loc / rot)\n"
myOutputString = myOutputString + "camobj.animation_data_create()\n"
myOutputString = myOutputString + "camdata.animation_data_create()\n"
myOutputString = myOutputString + "camobj.animation_data.action = bpy.data.actions.new(name=\"camObjAction\")\n"
myOutputString = myOutputString + "camdata.animation_data.action = bpy.data.actions.new(name=\"camDataAction\")\n\n"
myOutputString = myOutputString + "################ ANIMATION DATA \n\n\n"
##############################################
#
# now do the frame by frame stuff
#
for theFrame in range (startFrame,endFrame+1):
# get the info we need for this frame
x = h.worldTransformAtTime(hou.frameToTime(theFrame))
rotates = x.extractRotates('srt','xyz',hou.Vector3())
translates = x.extractTranslates('srt')
# camera-specific data gets confused by switcher objects, so find
# the real camera object first
camNode = h
if h.type().name() == 'switcher':
camNode = h.inputs()[h.parm("camswitch").evalAsIntAtFrame(theFrame)]
focallength = camNode.parm("focal").evalAsFloatAtFrame(theFrame)
focusdistance = camNode.parm("focus").evalAsFloatAtFrame(theFrame)
fstop = camNode.parm("fstop").evalAsFloatAtFrame(theFrame)
##############################
#
# Apply the values
#
myOutputString = myOutputString + "camobj.location = (" + str(translates[0]) + "," + str(-translates[2]) + "," + str(translates[1]) + ")\n"
myOutputString = myOutputString + "camobj.rotation_euler = (" + str(dtr*(90+rotates[0])) + "," + str(rotates[2]*dtr) + "," + str(rotates[1]*dtr) + ")\n"
myOutputString = myOutputString + "camdata.lens = " + str(focallength) + "\n"
myOutputString = myOutputString + "camdata.dof_distance = " + str(focusdistance) + "\n"
myOutputString = myOutputString + "camdata.cycles.aperture_fstop = " + str(fstop) + "\n"
##############################
#
# Set the keyframes
#
frameString = str(theFrame)
myOutputString = myOutputString + "camobj.keyframe_insert(data_path=\"location\", index = -1, frame = " + frameString + ")\n"
myOutputString = myOutputString + "camobj.keyframe_insert(data_path=\"rotation_euler\", index = -1, frame = " + frameString + ")\n"
myOutputString = myOutputString + "camdata.keyframe_insert(data_path=\"lens\", index = -1, frame = " + frameString + ")\n"
myOutputString = myOutputString + "camdata.keyframe_insert(data_path=\"dof_distance\", index = -1, frame = " + frameString + ")\n"
myOutputString = myOutputString + "camdata.keyframe_insert(data_path=\"cycles.aperture_fstop\", index = -1, frame = " + frameString + ")\n"
myOutputString = myOutputString + "\n\n#### End of Data. Yay!\n"
hou.ui.copyTextToClipboard(myOutputString)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment