[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [54734] trunk/blender: Animation Editors: Operators to Group/Ungroup Selected F-Curves

Joshua Leung aligorith at gmail.com
Fri Feb 22 02:49:52 CET 2013


Revision: 54734
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=54734
Author:   aligorith
Date:     2013-02-22 01:49:51 +0000 (Fri, 22 Feb 2013)
Log Message:
-----------
Animation Editors: Operators to Group/Ungroup Selected F-Curves

This commit introduces operators to customise the grouping of F-Curves. As
groups are only available in Actions, these grouping operators only work in the
Dopesheet, Action Editor, and Graph Editor (Animation) modes.

To Use:
* Ctrl-G = Group selected F-Curves
* Alt-G  = Ungroup selected F-Curves
* or find these tools from the Channels menu

Notes:
* When invoking the grouping operator from the Channels menu, the name popup
won't show up. Instead, the group(s) created will be created with the default
name. To fix, you can either use the F6 operator properties edit OR manually
edit the names (Ctrl-LMB on the relevant channel)

Modified Paths:
--------------
    trunk/blender/release/scripts/startup/bl_ui/space_dopesheet.py
    trunk/blender/release/scripts/startup/bl_ui/space_graph.py
    trunk/blender/source/blender/editors/animation/anim_channels_edit.c
    trunk/blender/source/blender/editors/animation/anim_filter.c

Modified: trunk/blender/release/scripts/startup/bl_ui/space_dopesheet.py
===================================================================
--- trunk/blender/release/scripts/startup/bl_ui/space_dopesheet.py	2013-02-22 01:48:53 UTC (rev 54733)
+++ trunk/blender/release/scripts/startup/bl_ui/space_dopesheet.py	2013-02-22 01:49:51 UTC (rev 54734)
@@ -241,6 +241,10 @@
         layout.operator("anim.channels_delete")
 
         layout.separator()
+        layout.operator("anim.channels_group")
+        layout.operator("anim.channels_ungroup")
+
+        layout.separator()
         layout.operator_menu_enum("anim.channels_setting_toggle", "type")
         layout.operator_menu_enum("anim.channels_setting_enable", "type")
         layout.operator_menu_enum("anim.channels_setting_disable", "type")

Modified: trunk/blender/release/scripts/startup/bl_ui/space_graph.py
===================================================================
--- trunk/blender/release/scripts/startup/bl_ui/space_graph.py	2013-02-22 01:48:53 UTC (rev 54733)
+++ trunk/blender/release/scripts/startup/bl_ui/space_graph.py	2013-02-22 01:49:51 UTC (rev 54734)
@@ -161,6 +161,10 @@
         layout.operator("anim.channels_delete")
 
         layout.separator()
+        layout.operator("anim.channels_group")
+        layout.operator("anim.channels_ungroup")
+
+        layout.separator()
         layout.operator_menu_enum("anim.channels_setting_toggle", "type")
         layout.operator_menu_enum("anim.channels_setting_enable", "type")
         layout.operator_menu_enum("anim.channels_setting_disable", "type")

Modified: trunk/blender/source/blender/editors/animation/anim_channels_edit.c
===================================================================
--- trunk/blender/source/blender/editors/animation/anim_channels_edit.c	2013-02-22 01:48:53 UTC (rev 54733)
+++ trunk/blender/source/blender/editors/animation/anim_channels_edit.c	2013-02-22 01:49:51 UTC (rev 54734)
@@ -1147,6 +1147,218 @@
 	ot->prop = RNA_def_enum(ot->srna, "direction", prop_animchannel_rearrange_types, REARRANGE_ANIMCHAN_DOWN, "Direction", "");
 }
 
