From d2833d9f0f1daa25f359e034b10bb4234c68a47d Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Thu, 4 Oct 2012 10:58:03 +0000 Subject: Added convenience operator to clear animation (i.e. all keyframes = F-Curves) from selected objects and bones --- release/scripts/startup/bl_ui/space_view3d.py | 3 +- source/blender/editors/animation/anim_intern.h | 2 + source/blender/editors/animation/anim_ops.c | 1 + source/blender/editors/animation/keyframing.c | 106 +++++++++++++++++++++---- 4 files changed, 96 insertions(+), 16 deletions(-) diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py index 1786c19ebdf..a77c5818fca 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -807,7 +807,8 @@ class VIEW3D_MT_object_animation(Menu): layout = self.layout layout.operator("anim.keyframe_insert_menu", text="Insert Keyframe...") - layout.operator("anim.keyframe_delete_v3d", text="Delete Keyframe...") + layout.operator("anim.keyframe_delete_v3d", text="Delete Keyframes...") + layout.operator("anim.keyframe_clear_v3d", text="Clear Keyframes...") layout.operator("anim.keying_set_active_set", text="Change Keying Set...") layout.separator() diff --git a/source/blender/editors/animation/anim_intern.h b/source/blender/editors/animation/anim_intern.h index cf84eb04b10..bc07bf091de 100644 --- a/source/blender/editors/animation/anim_intern.h +++ b/source/blender/editors/animation/anim_intern.h @@ -50,7 +50,9 @@ void ANIM_OT_keyframe_delete(struct wmOperatorType *ot); * required for each space. */ void ANIM_OT_keyframe_insert_menu(struct wmOperatorType *ot); + void ANIM_OT_keyframe_delete_v3d(struct wmOperatorType *ot); +void ANIM_OT_keyframe_clear_v3d(struct wmOperatorType *ot); /* Keyframe managment operators for UI buttons (RMB menu). */ void ANIM_OT_keyframe_insert_button(struct wmOperatorType *ot); diff --git a/source/blender/editors/animation/anim_ops.c b/source/blender/editors/animation/anim_ops.c index e24a4d49a05..f2711ec3bb5 100644 --- a/source/blender/editors/animation/anim_ops.c +++ b/source/blender/editors/animation/anim_ops.c @@ -290,6 +290,7 @@ void ED_operatortypes_anim(void) WM_operatortype_append(ANIM_OT_keyframe_delete); WM_operatortype_append(ANIM_OT_keyframe_insert_menu); WM_operatortype_append(ANIM_OT_keyframe_delete_v3d); + WM_operatortype_append(ANIM_OT_keyframe_clear_v3d); WM_operatortype_append(ANIM_OT_keyframe_insert_button); WM_operatortype_append(ANIM_OT_keyframe_delete_button); WM_operatortype_append(ANIM_OT_keyframe_clear_button); diff --git a/source/blender/editors/animation/keyframing.c b/source/blender/editors/animation/keyframing.c index 1791d84d90b..a8aba82fb03 100644 --- a/source/blender/editors/animation/keyframing.c +++ b/source/blender/editors/animation/keyframing.c @@ -1440,46 +1440,122 @@ void ANIM_OT_keyframe_delete(wmOperatorType *ot) } /* Delete Key Operator ------------------------ */ - -/* XXX WARNING: - * This is currently just a basic operator, which work in 3d-view context on objects only. - * Should this be kept? It does have advantages over a version which requires selecting a keyingset to use... - * -- Joshua Leung, Jan 2009 +/* NOTE: Although this version is simpler than the more generic version for KeyingSets, + * it is more useful for animators working in the 3D view. */ +static int clear_anim_v3d_exec(bContext *C, wmOperator *op) +{ + Main *bmain = CTX_data_main(C); + + CTX_DATA_BEGIN (C, Object *, ob, selected_objects) + { + /* just those in active action... */ + if ((ob->adt) && (ob->adt->action)) { + AnimData *adt = ob->adt; + bAction *act = adt->action; + FCurve *fcu, *fcn; + + for (fcu = act->curves.first; fcu; fcu = fcn) { + short can_delete = FALSE; + + fcn = fcu->next; + + /* in pose mode, only delete the F-Curve if it belongs to a selected bone */ + if (ob->mode & OB_MODE_POSE) { + if ((fcu->rna_path) && strstr(fcu->rna_path, "pose.bones[")) { + bPoseChannel *pchan; + char *bone_name; + + /* get bone-name, and check if this bone is selected */ + bone_name = BLI_str_quoted_substrN(fcu->rna_path, "pose.bones["); + pchan = BKE_pose_channel_find_name(ob->pose, bone_name); + if (bone_name) MEM_freeN(bone_name); + + /* delete if bone is selected*/ + if ((pchan) && (pchan->bone)) { + if (pchan->bone->flag & BONE_SELECTED) + can_delete = TRUE; + } + } + } + else { + /* object mode - all of Object's F-Curves are affected */ + can_delete = TRUE; + } + + /* delete F-Curve completely */ + if (can_delete) { + ANIM_fcurve_delete_from_animdata(NULL, adt, fcu); + } + } + } + + /* update... */ + ob->recalc |= OB_RECALC_OB; + } + CTX_DATA_END; + + /* send updates */ + DAG_ids_flush_update(bmain, 0); + WM_event_add_notifier(C, NC_OBJECT | ND_KEYS, NULL); + + return OPERATOR_FINISHED; +} + +void ANIM_OT_keyframe_clear_v3d(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Remove Animation"; + ot->description = "Remove all keyframe animation for selected objects"; + ot->idname = "ANIM_OT_keyframe_clear_v3d"; + + /* callbacks */ + ot->invoke = WM_operator_confirm; + ot->exec = clear_anim_v3d_exec; + + ot->poll = ED_operator_areaactive; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + + static int delete_key_v3d_exec(bContext *C, wmOperator *op) { Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); - float cfra = (float)CFRA; // XXX for now, don't bother about all the yucky offset crap + float cfra = (float)CFRA; - // XXX more comprehensive tests will be needed CTX_DATA_BEGIN (C, Object *, ob, selected_objects) { - ID *id = (ID *)ob; - FCurve *fcu, *fcn; - short success = 0; + ID *id = &ob->id; + size_t success = 0; - /* loop through all curves in animdata and delete keys on this frame */ + /* just those in active action... */ if ((ob->adt) && (ob->adt->action)) { AnimData *adt = ob->adt; bAction *act = adt->action; + FCurve *fcu, *fcn; for (fcu = act->curves.first; fcu; fcu = fcn) { fcn = fcu->next; + + /* delete keyframes on current frame + * WARNING: this can delete the next F-Curve, hence the "fcn" copying + */ success += delete_keyframe(op->reports, id, NULL, NULL, fcu->rna_path, fcu->array_index, cfra, 0); } } - BKE_reportf(op->reports, RPT_INFO, "Ob '%s' - Successfully had %d keyframes removed", id->name + 2, success); - + /* report success (or failure) */ + BKE_reportf(op->reports, RPT_INFO, "Object '%s' successfully had %u keyframes removed", id->name + 2, success); ob->recalc |= OB_RECALC_OB; } CTX_DATA_END; /* send updates */ DAG_ids_flush_update(bmain, 0); - WM_event_add_notifier(C, NC_OBJECT | ND_KEYS, NULL); return OPERATOR_FINISHED; @@ -1489,7 +1565,7 @@ void ANIM_OT_keyframe_delete_v3d(wmOperatorType *ot) { /* identifiers */ ot->name = "Delete Keyframe"; - ot->description = "Remove keyframes on current frame for selected object"; + ot->description = "Remove keyframes on current frame for selected objects"; ot->idname = "ANIM_OT_keyframe_delete_v3d"; /* callbacks */ -- cgit v1.2.3