Keyframing Bugfixes and Feature Requests:
authorJoshua Leung <aligorith@gmail.com>
Mon, 14 Dec 2009 12:09:20 +0000 (12:09 +0000)
committerJoshua Leung <aligorith@gmail.com>
Mon, 14 Dec 2009 12:09:20 +0000 (12:09 +0000)
* Added a User-Pref option for the "XYZ to RGB" colour-mode setting for new F-Curves to compliment the one used for Keying Sets. With this option enabled, the builtin Keying Sets also can obey this option.

* Made all places that were previously manually checking the flags for keyframing to use a standard API function to do this now.

* Fixed bug introduced earlier today in commit 25353 by reverting the changes to keyingsets.c. Forgot that delete_keyframe doesn't handle do the "entire array" hack with array_index = -1

* Fixed bug with the insert-keyframe code for the array_index = -1 case, where too many channels were being keyed (i.e. an imaginary channel was often keyed in addition to the valid ones)

12 files changed:
release/scripts/ui/space_userpref.py
source/blender/editors/animation/anim_channels_defines.c
source/blender/editors/animation/keyframing.c
source/blender/editors/animation/keyingsets.c
source/blender/editors/include/ED_keyframing.h
source/blender/editors/interface/interface_anim.c
source/blender/editors/space_action/action_edit.c
source/blender/editors/space_graph/graph_edit.c
source/blender/editors/transform/transform_conversions.c
source/blender/makesdna/DNA_userdef_types.h
source/blender/makesrna/intern/rna_animation.c
source/blender/makesrna/intern/rna_userdef.c

index 6d1a358408f8f989fb6f5392f0c3aa5bf84c142b..cf5b2eb9eed7eaad9b1cd10042a1d7bc89dafde3 100644 (file)
@@ -213,6 +213,7 @@ class USERPREF_PT_edit(bpy.types.Panel):
 
         col.label(text="New F-Curve Defaults:")
         col.prop(edit, "new_interpolation_type", text="Interpolation")
+        col.prop(edit, "insertkey_xyz_to_rgb", text="XYZ to RGB")
 
         col.separator()
 
