From d6ef4380a0d23acb619018fdaf84f5381b71f325 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Fri, 10 Jul 2009 12:11:00 +0000 Subject: NLA SoC: Delete Channels operator F-Curves and Groups can now be deleted again from DopeSheet/Graph Editors. --- source/blender/editors/animation/anim_channels.c | 148 ++++++++++++++++++++++- 1 file changed, 142 insertions(+), 6 deletions(-) (limited to 'source/blender/editors/animation') diff --git a/source/blender/editors/animation/anim_channels.c b/source/blender/editors/animation/anim_channels.c index 1cf553f6f26..5c31d007705 100644 --- a/source/blender/editors/animation/anim_channels.c +++ b/source/blender/editors/animation/anim_channels.c @@ -63,9 +63,10 @@ #include "RNA_access.h" #include "RNA_define.h" +#include "BKE_animsys.h" #include "BKE_action.h" #include "BKE_depsgraph.h" -#include "BKE_ipo.h" +#include "BKE_fcurve.h" #include "BKE_key.h" #include "BKE_material.h" #include "BKE_object.h" @@ -133,7 +134,7 @@ void ANIM_set_active_channel (bAnimContext *ac, void *data, short datatype, int } /* set active flag */ - if (channel_data) { + if (channel_data != NULL) { switch (channel_type) { case ANIMTYPE_GROUP: { @@ -691,6 +692,121 @@ void ANIM_OT_channels_move_bottom (wmOperatorType *ot) #endif // XXX old animation system - needs to be updated for new system... +/* ******************** Delete Channel Operator *********************** */ + +static int animchannels_delete_exec(bContext *C, wmOperator *op) +{ + bAnimContext ac; + ListBase anim_data = {NULL, NULL}; + bAnimListElem *ale; + int filter; + + /* get editor data */ + if (ANIM_animdata_get_context(C, &ac) == 0) + return OPERATOR_CANCELLED; + + /* cannot delete in shapekey */ + if (ac.datatype == ANIMCONT_SHAPEKEY) + return OPERATOR_CANCELLED; + + + /* do groups only first (unless in Drivers mode, where there are none) */ + if (ac.datatype != ANIMCONT_DRIVERS) { + /* filter data */ + filter= (ANIMFILTER_VISIBLE | ANIMFILTER_SEL | ANIMFILTER_CHANNELS | ANIMFILTER_FOREDIT); + ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype); + + /* delete selected groups and their associated channels */ + for (ale= anim_data.first; ale; ale= ale->next) { + /* only groups - don't check other types yet, since they may no-longer exist */ + if (ale->type == ANIMTYPE_GROUP) { + bActionGroup *agrp= (bActionGroup *)ale->data; + AnimData *adt= BKE_animdata_from_id(ale->id); + FCurve *fcu, *fcn; + + /* skip this group if no AnimData available, as we can't safely remove the F-Curves */ + if (adt == NULL) + continue; + + /* delete all of the Group's F-Curves, but no others */ + for (fcu= agrp->channels.first; fcu && fcu->grp==agrp; fcu= fcn) { + fcn= fcu->next; + + /* remove from group and action, then free */ + action_groups_remove_channel(adt->action, fcu); + free_fcurve(fcu); + } + + /* free the group itself */ + if (adt->action) + BLI_freelinkN(&adt->action->groups, agrp); + else + MEM_freeN(agrp); + } + } + + /* cleanup */ + BLI_freelistN(&anim_data); + } + + /* now do F-Curves */ + if (ac.datatype != ANIMCONT_GPENCIL) { + /* filter data */ + filter= (ANIMFILTER_VISIBLE | ANIMFILTER_SEL | ANIMFILTER_FOREDIT); + ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype); + + /* delete selected F-Curves */ + for (ale= anim_data.first; ale; ale= ale->next) { + /* only F-Curves, and only if we can identify its parent */ + if (ale->type == ANIMTYPE_FCURVE) { + AnimData *adt= BKE_animdata_from_id(ale->id); + 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? + */ + if (fcu->grp) + action_groups_remove_channel(adt->action, fcu); + else if (adt->action) + BLI_remlink(&adt->action->curves, fcu); + else if (ac.datatype == ANIMCONT_DRIVERS) + BLI_remlink(&adt->drivers, fcu); + + /* free the F-Curve itself */ + free_fcurve(fcu); + } + } + + /* cleanup */ + BLI_freelistN(&anim_data); + } + + /* send notifier that things have changed */ + WM_event_add_notifier(C, NC_ANIMATION|ND_ANIMCHAN_EDIT, NULL); + + return OPERATOR_FINISHED; +} + +void ANIM_OT_channels_delete (wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Delete Channels"; + ot->idname= "ANIM_OT_channels_delete"; + + /* api callbacks */ + ot->exec= animchannels_delete_exec; + ot->poll= animedit_poll_channels_active; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} /* ******************** Toggle Channel Visibility Operator *********************** */ @@ -707,7 +823,7 @@ static int animchannels_visibility_toggle_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; /* filter data */ - filter= (ANIMFILTER_VISIBLE | ANIMFILTER_SEL | ANIMFILTER_CURVESONLY); + filter= (ANIMFILTER_VISIBLE | ANIMFILTER_SEL); ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype); /* See if we should be making showing all selected or hiding */ @@ -715,14 +831,28 @@ static int animchannels_visibility_toggle_exec(bContext *C, wmOperator *op) if (vis == ACHANNEL_SETFLAG_CLEAR) break; - if (ale->flag & FCURVE_VISIBLE) + if ((ale->type == ANIMTYPE_FCURVE) && (ale->flag & FCURVE_VISIBLE)) + vis= ACHANNEL_SETFLAG_CLEAR; + else if ((ale->type == ANIMTYPE_GROUP) && !(ale->flag & AGRP_NOTVISIBLE)) vis= ACHANNEL_SETFLAG_CLEAR; } /* Now set the flags */ for (ale= anim_data.first; ale; ale= ale->next) { - FCurve *fcu= (FCurve *)ale->data; - ACHANNEL_SET_FLAG(fcu, vis, FCURVE_VISIBLE); + switch (ale->type) { + case ANIMTYPE_FCURVE: /* F-Curve */ + { + FCurve *fcu= (FCurve *)ale->data; + ACHANNEL_SET_FLAG(fcu, vis, FCURVE_VISIBLE); + } + break; + case ANIMTYPE_GROUP: /* Group */ + { + bActionGroup *agrp= (bActionGroup *)ale->data; + ACHANNEL_SET_FLAG_NEG(agrp, vis, AGRP_NOTVISIBLE); + } + break; + } } /* cleanup */ @@ -1753,6 +1883,8 @@ void ED_operatortypes_animchannels(void) WM_operatortype_append(ANIM_OT_channels_setting_disable); WM_operatortype_append(ANIM_OT_channels_setting_toggle); + WM_operatortype_append(ANIM_OT_channels_delete); + // XXX does this need to be a separate operator? WM_operatortype_append(ANIM_OT_channels_editable_toggle); @@ -1786,6 +1918,10 @@ void ED_keymap_animchannels(wmWindowManager *wm) /* borderselect */ WM_keymap_add_item(keymap, "ANIM_OT_channels_select_border", BKEY, KM_PRESS, 0, 0); + /* delete */ + WM_keymap_add_item(keymap, "ANIM_OT_channels_delete", XKEY, KM_PRESS, 0, 0); + WM_keymap_add_item(keymap, "ANIM_OT_channels_delete", DELKEY, KM_PRESS, 0, 0); + /* settings */ WM_keymap_add_item(keymap, "ANIM_OT_channels_setting_toggle", WKEY, KM_PRESS, KM_SHIFT, 0); WM_keymap_add_item(keymap, "ANIM_OT_channels_setting_enable", WKEY, KM_PRESS, KM_CTRL|KM_SHIFT, 0); -- cgit v1.2.3