[Bf-blender-cvs] [ac30378] master: Action Editor: Stash Action Operator

Joshua Leung noreply at git.blender.org
Sat Feb 28 14:37:13 CET 2015


Commit: ac30378e3e3d790bad6d8027c2443b57cf47068e
Author: Joshua Leung
Date:   Sat Feb 28 03:32:13 2015 +1300
Branches: master
https://developer.blender.org/rBac30378e3e3d790bad6d8027c2443b57cf47068e

Action Editor: Stash Action Operator

This operator (the snowflake icon, beside the pushdown button on the Action Editor
header) adds the currently active action to the NLA stack in a muted track, then
creates + loads a new action ready to be populated with new keyframes.
Since the NLA is being used to hang on to all the actions here, no actions are
getting lost.

Usage Notes (there will be some additional tweaks to make this nicer):
* To preview different actions that have been "stashed", simply click the "Solo"
  toggle for the track containing the action in question. Playing back the NLA will
  now show the stashed track
* To edit a previously stashed action - simply enter tweakmode on it in the NLA
  while the "Solo" toggle is enabled.

Todo:
* Add some more operators here to polish up the Action <-> NLA bridge to make the
  layered and stash workflows smoother. Examples include some tools to easily
  switch between the different actions layers in the stack, as well as making it
  easier to get out of tweakmode (and sync up the action lengths)

* Review and cleanup the behaviour of the "new" operator here to avoid the old
  problems that users were running into

* After the next release - Implement the full Action Libraries functionality, with
  ways to bridge the stashed strips over to a full-blown library.

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

M	release/scripts/startup/bl_ui/space_dopesheet.py
M	source/blender/editors/space_action/CMakeLists.txt
M	source/blender/editors/space_action/SConscript
M	source/blender/editors/space_action/action_edit.c
M	source/blender/editors/space_action/action_intern.h
M	source/blender/editors/space_action/action_ops.c

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

diff --git a/release/scripts/startup/bl_ui/space_dopesheet.py b/release/scripts/startup/bl_ui/space_dopesheet.py
index 16dfb1d..f69ab3a 100644
--- a/release/scripts/startup/bl_ui/space_dopesheet.py
+++ b/release/scripts/startup/bl_ui/space_dopesheet.py
@@ -126,7 +126,7 @@ class DOPESHEET_HT_header(Header):
 
             row = layout.row(align=True)
             row.operator("action.push_down", text="", icon='NLA_PUSHDOWN')
-            row.operator("action.push_down", text="", icon='FREEZE') # XXX: "stash"
+            row.operator("action.stash", text="", icon='FREEZE')
 
         # Grease Pencil mode doesn't need snapping, as it's frame-aligned only
         if st.mode != 'GPENCIL':
diff --git a/source/blender/editors/space_action/CMakeLists.txt b/source/blender/editors/space_action/CMakeLists.txt
index 96a1e74..50cf840 100644
--- a/source/blender/editors/space_action/CMakeLists.txt
+++ b/source/blender/editors/space_action/CMakeLists.txt
@@ -22,6 +22,7 @@ set(INC
 	../include
 	../../blenkernel
 	../../blenlib
+	../../blenfont
 	../../gpu
 	../../makesdna
 	../../makesrna
diff --git a/source/blender/editors/space_action/SConscript b/source/blender/editors/space_action/SConscript
index 2e2081b..20f31dd 100644
--- a/source/blender/editors/space_action/SConscript
+++ b/source/blender/editors/space_action/SConscript
@@ -38,6 +38,7 @@ incs = [
     '../include',
     '../../blenkernel',
     '../../blenlib',
+    '../../blenfont',
     '../../gpu',
     '../../makesdna',
     '../../makesrna',
diff --git a/source/blender/editors/space_action/action_edit.c b/source/blender/editors/space_action/action_edit.c
index fe29fed..1562097 100644
--- a/source/blender/editors/space_action/action_edit.c
+++ b/source/blender/editors/space_action/action_edit.c
@@ -40,6 +40,8 @@
 #include "BLI_math.h"
 #include "BLI_utildefines.h"
 
+#include "BLF_translation.h"
+
 #include "DNA_anim_types.h"
 #include "DNA_gpencil_types.h"
 #include "DNA_key_types.h"
@@ -54,6 +56,7 @@
 #include "BKE_action.h"
 #include "BKE_fcurve.h"
 #include "BKE_global.h"
+#include "BKE_library.h"
 #include "BKE_key.h"
 #include "BKE_main.h"
 #include "BKE_nla.h"
@@ -107,7 +110,7 @@ static int act_new_exec(bContext *C, wmOperator *UNUSED(op))
 		}
 		else {
 			Main *bmain = CTX_data_main(C);
-
+			
 			/* just make a new (empty) action */
 			action = add_empty_action(bmain, "Action");
 		}
@@ -237,6 +240,121 @@ void ACTION_OT_push_down(wmOperatorType *ot)
 	ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
 }
 
