diff options
author | Ton Roosendaal <ton@blender.org> | 2006-11-10 13:17:04 +0300 |
---|---|---|
committer | Ton Roosendaal <ton@blender.org> | 2006-11-10 13:17:04 +0300 |
commit | 9a145481041c51c17d6ec1fba2b10621dc93ecce (patch) | |
tree | e191bcd78569b5e3d7604941f7aaa56ff8b22c54 /source/blender/blenloader | |
parent | a54bd4993fa825df60e43f307c58d47981b37cea (diff) |
Old feature request: undo system now restores images without reloading.
Was surprisingly easy to add, compiant with file reading and undo code.
Currently only the Image->ibuf gets restored, and its opengl binding, so
for realtime texture it works nicely. Also texture images are not freed
inbetween undo steps
Notes:
- Painting textures will just keep the painted image, there's no undo
yet for that
- If this works satisfying, I'll extend it to compositing previews
TEST IT WELL PLEASE! :)
Diffstat (limited to 'source/blender/blenloader')
-rw-r--r-- | source/blender/blenloader/intern/readblenentry.c | 9 | ||||
-rw-r--r-- | source/blender/blenloader/intern/readfile.c | 60 | ||||
-rw-r--r-- | source/blender/blenloader/intern/readfile.h | 5 |
3 files changed, 68 insertions, 6 deletions
diff --git a/source/blender/blenloader/intern/readblenentry.c b/source/blender/blenloader/intern/readblenentry.c index 4e3c674c2f5..17549485025 100644 --- a/source/blender/blenloader/intern/readblenentry.c +++ b/source/blender/blenloader/intern/readblenentry.c @@ -289,6 +289,7 @@ BlendFileData *BLO_read_from_memory(void *mem, int memsize, BlendReadError *erro return bfd; } + BlendFileData *BLO_read_from_memfile(const char *filename, MemFile *memfile, BlendReadError *error_r) { BlendFileData *bfd = NULL; @@ -297,11 +298,19 @@ BlendFileData *BLO_read_from_memfile(const char *filename, MemFile *memfile, Ble fd = blo_openblendermemfile(memfile, error_r); if (fd) { strcpy(fd->filename, filename); + + /* makes lookup of existing images in G.main */ + blo_make_image_pointer_map(fd); + bfd= blo_read_file_internal(fd, error_r); if (bfd) { bfd->type= BLENFILETYPE_BLEND; strcpy(bfd->main->name, ""); } + + /* ensures relinked images are not freed */ + blo_end_image_pointer_map(fd); + blo_freefiledata(fd); } diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 594bfba0e92..969a0c71ebb 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -983,6 +983,8 @@ void blo_freefiledata(FileData *fd) oldnewmap_free(fd->datamap); if (fd->globmap) oldnewmap_free(fd->globmap); + if (fd->imamap) + oldnewmap_free(fd->imamap); if (fd->libmap && !(fd->flags & FD_FLAGS_NOT_MY_LIBMAP)) oldnewmap_free(fd->libmap); @@ -1009,6 +1011,14 @@ static void *newglobadr(FileData *fd, void *adr) /* direct datablocks with glob return oldnewmap_lookup_and_inc(fd->globmap, adr); } +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 *newlibadr(FileData *fd, void *lib, void *adr) /* only lib data */ { return oldnewmap_liblookup(fd->libmap, adr, lib); @@ -1056,6 +1066,42 @@ static void change_idid_adr(ListBase *mainlist, FileData *basefd, void *old, voi } } +/* assumed; G.main still exists */ +void blo_make_image_pointer_map(FileData *fd) +{ + Image *ima= G.main->image.first; + + fd->imamap= oldnewmap_new(); + + for(;ima; ima= ima->id.next) { + if(ima->ibuf) + oldnewmap_insert(fd->imamap, ima->ibuf, ima->ibuf, 0); + } +} + +/* set G.main image ibufs to zero if it has been restored */ +void blo_end_image_pointer_map(FileData *fd) +{ + OldNew *entry= fd->imamap->entries; + Image *ima= G.main->image.first; + int i; + + /* used entries were restored, so we put them to zero */ + for (i=0; i<fd->imamap->nentries; i++, entry++) { + if (entry->nr>0) + entry->newp= NULL; + } + + for(;ima; ima= ima->id.next) { + if(ima->ibuf) { + ima->ibuf= newimaadr(fd, ima->ibuf); + /* this mirrors direct_link_image */ + if(ima->ibuf==NULL) + ima->bindcode= 0; + } + } +} + /* ********** END OLD POINTERS ****************** */ /* ********** READ FILE ****************** */ @@ -1977,12 +2023,16 @@ static void lib_link_image(FileData *fd, Main *main) static void direct_link_image(FileData *fd, Image *ima) { - ima->ibuf= NULL; - ima->anim= NULL; + /* for undo system, pointers could be restored */ + ima->ibuf= newimaadr(fd, ima->ibuf); + /* if restored, we keep the binded opengl index */ + if(ima->ibuf==NULL) + ima->bindcode= 0; + memset(ima->mipmap, 0, sizeof(ima->mipmap)); - ima->repbind= 0; - ima->bindcode= 0; - + ima->anim= NULL; + ima->repbind= NULL; + ima->packedfile = direct_link_packedfile(fd, ima->packedfile); ima->preview = direct_link_preview_image(fd, ima->preview); ima->ok= 1; diff --git a/source/blender/blenloader/intern/readfile.h b/source/blender/blenloader/intern/readfile.h index efdfa9f76bf..a0f42769762 100644 --- a/source/blender/blenloader/intern/readfile.h +++ b/source/blender/blenloader/intern/readfile.h @@ -73,6 +73,7 @@ typedef struct FileData { struct OldNewMap *datamap; struct OldNewMap *globmap; struct OldNewMap *libmap; + struct OldNewMap *imamap; ListBase mainlist; @@ -108,8 +109,10 @@ FileData *blo_openblenderfile( char *name, BlendReadError *error_r); FileData *blo_openblendermemory( void *buffer, int buffersize, BlendReadError *error_r); FileData *blo_openblendermemfile(struct MemFile *memfile, BlendReadError *error_r); -void blo_freefiledata( FileData *fd); +void blo_make_image_pointer_map(FileData *fd); +void blo_end_image_pointer_map(FileData *fd); +void blo_freefiledata( FileData *fd); BHead *blo_firstbhead(FileData *fd); BHead *blo_nextbhead(FileData *fd, BHead *thisblock); |