[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [36222] trunk/blender/source/blender: Bugfix [#25960] Action/NLA Editor issues with animdata context

Joshua Leung aligorith at gmail.com
Tue Apr 19 15:01:50 CEST 2011


Revision: 36222
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=36222
Author:   aligorith
Date:     2011-04-19 13:01:50 +0000 (Tue, 19 Apr 2011)
Log Message:
-----------
Bugfix [#25960] Action/NLA Editor issues with animdata context

Actions now get tagged with an ID-code, which is used to determine
what ID-blocks they can be assigned to. This ensures that material
actions cannot be assigned to the object-level for example.

* Action lists in general will now show only the actions that can be
set for that particular slot. This prevents selection of invalid
actions, and helps cut down the list of actions.
** An exception here is the Add Action Clip in NLA Editor, which will
show all actions but will only add where appropriate. This is because
it's not easy/possible to tell in advance which blocktypes to filter
for when building this list. (TODO?)

* The "Action Editor" is now strictly for object-level action
editing+setting now. This avoids repeateded confusion by people who
try using this to view their shapekey actions, which should go to the
Shape Key Editor instead!
** A context switcher for the legitimate times where this capability
might come in handy is still being investigated.

* "Floating" actions (i.e. actions in some action_library.blend) are
NOT able to be automatically tagged until they are assigned to some
datablocks (i.e. loaded onto the rig + played back once). It is
possible to write scripts that check for certain RNA-paths and "guess"
what datablocks they work on, but it is recommended that you load up
the Datablocks Viewer, and go through such actions by hand, setting
the "ID Root Type" property as appropriate per action.

Modified Paths:
--------------
    trunk/blender/source/blender/blenkernel/intern/anim_sys.c
    trunk/blender/source/blender/blenkernel/intern/ipo.c
    trunk/blender/source/blender/blenloader/intern/readfile.c
    trunk/blender/source/blender/editors/space_nla/nla_edit.c
    trunk/blender/source/blender/makesdna/DNA_action_types.h
    trunk/blender/source/blender/makesrna/intern/rna_action.c
    trunk/blender/source/blender/makesrna/intern/rna_animation.c
    trunk/blender/source/blender/makesrna/intern/rna_internal.h
    trunk/blender/source/blender/makesrna/intern/rna_nla.c
    trunk/blender/source/blender/makesrna/intern/rna_space.c

Modified: trunk/blender/source/blender/blenkernel/intern/anim_sys.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/anim_sys.c	2011-04-19 11:17:29 UTC (rev 36221)
+++ trunk/blender/source/blender/blenkernel/intern/anim_sys.c	2011-04-19 13:01:50 UTC (rev 36222)
@@ -1199,6 +1199,39 @@
 /* ***************************************** */
 /* Actions Evaluation */
 
+/* strictly not necessary for actual "evaluation", but it is a useful safety check
+ * to reduce the amount of times that users end up having to "revive" wrongly-assigned
+ * actions
+ */
+static void action_idcode_patch_check (ID *id, bAction *act)
+{
+	int idcode = 0;
+	
+	/* just in case */
+	if (ELEM(NULL, id, act))
+		return;
+	else
+		idcode = GS(id->name);
+	
+	/* the actual checks... hopefully not too much of a performance hit in the long run... */
+	if (act->idroot == 0) {
+		/* use the current root if not set already (i.e. newly created actions and actions from 2.50-2.57 builds)
+		 * 	- this has problems if there are 2 users, and the first one encountered is the invalid one
+		 *	  in which case, the user will need to manually fix this (?)
+		 */
+		act->idroot = idcode;
+	}
+	else if (act->idroot != idcode) {
+		/* only report this error if debug mode is enabled (to save performance everywhere else) */
+		if (G.f & G_DEBUG) {
+			printf("AnimSys Safety Check Failed: Action '%s' is not meant to be used from ID-Blocks of type %d such as '%s'\n",
+				act->id.name+2, idcode, id->name);
+		}
+	}
+}
+
+/* ----------------------------------------- */
+
 /* Evaluate Action Group */
 void animsys_evaluate_action_group (PointerRNA *ptr, bAction *act, bActionGroup *agrp, AnimMapper *remap, float ctime)
 {
@@ -1208,6 +1241,8 @@
 	if ELEM(NULL, act, agrp) return;
 	if ((remap) && (remap->target != act)) remap= NULL;
 	
+	action_idcode_patch_check(ptr->id.data, act);
+	
 	/* if group is muted, don't evaluated any of the F-Curve */
 	if (agrp->flag & AGRP_MUTED)
 		return;
@@ -1231,6 +1266,8 @@
 	if (act == NULL) return;
 	if ((remap) && (remap->target != act)) remap= NULL;
 	
+	action_idcode_patch_check(ptr->id.data, act);
+	
 	/* calculate then execute each curve */
 	animsys_evaluate_fcurves(ptr, &act->curves, remap, ctime);
 }
@@ -1630,6 +1667,17 @@
 	FCurve *fcu;
 	float evaltime;
 	
+	/* sanity checks for action */
+	if (strip == NULL)
+		return;
+		
+	if (strip->act == NULL) {
+		printf("NLA-Strip Eval Error: Strip '%s' has no Action\n", strip->name);
+		return;
+	}
+	
+	action_idcode_patch_check(ptr->id.data, strip->act);
+	
 	/* join this strip's modifiers to the parent's modifiers (own modifiers first) */
 	nlaeval_fmodifiers_join_stacks(&tmp_modifiers, &strip->modifiers, modifiers);
 	

Modified: trunk/blender/source/blender/blenkernel/intern/ipo.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/ipo.c	2011-04-19 11:17:29 UTC (rev 36221)
+++ trunk/blender/source/blender/blenkernel/intern/ipo.c	2011-04-19 13:01:50 UTC (rev 36222)
@@ -1372,7 +1372,7 @@
  * This does not assume that any ID or AnimData uses it, but does assume that
  * it is given two lists, which it will perform driver/animation-data separation.
  */
-static void ipo_to_animato (ID *id, Ipo *ipo, char actname[], char constname[], Sequence * seq, ListBase *animgroups, ListBase *anim, ListBase *drivers)
+static void ipo_to_animato (ID *id, Ipo *ipo, char actname[], char constname[], Sequence *seq, ListBase *animgroups, ListBase *anim, ListBase *drivers)
 {
 	IpoCurve *icu;
 	
@@ -1804,6 +1804,10 @@
 				BLI_freelinkN(&ob->constraintChannels, conchan);
 			}
 		}
+		
+		/* object's action will always be object-rooted */
+		if (adt->action)
+			adt->action->idroot = ID_OB;
 	}
 	
 	/* shapekeys */
@@ -1822,6 +1826,10 @@
 			
 			/* Convert Shapekey data... */
 			ipo_to_animdata(id, key->ipo, NULL, NULL, NULL);
+			
+			if (adt->action)
+				adt->action->idroot = key->ipo->blocktype;
+			
 			key->ipo->id.us--;
 			key->ipo= NULL;
 		}
