[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [41292] trunk/blender/source/blender: Fix [#28772] Filepaths are not remmaped after making a library item local

Alex Fraser alex at phatcore.com
Wed Oct 26 12:49:22 CEST 2011


Revision: 41292
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=41292
Author:   z0r
Date:     2011-10-26 10:49:21 +0000 (Wed, 26 Oct 2011)
Log Message:
-----------
Fix [#28772] Filepaths are not remmaped after making a library item local
Added a visitor function to simplify processing of file paths that are attached to IDs. This is used for images, and could be used for other ID types in future.
Code reviewed by ideasman_42.

Modified Paths:
--------------
    trunk/blender/source/blender/blenkernel/BKE_image.h
    trunk/blender/source/blender/blenkernel/BKE_library.h
    trunk/blender/source/blender/blenkernel/intern/action.c
    trunk/blender/source/blender/blenkernel/intern/armature.c
    trunk/blender/source/blender/blenkernel/intern/brush.c
    trunk/blender/source/blender/blenkernel/intern/curve.c
    trunk/blender/source/blender/blenkernel/intern/image.c
    trunk/blender/source/blender/blenkernel/intern/lattice.c
    trunk/blender/source/blender/blenkernel/intern/library.c
    trunk/blender/source/blender/blenkernel/intern/material.c
    trunk/blender/source/blender/blenkernel/intern/mball.c
    trunk/blender/source/blender/blenkernel/intern/mesh.c
    trunk/blender/source/blender/blenkernel/intern/node.c
    trunk/blender/source/blender/blenkernel/intern/object.c
    trunk/blender/source/blender/blenkernel/intern/particle.c
    trunk/blender/source/blender/blenkernel/intern/speaker.c
    trunk/blender/source/blender/blenkernel/intern/texture.c
    trunk/blender/source/blender/blenkernel/intern/world.c
    trunk/blender/source/blender/blenlib/BLI_bpath.h
    trunk/blender/source/blender/blenlib/intern/bpath.c
    trunk/blender/source/blender/blenloader/intern/readfile.c
    trunk/blender/source/blender/editors/space_outliner/outliner_tools.c

Modified: trunk/blender/source/blender/blenkernel/BKE_image.h
===================================================================
--- trunk/blender/source/blender/blenkernel/BKE_image.h	2011-10-26 10:04:10 UTC (rev 41291)
+++ trunk/blender/source/blender/blenkernel/BKE_image.h	2011-10-26 10:49:21 UTC (rev 41292)
@@ -61,7 +61,9 @@
 struct anim *openanim(char * name, int flags, int streamindex);
 
 void	image_de_interlace(struct Image *ima, int odd);
-	
+
+void	make_local_image(struct Image *ima);
+
 void	tag_image_time(struct Image *ima);
 void	free_old_images(void);
 

Modified: trunk/blender/source/blender/blenkernel/BKE_library.h
===================================================================
--- trunk/blender/source/blender/blenkernel/BKE_library.h	2011-10-26 10:04:10 UTC (rev 41291)
+++ trunk/blender/source/blender/blenkernel/BKE_library.h	2011-10-26 10:49:21 UTC (rev 41292)
@@ -59,6 +59,7 @@
 int id_unlink(struct ID *id, int test);
 
 int new_id(struct ListBase *lb, struct ID *id, const char *name);
+void id_clear_lib_data(struct ListBase *lb, struct ID *id);
 
 struct ListBase *which_libbase(struct Main *mainlib, short type);
 

Modified: trunk/blender/source/blender/blenkernel/intern/action.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/action.c	2011-10-26 10:04:10 UTC (rev 41291)
+++ trunk/blender/source/blender/blenkernel/intern/action.c	2011-10-26 10:49:21 UTC (rev 41292)
@@ -137,19 +137,14 @@
 	
 	// 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);
+		id_clear_lib_data(&bmain->action, (ID *)act);
 		return;
 	}
 	
 	BKE_animdata_main_cb(bmain, make_localact_init_cb, &mlac);
 	
 	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);
+		id_clear_lib_data(&bmain->action, (ID *)act);
 	}
 	else if (mlac.local && mlac.lib) {
 		mlac.actn= copy_action(act);

Modified: trunk/blender/source/blender/blenkernel/intern/armature.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/armature.c	2011-10-26 10:04:10 UTC (rev 41291)
+++ trunk/blender/source/blender/blenkernel/intern/armature.c	2011-10-26 10:49:21 UTC (rev 41292)
@@ -141,9 +141,7 @@
 
 	if (arm->id.lib==NULL) return;
 	if (arm->id.us==1) {
-		arm->id.lib= NULL;
-		arm->id.flag= LIB_LOCAL;
-		new_id(&bmain->armature, (ID*)arm, NULL);
+		id_clear_lib_data(&bmain->armature, (ID *)arm);
 		return;
 	}
 
@@ -155,9 +153,7 @@
 	}
 
 	if(local && lib==0) {
-		arm->id.lib= NULL;
-		arm->id.flag= LIB_LOCAL;
-		new_id(&bmain->armature, (ID *)arm, NULL);
+		id_clear_lib_data(&bmain->armature, (ID *)arm);
 	}
 	else if(local && lib) {
 		bArmature *armn= copy_armature(arm);

Modified: trunk/blender/source/blender/blenkernel/intern/brush.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/brush.c	2011-10-26 10:04:10 UTC (rev 41291)
+++ trunk/blender/source/blender/blenkernel/intern/brush.c	2011-10-26 10:49:21 UTC (rev 41292)
@@ -181,6 +181,7 @@
 static void extern_local_brush(Brush *brush)
 {
 	id_lib_extern((ID *)brush->mtex.tex);
+	id_lib_extern((ID *)brush->clone.image);
 }
 
 void make_local_brush(Brush *brush)
@@ -198,10 +199,9 @@
 	if(brush->id.lib==NULL) return;
 
 	if(brush->clone.image) {
-		/* special case: ima always local immediately */
-		brush->clone.image->id.lib= NULL;
-		brush->clone.image->id.flag= LIB_LOCAL;
-		new_id(&bmain->brush, (ID *)brush->clone.image, NULL);
+		/* special case: ima always local immediately. Clone image should only
+		   have one user anyway. */
+		id_clear_lib_data(&bmain->brush, (ID *)brush->clone.image);
 		extern_local_brush(brush);
 	}
 
@@ -213,9 +213,7 @@
 	}
 
 	if(local && lib==0) {
-		brush->id.lib= NULL;
-		brush->id.flag= LIB_LOCAL;
-		new_id(&bmain->brush, (ID *)brush, NULL);
+		id_clear_lib_data(&bmain->brush, (ID *)brush);
 		extern_local_brush(brush);
 
 		/* enable fake user by default */

Modified: trunk/blender/source/blender/blenkernel/intern/curve.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/curve.c	2011-10-26 10:04:10 UTC (rev 41291)
+++ trunk/blender/source/blender/blenkernel/intern/curve.c	2011-10-26 10:49:21 UTC (rev 41292)
@@ -255,10 +255,7 @@
 	if(cu->id.lib==NULL) return;
 
 	if(cu->id.us==1) {
-		cu->id.lib= NULL;
-		cu->id.flag= LIB_LOCAL;
-
-		new_id(&bmain->curve, (ID *)cu, NULL);
+		id_clear_lib_data(&bmain->curve, (ID *)cu);
 		extern_local_curve(cu);
 		return;
 	}
@@ -271,10 +268,7 @@
 	}
 
 	if(local && lib==0) {
-		cu->id.lib= NULL;
-		cu->id.flag= LIB_LOCAL;
-
-		new_id(&bmain->curve, (ID *)cu, NULL);
+		id_clear_lib_data(&bmain->curve, (ID *)cu);
 		extern_local_curve(cu);
 	}
 	else if(local && lib) {

Modified: trunk/blender/source/blender/blenkernel/intern/image.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/image.c	2011-10-26 10:04:10 UTC (rev 41291)
+++ trunk/blender/source/blender/blenkernel/intern/image.c	2011-10-26 10:49:21 UTC (rev 41292)
@@ -60,10 +60,14 @@
 #include "DNA_camera_types.h"
 #include "DNA_sequence_types.h"
 #include "DNA_userdef_types.h"
+#include "DNA_brush_types.h"
+#include "DNA_mesh_types.h"
+#include "DNA_meshdata_types.h"
 
 #include "BLI_blenlib.h"
 #include "BLI_threads.h"
 #include "BLI_utildefines.h"
+#include "BLI_bpath.h"
 
 #include "BKE_bmfont.h"
 #include "BKE_global.h"
@@ -313,6 +317,132 @@
 	return nima;
 }
 
