[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [34546] trunk/blender/release/scripts/ keyingsets/keyingsets_builtins.py: Character Animation Goodie: " Whole Character" Builtin Keying Set

Joshua Leung aligorith at gmail.com
Sat Jan 29 04:01:54 CET 2011


Revision: 34546
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=34546
Author:   aligorith
Date:     2011-01-29 03:01:51 +0000 (Sat, 29 Jan 2011)
Log Message:
-----------
Character Animation Goodie: "Whole Character" Builtin Keying Set

This commit introduces a new Keying Set: "Whole Character", which is
specially designed for character animators blocking out their
animation. It should make animating with rigs such as the Sintel rigs
(and other "mainstream" setups, though others may also work with a few
modifications) much easier.

It automatically determines which properties on every bone in the
active rig should be keyframed, avoiding an initial set up step where
properties may be missed, or non-animatable properties are also
needlessly keyframed. To do this, it relies on several rules:
1) All bones in the armature, regardless of visibility status are
considered, so that hiding some layers on some keyframes then
keyframing them later won't create problems with earlier poses
changing
2) Bones starting with certain prefixes, i.e. DEF, MCH, VIS, etc. (the
full list is available in the code for this, and can be/is meant to be
modified by riggers in their own versions as they see fit), so that
some bones on hidden layers which shouldn't be seen by animators are
not keyframed
3) Locked transforms AREN'T keyframed
4) All custom properties ARE keyframed - currently this is the best we
can do, as it's hard to tell if they're needed or not, or even if
they're already driven.

Modified Paths:
--------------
    trunk/blender/release/scripts/keyingsets/keyingsets_builtins.py

Modified: trunk/blender/release/scripts/keyingsets/keyingsets_builtins.py
===================================================================
--- trunk/blender/release/scripts/keyingsets/keyingsets_builtins.py	2011-01-28 15:24:02 UTC (rev 34545)
+++ trunk/blender/release/scripts/keyingsets/keyingsets_builtins.py	2011-01-29 03:01:51 UTC (rev 34546)
@@ -190,6 +190,130 @@
 
 ############################### 
 
+# All properties that are likely to get animated in a character rig
+class BUILTIN_KSI_WholeCharacter(bpy.types.KeyingSetInfo):
+    bl_label = "Whole Character"
+    
+    # these prefixes should be avoided, as they are not really bones
+    # that animators should be touching (or need to touch)
+    badBonePrefixes = (
+        'DEF', 
+        'GEO', 
+        'MCH', 
+        'ORG',
+        'COR',
+        'VIS',
+        # ... more can be added here as you need in your own rigs ...
+    )
+    
+    # poll - pose-mode on active object only
+    def poll(ksi, context):
+        return ((context.active_object) and (context.active_object.pose) and
+                (context.active_object.mode == 'POSE'))
+
+    # iterator - all bones regardless of selection
+    def iterator(ksi, context, ks):
+        for bone in context.active_object.pose.bones:
+            if not bone.name.startswith(BUILTIN_KSI_WholeCharacter.badBonePrefixes):
+                ksi.generate(context, ks, bone)
+
+    # generator - all unlocked bone transforms + custom properties
+    def generate(ksi, context, ks, bone):
+        # loc, rot, scale - only include unlocked ones
+        ksi.doLoc(ks, bone)
+        
+        if bone.rotation_mode in ('QUATERNION', 'AXIS_ANGLE'):
+            ksi.doRot4d(ks, bone)
+        else:
+            ksi.doRot3d(ks, bone)
+        ksi.doScale(ks, bone)
+        
+        # custom props?
+        ksi.doCustomProps(ks, bone)
+        
+    # ----------------
+    
+    # helper to add some bone's property to the Keying Set
+    def addProp(ksi, ks, bone, prop, index=-1, use_groups=True):        
+        # add the property name to the base path
+        path = path_add_property(bone.path_from_id(), prop)
+        
+        # add Keying Set entry for this...
+        id_block = bone.id_data
+        
+        if use_groups:
+            ks.paths.add(id_block, path, index, group_method='NAMED', group_name=bone.name)
+        else:
+            ks.paths.add(id_block, path, index)
+    
+    # ----------------
+    
+    # location properties
+    def doLoc(ksi, ks, bone):
+        if bone.lock_location == (False, False, False):
+            ksi.addProp(ks, bone, "location")
+        else:
+            for i in range(3):
+                if not bone.lock_location[i]:
+                    ksi.addProp(ks, bone, "location", i)
+    
+    # rotation properties
+    def doRot4d(ksi, ks, bone):
+        # rotation mode affects the property used
+        if bone.rotation_mode == 'QUATERNION':
+            prop = "rotation_quaternion"
+        elif bone.rotation_mode == 'AXIS_ANGLE':
+            prop = "rotation_axis_angle"
+        
+        # add rotation properties if they will
+        if bone.lock_rotations_4d:
+            # can check individually
+            if (bone.lock_rotation == (False, False, False)) and (bone.lock_rotation_w == False):
+                ksi.addProp(ks, bone, prop)
+            else:
+                if bone.lock_rotation_w == False:
+                    ksi.addProp(ks, bone, prop, 0) # w = 0
+                
+                for i in range(3):
+                    if not bone.lock_rotation[i]:
+                        ksi.addProp(ks, bone, prop, i+1) # i+1, since here x,y,z = 1,2,3, and w=0
+        elif True not in bone.lock_rotation:
+            # if axis-angle rotations get locked as eulers, then it's too messy to allow anything 
+            # other than all open unless we keyframe the whole lot
+            ksi.addProp(ks, bone, prop)
+        
+    def doRot3d(ksi, ks, bone):
+        if bone.lock_rotation == (False, False, False):
+            ksi.addProp(ks, bone, "rotation_euler")
+        else:
+            for i in range(3):
+                if not bone.lock_rotation[i]:
+                    ksi.addProp(ks, bone, "rotation_euler", i)
+            
+    # scale properties
+    def doScale(ksi, ks, bone):
+        if bone.lock_scale == (0,0,0):
+            ksi.addProp(ks, bone, "scale")
+        else:
+            for i in range(3):
+                if not bone.lock_scale[i]:
+                    ksi.addProp(ks, bone, "scale", i)
+                    
+    # ----------------
+    
+    # custom properties
+    def doCustomProps(ksi, ks, bone):
+        # go over all custom properties for bone
+        for prop,val in bone.items():
+            # ignore special "_RNA_UI" used for UI editing
+            if prop == "_RNA_UI":
+                continue
+            
+            # for now, just add all of 'em
+            ksi.addProp(ks, bone, '["%s"]' % (prop))
+
+############################### 
+
 classes = [
     BUILTIN_KSI_Location,
     BUILTIN_KSI_Rotation,
@@ -199,6 +323,8 @@
     BUILTIN_KSI_LocScale,
     BUILTIN_KSI_LocRotScale,
     BUILTIN_KSI_RotScale,
+    
+    BUILTIN_KSI_WholeCharacter,
 
     BUILTIN_KSI_VisualLoc,
     BUILTIN_KSI_VisualRot,




More information about the Bf-blender-cvs mailing list