@@ -1840,6 +1848,10 @@
 			
 			/* Convert Material data... */
 			ipo_to_animdata(id, ma->ipo, NULL, NULL, NULL);
+			
+			if (adt->action)
+				adt->action->idroot = ma->ipo->blocktype;
+			
 			ma->ipo->id.us--;
 			ma->ipo= NULL;
 		}
@@ -1858,6 +1870,10 @@
 			
 			/* Convert World data... */
 			ipo_to_animdata(id, wo->ipo, NULL, NULL, NULL);
+			
+			if (adt->action)
+				adt->action->idroot = wo->ipo->blocktype;
+			
 			wo->ipo->id.us--;
 			wo->ipo= NULL;
 		}
@@ -1904,6 +1920,10 @@
 				
 				/* convert IPO */
 				ipo_to_animdata((ID *)scene, seq->ipo, NULL, NULL, seq);
+				
+				if (adt->action)
+					adt->action->idroot = ID_SCE; /* scene-rooted */
+				
 				seq->ipo->id.us--;
 				seq->ipo = NULL;
 			}
@@ -1925,6 +1945,10 @@
 			
 			/* Convert Texture data... */
 			ipo_to_animdata(id, te->ipo, NULL, NULL, NULL);
+			
+			if (adt->action)
+				adt->action->idroot = te->ipo->blocktype;
+			
 			te->ipo->id.us--;
 			te->ipo= NULL;
 		}
@@ -1943,6 +1967,10 @@
 			
 			/* Convert Camera data... */
 			ipo_to_animdata(id, ca->ipo, NULL, NULL, NULL);
+			
+			if (adt->action)
+				adt->action->idroot = ca->ipo->blocktype;
+			
 			ca->ipo->id.us--;
 			ca->ipo= NULL;
 		}
@@ -1961,6 +1989,10 @@
 			
 			/* Convert Lamp data... */
 			ipo_to_animdata(id, la->ipo, NULL, NULL, NULL);
+			
+			if (adt->action)
+				adt->action->idroot = la->ipo->blocktype;
+			
 			la->ipo->id.us--;
 			la->ipo= NULL;
 		}
@@ -1979,6 +2011,10 @@
 			
 			/* Convert Curve data... */
 			ipo_to_animdata(id, cu->ipo, NULL, NULL, NULL);
+			
+			if (adt->action)
+				adt->action->idroot = cu->ipo->blocktype;
+			
 			cu->ipo->id.us--;
 			cu->ipo= NULL;
 		}
@@ -2001,6 +2037,10 @@
 		
 		if (G.f & G_DEBUG) printf("\tconverting action %s \n", id->name+2);
 		
+		/* if old action, it will be object-only... */
+		if (act->chanbase.first)
+			act->idroot = ID_OB;
+		
 		/* be careful! some of the actions we encounter will be converted ones... */
 		action_to_animato(NULL, act, &act->groups, &act->curves, &drivers);
 	}
