Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/editors/animation/keyframing.c')
-rw-r--r--source/blender/editors/animation/keyframing.c255
1 files changed, 92 insertions, 163 deletions
diff --git a/source/blender/editors/animation/keyframing.c b/source/blender/editors/animation/keyframing.c
index d0675dc42ba..f60181d7f6c 100644
--- a/source/blender/editors/animation/keyframing.c
+++ b/source/blender/editors/animation/keyframing.c
@@ -40,15 +40,11 @@
#include "BLI_dynstr.h"
#include "DNA_anim_types.h"
-#include "DNA_action_types.h"
#include "DNA_armature_types.h"
#include "DNA_constraint_types.h"
#include "DNA_key_types.h"
-#include "DNA_object_types.h"
#include "DNA_material_types.h"
#include "DNA_scene_types.h"
-#include "DNA_userdef_types.h"
-#include "DNA_windowmanager_types.h"
#include "BKE_animsys.h"
#include "BKE_action.h"
@@ -67,7 +63,6 @@
#include "ED_keyframing.h"
#include "ED_keyframes_edit.h"
#include "ED_screen.h"
-#include "ED_util.h"
#include "UI_interface.h"
@@ -76,7 +71,6 @@
#include "RNA_access.h"
#include "RNA_define.h"
-#include "RNA_types.h"
#include "anim_intern.h"
@@ -136,8 +130,11 @@ bAction *verify_adt_action (ID *id, short add)
/* init action if none available yet */
// TODO: need some wizardry to handle NLA stuff correct
- if ((adt->action == NULL) && (add))
- adt->action= add_empty_action("Action");
+ if ((adt->action == NULL) && (add)) {
+ char actname[sizeof(id->name)-2];
+ BLI_snprintf(actname, sizeof(actname), "%sAction", id->name+2);
+ adt->action= add_empty_action(actname);
+ }
/* return the action */
return adt->action;
@@ -182,16 +179,8 @@ FCurve *verify_fcurve (bAction *act, const char group[], const char rna_path[],
grp= action_groups_find_named(act, group);
/* no matching groups, so add one */
- if (grp == NULL) {
- /* Add a new group, and make it active */
- grp= MEM_callocN(sizeof(bActionGroup), "bActionGroup");
-
- grp->flag = AGRP_SELECTED;
- strncpy(grp->name, group, sizeof(grp->name));
-
- BLI_addtail(&act->groups, grp);
- BLI_uniquename(&act->groups, grp, "Group", '.', offsetof(bActionGroup, name), sizeof(grp->name));
- }
+ if (grp == NULL)
+ grp= action_groups_add_new(act, group);
/* add F-Curve to group */
action_groups_add_channel(act, grp, fcu);
@@ -231,27 +220,16 @@ int insert_bezt_fcurve (FCurve *fcu, BezTriple *bezt, short flag)
if (replace) {
/* sanity check: 'i' may in rare cases exceed arraylen */
if ((i >= 0) && (i < fcu->totvert)) {
- /* take care with the handletypes and other info if the replacement flags are set */
- if (flag & INSERTKEY_REPLACE) {
- BezTriple *dst= (fcu->bezt + i);
- float dy= bezt->vec[1][1] - dst->vec[1][1];
-
- /* just apply delta value change to the handle values */
- dst->vec[0][1] += dy;
- dst->vec[1][1] += dy;
- dst->vec[2][1] += dy;
-
- // TODO: perform some other operations?
- }
- else {
- char oldKeyType= BEZKEYTYPE(fcu->bezt + i);
-
- /* just brutally replace the values */
- *(fcu->bezt + i) = *bezt;
-
- /* special exception for keyframe type - copy value back so that this info isn't lost */
- BEZKEYTYPE(fcu->bezt + i)= oldKeyType;
- }
+ /* just change the values when replacing, so as to not overwrite handles */
+ BezTriple *dst= (fcu->bezt + i);
+ float dy= bezt->vec[1][1] - dst->vec[1][1];
+
+ /* just apply delta value change to the handle values */
+ dst->vec[0][1] += dy;
+ dst->vec[1][1] += dy;
+ dst->vec[2][1] += dy;
+
+ // TODO: perform some other operations?
}
}
/* keyframing modes allow to not replace keyframe */
@@ -259,14 +237,14 @@ int insert_bezt_fcurve (FCurve *fcu, BezTriple *bezt, short flag)
/* insert new - if we're not restricted to replacing keyframes only */
BezTriple *newb= MEM_callocN((fcu->totvert+1)*sizeof(BezTriple), "beztriple");
- /* add the beztriples that should occur before the beztriple to be pasted (originally in ei->icu) */
+ /* add the beztriples that should occur before the beztriple to be pasted (originally in fcu) */
if (i > 0)
memcpy(newb, fcu->bezt, i*sizeof(BezTriple));
/* add beztriple to paste at index i */
*(newb + i)= *bezt;
- /* add the beztriples that occur after the beztriple to be pasted (originally in icu) */
+ /* add the beztriples that occur after the beztriple to be pasted (originally in fcu) */
if (i < fcu->totvert)
memcpy(newb+i+1, fcu->bezt+i, (fcu->totvert-i)*sizeof(BezTriple));
@@ -311,17 +289,19 @@ int insert_vert_fcurve (FCurve *fcu, float x, float y, short flag)
BezTriple beztr;
int a;
- /* set all three points, for nicer start position */
+ /* set all three points, for nicer start position
+ * NOTE: +/- 1 on vec.x for left and right handles is so that 'free' handles work ok...
+ */
memset(&beztr, 0, sizeof(BezTriple));
- beztr.vec[0][0]= x;
+ beztr.vec[0][0]= x-1.0f;
beztr.vec[0][1]= y;
beztr.vec[1][0]= x;
beztr.vec[1][1]= y;
- beztr.vec[2][0]= x;
+ beztr.vec[2][0]= x+1.0f;
beztr.vec[2][1]= y;
beztr.ipo= U.ipo_new; /* use default interpolation mode here... */
beztr.f1= beztr.f2= beztr.f3= SELECT;
- beztr.h1= beztr.h2= HD_AUTO; // XXX what about when we replace an old one?
+ beztr.h1= beztr.h2= U.keyhandles_new; /* use default handle type here */
//BEZKEYTYPE(&beztr)= scene->keytype; /* default keyframe type */
/* add temp beztriple to keyframes */
@@ -342,18 +322,9 @@ int insert_vert_fcurve (FCurve *fcu, float x, float y, short flag)
/* set handletype and interpolation */
if ((fcu->totvert > 2) && (flag & INSERTKEY_REPLACE)==0) {
BezTriple *bezt= (fcu->bezt + a);
- char h1, h2;
-
- /* set handles (autohandles by default) */
- h1= h2= HD_AUTO;
-
- if (a > 0) h1= (bezt-1)->h2;
- if (a < fcu->totvert-1) h2= (bezt+1)->h1;
-
- bezt->h1= h1;
- bezt->h2= h2;
/* set interpolation from previous (if available) */
+ // FIXME: this doesn't work if user tweaked the interpolation specifically, and they were just overwriting some existing key in the process...
if (a > 0) bezt->ipo= (bezt-1)->ipo;
else if (a < fcu->totvert-1) bezt->ipo= (bezt+1)->ipo;
@@ -846,15 +817,21 @@ short insert_keyframe_direct (PointerRNA ptr, PropertyRNA *prop, FCurve *fcu, fl
short insert_keyframe (ID *id, bAction *act, const char group[], const char rna_path[], int array_index, float cfra, short flag)
{
PointerRNA id_ptr, ptr;
- PropertyRNA *prop;
+ PropertyRNA *prop = NULL;
FCurve *fcu;
int array_index_max= array_index+1;
int ret= 0;
/* validate pointer first - exit if failure */
+ if (id == NULL) {
+ printf("Insert Key: no ID-block to insert keyframe in (Path = %s) \n", rna_path);
+ return 0;
+ }
+
RNA_id_pointer_create(id, &id_ptr);
if ((RNA_path_resolve(&id_ptr, rna_path, &ptr, &prop) == 0) || (prop == NULL)) {
- printf("Insert Key: Could not insert keyframe, as RNA Path is invalid for the given ID (ID = %s, Path = %s)\n", id->name, rna_path);
+ printf("Insert Key: Could not insert keyframe, as RNA Path is invalid for the given ID (ID = %s, Path = %s)\n",
+ (id)? id->name : "<Missing ID-Block>", rna_path);
return 0;
}
@@ -903,21 +880,27 @@ short insert_keyframe (ID *id, bAction *act, const char group[], const char rna_
/* will only loop once unless the array index was -1 */
for (; array_index < array_index_max; array_index++) {
- /* make sure the F-Curve exists */
- fcu= verify_fcurve(act, group, rna_path, array_index, 1);
+ /* make sure the F-Curve exists
+ * - if we're replacing keyframes only, DO NOT create new F-Curves if they do not exist yet
+ * but still try to get the F-Curve if it exists...
+ */
+ fcu= verify_fcurve(act, group, rna_path, array_index, (flag & INSERTKEY_REPLACE)==0);
- /* set color mode if the F-Curve is new (i.e. without any keyframes) */
- if ((fcu->totvert == 0) && (flag & INSERTKEY_XYZ2RGB)) {
- /* for Loc/Rot/Scale and also Color F-Curves, the color of the F-Curve in the Graph Editor,
- * is determined by the array index for the F-Curve
- */
- if (ELEM4(RNA_property_subtype(prop), PROP_TRANSLATION, PROP_XYZ, PROP_EULER, PROP_COLOR)) {
- fcu->color_mode= FCURVE_COLOR_AUTO_RGB;
+ /* we may not have a F-Curve when we're replacing only... */
+ if (fcu) {
+ /* set color mode if the F-Curve is new (i.e. without any keyframes) */
+ if ((fcu->totvert == 0) && (flag & INSERTKEY_XYZ2RGB)) {
+ /* for Loc/Rot/Scale and also Color F-Curves, the color of the F-Curve in the Graph Editor,
+ * is determined by the array index for the F-Curve
+ */
+ if (ELEM4(RNA_property_subtype(prop), PROP_TRANSLATION, PROP_XYZ, PROP_EULER, PROP_COLOR)) {
+ fcu->color_mode= FCURVE_COLOR_AUTO_RGB;
+ }
}
+
+ /* insert keyframe */
+ ret += insert_keyframe_direct(ptr, prop, fcu, cfra, flag);
}
-
- /* insert keyframe */
- ret += insert_keyframe_direct(ptr, prop, fcu, cfra, flag);
}
return ret;
@@ -945,7 +928,7 @@ short delete_keyframe (ID *id, bAction *act, const char group[], const char rna_
if ELEM(NULL, id, adt) {
printf("ERROR: no ID-block and/or AnimData to delete keyframe from \n");
return 0;
- }
+ }
/* validate pointer first - exit if failure */
RNA_id_pointer_create(id, &id_ptr);
@@ -1059,9 +1042,13 @@ static int modify_key_op_poll(bContext *C)
if (ELEM(NULL, sa, scene))
return 0;
- /* if Outliner, only allow in DataBlocks view */
- if (so && (so->outlinevis != SO_DATABLOCKS))
- return 0;
+ /* if Outliner, don't allow in some views */
+ if (so) {
+ if (ELEM4(so->outlinevis, SO_GROUPS, SO_LIBRARIES, SO_VERSE_SESSION, SO_VERSE_SESSION))
+ return 0;
+ if (ELEM3(so->outlinevis, SO_SEQUENCE, SO_USERDEF, SO_KEYMAP))
+ return 0;
+ }
/* TODO: checks for other space types can be added here */
@@ -1073,7 +1060,6 @@ static int modify_key_op_poll(bContext *C)
static int insert_key_exec (bContext *C, wmOperator *op)
{
- ListBase dsources = {NULL, NULL};
Scene *scene= CTX_data_scene(C);
KeyingSet *ks= NULL;
int type= RNA_int_get(op->ptr, "type");
@@ -1098,38 +1084,26 @@ static int insert_key_exec (bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
- /* get context info for relative Keying Sets */
- if ((ks->flag & KEYINGSET_ABSOLUTE) == 0) {
- /* exit if no suitable data obtained */
- if (modifykey_get_context_data(C, &dsources, ks) == 0) {
- BKE_report(op->reports, RPT_ERROR, "No suitable context info for active Keying Set");
- return OPERATOR_CANCELLED;
- }
- }
-
/* try to insert keyframes for the channels specified by KeyingSet */
- success= modify_keyframes(scene, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, cfra);
+ success= ANIM_apply_keyingset(C, NULL, NULL, ks, MODIFYKEY_MODE_INSERT, cfra);
if (G.f & G_DEBUG)
BKE_reportf(op->reports, RPT_INFO, "KeyingSet '%s' - Successfully added %d Keyframes \n", ks->name, success);
/* report failure or do updates? */
- if (success) {
+ if (success == MODIFYKEY_INVALID_CONTEXT) {
+ BKE_report(op->reports, RPT_ERROR, "No suitable context info for active Keying Set");
+ return OPERATOR_CANCELLED;
+ }
+ else if (success) {
/* if the appropriate properties have been set, make a note that we've inserted something */
if (RNA_boolean_get(op->ptr, "confirm_success"))
BKE_reportf(op->reports, RPT_INFO, "Successfully added %d Keyframes for KeyingSet '%s'", success, ks->name);
/* send notifiers that keyframes have been changed */
- WM_event_add_notifier(C, NC_ANIMATION|ND_KEYFRAME_EDIT, NULL);
+ WM_event_add_notifier(C, NC_ANIMATION|ND_KEYFRAME|NA_EDITED, NULL);
}
else
BKE_report(op->reports, RPT_WARNING, "Keying Set failed to insert any keyframes");
-
-
- /* free temp context-data if available */
- if (dsources.first) {
- /* we assume that there is no extra data that needs to be freed from here... */
- BLI_freelistN(&dsources);
- }
/* send updates */
DAG_ids_flush_update(0);
@@ -1139,6 +1113,8 @@ static int insert_key_exec (bContext *C, wmOperator *op)
void ANIM_OT_keyframe_insert (wmOperatorType *ot)
{
+ PropertyRNA *prop;
+
/* identifiers */
ot->name= "Insert Keyframe";
ot->idname= "ANIM_OT_keyframe_insert";
@@ -1154,60 +1130,20 @@ void ANIM_OT_keyframe_insert (wmOperatorType *ot)
/* keyingset to use
* - here the type is int not enum, since many of the indicies here are determined dynamically
*/
- RNA_def_int(ot->srna, "type", 0, INT_MIN, INT_MAX, "Keying Set Number", "Index (determined internally) of the Keying Set to use", 0, 1);
+ prop= RNA_def_int(ot->srna, "type", 0, INT_MIN, INT_MAX, "Keying Set Number", "Index (determined internally) of the Keying Set to use", 0, 1);
+ RNA_def_property_flag(prop, PROP_HIDDEN);
/* confirm whether a keyframe was added by showing a popup
* - by default, this is enabled, since this operator is assumed to be called independently
*/
- RNA_def_boolean(ot->srna, "confirm_success", 1, "Confirm Successful Insert", "Show a popup when the keyframes get successfully added");
+ prop= RNA_def_boolean(ot->srna, "confirm_success", 1, "Confirm Successful Insert", "Show a popup when the keyframes get successfully added");
+ RNA_def_property_flag(prop, PROP_HIDDEN);
}
/* Insert Key Operator (With Menu) ------------------------ */
/* This operator checks if a menu should be shown for choosing the KeyingSet to use,
- * then calls the
+ * then calls the menu if necessary before
*/
-static void insert_key_menu_prompt (bContext *C)
-{
- Scene *scene= CTX_data_scene(C);
- KeyingSet *ks;
- uiPopupMenu *pup;
- uiLayout *layout;
- int i = 0;
-
- pup= uiPupMenuBegin(C, "Insert Keyframe", 0);
- layout= uiPupMenuLayout(pup);
-
- /* active Keying Set
- * - only include entry if it exists
- */
- if (scene->active_keyingset) {
- uiItemIntO(layout, "Active Keying Set", 0, "ANIM_OT_keyframe_insert_menu", "type", i++);
- uiItemS(layout);
- }
- else
- i++;
-
- /* user-defined Keying Sets
- * - these are listed in the order in which they were defined for the active scene
- */
- if (scene->keyingsets.first) {
- for (ks= scene->keyingsets.first; ks; ks= ks->next)
- uiItemIntO(layout, ks->name, 0, "ANIM_OT_keyframe_insert_menu", "type", i++);
- uiItemS(layout);
- }
-
- /* builtin Keying Sets */
- i= -1;
- for (ks= builtin_keyingsets.first; ks; ks= ks->next) {
- /* only show KeyingSet if context is suitable */
- if (keyingset_context_ok_poll(C, ks)) {
- uiItemIntO(layout, ks->name, 0, "ANIM_OT_keyframe_insert_menu", "type", i--);
- }
- }
-
- uiPupMenuEnd(C, pup);
-}
-
static int insert_key_menu_invoke (bContext *C, wmOperator *op, wmEvent *event)
{
Scene *scene= CTX_data_scene(C);
@@ -1215,7 +1151,7 @@ static int insert_key_menu_invoke (bContext *C, wmOperator *op, wmEvent *event)
/* if prompting or no active Keying Set, show the menu */
if ((scene->active_keyingset == 0) || RNA_boolean_get(op->ptr, "always_prompt")) {
/* call the menu, which will call this operator again, hence the cancelled */
- insert_key_menu_prompt(C);
+ ANIM_keying_sets_menu_setup(C, op->type->name, "ANIM_OT_keyframe_insert_menu");
return OPERATOR_CANCELLED;
}
else {
@@ -1229,6 +1165,8 @@ static int insert_key_menu_invoke (bContext *C, wmOperator *op, wmEvent *event)
void ANIM_OT_keyframe_insert_menu (wmOperatorType *ot)
{
+ PropertyRNA *prop;
+
/* identifiers */
ot->name= "Insert Keyframe Menu";
ot->idname= "ANIM_OT_keyframe_insert_menu";
@@ -1244,24 +1182,26 @@ void ANIM_OT_keyframe_insert_menu (wmOperatorType *ot)
/* keyingset to use
* - here the type is int not enum, since many of the indicies here are determined dynamically
*/
- RNA_def_int(ot->srna, "type", 0, INT_MIN, INT_MAX, "Keying Set Number", "Index (determined internally) of the Keying Set to use", 0, 1);
+ prop= RNA_def_int(ot->srna, "type", 0, INT_MIN, INT_MAX, "Keying Set Number", "Index (determined internally) of the Keying Set to use", 0, 1);
+ RNA_def_property_flag(prop, PROP_HIDDEN);
/* confirm whether a keyframe was added by showing a popup
* - by default, this is disabled so that if a menu is shown, this doesn't come up too
*/
// XXX should this just be always on?
- RNA_def_boolean(ot->srna, "confirm_success", 0, "Confirm Successful Insert", "Show a popup when the keyframes get successfully added");
+ prop= RNA_def_boolean(ot->srna, "confirm_success", 0, "Confirm Successful Insert", "Show a popup when the keyframes get successfully added");
+ RNA_def_property_flag(prop, PROP_HIDDEN);
/* whether the menu should always be shown
* - by default, the menu should only be shown when there is no active Keying Set (2.5 behaviour),
* although in some cases it might be useful to always shown (pre 2.5 behaviour)
*/
- RNA_def_boolean(ot->srna, "always_prompt", 0, "Always Show Menu", "");
+ prop= RNA_def_boolean(ot->srna, "always_prompt", 0, "Always Show Menu", "");
+ RNA_def_property_flag(prop, PROP_HIDDEN);
}
/* Delete Key Operator ------------------------ */
static int delete_key_exec (bContext *C, wmOperator *op)
{
- ListBase dsources = {NULL, NULL};
Scene *scene= CTX_data_scene(C);
KeyingSet *ks= NULL;
int type= RNA_int_get(op->ptr, "type");
@@ -1286,38 +1226,27 @@ static int delete_key_exec (bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
- /* get context info for relative Keying Sets */
- if ((ks->flag & KEYINGSET_ABSOLUTE) == 0) {
- /* exit if no suitable data obtained */
- if (modifykey_get_context_data(C, &dsources, ks) == 0) {
- BKE_report(op->reports, RPT_ERROR, "No suitable context info for active Keying Set");
- return OPERATOR_CANCELLED;
- }
- }
-
/* try to insert keyframes for the channels specified by KeyingSet */
- success= modify_keyframes(scene, &dsources, NULL, ks, MODIFYKEY_MODE_DELETE, cfra);
+ success= ANIM_apply_keyingset(C, NULL, NULL, ks, MODIFYKEY_MODE_DELETE, cfra);
if (G.f & G_DEBUG)
printf("KeyingSet '%s' - Successfully removed %d Keyframes \n", ks->name, success);
/* report failure or do updates? */
- if (success) {
+ if (success == MODIFYKEY_INVALID_CONTEXT) {
+ BKE_report(op->reports, RPT_ERROR, "No suitable context info for active Keying Set");
+ return OPERATOR_CANCELLED;
+ }
+ else if (success) {
/* if the appropriate properties have been set, make a note that we've inserted something */
if (RNA_boolean_get(op->ptr, "confirm_success"))
BKE_reportf(op->reports, RPT_INFO, "Successfully removed %d Keyframes for KeyingSet '%s'", success, ks->name);
/* send notifiers that keyframes have been changed */
- WM_event_add_notifier(C, NC_ANIMATION|ND_KEYFRAME_EDIT, NULL);
+ WM_event_add_notifier(C, NC_ANIMATION|ND_KEYFRAME|NA_EDITED, NULL);
}
else
BKE_report(op->reports, RPT_WARNING, "Keying Set failed to remove any keyframes");
- /* free temp context-data if available */
- if (dsources.first) {
- /* we assume that there is no extra data that needs to be freed from here... */
- BLI_freelistN(&dsources);
- }
-
/* send updates */
DAG_ids_flush_update(0);
@@ -1474,7 +1403,7 @@ static int insert_key_button_exec (bContext *C, wmOperator *op)
DAG_ids_flush_update(0);
/* send notifiers that keyframes have been changed */
- WM_event_add_notifier(C, NC_ANIMATION|ND_KEYFRAME_EDIT, NULL);
+ WM_event_add_notifier(C, NC_ANIMATION|ND_KEYFRAME|NA_EDITED, NULL);
}
return (success)? OPERATOR_FINISHED: OPERATOR_CANCELLED;
@@ -1544,7 +1473,7 @@ static int delete_key_button_exec (bContext *C, wmOperator *op)
DAG_ids_flush_update(0);
/* send notifiers that keyframes have been changed */
- WM_event_add_notifier(C, NC_ANIMATION|ND_KEYFRAME_EDIT, NULL);
+ WM_event_add_notifier(C, NC_ANIMATION|ND_KEYFRAME|NA_EDITED, NULL);
}
return (success)? OPERATOR_FINISHED: OPERATOR_CANCELLED;