diff options
author | Antonio Vazquez <blendergit@gmail.com> | 2019-10-02 14:15:37 +0300 |
---|---|---|
committer | Antonio Vazquez <blendergit@gmail.com> | 2019-10-02 14:15:37 +0300 |
commit | 386ba094988fc793f8e060d15438566e5e2d2cae (patch) | |
tree | 4cbde50b5d1d7a45c89ee99c29dd1b86d1d97b59 /source/blender/blenloader/intern/readfile.c | |
parent | 6129e20cec4639aebf335ff13b2ba0c59670662d (diff) | |
parent | f97a64aa9b7b384f8221a1ef4f2eef9cde1238db (diff) |
Merge branch 'master' into temp-gpencil-drw-engine
Conflicts:
source/blender/draw/engines/gpencil/gpencil_engine.c
Diffstat (limited to 'source/blender/blenloader/intern/readfile.c')
-rw-r--r-- | source/blender/blenloader/intern/readfile.c | 198 |
1 files changed, 158 insertions, 40 deletions
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 2a036d7f4ea..545659d06c2 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -24,15 +24,12 @@ #include "zlib.h" #include <limits.h> -#include <stdio.h> // for printf fopen fwrite fclose sprintf FILE -#include <stdlib.h> // for getenv atoi -#include <stddef.h> // for offsetof -#include <fcntl.h> // for open -#include <string.h> // for strrchr strncmp strstr -#include <math.h> // for fabs -#include <stdarg.h> /* for va_start/end */ -#include <time.h> /* for gmtime */ -#include <ctype.h> /* for isdigit */ +#include <stdlib.h> /* for atoi. */ +#include <stddef.h> /* for offsetof. */ +#include <fcntl.h> /* for open flags (O_BINARY, O_RDONLY). */ +#include <stdarg.h> /* for va_start/end. */ +#include <time.h> /* for gmtime. */ +#include <ctype.h> /* for isdigit. */ #include "BLI_utildefines.h" #ifndef WIN32 @@ -95,8 +92,6 @@ #include "DNA_movieclip_types.h" #include "DNA_mask_types.h" -#include "RNA_access.h" - #include "MEM_guardedalloc.h" #include "BLI_endian_switch.h" @@ -111,8 +106,6 @@ #include "BKE_action.h" #include "BKE_armature.h" #include "BKE_brush.h" -#include "BKE_cachefile.h" -#include "BKE_cloth.h" #include "BKE_collection.h" #include "BKE_colortools.h" #include "BKE_constraint.h" @@ -120,7 +113,6 @@ #include "BKE_effect.h" #include "BKE_fcurve.h" #include "BKE_global.h" // for G -#include "BKE_gpencil.h" #include "BKE_gpencil_modifier.h" #include "BKE_idcode.h" #include "BKE_idprop.h" @@ -137,8 +129,6 @@ #include "BKE_multires.h" #include "BKE_node.h" // for tree type defines #include "BKE_object.h" -#include "BKE_ocean.h" -#include "BKE_outliner_treehash.h" #include "BKE_paint.h" #include "BKE_particle.h" #include "BKE_pointcache.h" @@ -184,7 +174,7 @@ * - read associated 'direct data' * - link direct data (internal and to LibBlock) * - read #FileGlobal - * - read #USER data, only when indicated (file is ``~/X.XX/startup.blend``) + * - read #USER data, only when indicated (file is `~/.config/blender/X.XX/config/userpref.blend`) * - free file * - per Library (per #Main) * - read file @@ -233,7 +223,7 @@ #define USE_GHASH_RESTORE_POINTER /* Define this to have verbose debug prints. */ -#define USE_DEBUG_PRINT +//#define USE_DEBUG_PRINT #ifdef USE_DEBUG_PRINT # define DEBUG_PRINTF(...) printf(__VA_ARGS__) @@ -2597,7 +2587,7 @@ static PreviewImage *direct_link_preview_image(FileData *fd, PreviewImage *old_p if (prv) { int i; - for (i = 0; i < NUM_ICON_SIZES; ++i) { + for (i = 0; i < NUM_ICON_SIZES; i++) { if (prv->rect[i]) { prv->rect[i] = newdataadr(fd, prv->rect[i]); } @@ -2667,6 +2657,7 @@ static void direct_link_id(FileData *fd, ID *id) * function are still in a clear tag state. * (glowering at certain nodetree fake data-lock here...). */ id->tag = 0; + id->flag &= ~LIB_INDIRECT_WEAK_LINK; /* Link direct data of overrides. */ if (id->override_library) { @@ -2838,6 +2829,12 @@ static PackedFile *direct_link_packedfile(FileData *fd, PackedFile *oldpf) if (pf) { pf->data = newpackedadr(fd, pf->data); + if (pf->data == NULL) { + /* We cannot allow a PackedFile with a NULL data field, + * the whole code assumes this is not possible. See T70315. */ + printf("%s: NULL packedfile data, cleaning up...\n", __func__); + MEM_SAFE_FREE(pf); + } } return pf; @@ -4382,7 +4379,7 @@ static void direct_link_curve(FileData *fd, Curve *cu) switch_endian_knots(nu); } } - cu->bb = NULL; + cu->texflag &= ~CU_AUTOSPACE_EVALUATED; } /** \} */ @@ -4938,7 +4935,7 @@ static void direct_link_mdisps(FileData *fd, int count, MDisps *mdisps, int exte if (mdisps) { int i; - for (i = 0; i < count; ++i) { + for (i = 0; i < count; i++) { mdisps[i].disps = newdataadr(fd, mdisps[i].disps); mdisps[i].hidden = newdataadr(fd, mdisps[i].hidden); @@ -4968,7 +4965,7 @@ static void direct_link_grid_paint_mask(FileData *fd, int count, GridPaintMask * if (grid_paint_mask) { int i; - for (i = 0; i < count; ++i) { + for (i = 0; i < count; i++) { GridPaintMask *gpm = &grid_paint_mask[i]; if (gpm->data) { gpm->data = newdataadr(fd, gpm->data); @@ -5049,7 +5046,7 @@ static void direct_link_mesh(FileData *fd, Mesh *mesh) direct_link_customdata(fd, &mesh->ldata, mesh->totloop); direct_link_customdata(fd, &mesh->pdata, mesh->totpoly); - mesh->bb = NULL; + mesh->texflag &= ~ME_AUTOSPACE_EVALUATED; mesh->edit_mesh = NULL; BKE_mesh_runtime_reset(mesh); @@ -5339,8 +5336,8 @@ static void lib_link_object(FileData *fd, Main *main) eModifierType_Smoke); if (smd && (smd->type == MOD_SMOKE_TYPE_DOMAIN) && smd->domain) { - smd->domain->flags |= - MOD_SMOKE_FILE_LOAD; /* flag for refreshing the simulation after loading */ + /* Flag for refreshing the simulation after loading. */ + smd->domain->flags |= MOD_SMOKE_FILE_LOAD; } } @@ -5753,8 +5750,8 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb) } /* runtime only */ - csmd->delta_cache = NULL; - csmd->delta_cache_num = 0; + csmd->delta_cache.deltas = NULL; + csmd->delta_cache.totverts = 0; } else if (md->type == eModifierType_MeshSequenceCache) { MeshSeqCacheModifierData *msmcd = (MeshSeqCacheModifierData *)md; @@ -6344,7 +6341,7 @@ static void direct_link_lightcache(FileData *fd, LightCache *cache) if (cache->cube_mips) { cache->cube_mips = newdataadr(fd, cache->cube_mips); - for (int i = 0; i < cache->mips_len; ++i) { + for (int i = 0; i < cache->mips_len; i++) { direct_link_lightcache_texture(fd, &cache->cube_mips[i]); } } @@ -6353,6 +6350,14 @@ static void direct_link_lightcache(FileData *fd, LightCache *cache) cache->grid_data = newdataadr(fd, cache->grid_data); } +static void direct_link_view3dshading(FileData *fd, View3DShading *shading) +{ + if (shading->prop) { + shading->prop = newdataadr(fd, shading->prop); + IDP_DirectLinkGroup_OrFree(&shading->prop, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd); + } +} + /* check for cyclic set-scene, * libs can cause this case which is normally prevented, see (T#####) */ #define USE_SETSCENE_CHECK @@ -6755,6 +6760,7 @@ static void direct_link_scene(FileData *fd, Scene *sce) ed->act_seq = newdataadr(fd, ed->act_seq); ed->cache = NULL; + ed->prefetch_job = NULL; /* recursive link sequences, lb will be correctly initialized */ link_recurs_seq(fd, &ed->seqbase); @@ -6987,6 +6993,8 @@ static void direct_link_scene(FileData *fd, Scene *sce) } } + direct_link_view3dshading(fd, &sce->display.shading); + sce->layer_properties = newdataadr(fd, sce->layer_properties); IDP_DirectLinkGroup_OrFree(&sce->layer_properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd); } @@ -7150,6 +7158,8 @@ static void direct_link_region(FileData *fd, ARegion *ar, int spacetype) rv3d->render_engine = NULL; rv3d->sms = NULL; rv3d->smooth_timer = NULL; + + rv3d->rflag &= ~(RV3D_NAVIGATING | RV3D_PAINTING); } } } @@ -7255,6 +7265,8 @@ static void direct_link_area(FileData *fd, ScrArea *area) v3d->fx_settings.ssao = newdataadr(fd, v3d->fx_settings.ssao); } + direct_link_view3dshading(fd, &v3d->shading); + blo_do_versions_view3d_split_250(v3d, &sl->regionbase); } else if (sl->spacetype == SPACE_GRAPH) { @@ -7859,6 +7871,45 @@ static void lib_link_clipboard_restore(struct IDNameLib_Map *id_map) BKE_sequencer_base_recursive_apply(&seqbase_clipboard, lib_link_seq_clipboard_cb, id_map); } +static int lib_link_main_data_restore_cb(void *user_data, + ID *UNUSED(id_self), + ID **id_pointer, + int cb_flag) +{ + if (cb_flag & IDWALK_CB_PRIVATE || *id_pointer == NULL) { + return IDWALK_RET_NOP; + } + + /* Special ugly case here, thanks again for those non-IDs IDs... */ + /* We probably need to add more cases here (hint: nodetrees), + * but will wait for changes from D5559 to get in first. */ + if (GS((*id_pointer)->name) == ID_GR) { + Collection *collection = (Collection *)*id_pointer; + if (collection->flag & COLLECTION_IS_MASTER) { + return IDWALK_RET_NOP; + } + } + + struct IDNameLib_Map *id_map = user_data; + + /* Note: Handling of usercount here is really bad, defining its own system... + * Will have to be refactored at some point, but that is not top priority task for now. + * And all usercounts are properly recomputed at the end of the undo management code anyway. */ + *id_pointer = restore_pointer_by_name( + id_map, *id_pointer, (cb_flag & IDWALK_CB_USER_ONE) ? USER_REAL : USER_IGNORE); + + return IDWALK_RET_NOP; +} + +static void lib_link_main_data_restore(struct IDNameLib_Map *id_map, Main *newmain) +{ + ID *id; + FOREACH_MAIN_ID_BEGIN (newmain, id) { + BKE_library_foreach_ID_link(newmain, id, lib_link_main_data_restore_cb, id_map, IDWALK_NOP); + } + FOREACH_MAIN_ID_END; +} + static void lib_link_window_scene_data_restore(wmWindow *win, Scene *scene, ViewLayer *view_layer) { bScreen *screen = BKE_workspace_active_screen_get(win->workspace_hook); @@ -8178,11 +8229,24 @@ void blo_lib_link_restore(Main *oldmain, /* keep cursor location through undo */ memcpy(&win->scene->cursor, &oldscene->cursor, sizeof(win->scene->cursor)); + /* Note: even though that function seems to redo part of what is done by + * `lib_link_workspace_layout_restore()` above, it seems to have a slightly different scope: + * while the former updates the whole UI pointers from Main db (going over all layouts of + * all workspaces), that one only focuses one current active screen, takes care of + * potential local view, and needs window's scene pointer to be final... */ lib_link_window_scene_data_restore(win, win->scene, cur_view_layer); BLI_assert(win->screen == NULL); } + /* Restore all ID pointers in Main database itself + * (especially IDProperties might point to some worspace of other 'weirdly unchanged' ID + * pointers, see T69146). + * Note that this will re;ap again a few pointers in workspaces or so, + * but since we are remapping final ones already set above, + * that is just some minor harmless double-processing. */ + lib_link_main_data_restore(id_map, newmain); + /* update IDs stored in all possible clipboards */ lib_link_clipboard_restore(id_map); @@ -9070,7 +9134,12 @@ static BHead *read_data_into_oldnewmap(FileData *fd, BHead *bhead, const char *a return bhead; } -static BHead *read_libblock(FileData *fd, Main *main, BHead *bhead, const int tag, ID **r_id) +static BHead *read_libblock(FileData *fd, + Main *main, + BHead *bhead, + const int tag, + const bool placeholder_set_indirect_extern, + ID **r_id) { /* this routine reads a libblock and its direct data. Use link functions to connect it all */ @@ -9190,7 +9259,16 @@ static BHead *read_libblock(FileData *fd, Main *main, BHead *bhead, const int ta /* this case cannot be direct_linked: it's just the ID part */ if (bhead->code == ID_LINK_PLACEHOLDER) { /* That way, we know which data-lock needs do_versions (required currently for linking). */ - id->tag = tag | LIB_TAG_NEED_LINK | LIB_TAG_NEW; + id->tag = tag | LIB_TAG_ID_LINK_PLACEHOLDER | LIB_TAG_NEED_LINK | LIB_TAG_NEW; + + if (placeholder_set_indirect_extern) { + if (id->flag & LIB_INDIRECT_WEAK_LINK) { + id->tag |= LIB_TAG_INDIRECT; + } + else { + id->tag |= LIB_TAG_EXTERN; + } + } return blo_bhead_next(fd, bhead); } @@ -9753,8 +9831,7 @@ BlendFileData *blo_read_file_internal(FileData *fd, const char *filepath) * to the file format definition. So we can use the entry at the * end of mainlist, added in direct_link_library. */ Main *libmain = mainlist.last; - bhead = read_libblock( - fd, libmain, bhead, LIB_TAG_ID_LINK_PLACEHOLDER | LIB_TAG_EXTERN, NULL); + bhead = read_libblock(fd, libmain, bhead, 0, true, NULL); } break; /* in 2.50+ files, the file identifier for screens is patched, forward compatibility */ @@ -9767,7 +9844,7 @@ BlendFileData *blo_read_file_internal(FileData *fd, const char *filepath) bhead = blo_bhead_next(fd, bhead); } else { - bhead = read_libblock(fd, bfd->main, bhead, LIB_TAG_LOCAL, NULL); + bhead = read_libblock(fd, bfd->main, bhead, LIB_TAG_LOCAL, false, NULL); } } } @@ -10015,7 +10092,7 @@ static void expand_doit_library(void *fdhandle, Main *mainvar, void *old) if (id == NULL) { /* ID has not been read yet, add placeholder to the main of the * library it belongs to, so that it will be read later. */ - read_libblock(fd, libmain, bhead, LIB_TAG_ID_LINK_PLACEHOLDER | LIB_TAG_INDIRECT, NULL); + read_libblock(fd, libmain, bhead, LIB_TAG_INDIRECT, false, NULL); // commented because this can print way too much // if (G.debug & G_DEBUG) printf("expand_doit: other lib %s\n", lib->name); @@ -10023,6 +10100,12 @@ static void expand_doit_library(void *fdhandle, Main *mainvar, void *old) libmain->curlib->parent = mainvar->curlib; } else { + /* Convert any previously read weak link to regular link + * to signal that we want to read this datablock. */ + if (id->tag & LIB_TAG_ID_LINK_PLACEHOLDER) { + id->flag &= ~LIB_INDIRECT_WEAK_LINK; + } + /* "id" is either a placeholder or real ID that is already in the * main of the library (A) it belongs to. However it might have been * put there by another library (C) which only updated its own @@ -10064,9 +10147,15 @@ static void expand_doit_library(void *fdhandle, Main *mainvar, void *old) ID *id = is_yet_read(fd, mainvar, bhead); if (id == NULL) { - read_libblock(fd, mainvar, bhead, LIB_TAG_NEED_EXPAND | LIB_TAG_INDIRECT, NULL); + read_libblock(fd, mainvar, bhead, LIB_TAG_NEED_EXPAND | LIB_TAG_INDIRECT, false, NULL); } else { + /* Convert any previously read weak link to regular link + * to signal that we want to read this datablock. */ + if (id->tag & LIB_TAG_ID_LINK_PLACEHOLDER) { + id->flag &= ~LIB_INDIRECT_WEAK_LINK; + } + /* this is actually only needed on UI call? when ID was already read before, * and another append happens which invokes same ID... * in that case the lookup table needs this entry */ @@ -11200,6 +11289,7 @@ static void add_loose_objects_to_scene(Main *mainvar, BKE_scene_object_base_flag_sync_from_base(base); ob->id.tag &= ~LIB_TAG_INDIRECT; + ob->id.flag &= ~LIB_INDIRECT_WEAK_LINK; ob->id.tag |= LIB_TAG_EXTERN; } } @@ -11292,6 +11382,7 @@ static void add_collections_to_scene(Main *mainvar, /* Those are kept for safety and consistency, but should not be needed anymore? */ collection->id.tag &= ~LIB_TAG_INDIRECT; + collection->id.flag &= ~LIB_INDIRECT_WEAK_LINK; collection->id.tag |= LIB_TAG_EXTERN; } } @@ -11316,7 +11407,7 @@ static ID *link_named_part( if (id == NULL) { /* not read yet */ const int tag = force_indirect ? LIB_TAG_INDIRECT : LIB_TAG_EXTERN; - read_libblock(fd, mainl, bhead, tag | LIB_TAG_NEED_EXPAND, &id); + read_libblock(fd, mainl, bhead, tag | LIB_TAG_NEED_EXPAND, false, &id); if (id) { /* sort by name in list */ @@ -11332,6 +11423,7 @@ static ID *link_named_part( oldnewmap_insert(fd->libmap, bhead->old, id, bhead->code); if (!force_indirect && (id->tag & LIB_TAG_INDIRECT)) { id->tag &= ~LIB_TAG_INDIRECT; + id->flag &= ~LIB_INDIRECT_WEAK_LINK; id->tag |= LIB_TAG_EXTERN; } } @@ -11370,7 +11462,7 @@ int BLO_library_link_copypaste(Main *mainl, BlendHandle *bh, const unsigned int if (BKE_idcode_is_valid(bhead->code) && BKE_idcode_is_linkable(bhead->code) && (id_types_mask == 0 || (BKE_idcode_to_idfilter((short)bhead->code) & id_types_mask) != 0)) { - read_libblock(fd, mainl, bhead, LIB_TAG_NEED_EXPAND | LIB_TAG_INDIRECT, &id); + read_libblock(fd, mainl, bhead, LIB_TAG_NEED_EXPAND | LIB_TAG_INDIRECT, false, &id); num_directly_linked++; } @@ -11656,7 +11748,7 @@ static int has_linked_ids_to_read(Main *mainvar) while (a--) { for (ID *id = lbarray[a]->first; id; id = id->next) { - if (id->tag & LIB_TAG_ID_LINK_PLACEHOLDER) { + if ((id->tag & LIB_TAG_ID_LINK_PLACEHOLDER) && !(id->flag & LIB_INDIRECT_WEAK_LINK)) { return true; } } @@ -11687,11 +11779,12 @@ static void read_library_linked_id( } id->tag &= ~LIB_TAG_ID_LINK_PLACEHOLDER; + id->flag &= ~LIB_INDIRECT_WEAK_LINK; if (bhead) { id->tag |= LIB_TAG_NEED_EXPAND; // printf("read lib block %s\n", id->name); - read_libblock(fd, mainvar, bhead, id->tag, r_id); + read_libblock(fd, mainvar, bhead, id->tag, false, r_id); } else { blo_reportf_wrap(reports, @@ -11725,7 +11818,7 @@ static void read_library_linked_ids(FileData *basefd, while (id) { ID *id_next = id->next; - if (id->tag & LIB_TAG_ID_LINK_PLACEHOLDER) { + if ((id->tag & LIB_TAG_ID_LINK_PLACEHOLDER) && !(id->flag & LIB_INDIRECT_WEAK_LINK)) { BLI_remlink(lbarray[a], id); /* When playing with lib renaming and such, you may end with cases where @@ -11761,6 +11854,28 @@ static void read_library_linked_ids(FileData *basefd, BLI_ghash_free(loaded_ids, NULL, NULL); } +static void read_library_clear_weak_links(FileData *basefd, ListBase *mainlist, Main *mainvar) +{ + /* Any remaining weak links at this point have been lost, silently drop + * those by setting them to NULL pointers. */ + ListBase *lbarray[MAX_LIBARRAY]; + int a = set_listbasepointers(mainvar, lbarray); + + while (a--) { + ID *id = lbarray[a]->first; + + while (id) { + ID *id_next = id->next; + if ((id->tag & LIB_TAG_ID_LINK_PLACEHOLDER) && (id->flag & LIB_INDIRECT_WEAK_LINK)) { + /* printf("Dropping weak link to %s\n", id->name); */ + change_link_placeholder_to_real_ID_pointer(mainlist, basefd, id, NULL); + BLI_freelinkN(lbarray[a], id); + } + id = id_next; + } + } +} + static FileData *read_library_file_data(FileData *basefd, ListBase *mainlist, Main *mainl, @@ -11887,6 +12002,9 @@ static void read_libraries(FileData *basefd, ListBase *mainlist) Main *main_newid = BKE_main_new(); for (Main *mainptr = mainl->next; mainptr; mainptr = mainptr->next) { + /* Drop weak links for which no datablock was found. */ + read_library_clear_weak_links(basefd, mainlist, mainptr); + /* Do versioning for newly added linked data-locks. If no data-locks * were read from a library versionfile will still be zero and we can * skip it. */ |