[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [53344] trunk/blender/source/blender: New features!

Ton Roosendaal ton at blender.org
Thu Dec 27 16:07:20 CET 2012


Revision: 53344
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=53344
Author:   ton
Date:     2012-12-27 15:07:19 +0000 (Thu, 27 Dec 2012)
Log Message:
-----------
New features!

- Packing .blend files

If you work a lot with dynamic linked .blend files ("Libraries"), it's always hard to
share your work with others (or for bug reports!).
This new option packs all used external .blend files, and - on save - combines it together
in one .blend file. You can save that file on any location.

Loading a packed .blend file then loads all library data usual - not editable.

Just use unpack to save out all linked .blend files. This will only save out the files
according the directory structure as was used on linking - relative to the current .blend.
It will create new directories, so be careful with unpacking when relative paths go up.

This feature also works fine for linked compressed .blend files.

It also works for many levels deep linked .blend hierarchies.

Access is hidden for now - I need to get some people to give it serious testing first.
You can find the options via spacebar search (try pack or unpack).

- Packed data and Undo

Now all packed data is excluded from the Undo buffer storage. Keeps undo memory smaller
and makes faster redo possible.

Modified Paths:
--------------
    trunk/blender/source/blender/blenkernel/BKE_packedFile.h
    trunk/blender/source/blender/blenkernel/intern/bpath.c
    trunk/blender/source/blender/blenkernel/intern/packedFile.c
    trunk/blender/source/blender/blenloader/intern/readblenentry.c
    trunk/blender/source/blender/blenloader/intern/readfile.c
    trunk/blender/source/blender/blenloader/intern/readfile.h
    trunk/blender/source/blender/blenloader/intern/writefile.c
    trunk/blender/source/blender/editors/space_info/info_intern.h
    trunk/blender/source/blender/editors/space_info/info_ops.c
    trunk/blender/source/blender/editors/space_info/space_info.c
    trunk/blender/source/blender/makesdna/DNA_ID.h

Modified: trunk/blender/source/blender/blenkernel/BKE_packedFile.h
===================================================================
--- trunk/blender/source/blender/blenkernel/BKE_packedFile.h	2012-12-27 12:40:02 UTC (rev 53343)
+++ trunk/blender/source/blender/blenkernel/BKE_packedFile.h	2012-12-27 15:07:19 UTC (rev 53344)
@@ -48,6 +48,7 @@
 struct PackedFile *newPackedFileMemory(void *mem, int memlen);
 
 void packAll(struct Main *bmain, struct ReportList *reports);
+void packLibraries(struct Main *bmain, struct ReportList *reports);
 
 /* unpack */
 char *unpackFile(struct ReportList *reports, const char *abs_name, const char *local_name, struct PackedFile *pf, int how);
@@ -55,6 +56,7 @@
 int unpackSound(struct Main *bmain, struct ReportList *reports, struct bSound *sound, int how);
 int unpackImage(struct ReportList *reports, struct Image *ima, int how);
 void unpackAll(struct Main *bmain, struct ReportList *reports, int how);
+int unpackLibraries(struct Main *bmain, struct ReportList *reports);
 
 int writePackedFile(struct ReportList *reports, const char *filename, struct PackedFile *pf, int guimode);
 

Modified: trunk/blender/source/blender/blenkernel/intern/bpath.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/bpath.c	2012-12-27 12:40:02 UTC (rev 53343)
+++ trunk/blender/source/blender/blenkernel/intern/bpath.c	2012-12-27 15:07:19 UTC (rev 53344)
@@ -588,8 +588,11 @@
 		case ID_LI:
 		{
 			Library *lib = (Library *)id;
-			if (rewrite_path_fixed(lib->name, visit_cb, absbase, bpath_user_data)) {
-				BKE_library_filepath_set(lib, lib->name);
+			/* keep packedfile paths always relative to the blend */
+			if (lib->packedfile == NULL) {
+				if (rewrite_path_fixed(lib->name, visit_cb, absbase, bpath_user_data)) {
+					BKE_library_filepath_set(lib, lib->name);
+				}
 			}
 			break;
 		}

Modified: trunk/blender/source/blender/blenkernel/intern/packedFile.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/packedFile.c	2012-12-27 12:40:02 UTC (rev 53343)
+++ trunk/blender/source/blender/blenkernel/intern/packedFile.c	2012-12-27 15:07:19 UTC (rev 53344)
@@ -43,6 +43,7 @@
 #include "MEM_guardedalloc.h"
 
 #include "DNA_image_types.h"
+#include "DNA_ID.h"
 #include "DNA_sound_types.h"
 #include "DNA_vfont_types.h"
 #include "DNA_packedFile_types.h"
@@ -226,6 +227,7 @@
 	return (pf);
 }
 
+/* no libraries for now */
 void packAll(Main *bmain, ReportList *reports)
 {
 	Image *ima;
@@ -538,6 +540,41 @@
 	return(ret_value);
 }
 
+int unpackLibraries(Main *bmain, ReportList *reports)
+{
+	Library *lib;
+	char *newname;
+	int ret_value = RET_ERROR;
+	
+	for (lib = bmain->library.first; lib; lib = lib->id.next) {
+		if (lib->packedfile && lib->name[0]) {
+			
+			newname = unpackFile(reports, lib->filepath, lib->filepath, lib->packedfile, PF_WRITE_ORIGINAL);
+			if (newname != NULL) {
+				ret_value = RET_OK;
+				
+				printf("Saved .blend library: %s\n", newname);
+				
+				freePackedFile(lib->packedfile);
+				lib->packedfile = NULL;
+
+				MEM_freeN(newname);
+			}
+		}
+	}
+	
+	return(ret_value);
+}
+
+void packLibraries(Main *bmain, ReportList *reports)
+{
+	Library *lib;
+	
+	for (lib = bmain->library.first; lib; lib = lib->id.next)
+		if (lib->packedfile == NULL)
+			lib->packedfile = newPackedFile(reports, lib->name, bmain->name);
+}
+
 void unpackAll(Main *bmain, ReportList *reports, int how)
 {
 	Image *ima;

Modified: trunk/blender/source/blender/blenloader/intern/readblenentry.c
===================================================================
--- trunk/blender/source/blender/blenloader/intern/readblenentry.c	2012-12-27 12:40:02 UTC (rev 53343)
+++ trunk/blender/source/blender/blenloader/intern/readblenentry.c	2012-12-27 15:07:19 UTC (rev 53344)
@@ -311,6 +311,9 @@
 		/* makes lookup of existing video clips in old main */
 		blo_make_movieclip_pointer_map(fd, oldmain);
 		
+		/* makes lookup of existing video clips in old main */
+		blo_make_packed_pointer_map(fd, oldmain);
+		
 		bfd = blo_read_file_internal(fd, filename);
 		
 		/* ensures relinked images are not freed */
@@ -319,6 +322,9 @@
 		/* ensures relinked movie clips are not freed */
 		blo_end_movieclip_pointer_map(fd, oldmain);
 		
+		/* ensures relinked packed data is not freed */
+		blo_end_packed_pointer_map(fd, oldmain);
+		
 		/* move libraries from old main to new main */
 		if (bfd && mainlist.first != mainlist.last) {
 			

Modified: trunk/blender/source/blender/blenloader/intern/readfile.c
===================================================================
--- trunk/blender/source/blender/blenloader/intern/readfile.c	2012-12-27 12:40:02 UTC (rev 53343)
+++ trunk/blender/source/blender/blenloader/intern/readfile.c	2012-12-27 15:07:19 UTC (rev 53344)
@@ -543,7 +543,9 @@
 	
 	BLI_strncpy(name1, filepath, sizeof(name1));
 	cleanup_path(relabase, name1);
-//	printf("blo_find_main: original in  %s\n", name);
+	
+//	printf("blo_find_main: relabase  %s\n", relabase);
+//	printf("blo_find_main: original in  %s\n", filepath);
 //	printf("blo_find_main: converted to %s\n", name1);
 	
 	for (m = mainlist->first; m; m = m->next) {
@@ -1020,6 +1022,46 @@
 	}
 }
 
+static int fd_read_gzip_from_memory(FileData *filedata, void *buffer, unsigned int size)
+{
+	int err;
+	
+	filedata->strm.next_out = (Bytef *) buffer;
+    filedata->strm.avail_out = size;
+	
+    // Inflate another chunk.
+    err = inflate (&filedata->strm, Z_SYNC_FLUSH);
+	
+    if (err == Z_STREAM_END) {
+		return 0;
+	}
+    else if (err != Z_OK)  {
+		printf("fd_read_gzip_from_memory: zlib error\n");
+		return 0;
+    }
+	
+	filedata->seek += size;
+	
+	return (size);
+}
+
+static int fd_read_gzip_from_memory_init(FileData *fd)
+{
+
+	fd->strm.next_in = (Bytef *) fd->buffer;
+	fd->strm.avail_in = fd->buffersize;
+	fd->strm.total_out = 0;
+	fd->strm.zalloc = Z_NULL;
+	fd->strm.zfree = Z_NULL;
+	
+	if (inflateInit2(&fd->strm, (16+MAX_WBITS)) != Z_OK)
+		return 0;
+
+	fd->read = fd_read_gzip_from_memory;
+	
+	return 1;
+}
+
 FileData *blo_openblendermemory(void *mem, int memsize, ReportList *reports)
 {
 	if (!mem || memsize<SIZEOFBLENDERHEADER) {
@@ -1028,11 +1070,23 @@
 	}
 	else {
 		FileData *fd = filedata_new();
+		char *cp = mem;
+		
 		fd->buffer = mem;
 		fd->buffersize = memsize;
-		fd->read = fd_read_from_memory;
+		
+		/* test if gzip */
+		if (cp[0] == 0x1f && cp[1] == 0x8b) {
+			if (0 == fd_read_gzip_from_memory_init(fd)) {
+				blo_freefiledata(fd);
+				return NULL;
+			}
+		}
+		else
+			fd->read = fd_read_from_memory;
+			
 		fd->flags |= FD_FLAGS_NOT_MY_BUFFER;
-		
+
 		return blo_decode_and_check(fd, reports);
 	}
 }
@@ -1066,6 +1120,12 @@
 			gzclose(fd->gzfiledes);
 		}
 		
+		if (fd->strm.next_in) {
+			if (inflateEnd (&fd->strm) != Z_OK) {
+				printf("close gzip stream error\n");
+			}
+		}
+		
 		if (fd->buffer && !(fd->flags & FD_FLAGS_NOT_MY_BUFFER)) {
 			MEM_freeN(fd->buffer);
 			fd->buffer = NULL;
@@ -1154,26 +1214,34 @@
 	return oldnewmap_lookup_and_inc(fd->datamap, adr);
 }
 
-static void *newglobadr(FileData *fd, void *adr)		/* direct datablocks with global linking */
+static void *newglobadr(FileData *fd, void *adr)	    /* direct datablocks with global linking */
 {
 	return oldnewmap_lookup_and_inc(fd->globmap, adr);
 }
 
-static void *newimaadr(FileData *fd, void *adr)		/* used to restore image data after undo */
+static void *newimaadr(FileData *fd, void *adr)		    /* used to restore image data after undo */
 {
 	if (fd->imamap && adr)
 		return oldnewmap_lookup_and_inc(fd->imamap, adr);
 	return NULL;
 }
 
-static void *newmclipadr(FileData *fd, void *adr)              /* used to restore movie clip data after undo */
+static void *newmclipadr(FileData *fd, void *adr)      /* used to restore movie clip data after undo */
 {
 	if (fd->movieclipmap && adr)
 		return oldnewmap_lookup_and_inc(fd->movieclipmap, adr);
 	return NULL;
 }
 
+static void *newpackedadr(FileData *fd, void *adr)      /* used to restore packed data after undo */
+{
+	if (fd->packedmap && adr)
+		return oldnewmap_lookup_and_inc(fd->packedmap, adr);
+	
+	return oldnewmap_lookup_and_inc(fd->datamap, adr);
+}
 
+
 static void *newlibadr(FileData *fd, void *lib, void *adr)		/* only lib data */
 {
 	return oldnewmap_liblookup(fd->libmap, adr, lib);
@@ -1369,7 +1437,70 @@
 	}
 }
 