+/* ******************** Group Channel Operator ************************ */
+
+static int animchannels_grouping_poll(bContext *C)
+{
+	ScrArea *sa = CTX_wm_area(C);
+	SpaceLink *sl;
+
+	/* channels region test */
+	/* TODO: could enhance with actually testing if channels region? */
+	if (ELEM(NULL, sa, CTX_wm_region(C)))
+		return 0;
+		
+	/* animation editor test - must be suitable modes only */
+	sl = CTX_wm_space_data(C);
+	
+	switch (sa->spacetype) {
+		/* supported... */
+		case SPACE_ACTION:
+		{
+			SpaceAction *saction = (SpaceAction *)sl;
+			
+			/* dopesheet and action only - all others are for other datatypes or have no groups */
+			if (ELEM(saction->mode, SACTCONT_ACTION, SACTCONT_DOPESHEET) == 0)
+				return 0;
+		}
+			break;
+			
+		case SPACE_IPO:
+		{
+			SpaceIpo *sipo = (SpaceIpo *)sl;
+			
+			/* drivers can't have groups... */
+			if (sipo->mode != SIPO_MODE_ANIMATION)
+				return 0;
+		}
+			break;
+			
+		/* unsupported... */
+		default:
+			return 0;
+	}
+	
+	return 1;
+}
+
+/* ----------------------------------------------------------- */
+
+static void animchannels_group_channels(bAnimContext *ac, bAnimListElem *adt_ref, const char name[])
+{	
+	AnimData *adt = adt_ref->adt;
+	bAction *act = adt->action;
+	
+	if (act) {
+		ListBase anim_data = {NULL, NULL};
+		int filter;
+		
+		/* find selected F-Curves to re-group */
+		filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_SEL);
+		ANIM_animdata_filter(ac, &anim_data, filter, adt_ref, ANIMCONT_CHANNEL);
+		
+		if (anim_data.first) {
+			bActionGroup *agrp;
+			bAnimListElem *ale;
+			
+			/* create new group, which should now be part of the action */
+			agrp = action_groups_add_new(act, name);
+			BLI_assert(agrp != NULL);
+			
+			/* transfer selected F-Curves across to new group  */
+			for (ale = anim_data.first; ale; ale = ale->next) {
+				FCurve *fcu = (FCurve *)ale->data;
+				bActionGroup *grp = fcu->grp;
+				
+				/* remove F-Curve from group, then group too if it is now empty */
+				action_groups_remove_channel(act, fcu);
+				
+				if ((grp) && (grp->channels.first == NULL)) {
+					BLI_freelinkN(&act->groups, grp);
+				}
+				
+				/* add F-Curve to group */
+				action_groups_add_channel(act, agrp, fcu);
+			}
+		}
+		
+		/* cleanup */
+		BLI_freelistN(&anim_data);
+	}
+}
+
+static int animchannels_group_exec(bContext *C, wmOperator *op)
+{
+	bAnimContext ac;
+	char name[MAX_NAME];
+	
+	/* get editor data */
+	if (ANIM_animdata_get_context(C, &ac) == 0)
+		return OPERATOR_CANCELLED;
+	
+	/* get name for new group */
+	RNA_string_get(op->ptr, "name", name);
+	
+	/* XXX: name for group should never be empty... */
+	if (name[0]) {
+		ListBase anim_data = {NULL, NULL};
+		bAnimListElem *ale;
+		int filter;
+		
+		/* handle each animdata block separately, so that the regrouping doesn't flow into blocks  */
+		filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_ANIMDATA | ANIMFILTER_NODUPLIS);
+		ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
+		
+		for (ale = anim_data.first; ale; ale = ale->next) {
+			animchannels_group_channels(&ac, ale, name);
+		}
+		
+		/* free temp data */
+		BLI_freelistN(&anim_data);
+		
+		/* updatss */
+		WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
+	}
+	
+	return OPERATOR_FINISHED;
+}
+
+static void ANIM_OT_channels_group(wmOperatorType *ot)
+{
+	/* identifiers */
+	ot->name = "Group Channels";
+	ot->idname = "ANIM_OT_channels_group";
+	ot->description = "Add selected F-Curves to a new group";
+	
+	/* callbacks */
+	ot->invoke = WM_operator_props_popup;
+	ot->exec = animchannels_group_exec;
+	ot->poll = animchannels_grouping_poll;
+	
+	/* flags */
+	ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+	
+	/* props */
+	ot->prop = RNA_def_string(ot->srna, "name", "New Group", 
+	                          sizeof(((bActionGroup *)NULL)->name), 
+	                          "Name", "Name of newly created group");
+	/* RNA_def_property_flag(ot->prop, PROP_SKIP_SAVE); */ /* XXX: still not too sure about this - keeping same text is confusing... */
+}
+
+/* ----------------------------------------------------------- */
+
+static int animchannels_ungroup_exec(bContext *C, wmOperator *UNUSED(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;
+		
+	/* just selected F-Curves... */
+	filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_SEL | ANIMFILTER_NODUPLIS);
+	ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
+	
+	for (ale = anim_data.first; ale; ale = ale->next) {
+		/* find action for this F-Curve... */
+		if (ale->adt && ale->adt->action) {
+			FCurve  *fcu = (FCurve *)ale->data;
+			bAction *act = ale->adt->action;
+			
+			/* only proceed to remove if F-Curve is in a group... */
+			if (fcu->grp) { 
+				bActionGroup *agrp = fcu->grp;
+				
+				/* remove F-Curve from group and add at tail (ungrouped) */
+				action_groups_remove_channel(act, fcu);
+				BLI_addtail(&act->curves, fcu);
+				
+				/* delete group if it is now empty */
+				if (agrp->channels.first == NULL) {
+					BLI_freelinkN(&act->groups, agrp);
+				}
+			}
+		}
+	}
+	
+	/* cleanup */
+	BLI_freelistN(&anim_data);
+	
+	/* updates */
+	WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
+	
+	return OPERATOR_FINISHED;
+}
+
+static void ANIM_OT_channels_ungroup(wmOperatorType *ot)
+{
+	/* identifiers */
+	ot->name = "Ungroup Channels";
+	ot->idname = "ANIM_OT_channels_ungroup";
+	ot->description = "Remove selected F-Curves from their current groups";
+	
+	/* callbacks */
+	ot->exec = animchannels_ungroup_exec;
+	ot->poll = animchannels_grouping_poll;
+	
+	/* flags */
+	ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
 /* ******************** Delete Channel Operator *********************** */
 
 static int animchannels_delete_exec(bContext *C, wmOperator *UNUSED(op))
@@ -1233,13 +1445,13 @@
 				BLI_freelinkN(&gpd->layers, gpl);
 			}
 			break;
