[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [27923] trunk/blender/release/scripts/op/ nla.py: missed in merging from render branch

Campbell Barton ideasman42 at gmail.com
Thu Apr 1 11:29:35 CEST 2010


Revision: 27923
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=27923
Author:   campbellbarton
Date:     2010-04-01 11:29:35 +0200 (Thu, 01 Apr 2010)

Log Message:
-----------
missed in merging from render branch

Added Paths:
-----------
    trunk/blender/release/scripts/op/nla.py

Added: trunk/blender/release/scripts/op/nla.py
===================================================================
--- trunk/blender/release/scripts/op/nla.py	                        (rev 0)
+++ trunk/blender/release/scripts/op/nla.py	2010-04-01 09:29:35 UTC (rev 27923)
@@ -0,0 +1,204 @@
+# ##### BEGIN GPL LICENSE BLOCK #####
+#
+#  This program is free software; you can redistribute it and/or
+#  modify it under the terms of the GNU General Public License
+#  as published by the Free Software Foundation; either version 2
+#  of the License, or (at your option) any later version.
+#
+#  This program is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU General Public License for more details.
+#
+#  You should have received a copy of the GNU General Public License
+#  along with this program; if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# ##### END GPL LICENSE BLOCK #####
+
+# <pep8 compliant>
+
+import bpy
+
+def pose_info():
+    from Mathutils import Matrix
+
+    info = {}
+
+    obj = bpy.context.object
+    pose = obj.pose
+
+    pose_items = pose.bones.items()
+
+    for name, pbone in pose_items:
+        binfo = {}
+        bone = pbone.bone
+
+        binfo["parent"] = getattr(bone.parent, "name", None)
+        binfo["bone"] = bone
+        binfo["pbone"] = pbone
+        binfo["matrix_local"] = bone.matrix_local.copy()
+        try:
+            binfo["matrix_local_inv"] = binfo["matrix_local"].copy().invert()
+        except:
+            binfo["matrix_local_inv"] = Matrix()
+        
+        binfo["matrix"] = bone.matrix.copy()
+        binfo["matrix_pose"] = pbone.matrix.copy()
+        try:
+            binfo["matrix_pose_inv"] = binfo["matrix_pose"].copy().invert()
+        except:
+            binfo["matrix_pose_inv"] = Matrix()
+        
+        print(binfo["matrix_pose"])
+        info[name] = binfo
+
+    for name, pbone in pose_items:
+        binfo = info[name]
+        binfo_parent = binfo.get("parent", None)
+        if binfo_parent:
+            binfo_parent = info[binfo_parent]
+        
+        matrix = binfo["matrix_pose"]
+        rest_matrix = binfo["matrix_local"]
+
+        if binfo_parent:
+            matrix= binfo_parent["matrix_pose_inv"] * matrix
+            rest_matrix= binfo_parent["matrix_local_inv"] * rest_matrix
+
+        matrix = rest_matrix.copy().invert() * matrix
+
+        binfo["matrix_key"] = matrix.copy()
+
+    return info
+
+
+def bake(start_frame, end_frame, step=1, only_selected=False):
+    # import nla; reload(nla); nla.bake()
+
+    scene = bpy.context.scene
+    obj = bpy.context.object
+    pose = obj.pose
+
+    info_ls = []
+    
+    frame_range = range(start_frame, end_frame + 1, step)
+
+    # could spped this up by applying steps here too...
+    for f in frame_range:
+        scene.set_frame(f)
+        
+        info = pose_info()
+        info_ls.append(info)
+        f += 1
+
+    action = bpy.data.actions.new("Action")
+
+    bpy.context.object.animation_data.action = action
+
+    pose_items = pose.bones.items()
+
+    for name, pbone in pose_items:
+        if only_selected and not pbone.selected:
+            continue
+
+        for f in frame_range:
+            matrix = info_ls[int((f-start_frame) / step)][name]["matrix_key"]
+
+            #pbone.location = matrix.translation_part()
+            #pbone.rotation_quaternion = matrix.to_quat()
+            pbone.matrix_local = [f for v in matrix for f in v]
+            
+            pbone.keyframe_insert("location", -1, f)
+            
+            rotation_mode = pbone.rotation_mode
+            
+            if rotation_mode == 'QUATERNION':
+                pbone.keyframe_insert("rotation_quaternion", -1, f)
+            elif rotation_mode == 'AXIS_ANGLE':
+                pbone.keyframe_insert("rotation_axis_angle", -1, f)
+            else: # euler, XYZ, ZXY etc
+                pbone.keyframe_insert("rotation_euler", -1, f)
+
+            pbone.keyframe_insert("scale", -1, f)
+
+    # assign groups, could become a more generic function
+    agrp_loc = action.groups.add("Location")
+    agrp_rot = action.groups.add("Rotation")
+    agrp_sca = action.groups.add("Scale")
+
+    for fcu in action.fcurves:
+        path = fcu.data_path.rsplit(".", 1)[-1]
+
+        if path.startswith("loc"):
+            fcu.group = agrp_loc
+        if path.startswith("rot"):
+            fcu.group = agrp_rot
+        if path.startswith("sca"):
+            fcu.group = agrp_sca
+
+    return action
+
+
+from bpy.props import *
+
+
+class BakeAction(bpy.types.Operator):
+    '''Add a torus mesh'''
+    bl_idname = "nla.bake"
+    bl_label = "Bake Action"
+    bl_options = {'REGISTER', 'UNDO'}
+
+    start_frame = IntProperty(name="Start Frame",
+            description="Start frame for baking",
+            default=1, min=1, max=300000)
+    end_frame = IntProperty(name="End Frame",
+            description="End frame for baking",
+            default=250, min=1, max=300000)
+    step = IntProperty(name="Frame Step",
+            description="Frame Step",
+            default=1, min=1, max=120)
+    only_selected = BoolProperty(name="Only Selected",
+            default=True)
+
+    def execute(self, context):
+        props = self.properties
+
+        action = bake(props.start_frame, props.end_frame, props.step, props.only_selected)
+        
+        # basic cleanup, could move elsewhere
+        for fcu in action.fcurves:
+            keyframe_points = fcu.keyframe_points
+            i = 1
+            while i < len(fcu.keyframe_points) - 1:
+                val_prev = keyframe_points[i - 1].co[1]
+                val_next = keyframe_points[i + 1].co[1]
+                val = keyframe_points[i].co[1]
+
+                if abs(val - val_prev) + abs(val - val_next) < 0.0001:
+                    keyframe_points.remove(keyframe_points[i])
+                else:
+                    i += 1
+
+        return {'FINISHED'}
+
+    def invoke(self, context, event):
+        wm = context.manager
+        return wm.invoke_props_dialog(self)
+
+
+#def menu_func(self, context):
+#    self.layout.operator(BakeAction.bl_idname, text="Bake Armature Action")
+
+
+def register():
+    bpy.types.register(BakeAction)
+    # bpy.types.INFO_MT_mesh_add.append(menu_func)
+
+
+def unregister():
+    bpy.types.unregister(BakeAction)
+    # bpy.types.INFO_MT_mesh_add.remove(menu_func)
+
+if __name__ == "__main__":
+    register()
\ No newline at end of file





More information about the Bf-blender-cvs mailing list