+static void extern_local_image(Image *UNUSED(ima))
+{
+	/* Nothing to do: images don't link to other IDs. This function exists to
+	   match id_make_local pattern. */
+}
+
+void make_local_image(struct Image *ima) {
+	Main *bmain= G.main;
+	Tex *tex;
+	Brush *brush;
+	Mesh *me;
+	int local=0, lib=0;
+
+	/* - only lib users: do nothing
+	 * - only local users: set flag
+	 * - mixed: make copy
+	 */
+
+	if(ima->id.lib==NULL) return;
+
+	/* Can't take short cut here: must check meshes at least because of bogus
+	   texface ID refs. - z0r */
+#if(0)
+	if(ima->id.us==1) {
+		id_clear_lib_data(&bmain->image, (ID *)ima);
+		extern_local_image(ima);
+		return;
+	}
+#endif
+
+	for(tex= bmain->tex.first; tex; tex= tex->id.next) {
+		if(tex->ima == ima) {
+			if(tex->id.lib) lib= 1;
+			else local= 1;
+		}
+	}
+	for(brush= bmain->brush.first; brush; brush= brush->id.next) {
+		if(brush->clone.image == ima) {
+			if(brush->id.lib) lib= 1;
+			else local= 1;
+		}
+	}
+	for(me= bmain->mesh.first; me; me= me->id.next) {
+		if(me->mtface) {
+			MTFace *tface;
+			int a, i;
+
+			for(i=0; i<me->fdata.totlayer; i++) {
+				if(me->fdata.layers[i].type == CD_MTFACE) {
+					tface= (MTFace*)me->fdata.layers[i].data;
+
+					for(a=0; a<me->totface; a++, tface++) {
+						if(tface->tpage == ima) {
+							if(me->id.lib) lib=1;
+							else local= 1;
+						}
+					}
+				}
+			}
+		}
+	}
+
+	if(local && lib==0) {
+		id_clear_lib_data(&bmain->image, (ID *)ima);
+		extern_local_image(ima);
+	}
+	else if(local && lib) {
+		Image *iman= copy_image(ima);
+		iman->id.us= 0;
+
+		/* Remap paths of new ID using old library as base. */
+		bpath_traverse_id((ID *)iman, bpath_relocate_visitor,
+		                     ((ID *)ima)->lib->filepath);
+
+		tex= bmain->tex.first;
+		while(tex) {
+			if(tex->id.lib==NULL) {
+				if(tex->ima==ima) {
+					tex->ima = iman;
+					iman->id.us++;
+					ima->id.us--;
+				}
+			}
+			tex= tex->id.next;
+		}
+		brush= bmain->brush.first;
+		while(brush) {
+			if(brush->id.lib==NULL) {
+				if(brush->clone.image==ima) {
+					brush->clone.image = iman;
+					iman->id.us++;
+					ima->id.us--;
+				}
+			}
+			brush= brush->id.next;
+		}
+		/* Transfer references in texfaces. Texfaces don't add to image ID
+		   user count *unless* there are no other users. See
+		   readfile.c:lib_link_mtface. */
+		me= bmain->mesh.first;
+		while(me) {
+			if(me->mtface) {
+				MTFace *tface;
+				int a, i;
+
+				for(i=0; i<me->fdata.totlayer; i++) {
+					if(me->fdata.layers[i].type == CD_MTFACE) {
+						tface= (MTFace*)me->fdata.layers[i].data;
+
+						for(a=0; a<me->totface; a++, tface++) {	
+							if(tface->tpage == ima) {
+								tface->tpage = iman;
+								if(iman->id.us == 0) {
+									tface->tpage->id.us= 1;
+								}
+								id_lib_extern((ID*)iman);
+							}
+						}
+					}
+				}
+			}
+			me= me->id.next;
+		}
+	}
+}
+
 void BKE_image_merge(Image *dest, Image *source)
 {
 	ImBuf *ibuf;

Modified: trunk/blender/source/blender/blenkernel/intern/lattice.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/lattice.c	2011-10-26 10:04:10 UTC (rev 41291)
+++ trunk/blender/source/blender/blenkernel/intern/lattice.c	2011-10-26 10:49:21 UTC (rev 41292)
@@ -255,9 +255,7 @@
 	
 	if(lt->id.lib==NULL) return;
 	if(lt->id.us==1) {
-		lt->id.lib= NULL;
-		lt->id.flag= LIB_LOCAL;
-		new_id(&bmain->latt, (ID *)lt, NULL);
+		id_clear_lib_data(&bmain->latt, (ID *)lt);
 		return;
 	}
 	
@@ -269,9 +267,7 @@
 	}
 	
 	if(local && lib==0) {
-		lt->id.lib= NULL;
-		lt->id.flag= LIB_LOCAL;
-		new_id(&bmain->latt, (ID *)lt, NULL);
+		id_clear_lib_data(&bmain->latt, (ID *)lt);
 	}
 	else if(local && lib) {
 		Lattice *ltn= copy_lattice(lt);

Modified: trunk/blender/source/blender/blenkernel/intern/library.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/library.c	2011-10-26 10:04:10 UTC (rev 41291)
+++ trunk/blender/source/blender/blenkernel/intern/library.c	2011-10-26 10:49:21 UTC (rev 41292)
@@ -74,8 +74,8 @@
 #include "BLI_blenlib.h"
 #include "BLI_dynstr.h"
 #include "BLI_utildefines.h"
+#include "BLI_bpath.h"
 
-
 #include "BKE_animsys.h"
 #include "BKE_context.h"
 #include "BKE_library.h"
@@ -108,6 +108,7 @@
 #include "BKE_gpencil.h"
 #include "BKE_fcurve.h"
 #include "BKE_speaker.h"
+#include "BKE_utildefines.h"
 
 #include "RNA_access.h"
 
@@ -194,7 +195,8 @@
 			if(!test) make_local_texture((Tex*)id);
 			return 1;
 		case ID_IM:
-			return 0; /* not implemented */
+			if(!test) make_local_image((Image*)id);
+			return 1;
 		case ID_LT:
 			if(!test) {
 				make_local_lattice((Lattice*)id);
@@ -1246,6 +1248,16 @@

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list