forked from bartvdbraak/blender
Bugfixes: Deleting Keyframes + F-Curves
This commit fixes #19908 and #20239. Deleting keyframes will now delete the F-Curves they came from too, if the F-Curves don't have any more keyframes and/or F-Modifiers providing any further motion info.
This commit is contained in:
parent
a9b9993414
commit
45955fef18
@ -86,9 +86,9 @@
|
||||
#include "WM_types.h"
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* CHANNELS API */
|
||||
/* CHANNELS API - Exposed API */
|
||||
|
||||
/* -------------------------- Exposed API ----------------------------------- */
|
||||
/* -------------------------- Selection ------------------------------------- */
|
||||
|
||||
/* Set the given animation-channel as the active one for the active context */
|
||||
// TODO: extend for animdata types...
|
||||
@ -352,6 +352,8 @@ void ANIM_deselect_anim_channels (void *data, short datatype, short test, short
|
||||
BLI_freelistN(&anim_data);
|
||||
}
|
||||
|
||||
/* ---------------------------- Graph Editor ------------------------------------- */
|
||||
|
||||
/* Flush visibility (for Graph Editor) changes up/down hierarchy for changes in the given setting
|
||||
* - anim_data: list of the all the anim channels that can be chosen
|
||||
* -> filtered using ANIMFILTER_CHANNELS only, since if we took VISIBLE too,
|
||||
@ -452,6 +454,35 @@ void ANIM_visibility_flush_anim_channels (bAnimContext *ac, ListBase *anim_data,
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------- F-Curves ------------------------------------- */
|
||||
|
||||
/* Delete the given F-Curve from its AnimData block */
|
||||
void ANIM_fcurve_delete_from_animdata (bAnimContext *ac, AnimData *adt, FCurve *fcu)
|
||||
{
|
||||
/* - if no AnimData, we've got nowhere to remove the F-Curve from
|
||||
* (this doesn't guarantee that the F-Curve is in there, but at least we tried
|
||||
* - if no F-Curve, there is nothing to remove
|
||||
*/
|
||||
if (ELEM(NULL, adt, fcu))
|
||||
return;
|
||||
|
||||
/* remove from whatever list it came from
|
||||
* - Action Group
|
||||
* - Action
|
||||
* - Drivers
|
||||
* - TODO... some others?
|
||||
*/
|
||||
if (fcu->grp)
|
||||
action_groups_remove_channel(adt->action, fcu);
|
||||
else if ((ac) && (ac->datatype == ANIMCONT_DRIVERS))
|
||||
BLI_remlink(&adt->drivers, fcu);
|
||||
else if (adt->action)
|
||||
BLI_remlink(&adt->action->curves, fcu);
|
||||
|
||||
/* free the F-Curve itself */
|
||||
free_fcurve(fcu);
|
||||
}
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* OPERATORS */
|
||||
|
||||
@ -945,28 +976,8 @@ static int animchannels_delete_exec(bContext *C, wmOperator *op)
|
||||
AnimData *adt= ale->adt;
|
||||
FCurve *fcu= (FCurve *)ale->data;
|
||||
|
||||
/* if no AnimData, we've got nowhere to remove the F-Curve from */
|
||||
if (adt == NULL)
|
||||
continue;
|
||||
|
||||
/* remove from whatever list it came from
|
||||
* - Action Group
|
||||
* - Action
|
||||
* - Drivers
|
||||
* - TODO... some others?
|
||||
*
|
||||
* note: this isn't well tested, we could also try remove
|
||||
* from all lists just to be safe - campbell
|
||||
*/
|
||||
if (fcu->grp)
|
||||
action_groups_remove_channel(adt->action, fcu);
|
||||
else if (ac.datatype == ANIMCONT_DRIVERS)
|
||||
BLI_remlink(&adt->drivers, fcu);
|
||||
else if (adt->action)
|
||||
BLI_remlink(&adt->action->curves, fcu);
|
||||
|
||||
/* free the F-Curve itself */
|
||||
free_fcurve(fcu);
|
||||
/* try to free F-Curve */
|
||||
ANIM_fcurve_delete_from_animdata(&ac, adt, fcu);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -110,14 +110,6 @@ void delete_fcurve_keys(FCurve *fcu)
|
||||
MEM_freeN(fcu->bezt);
|
||||
fcu->bezt= NULL;
|
||||
}
|
||||
|
||||
#if 0 // XXX for now, we don't get rid of empty curves...
|
||||
/* Only delete if there isn't an ipo-driver still hanging around on an empty curve */
|
||||
if ((icu->totvert==0) && (icu->driver==NULL)) {
|
||||
BLI_remlink(&ipo->curve, icu);
|
||||
free_ipo_curve(icu);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* ---------------- */
|
||||
|
@ -863,6 +863,7 @@ short insert_keyframe (ID *id, bAction *act, const char group[], const char rna_
|
||||
*/
|
||||
short delete_keyframe (ID *id, bAction *act, const char group[], const char rna_path[], int array_index, float cfra, short flag)
|
||||
{
|
||||
AnimData *adt= BKE_animdata_from_id(id);
|
||||
FCurve *fcu = NULL;
|
||||
|
||||
/* get F-Curve
|
||||
@ -871,7 +872,6 @@ short delete_keyframe (ID *id, bAction *act, const char group[], const char rna_
|
||||
*/
|
||||
if (act == NULL) {
|
||||
/* if no action is provided, use the default one attached to this ID-block */
|
||||
AnimData *adt= BKE_animdata_from_id(id);
|
||||
act= adt->action;
|
||||
|
||||
/* apply NLA-mapping to frame to use (if applicable) */
|
||||
@ -913,11 +913,9 @@ short delete_keyframe (ID *id, bAction *act, const char group[], const char rna_
|
||||
/* delete the key at the index (will sanity check + do recalc afterwards) */
|
||||
delete_fcurve_key(fcu, i, 1);
|
||||
|
||||
/* Only delete curve too if there are no points (we don't need to check for drivers, as they're kept separate) */
|
||||
if (fcu->totvert == 0) {
|
||||
BLI_remlink(&act->curves, fcu);
|
||||
free_fcurve(fcu);
|
||||
}
|
||||
/* Only delete curve too if it won't be doing anything anymore */
|
||||
if ((fcu->totvert == 0) && (list_has_suitable_fmodifier(&fcu->modifiers, 0, FMI_TYPE_GENERATE_CURVE) == 0))
|
||||
ANIM_fcurve_delete_from_animdata(NULL, adt, fcu);
|
||||
|
||||
/* return success */
|
||||
return 1;
|
||||
|
@ -394,6 +394,10 @@ void ANIM_deselect_anim_channels(void *data, short datatype, short test, short s
|
||||
/* Set the 'active' channel of type channel_type, in the given action */
|
||||
void ANIM_set_active_channel(bAnimContext *ac, void *data, short datatype, int filter, void *channel_data, short channel_type);
|
||||
|
||||
|
||||
/* Delete the F-Curve from the given AnimData block (if possible), as appropriate according to animation context */
|
||||
void ANIM_fcurve_delete_from_animdata(bAnimContext *ac, struct AnimData *adt, struct FCurve *fcu);
|
||||
|
||||
/* ************************************************ */
|
||||
/* DRAWING API */
|
||||
/* anim_draw.c */
|
||||
|
@ -613,10 +613,19 @@ static void delete_action_keys (bAnimContext *ac)
|
||||
|
||||
/* loop through filtered data and delete selected keys */
|
||||
for (ale= anim_data.first; ale; ale= ale->next) {
|
||||
//if (ale->type == ANIMTYPE_GPLAYER)
|
||||
// delete_gplayer_frames((bGPDlayer *)ale->data);
|
||||
if (ale->type != ANIMTYPE_GPLAYER) {
|
||||
FCurve *fcu= (FCurve *)ale->key_data;
|
||||
AnimData *adt= ale->adt;
|
||||
|
||||
/* delete selected keyframes only */
|
||||
delete_fcurve_keys(fcu);
|
||||
|
||||
/* Only delete curve too if it won't be doing anything anymore */
|
||||
if ((fcu->totvert == 0) && (list_has_suitable_fmodifier(&fcu->modifiers, 0, FMI_TYPE_GENERATE_CURVE) == 0))
|
||||
ANIM_fcurve_delete_from_animdata(ac, ale->adt, fcu);
|
||||
}
|
||||
//else
|
||||
delete_fcurve_keys((FCurve *)ale->key_data); // XXX... this doesn't delete empty curves anymore
|
||||
// delete_gplayer_frames((bGPDlayer *)ale->data);
|
||||
}
|
||||
|
||||
/* free filtered list */
|
||||
|
@ -792,7 +792,15 @@ static void delete_graph_keys (bAnimContext *ac)
|
||||
|
||||
/* loop through filtered data and delete selected keys */
|
||||
for (ale= anim_data.first; ale; ale= ale->next) {
|
||||
delete_fcurve_keys((FCurve *)ale->key_data); // XXX... this doesn't delete empty curves anymore
|
||||
FCurve *fcu= (FCurve *)ale->key_data;
|
||||
AnimData *adt= ale->adt;
|
||||
|
||||
/* delete selected keyframes only */
|
||||
delete_fcurve_keys(fcu);
|
||||
|
||||
/* Only delete curve too if it won't be doing anything anymore */
|
||||
if ((fcu->totvert == 0) && (list_has_suitable_fmodifier(&fcu->modifiers, 0, FMI_TYPE_GENERATE_CURVE) == 0))
|
||||
ANIM_fcurve_delete_from_animdata(ac, ale->adt, fcu);
|
||||
}
|
||||
|
||||
/* free filtered list */
|
||||
|
Loading…
Reference in New Issue
Block a user