[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