[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [18977] branches/blender2.5/blender/source /blender: Keying Sets: Added 'remove selected from active set' (Alt-K) operator in Outliner

Joshua Leung aligorith at gmail.com
Sun Feb 15 08:00:33 CET 2009


Revision: 18977
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=18977
Author:   aligorith
Date:     2009-02-15 08:00:13 +0100 (Sun, 15 Feb 2009)

Log Message:
-----------
Keying Sets: Added 'remove selected from active set' (Alt-K) operator in Outliner 

* Cleaned up the helper functions for the Outliner operators which deal with Keying Sets
* Fixed a few minor bugs in the Keying Sets API that won't show up with the current tools, but may crop up later
* Added a new method to find a 'matching' path in a Keying Set. Now adding a new path to a Keying Set will firstly check if there is any similar path already, and skip adding another path.

Modified Paths:
--------------
    branches/blender2.5/blender/source/blender/blenkernel/BKE_animsys.h
    branches/blender2.5/blender/source/blender/blenkernel/intern/anim_sys.c
    branches/blender2.5/blender/source/blender/editors/space_outliner/outliner.c

Modified: branches/blender2.5/blender/source/blender/blenkernel/BKE_animsys.h
===================================================================
--- branches/blender2.5/blender/source/blender/blenkernel/BKE_animsys.h	2009-02-15 02:14:40 UTC (rev 18976)
+++ branches/blender2.5/blender/source/blender/blenkernel/BKE_animsys.h	2009-02-15 07:00:13 UTC (rev 18977)
@@ -10,6 +10,7 @@
 struct Main;
 struct AnimData;
 struct KeyingSet;
+struct KS_Path;
 
 /* ************************************* */
 /* AnimData API */
@@ -35,6 +36,8 @@
 /* Add a destination to a KeyingSet */
 void BKE_keyingset_add_destination(struct KeyingSet *ks, struct ID *id, const char group_name[], const char rna_path[], int array_index, short flag, short groupmode);
 
+struct KS_Path *BKE_keyingset_find_destination(struct KeyingSet *ks, struct ID *id, const char group_name[], const char rna_path[], int array_index, int group_mode);
+
 /* Free data for KeyingSet but not set itself */
 void BKE_keyingset_free(struct KeyingSet *ks);
 

Modified: branches/blender2.5/blender/source/blender/blenkernel/intern/anim_sys.c
===================================================================
--- branches/blender2.5/blender/source/blender/blenkernel/intern/anim_sys.c	2009-02-15 02:14:40 UTC (rev 18976)
+++ branches/blender2.5/blender/source/blender/blenkernel/intern/anim_sys.c	2009-02-15 07:00:13 UTC (rev 18977)
@@ -167,6 +167,56 @@
  * from Python/scripts so that riggers can automate the creation of KeyingSets for their rigs.
  */
 
+/* Finding Tools --------------------------- */
+
+/* Find the first path that matches the given criteria */
+// TODO: do we want some method to perform partial matches too?
+KS_Path *BKE_keyingset_find_destination (KeyingSet *ks, ID *id, const char group_name[], const char rna_path[], int array_index, int group_mode)
+{
+	KS_Path *ksp;
+	
+	/* sanity checks */
+	if ELEM(NULL, ks, rna_path)
+		return NULL;
+	
+	/* ID is optional for relative KeyingSets, but is necessary for absolute KeyingSets */
+	if (id == NULL) {
+		if (ks->flag & KEYINGSET_ABSOLUTE)
+			return NULL;
+	}
+	
+	/* loop over paths in the current KeyingSet, finding the first one where all settings match 
+	 * (i.e. the first one where none of the checks fail and equal 0)
+	 */
+	for (ksp= ks->paths.first; ksp; ksp= ksp->next) {
+		short eq_id=1, eq_path=1, eq_index=1, eq_group=1;
+		
+		/* id */
+		if ((ks->flag & KEYINGSET_ABSOLUTE) && (id != ksp->id))
+			eq_id= 0;
+		
+		/* path */
+		if ((ksp->rna_path==0) || strcmp(rna_path, ksp->rna_path))
+			eq_path= 0;
+			
+		/* index */
+		if (ksp->array_index != array_index)
+			eq_index= 0;
+			
+		/* group */
+		if (group_name) {
+			// FIXME: these checks need to be coded... for now, it's not too important though
+		}
+			
+		/* if all aspects are ok, return */
+		if (eq_id && eq_path && eq_index && eq_group)
+			return ksp;
+	}
+	
+	/* none found */
+	return NULL;
+}
+ 
 /* Defining Tools --------------------------- */
 
 /* Used to create a new 'custom' KeyingSet for the user, that will be automatically added to the stack */
@@ -203,12 +253,16 @@
 	if ELEM(NULL, ks, rna_path)
 		return;
 	
-	/* ID is optional, and should only be provided for absolute KeyingSets */
-	if (id) {
-		if ((ks->flag & KEYINGSET_ABSOLUTE) == 0)
+	/* ID is optional for relative KeyingSets, but is necessary for absolute KeyingSets */
+	if (id == NULL) {
+		if (ks->flag & KEYINGSET_ABSOLUTE)
 			return;
 	}
 	
+	/* don't add if there is already a matching KS_Path in the KeyingSet */
+	if (BKE_keyingset_find_destination(ks, id, group_name, rna_path, array_index, groupmode))
+		return;
+	
 	/* allocate a new KeyingSet Path */
 	ksp= MEM_callocN(sizeof(KS_Path), "KeyingSet Path");
 	

Modified: branches/blender2.5/blender/source/blender/editors/space_outliner/outliner.c
===================================================================
--- branches/blender2.5/blender/source/blender/editors/space_outliner/outliner.c	2009-02-15 02:14:40 UTC (rev 18976)
+++ branches/blender2.5/blender/source/blender/editors/space_outliner/outliner.c	2009-02-15 07:00:13 UTC (rev 18977)
@@ -3098,9 +3098,6 @@
 	KEYINGSET_EDITMODE_REMOVE,
 } eKeyingSet_EditModes;
 
-/* typedef'd function-prototype style for KeyingSet operation callbacks */
-typedef void (*ksEditOp)(SpaceOops *soops, KeyingSet *ks, TreeElement *te, TreeStoreElem *tselem);
- 
 /* Utilities ---------------------------------- */
  
 /* specialised poll callback for these operators to work in Datablocks view only */
@@ -3139,8 +3136,12 @@
 	return ks;
 }
 