@@ -2018,6 +2058,7 @@
 			/* add a new action for this, and convert all data into that action */
 			new_act= add_empty_action("ConvIPO_Action"); // XXX need a better name...
 			ipo_to_animato(NULL, ipo, NULL, NULL, NULL, NULL, &new_act->curves, &drivers);
+			new_act->idroot = ipo->blocktype;
 		}
 		
 		/* clear fake-users, and set user-count to zero to make sure it is cleared on file-save */

Modified: trunk/blender/source/blender/blenloader/intern/readfile.c
===================================================================
--- trunk/blender/source/blender/blenloader/intern/readfile.c	2011-04-19 11:17:29 UTC (rev 36221)
+++ trunk/blender/source/blender/blenloader/intern/readfile.c	2011-04-19 13:01:50 UTC (rev 36222)
@@ -1863,6 +1863,10 @@
 		
 		/* reassign the counted-reference to action */
 		strip->act = newlibadr_us(fd, id->lib, strip->act);
+		
+		/* fix action id-root (i.e. if it comes from a pre 2.57 .blend file) */
+		if ((strip->act) && (strip->act->idroot == 0))
+			strip->act->idroot = GS(id->name);
 	}
 }
 
@@ -1956,6 +1960,12 @@
 	adt->action= newlibadr_us(fd, id->lib, adt->action);
 	adt->tmpact= newlibadr_us(fd, id->lib, adt->tmpact);
 	
+	/* fix action id-roots (i.e. if they come from a pre 2.57 .blend file) */
+	if ((adt->action) && (adt->action->idroot == 0))
+		adt->action->idroot = GS(id->name);
+	if ((adt->tmpact) && (adt->tmpact->idroot == 0))
+		adt->tmpact->idroot = GS(id->name);
+	
 	/* link drivers */
 	lib_link_fcurves(fd, id, &adt->drivers);
 	

Modified: trunk/blender/source/blender/editors/space_nla/nla_edit.c
===================================================================
--- trunk/blender/source/blender/editors/space_nla/nla_edit.c	2011-04-19 11:17:29 UTC (rev 36221)
+++ trunk/blender/source/blender/editors/space_nla/nla_edit.c	2011-04-19 13:01:50 UTC (rev 36222)
@@ -271,6 +271,12 @@
 		//printf("Add strip - actname = '%s' \n", actname);
 		return OPERATOR_CANCELLED;
 	}
+	else if (act->idroot == 0) {
+		/* hopefully in this case (i.e. library of userless actions), the user knows what they're doing... */
+		BKE_reportf(op->reports, RPT_WARNING,
+			"Action '%s' does not specify what datablocks it can be used on. Try setting the 'ID Root Type' setting from the Datablocks Editor for this Action to avoid future problems",
+			act->id.name+2);
+	}
 	
 	/* get a list of the editable tracks being shown in the NLA
 	 *	- this is limited to active ones for now, but could be expanded to 
@@ -289,6 +295,16 @@
 		AnimData *adt= ale->adt;
 		NlaStrip *strip= NULL;
 		
+		/* sanity check: only apply actions of the right type for this ID 
+		 * NOTE: in the case that this hasn't been set, we've already warned the user about this already
+		 */
+		if ((act->idroot) && (act->idroot != GS(ale->id->name))) {
+			BKE_reportf(op->reports, RPT_ERROR, 
+				"Couldn't add action '%s' as it cannot be used relative to ID-blocks of type '%s'",
+				act->id.name+2, ale->id->name);
+			continue;
+		}
+		
 		/* create a new strip, and offset it to start on the current frame */
 		strip= add_nlastrip(act);
 		

Modified: trunk/blender/source/blender/makesdna/DNA_action_types.h
===================================================================
--- trunk/blender/source/blender/makesdna/DNA_action_types.h	2011-04-19 11:17:29 UTC (rev 36221)
+++ trunk/blender/source/blender/makesdna/DNA_action_types.h	2011-04-19 13:01:50 UTC (rev 36222)
@@ -487,6 +487,9 @@
 	
 	int flag;			/* settings for this action */
 	int active_marker;	/* index of the active marker */
+	
+	int idroot;			/* type of ID-blocks that action can be assigned to (if 0, will be set to whatever ID first evaluates it) */
+	int pad;
 } bAction;
 
 

Modified: trunk/blender/source/blender/makesrna/intern/rna_action.c
===================================================================
--- trunk/blender/source/blender/makesrna/intern/rna_action.c	2011-04-19 11:17:29 UTC (rev 36221)
+++ trunk/blender/source/blender/makesrna/intern/rna_action.c	2011-04-19 13:01:50 UTC (rev 36222)
@@ -30,6 +30,7 @@
 #include <stdlib.h>
 
 #include "RNA_define.h"
+#include "RNA_enum_types.h"
 
 #include "rna_internal.h"
 
@@ -194,6 +195,56 @@
 	calc_action_range(ptr->id.data, values, values+1, 1);
 }
 
+
+/* used to check if an action (value pointer) is suitable to be assigned to the ID-block that is ptr */
+int rna_Action_id_poll(PointerRNA *ptr, PointerRNA value)
+{
+	ID *srcId = (ID *)ptr->id.data;

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list