index c3044e03a2f5343ffaa63595d4294a58368072ef..0a71f79f13249b935335ffdb9c971305ad7da75f 100644 (file)
@@ -2395,13 +2395,7 @@ static void achannel_setting_slider_cb(bContext *C, void *id_poin, void *fcu_poi
        cfra= (float)CFRA;
        
        /* get flags for keyframing */
-       if (IS_AUTOKEY_FLAG(INSERTNEEDED))
-               flag |= INSERTKEY_NEEDED;
-       if (IS_AUTOKEY_FLAG(AUTOMATKEY))
-               flag |= INSERTKEY_MATRIX;
-       if (IS_AUTOKEY_MODE(scene, EDITKEYS))
-               flag |= INSERTKEY_REPLACE;
-       
+       flag = ANIM_get_keyframing_flags(scene, 1);
        
        /* get RNA pointer, and resolve the path */
        RNA_id_pointer_create(id, &id_ptr);
@@ -2438,13 +2432,7 @@ static void achannel_setting_slider_shapekey_cb(bContext *C, void *key_poin, voi
        cfra= (float)CFRA;
        
        /* get flags for keyframing */
-       if (IS_AUTOKEY_FLAG(INSERTNEEDED))
-               flag |= INSERTKEY_NEEDED;
-       if (IS_AUTOKEY_FLAG(AUTOMATKEY))
-               flag |= INSERTKEY_MATRIX;
-       if (IS_AUTOKEY_MODE(scene, EDITKEYS))
-               flag |= INSERTKEY_REPLACE;
-       
+       flag = ANIM_get_keyframing_flags(scene, 1);
        
        /* get RNA pointer, and resolve the path */
        RNA_id_pointer_create((ID *)key, &id_ptr);
index 3e25c9a6b608eef7d24d18c838892182a0d7934c..b126e57705e270e5183d1574894d1e69286203b1 100644 (file)
 
 #include "anim_intern.h"
 
+/* ************************************************** */
+/* Keyframing Setting Wrangling */
+
+/* Get the active settings for keyframing settings from context (specifically the given scene) */
+short ANIM_get_keyframing_flags (Scene *scene, short incl_mode)
+{
+       short flag = 0;
+       
+       /* standard flags */
+       {
+               /* visual keying */
+               if (IS_AUTOKEY_FLAG(AUTOMATKEY)) 
+                       flag |= INSERTKEY_MATRIX;
+               
+               /* only needed */
+               if (IS_AUTOKEY_FLAG(INSERTNEEDED)) 
+                       flag |= INSERTKEY_NEEDED;
+               
+               /* default F-Curve color mode - RGB from XYZ indicies */
+               if (IS_AUTOKEY_FLAG(XYZ2RGB)) 
+                       flag |= INSERTKEY_XYZ2RGB;
+       }
+               
+       /* only if including settings from the autokeying mode... */
+       if (incl_mode) 
+       { 
+               /* keyframing mode - only replace existing keyframes */
+               if (IS_AUTOKEY_MODE(scene, EDITKEYS)) 
+                       flag |= INSERTKEY_REPLACE;
+       }
+               
+       return flag;
+}
+
 /* ******************************************* */
 /* Animation Data Validation */
 
@@ -838,7 +872,7 @@ short insert_keyframe (ID *id, bAction *act, const char group[], const char rna_
        /* key entire array convenience method */
        if (array_index == -1) { 
                array_index= 0;
-               array_index_max= RNA_property_array_length(&ptr, prop) + 1;
+               array_index_max= RNA_property_array_length(&ptr, prop);
        }
        
        /* will only loop once unless the array index was -1 */
@@ -1326,12 +1360,7 @@ static int insert_key_button_exec (bContext *C, wmOperator *op)
        short flag = 0;
        
        /* flags for inserting keyframes */
-       if (IS_AUTOKEY_FLAG(AUTOMATKEY))
-               flag |= INSERTKEY_MATRIX;
-       if (IS_AUTOKEY_FLAG(INSERTNEEDED))
-               flag |= INSERTKEY_NEEDED;
-       if (IS_AUTOKEY_MODE(scene, EDITKEYS))
-               flag |= INSERTKEY_REPLACE;
+       flag = ANIM_get_keyframing_flags(scene, 1);
        
        /* try to insert keyframe using property retrieved from UI */
        memset(&ptr, 0, sizeof(PointerRNA));
index afd693d7981b30fe8e8d62d1d9ec4d7fc58fd014..d5624b8bc5b308104098b687646b1ec4fa7a6867 100644 (file)
@@ -133,11 +133,9 @@ static int add_default_keyingset_exec (bContext *C, wmOperator *op)
         */
        flag |= KEYINGSET_ABSOLUTE;
        
-       if (IS_AUTOKEY_FLAG(AUTOMATKEY)) 
-               keyingflag |= INSERTKEY_MATRIX;
-       if (IS_AUTOKEY_FLAG(INSERTNEEDED)) 
-               keyingflag |= INSERTKEY_NEEDED;
-               
+       /* 2nd arg is 0 to indicate that we don't want to include autokeying mode related settings */
+       keyingflag = ANIM_get_keyframing_flags(scene, 0);
+       
        /* call the API func, and set the active keyingset index */
        BKE_keyingset_add(&scene->keyingsets, NULL, flag, keyingflag);
        
@@ -326,6 +324,8 @@ static int add_keyingset_button_exec (bContext *C, wmOperator *op)
                        keyingflag |= INSERTKEY_MATRIX;
                if (IS_AUTOKEY_FLAG(INSERTNEEDED)) 
                        keyingflag |= INSERTKEY_NEEDED;
+               if (IS_AUTOKEY_FLAG(XYZ2RGB)) 
+                       keyingflag |= INSERTKEY_XYZ2RGB;
                        
                /* call the API func, and set the active keyingset index */
                ks= BKE_keyingset_add(&scene->keyingsets, "ButtonKeyingSet", flag, keyingflag);
@@ -1305,9 +1305,7 @@ int modify_keyframes (Scene *scene, ListBase *dsources, bAction *act, KeyingSet
                kflag= ks->keyingflag;
                
                /* suppliment with info from the context */
-               if (IS_AUTOKEY_FLAG(AUTOMATKEY)) kflag |= INSERTKEY_MATRIX;
-               if (IS_AUTOKEY_FLAG(INSERTNEEDED)) kflag |= INSERTKEY_NEEDED;
-               if (IS_AUTOKEY_MODE(scene, EDITKEYS)) kflag |= INSERTKEY_REPLACE;
+               kflag |= ANIM_get_keyframing_flags(scene, 1);
        }
        else if (mode == MODIFYKEY_MODE_DELETE)
                kflag= 0;
@@ -1318,7 +1316,7 @@ int modify_keyframes (Scene *scene, ListBase *dsources, bAction *act, KeyingSet
                 * provided by the user, and is stored, ready to use, in the KeyingSet paths.
                 */
                for (ksp= ks->paths.first; ksp; ksp= ksp->next) {
-                       int i;
+                       int arraylen, i;
                        
                        /* get pointer to name of group to add channels to */
                        if (ksp->groupmode == KSP_GROUP_NONE)
@@ -1328,14 +1326,36 @@ int modify_keyframes (Scene *scene, ListBase *dsources, bAction *act, KeyingSet
                        else
                                groupname= ksp->group;
                        
-                       /* passing -1 as the array_index results in the entire array being modified */
-                       i= (ksp->flag & KSP_FLAG_WHOLE_ARRAY) ? (-1) : (ksp->array_index);
+                       /* init arraylen and i - arraylen should be greater than i so that
+                        * normal non-array entries get keyframed correctly
+                        */
+                       i= ksp->array_index;
+                       arraylen= i;
+                       
+                       /* get length of array if whole array option is enabled */
+                       if (ksp->flag & KSP_FLAG_WHOLE_ARRAY) {
+                               PointerRNA id_ptr, ptr;
+                               PropertyRNA *prop;
+                               
+                               RNA_id_pointer_create(ksp->id, &id_ptr);
+                               if (RNA_path_resolve(&id_ptr, ksp->rna_path, &ptr, &prop) && prop)
+                                       arraylen= RNA_property_array_length(&ptr, prop);
+                       }
+                       
+                       /* we should do at least one step */
+                       if (arraylen == i)
+                               arraylen++;
                        
-                       /* action to take depends on mode */
-                       if (mode == MODIFYKEY_MODE_INSERT)
-                               success += insert_keyframe(ksp->id, act, groupname, ksp->rna_path, i, cfra, kflag);
-                       else if (mode == MODIFYKEY_MODE_DELETE)
-                               success += delete_keyframe(ksp->id, act, groupname, ksp->rna_path, i, cfra, kflag);
+                       /* for each possible index, perform operation 
+                        *      - assume that arraylen is greater than index
+                        */
+                       for (; i < arraylen; i++) {
+                               /* action to take depends on mode */
+                               if (mode == MODIFYKEY_MODE_INSERT)
+                                       success += insert_keyframe(ksp->id, act, groupname, ksp->rna_path, i, cfra, kflag);
+                               else if (mode == MODIFYKEY_MODE_DELETE)
+                                       success += delete_keyframe(ksp->id, act, groupname, ksp->rna_path, i, cfra, kflag);
+                       }
                        
                        /* set recalc-flags */
                        if (ksp->id) {
@@ -1364,7 +1384,7 @@ int modify_keyframes (Scene *scene, ListBase *dsources, bAction *act, KeyingSet
                        for (ksp= ks->paths.first; ksp; ksp= ksp->next) {
                                DynStr *pathds= BLI_dynstr_new();
                                char *path = NULL;
-                               int i;
+                               int arraylen, i;
                                
                                /* set initial group name */
                                if (cks->id == NULL) {
@@ -1439,14 +1459,32 @@ int modify_keyframes (Scene *scene, ListBase *dsources, bAction *act, KeyingSet
                                else if (ksp->groupmode == KSP_GROUP_NAMED)
                                        groupname= ksp->group;
                                
-                               /* passing -1 as the array_index results in the entire array being modified */
-                               i= (ksp->flag & KSP_FLAG_WHOLE_ARRAY) ? (-1) : (ksp->array_index);
+                               /* init arraylen and i - arraylen should be greater than i so that
+                                * normal non-array entries get keyframed correctly
+                                */
+                               i= ksp->array_index;
+                               arraylen= i+1;
                                
-                               /* action to take depends on mode */
-                               if (mode == MODIFYKEY_MODE_INSERT)
-                                       success+= insert_keyframe(cks->id, act, groupname, path, i, cfra, kflag);
-                               else if (mode == MODIFYKEY_MODE_DELETE)
-                                       success+= delete_keyframe(cks->id, act, groupname, path, i, cfra, kflag);
+                               /* get length of array if whole array option is enabled */
+                               if (ksp->flag & KSP_FLAG_WHOLE_ARRAY) {
+                                       PointerRNA id_ptr, ptr;
+                                       PropertyRNA *prop;
+                                       
+                                       RNA_id_pointer_create(cks->id, &id_ptr);
+                                       if (RNA_path_resolve(&id_ptr, path, &ptr, &prop) && prop)
+                                               arraylen= RNA_property_array_length(&ptr, prop);
+                               }
+                               
+                               /* for each possible index, perform operation 
+                                *      - assume that arraylen is greater than index
+                                */
+                               for (; i < arraylen; i++) {
+                                       /* action to take depends on mode */
+                                       if (mode == MODIFYKEY_MODE_INSERT)
+                                               success+= insert_keyframe(cks->id, act, groupname, path, i, cfra, kflag);
+                                       else if (mode == MODIFYKEY_MODE_DELETE)
+                                               success+= delete_keyframe(cks->id, act, groupname, path, i, cfra, kflag);
+                               }
                                
                                /* free the path */
                                MEM_freeN(path);
index 45a62ee7bcb52054dd6151eee8cf21b7fc39f13f..d16cfe540ea1a245d970372ac5b583239783da51 100644 (file)
@@ -49,6 +49,13 @@ struct PropertyRNA;
 
 /* ************ Keyframing Management **************** */
 
+/* Get the active settings for keyframing settings from context (specifically the given scene) 
+ *     - incl_mode: include settings from keyframing mode in the result (i.e. replace only)
+ */
+short ANIM_get_keyframing_flags(struct Scene *scene, short incl_mode);
+
+/* -------- */
+
 /* Get (or add relevant data to be able to do so) the Active Action for the given 
  * Animation Data block, given an ID block where the Animation Data should reside.
  */
index 0925598cc99c7deab4e03b86ea0ce916173debf1..acfd48e02699e8ce5f159c7fc0ffe54d533f0f73 100644 (file)
@@ -147,14 +147,7 @@ void ui_but_anim_autokey(uiBut *but, Scene *scene, float cfra)
                
                // TODO: this should probably respect the keyingset only option for anim
                if(autokeyframe_cfra_can_key(scene, id)) {
-                       short flag = 0;
-                       
-                       if (IS_AUTOKEY_FLAG(INSERTNEEDED))
-                               flag |= INSERTKEY_NEEDED;
-                       if (IS_AUTOKEY_FLAG(AUTOMATKEY))
-                               flag |= INSERTKEY_MATRIX;
-                       if (IS_AUTOKEY_MODE(scene, EDITKEYS))
-                               flag |= INSERTKEY_REPLACE;
+                       short flag = ANIM_get_keyframing_flags(scene, 1);
                        
                        fcu->flag &= ~FCURVE_SELECTED;
                        insert_keyframe(id, action, ((fcu->grp)?(fcu->grp->name):(NULL)), fcu->rna_path, fcu->array_index, cfra, flag);
index c5da96267e1c77f418069e50fb0f4cacdebc8243..e7b1dcb677d8978fe8d350331d6264891ee328ad 100644 (file)
@@ -446,9 +446,7 @@ static void insert_action_keys(bAnimContext *ac, short mode)
        ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
        
        /* init keyframing flag */
-       if (IS_AUTOKEY_FLAG(AUTOMATKEY)) flag |= INSERTKEY_MATRIX;
-       if (IS_AUTOKEY_FLAG(INSERTNEEDED)) flag |= INSERTKEY_NEEDED;
-       if (IS_AUTOKEY_MODE(scene, EDITKEYS)) flag |= INSERTKEY_REPLACE;
+       flag = ANIM_get_keyframing_flags(scene, 1);
        
        /* insert keyframes */
        for (ale= anim_data.first; ale; ale= ale->next) {
index 6e488678f2b605530c7b6989890ed7752ce812c2..8ac3f2efefb1fd8b2f1ad7f65428d05ed64f10c9 100644 (file)
@@ -428,9 +428,7 @@ static void insert_graph_keys(bAnimContext *ac, short mode)
        ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
        
        /* init keyframing flag */
-       if (IS_AUTOKEY_FLAG(AUTOMATKEY)) flag |= INSERTKEY_MATRIX;
-       if (IS_AUTOKEY_FLAG(INSERTNEEDED)) flag |= INSERTKEY_NEEDED;
-       if (IS_AUTOKEY_MODE(scene, EDITKEYS)) flag |= INSERTKEY_REPLACE;
+       flag = ANIM_get_keyframing_flags(scene, 1);
        
        /* insert keyframes */
        for (ale= anim_data.first; ale; ale= ale->next) {
index c7b5c29e26221c97d609cf60ad98241f1e817e07..e9b0cb40b1b165fabdfa2f1ba60f4b736a402328 100644 (file)
@@ -4525,13 +4525,7 @@ void autokeyframe_ob_cb_func(bContext *C, Scene *scene, View3D *v3d, Object *ob,
                memset(&cks, 0, sizeof(bCommonKeySrc));
                cks.id= &ob->id;
                
-               if (IS_AUTOKEY_FLAG(INSERTNEEDED))
-                       flag |= INSERTKEY_NEEDED;
-               if (IS_AUTOKEY_FLAG(AUTOMATKEY))
-                       flag |= INSERTKEY_MATRIX;
-               if (IS_AUTOKEY_MODE(scene, EDITKEYS))
-                       flag |= INSERTKEY_REPLACE;
-                       
+               flag = ANIM_get_keyframing_flags(scene, 1);
                
                if (IS_AUTOKEY_FLAG(ONLYKEYINGSET) && (active_ks)) {
                        /* only insert into active keyingset */
@@ -4632,12 +4626,10 @@ void autokeyframe_pose_cb_func(bContext *C, Scene *scene, View3D *v3d, Object *o
                 *        visual keyframes even if flag not set, as it's not that useful otherwise
                 *        (for quick animation recording)
                 */
-               if (IS_AUTOKEY_FLAG(AUTOMATKEY) || (targetless_ik))
+               flag = ANIM_get_keyframing_flags(scene, 1);
+               
+               if (targetless_ik) 
                        flag |= INSERTKEY_MATRIX;
-               if (IS_AUTOKEY_FLAG(INSERTNEEDED))
-                       flag |= INSERTKEY_NEEDED;
-               if (IS_AUTOKEY_MODE(scene, EDITKEYS))
-                       flag |= INSERTKEY_REPLACE;
                
                for (pchan=pose->chanbase.first; pchan; pchan=pchan->next) {
                        if (pchan->bone->flag & BONE_TRANSFORM) {
index c6b1bf0b3f682a12093e5c494b61c87e5dedbfc5..a6be72561701000fb475d71d025d49397e03b0c5 100644 (file)
@@ -433,6 +433,7 @@ extern UserDef U; /* from blenkernel blender.c */
 #define                AUTOKEY_FLAG_INSERTAVAIL        (1<<0)
 #define                AUTOKEY_FLAG_INSERTNEEDED       (1<<1)
 #define                AUTOKEY_FLAG_AUTOMATKEY         (1<<2)
+#define                AUTOKEY_FLAG_XYZ2RGB            (1<<3)
        /* U.autokey_flag (strictly autokeying only) */
 #define        AUTOKEY_FLAG_ONLYKEYINGSET      (1<<6)
        /* toolsettings->autokey_flag */
index 035194e0d9f452be1e14302841149dcb8833ec1e..56e2707b5bbac95159b14e0908632ef819e01024 100644 (file)
@@ -269,7 +269,7 @@ static void rna_def_keyingset(BlenderRNA *brna)
        
        prop= RNA_def_property(srna, "insertkey_xyz_to_rgb", PROP_BOOLEAN, PROP_NONE);
        RNA_def_property_boolean_sdna(prop, NULL, "keyingflag", INSERTKEY_XYZ2RGB);
-       RNA_def_property_ui_text(prop, "XYZ Transforms to RGB", "Color for newly added transformation F-Curves (Location, Rotation, Scale) and also Color is based on the transform axis.");
+       RNA_def_property_ui_text(prop, "F-Curve Colors - XYZ to RGB", "Color for newly added transformation F-Curves (Location, Rotation, Scale) and also Color is based on the transform axis.");
        
        /* Keying Set API */
        RNA_api_keyingset(srna);
index d33299079390329f9a4f437cb64b74775878c2a4..9b314afeb08841209bb2770164e75adc22508497 100644 (file)
@@ -1918,7 +1918,11 @@ static void rna_def_userdef_edit(BlenderRNA *brna)
        prop= RNA_def_property(srna, "use_visual_keying", PROP_BOOLEAN, PROP_NONE);
        RNA_def_property_boolean_sdna(prop, NULL, "autokey_flag", AUTOKEY_FLAG_AUTOMATKEY);
        RNA_def_property_ui_text(prop, "Visual Keying", "Use Visual keying automatically for constrained objects.");
-
+       
+       prop= RNA_def_property(srna, "insertkey_xyz_to_rgb", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_boolean_sdna(prop, NULL, "autokey_flag", AUTOKEY_FLAG_XYZ2RGB);
+       RNA_def_property_ui_text(prop, "New F-Curve Colors - XYZ to RGB", "Color for newly added transformation F-Curves (Location, Rotation, Scale) and also Color is based on the transform axis.");
+       
        prop= RNA_def_property(srna, "new_interpolation_type", PROP_ENUM, PROP_NONE);
        RNA_def_property_enum_items(prop, new_interpolation_types);
        RNA_def_property_enum_sdna(prop, NULL, "ipo_new");