-/* helper func to add a new KeyingSet Path */
-static void ks_editop_add_cb(SpaceOops *soops, KeyingSet *ks, TreeElement *te, TreeStoreElem *tselem)
+/* Helper func to extract an RNA path from seleted tree element 
+ * NOTE: the caller must zero-out all values of the pointers that it passes here first, as
+ * this function does not do that yet 
+ */
+static void tree_element_to_path(SpaceOops *soops, TreeElement *te, TreeStoreElem *tselem, 
+							ID **id, char **path, int *array_index, short *flag, short *groupmode)
 {
 	ListBase hierarchy = {NULL, NULL};
 	LinkData *ld;
@@ -3148,11 +3149,7 @@
 	TreeStoreElem *tse, *tsenext;
 	PointerRNA *ptr, *nextptr;
 	PropertyRNA *prop, *nameprop;
-	ID *id = NULL;
-	char *path=NULL, *newpath=NULL;
-	int array_index= 0;
-	short flag = 0;
-	short groupmode= KSP_GROUP_KSNAME;
+	char *newpath=NULL;
 	
 	/* optimise tricks:
 	 *	- Don't do anything if the selected item is a 'struct', but arrays are allowed
@@ -3160,8 +3157,6 @@
 	if (tselem->type == TSE_RNA_STRUCT)
 		return;
 	
-	printf("ks_editop_add_cb() \n");
-	
 	/* Overview of Algorithm:
 	 * 	1. Go up the chain of parents until we find the 'root', taking note of the 
 	 *	   levels encountered in reverse-order (i.e. items are added to the start of the list
@@ -3170,7 +3165,6 @@
 	 *	   (which will become the 'ID' for the KeyingSet Path), and build a  
 	 * 		path as we step through the chain
 	 */
-	// XXX do we want to separate this part out to a helper func for the other editing op at some point?
 	 
 	/* step 1: flatten out hierarchy of parents into a flat chain */
 	for (tem= te->parent; tem; tem= tem->parent) {
@@ -3188,16 +3182,7 @@
 		prop= tem->directdata;
 		
 		/* check if we're looking for first ID, or appending to path */
-		if (id) {
-			if(tse->type == TSE_RNA_STRUCT)
-				printf("\t tem = RNA Struct '%s' \n", tem->name);
-			else if(tse->type == TSE_RNA_ARRAY_ELEM)
-				printf("\t tem = RNA Array Elem '%s' \n", tem->name);
-			else if (tse->type == TSE_RNA_PROPERTY)
-				printf("\t tem = RNA Property '%s' \n", tem->name);
-			else
-				printf("\t tem = WTF? \n");
-			
+		if (*id) {
 			/* just 'append' property to path 
 			 *	- to prevent memory leaks, we must write to newpath not path, then free old path + swap them
 			 */
@@ -3205,43 +3190,43 @@
 			if(tse->type == TSE_RNA_PROPERTY) {
 				if(RNA_property_type(ptr, prop) == PROP_POINTER) {
 					/* for pointer we just append property name */
-					newpath= RNA_path_append(path, ptr, prop, 0, NULL);
+					newpath= RNA_path_append(*path, ptr, prop, 0, NULL);
 				}
 				else if(RNA_property_type(ptr, prop) == PROP_COLLECTION) {
 					temnext= (TreeElement*)(ld->next->data);
 					tsenext= TREESTORE(temnext);
-
+					
 					nextptr= &temnext->rnaptr;
 					nameprop= RNA_struct_name_property(nextptr);
-
+					
 					if(nameprop) {
 						/* if possible, use name as a key in the path */
 						char buf[128], *name;
 						name= RNA_property_string_get_alloc(nextptr, nameprop, buf, sizeof(buf));
-
-						newpath= RNA_path_append(path, NULL, prop, 0, name);
-
+						
+						newpath= RNA_path_append(*path, NULL, prop, 0, name);
+						
 						if(name != buf)
 							MEM_freeN(name);
 					}
 					else {
 						/* otherwise use index */
 						int index= 0;
-
+						
 						for(temsub=tem->subtree.first; temsub; temsub=temsub->next, index++)
 							if(temsub == temnext)
 								break;
-
-						newpath= RNA_path_append(path, NULL, prop, index, NULL);
+						
+						newpath= RNA_path_append(*path, NULL, prop, index, NULL);
 					}
-
+					
 					ld= ld->next;
 				}
 			}
 			
 			if(newpath) {
-				if (path) MEM_freeN(path);
-				path= newpath;
+				if (*path) MEM_freeN(*path);
+				*path= newpath;
 				newpath= NULL;
 			}
 		}
@@ -3250,11 +3235,11 @@
 			if (tse->type == TSE_RNA_STRUCT) {
 				/* ptr->data not ptr->id.data seems to be the one we want, since ptr->data is sometimes the owner of this ID? */
 				if(RNA_struct_is_ID(ptr)) {
-					id= (ID *)ptr->data;
-
+					*id= (ID *)ptr->data;
+					
 					/* clear path */
-					if(path) {
-						MEM_freeN(path);
+					if(*path) {
+						MEM_freeN(*path);
 						path= NULL;
 					}
 				}
@@ -3263,42 +3248,33 @@
 	}
 
 	/* step 3: if we've got an ID, add the current item to the path */
-	if (id) {
+	if (*id) {
 		/* add the active property to the path */
-		// if array base, add KSP_FLAG_WHOLE_ARRAY
 		ptr= &te->rnaptr;
 		prop= te->directdata;
 		
 		/* array checks */
 		if (tselem->type == TSE_RNA_ARRAY_ELEM) {
 			/* item is part of an array, so must set the array_index */
-			array_index= te->index;
+			*array_index= te->index;
 		}
 		else if (RNA_property_array_length(ptr, prop)) {
 			/* entire array was selected, so keyframe all */
-			flag |= KSP_FLAG_WHOLE_ARRAY;
+			*flag |= KSP_FLAG_WHOLE_ARRAY;
 		}
 		
 		/* path */
-		newpath= RNA_path_append(path, NULL, prop, 0, NULL);
-		if (path) MEM_freeN(path);
-		path= newpath;
-		
-		printf("Adding KeyingSet '%s': Path %s %d \n", ks->name, path, array_index);
-		
-		/* add a new path with the information obtained (only if valid) */
-		// TODO: what do we do with group name? for now, we don't supply one, and just let this use the KeyingSet name
-		if (path)
-			BKE_keyingset_add_destination(ks, id, NULL, path, array_index, flag, groupmode);
+		newpath= RNA_path_append(*path, NULL, prop, 0, NULL);
+		if (*path) MEM_freeN(*path);
+		*path= newpath;
 	}
 
 	/* free temp data */
-	if (path) MEM_freeN(path);
 	BLI_freelistN(&hierarchy);
 }
 
 /* Recursively iterate over tree, finding and working on selected items */
-static void do_outliner_keyingset_editop(SpaceOops *soops, KeyingSet *ks, ListBase *tree, ksEditOp edit_cb)
+static void do_outliner_keyingset_editop(SpaceOops *soops, KeyingSet *ks, ListBase *tree, short mode)
 {
 	TreeElement *te;
 	TreeStoreElem *tselem;
@@ -3308,12 +3284,54 @@
 		
 		/* if item is selected, perform operation */
 		if (tselem->flag & TSE_SELECTED) {
-			if (edit_cb) edit_cb(soops, ks, te, tselem);

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list