+static void insert_packedmap(FileData *fd, PackedFile *pf)
+{
+	oldnewmap_insert(fd->packedmap, pf, pf, 0);
+	oldnewmap_insert(fd->packedmap, pf->data, pf->data, 0);
+}
 
+void blo_make_packed_pointer_map(FileData *fd, Main *oldmain)
+{
+	Image *ima;
+	VFont *vfont;
+	bSound *sound;
+	Library *lib;
+	
+	fd->packedmap = oldnewmap_new();
+	
+	for (ima = oldmain->image.first; ima; ima = ima->id.next)
+		if (ima->packedfile)
+			insert_packedmap(fd, ima->packedfile);
+			
+	for (vfont = oldmain->vfont.first; vfont; vfont = vfont->id.next)
+		if (vfont->packedfile)
+			insert_packedmap(fd, vfont->packedfile);
+	
+	for (sound = oldmain->sound.first; sound; sound = sound->id.next)
+		if (sound->packedfile)
+			insert_packedmap(fd, sound->packedfile);
+	
+	for (lib = oldmain->library.first; lib; lib = lib->id.next)
+		if (lib->packedfile)
+			insert_packedmap(fd, lib->packedfile);
+
+}
+
+/* set old main packed data to zero if it has been restored */
+/* this works because freeing old main only happens after this call */
+void blo_end_packed_pointer_map(FileData *fd, Main *oldmain)
+{
+	Image *ima;
+	VFont *vfont;
+	bSound *sound;
+	Library *lib;
+	OldNew *entry = fd->packedmap->entries;
+	int i;
+	
+	/* used entries were restored, so we put them to zero */
+	for (i=0; i < fd->packedmap->nentries; i++, entry++) {
+		if (entry->nr > 0)
+			entry->newp = NULL;
+	}
+	
+	for (ima = oldmain->image.first; ima; ima = ima->id.next)
+		ima->packedfile = newpackedadr(fd, ima->packedfile);
+	
+	for (vfont = oldmain->vfont.first; vfont; vfont = vfont->id.next)
+		vfont->packedfile = newpackedadr(fd, vfont->packedfile);
+
+	for (sound = oldmain->sound.first; sound; sound = sound->id.next)
+		sound->packedfile = newpackedadr(fd, sound->packedfile);
+		
+	for (lib = oldmain->library.first; lib; lib = lib->id.next)
+		lib->packedfile = newpackedadr(fd, lib->packedfile);
+}
+
+
 /* undo file support: add all library pointers in lookup */
 void blo_add_library_pointer_map(ListBase *mainlist, FileData *fd)
 {
@@ -1708,10 +1839,10 @@
 
 static PackedFile *direct_link_packedfile(FileData *fd, PackedFile *oldpf)
 {

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list