[Bf-blender-cvs] [a4c4145] master: NLA/AnimEditors: Added operator to remove all "empty" AnimData blocks

Joshua Leung noreply at git.blender.org
Sun Jul 6 09:36:53 CEST 2014


Commit: a4c414580006645f5d789c37f7f5fe4f5a7d0d54
Author: Joshua Leung
Date:   Sun Jul 6 19:32:01 2014 +1200
https://developer.blender.org/rBa4c414580006645f5d789c37f7f5fe4f5a7d0d54

NLA/AnimEditors: Added operator to remove all "empty" AnimData blocks

It is sometimes possible to end up with a lot of datablocks which have old + unused
"AnimData" containers still attached. This most commonly happens when doing motion
graphics work (i.e. when some linked-in objects may have previously been used to develop
a set of reusable assets), and is particularly distracting in the NLA Editor.

This commit adds an operator which removes AnimData blocks (restricted to only those
which are visible in the animation editor where it is run from) which are "empty"
(i.e. that is, have no active action, drivers, and nla tracks or strips).

This operator can be found from the "Edit" menu in the NLA Editor. Although it also
works when run from the DopeSheet or Graph Editors, it is of less use there since
those won't show these empty AnimData blocks by default (since by definition, such
AnimData blocks necesarily have no keyframes or drivers that can be shown), hence
there will be no feedback if the operator fails or succeeds.

===================================================================

M	release/scripts/startup/bl_ui/space_nla.py
M	source/blender/editors/animation/anim_channels_edit.c

===================================================================

diff --git a/release/scripts/startup/bl_ui/space_nla.py b/release/scripts/startup/bl_ui/space_nla.py
index baadc69..7634620 100644
--- a/release/scripts/startup/bl_ui/space_nla.py
+++ b/release/scripts/startup/bl_ui/space_nla.py
@@ -158,6 +158,7 @@ class NLA_MT_edit(Menu):
         # TODO: this really belongs more in a "channel" (or better, "track") menu
         layout.separator()
         layout.operator_menu_enum("anim.channels_move", "direction", text="Track Ordering...")
+        layout.operator("anim.channels_clean_empty")
 
         layout.separator()
         # TODO: names of these tools for 'tweak-mode' need changing?
diff --git a/source/blender/editors/animation/anim_channels_edit.c b/source/blender/editors/animation/anim_channels_edit.c
index 07a538f..5eb5f8c 100644
--- a/source/blender/editors/animation/anim_channels_edit.c
+++ b/source/blender/editors/animation/anim_channels_edit.c
@@ -49,6 +49,7 @@
 #include "RNA_access.h"
 #include "RNA_define.h"
 
+#include "BKE_animsys.h"
 #include "BKE_action.h"
 #include "BKE_fcurve.h"
 #include "BKE_gpencil.h"
@@ -2065,6 +2066,113 @@ static void ANIM_OT_channels_collapse(wmOperatorType *ot)
 	ot->prop = RNA_def_boolean(ot->srna, "all", true, "All", "Collapse all channels (not just selected ones)");
 }
 
+/* ************ Remove All "Empty" AnimData Blocks Operator ********* */
+/* We define "empty" AnimData blocks here as those which have all 3 of criteria:
+ *  1) No active action OR that active actions are empty
+ *     Assuming that all legitimate entries will have an action,
+ *     and that empty actions
+ *  2) No NLA Tracks + NLA Strips
+ *     Assuming that users haven't set up any of these as "placeholders"
+ *     for convenience sake, and that most that exist were either unintentional
+ *     or are no longer wanted
+ *  3) No drivers
+ */
+ 
+static int animchannels_clean_empty_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;
+	
+	/* get animdata blocks */
+	filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_ANIMDATA);
+	ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
+	
+	for (ale = anim_data.first; ale; ale = ale->next) {
+		ID *id = ale->id;
+		AnimData *adt = ale->data;
+		
+		bool action_empty  = false;
+		bool nla_empty     = false;
+		bool drivers_empty = false;
+		
+		/* sanity checks */
+		BLI_assert((id != NULL) && (adt != NULL));
+		
+		/* check if this is "empty" and can be deleted */
+		/* (For now, there are only these 3 criteria) */
+		
+		/* 1) Active Action is missing or empty */
+		if (ELEM(NULL, adt->action, adt->action->curves.first)) {
+			action_empty = true;
+		}
+		else {
+			/* TODO: check for keyframe + fmodifier data on these too */
+		}
+		
+		/* 2) No NLA Tracks and/or NLA Strips */
+		if (adt->nla_tracks.first == NULL) {
+			nla_empty = true;
+		}
+		else {
+			NlaTrack *nlt;
+			
+			/* empty tracks? */
+			for (nlt = adt->nla_tracks.first; nlt; nlt = nlt->next) {
+				if (nlt->strips.first) {
+					/* stop searching, as we found one that actually had stuff we don't want lost 
+					 * NOTE: nla_empty gets reset to false, as a previous track may have been empty
+					 */
+					nla_empty = false;
+					break;
+				}
+				else if (nlt->strips.first == NULL) {
+					/* this track is empty, but another one may still have stuff in it, so can't break yet */
+					nla_empty = true;
+				}
+			}
+		}
+		
+		/* 3) Drivers */
+		drivers_empty = (adt->drivers.first == NULL);
+		
+		
+		/* remove AnimData? */
+		if (action_empty && nla_empty && drivers_empty) {
+			BKE_free_animdata(id);
+		}
+	}
+	
+	/* free temp data */
+	ANIM_animdata_freelist(&anim_data);
+	
+	/* send notifier that things have changed */
+	WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
+	
+	return OPERATOR_FINISHED;
+}
+
+static void ANIM_OT_channels_clean_empty(wmOperatorType *ot)
+{
+	/* identifiers */
+	ot->name = "Remove Empty Animation Data";
+	ot->idname = "ANIM_OT_channels_clean_empty";
+	ot->description = "Delete all empty animation data containers from visible datablocks";
+	
+	/* api callbacks */
+	ot->exec = animchannels_clean_empty_exec;
+	ot->poll = animedit_poll_channels_nla_tweakmode_off;
+	
+	/* flags */
+	ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
 /* ******************* Reenable Disabled Operator ******************* */
 
 static int animchannels_enable_poll(bContext *C)
@@ -2939,6 +3047,8 @@ void ED_operatortypes_animchannels(void)
 	
 	WM_operatortype_append(ANIM_OT_channels_fcurves_enable);
 	
+	WM_operatortype_append(ANIM_OT_channels_clean_empty);
+	
 	WM_operatortype_append(ANIM_OT_channels_group);
 	WM_operatortype_append(ANIM_OT_channels_ungroup);
 }




More information about the Bf-blender-cvs mailing list