[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [37936] branches/soc-2011-pepper/source/ blender: Actions can now be made single-user from the Outliner

Joshua Leung aligorith at gmail.com
Wed Jun 29 06:34:23 CEST 2011


Revision: 37936
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=37936
Author:   aligorith
Date:     2011-06-29 04:34:20 +0000 (Wed, 29 Jun 2011)
Log Message:
-----------
Actions can now be made single-user from the Outliner

* Use the same method as from unlinking actions to do this.
* Split off the make single-user code used for the ID-browser into a
function in blenkernel which can be used elsewhere. Getting materials
to also work using this method proved to be a bit too tricky (due to
the whole messy ob vs obdata situation), so I haven't done that.

Modified Paths:
--------------
    branches/soc-2011-pepper/source/blender/blenkernel/BKE_library.h
    branches/soc-2011-pepper/source/blender/blenkernel/intern/action.c
    branches/soc-2011-pepper/source/blender/blenkernel/intern/library.c
    branches/soc-2011-pepper/source/blender/editors/interface/interface_templates.c
    branches/soc-2011-pepper/source/blender/editors/space_outliner/outliner.c

Modified: branches/soc-2011-pepper/source/blender/blenkernel/BKE_library.h
===================================================================
--- branches/soc-2011-pepper/source/blender/blenkernel/BKE_library.h	2011-06-29 03:02:20 UTC (rev 37935)
+++ branches/soc-2011-pepper/source/blender/blenkernel/BKE_library.h	2011-06-29 04:34:20 UTC (rev 37936)
@@ -44,6 +44,8 @@
 struct Library;
 struct wmWindowManager;
 struct bContext;
+struct PointerRNA;
+struct PropertyRNA;
 
 void *alloc_libblock(struct ListBase *lb, short type, const char *name);
 void *copy_libblock(void *rt);
@@ -53,6 +55,7 @@
 void id_us_plus(struct ID *id);
 void id_us_min(struct ID *id);
 int id_make_local(struct ID *id, int test);
+int id_single_user(struct bContext *C, struct ID *id, struct PointerRNA *ptr, struct PropertyRNA *prop);
 int id_copy(struct ID *id, struct ID **newid, int test);
 int id_unlink(struct ID *id, int test);
 

Modified: branches/soc-2011-pepper/source/blender/blenkernel/intern/action.c
===================================================================
--- branches/soc-2011-pepper/source/blender/blenkernel/intern/action.c	2011-06-29 03:02:20 UTC (rev 37935)
+++ branches/soc-2011-pepper/source/blender/blenkernel/intern/action.c	2011-06-29 04:34:20 UTC (rev 37936)
@@ -89,60 +89,80 @@
 	return act;
 }	
 