+/* ******************* Action Stash Operator ******************** */
+
+static int action_stash_exec(bContext *C, wmOperator *op)
+{
+	SpaceAction *saction = (SpaceAction *)CTX_wm_space_data(C);
+	Object *ob = CTX_data_active_object(C);
+	AnimData *adt = NULL;
+	
+	/* Get AnimData block to use */
+	if (saction->mode == SACTCONT_ACTION) {
+		/* Currently, "Action Editor" means object-level only... */
+		adt = ob->adt;
+	}
+	else if (saction->mode == SACTCONT_SHAPEKEY) {
+		Key *key = BKE_key_from_object(ob);
+		adt = key->adt;
+	}
+	
+	/* Perform stashing operation */
+	// TODO: abstract this out to an API call
+	if (adt) {
+		/* don't do anything if this action is empty... */
+		if (action_has_motion(adt->action) == 0) {
+			/* action may not be suitable... */
+			BKE_report(op->reports, RPT_WARNING, "Action needs have at least a keyframe or some FModifiers");
+			return OPERATOR_CANCELLED;
+		}
+		else {
+			const char *STASH_TRACK_NAME = DATA_("[Action Stash]");
+			
+			NlaTrack *prev_track = NULL;
+			NlaTrack *nlt;
+			NlaStrip *strip;
+			
+			bAction *new_action = NULL;
+			
+			PointerRNA ptr, idptr;
+			PropertyRNA *prop;
+			
+			/* create a new track, and add this immediately above the previous stashing track */
+			for (prev_track = adt->nla_tracks.last; prev_track; prev_track = prev_track->prev) {
+				if (strstr(prev_track->name, STASH_TRACK_NAME)) {
+					break;
+				}
+			}
+			
+			nlt = add_nlatrack(adt, prev_track);
+			nlt->flag |= NLATRACK_MUTED; /* so that stash track doesn't disturb the stack animation */
+			
+			BLI_strncpy(nlt->name, STASH_TRACK_NAME, sizeof(nlt->name));
+			BLI_uniquename(&adt->nla_tracks, nlt, STASH_TRACK_NAME, '.', offsetof(NlaTrack, name), sizeof(nlt->name));
+			
+			/* add the action as a strip in this new track
+			 * NOTE: a new user is created here
+			 */
+			strip = add_nlastrip(adt->action);
+			
+			BKE_nlatrack_add_strip(nlt, strip);
+			BKE_nlastrip_validate_name(adt, strip);
+			BKE_nlastrip_set_active(adt, strip);
+			
+			/* create new action (if required) */
+			if (RNA_boolean_get(op->ptr, "create_new")) {
+				new_action = add_empty_action(CTX_data_main(C), "New Action");
+				
+				/* when creating new ID blocks, there is already 1 user (as for all new datablocks), 
+				 * but the RNA pointer code will assign all the proper users instead, so we compensate
+				 * for that here
+				 */
+				BLI_assert(new_action->id.us == 1);
+				new_action->id.us--;
+				
+				/* set ID-Root type */
+				if (saction->mode == SACTCONT_SHAPEKEY)
+					new_action->idroot = ID_KE;
+				else
+					new_action->idroot = ID_OB;
+			}
+			
+			/* update pointers
+			 * NOTE: this will clear the user from whatever it is using now
+			 */
+			RNA_pointer_create((ID *)CTX_wm_screen(C), &RNA_SpaceDopeSheetEditor, saction, &ptr);
+			prop = RNA_struct_find_property(&ptr, "action");
+			RNA_id_pointer_create((ID *)new_action, &idptr);
+			
+			RNA_property_pointer_set(&ptr, prop, idptr);
+			RNA_property_update(C, &ptr, prop);
+		}
+	}
+	
+	/* Send notifiers that stuff has changed */
+	WM_event_add_notifier(C, NC_ANIMATION | ND_NLA_ACTCHANGE, NULL);
+	return OPERATOR_FINISHED;
+}
+
+void ACTION_OT_stash(wmOperatorType *ot)
+{
+	/* identifiers */
+	ot->name = "Stash Action";
+	ot->idname = "ACTION_OT_stash";
+	ot->description = "Store this action in the NLA stack as a non-contributing strip for later use";
+	
+	/* callbacks */
+	ot->exec = action_stash_exec;
+	ot->poll = action_pushdown_poll;
+	
+	/* flags */
+	ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+	
+	/* properties */
+	ot->prop = RNA_def_boolean(ot->srna, "create_new", true, "Create New Action", 
+	                           "Create a new action once the existing one has been safely stored");
+}
+
 /* ************************************************************************** */
 /* POSE MARKERS STUFF */
 
diff --git a/source/blender/editors/space_action/action_intern.h b/source/blender/editors/space_action/action_intern.h
index 8bade7a..f0f651d 100644
--- a/source/blender/editors/space_action/action_intern.h
+++ b/source/blender/editors/space_action/action_intern.h
@@ -102,6 +102,7 @@ void ACTION_OT_mirror(struct wmOperatorType *ot);
 
 void ACTION_OT_new(struct wmOperatorType *ot);
 void ACTION_OT_push_down(struct wmOperatorType *ot);
+void ACTION_OT_stash(struct wmOperatorType *ot);
 
 void ACTION_OT_markers_make_local(struct wmOperatorType *ot);
 
diff --git a/source/blender/editors/space_action/action_ops.c b/source/blender/editors/space_action/action_ops.c
index 76b0801..0bf31d2 100644
--- a/source/blender/editors/space_action/action_ops.c
+++ b/source/blender/editors/space_action/action_ops.c
@@ -80,6 +80,7 @@ void action_operatortypes(void)
 	
 	WM_operatortype_append(ACTION_OT_new);
 	WM_operatortype_append(ACTION_OT_push_down);
+	WM_operatortype_append(ACTION_OT_stash);
 	
 	WM_operatortype_append(ACTION_OT_previewrange_set);
 	WM_operatortype_append(ACTION_OT_view_all);




More information about the Bf-blender-cvs mailing list