-
+			
 			case ANIMTYPE_MASKLAYER:
 			{
 				/* Mask layer */
 				Mask *mask = (Mask *)ale->id;
 				MaskLayer *masklay = (MaskLayer *)ale->data;
-
+				
 				/* try to delete the layer's data and the layer itself */
 				BKE_mask_layer_remove(mask, masklay);
 			}
@@ -1330,10 +1542,10 @@
 		/* TODO: find out why this is the case, and fix that */
 		if (ale->type == ANIMTYPE_OBJECT)
 			continue;
-
+		
 		/* enable the setting */
 		ANIM_channel_setting_set(&ac, ale, ACHANNEL_SETTING_VISIBLE, ACHANNEL_SETFLAG_ADD);
-
+		
 		/* now, also flush selection status up/down as appropriate */
 		ANIM_flush_setting_anim_channels(&ac, &all_data, ale, ACHANNEL_SETTING_VISIBLE, 1);
 	}
@@ -1407,10 +1619,10 @@
 		/* TODO: find out why this is the case, and fix that */
 		if (ale->type == ANIMTYPE_OBJECT)
 			continue;
-
+		
 		/* change the setting */
 		ANIM_channel_setting_set(&ac, ale, ACHANNEL_SETTING_VISIBLE, vis);
-
+		
 		/* now, also flush selection status up/down as appropriate */
 		ANIM_flush_setting_anim_channels(&ac, &all_data, ale, ACHANNEL_SETTING_VISIBLE, (vis == ACHANNEL_SETFLAG_ADD));
 	}
@@ -2480,6 +2692,9 @@
 	WM_operatortype_append(ANIM_OT_channels_visibility_set);
 	
 	WM_operatortype_append(ANIM_OT_channels_fcurves_enable);
+	
+	WM_operatortype_append(ANIM_OT_channels_group);
+	WM_operatortype_append(ANIM_OT_channels_ungroup);
 }
 
 // TODO: check on a poll callback for this, to get hotkeys into menus
@@ -2533,6 +2748,10 @@
 	RNA_enum_set(WM_keymap_add_item(keymap, "ANIM_OT_channels_move", PAGEUPKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "direction", REARRANGE_ANIMCHAN_TOP);
 	RNA_enum_set(WM_keymap_add_item(keymap, "ANIM_OT_channels_move", PAGEDOWNKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "direction", REARRANGE_ANIMCHAN_BOTTOM);
 	
+	/* grouping */
+	WM_keymap_add_item(keymap, "ANIM_OT_channels_group", GKEY, KM_PRESS, KM_CTRL, 0);
+	WM_keymap_add_item(keymap, "ANIM_OT_channels_ungroup", GKEY, KM_PRESS, KM_ALT, 0);
+	
 	/* Graph Editor only */
 	WM_keymap_add_item(keymap, "ANIM_OT_channels_visibility_set", VKEY, KM_PRESS, 0, 0);
 	WM_keymap_add_item(keymap, "ANIM_OT_channels_visibility_toggle", VKEY, KM_PRESS, KM_SHIFT, 0);

Modified: trunk/blender/source/blender/editors/animation/anim_filter.c
===================================================================

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list