diff --git a/source/blender/blenkernel/intern/group.c b/source/blender/blenkernel/intern/group.c index ae3ab833a87..ae99ff1bbf3 100644 --- a/source/blender/blenkernel/intern/group.c +++ b/source/blender/blenkernel/intern/group.c @@ -49,6 +49,7 @@ #include "BKE_depsgraph.h" #include "BKE_global.h" #include "BKE_group.h" +#include "BKE_icons.h" #include "BKE_library.h" #include "BKE_main.h" #include "BKE_object.h" @@ -64,7 +65,9 @@ void BKE_group_free(Group *group) { /* don't free group itself */ GroupObject *go; - + + BKE_previewimg_free(&group->preview); + while ((go = BLI_pophead(&group->gobject))) { free_group_object(go); } @@ -139,6 +142,9 @@ Group *BKE_group_add(Main *bmain, const char *name) group = BKE_libblock_alloc(bmain, ID_GR, name); group->layer = (1 << 20) - 1; + + group->preview = NULL; + return group; } @@ -149,6 +155,8 @@ Group *BKE_group_copy(Group *group) groupn = BKE_libblock_copy(&group->id); BLI_duplicatelist(&groupn->gobject, &group->gobject); + /* Do not copy group's preview (same behavior as for objects). */ + if (group->id.lib) { BKE_id_lib_local_paths(G.main, group->id.lib, &groupn->id); } diff --git a/source/blender/blenkernel/intern/icons.c b/source/blender/blenkernel/intern/icons.c index 7696249f2de..2171f193bac 100644 --- a/source/blender/blenkernel/intern/icons.c +++ b/source/blender/blenkernel/intern/icons.c @@ -37,8 +37,11 @@ #include "MEM_guardedalloc.h" +#include "DNA_group_types.h" #include "DNA_lamp_types.h" #include "DNA_material_types.h" +#include "DNA_object_types.h" +#include "DNA_scene_types.h" #include "DNA_texture_types.h" #include "DNA_world_types.h" #include "DNA_brush_types.h" @@ -228,6 +231,9 @@ PreviewImage **BKE_previewimg_id_get_p(ID *id) ID_PRV_CASE(ID_LA, Lamp); ID_PRV_CASE(ID_IM, Image); ID_PRV_CASE(ID_BR, Brush); + ID_PRV_CASE(ID_OB, Object); + ID_PRV_CASE(ID_GR, Group); + ID_PRV_CASE(ID_SCE, Scene); #undef ID_PRV_CASE } diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index 647aadf237c..65599896f02 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -87,6 +87,7 @@ #include "BKE_effect.h" #include "BKE_fcurve.h" #include "BKE_group.h" +#include "BKE_icons.h" #include "BKE_key.h" #include "BKE_lamp.h" #include "BKE_lattice.h" @@ -457,6 +458,8 @@ void BKE_object_free_ex(Object *ob, bool do_id_user) free_path(ob->curve_cache->path); MEM_freeN(ob->curve_cache); } + + BKE_previewimg_free(&ob->preview); } void BKE_object_free(Object *ob) @@ -1040,6 +1043,7 @@ Object *BKE_object_add_only_object(Main *bmain, int type, const char *name) ob->fall_speed = 55.0f; ob->col_group = 0x01; ob->col_mask = 0xffff; + ob->preview = NULL; /* NT fluid sim defaults */ ob->fluidsimSettings = NULL; @@ -1557,6 +1561,8 @@ Object *BKE_object_copy_ex(Main *bmain, Object *ob, bool copy_caches) BKE_id_lib_local_paths(bmain, ob->id.lib, &obn->id); } + /* Do not copy object's preview (mostly due to the fact renderers create temp copy of objects). */ + return obn; } @@ -1593,6 +1599,8 @@ static void extern_local_object(Object *ob) id_lib_extern((ID *)psys->part); modifiers_foreachIDLink(ob, extern_local_object__modifiersForeachIDLink, NULL); + + ob->preview = NULL; } void BKE_object_make_local(Object *ob) diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index b518ae4b4a9..14cb5859918 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -72,6 +72,7 @@ #include "BKE_global.h" #include "BKE_gpencil.h" #include "BKE_group.h" +#include "BKE_icons.h" #include "BKE_idprop.h" #include "BKE_image.h" #include "BKE_library.h" @@ -346,6 +347,10 @@ Scene *BKE_scene_copy(Scene *sce, int type) } } + if (sce->preview) { + scen->preview = BKE_previewimg_copy(sce->preview); + } + return scen; } @@ -455,6 +460,8 @@ void BKE_scene_free(Scene *sce) BKE_sound_destroy_scene(sce); BKE_color_managed_view_settings_free(&sce->view_settings); + + BKE_previewimg_free(&sce->preview); } Scene *BKE_scene_add(Main *bmain, const char *name) @@ -735,6 +742,8 @@ Scene *BKE_scene_add(Main *bmain, const char *name) copy_v2_fl2(sce->safe_areas.title_center, 17.5f / 100.0f, 5.0f / 100.0f); copy_v2_fl2(sce->safe_areas.action_center, 15.0f / 100.0f, 5.0f / 100.0f); + sce->preview = NULL; + return sce; } diff --git a/source/blender/blenloader/intern/readblenentry.c b/source/blender/blenloader/intern/readblenentry.c index 20ec27a1f4b..e8d7a46687f 100644 --- a/source/blender/blenloader/intern/readblenentry.c +++ b/source/blender/blenloader/intern/readblenentry.c @@ -161,6 +161,9 @@ LinkNode *BLO_blendhandle_get_previews(BlendHandle *bh, int ofblocktype, int *to case ID_IM: /* fall through */ case ID_WO: /* fall through */ case ID_LA: /* fall through */ + case ID_OB: /* fall through */ + case ID_GR: /* fall through */ + case ID_SCE: /* fall through */ new_prv = MEM_callocN(sizeof(PreviewImage), "newpreview"); BLI_linklist_prepend(&previews, new_prv); tot++; diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index f37d24f9681..51d25b463a3 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -1920,6 +1920,25 @@ static void IDP_LibLinkProperty(IDProperty *UNUSED(prop), int UNUSED(switch_endi { } +/* ************ READ IMAGE PREVIEW *************** */ + +static PreviewImage *direct_link_preview_image(FileData *fd, PreviewImage *old_prv) +{ + PreviewImage *prv = newdataadr(fd, old_prv); + + if (prv) { + int i; + for (i = 0; i < NUM_ICON_SIZES; ++i) { + if (prv->rect[i]) { + prv->rect[i] = newdataadr(fd, prv->rect[i]); + } + prv->gputexture[i] = NULL; + } + } + + return prv; +} + /* ************ READ ID *************** */ static void direct_link_id(FileData *fd, ID *id) @@ -2042,25 +2061,6 @@ static PackedFile *direct_link_packedfile(FileData *fd, PackedFile *oldpf) return pf; } -/* ************ READ IMAGE PREVIEW *************** */ - -static PreviewImage *direct_link_preview_image(FileData *fd, PreviewImage *old_prv) -{ - PreviewImage *prv = newdataadr(fd, old_prv); - - if (prv) { - int i; - for (i = 0; i < NUM_ICON_SIZES; ++i) { - if (prv->rect[i]) { - prv->rect[i] = newdataadr(fd, prv->rect[i]); - } - prv->gputexture[i] = NULL; - } - } - - return prv; -} - /* ************ READ ANIMATION STUFF ***************** */ /* Legacy Data Support (for Version Patching) ----------------------------- */ @@ -5280,6 +5280,8 @@ static void direct_link_object(FileData *fd, Object *ob) link_list(fd, &ob->lodlevels); ob->currentlod = ob->lodlevels.first; + + ob->preview = direct_link_preview_image(fd, ob->preview); } /* ************ READ SCENE ***************** */ @@ -5837,6 +5839,8 @@ static void direct_link_scene(FileData *fd, Scene *sce) rbw->ltime = (float)rbw->pointcache->startframe; } } + + sce->preview = direct_link_preview_image(fd, sce->preview); } /* ************ READ WM ***************** */ @@ -7083,6 +7087,8 @@ static void lib_link_sound(FileData *fd, Main *main) static void direct_link_group(FileData *fd, Group *group) { link_list(fd, &group->gobject); + + group->preview = direct_link_preview_image(fd, group->preview); } static void lib_link_group(FileData *fd, Main *main) diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index f5d35e45fc0..2dfb100cc62 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -588,6 +588,33 @@ void IDP_WriteProperty(IDProperty *prop, void *wd) IDP_WriteProperty_OnlyData(prop, wd); } +static void write_previews(WriteData *wd, PreviewImage *prv) +{ + /* Never write previews when doing memsave (i.e. undo/redo)! */ + if (prv && !wd->current) { + short w = prv->w[1]; + short h = prv->h[1]; + unsigned int *rect = prv->rect[1]; + + /* don't write out large previews if not requested */ + if (!(U.flag & USER_SAVE_PREVIEWS)) { + prv->w[1] = 0; + prv->h[1] = 0; + prv->rect[1] = NULL; + } + writestruct(wd, DATA, "PreviewImage", 1, prv); + if (prv->rect[0]) writedata(wd, DATA, prv->w[0] * prv->h[0] * sizeof(unsigned int), prv->rect[0]); + if (prv->rect[1]) writedata(wd, DATA, prv->w[1] * prv->h[1] * sizeof(unsigned int), prv->rect[1]); + + /* restore preview, we still want to keep it in memory even if not saved to file */ + if (!(U.flag & USER_SAVE_PREVIEWS) ) { + prv->w[1] = w; + prv->h[1] = h; + prv->rect[1] = rect; + } + } +} + static void write_fmodifiers(WriteData *wd, ListBase *fmodifiers) { FModifier *fcm; @@ -1698,6 +1725,9 @@ static void write_objects(WriteData *wd, ListBase *idbase) writelist(wd, DATA, "LinkData", &ob->pc_ids); writelist(wd, DATA, "LodLevel", &ob->lodlevels); } + + write_previews(wd, ob->preview); + ob= ob->id.next; } @@ -2138,32 +2168,6 @@ static void write_lattices(WriteData *wd, ListBase *idbase) } } -static void write_previews(WriteData *wd, PreviewImage *prv) -{ - /* Never write previews in undo steps! */ - if (prv && !wd->current) { - short w = prv->w[1]; - short h = prv->h[1]; - unsigned int *rect = prv->rect[1]; - /* don't write out large previews if not requested */ - if (!(U.flag & USER_SAVE_PREVIEWS)) { - prv->w[1] = 0; - prv->h[1] = 0; - prv->rect[1] = NULL; - } - writestruct(wd, DATA, "PreviewImage", 1, prv); - if (prv->rect[0]) writedata(wd, DATA, prv->w[0]*prv->h[0]*sizeof(unsigned int), prv->rect[0]); - if (prv->rect[1]) writedata(wd, DATA, prv->w[1]*prv->h[1]*sizeof(unsigned int), prv->rect[1]); - - /* restore preview, we still want to keep it in memory even if not saved to file */ - if (!(U.flag & USER_SAVE_PREVIEWS) ) { - prv->w[1] = w; - prv->h[1] = h; - prv->rect[1] = rect; - } - } -} - static void write_images(WriteData *wd, ListBase *idbase) { Image *ima; @@ -2572,6 +2576,8 @@ static void write_scenes(WriteData *wd, ListBase *scebase) write_pointcaches(wd, &(sce->rigidbody_world->ptcaches)); } + write_previews(wd, sce->preview); + sce= sce->id.next; } /* flush helps the compression for undo-save */ @@ -3068,6 +3074,8 @@ static void write_groups(WriteData *wd, ListBase *idbase) writestruct(wd, ID_GR, "Group", 1, group); if (group->id.properties) IDP_WriteProperty(group->id.properties, wd); + write_previews(wd, group->preview); + go= group->gobject.first; while (go) { writestruct(wd, DATA, "GroupObject", 1, go); diff --git a/source/blender/makesdna/DNA_group_types.h b/source/blender/makesdna/DNA_group_types.h index 2740281b4c0..45dd0cb9ff2 100644 --- a/source/blender/makesdna/DNA_group_types.h +++ b/source/blender/makesdna/DNA_group_types.h @@ -52,7 +52,9 @@ typedef struct Group { ID id; ListBase gobject; /* GroupObject */ - + + struct PreviewImage *preview; + /* Bad design, since layers stored in the scenes 'Base' * the objects that show in the group can change depending * on the last used scene */ diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h index 0a454d4f281..2937be7d133 100644 --- a/source/blender/makesdna/DNA_object_types.h +++ b/source/blender/makesdna/DNA_object_types.h @@ -296,6 +296,8 @@ typedef struct Object { ListBase lodlevels; /* contains data for levels of detail */ LodLevel *currentlod; + + struct PreviewImage *preview; } Object; /* Warning, this is not used anymore because hooks are now modifiers */ diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index fd6d39c9ce6..f9cea3871f6 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -1443,6 +1443,8 @@ typedef struct Scene { /* RigidBody simulation world+settings */ struct RigidBodyWorld *rigidbody_world; + + struct PreviewImage *preview; } Scene; /* **************** RENDERDATA ********************* */