[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [33983] trunk/blender/release/scripts/op/ io_anim_bvh: added bvh export operator & menu item, now user accessible.
Campbell Barton
ideasman42 at gmail.com
Sat Jan 1 10:44:13 CET 2011
Revision: 33983
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=33983
Author: campbellbarton
Date: 2011-01-01 10:44:13 +0100 (Sat, 01 Jan 2011)
Log Message:
-----------
added bvh export operator & menu item, now user accessible.
Modified Paths:
--------------
trunk/blender/release/scripts/op/io_anim_bvh/__init__.py
trunk/blender/release/scripts/op/io_anim_bvh/export_bvh.py
trunk/blender/release/scripts/op/io_anim_bvh/import_bvh.py
Modified: trunk/blender/release/scripts/op/io_anim_bvh/__init__.py
===================================================================
--- trunk/blender/release/scripts/op/io_anim_bvh/__init__.py 2011-01-01 08:57:09 UTC (rev 33982)
+++ trunk/blender/release/scripts/op/io_anim_bvh/__init__.py 2011-01-01 09:44:13 UTC (rev 33983)
@@ -27,18 +27,18 @@
import bpy
from bpy.props import *
-from io_utils import ImportHelper
+from io_utils import ImportHelper, ExportHelper
class BvhImporter(bpy.types.Operator, ImportHelper):
- '''Load a OBJ Motion Capture File'''
+ '''Load a BVH motion capture file'''
bl_idname = "import_anim.bvh"
bl_label = "Import BVH"
filename_ext = ".bvh"
filter_glob = StringProperty(default="*.bvh", options={'HIDDEN'})
- scale = FloatProperty(name="Scale", description="Scale the BVH by this value", min=0.0001, max=1000000.0, soft_min=0.001, soft_max=100.0, default=0.1)
+ global_scale = FloatProperty(name="Scale", description="Scale the BVH by this value", min=0.0001, max=1000000.0, soft_min=0.001, soft_max=100.0, default=1.0)
frame_start = IntProperty(name="Start Frame", description="Starting frame for the animation", default=1)
use_cyclic = BoolProperty(name="Loop", description="Loop the animation playback", default=False)
rotate_mode = EnumProperty(items=(
@@ -53,23 +53,52 @@
),
name="Rotation",
description="Rotation conversion.",
- default='NATIVE')
+ default='QUATERNION') # XXX, eulers are broken!
def execute(self, context):
from . import import_bvh
return import_bvh.load(self, context, **self.as_keywords(ignore=("filter_glob",)))
-def menu_func(self, context):
+class BvhExporter(bpy.types.Operator, ExportHelper):
+ '''Save a BVH motion capture file from an armature'''
+ bl_idname = "export_anim.bvh"
+ bl_label = "Export BVH"
+
+ filename_ext = ".bvh"
+ filter_glob = StringProperty(default="*.bvh", options={'HIDDEN'})
+
+ global_scale = FloatProperty(name="Scale", description="Scale the BVH by this value", min=0.0001, max=1000000.0, soft_min=0.001, soft_max=100.0, default=1.0)
+ frame_start = IntProperty(name="Start Frame", description="Starting frame to export")
+ frame_end = IntProperty(name="End Frame", description="End frame to export")
+
+ def invoke(self, context, event):
+ self.frame_start = context.scene.frame_start
+ self.frame_end = context.scene.frame_end
+
+ return super().invoke(context, event)
+
+ def execute(self, context):
+ from . import export_bvh
+ return export_bvh.save(self, context, **self.as_keywords(ignore=("check_existing", "filter_glob")))
+
+
+def menu_func_import(self, context):
self.layout.operator(BvhImporter.bl_idname, text="Motion Capture (.bvh)")
+def menu_func_export(self, context):
+ self.layout.operator(BvhExporter.bl_idname, text="Motion Capture (.bvh)")
+
+
def register():
- bpy.types.INFO_MT_file_import.append(menu_func)
+ bpy.types.INFO_MT_file_import.append(menu_func_import)
+ bpy.types.INFO_MT_file_export.append(menu_func_export)
def unregister():
- bpy.types.INFO_MT_file_import.remove(menu_func)
+ bpy.types.INFO_MT_file_import.remove(menu_func_import)
+ bpy.types.INFO_MT_file_export.remove(menu_func_export)
if __name__ == "__main__":
register()
Modified: trunk/blender/release/scripts/op/io_anim_bvh/export_bvh.py
===================================================================
--- trunk/blender/release/scripts/op/io_anim_bvh/export_bvh.py 2011-01-01 08:57:09 UTC (rev 33982)
+++ trunk/blender/release/scripts/op/io_anim_bvh/export_bvh.py 2011-01-01 09:44:13 UTC (rev 33983)
@@ -22,44 +22,32 @@
# fixes from Andrea Rugliancich
import bpy
-from mathutils import Matrix, Vector
-from math import degrees
-def bvh_export(filepath, obj, pref_startframe, pref_endframe, pref_scale=1.0):
+def _read(context, filepath, frame_start, frame_end, global_scale=1.0):
- # Window.EditMode(0)
+ from mathutils import Matrix, Vector
+ from math import degrees
file = open(filepath, "w")
- # bvh_nodes = {}
- arm_data = obj.data
- bones = arm_data.bones.values()
+ obj = context.object
+ arm = obj.data
# Build a dictionary of bone children.
# None is for parentless bones
bone_children = {None: []}
# initialize with blank lists
- for bone in bones:
+ for bone in arm.bones:
bone_children[bone.name] = []
- for bone in bones:
- parent = bone.parent
- bone_name = bone.name
- if parent:
- bone_children[parent.name].append(bone_name)
- else: # root node
- bone_children[None].append(bone_name)
+ for bone in arm.bones:
+ bone_children[getattr(bone.parent, "name", None)].append(bone.name)
# sort the children
for children_list in bone_children.values():
children_list.sort()
- # build a (name:bone) mapping dict
- bone_dict = {}
- for bone in bones:
- bone_dict[bone.name] = bone
-
# bone name list in the order that the bones are written
bones_serialized_names = []
@@ -72,7 +60,7 @@
indent_str = "\t" * indent
- bone = bone_dict[bone_name]
+ bone = arm.bones[bone_name]
loc = bone.head_local
bone_locs[bone_name] = loc
@@ -86,7 +74,7 @@
file.write("%sROOT %s\n" % (indent_str, bone_name))
file.write("%s{\n" % indent_str)
- file.write("%s\tOFFSET %.6f %.6f %.6f\n" % (indent_str, loc.x * pref_scale, loc.y * pref_scale, loc.z * pref_scale))
+ file.write("%s\tOFFSET %.6f %.6f %.6f\n" % (indent_str, loc.x * global_scale, loc.y * global_scale, loc.z * global_scale))
file.write("%s\tCHANNELS 6 Xposition Yposition Zposition Xrotation Yrotation Zrotation\n" % indent_str)
if my_bone_children:
@@ -103,7 +91,7 @@
file.write("%s\tEnd Site\n" % indent_str)
file.write("%s\t{\n" % indent_str)
loc = bone.tail_local - bone_locs[bone_name]
- file.write("%s\t\tOFFSET %.6f %.6f %.6f\n" % (indent_str, loc.x * pref_scale, loc.y * pref_scale, loc.z * pref_scale))
+ file.write("%s\t\tOFFSET %.6f %.6f %.6f\n" % (indent_str, loc.x * global_scale, loc.y * global_scale, loc.z * global_scale))
file.write("%s\t}\n" % indent_str)
file.write("%s}\n" % indent_str)
@@ -129,9 +117,7 @@
file.write("}\n")
# redefine bones as sorted by bones_serialized_names
- # se we can write motion
- pose_dict = obj.pose.bones
- #pose_bones = [(pose_dict[bone_name], bone_dict[bone_name].matrix_local.copy().invert()) for bone_name in bones_serialized_names]
+ # so we can write motion
class decorated_bone(object):
__slots__ = (\
@@ -148,8 +134,8 @@
def __init__(self, bone_name):
self.name = bone_name
- self.rest_bone = bone_dict[bone_name]
- self.pose_bone = pose_dict[bone_name]
+ self.rest_bone = arm.bones[bone_name]
+ self.pose_bone = obj.pose.bones[bone_name]
self.pose_mat = self.pose_bone.matrix
@@ -189,13 +175,13 @@
# finish assigning parents
file.write("MOTION\n")
- file.write("Frames: %d\n" % (pref_endframe - pref_startframe + 1))
+ file.write("Frames: %d\n" % (frame_end - frame_start + 1))
file.write("Frame Time: %.6f\n" % 0.03)
scene = bpy.context.scene
triple = "%.6f %.6f %.6f "
- for frame in range(pref_startframe, pref_endframe + 1):
+ for frame in range(frame_start, frame_end + 1):
scene.frame_set(frame)
obj.update(scene, 1,1,1)
scene.update()
@@ -205,9 +191,6 @@
if dbone.parent:
trans = Matrix.Translation(dbone.rest_bone.head_local)
itrans = Matrix.Translation(-dbone.rest_bone.head_local)
-
- # mat2 = dbone.rest_arm_imat * dbone.pose_mat * dbone.parent.pose_imat * dbone.parent.rest_arm_mat
- # mat2 = trans * mat2 * itrans
mat2 = dbone.parent.rest_arm_mat * dbone.parent.pose_imat * dbone.pose_mat * dbone.rest_arm_imat
mat2 = itrans * mat2 * trans
@@ -217,63 +200,37 @@
trans = Matrix.Translation(dbone.rest_bone.head_local)
itrans = Matrix.Translation(-dbone.rest_bone.head_local)
- # mat2 = dbone.rest_arm_imat * dbone.pose_mat
- # mat2 = trans * mat2 * itrans
mat2 = dbone.pose_mat * dbone.rest_arm_imat
mat2 = itrans * mat2 * trans
myloc = mat2.translation_part() + dbone.rest_bone.head_local
rot = mat2.copy().transpose().to_euler()
- file.write(triple % (myloc[0] * pref_scale, myloc[1] * pref_scale, myloc[2] * pref_scale))
+ file.write(triple % (myloc[0] * global_scale, myloc[1] * global_scale, myloc[2] * global_scale))
file.write(triple % (-degrees(rot[0]), -degrees(rot[1]), -degrees(rot[2])))
file.write("\n")
- numframes = pref_endframe - pref_startframe + 1
file.close()
- print("BVH Exported: %s frames:%d\n" % (filepath, numframes))
+ print("BVH Exported: %s frames:%d\n" % (filepath, frame_end - frame_start + 1))
-bvh_export("/foo.bvh", bpy.context.object, 1, 190, 1.0)
-'''
-def bvh_export_ui(filepath):
- # Dont overwrite
- if not BPyMessages.Warning_SaveOver(filepath):
- return
+def save(operator, context, filepath="",
+ frame_start=-1,
+ frame_end=-1,
+ global_scale=1.0,
+ ):
- scn = Scene.GetCurrent()
- ob_act = scn.objects.active
- if not ob_act or ob_act.type != 'Armature':
- BPyMessages.Error_NoArmatureActive()
+ _read(context, filepath,
+ frame_start=frame_start,
+ frame_end=frame_end,
+ global_scale=global_scale,
+ )
- arm_ob = scn.objects.active
+ return {'FINISHED'}
- if not arm_ob or arm_ob.type != 'Armature':
- Blender.Draw.PupMenu('No Armature object selected.')
- return
- ctx = scn.getRenderingContext()
- orig_frame = Blender.Get('curframe')
- pref_startframe = Blender.Draw.Create(int(ctx.startFrame()))
- pref_endframe = Blender.Draw.Create(int(ctx.endFrame()))
-
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list