Keyframing Bugfixes and Feature Requests:

* 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)
This commit is contained in:
Joshua Leung 2009-12-14 12:09:20 +00:00
parent 96df285ff6
commit b1a39375e5
12 changed files with 122 additions and 73 deletions

@ -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()

@ -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);

@ -80,6 +80,40 @@
#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));

@ -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;
/* 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);
/* 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++;
/* 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);

@ -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.
*/

@ -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);

@ -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) {

@ -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) {

@ -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) {

@ -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 */

@ -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);

@ -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");