+/* .................................. */
+
+/* temp data for make_local_action */
+typedef struct tMakeLocalActionContext {
+	bAction *act;    /* original action */
+	bAction *actn;   /* new action */
+	
+	int lib;         /* some action users were libraries */
+	int local;       /* some action users were not libraries */
+} tMakeLocalActionContext;
+
+/* helper function for make_local_action() - local/lib init step */
+static void make_localact_init_cb(ID *id, AnimData *adt, void *mlac_ptr)
+{
+	tMakeLocalActionContext *mlac = (tMakeLocalActionContext *)mlac_ptr;
+	
+	if (adt->action == mlac->act) {
+		if (id->lib) 
+			mlac->lib = 1;
+		else 
+			mlac->local = 1;
+	}
+}
+
+/* helper function for make_local_action() - change references */
+static void make_localact_apply_cb(ID *id, AnimData *adt, void *mlac_ptr)
+{
+	tMakeLocalActionContext *mlac = (tMakeLocalActionContext *)mlac_ptr;
+	
+	if (adt->action == mlac->act) {
+		if (id->lib==0) {
+			adt->action = mlac->actn;
+			
+			id_us_plus(&mlac->actn->id);
+			id_us_min(&mlac->act->id);
+		}
+	}
+}
+
 // does copy_fcurve...
 void make_local_action(bAction *act)
 {
-	// Object *ob;
+	tMakeLocalActionContext mlac = {act, NULL, 0, 0};
 	Main *bmain= G.main;
-	bAction *actn;
-	int local=0, lib=0;
 	
-	if (act->id.lib==NULL) return;
-	if (act->id.us==1) {
+	if (act->id.lib==NULL) 
+		return;
+	
+	// XXX: double-check this; it used to be just single-user check, but that was when fake-users were still default
+	if ((act->id.flag & LIB_FAKEUSER) && (act->id.us<=1)) {
 		act->id.lib= NULL;
 		act->id.flag= LIB_LOCAL;
 		new_id(&bmain->action, (ID *)act, NULL);
 		return;
 	}
 	
-#if 0	// XXX old animation system
-	ob= G.main->object.first;
-	while(ob) {
-		if(ob->action==act) {
-			if(ob->id.lib) lib= 1;
-			else local= 1;
-		}
-		ob= ob->id.next;
-	}
-#endif
+	BKE_animdata_main_cb(bmain, make_localact_init_cb, &mlac);
 	
-	if(local && lib==0) {
+	if (mlac.local && mlac.lib==0) {
 		act->id.lib= NULL;
 		act->id.flag= LIB_LOCAL;
 		//make_local_action_channels(act);
 		new_id(&bmain->action, (ID *)act, NULL);
 	}
-	else if(local && lib) {
-		actn= copy_action(act);
-		actn->id.us= 0;
+	else if (mlac.local && mlac.lib) {
+		mlac.actn= copy_action(act);
+		mlac.actn->id.us= 0;
 		
-#if 0	// XXX old animation system
-		ob= G.main->object.first;
-		while(ob) {
-			if(ob->action==act) {
-				
-				if(ob->id.lib==0) {
-					ob->action = actn;
-					actn->id.us++;
-					act->id.us--;
-				}
-			}
-			ob= ob->id.next;
-		}
-#endif	// XXX old animation system
+		BKE_animdata_main_cb(bmain, make_localact_apply_cb, &mlac);
 	}
 }
 
+/* .................................. */
+
 void free_action (bAction *act)
 {
 	/* sanity check */
@@ -161,6 +181,8 @@
 		BLI_freelistN(&act->markers);
 }
 
+/* .................................. */
+
 bAction *copy_action (bAction *src)
 {
 	bAction *dst = NULL;

Modified: branches/soc-2011-pepper/source/blender/blenkernel/intern/library.c
===================================================================
--- branches/soc-2011-pepper/source/blender/blenkernel/intern/library.c	2011-06-29 03:02:20 UTC (rev 37935)
+++ branches/soc-2011-pepper/source/blender/blenkernel/intern/library.c	2011-06-29 04:34:20 UTC (rev 37936)
@@ -368,6 +368,34 @@
 	return 0;
 }
 
+int id_single_user(bContext *C, ID *id, PointerRNA *ptr, PropertyRNA *prop)
+{
+	ID *newid = NULL;
+	PointerRNA idptr;
+	
+	if (id) {
+		/* if property isn't editable, we're going to have an extra block hanging around until we save */
+		if (RNA_property_editable(ptr, prop)) {
+			if (id_copy(id, &newid, 0) && newid) {
+				/* copy animation actions too */
+				BKE_copy_animdata_id_action(id);
+				/* us is 1 by convention, but RNA_property_pointer_set
+				   will also incremement it, so set it to zero */
+				newid->us= 0;
+				
+				/* assign copy */
+				RNA_id_pointer_create(newid, &idptr);
+				RNA_property_pointer_set(ptr, prop, idptr);
+				RNA_property_update(C, ptr, prop);
+				
+				return 1;
+			}
+		}
+	}
+	
+	return 0;
+}
+
 ListBase *which_libbase(Main *mainlib, short type)
 {
 	switch( type ) {

Modified: branches/soc-2011-pepper/source/blender/editors/interface/interface_templates.c
===================================================================
--- branches/soc-2011-pepper/source/blender/editors/interface/interface_templates.c	2011-06-29 03:02:20 UTC (rev 37935)
+++ branches/soc-2011-pepper/source/blender/editors/interface/interface_templates.c	2011-06-29 04:34:20 UTC (rev 37936)
@@ -234,7 +234,7 @@
 {
 	TemplateID *template= (TemplateID*)arg_litem;
 	PointerRNA idptr= RNA_property_pointer_get(&template->ptr, template->prop);
-	ID *id= idptr.data, *newid;
+	ID *id= idptr.data;
 	int event= GET_INT_FROM_POINTER(arg_event);
 	
 	switch(event) {
@@ -273,21 +273,8 @@
 			}
 			break;
 		case UI_ID_ALONE:
-			if(id) {
-				/* make copy */
-				if(id_copy(id, &newid, 0) && newid) {
-					/* copy animation actions too */
-					BKE_copy_animdata_id_action(id);
-					/* us is 1 by convention, but RNA_property_pointer_set
-					   will also incremement it, so set it to zero */
-					newid->us= 0;
-
-					/* assign copy */
-					RNA_id_pointer_create(newid, &idptr);
-					RNA_property_pointer_set(&template->ptr, template->prop, idptr);
-					RNA_property_update(C, &template->ptr, template->prop);
-				}
-			}
+			if(id) 
+				id_single_user(C, id, &template->ptr, template->prop);
 			break;
 #if 0
 		case UI_ID_AUTO_NAME:

Modified: branches/soc-2011-pepper/source/blender/editors/space_outliner/outliner.c
===================================================================
--- branches/soc-2011-pepper/source/blender/editors/space_outliner/outliner.c	2011-06-29 03:02:20 UTC (rev 37935)
+++ branches/soc-2011-pepper/source/blender/editors/space_outliner/outliner.c	2011-06-29 04:34:20 UTC (rev 37936)
@@ -3340,6 +3340,23 @@
 	}
 }
 
+
+static void singleuser_action_cb(bContext *C, Scene *UNUSED(scene), TreeElement *UNUSED(te), TreeStoreElem *tsep, TreeStoreElem *tselem)
+{
+	ID *id = tselem->id;
+	
+	if (id) {
+		IdAdtTemplate *iat = (IdAdtTemplate *)tsep->id;
+		PointerRNA ptr = {{0}};
+		PropertyRNA *prop;
+		
+		RNA_pointer_create(&iat->id, &RNA_AnimData, iat->adt, &ptr);
+		prop = RNA_struct_find_property(&ptr, "action");
+		
+		id_single_user(C, id, &ptr, prop);
+	}
+}
+
 static void group_linkobs2scene_cb(bContext *UNUSED(C), Scene *scene, TreeElement *UNUSED(te), TreeStoreElem *UNUSED(tsep), TreeStoreElem *tselem)
 {
 	Group *group= (Group *)tselem->id;
@@ -3634,10 +3651,18 @@
 
 /* **************************************** */
 
+typedef enum eOutlinerIdOpTypes {
+	OUTLINER_IDOP_INVALID = 0,
+	OUTLINER_IDOP_UNLINK,
+	OUTLINER_IDOP_LOCAL,
+	OUTLINER_IDOP_SINGLE
+} eOutlinerIdOpTypes;
+
 // TODO: implement support for changing the ID-block used
 static EnumPropertyItem prop_id_op_types[] = {
-	{1, "UNLINK", 0, "Unlink", ""},
-	{2, "LOCAL", 0, "Make Local", ""},
+	{OUTLINER_IDOP_UNLINK, "UNLINK", 0, "Unlink", ""},
+	{OUTLINER_IDOP_LOCAL, "LOCAL", 0, "Make Local", ""},
+	{OUTLINER_IDOP_SINGLE, "SINGLE", 0, "Make Single User", ""},
 	{0, NULL, 0, NULL, NULL}
 };
 
@@ -3646,7 +3671,7 @@
 	Scene *scene= CTX_data_scene(C);
 	SpaceOops *soops= CTX_wm_space_outliner(C);
 	int scenelevel=0, objectlevel=0, idlevel=0, datalevel=0;
-	int event;
+	eOutlinerIdOpTypes event;
 	
 	/* check for invalid states */
 	if (soops == NULL)
@@ -3656,34 +3681,66 @@
 	
 	event= RNA_enum_get(op->ptr, "type");
 	
-	if(event==1) {
-		switch(idlevel) {
-			case ID_AC:
-				outliner_do_libdata_operation(C, scene, soops, &soops->tree, unlink_action_cb);
-				
-				WM_event_add_notifier(C, NC_ANIMATION|ND_NLA_ACTCHANGE, NULL);
-				ED_undo_push(C, "Unlink action");
-				break;
-			case ID_MA:
-				outliner_do_libdata_operation(C, scene, soops, &soops->tree, unlink_material_cb);
-				
-				WM_event_add_notifier(C, NC_OBJECT|ND_OB_SHADING, NULL);
-				ED_undo_push(C, "Unlink material");
-				break;
-			case ID_TE:
-				outliner_do_libdata_operation(C, scene, soops, &soops->tree, unlink_texture_cb);
-				
-				WM_event_add_notifier(C, NC_OBJECT|ND_OB_SHADING, NULL);
-				ED_undo_push(C, "Unlink texture");
-				break;
-			default:
-				BKE_report(op->reports, RPT_WARNING, "Not Yet");
+	switch (event) {
+		case OUTLINER_IDOP_UNLINK:
+		{
+			/* unlink datablock from its parent */
+			switch (idlevel) {
+				case ID_AC:
+					outliner_do_libdata_operation(C, scene, soops, &soops->tree, unlink_action_cb);
+					
+					WM_event_add_notifier(C, NC_ANIMATION|ND_NLA_ACTCHANGE, NULL);
+					ED_undo_push(C, "Unlink action");
+					break;
+				case ID_MA:
+					outliner_do_libdata_operation(C, scene, soops, &soops->tree, unlink_material_cb);
+					
+					WM_event_add_notifier(C, NC_OBJECT|ND_OB_SHADING, NULL);
+					ED_undo_push(C, "Unlink material");
+					break;
+				case ID_TE:
+					outliner_do_libdata_operation(C, scene, soops, &soops->tree, unlink_texture_cb);
+					
+					WM_event_add_notifier(C, NC_OBJECT|ND_OB_SHADING, NULL);
+					ED_undo_push(C, "Unlink texture");
+					break;
+				default:
+					BKE_report(op->reports, RPT_WARNING, "Not Yet");
+					break;
+			}
 		}
+			break;
+			
+		case OUTLINER_IDOP_LOCAL:
+		{
+			/* make local */

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list