I didn't read your answer, sorry.
I have found this bvh exporter but is a bit special.
I only have found one blend file that worked.
As long as I know the armature has to be just one root. And it has to have selected before run the script.
Could a few volunteers to test this script and even if possible tweak it a bit to make it more flexible?
Thanks
Code:
#!BPY
"""
Name: 'IK Capture (.bvh)...'
Blender: 237
Group: 'Export'
Tip: 'Export a (.bvh) IK capture file'
"""
__author__ = "Jean-Baptiste PERIN"
__url__ = ("blender", "elysiun")
__version__ = "0.4 05/12/01"
__email__= ["M. PERIN Jean-Baptiste, jb_perin@yahoo.fr", "scripts"]
__bpydoc__ = """\
This script exports Empty animation to bvh file format.
Supported: Poser 3.01<br>
Missing:<br>
Known issues:<br>
Notes:<br>
"""
#----------------------------------------------
# (c) Jean-Baptiste PERIN december 2005, released under Blender Artistic Licence
#----------------------------------------------
import Blender
import math
empty_rest_ori = {}
def getRootBone(armature):
rootBone = None
for bone in armature.bones.values():
if bone.parent == None :
if rootBone == None:
rootBone = bone
else:
print"Multiple root armature not handled"
return rootBone
def getBoneCurPos(armature, bone):
lempty = Blender.Object.Get(bone.name)
return (lempty.getLocation())
def getBoneCurRot(armature, bone):
lempty = Blender.Object.Get(bone.name)
return (lempty.getMatrix('worldspace'))
def getBoneRestPos(armature, bone):
return (bone.head)
def getBoneRestRot(armature, bone):
lempty = Blender.Object.Get(bone.name)
return (bone.matrix)
def indentString(i):
string = ""
for v in range(0,i):
string += "\t"
return string
def printBoneHierarchie (armature, bone, level):
str = "%sJOINT %s\n"%(indentString(level), bone.name)
str += "%s{\n"%indentString(level)
str += "%s\tOFFSET %f %f %f\n"%(indentString(level),
getBoneRestPos(armature, bone)['ARMATURESPACE'][0] - getBoneRestPos(armature, bone.parent)['ARMATURESPACE'][0],
getBoneRestPos(armature, bone)['ARMATURESPACE'][1]- getBoneRestPos(armature, bone.parent)['ARMATURESPACE'][1],
getBoneRestPos(armature, bone)['ARMATURESPACE'][2]- getBoneRestPos(armature, bone.parent)['ARMATURESPACE'][2])
empty_rest_ori [bone.name] = getBoneRestRot(armature, bone)['ARMATURESPACE']
print empty_rest_ori [bone.name]
str += "%s\tCHANNELS 3 Zrotation Xrotation Yrotation\n"%indentString(level)
if bone.children != None:
for b in bone.children:
if bone.name == b.parent.name:
str += printBoneHierarchie (armature,b, level+1)
else:
str += "%s\tEnd Site\n"%indentString(level)
str += "%s\t{\n"%indentString(level)
str += "%s\t\tOFFSET %f %f %f\n"%(indentString(level),
bone.tail['ARMATURESPACE'][0]-bone.head['ARMATURESPACE'][0],
bone.tail['ARMATURESPACE'][1]-bone.head['ARMATURESPACE'][1],
bone.tail['ARMATURESPACE'][2]-bone.head['ARMATURESPACE'][2])
str += "%s\t}\n"%indentString(level)
str += "%s}\n"%indentString(level)
return (str)
def printArmatureHierarchie(armature):
rootBone = getRootBone(armature)
str = "ROOT %s\n{\n"%rootBone.name
str += "\tOFFSET %f %f %f\n"%(getBoneRestPos(armature, rootBone)['ARMATURESPACE'][0],
getBoneRestPos(armature, rootBone)['ARMATURESPACE'][1],
getBoneRestPos(armature, rootBone)['ARMATURESPACE'][2])
str += "\tCHANNELS 6 Xposition Yposition Zposition Zrotation Xrotation Yrotation\n"
empty_rest_ori [rootBone.name] = getBoneRestRot(armature, rootBone)['ARMATURESPACE']
for b in rootBone.children:
if rootBone.name == b.parent.name:
str += printBoneHierarchie (armature,b,1)
str += "}\n"
return (str)
def printBoneFrame (armature, bone, level):
mat1inv = Blender.Mathutils.Matrix(empty_rest_ori [bone.name][0],
empty_rest_ori [bone.name][1],
empty_rest_ori [bone.name][2],
empty_rest_ori [bone.name][3])
mat1inv.invert()
mat2 = Blender.Mathutils.Matrix(getBoneCurRot(armature, bone)[0],
getBoneCurRot(armature, bone)[1],
getBoneCurRot(armature, bone)[2],
getBoneCurRot(armature, bone)[3])
mat3=mat1inv*mat2
eul = mat3.rotationPart().toEuler()
str = "%f %f %f "%(
eul[2],
eul[0],
eul[1])
if bone.children != None:
for b in bone.children:
if bone.name == b.parent.name:
str += printBoneFrame (printBoneFrame,b, level+1)
return (str)
def printArmatureFrame (armature):
rootBone = getRootBone(armature)
str = "%f %f %f %f %f %f "%(
getBoneCurPos(armature, getRootBone(armature))[0],
getBoneCurPos(armature, getRootBone(armature))[1],
getBoneCurPos(armature, getRootBone(armature))[2],
getBoneCurRot(armature, getRootBone(armature)).rotationPart().toEuler()[2],
getBoneCurRot(armature, getRootBone(armature)).rotationPart().toEuler()[0],
getBoneCurRot(armature, getRootBone(armature)).rotationPart().toEuler()[1]
)
for b in rootBone.children:
if rootBone.name == b.parent.name:
str += printBoneFrame (armature,b,1)
str += "\n"
return (str)
def exportBVH(filename):
global armaturename
print "Exporting armature %s to file %s "%( armaturename, filename)
startFrame = Blender.Get('staframe')
endFrame = Blender.Get('endframe')
outputfile = file(filename,'w')
outputfile.write("HIERARCHY\n")
armData = Blender.Object.Get(armaturename).getData()
str_res = printArmatureHierarchie (armData)
outputfile.write(str_res)
outputfile.write("MOTION\n")
outputfile.write("Frames: %d\n"%(endFrame-startFrame))
outputfile.write("Frame Time: %f\n"%(1.0/Blender.Scene.getCurrent().getRenderingContext().framesPerSec()))
ctx = Blender.Scene.getCurrent().getRenderingContext()
Blender.Set('curframe', startFrame)
while Blender.Get('curframe') < endFrame:
print "frame : %d"%(Blender.Get('curframe'))
str_res = printArmatureFrame(armData)
outputfile.write(str_res)
Blender.Set('curframe',Blender.Get('curframe')+1)
outputfile.close()
Blender.Set('curframe', startFrame)
Blender.Redraw()
print "**** START ****"
bfilename = Blender.Get('filename')
armaturename = ""
nfilename = bfilename.replace('.blend', '.bvh')
print nfilename
obj_sel = Blender.Object.GetSelected()
if (obj_sel != None) and (len (obj_sel) == 1) and (type(obj_sel[0].getData()) == Blender.Types.ArmatureType):
print obj_sel[0].getName()
print type(obj_sel[0].getData())
armaturename = obj_sel[0].getName()
Blender.Window.FileSelector(exportBVH, 'Export BVH',nfilename)
else:
error_txt = "Error%t|Select one and only one armature before running this script"
Blender.Draw.PupMenu(error_txt)
print error_txt
print "**** END ****"