diff options
author | Julian Eisel <julian@blender.org> | 2020-06-05 14:09:31 +0300 |
---|---|---|
committer | Julian Eisel <julian@blender.org> | 2020-06-05 14:09:31 +0300 |
commit | 920a58d9b6d667894cf166cbbd25e4c2fbd238ea (patch) | |
tree | 7ca5a9da640753b5e070c439ac3bdd14dfad92cf /source/blender/blenloader/intern | |
parent | c94b6209861ca7cc3985b53474feed7d94c0221a (diff) | |
parent | a1d55bdd530390e58c51abe9707b8d3b0ae3e861 (diff) |
Merge branch 'master' into wm-drag-drop-rewritewm-drag-drop-rewrite
Diffstat (limited to 'source/blender/blenloader/intern')
-rw-r--r-- | source/blender/blenloader/intern/readblenentry.c | 35 | ||||
-rw-r--r-- | source/blender/blenloader/intern/readfile.c | 1679 | ||||
-rw-r--r-- | source/blender/blenloader/intern/readfile.h | 9 | ||||
-rw-r--r-- | source/blender/blenloader/intern/undofile.c | 62 | ||||
-rw-r--r-- | source/blender/blenloader/intern/versioning_250.c | 259 | ||||
-rw-r--r-- | source/blender/blenloader/intern/versioning_260.c | 120 | ||||
-rw-r--r-- | source/blender/blenloader/intern/versioning_270.c | 100 | ||||
-rw-r--r-- | source/blender/blenloader/intern/versioning_280.c | 682 | ||||
-rw-r--r-- | source/blender/blenloader/intern/versioning_290.c | 270 | ||||
-rw-r--r-- | source/blender/blenloader/intern/versioning_cycles.c | 48 | ||||
-rw-r--r-- | source/blender/blenloader/intern/versioning_defaults.c | 332 | ||||
-rw-r--r-- | source/blender/blenloader/intern/versioning_legacy.c | 184 | ||||
-rw-r--r-- | source/blender/blenloader/intern/versioning_userdef.c | 28 | ||||
-rw-r--r-- | source/blender/blenloader/intern/writefile.c | 833 |
14 files changed, 2953 insertions, 1688 deletions
diff --git a/source/blender/blenloader/intern/readblenentry.c b/source/blender/blenloader/intern/readblenentry.c index adf7db0267e..1309b3e3c33 100644 --- a/source/blender/blenloader/intern/readblenentry.c +++ b/source/blender/blenloader/intern/readblenentry.c @@ -428,41 +428,6 @@ BlendFileData *BLO_read_from_memfile(Main *oldmain, * but oldmain itself shall *never* be 'transferred' to new mainlist! */ BLI_assert(old_mainlist.first == oldmain); - if (bfd && old_mainlist.first != old_mainlist.last) { - /* Even though directly used libs have been already moved to new main, - * indirect ones have not. - * This is a bit annoying, but we have no choice but to keep them all for now - - * means some now unused data may remain in memory, but think we'll have to live with it. */ - Main *libmain, *libmain_next; - Main *newmain = bfd->main; - ListBase new_mainlist = {newmain, newmain}; - - for (libmain = oldmain->next; libmain; libmain = libmain_next) { - libmain_next = libmain->next; - /* Note that LIB_INDIRECT does not work with libraries themselves, so we use non-NULL - * parent to detect indirect-linked ones. */ - if (libmain->curlib && (libmain->curlib->parent != NULL)) { - BLI_remlink(&old_mainlist, libmain); - BLI_addtail(&new_mainlist, libmain); - } - else { -#ifdef PRINT_DEBUG - printf("Dropped Main for lib: %s\n", libmain->curlib->id.name); -#endif - } - } - /* In any case, we need to move all lib data-blocks themselves - those are - * 'first level data', getting rid of them would imply updating spaces & co - * to prevent invalid pointers access. */ - BLI_movelisttolist(&newmain->libraries, &oldmain->libraries); - - blo_join_main(&new_mainlist); - } - -#if 0 - printf("Remaining mains/libs in oldmain: %d\n", BLI_listbase_count(&fd->old_mainlist) - 1); -#endif - /* That way, libs (aka mains) we did not reuse in new undone/redone state * will be cleared together with oldmain... */ blo_join_main(&old_mainlist); diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 61179f65ad2..6a51102a969 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -86,6 +86,7 @@ #include "DNA_sdna_types.h" #include "DNA_sequence_types.h" #include "DNA_shader_fx_types.h" +#include "DNA_simulation_types.h" #include "DNA_sound_types.h" #include "DNA_space_types.h" #include "DNA_speaker_types.h" @@ -109,7 +110,7 @@ #include "BLT_translation.h" #include "BKE_action.h" -#include "BKE_animsys.h" +#include "BKE_anim_data.h" #include "BKE_armature.h" #include "BKE_brush.h" #include "BKE_collection.h" @@ -117,7 +118,7 @@ #include "BKE_constraint.h" #include "BKE_curve.h" #include "BKE_effect.h" -#include "BKE_fcurve.h" +#include "BKE_fcurve_driver.h" #include "BKE_fluid.h" #include "BKE_global.h" // for G #include "BKE_gpencil_modifier.h" @@ -146,6 +147,7 @@ #include "BKE_screen.h" #include "BKE_sequencer.h" #include "BKE_shader_fx.h" +#include "BKE_simulation.h" #include "BKE_sound.h" #include "BKE_volume.h" #include "BKE_workspace.h" @@ -158,6 +160,7 @@ #include "BLO_blend_defs.h" #include "BLO_blend_validate.h" +#include "BLO_read_write.h" #include "BLO_readfile.h" #include "BLO_undofile.h" @@ -470,8 +473,9 @@ static void *oldnewmap_liblookup(OldNewMap *onm, const void *addr, const void *l return NULL; } -static void oldnewmap_free_unused(OldNewMap *onm) +static void oldnewmap_clear(OldNewMap *onm) { + /* Free unused data. */ for (int i = 0; i < onm->nentries; i++) { OldNew *entry = &onm->entries[i]; if (entry->nr == 0) { @@ -479,10 +483,7 @@ static void oldnewmap_free_unused(OldNewMap *onm) entry->newp = NULL; } } -} -static void oldnewmap_clear(OldNewMap *onm) -{ onm->capacity_exp = DEFAULT_SIZE_EXP; oldnewmap_clear_map(onm); onm->nentries = 0; @@ -664,7 +665,7 @@ static Main *blo_find_main(FileData *fd, const char *filepath, const char *relab char name1[FILE_MAX]; BLI_strncpy(name1, filepath, sizeof(name1)); - BLI_cleanup_path(relabase, name1); + BLI_path_normalize(relabase, name1); // printf("blo_find_main: relabase %s\n", relabase); // printf("blo_find_main: original in %s\n", filepath); @@ -691,7 +692,7 @@ static Main *blo_find_main(FileData *fd, const char *filepath, const char *relab /* Important, consistency with main ID reading code from read_libblock(). */ lib->id.us = ID_FAKE_USERS(lib); - /* Matches lib_link_library(). */ + /* Matches direct_link_library(). */ id_us_ensure_real(&lib->id); BLI_strncpy(lib->name, filepath, sizeof(lib->name)); @@ -713,6 +714,20 @@ static Main *blo_find_main(FileData *fd, const char *filepath, const char *relab /** \name File Parsing * \{ */ +typedef struct BlendDataReader { + FileData *fd; +} BlendDataReader; + +typedef struct BlendLibReader { + FileData *fd; + Main *main; +} BlendLibReader; + +typedef struct BlendExpander { + FileData *fd; + Main *main; +} BlendExpander; + static void switch_endian_bh4(BHead4 *bhead) { /* the ID_.. codes */ @@ -1680,7 +1695,7 @@ bool BLO_library_path_explode(const char *path, char *r_dir, char **r_group, cha strcpy(r_dir, path); - while ((slash = (char *)BLI_last_slash(r_dir))) { + while ((slash = (char *)BLI_path_slash_rfind(r_dir))) { char tc = *slash; *slash = '\0'; if (BLO_has_bfile_extension(r_dir) && BLI_is_file(r_dir)) { @@ -2376,9 +2391,6 @@ static void *read_struct(FileData *fd, BHead *bh, const char *blockname) } } - if (!BHEADN_FROM_BHEAD(bh)->is_memchunk_identical) { - fd->are_memchunks_identical = false; - } #ifdef USE_BHEAD_READ_ON_DEMAND if (bh_orig != bh) { MEM_freeN(BHEADN_FROM_BHEAD(bh)); @@ -2389,6 +2401,15 @@ static void *read_struct(FileData *fd, BHead *bh, const char *blockname) return temp; } +/* Like read_struct, but gets a pointer without allocating. Only works for + * undo since DNA must match. */ +static const void *peek_struct_undo(FileData *fd, BHead *bhead) +{ + BLI_assert(fd->memfile != NULL); + UNUSED_VARS_NDEBUG(fd); + return (bhead->len) ? (const void *)(bhead + 1) : NULL; +} + typedef void (*link_list_cb)(FileData *fd, void *data); static void link_list_ex(FileData *fd, ListBase *lb, link_list_cb callback) /* only direct data */ @@ -2670,7 +2691,7 @@ static void IDP_LibLinkProperty(IDProperty *prop, FileData *fd) } case IDP_GROUP: /* PointerProperty */ { - for (IDProperty *loop = prop->data.group.first; loop; loop = loop->next) { + LISTBASE_FOREACH (IDProperty *, loop, &prop->data.group) { IDP_LibLinkProperty(loop, fd); } break; @@ -2715,7 +2736,7 @@ static void lib_link_id(FileData *fd, Main *bmain, ID *id); static void lib_link_nodetree(FileData *fd, Main *bmain, bNodeTree *ntree); static void lib_link_collection(FileData *fd, Main *bmain, Collection *collection); -static void lib_link_id_private_id(FileData *fd, Main *bmain, ID *id) +static void lib_link_id_embedded_id(FileData *fd, Main *bmain, ID *id) { /* Handle 'private IDs'. */ bNodeTree *nodetree = ntreeFromID(id); @@ -2749,7 +2770,7 @@ static void lib_link_id(FileData *fd, Main *bmain, ID *id) id->override_library->storage = newlibadr(fd, id->lib, id->override_library->storage); } - lib_link_id_private_id(fd, bmain, id); + lib_link_id_embedded_id(fd, bmain, id); } static void direct_link_id_override_property_operation_cb(FileData *fd, void *data) @@ -2758,6 +2779,8 @@ static void direct_link_id_override_property_operation_cb(FileData *fd, void *da opop->subitem_reference_name = newdataadr(fd, opop->subitem_reference_name); opop->subitem_local_name = newdataadr(fd, opop->subitem_local_name); + + opop->tag = 0; /* Runtime only. */ } static void direct_link_id_override_property_cb(FileData *fd, void *data) @@ -2765,20 +2788,28 @@ static void direct_link_id_override_property_cb(FileData *fd, void *data) IDOverrideLibraryProperty *op = data; op->rna_path = newdataadr(fd, op->rna_path); + + op->tag = 0; /* Runtime only. */ + link_list_ex(fd, &op->operations, direct_link_id_override_property_operation_cb); } -static void direct_link_id(FileData *fd, ID *id, ID *id_old); +static void direct_link_id_common( + FileData *fd, Library *current_library, ID *id, ID *id_old, const int tag); static void direct_link_nodetree(FileData *fd, bNodeTree *ntree); static void direct_link_collection(FileData *fd, Collection *collection); -static void direct_link_id_private_id(FileData *fd, ID *id, ID *id_old) +static void direct_link_id_embedded_id(FileData *fd, Library *current_library, ID *id, ID *id_old) { /* Handle 'private IDs'. */ bNodeTree **nodetree = BKE_ntree_ptr_from_id(id); if (nodetree != NULL && *nodetree != NULL) { *nodetree = newdataadr(fd, *nodetree); - direct_link_id(fd, (ID *)*nodetree, id_old != NULL ? (ID *)ntreeFromID(id_old) : NULL); + direct_link_id_common(fd, + current_library, + (ID *)*nodetree, + id_old != NULL ? (ID *)ntreeFromID(id_old) : NULL, + 0); direct_link_nodetree(fd, *nodetree); } @@ -2786,28 +2817,106 @@ static void direct_link_id_private_id(FileData *fd, ID *id, ID *id_old) Scene *scene = (Scene *)id; if (scene->master_collection != NULL) { scene->master_collection = newdataadr(fd, scene->master_collection); - direct_link_id(fd, - &scene->master_collection->id, - id_old != NULL ? &((Scene *)id_old)->master_collection->id : NULL); + direct_link_id_common(fd, + current_library, + &scene->master_collection->id, + id_old != NULL ? &((Scene *)id_old)->master_collection->id : NULL, + 0); direct_link_collection(fd, scene->master_collection); } } } -static void direct_link_id(FileData *fd, ID *id, ID *id_old) +static int direct_link_id_restore_recalc_exceptions(const ID *id_current) +{ + /* Exception for armature objects, where the pose has direct points to the + * armature databolock. */ + if (GS(id_current->name) == ID_OB && ((Object *)id_current)->pose) { + return ID_RECALC_GEOMETRY; + } + + return 0; +} + +static int direct_link_id_restore_recalc(const FileData *fd, + const ID *id_target, + const ID *id_current, + const bool is_identical) +{ + /* These are the evaluations that had not been performed yet at the time the + * target undo state was written. These need to be done again, since they may + * flush back changes to the original datablock. */ + int recalc = id_target->recalc; + + if (id_current == NULL) { + /* ID does not currently exist in the database, so also will not exist in + * the dependency graphs. That means it will be newly created and as a + * result also fully re-evaluated regardless of the recalc flag set here. */ + recalc |= ID_RECALC_ALL; + } + else { + /* If the contents datablock changed, the depsgraph needs to copy the + * datablock again to ensure it matches the original datablock. */ + if (!is_identical) { + recalc |= ID_RECALC_COPY_ON_WRITE; + } + + /* Special exceptions. */ + recalc |= direct_link_id_restore_recalc_exceptions(id_current); + + /* Evaluations for the current state that have not been performed yet + * by the time we are performing this undo step. */ + recalc |= id_current->recalc; + + /* Tags that were set between the target state and the current state, + * that we need to perform again. */ + if (fd->undo_direction < 0) { + /* Undo: tags from target to the current state. */ + recalc |= id_current->recalc_up_to_undo_push; + } + else { + /* Redo: tags from current to the target state. */ + recalc |= id_target->recalc_up_to_undo_push; + } + } + + return recalc; +} + +static void direct_link_id_common( + FileData *fd, Library *current_library, ID *id, ID *id_old, const int tag) { + if (fd->memfile == NULL) { + /* When actually reading a file , we do want to reset/re-generate session uuids. + * In undo case, we want to re-use existing ones. */ + id->session_uuid = MAIN_ID_SESSION_UUID_UNSET; + } + + BKE_lib_libblock_session_uuid_ensure(id); + + id->lib = current_library; + id->us = ID_FAKE_USERS(id); + id->icon_id = 0; + id->newid = NULL; /* Needed because .blend may have been saved with crap value here... */ + id->orig_id = NULL; + id->py_instance = NULL; + + /* Initialize with provided tag. */ + id->tag = tag; + + if (tag & LIB_TAG_ID_LINK_PLACEHOLDER) { + /* For placeholder we only need to set the tag and properly initialize generic ID fields above, + * no further data to read. */ + return; + } + /*link direct data of ID properties*/ if (id->properties) { id->properties = newdataadr(fd, id->properties); /* this case means the data was written incorrectly, it should not happen */ IDP_DirectLinkGroup_OrFree(&id->properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd); } - id->py_instance = NULL; - /* That way data-lock reading not going through main read_libblock() - * 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; /* NOTE: It is important to not clear the recalc flags for undo/redo. @@ -2820,32 +2929,11 @@ static void direct_link_id(FileData *fd, ID *id, ID *id_old) * the version the file has been saved with. */ if (fd->memfile == NULL) { id->recalc = 0; - id->recalc_undo_accumulated = 0; + id->recalc_after_undo_push = 0; } else if ((fd->skip_flags & BLO_READ_SKIP_UNDO_OLD_MAIN) == 0) { - if (fd->undo_direction < 0) { - /* We are coming from the future (i.e. do an actual undo, and not a redo), and we found an - * old (aka existing) ID: we use its 'accumulated recalc flags since last memfile undo step - * saving' as recalc flags of our newly read ID. */ - if (id_old != NULL) { - id->recalc = id_old->recalc_undo_accumulated; - } - } - else { - /* We are coming from the past (i.e. do a redo), we use saved 'accumulated - * recalc flags since last memfile undo step saving' as recalc flags of our newly read ID. */ - id->recalc = id->recalc_undo_accumulated; - } - /* In any case, we need to flush the depsgraph's CoWs, as even if the ID address itself did not - * change, internal data most likely have. */ - id->recalc |= ID_RECALC_COPY_ON_WRITE; - - /* We need to 'accumulate' the accumulated recalc flags of all undo steps until we actually - * perform a depsgraph update, otherwise we'd only ever use the flags from one of the steps, - * and never get proper flags matching all others. */ - if (id_old != NULL) { - id->recalc_undo_accumulated |= id_old->recalc_undo_accumulated; - } + id->recalc = direct_link_id_restore_recalc(fd, id, id_old, false); + id->recalc_after_undo_push = 0; } /* Link direct data of overrides. */ @@ -2861,7 +2949,7 @@ static void direct_link_id(FileData *fd, ID *id, ID *id_old) } /* Handle 'private IDs'. */ - direct_link_id_private_id(fd, id, id_old); + direct_link_id_embedded_id(fd, current_library, id, id_old); } /** \} */ @@ -2955,6 +3043,19 @@ static void direct_link_brush(FileData *fd, Brush *brush) brush->gpencil_settings->curve_strength); brush->gpencil_settings->curve_jitter = newdataadr(fd, brush->gpencil_settings->curve_jitter); + brush->gpencil_settings->curve_rand_pressure = newdataadr( + fd, brush->gpencil_settings->curve_rand_pressure); + brush->gpencil_settings->curve_rand_strength = newdataadr( + fd, brush->gpencil_settings->curve_rand_strength); + brush->gpencil_settings->curve_rand_uv = newdataadr(fd, + brush->gpencil_settings->curve_rand_uv); + brush->gpencil_settings->curve_rand_hue = newdataadr(fd, + brush->gpencil_settings->curve_rand_hue); + brush->gpencil_settings->curve_rand_saturation = newdataadr( + fd, brush->gpencil_settings->curve_rand_saturation); + brush->gpencil_settings->curve_rand_value = newdataadr( + fd, brush->gpencil_settings->curve_rand_value); + if (brush->gpencil_settings->curve_sensitivity) { direct_link_curvemapping(fd, brush->gpencil_settings->curve_sensitivity); } @@ -2966,6 +3067,30 @@ static void direct_link_brush(FileData *fd, Brush *brush) if (brush->gpencil_settings->curve_jitter) { direct_link_curvemapping(fd, brush->gpencil_settings->curve_jitter); } + + if (brush->gpencil_settings->curve_rand_pressure) { + direct_link_curvemapping(fd, brush->gpencil_settings->curve_rand_pressure); + } + + if (brush->gpencil_settings->curve_rand_strength) { + direct_link_curvemapping(fd, brush->gpencil_settings->curve_rand_strength); + } + + if (brush->gpencil_settings->curve_rand_uv) { + direct_link_curvemapping(fd, brush->gpencil_settings->curve_rand_uv); + } + + if (brush->gpencil_settings->curve_rand_hue) { + direct_link_curvemapping(fd, brush->gpencil_settings->curve_rand_hue); + } + + if (brush->gpencil_settings->curve_rand_saturation) { + direct_link_curvemapping(fd, brush->gpencil_settings->curve_rand_saturation); + } + + if (brush->gpencil_settings->curve_rand_value) { + direct_link_curvemapping(fd, brush->gpencil_settings->curve_rand_value); + } } brush->preview = NULL; @@ -3030,7 +3155,7 @@ static PackedFile *direct_link_packedfile(FileData *fd, PackedFile *oldpf) // XXX deprecated - old animation system static void lib_link_ipo(FileData *fd, Main *UNUSED(bmain), Ipo *ipo) { - for (IpoCurve *icu = ipo->curve.first; icu; icu = icu->next) { + LISTBASE_FOREACH (IpoCurve *, icu, &ipo->curve) { if (icu->driver) { icu->driver->ob = newlibadr(fd, ipo->id.lib, icu->driver->ob); } @@ -3251,7 +3376,7 @@ static void direct_link_fcurves(FileData *fd, ListBase *list) static void lib_link_action(FileData *fd, Main *UNUSED(bmain), bAction *act) { // XXX deprecated - old animation system <<< - for (bActionChannel *chan = act->chanbase.first; chan; chan = chan->next) { + LISTBASE_FOREACH (bActionChannel *, chan, &act->chanbase) { chan->ipo = newlibadr(fd, act->id.lib, chan->ipo); lib_link_constraint_channels(fd, &act->id, &chan->constraintChannels); } @@ -3259,7 +3384,7 @@ static void lib_link_action(FileData *fd, Main *UNUSED(bmain), bAction *act) lib_link_fcurves(fd, &act->id, &act->curves); - for (TimeMarker *marker = act->markers.first; marker; marker = marker->next) { + LISTBASE_FOREACH (TimeMarker *, marker, &act->markers) { if (marker->camera) { marker->camera = newlibadr(fd, act->id.lib, marker->camera); } @@ -3305,11 +3430,6 @@ static void lib_link_nladata_strips(FileData *fd, ID *id, ListBase *list) /* reassign the counted-reference to action */ strip->act = newlibadr(fd, id->lib, strip->act); - - /* fix action id-root (i.e. if it comes from a pre 2.57 .blend file) */ - if ((strip->act) && (strip->act->idroot == 0)) { - strip->act->idroot = GS(id->name); - } } } @@ -3404,14 +3524,6 @@ static void lib_link_animdata(FileData *fd, ID *id, AnimData *adt) adt->action = newlibadr(fd, id->lib, adt->action); adt->tmpact = newlibadr(fd, id->lib, adt->tmpact); - /* fix action id-roots (i.e. if they come from a pre 2.57 .blend file) */ - if ((adt->action) && (adt->action->idroot == 0)) { - adt->action->idroot = GS(id->name); - } - if ((adt->tmpact) && (adt->tmpact->idroot == 0)) { - adt->tmpact->idroot = GS(id->name); - } - /* link drivers */ lib_link_fcurves(fd, id, &adt->drivers); @@ -3482,15 +3594,11 @@ static void direct_link_cachefile(FileData *fd, CacheFile *cache_file) static void lib_link_workspaces(FileData *fd, Main *bmain, WorkSpace *workspace) { - ListBase *layouts = BKE_workspace_layouts_get(workspace); ID *id = (ID *)workspace; - id_us_ensure_real(id); - - for (WorkSpaceLayout *layout = layouts->first, *layout_next; layout; layout = layout_next) { + LISTBASE_FOREACH_MUTABLE (WorkSpaceLayout *, layout, &workspace->layouts) { layout->screen = newlibadr(fd, id->lib, layout->screen); - layout_next = layout->next; if (layout->screen) { if (ID_IS_LINKED(id)) { layout->screen->winid = 0; @@ -3510,39 +3618,34 @@ static void lib_link_workspaces(FileData *fd, Main *bmain, WorkSpace *workspace) static void direct_link_workspace(FileData *fd, WorkSpace *workspace, const Main *main) { - link_list(fd, BKE_workspace_layouts_get(workspace)); + link_list(fd, &workspace->layouts); link_list(fd, &workspace->hook_layout_relations); link_list(fd, &workspace->owner_ids); link_list(fd, &workspace->tools); - for (WorkSpaceDataRelation *relation = workspace->hook_layout_relations.first; relation; - relation = relation->next) { - + LISTBASE_FOREACH (WorkSpaceDataRelation *, relation, &workspace->hook_layout_relations) { /* data from window - need to access through global oldnew-map */ relation->parent = newglobadr(fd, relation->parent); - relation->value = newdataadr(fd, relation->value); } /* Same issue/fix as in direct_link_workspace_link_scene_data: Can't read workspace data * when reading windows, so have to update windows after/when reading workspaces. */ for (wmWindowManager *wm = main->wm.first; wm; wm = wm->id.next) { - for (wmWindow *win = wm->windows.first; win; win = win->next) { - WorkSpaceLayout *act_layout = newdataadr( - fd, BKE_workspace_active_layout_get(win->workspace_hook)); - if (act_layout) { - BKE_workspace_active_layout_set(win->workspace_hook, act_layout); - } + LISTBASE_FOREACH (wmWindow *, win, &wm->windows) { + win->workspace_hook->act_layout = newdataadr(fd, win->workspace_hook->act_layout); } } - for (bToolRef *tref = workspace->tools.first; tref; tref = tref->next) { + LISTBASE_FOREACH (bToolRef *, tref, &workspace->tools) { tref->runtime = NULL; tref->properties = newdataadr(fd, tref->properties); IDP_DirectLinkGroup_OrFree(&tref->properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd); } workspace->status_text = NULL; + + id_us_ensure_real(&workspace->id); } static void lib_link_workspace_instance_hook(FileData *fd, WorkSpaceInstanceHook *hook, ID *id) @@ -3557,6 +3660,45 @@ static void lib_link_workspace_instance_hook(FileData *fd, WorkSpaceInstanceHook /** \name Read ID: Node Tree * \{ */ +static void lib_link_node_socket(FileData *fd, Library *lib, bNodeSocket *sock) +{ + IDP_LibLinkProperty(sock->prop, fd); + + switch ((eNodeSocketDatatype)sock->type) { + case SOCK_OBJECT: { + bNodeSocketValueObject *default_value = sock->default_value; + default_value->value = newlibadr(fd, lib, default_value->value); + break; + } + case SOCK_IMAGE: { + bNodeSocketValueImage *default_value = sock->default_value; + default_value->value = newlibadr(fd, lib, default_value->value); + break; + } + case SOCK_FLOAT: + case SOCK_VECTOR: + case SOCK_RGBA: + case SOCK_BOOLEAN: + case SOCK_INT: + case SOCK_STRING: + case __SOCK_MESH: + case SOCK_CUSTOM: + case SOCK_SHADER: + case SOCK_EMITTERS: + case SOCK_EVENTS: + case SOCK_FORCES: + case SOCK_CONTROL_FLOW: + break; + } +} + +static void lib_link_node_sockets(FileData *fd, Library *lib, ListBase *sockets) +{ + LISTBASE_FOREACH (bNodeSocket *, sock, sockets) { + lib_link_node_socket(fd, lib, sock); + } +} + /* Single node tree (also used for material/scene trees), ntree is not NULL */ static void lib_link_ntree(FileData *fd, Library *lib, bNodeTree *ntree) { @@ -3564,27 +3706,19 @@ static void lib_link_ntree(FileData *fd, Library *lib, bNodeTree *ntree) ntree->gpd = newlibadr(fd, lib, ntree->gpd); - for (bNode *node = ntree->nodes.first; node; node = node->next) { + LISTBASE_FOREACH (bNode *, node, &ntree->nodes) { /* Link ID Properties -- and copy this comment EXACTLY for easy finding * of library blocks that implement this.*/ IDP_LibLinkProperty(node->prop, fd); node->id = newlibadr(fd, lib, node->id); - for (bNodeSocket *sock = node->inputs.first; sock; sock = sock->next) { - IDP_LibLinkProperty(sock->prop, fd); - } - for (bNodeSocket *sock = node->outputs.first; sock; sock = sock->next) { - IDP_LibLinkProperty(sock->prop, fd); - } + lib_link_node_sockets(fd, lib, &node->inputs); + lib_link_node_sockets(fd, lib, &node->outputs); } - for (bNodeSocket *sock = ntree->inputs.first; sock; sock = sock->next) { - IDP_LibLinkProperty(sock->prop, fd); - } - for (bNodeSocket *sock = ntree->outputs.first; sock; sock = sock->next) { - IDP_LibLinkProperty(sock->prop, fd); - } + lib_link_node_sockets(fd, lib, &ntree->inputs); + lib_link_node_sockets(fd, lib, &ntree->outputs); /* Set node->typeinfo pointers. This is done in lib linking, after the * first versioning that can change types still without functions that @@ -3595,7 +3729,7 @@ static void lib_link_ntree(FileData *fd, Library *lib, bNodeTree *ntree) /* For nodes with static socket layout, add/remove sockets as needed * to match the static layout. */ if (fd->memfile == NULL) { - for (bNode *node = ntree->nodes.first; node; node = node->next) { + LISTBASE_FOREACH (bNode *, node, &ntree->nodes) { node_verify_socket_templates(ntree, node); } } @@ -3757,23 +3891,23 @@ static void direct_link_nodetree(FileData *fd, bNodeTree *ntree) } #if 0 - if (ntree->previews) { - bNodeInstanceHash* new_previews = BKE_node_instance_hash_new("node previews"); - bNodeInstanceHashIterator iter; - - NODE_INSTANCE_HASH_ITER(iter, ntree->previews) { - bNodePreview* preview = BKE_node_instance_hash_iterator_get_value(&iter); - if (preview) { - bNodePreview* new_preview = newimaadr(fd, preview); - if (new_preview) { - bNodeInstanceKey key = BKE_node_instance_hash_iterator_get_key(&iter); - BKE_node_instance_hash_insert(new_previews, key, new_preview); - } - } - } - BKE_node_instance_hash_free(ntree->previews, NULL); - ntree->previews = new_previews; - } + if (ntree->previews) { + bNodeInstanceHash* new_previews = BKE_node_instance_hash_new("node previews"); + bNodeInstanceHashIterator iter; + + NODE_INSTANCE_HASH_ITER(iter, ntree->previews) { + bNodePreview* preview = BKE_node_instance_hash_iterator_get_value(&iter); + if (preview) { + bNodePreview* new_preview = newimaadr(fd, preview); + if (new_preview) { + bNodeInstanceKey key = BKE_node_instance_hash_iterator_get_key(&iter); + BKE_node_instance_hash_insert(new_previews, key, new_preview); + } + } + } + BKE_node_instance_hash_free(ntree->previews, NULL); + ntree->previews = new_previews; + } #else /* XXX TODO */ ntree->previews = NULL; @@ -3796,20 +3930,11 @@ typedef struct tConstraintLinkData { /* callback function used to relink constraint ID-links */ static void lib_link_constraint_cb(bConstraint *UNUSED(con), ID **idpoin, - bool is_reference, + bool UNUSED(is_reference), void *userdata) { tConstraintLinkData *cld = (tConstraintLinkData *)userdata; - - /* for reference types, we need to increment the user-counts on load... */ - if (is_reference) { - /* reference type - with usercount */ - *idpoin = newlibadr(cld->fd, cld->id->lib, *idpoin); - } - else { - /* target type - no usercount needed */ - *idpoin = newlibadr(cld->fd, cld->id->lib, *idpoin); - } + *idpoin = newlibadr(cld->fd, cld->id->lib, *idpoin); } static void lib_link_constraints(FileData *fd, ID *id, ListBase *conlist) @@ -3929,7 +4054,7 @@ static void lib_link_pose(FileData *fd, Main *bmain, Object *ob, bPose *pose) } } - for (bPoseChannel *pchan = pose->chanbase.first; pchan; pchan = pchan->next) { + LISTBASE_FOREACH (bPoseChannel *, pchan, &pose->chanbase) { lib_link_constraints(fd, (ID *)ob, &pchan->constraints); pchan->bone = BKE_armature_find_bone_name(arm, pchan->name); @@ -3958,14 +4083,14 @@ static void lib_link_bones(FileData *fd, Bone *bone) { IDP_LibLinkProperty(bone->prop, fd); - for (Bone *curbone = bone->childbase.first; curbone; curbone = curbone->next) { + LISTBASE_FOREACH (Bone *, curbone, &bone->childbase) { lib_link_bones(fd, curbone); } } static void lib_link_armature(FileData *fd, Main *UNUSED(bmain), bArmature *arm) { - for (Bone *curbone = arm->bonebase.first; curbone; curbone = curbone->next) { + LISTBASE_FOREACH (Bone *, curbone, &arm->bonebase) { lib_link_bones(fd, curbone); } } @@ -4026,7 +4151,7 @@ static void lib_link_camera(FileData *fd, Main *UNUSED(bmain), Camera *ca) ca->dof_ob = newlibadr(fd, ca->id.lib, ca->dof_ob); /* deprecated, for versioning */ ca->dof.focus_object = newlibadr(fd, ca->id.lib, ca->dof.focus_object); - for (CameraBGImage *bgpic = ca->bg_images.first; bgpic; bgpic = bgpic->next) { + LISTBASE_FOREACH (CameraBGImage *, bgpic, &ca->bg_images) { bgpic->ima = newlibadr(fd, ca->id.lib, bgpic->ima); bgpic->clip = newlibadr(fd, ca->id.lib, bgpic->clip); } @@ -4039,7 +4164,7 @@ static void direct_link_camera(FileData *fd, Camera *ca) link_list(fd, &ca->bg_images); - for (CameraBGImage *bgpic = ca->bg_images.first; bgpic; bgpic = bgpic->next) { + LISTBASE_FOREACH (CameraBGImage *, bgpic, &ca->bg_images) { bgpic->iuser.ok = 1; bgpic->iuser.scene = NULL; } @@ -4232,10 +4357,10 @@ static void direct_link_text(FileData *fd, Text *text) text->compiled = NULL; #if 0 - if (text->flags & TXT_ISEXT) { - BKE_text_reload(text); - } - /* else { */ + if (text->flags & TXT_ISEXT) { + BKE_text_reload(text); + } + /* else { */ #endif link_list(fd, &text->lines); @@ -4614,7 +4739,7 @@ static void lib_link_particlesettings(FileData *fd, Main *UNUSED(bmain), Particl } if (part->instance_weights.first && part->instance_collection) { - for (ParticleDupliWeight *dw = part->instance_weights.first; dw; dw = dw->next) { + LISTBASE_FOREACH (ParticleDupliWeight *, dw, &part->instance_weights) { dw->ob = newlibadr(fd, part->id.lib, dw->ob); } } @@ -4745,7 +4870,7 @@ static void lib_link_particlesystems(FileData *fd, Object *ob, ID *id, ListBase /* particle modifier must be removed before particle system */ ParticleSystemModifierData *psmd = psys_get_modifier(ob, psys); BLI_remlink(&ob->modifiers, psmd); - modifier_free((ModifierData *)psmd); + BKE_modifier_free((ModifierData *)psmd); BLI_remlink(particles, psys); MEM_freeN(psys); @@ -5114,7 +5239,7 @@ static void lib_link_modifiers_common(void *userData, Object *ob, ID **idpoin, i static void lib_link_modifiers(FileData *fd, Object *ob) { - modifiers_foreachIDLink(ob, lib_link_modifiers_common, fd); + BKE_modifiers_foreach_ID_link(ob, lib_link_modifiers_common, fd); /* If linking from a library, clear 'local' library override flag. */ if (ob->id.lib != NULL) { @@ -5126,7 +5251,7 @@ static void lib_link_modifiers(FileData *fd, Object *ob) static void lib_link_gpencil_modifiers(FileData *fd, Object *ob) { - BKE_gpencil_modifiers_foreachIDLink(ob, lib_link_modifiers_common, fd); + BKE_gpencil_modifiers_foreach_ID_link(ob, lib_link_modifiers_common, fd); /* If linking from a library, clear 'local' library override flag. */ if (ob->id.lib != NULL) { @@ -5139,7 +5264,7 @@ static void lib_link_gpencil_modifiers(FileData *fd, Object *ob) static void lib_link_shaderfxs(FileData *fd, Object *ob) { - BKE_shaderfx_foreachIDLink(ob, lib_link_modifiers_common, fd); + BKE_shaderfx_foreach_ID_link(ob, lib_link_modifiers_common, fd); /* If linking from a library, clear 'local' library override flag. */ if (ob->id.lib != NULL) { @@ -5223,7 +5348,7 @@ static void lib_link_object(FileData *fd, Main *bmain, Object *ob) * some leaked memory rather then crashing immediately * while bad this _is_ an exceptional case - campbell */ #if 0 - BKE_pose_free(ob->pose); + BKE_pose_free(ob->pose); #else MEM_freeN(ob->pose); #endif @@ -5259,14 +5384,14 @@ static void lib_link_object(FileData *fd, Main *bmain, Object *ob) lib_link_nlastrips(fd, &ob->id, &ob->nlastrips); // >>> XXX deprecated - old animation system - for (PartEff *paf = ob->effect.first; paf; paf = paf->next) { + LISTBASE_FOREACH (PartEff *, paf, &ob->effect) { if (paf->type == EFF_PARTICLE) { paf->group = newlibadr(fd, ob->id.lib, paf->group); } } { - FluidsimModifierData *fluidmd = (FluidsimModifierData *)modifiers_findByType( + FluidsimModifierData *fluidmd = (FluidsimModifierData *)BKE_modifiers_findby_type( ob, eModifierType_Fluidsim); if (fluidmd && fluidmd->fss) { @@ -5276,12 +5401,19 @@ static void lib_link_object(FileData *fd, Main *bmain, Object *ob) } { - FluidModifierData *mmd = (FluidModifierData *)modifiers_findByType(ob, eModifierType_Fluid); + FluidModifierData *mmd = (FluidModifierData *)BKE_modifiers_findby_type(ob, + eModifierType_Fluid); if (mmd && (mmd->type == MOD_FLUID_TYPE_DOMAIN) && mmd->domain) { /* Flag for refreshing the simulation after loading */ mmd->domain->flags |= FLUID_DOMAIN_FILE_LOAD; } + else if (mmd && (mmd->type == MOD_FLUID_TYPE_FLOW) && mmd->flow) { + mmd->flow->flags &= ~FLUID_FLOW_NEEDS_UPDATE; + } + else if (mmd && (mmd->type == MOD_FLUID_TYPE_EFFEC) && mmd->effector) { + mmd->effector->flags &= ~FLUID_EFFECTOR_NEEDS_UPDATE; + } } /* texture field */ @@ -5412,7 +5544,7 @@ static ModifierData *modifier_replace_with_fluid(FileData *fd, ListBase *modifiers, ModifierData *old_modifier_data) { - ModifierData *new_modifier_data = modifier_new(eModifierType_Fluid); + ModifierData *new_modifier_data = BKE_modifier_new(eModifierType_Fluid); FluidModifierData *fluid_modifier_data = (FluidModifierData *)new_modifier_data; if (old_modifier_data->type == eModifierType_Fluidsim) { @@ -5535,7 +5667,7 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb, Object *ob) is_allocated = true; } /* if modifiers disappear, or for upward compatibility */ - if (NULL == modifierType_getInfo(md->type)) { + if (NULL == BKE_modifier_get_info(md->type)) { md->type = eModifierType_None; } @@ -5693,15 +5825,15 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb, Object *ob) else if (md->type == eModifierType_Collision) { CollisionModifierData *collmd = (CollisionModifierData *)md; #if 0 - // TODO: CollisionModifier should use pointcache - // + have proper reset events before enabling this - collmd->x = newdataadr(fd, collmd->x); - collmd->xnew = newdataadr(fd, collmd->xnew); - collmd->mfaces = newdataadr(fd, collmd->mfaces); - - collmd->current_x = MEM_calloc_arrayN(collmd->numverts, sizeof(MVert), "current_x"); - collmd->current_xnew = MEM_calloc_arrayN(collmd->numverts, sizeof(MVert), "current_xnew"); - collmd->current_v = MEM_calloc_arrayN(collmd->numverts, sizeof(MVert), "current_v"); + // TODO: CollisionModifier should use pointcache + // + have proper reset events before enabling this + collmd->x = newdataadr(fd, collmd->x); + collmd->xnew = newdataadr(fd, collmd->xnew); + collmd->mfaces = newdataadr(fd, collmd->mfaces); + + collmd->current_x = MEM_calloc_arrayN(collmd->numverts, sizeof(MVert), "current_x"); + collmd->current_xnew = MEM_calloc_arrayN(collmd->numverts, sizeof(MVert), "current_xnew"); + collmd->current_v = MEM_calloc_arrayN(collmd->numverts, sizeof(MVert), "current_v"); #endif collmd->x = NULL; @@ -5889,7 +6021,7 @@ static void direct_link_gpencil_modifiers(FileData *fd, ListBase *lb) md->error = NULL; /* if modifiers disappear, or for upward compatibility */ - if (NULL == BKE_gpencil_modifierType_getInfo(md->type)) { + if (NULL == BKE_gpencil_modifier_get_info(md->type)) { md->type = eModifierType_None; } @@ -5970,7 +6102,7 @@ static void direct_link_shaderfxs(FileData *fd, ListBase *lb) fx->error = NULL; /* if shader disappear, or for upward compatibility */ - if (NULL == BKE_shaderfxType_getInfo(fx->type)) { + if (NULL == BKE_shaderfx_get_info(fx->type)) { fx->type = eShaderFxType_None; } } @@ -6033,7 +6165,7 @@ static void direct_link_object(FileData *fd, Object *ob) if (paf->type == EFF_WAVE) { WaveEff *wav = (WaveEff *)paf; PartEff *next = paf->next; - WaveModifierData *wmd = (WaveModifierData *)modifier_new(eModifierType_Wave); + WaveModifierData *wmd = (WaveModifierData *)BKE_modifier_new(eModifierType_Wave); wmd->damp = wav->damp; wmd->flag = wav->flag; @@ -6057,7 +6189,7 @@ static void direct_link_object(FileData *fd, Object *ob) if (paf->type == EFF_BUILD) { BuildEff *baf = (BuildEff *)paf; PartEff *next = paf->next; - BuildModifierData *bmd = (BuildModifierData *)modifier_new(eModifierType_Build); + BuildModifierData *bmd = (BuildModifierData *)BKE_modifier_new(eModifierType_Build); bmd->start = baf->sfra; bmd->length = baf->len; @@ -6134,7 +6266,7 @@ static void direct_link_object(FileData *fd, Object *ob) link_list(fd, &ob->hooks); while (ob->hooks.first) { ObHook *hook = ob->hooks.first; - HookModifierData *hmd = (HookModifierData *)modifier_new(eModifierType_Hook); + HookModifierData *hmd = (HookModifierData *)BKE_modifier_new(eModifierType_Hook); hook->indexar = newdataadr(fd, hook->indexar); if (fd->flags & FD_FLAGS_SWITCH_ENDIAN) { @@ -6156,7 +6288,7 @@ static void direct_link_object(FileData *fd, Object *ob) BLI_addhead(&ob->modifiers, hmd); BLI_remlink(&ob->hooks, hook); - modifier_unique_name(&ob->modifiers, (ModifierData *)hmd); + BKE_modifier_unique_name(&ob->modifiers, (ModifierData *)hmd); MEM_freeN(hook); } @@ -6204,7 +6336,7 @@ static void direct_link_view_settings(FileData *fd, ColorManagedViewSettings *vi static void direct_link_layer_collections(FileData *fd, ListBase *lb, bool master) { link_list(fd, lb); - for (LayerCollection *lc = lb->first; lc; lc = lc->next) { + LISTBASE_FOREACH (LayerCollection *, lc, lb) { #ifdef USE_COLLECTION_COMPAT_28 lc->scene_collection = newdataadr(fd, lc->scene_collection); #endif @@ -6257,12 +6389,11 @@ static void lib_link_layer_collection(FileData *fd, static void lib_link_view_layer(FileData *fd, Library *lib, ViewLayer *view_layer) { - for (FreestyleModuleConfig *fmc = view_layer->freestyle_config.modules.first; fmc; - fmc = fmc->next) { + LISTBASE_FOREACH (FreestyleModuleConfig *, fmc, &view_layer->freestyle_config.modules) { fmc->script = newlibadr(fd, lib, fmc->script); } - for (FreestyleLineSet *fls = view_layer->freestyle_config.linesets.first; fls; fls = fls->next) { + LISTBASE_FOREACH (FreestyleLineSet *, fls, &view_layer->freestyle_config.linesets) { fls->linestyle = newlibadr(fd, lib, fls->linestyle); fls->group = newlibadr(fd, lib, fls->group); } @@ -6305,19 +6436,19 @@ static void direct_link_scene_collection(FileData *fd, SceneCollection *sc) link_list(fd, &sc->objects); link_list(fd, &sc->scene_collections); - for (SceneCollection *nsc = sc->scene_collections.first; nsc; nsc = nsc->next) { + LISTBASE_FOREACH (SceneCollection *, nsc, &sc->scene_collections) { direct_link_scene_collection(fd, nsc); } } static void lib_link_scene_collection(FileData *fd, Library *lib, SceneCollection *sc) { - for (LinkData *link = sc->objects.first; link; link = link->next) { + LISTBASE_FOREACH (LinkData *, link, &sc->objects) { link->data = newlibadr(fd, lib, link->data); BLI_assert(link->data); } - for (SceneCollection *nsc = sc->scene_collections.first; nsc; nsc = nsc->next) { + LISTBASE_FOREACH (SceneCollection *, nsc, &sc->scene_collections) { lib_link_scene_collection(fd, lib, nsc); } } @@ -6625,7 +6756,7 @@ static void lib_link_scene(FileData *fd, Main *UNUSED(bmain), Scene *sce) } SEQ_END; - for (TimeMarker *marker = sce->markers.first; marker; marker = marker->next) { + LISTBASE_FOREACH (TimeMarker *, marker, &sce->markers) { if (marker->camera) { marker->camera = newlibadr(fd, sce->id.lib, marker->camera); } @@ -6649,12 +6780,12 @@ static void lib_link_scene(FileData *fd, Main *UNUSED(bmain), Scene *sce) composite_patch(sce->nodetree, sce); } - for (SceneRenderLayer *srl = sce->r.layers.first; srl; srl = srl->next) { + LISTBASE_FOREACH (SceneRenderLayer *, srl, &sce->r.layers) { srl->mat_override = newlibadr(fd, sce->id.lib, srl->mat_override); - for (FreestyleModuleConfig *fmc = srl->freestyleConfig.modules.first; fmc; fmc = fmc->next) { + LISTBASE_FOREACH (FreestyleModuleConfig *, fmc, &srl->freestyleConfig.modules) { fmc->script = newlibadr(fd, sce->id.lib, fmc->script); } - for (FreestyleLineSet *fls = srl->freestyleConfig.linesets.first; fls; fls = fls->next) { + LISTBASE_FOREACH (FreestyleLineSet *, fls, &srl->freestyleConfig.linesets) { fls->linestyle = newlibadr(fd, sce->id.lib, fls->linestyle); fls->group = newlibadr(fd, sce->id.lib, fls->group); } @@ -6668,7 +6799,7 @@ static void lib_link_scene(FileData *fd, Main *UNUSED(bmain), Scene *sce) } #endif - for (ViewLayer *view_layer = sce->view_layers.first; view_layer; view_layer = view_layer->next) { + LISTBASE_FOREACH (ViewLayer *, view_layer, &sce->view_layers) { lib_link_view_layer(fd, sce->id.lib, view_layer); } @@ -6825,7 +6956,6 @@ static void direct_link_scene(FileData *fd, Scene *sce) direct_link_paint(fd, sce, &sce->toolsettings->imapaint.paint); - sce->toolsettings->imapaint.paintcursor = NULL; sce->toolsettings->particle.paintcursor = NULL; sce->toolsettings->particle.scene = NULL; sce->toolsettings->particle.object = NULL; @@ -7199,11 +7329,11 @@ static void direct_link_panel_list(FileData *fd, ListBase *lb) { link_list(fd, lb); - for (Panel *pa = lb->first; pa; pa = pa->next) { - pa->runtime_flag = 0; - pa->activedata = NULL; - pa->type = NULL; - direct_link_panel_list(fd, &pa->children); + LISTBASE_FOREACH (Panel *, panel, lb) { + panel->runtime_flag = 0; + panel->activedata = NULL; + panel->type = NULL; + direct_link_panel_list(fd, &panel->children); } } @@ -7408,10 +7538,10 @@ static void direct_link_area(FileData *fd, ScrArea *area) * so sacrifice a few old files for now to avoid crashes with new files! * committed: r28002 */ #if 0 - sima->gpd = newdataadr(fd, sima->gpd); - if (sima->gpd) { - direct_link_gpencil(fd, sima->gpd); - } + sima->gpd = newdataadr(fd, sima->gpd); + if (sima->gpd) { + direct_link_gpencil(fd, sima->gpd); + } #endif } else if (sl->spacetype == SPACE_NODE) { @@ -7442,10 +7572,10 @@ static void direct_link_area(FileData *fd, ScrArea *area) * simple return NULL here (sergey) */ #if 0 - if (sseq->gpd) { - sseq->gpd = newdataadr(fd, sseq->gpd); - direct_link_gpencil(fd, sseq->gpd); - } + if (sseq->gpd) { + sseq->gpd = newdataadr(fd, sseq->gpd); + direct_link_gpencil(fd, sseq->gpd); + } #endif sseq->scopes.reference_ibuf = NULL; sseq->scopes.zebra_ibuf = NULL; @@ -7524,7 +7654,7 @@ static void lib_link_area(FileData *fd, ID *parent_id, ScrArea *area) memset(&area->runtime, 0x0, sizeof(area->runtime)); - for (SpaceLink *sl = area->spacedata.first; sl; sl = sl->next) { + LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) { switch (sl->spacetype) { case SPACE_VIEW3D: { View3D *v3d = (View3D *)sl; @@ -7701,12 +7831,12 @@ static bool direct_link_area_map(FileData *fd, ScrAreaMap *area_map) link_list(fd, &area_map->vertbase); link_list(fd, &area_map->edgebase); link_list(fd, &area_map->areabase); - for (ScrArea *area = area_map->areabase.first; area; area = area->next) { + LISTBASE_FOREACH (ScrArea *, area, &area_map->areabase) { direct_link_area(fd, area); } /* edges */ - for (ScrEdge *se = area_map->edgebase.first; se; se = se->next) { + LISTBASE_FOREACH (ScrEdge *, se, &area_map->edgebase) { se->v1 = newdataadr(fd, se->v1); se->v2 = newdataadr(fd, se->v2); BKE_screen_sort_scrvert(&se->v1, &se->v2); @@ -7823,7 +7953,7 @@ static void direct_link_windowmanager(FileData *fd, wmWindowManager *wm) static void lib_link_windowmanager(FileData *fd, Main *UNUSED(bmain), wmWindowManager *wm) { - for (wmWindow *win = wm->windows.first; win; win = win->next) { + LISTBASE_FOREACH (wmWindow *, win, &wm->windows) { if (win->workspace_hook) { /* NULL for old files */ lib_link_workspace_instance_hook(fd, win->workspace_hook, &wm->id); } @@ -7831,7 +7961,7 @@ static void lib_link_windowmanager(FileData *fd, Main *UNUSED(bmain), wmWindowMa /* deprecated, but needed for versioning (will be NULL'ed then) */ win->screen = newlibadr(fd, NULL, win->screen); - for (ScrArea *area = win->global_areas.areabase.first; area; area = area->next) { + LISTBASE_FOREACH (ScrArea *, area, &win->global_areas.areabase) { lib_link_area(fd, &wm->id, area); } @@ -7847,17 +7977,17 @@ static void lib_link_windowmanager(FileData *fd, Main *UNUSED(bmain), wmWindowMa /* note: file read without screens option G_FILE_NO_UI; * check lib pointers in call below */ -static void lib_link_screen(FileData *fd, Main *UNUSED(bmain), bScreen *sc) +static void lib_link_screen(FileData *fd, Main *UNUSED(bmain), bScreen *screen) { /* deprecated, but needed for versioning (will be NULL'ed then) */ - sc->scene = newlibadr(fd, sc->id.lib, sc->scene); + screen->scene = newlibadr(fd, screen->id.lib, screen->scene); - sc->animtimer = NULL; /* saved in rare cases */ - sc->tool_tip = NULL; - sc->scrubbing = false; + screen->animtimer = NULL; /* saved in rare cases */ + screen->tool_tip = NULL; + screen->scrubbing = false; - for (ScrArea *area = sc->areabase.first; area; area = area->next) { - lib_link_area(fd, &sc->id, area); + LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { + lib_link_area(fd, &screen->id, area); } } @@ -8010,8 +8140,8 @@ static void lib_link_window_scene_data_restore(wmWindow *win, Scene *scene, View { bScreen *screen = BKE_workspace_active_screen_get(win->workspace_hook); - for (ScrArea *area = screen->areabase.first; area; area = area->next) { - for (SpaceLink *sl = area->spacedata.first; sl; sl = sl->next) { + LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { + LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) { if (sl->spacetype == SPACE_VIEW3D) { View3D *v3d = (View3D *)sl; @@ -8039,7 +8169,7 @@ static void lib_link_window_scene_data_restore(wmWindow *win, Scene *scene, View /* Regionbase storage is different depending if the space is active. */ ListBase *regionbase = (sl == area->spacedata.first) ? &area->regionbase : &sl->regionbase; - for (ARegion *region = regionbase->first; region; region = region->next) { + LISTBASE_FOREACH (ARegion *, region, regionbase) { if (region->regiontype == RGN_TYPE_WINDOW) { RegionView3D *rv3d = region->regiondata; if (rv3d->localvd) { @@ -8063,26 +8193,13 @@ static void lib_link_workspace_layout_restore(struct IDNameLib_Map *id_map, /* avoid conflicts with 2.8x branch */ { - for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) { - for (SpaceLink *sl = sa->spacedata.first; sl; sl = sl->next) { + LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { + LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) { if (sl->spacetype == SPACE_VIEW3D) { View3D *v3d = (View3D *)sl; - ARegion *region; v3d->camera = restore_pointer_by_name(id_map, (ID *)v3d->camera, USER_REAL); v3d->ob_center = restore_pointer_by_name(id_map, (ID *)v3d->ob_center, USER_REAL); - - /* Free render engines for now. */ - ListBase *regionbase = (sl == sa->spacedata.first) ? &sa->regionbase : &sl->regionbase; - for (region = regionbase->first; region; region = region->next) { - if (region->regiontype == RGN_TYPE_WINDOW) { - RegionView3D *rv3d = region->regiondata; - if (rv3d && rv3d->render_engine) { - RE_engine_free(rv3d->render_engine); - rv3d->render_engine = NULL; - } - } - } } else if (sl->spacetype == SPACE_GRAPH) { SpaceGraph *sipo = (SpaceGraph *)sl; @@ -8145,11 +8262,11 @@ static void lib_link_workspace_layout_restore(struct IDNameLib_Map *id_map, sima->iuser.scene = NULL; #if 0 - /* Those are allocated and freed by space code, no need to handle them here. */ - MEM_SAFE_FREE(sima->scopes.waveform_1); - MEM_SAFE_FREE(sima->scopes.waveform_2); - MEM_SAFE_FREE(sima->scopes.waveform_3); - MEM_SAFE_FREE(sima->scopes.vecscope); + /* Those are allocated and freed by space code, no need to handle them here. */ + MEM_SAFE_FREE(sima->scopes.waveform_1); + MEM_SAFE_FREE(sima->scopes.waveform_2); + MEM_SAFE_FREE(sima->scopes.waveform_3); + MEM_SAFE_FREE(sima->scopes.vecscope); #endif sima->scopes.ok = 0; @@ -8194,7 +8311,7 @@ static void lib_link_workspace_layout_restore(struct IDNameLib_Map *id_map, scpt->script = restore_pointer_by_name(id_map, (ID *)scpt->script, USER_REAL); - /*sc->script = NULL; - 2.45 set to null, better re-run the script */ + /*screen->script = NULL; - 2.45 set to null, better re-run the script */ if (scpt->script) { SCRIPT_SET_NULL(scpt->script); } @@ -8300,14 +8417,12 @@ void blo_lib_link_restore(Main *oldmain, for (WorkSpace *workspace = newmain->workspaces.first; workspace; workspace = workspace->id.next) { - ListBase *layouts = BKE_workspace_layouts_get(workspace); - - for (WorkSpaceLayout *layout = layouts->first; layout; layout = layout->next) { + LISTBASE_FOREACH (WorkSpaceLayout *, layout, &workspace->layouts) { lib_link_workspace_layout_restore(id_map, newmain, layout); } } - for (wmWindow *win = curwm->windows.first; win; win = win->next) { + LISTBASE_FOREACH (wmWindow *, win, &curwm->windows) { WorkSpace *workspace = BKE_workspace_active_get(win->workspace_hook); ID *workspace_id = (ID *)workspace; Scene *oldscene = win->scene; @@ -8377,22 +8492,22 @@ void blo_do_versions_view3d_split_250(View3D *v3d, ListBase *regions) } } -static bool direct_link_screen(FileData *fd, bScreen *sc) +static bool direct_link_screen(FileData *fd, bScreen *screen) { - bool wrong_id = false; + bool success = true; - sc->regionbase.first = sc->regionbase.last = NULL; - sc->context = NULL; - sc->active_region = NULL; + screen->regionbase.first = screen->regionbase.last = NULL; + screen->context = NULL; + screen->active_region = NULL; - sc->preview = direct_link_preview_image(fd, sc->preview); + screen->preview = direct_link_preview_image(fd, screen->preview); - if (!direct_link_area_map(fd, AREAMAP_FROM_SCREEN(sc))) { - printf("Error reading Screen %s... removing it.\n", sc->id.name + 2); - wrong_id = true; + if (!direct_link_area_map(fd, AREAMAP_FROM_SCREEN(screen))) { + printf("Error reading Screen %s... removing it.\n", screen->id.name + 2); + success = false; } - return wrong_id; + return success; } /** \} */ @@ -8437,7 +8552,7 @@ static void direct_link_library(FileData *fd, Library *lib, Main *main) /* make sure we have full path in lib->filepath */ BLI_strncpy(lib->filepath, lib->name, sizeof(lib->name)); - BLI_cleanup_path(fd->relabase, lib->filepath); + BLI_path_normalize(fd->relabase, lib->filepath); // printf("direct_link_library: name %s\n", lib->name); // printf("direct_link_library: filepath %s\n", lib->filepath); @@ -8450,11 +8565,12 @@ static void direct_link_library(FileData *fd, Library *lib, Main *main) newmain->curlib = lib; lib->parent = NULL; + + id_us_ensure_real(&lib->id); } -static void lib_link_library(FileData *UNUSED(fd), Main *UNUSED(bmain), Library *lib) +static void lib_link_library(FileData *UNUSED(fd), Main *UNUSED(bmain), Library *UNUSED(lib)) { - id_us_ensure_real(&lib->id); } /* Always call this once you have loaded new library data to set the relative paths correctly @@ -8522,8 +8638,8 @@ static void direct_link_speaker(FileData *fd, Speaker *spk) direct_link_animdata(fd, spk->adt); #if 0 - spk->sound = newdataadr(fd, spk->sound); - direct_link_sound(fd, spk->sound); + spk->sound = newdataadr(fd, spk->sound); + direct_link_sound(fd, spk->sound); #endif } @@ -8685,7 +8801,7 @@ static void lib_link_movieclip(FileData *fd, Main *UNUSED(bmain), MovieClip *cli lib_link_movieTracks(fd, clip, &tracking->tracks); lib_link_moviePlaneTracks(fd, clip, &tracking->plane_tracks); - for (MovieTrackingObject *object = tracking->objects.first; object; object = object->next) { + LISTBASE_FOREACH (MovieTrackingObject *, object, &tracking->objects) { lib_link_movieTracks(fd, clip, &object->tracks); lib_link_moviePlaneTracks(fd, clip, &object->plane_tracks); } @@ -8762,7 +8878,7 @@ static void lib_link_mask_parent(FileData *fd, Mask *mask, MaskParent *parent) static void lib_link_mask(FileData *fd, Main *UNUSED(bmain), Mask *mask) { - for (MaskLayer *masklay = mask->masklayers.first; masklay; masklay = masklay->next) { + LISTBASE_FOREACH (MaskLayer *, masklay, &mask->masklayers) { MaskSpline *spline; spline = masklay->splines.first; @@ -9107,6 +9223,24 @@ static void direct_link_volume(FileData *fd, Volume *volume) /** \} */ /* -------------------------------------------------------------------- */ +/** \name Read ID: Simulation + * \{ */ + +static void lib_link_simulation(FileData *UNUSED(fd), + Main *UNUSED(main), + Simulation *UNUSED(simulation)) +{ +} + +static void direct_link_simulation(FileData *fd, Simulation *simulation) +{ + simulation->adt = newdataadr(fd, simulation->adt); + direct_link_animdata(fd, simulation->adt); +} + +/** \} */ + +/* -------------------------------------------------------------------- */ /** \name Read Library Data Block * \{ */ @@ -9224,328 +9358,33 @@ static const char *dataname(short id_code) return "Data from PT"; case ID_VO: return "Data from VO"; + case ID_SIM: + return "Data from SIM"; } return "Data from Lib Block"; } -static BHead *read_data_into_oldnewmap(FileData *fd, BHead *bhead, const char *allocname) +static bool direct_link_id(FileData *fd, Main *main, const int tag, ID *id, ID *id_old) { - bhead = blo_bhead_next(fd, bhead); - - while (bhead && bhead->code == DATA) { - void *data; -#if 0 - /* XXX DUMB DEBUGGING OPTION TO GIVE NAMES for guarded malloc errors */ - short* sp = fd->filesdna->structs[bhead->SDNAnr]; - char* tmp = malloc(100); - allocname = fd->filesdna->types[sp[0]]; - strcpy(tmp, allocname); - data = read_struct(fd, bhead, tmp); -#else - data = read_struct(fd, bhead, allocname); -#endif - - if (data) { - oldnewmap_insert(fd->datamap, bhead->old, data, 0); - } + /* Read part of datablock that is common between real and embedded datablocks. */ + direct_link_id_common(fd, main->curlib, id, id_old, tag); - bhead = blo_bhead_next(fd, bhead); + if (tag & LIB_TAG_ID_LINK_PLACEHOLDER) { + /* For placeholder we only need to set the tag, no further data to read. */ + id->tag = tag; + return true; } - return bhead; -} - -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 - */ - ID *id; - ListBase *lb; - const char *allocname; - - /* XXX Very weakly handled currently, see comment at the end of this function before trying to + /* XXX Very weakly handled currently, see comment in read_libblock() before trying to * use it for anything new. */ - bool wrong_id = false; - - /* In undo case, most libs and linked data should be kept as is from previous state - * (see BLO_read_from_memfile). - * However, some needed by the snapshot being read may have been removed in previous one, - * and would go missing. - * This leads e.g. to disappearing objects in some undo/redo case, see T34446. - * That means we have to carefully check whether current lib or - * libdata already exits in old main, if it does we merely copy it over into new main area, - * otherwise we have to do a full read of that bhead... */ - if (fd->memfile && ELEM(bhead->code, ID_LI, ID_LINK_PLACEHOLDER)) { - const char *idname = blo_bhead_id_name(fd, bhead); - - DEBUG_PRINTF("Checking %s...\n", idname); - - if (bhead->code == ID_LI) { - Main *libmain = fd->old_mainlist->first; - /* Skip oldmain itself... */ - for (libmain = libmain->next; libmain; libmain = libmain->next) { - DEBUG_PRINTF("... against %s: ", libmain->curlib ? libmain->curlib->id.name : "<NULL>"); - if (libmain->curlib && STREQ(idname, libmain->curlib->id.name)) { - Main *oldmain = fd->old_mainlist->first; - DEBUG_PRINTF("FOUND!\n"); - /* In case of a library, we need to re-add its main to fd->mainlist, - * because if we have later a missing ID_LINK_PLACEHOLDER, - * we need to get the correct lib it is linked to! - * Order is crucial, we cannot bulk-add it in BLO_read_from_memfile() - * like it used to be. */ - BLI_remlink(fd->old_mainlist, libmain); - BLI_remlink_safe(&oldmain->libraries, libmain->curlib); - BLI_addtail(fd->mainlist, libmain); - BLI_addtail(&main->libraries, libmain->curlib); - - if (r_id) { - *r_id = NULL; /* Just in case... */ - } - return blo_bhead_next(fd, bhead); - } - DEBUG_PRINTF("nothing...\n"); - } - } - else { - DEBUG_PRINTF("... in %s (%s): ", - main->curlib ? main->curlib->id.name : "<NULL>", - main->curlib ? main->curlib->name : "<NULL>"); - if ((id = BKE_libblock_find_name(main, GS(idname), idname + 2))) { - DEBUG_PRINTF("FOUND!\n"); - /* Even though we found our linked ID, - * there is no guarantee its address is still the same. */ - if (id != bhead->old) { - oldnewmap_insert(fd->libmap, bhead->old, id, GS(id->name)); - } - - /* No need to do anything else for ID_LINK_PLACEHOLDER, - * it's assumed already present in its lib's main. */ - if (r_id) { - *r_id = NULL; /* Just in case... */ - } - return blo_bhead_next(fd, bhead); - } - DEBUG_PRINTF("nothing...\n"); - } - } - - /* read libblock */ - fd->are_memchunks_identical = true; - id = read_struct(fd, bhead, "lib block"); - const short idcode = id != NULL ? GS(id->name) : 0; - - BHead *id_bhead = bhead; - /* Used when undoing from memfile, we swap changed IDs into their old addresses when found. */ - ID *id_old = NULL; - bool do_id_swap = false; - - if (id != NULL) { - const bool do_partial_undo = (fd->skip_flags & BLO_READ_SKIP_UNDO_OLD_MAIN) == 0; - - if (id_bhead->code != ID_LINK_PLACEHOLDER) { - /* need a name for the mallocN, just for debugging and sane prints on leaks */ - allocname = dataname(idcode); - - /* read all data into fd->datamap */ - /* TODO: instead of building oldnewmap here we could just quickly check the bheads... could - * save some more ticks. Probably not worth it though, bottleneck is full depsgraph rebuild - * and evaluate, not actual file reading. */ - bhead = read_data_into_oldnewmap(fd, id_bhead, allocname); - - DEBUG_PRINTF( - "%s: ID %s is unchanged: %d\n", __func__, id->name, fd->are_memchunks_identical); - - if (fd->memfile != NULL) { - BLI_assert(fd->old_idmap != NULL || !do_partial_undo); - /* This code should only ever be reached for local data-blocks. */ - BLI_assert(main->curlib == NULL); - - /* Find the 'current' existing ID we want to reuse instead of the one we would read from - * the undo memfile. */ - DEBUG_PRINTF("\t Looking for ID %s with uuid %u instead of newly read one\n", - id->name, - id->session_uuid); - id_old = do_partial_undo ? BKE_main_idmap_lookup_uuid(fd->old_idmap, id->session_uuid) : - NULL; - bool can_finalize_and_return = false; - - if (ELEM(idcode, ID_WM, ID_SCR, ID_WS)) { - /* Read WindowManager, Screen and WorkSpace IDs are never actually used during undo (see - * `setup_app_data()` in `blendfile.c`). - * So we can just abort here, just ensuring libmapping is set accordingly. */ - can_finalize_and_return = true; - } - else if (id_old != NULL && fd->are_memchunks_identical) { - /* Do not add LIB_TAG_NEW here, this should not be needed/used in undo case anyway (as - * this is only for do_version-like code), but for sake of consistency, and also because - * it will tell us which ID is re-used from old Main, and which one is actually new. */ - id_old->tag = tag | LIB_TAG_NEED_LINK | LIB_TAG_UNDO_OLD_ID_REUSED; - id_old->lib = main->curlib; - id_old->us = ID_FAKE_USERS(id_old); - /* Do not reset id->icon_id here, memory allocated for it remains valid. */ - /* Needed because .blend may have been saved with crap value here... */ - id_old->newid = NULL; - id_old->orig_id = NULL; - - /* About recalc: since that ID did not change at all, we know that its recalc fields also - * remained unchanged, so no need to handle neither recalc nor recalc_undo_future here. - */ - - Main *old_bmain = fd->old_mainlist->first; - ListBase *old_lb = which_libbase(old_bmain, idcode); - ListBase *new_lb = which_libbase(main, idcode); - BLI_remlink(old_lb, id_old); - BLI_addtail(new_lb, id_old); - - can_finalize_and_return = true; - } - - if (can_finalize_and_return) { - DEBUG_PRINTF("Re-using existing ID %s instead of newly read one\n", id_old->name); - oldnewmap_insert(fd->libmap, id_bhead->old, id_old, id_bhead->code); - oldnewmap_insert(fd->libmap, id_old, id_old, id_bhead->code); - - if (r_id) { - *r_id = id_old; - } - - if (do_partial_undo) { - /* Even though we re-use the old ID as-is, it does not mean that we are 100% safe from - * needing some depsgraph updates for it (it could depend on another ID which address - * did - * not change, but which actual content might have been re-read from the memfile). */ - if (fd->undo_direction < 0) { - /* We are coming from the future (i.e. do an actual undo, and not a redo), we use our - * old reused ID's 'accumulated recalc flags since last memfile undo step saving' as - * recalc flags. */ - id_old->recalc = id_old->recalc_undo_accumulated; - } - else { - /* We are coming from the past (i.e. do a redo), we use the saved 'accumulated recalc - * flags since last memfile undo step saving' from the newly read ID as recalc flags. - */ - id_old->recalc = id->recalc_undo_accumulated; - } - /* There is no need to flush the depsgraph's CoWs here, since that ID's data itself did - * not change. */ - - /* We need to 'accumulate' the accumulated recalc flags of all undo steps until we - * actually perform a depsgraph update, otherwise we'd only ever use the flags from one - * of the steps, and never get proper flags matching all others. */ - id_old->recalc_undo_accumulated |= id->recalc_undo_accumulated; - } - - MEM_freeN(id); - oldnewmap_free_unused(fd->datamap); - oldnewmap_clear(fd->datamap); - - return bhead; - } - } - } - - /* do after read_struct, for dna reconstruct */ - lb = which_libbase(main, idcode); - if (lb) { - /* Some re-used old IDs might also use newly read ones, so we have to check for old memory - * addresses for those as well. */ - if (fd->memfile != NULL && do_partial_undo && id->lib == NULL) { - BLI_assert(fd->old_idmap != NULL); - DEBUG_PRINTF("\t Looking for ID %s with uuid %u instead of newly read one\n", - id->name, - id->session_uuid); - id_old = BKE_main_idmap_lookup_uuid(fd->old_idmap, id->session_uuid); - if (id_old != NULL) { - BLI_assert(MEM_allocN_len(id) == MEM_allocN_len(id_old)); - /* UI IDs are always re-used from old bmain at higher-level calling code, so never swap - * those. Besides maybe custom properties, no other ID should have pointers to those - * anyway... - * And linked IDs are handled separately as well. */ - do_id_swap = !ELEM(idcode, ID_WM, ID_SCR, ID_WS) && - !(id_bhead->code == ID_LINK_PLACEHOLDER); - } - } - - /* At this point, we know we are going to keep that newly read & allocated ID, so we need to - * reallocate it to ensure we actually get a unique memory address for it. */ - if (!do_id_swap) { - DEBUG_PRINTF("using newly-read ID %s to a new mem address\n", id->name); - } - else { - DEBUG_PRINTF("using newly-read ID %s to its old, already existing address\n", id->name); - } - - /* for ID_LINK_PLACEHOLDER check */ - ID *id_target = do_id_swap ? id_old : id; - oldnewmap_insert(fd->libmap, id_bhead->old, id_target, id_bhead->code); - oldnewmap_insert(fd->libmap, id_old, id_target, id_bhead->code); - - BLI_addtail(lb, id); - - if (fd->memfile == NULL) { - /* When actually reading a file , we do want to reset/re-generate session uuids. - * In unod case, we want to re-use existing ones. */ - id->session_uuid = MAIN_ID_SESSION_UUID_UNSET; - } - - BKE_lib_libblock_session_uuid_ensure(id); - } - else { - /* unknown ID type */ - printf("%s: unknown id code '%c%c'\n", __func__, (idcode & 0xff), (idcode >> 8)); - MEM_freeN(id); - id = NULL; - } - } - - if (r_id) { - *r_id = do_id_swap ? id_old : id; - } - if (!id) { - return blo_bhead_next(fd, id_bhead); - } - - id->lib = main->curlib; - id->us = ID_FAKE_USERS(id); - id->icon_id = 0; - id->newid = NULL; /* Needed because .blend may have been saved with crap value here... */ - id->orig_id = NULL; - - /* this case cannot be direct_linked: it's just the ID part */ - if (id_bhead->code == ID_LINK_PLACEHOLDER) { - /* That way, we know which data-lock needs do_versions (required currently for linking). */ - 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, id_bhead); - } - - /* init pointers direct data */ - direct_link_id(fd, id, id_old); - - /* That way, we know which data-lock needs do_versions (required currently for linking). */ - /* Note: doing this after direct_link_id(), which resets that field. */ - id->tag = tag | LIB_TAG_NEED_LINK | LIB_TAG_NEW; + bool success = true; - switch (idcode) { + switch (GS(id->name)) { case ID_WM: direct_link_windowmanager(fd, (wmWindowManager *)id); break; case ID_SCR: - wrong_id = direct_link_screen(fd, (bScreen *)id); + success = direct_link_screen(fd, (bScreen *)id); break; case ID_SCE: direct_link_scene(fd, (Scene *)id); @@ -9658,12 +9497,372 @@ static BHead *read_libblock(FileData *fd, case ID_VO: direct_link_volume(fd, (Volume *)id); break; + case ID_SIM: + direct_link_simulation(fd, (Simulation *)id); + break; } - oldnewmap_free_unused(fd->datamap); + return success; +} + +/* Read all data associated with a datablock into datamap. */ +static BHead *read_data_into_datamap(FileData *fd, BHead *bhead, const char *allocname) +{ + bhead = blo_bhead_next(fd, bhead); + + while (bhead && bhead->code == DATA) { + void *data; +#if 0 + /* XXX DUMB DEBUGGING OPTION TO GIVE NAMES for guarded malloc errors */ + short* sp = fd->filesdna->structs[bhead->SDNAnr]; + char* tmp = malloc(100); + allocname = fd->filesdna->types[sp[0]]; + strcpy(tmp, allocname); + data = read_struct(fd, bhead, tmp); +#else + data = read_struct(fd, bhead, allocname); +#endif + + if (data) { + oldnewmap_insert(fd->datamap, bhead->old, data, 0); + } + + bhead = blo_bhead_next(fd, bhead); + } + + return bhead; +} + +/* Verify if the datablock and all associated data is identical. */ +static bool read_libblock_is_identical(FileData *fd, BHead *bhead) +{ + /* Test ID itself. */ + if (bhead->len && !BHEADN_FROM_BHEAD(bhead)->is_memchunk_identical) { + return false; + } + + /* Test any other data that is part of ID (logic must match read_data_into_datamap). */ + bhead = blo_bhead_next(fd, bhead); + + while (bhead && bhead->code == DATA) { + if (bhead->len && !BHEADN_FROM_BHEAD(bhead)->is_memchunk_identical) { + return false; + } + + bhead = blo_bhead_next(fd, bhead); + } + + return true; +} + +/* For undo, restore matching library datablock from the old main. */ +static bool read_libblock_undo_restore_library(FileData *fd, Main *main, const ID *id) +{ + /* In undo case, most libs and linked data should be kept as is from previous state + * (see BLO_read_from_memfile). + * However, some needed by the snapshot being read may have been removed in previous one, + * and would go missing. + * This leads e.g. to disappearing objects in some undo/redo case, see T34446. + * That means we have to carefully check whether current lib or + * libdata already exits in old main, if it does we merely copy it over into new main area, + * otherwise we have to do a full read of that bhead... */ + DEBUG_PRINTF("UNDO: restore library %s\n", id->name); + + Main *libmain = fd->old_mainlist->first; + /* Skip oldmain itself... */ + for (libmain = libmain->next; libmain; libmain = libmain->next) { + DEBUG_PRINTF(" compare with %s -> ", libmain->curlib ? libmain->curlib->id.name : "<NULL>"); + if (libmain->curlib && STREQ(id->name, libmain->curlib->id.name)) { + Main *oldmain = fd->old_mainlist->first; + DEBUG_PRINTF("match!\n"); + /* In case of a library, we need to re-add its main to fd->mainlist, + * because if we have later a missing ID_LINK_PLACEHOLDER, + * we need to get the correct lib it is linked to! + * Order is crucial, we cannot bulk-add it in BLO_read_from_memfile() + * like it used to be. */ + BLI_remlink(fd->old_mainlist, libmain); + BLI_remlink_safe(&oldmain->libraries, libmain->curlib); + BLI_addtail(fd->mainlist, libmain); + BLI_addtail(&main->libraries, libmain->curlib); + return true; + } + DEBUG_PRINTF("no match\n"); + } + + return false; +} + +/* For undo, restore existing linked datablock from the old main. */ +static bool read_libblock_undo_restore_linked(FileData *fd, Main *main, const ID *id, BHead *bhead) +{ + DEBUG_PRINTF("UNDO: restore linked datablock %s\n", id->name); + DEBUG_PRINTF(" from %s (%s): ", + main->curlib ? main->curlib->id.name : "<NULL>", + main->curlib ? main->curlib->name : "<NULL>"); + + ID *id_old = BKE_libblock_find_name(main, GS(id->name), id->name + 2); + if (id_old != NULL) { + DEBUG_PRINTF(" found!\n"); + /* Even though we found our linked ID, there is no guarantee its address + * is still the same. */ + if (id_old != bhead->old) { + oldnewmap_insert(fd->libmap, bhead->old, id_old, GS(id_old->name)); + } + + /* No need to do anything else for ID_LINK_PLACEHOLDER, it's assumed + * already present in its lib's main. */ + return true; + } + + DEBUG_PRINTF(" not found\n"); + return false; +} + +/* For undo, restore unchanged datablock from old main. */ +static void read_libblock_undo_restore_identical( + FileData *fd, Main *main, const ID *UNUSED(id), ID *id_old, const int tag) +{ + BLI_assert((fd->skip_flags & BLO_READ_SKIP_UNDO_OLD_MAIN) == 0); + BLI_assert(id_old != NULL); + + /* Some tags need to be preserved here. */ + id_old->tag = tag | (id_old->tag & LIB_TAG_EXTRAUSER); + id_old->lib = main->curlib; + id_old->us = ID_FAKE_USERS(id_old); + /* Do not reset id->icon_id here, memory allocated for it remains valid. */ + /* Needed because .blend may have been saved with crap value here... */ + id_old->newid = NULL; + id_old->orig_id = NULL; + + const short idcode = GS(id_old->name); + Main *old_bmain = fd->old_mainlist->first; + ListBase *old_lb = which_libbase(old_bmain, idcode); + ListBase *new_lb = which_libbase(main, idcode); + BLI_remlink(old_lb, id_old); + BLI_addtail(new_lb, id_old); + + /* Recalc flags, mostly these just remain as they are. */ + id_old->recalc |= direct_link_id_restore_recalc_exceptions(id_old); + id_old->recalc_after_undo_push = 0; + + /* As usual, proxies require some special love... + * In `blo_clear_proxy_pointers_from_lib()` we clear all `proxy_from` pointers to local IDs, for + * undo. This is required since we do not re-read linked data in that case, so we also do not + * re-'lib_link' their pointers. + * Those `proxy_from` pointers are then re-defined properly when lib_linking the newly read local + * object. However, in case of re-used data 'as-is', we never lib_link it again, so we have to + * fix those backward pointers here. */ + if (GS(id_old->name) == ID_OB) { + Object *ob = (Object *)id_old; + if (ob->proxy != NULL) { + ob->proxy->proxy_from = ob; + } + } +} + +/* For undo, store changed datablock at old address. */ +static void read_libblock_undo_restore_at_old_address(FileData *fd, Main *main, ID *id, ID *id_old) +{ + /* During memfile undo, if an ID changed and we cannot directly re-use existing one from old + * bmain, we do a full read of the new id from the memfile, and then fully swap its content + * with the old id. This allows us to keep the same pointer even for modified data, which + * helps reducing further detected changes by the depsgraph (since unchanged IDs remain fully + * unchanged, even if they are using/pointing to a changed one). */ + BLI_assert((fd->skip_flags & BLO_READ_SKIP_UNDO_OLD_MAIN) == 0); + BLI_assert(id_old != NULL); + + const short idcode = GS(id->name); + + /* XXX 3DCursor (witch is UI data and as such should not be affected by undo) is stored in + * Scene... So this requires some special handling, previously done in `blo_lib_link_restore()`, + * but this cannot work anymore when we overwrite existing memory... */ + if (idcode == ID_SCE) { + Scene *scene_old = (Scene *)id_old; + Scene *scene = (Scene *)id; + SWAP(View3DCursor, scene_old->cursor, scene->cursor); + } + + Main *old_bmain = fd->old_mainlist->first; + ListBase *old_lb = which_libbase(old_bmain, idcode); + ListBase *new_lb = which_libbase(main, idcode); + BLI_remlink(old_lb, id_old); + BLI_remlink(new_lb, id); + + /* We do not need any remapping from this call here, since no ID pointer is valid in the data + * currently (they are all pointing to old addresses, and need to go through `lib_link` + * process). So we can pass NULL for the Main pointer parameter. */ + BKE_lib_id_swap_full(NULL, id, id_old); + + BLI_addtail(new_lb, id_old); + BLI_addtail(old_lb, id); +} + +static bool read_libblock_undo_restore( + FileData *fd, Main *main, BHead *bhead, const int tag, ID **r_id_old) +{ + /* Get pointer to memory of new ID that we will be reading. */ + const ID *id = peek_struct_undo(fd, bhead); + const short idcode = GS(id->name); + + if (bhead->code == ID_LI) { + /* Restore library datablock. */ + if (read_libblock_undo_restore_library(fd, main, id)) { + return true; + } + } + else if (bhead->code == ID_LINK_PLACEHOLDER) { + /* Restore linked datablock. */ + if (read_libblock_undo_restore_linked(fd, main, id, bhead)) { + return true; + } + } + else if (ELEM(idcode, ID_WM, ID_SCR, ID_WS)) { + /* Skip reading any UI datablocks, existing ones are kept. We don't + * support pointers from other datablocks to UI datablocks so those + * we also don't put UI datablocks in fd->libmap. */ + return true; + } + + /* Restore local datablocks. */ + DEBUG_PRINTF("UNDO: read %s (uuid %u) -> ", id->name, id->session_uuid); + + ID *id_old = NULL; + const bool do_partial_undo = (fd->skip_flags & BLO_READ_SKIP_UNDO_OLD_MAIN) == 0; + if (do_partial_undo && (bhead->code != ID_LINK_PLACEHOLDER)) { + /* This code should only ever be reached for local data-blocks. */ + BLI_assert(main->curlib == NULL); + + /* Find the 'current' existing ID we want to reuse instead of the one we + * would read from the undo memfile. */ + BLI_assert(fd->old_idmap != NULL); + id_old = BKE_main_idmap_lookup_uuid(fd->old_idmap, id->session_uuid); + } + + if (id_old != NULL && read_libblock_is_identical(fd, bhead)) { + /* Local datablock was unchanged, restore from the old main. */ + DEBUG_PRINTF("keep identical datablock\n"); + + /* Do not add LIB_TAG_NEW here, this should not be needed/used in undo case anyway (as + * this is only for do_version-like code), but for sake of consistency, and also because + * it will tell us which ID is re-used from old Main, and which one is actually new. */ + /* Also do not add LIB_TAG_NEED_LINK, those IDs will never be re-liblinked, hence that tag will + * never be cleared, leading to critical issue in link/append code. */ + const int id_tag = tag | LIB_TAG_UNDO_OLD_ID_REUSED; + read_libblock_undo_restore_identical(fd, main, id, id_old, id_tag); + + /* Insert into library map for lookup by newly read datablocks (with pointer value bhead->old). + * Note that existing datablocks in memory (which pointer value would be id_old) are not + * remapped anymore, so no need to store this info here. */ + oldnewmap_insert(fd->libmap, bhead->old, id_old, bhead->code); + + *r_id_old = id_old; + return true; + } + else if (id_old != NULL) { + /* Local datablock was changed. Restore at the address of the old datablock. */ + DEBUG_PRINTF("read to old existing address\n"); + *r_id_old = id_old; + return false; + } + else { + /* Local datablock does not exist in the undo step, so read from scratch. */ + DEBUG_PRINTF("read at new address\n"); + return false; + } +} + +/* This routine reads a datablock and its direct data, and advances bhead to + * the next datablock. For library linked datablocks, only a placeholder will + * be generated, to be replaced in read_library_linked_ids. + * + * When reading for undo, libraries, linked datablocks and unchanged datablocks + * will be restored from the old database. Only new or changed datablocks will + * actually be read. */ +static BHead *read_libblock(FileData *fd, + Main *main, + BHead *bhead, + const int tag, + const bool placeholder_set_indirect_extern, + ID **r_id) +{ + /* First attempt to restore existing datablocks for undo. + * When datablocks are changed but still exist, we restore them at the old + * address and inherit recalc flags for the dependency graph. */ + ID *id_old = NULL; + if (fd->memfile != NULL) { + if (read_libblock_undo_restore(fd, main, bhead, tag, &id_old)) { + if (r_id) { + *r_id = id_old; + } + return blo_bhead_next(fd, bhead); + } + } + + /* Read libblock struct. */ + ID *id = read_struct(fd, bhead, "lib block"); + if (id == NULL) { + if (r_id) { + *r_id = NULL; + } + return blo_bhead_next(fd, bhead); + } + + /* Determine ID type and add to main database list. */ + const short idcode = GS(id->name); + ListBase *lb = which_libbase(main, idcode); + if (lb == NULL) { + /* Unknown ID type. */ + printf("%s: unknown id code '%c%c'\n", __func__, (idcode & 0xff), (idcode >> 8)); + MEM_freeN(id); + if (r_id) { + *r_id = NULL; + } + return blo_bhead_next(fd, bhead); + } + + /* NOTE: id must be added to the list before direct_link_id(), since + * direct_link_library() may remove it from there in case of duplicates. */ + BLI_addtail(lb, id); + + /* Insert into library map for lookup by newly read datablocks (with pointer value bhead->old). + * Note that existing datablocks in memory (which pointer value would be id_old) are not remapped + * remapped anymore, so no need to store this info here. */ + ID *id_target = id_old ? id_old : id; + oldnewmap_insert(fd->libmap, bhead->old, id_target, bhead->code); + + if (r_id) { + *r_id = id_target; + } + + /* Set tag for new datablock to indicate lib linking and versioning needs + * to be done still. */ + int id_tag = tag | LIB_TAG_NEED_LINK | LIB_TAG_NEW; + + if (bhead->code == ID_LINK_PLACEHOLDER) { + /* Read placeholder for linked datablock. */ + id_tag |= LIB_TAG_ID_LINK_PLACEHOLDER; + + if (placeholder_set_indirect_extern) { + if (id->flag & LIB_INDIRECT_WEAK_LINK) { + id_tag |= LIB_TAG_INDIRECT; + } + else { + id_tag |= LIB_TAG_EXTERN; + } + } + + direct_link_id(fd, main, id_tag, id, id_old); + return blo_bhead_next(fd, bhead); + } + + /* Read datablock contents. + * Use convenient malloc name for debugging and better memory link prints. */ + const char *allocname = dataname(idcode); + bhead = read_data_into_datamap(fd, bhead, allocname); + const bool success = direct_link_id(fd, main, id_tag, id, id_old); oldnewmap_clear(fd->datamap); - if (wrong_id) { + if (!success) { /* XXX This is probably working OK currently given the very limited scope of that flag. * However, it is absolutely **not** handled correctly: it is freeing an ID pointer that has * been added to the fd->libmap mapping, which in theory could lead to nice crashes... @@ -9673,39 +9872,12 @@ static BHead *read_libblock(FileData *fd, *r_id = NULL; } } - else if (do_id_swap) { - /* During memfile undo, if an ID changed and we cannot directly re-use existing one from old - * bmain, we do a full read of the new id from the memfile, and then fully swap its content - * with the old id. This allows us to keep the same pointer even for modified data, which helps - * reducing further detected changes by the depsgraph (since unchanged IDs remain fully - * unchanged, even if they are using/pointing to a changed one). */ - - BLI_assert((fd->skip_flags & BLO_READ_SKIP_UNDO_OLD_MAIN) == 0); - - Main *old_bmain = fd->old_mainlist->first; - BLI_assert(id_old != NULL); - - ListBase *old_lb = which_libbase(old_bmain, idcode); - ListBase *new_lb = which_libbase(main, idcode); - BLI_remlink(old_lb, id_old); - BLI_remlink(new_lb, id); - - /* We do not need any remapping from this call here, since no ID pointer is valid in the data - * currently (they are all pointing to old addresses, and need to go through `lib_link` - * process). So we can pass NULL for the Main pointer parameter. */ - BKE_lib_id_swap_full(NULL, id, id_old); - - BLI_addtail(new_lb, id_old); - BLI_addtail(old_lb, id); - } - else if (fd->memfile != NULL) { - DEBUG_PRINTF("We had to fully re-recreate ID %s (old addr: %p, new addr: %p)...\n", - id->name, - id_old, - id); + else if (id_old) { + /* For undo, store contents read into id at id_old. */ + read_libblock_undo_restore_at_old_address(fd, main, id, id_old); } - return (bhead); + return bhead; } /** \} */ @@ -9823,6 +9995,9 @@ static void do_versions(FileData *fd, Library *lib, Main *main) { /* WATCH IT!!!: pointers from libdata have not been converted */ + /* Don't allow versioning to create new data-blocks. */ + main->is_locked_for_linking = true; + if (G.debug & G_DEBUG) { char build_commit_datetime[32]; time_t temp_time = main->build_commit_timestamp; @@ -9847,12 +10022,15 @@ static void do_versions(FileData *fd, Library *lib, Main *main) blo_do_versions_260(fd, lib, main); blo_do_versions_270(fd, lib, main); blo_do_versions_280(fd, lib, main); + blo_do_versions_290(fd, lib, main); blo_do_versions_cycles(fd, lib, main); /* WATCH IT!!!: pointers from libdata have not been converted yet here! */ /* WATCH IT 2!: Userdef struct init see do_versions_userdef() above! */ /* don't forget to set version number in BKE_blender_version.h! */ + + main->is_locked_for_linking = false; } static void do_versions_after_linking(Main *main, ReportList *reports) @@ -9860,11 +10038,17 @@ static void do_versions_after_linking(Main *main, ReportList *reports) // printf("%s for %s (%s), %d.%d\n", __func__, main->curlib ? main->curlib->name : main->name, // main->curlib ? "LIB" : "MAIN", main->versionfile, main->subversionfile); + /* Don't allow versioning to create new data-blocks. */ + main->is_locked_for_linking = true; + do_versions_after_linking_250(main); do_versions_after_linking_260(main); do_versions_after_linking_270(main); do_versions_after_linking_280(main, reports); + do_versions_after_linking_290(main, reports); do_versions_after_linking_cycles(main); + + main->is_locked_for_linking = false; } /** \} */ @@ -10019,6 +10203,9 @@ static void lib_link_all(FileData *fd, Main *bmain) case ID_AC: lib_link_action(fd, bmain, (bAction *)id); break; + case ID_SIM: + lib_link_simulation(fd, bmain, (Simulation *)id); + break; case ID_IP: /* XXX deprecated... still needs to be maintained for version patches still. */ lib_link_ipo(fd, bmain, (Ipo *)id); @@ -10051,6 +10238,15 @@ static void lib_link_all(FileData *fd, Main *bmain) * 'permanently' in our data structures... */ BKE_main_collections_parent_relations_rebuild(bmain); } + +#ifndef NDEBUG + /* Double check we do not have any 'need link' tag remaining, this should never be the case once + * this function has run. */ + FOREACH_MAIN_ID_BEGIN (bmain, id) { + BLI_assert((id->tag & LIB_TAG_NEED_LINK) == 0); + } + FOREACH_MAIN_ID_END; +#endif } /** \} */ @@ -10082,7 +10278,7 @@ static BHead *read_userdef(BlendFileData *bfd, FileData *fd, BHead *bhead) user->subversionfile = bfd->main->subversionfile; /* read all data into fd->datamap */ - bhead = read_data_into_oldnewmap(fd, bhead, "user def"); + bhead = read_data_into_datamap(fd, bhead, "user def"); link_list(fd, &user->themes); link_list(fd, &user->user_keymaps); @@ -10116,14 +10312,14 @@ static BHead *read_userdef(BlendFileData *bfd, FileData *fd, BHead *bhead) } } - for (wmKeyConfigPref *kpt = user->user_keyconfig_prefs.first; kpt; kpt = kpt->next) { + LISTBASE_FOREACH (wmKeyConfigPref *, kpt, &user->user_keyconfig_prefs) { kpt->prop = newdataadr(fd, kpt->prop); IDP_DirectLinkGroup_OrFree(&kpt->prop, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd); } - for (bUserMenu *um = user->user_menus.first; um; um = um->next) { + LISTBASE_FOREACH (bUserMenu *, um, &user->user_menus) { link_list(fd, &um->items); - for (bUserMenuItem *umi = um->items.first; umi; umi = umi->next) { + LISTBASE_FOREACH (bUserMenuItem *, umi, &um->items) { if (umi->type == USER_MENU_TYPE_OPERATOR) { bUserMenuItem_Op *umi_op = (bUserMenuItem_Op *)umi; umi_op->prop = newdataadr(fd, umi_op->prop); @@ -10150,7 +10346,6 @@ static BHead *read_userdef(BlendFileData *bfd, FileData *fd, BHead *bhead) user->edit_studio_light = 0; /* free fd->datamap again */ - oldnewmap_free_unused(fd->datamap); oldnewmap_clear(fd->datamap); return bhead; @@ -10168,6 +10363,10 @@ BlendFileData *blo_read_file_internal(FileData *fd, const char *filepath) BlendFileData *bfd; ListBase mainlist = {NULL, NULL}; + if (fd->memfile != NULL) { + DEBUG_PRINTF("\nUNDO: read step\n"); + } + bfd = MEM_callocN(sizeof(BlendFileData), "blendfiledata"); bfd->main = BKE_main_new(); @@ -10285,7 +10484,7 @@ BlendFileData *blo_read_file_internal(FileData *fd, const char *filepath) /* Yep, second splitting... but this is a very cheap operation, so no big deal. */ blo_split_main(&mainlist, bfd->main); - for (Main *mainvar = mainlist.first; mainvar; mainvar = mainvar->next) { + LISTBASE_FOREACH (Main *, mainvar, &mainlist) { BLI_assert(mainvar->versionfile != 0); do_versions_after_linking(mainvar, fd->reports); } @@ -10394,7 +10593,7 @@ static BHead *find_previous_lib(FileData *fd, BHead *bhead) static BHead *find_bhead(FileData *fd, void *old) { #if 0 - BHead* bhead; + BHead* bhead; #endif struct BHeadSort *bhs, bhs_s; @@ -10414,11 +10613,11 @@ static BHead *find_bhead(FileData *fd, void *old) } #if 0 - for (bhead = blo_bhead_first(fd); bhead; bhead = blo_bhead_next(fd, bhead)) { - if (bhead->old == old) { - return bhead; - } - } + for (bhead = blo_bhead_first(fd); bhead; bhead = blo_bhead_next(fd, bhead)) { + if (bhead->old == old) { + return bhead; + } + } #endif return NULL; @@ -10549,9 +10748,9 @@ static void expand_doit_library(void *fdhandle, Main *mainvar, void *old) /* Commented because this can print way too much. */ #if 0 - if (G.debug & G_DEBUG) { - printf("expand_doit: already linked: %s lib: %s\n", id->name, lib->name); - } + if (G.debug & G_DEBUG) { + printf("expand_doit: already linked: %s lib: %s\n", id->name, lib->name); + } #endif } @@ -10703,7 +10902,7 @@ static void expand_idprops(FileData *fd, Main *mainvar, IDProperty *prop) break; } case IDP_GROUP: - for (IDProperty *loop = prop->data.group.first; loop; loop = loop->next) { + LISTBASE_FOREACH (IDProperty *, loop, &prop->data.group) { expand_idprops(fd, mainvar, loop); } break; @@ -10714,7 +10913,7 @@ static void expand_id(FileData *fd, Main *mainvar, ID *id); static void expand_nodetree(FileData *fd, Main *mainvar, bNodeTree *ntree); static void expand_collection(FileData *fd, Main *mainvar, Collection *collection); -static void expand_id_private_id(FileData *fd, Main *mainvar, ID *id) +static void expand_id_embedded_id(FileData *fd, Main *mainvar, ID *id) { /* Handle 'private IDs'. */ bNodeTree *nodetree = ntreeFromID(id); @@ -10746,7 +10945,7 @@ static void expand_id(FileData *fd, Main *mainvar, ID *id) expand_animdata(fd, mainvar, adt); } - expand_id_private_id(fd, mainvar, id); + expand_id_embedded_id(fd, mainvar, id); } static void expand_action(FileData *fd, Main *mainvar, bAction *act) @@ -10763,7 +10962,7 @@ static void expand_action(FileData *fd, Main *mainvar, bAction *act) /* F-Curves in Action */ expand_fcurves(fd, mainvar, &act->curves); - for (TimeMarker *marker = act->markers.first; marker; marker = marker->next) { + LISTBASE_FOREACH (TimeMarker *, marker, &act->markers) { if (marker->camera) { expand_doit(fd, mainvar, marker->camera); } @@ -10831,18 +11030,18 @@ static void expand_particlesettings(FileData *fd, Main *mainvar, ParticleSetting } } - for (ParticleDupliWeight *dw = part->instance_weights.first; dw; dw = dw->next) { + LISTBASE_FOREACH (ParticleDupliWeight *, dw, &part->instance_weights) { expand_doit(fd, mainvar, dw->ob); } } static void expand_collection(FileData *fd, Main *mainvar, Collection *collection) { - for (CollectionObject *cob = collection->gobject.first; cob; cob = cob->next) { + LISTBASE_FOREACH (CollectionObject *, cob, &collection->gobject) { expand_doit(fd, mainvar, cob->ob); } - for (CollectionChild *child = collection->children.first; child; child = child->next) { + LISTBASE_FOREACH (CollectionChild *, child, &collection->children) { expand_doit(fd, mainvar, child->collection); } @@ -10858,10 +11057,51 @@ static void expand_key(FileData *fd, Main *mainvar, Key *key) expand_doit(fd, mainvar, key->ipo); // XXX deprecated - old animation system } +static void expand_node_socket(FileData *fd, Main *mainvar, bNodeSocket *sock) +{ + expand_idprops(fd, mainvar, sock->prop); + + if (sock->default_value != NULL) { + + switch ((eNodeSocketDatatype)sock->type) { + case SOCK_OBJECT: { + bNodeSocketValueObject *default_value = sock->default_value; + expand_doit(fd, mainvar, default_value->value); + break; + } + case SOCK_IMAGE: { + bNodeSocketValueImage *default_value = sock->default_value; + expand_doit(fd, mainvar, default_value->value); + break; + } + case SOCK_FLOAT: + case SOCK_VECTOR: + case SOCK_RGBA: + case SOCK_BOOLEAN: + case SOCK_INT: + case SOCK_STRING: + case __SOCK_MESH: + case SOCK_CUSTOM: + case SOCK_SHADER: + case SOCK_EMITTERS: + case SOCK_EVENTS: + case SOCK_FORCES: + case SOCK_CONTROL_FLOW: + break; + } + } +} + +static void expand_node_sockets(FileData *fd, Main *mainvar, ListBase *sockets) +{ + LISTBASE_FOREACH (bNodeSocket *, sock, sockets) { + expand_node_socket(fd, mainvar, sock); + } +} + static void expand_nodetree(FileData *fd, Main *mainvar, bNodeTree *ntree) { bNode *node; - bNodeSocket *sock; if (ntree->gpd) { expand_doit(fd, mainvar, ntree->gpd); @@ -10874,20 +11114,12 @@ static void expand_nodetree(FileData *fd, Main *mainvar, bNodeTree *ntree) expand_idprops(fd, mainvar, node->prop); - for (sock = node->inputs.first; sock; sock = sock->next) { - expand_idprops(fd, mainvar, sock->prop); - } - for (sock = node->outputs.first; sock; sock = sock->next) { - expand_idprops(fd, mainvar, sock->prop); - } + expand_node_sockets(fd, mainvar, &node->inputs); + expand_node_sockets(fd, mainvar, &node->outputs); } - for (sock = ntree->inputs.first; sock; sock = sock->next) { - expand_idprops(fd, mainvar, sock->prop); - } - for (sock = ntree->outputs.first; sock; sock = sock->next) { - expand_idprops(fd, mainvar, sock->prop); - } + expand_node_sockets(fd, mainvar, &ntree->inputs); + expand_node_sockets(fd, mainvar, &ntree->outputs); } static void expand_texture(FileData *fd, Main *mainvar, Tex *tex) @@ -11027,14 +11259,14 @@ static void expand_bones(FileData *fd, Main *mainvar, Bone *bone) { expand_idprops(fd, mainvar, bone->prop); - for (Bone *curBone = bone->childbase.first; curBone; curBone = curBone->next) { + LISTBASE_FOREACH (Bone *, curBone, &bone->childbase) { expand_bones(fd, mainvar, curBone); } } static void expand_armature(FileData *fd, Main *mainvar, bArmature *arm) { - for (Bone *curBone = arm->bonebase.first; curBone; curBone = curBone->next) { + LISTBASE_FOREACH (Bone *, curBone, &arm->bonebase) { expand_bones(fd, mainvar, curBone); } } @@ -11073,7 +11305,7 @@ static void expand_object(FileData *fd, Main *mainvar, Object *ob) data.fd = fd; data.mainvar = mainvar; - modifiers_foreachIDLink(ob, expand_object_expandModifiers, (void *)&data); + BKE_modifiers_foreach_ID_link(ob, expand_object_expandModifiers, (void *)&data); } /* expand_object_expandModifier() */ @@ -11085,7 +11317,7 @@ static void expand_object(FileData *fd, Main *mainvar, Object *ob) data.fd = fd; data.mainvar = mainvar; - BKE_gpencil_modifiers_foreachIDLink(ob, expand_object_expandModifiers, (void *)&data); + BKE_gpencil_modifiers_foreach_ID_link(ob, expand_object_expandModifiers, (void *)&data); } /* expand_object_expandShaderFx() */ @@ -11097,7 +11329,7 @@ static void expand_object(FileData *fd, Main *mainvar, Object *ob) data.fd = fd; data.mainvar = mainvar; - BKE_shaderfx_foreachIDLink(ob, expand_object_expandModifiers, (void *)&data); + BKE_shaderfx_foreach_ID_link(ob, expand_object_expandModifiers, (void *)&data); } expand_pose(fd, mainvar, ob->pose); @@ -11172,11 +11404,11 @@ static void expand_object(FileData *fd, Main *mainvar, Object *ob) #ifdef USE_COLLECTION_COMPAT_28 static void expand_scene_collection(FileData *fd, Main *mainvar, SceneCollection *sc) { - for (LinkData *link = sc->objects.first; link; link = link->next) { + LISTBASE_FOREACH (LinkData *, link, &sc->objects) { expand_doit(fd, mainvar, link->data); } - for (SceneCollection *nsc = sc->scene_collections.first; nsc; nsc = nsc->next) { + LISTBASE_FOREACH (SceneCollection *, nsc, &sc->scene_collections) { expand_scene_collection(fd, mainvar, nsc); } } @@ -11188,7 +11420,7 @@ static void expand_scene(FileData *fd, Main *mainvar, Scene *sce) FreestyleModuleConfig *module; FreestyleLineSet *lineset; - for (Base *base_legacy = sce->base.first; base_legacy; base_legacy = base_legacy->next) { + LISTBASE_FOREACH (Base *, base_legacy, &sce->base) { expand_doit(fd, mainvar, base_legacy->object); } expand_doit(fd, mainvar, sce->camera); @@ -11215,7 +11447,7 @@ static void expand_scene(FileData *fd, Main *mainvar, Scene *sce) } } - for (ViewLayer *view_layer = sce->view_layers.first; view_layer; view_layer = view_layer->next) { + LISTBASE_FOREACH (ViewLayer *, view_layer, &sce->view_layers) { expand_idprops(fd, mainvar, view_layer->id_properties); for (module = view_layer->freestyle_config.modules.first; module; module = module->next) { @@ -11271,7 +11503,7 @@ static void expand_scene(FileData *fd, Main *mainvar, Scene *sce) expand_doit(fd, mainvar, sce->rigidbody_world->constraints); } - for (TimeMarker *marker = sce->markers.first; marker; marker = marker->next) { + LISTBASE_FOREACH (TimeMarker *, marker, &sce->markers) { if (marker->camera) { expand_doit(fd, mainvar, marker->camera); } @@ -11294,7 +11526,7 @@ static void expand_camera(FileData *fd, Main *mainvar, Camera *ca) { expand_doit(fd, mainvar, ca->ipo); // XXX deprecated - old animation system - for (CameraBGImage *bgpic = ca->bg_images.first; bgpic; bgpic = bgpic->next) { + LISTBASE_FOREACH (CameraBGImage *, bgpic, &ca->bg_images) { if (bgpic->source == CAM_BGIMG_SOURCE_IMAGE) { expand_doit(fd, mainvar, bgpic->ima); } @@ -11398,9 +11630,7 @@ static void expand_gpencil(FileData *fd, Main *mainvar, bGPdata *gpd) static void expand_workspace(FileData *fd, Main *mainvar, WorkSpace *workspace) { - ListBase *layouts = BKE_workspace_layouts_get(workspace); - - for (WorkSpaceLayout *layout = layouts->first; layout; layout = layout->next) { + LISTBASE_FOREACH (WorkSpaceLayout *, layout, &workspace->layouts) { expand_doit(fd, mainvar, BKE_workspace_layout_screen_get(layout)); } } @@ -11438,6 +11668,13 @@ static void expand_volume(FileData *fd, Main *mainvar, Volume *volume) } } +static void expand_simulation(FileData *fd, Main *mainvar, Simulation *simulation) +{ + if (simulation->adt) { + expand_animdata(fd, mainvar, simulation->adt); + } +} + /** * Set the callback func used over all ID data found by \a BLO_expand_main func. * @@ -11567,6 +11804,9 @@ void BLO_expand_main(void *fdhandle, Main *mainvar) case ID_VO: expand_volume(fd, mainvar, (Volume *)id); break; + case ID_SIM: + expand_simulation(fd, mainvar, (Simulation *)id); + break; default: break; } @@ -11703,6 +11943,7 @@ static void add_collections_to_scene(Main *mainvar, /* BKE_object_add(...) messes with the selection. */ Object *ob = BKE_object_add_only_object(bmain, OB_EMPTY, collection->id.name + 2); ob->type = OB_EMPTY; + ob->empty_drawsize = U.collection_instance_empty_size; BKE_collection_object_add(bmain, active_collection, ob); Base *base = BKE_view_layer_base_find(view_layer, ob); @@ -12142,7 +12383,7 @@ static int has_linked_ids_to_read(Main *mainvar) int a = set_listbasepointers(mainvar, lbarray); while (a--) { - for (ID *id = lbarray[a]->first; id; id = id->next) { + LISTBASE_FOREACH (ID *, id, lbarray[a]) { if ((id->tag & LIB_TAG_ID_LINK_PLACEHOLDER) && !(id->flag & LIB_INDIRECT_WEAK_LINK)) { return true; } @@ -12373,9 +12614,9 @@ static void read_libraries(FileData *basefd, ListBase *mainlist) /* Does this library have any more linked data-blocks we need to read? */ if (has_linked_ids_to_read(mainptr)) { #if 0 - printf("Reading linked data-blocks from %s (%s)\n", - mainptr->curlib->id.name, - mainptr->curlib->name); + printf("Reading linked data-blocks from %s (%s)\n", + mainptr->curlib->id.name, + mainptr->curlib->name); #endif /* Open file if it has not been done yet. */ @@ -12439,4 +12680,164 @@ static void read_libraries(FileData *basefd, ListBase *mainlist) BKE_main_free(main_newid); } +void *BLO_read_get_new_data_address(BlendDataReader *reader, const void *old_address) +{ + return newdataadr(reader->fd, old_address); +} + +ID *BLO_read_get_new_id_address(BlendLibReader *reader, Library *lib, ID *id) +{ + return newlibadr(reader->fd, lib, id); +} + +bool BLO_read_requires_endian_switch(BlendDataReader *reader) +{ + return (reader->fd->flags & FD_FLAGS_SWITCH_ENDIAN) != 0; +} + +/** + * Updates all ->prev and ->next pointers of the list elements. + * Updates the list->first and list->last pointers. + * When not NULL, calls the callback on every element. + */ +void BLO_read_list(BlendDataReader *reader, ListBase *list, BlendReadListFn callback) +{ + if (BLI_listbase_is_empty(list)) { + return; + } + + BLO_read_data_address(reader, &list->first); + if (callback != NULL) { + callback(reader, list->first); + } + Link *ln = list->first; + Link *prev = NULL; + while (ln) { + BLO_read_data_address(reader, &ln->next); + if (ln->next != NULL && callback != NULL) { + callback(reader, ln->next); + } + ln->prev = prev; + prev = ln; + ln = ln->next; + } + list->last = prev; +} + +void BLO_read_int32_array(BlendDataReader *reader, int array_size, int32_t **ptr_p) +{ + BLO_read_data_address(reader, ptr_p); + if (BLO_read_requires_endian_switch(reader)) { + BLI_endian_switch_int32_array(*ptr_p, array_size); + } +} + +void BLO_read_uint32_array(BlendDataReader *reader, int array_size, uint32_t **ptr_p) +{ + BLO_read_data_address(reader, ptr_p); + if (BLO_read_requires_endian_switch(reader)) { + BLI_endian_switch_uint32_array(*ptr_p, array_size); + } +} + +void BLO_read_float_array(BlendDataReader *reader, int array_size, float **ptr_p) +{ + BLO_read_data_address(reader, ptr_p); + if (BLO_read_requires_endian_switch(reader)) { + BLI_endian_switch_float_array(*ptr_p, array_size); + } +} + +void BLO_read_float3_array(BlendDataReader *reader, int array_size, float **ptr_p) +{ + BLO_read_float_array(reader, array_size * 3, ptr_p); +} + +void BLO_read_double_array(BlendDataReader *reader, int array_size, double **ptr_p) +{ + BLO_read_data_address(reader, ptr_p); + if (BLO_read_requires_endian_switch(reader)) { + BLI_endian_switch_double_array(*ptr_p, array_size); + } +} + +static void convert_pointer_array_64_to_32(BlendDataReader *reader, + uint array_size, + const uint64_t *src, + uint32_t *dst) +{ + /* Match pointer conversion rules from bh4_from_bh8 and cast_pointer. */ + if (BLO_read_requires_endian_switch(reader)) { + for (int i = 0; i < array_size; i++) { + uint64_t ptr = src[i]; + BLI_endian_switch_uint64(&ptr); + dst[i] = (uint32_t)(ptr >> 3); + } + } + else { + for (int i = 0; i < array_size; i++) { + dst[i] = (uint32_t)(src[i] >> 3); + } + } +} + +static void convert_pointer_array_32_to_64(BlendDataReader *UNUSED(reader), + uint array_size, + const uint32_t *src, + uint64_t *dst) +{ + /* Match pointer conversion rules from bh8_from_bh4 and cast_pointer. */ + for (int i = 0; i < array_size; i++) { + dst[i] = src[i]; + } +} + +void BLO_read_pointer_array(BlendDataReader *reader, void **ptr_p) +{ + FileData *fd = reader->fd; + + void *orig_array = newdataadr(fd, *ptr_p); + if (orig_array == NULL) { + *ptr_p = NULL; + return; + } + + int file_pointer_size = fd->filesdna->pointer_size; + int current_pointer_size = fd->memsdna->pointer_size; + + /* Overallocation is fine, but might be better to pass the length as parameter. */ + int array_size = MEM_allocN_len(orig_array) / file_pointer_size; + + void *final_array = NULL; + + if (file_pointer_size == current_pointer_size) { + /* No pointer conversion necessary. */ + final_array = orig_array; + } + else if (file_pointer_size == 8 && current_pointer_size == 4) { + /* Convert pointers from 64 to 32 bit. */ + final_array = MEM_malloc_arrayN(array_size, 4, "new pointer array"); + convert_pointer_array_64_to_32( + reader, array_size, (uint64_t *)orig_array, (uint32_t *)final_array); + MEM_freeN(orig_array); + } + else if (file_pointer_size == 4 && current_pointer_size == 8) { + /* Convert pointers from 32 to 64 bit. */ + final_array = MEM_malloc_arrayN(array_size, 8, "new pointer array"); + convert_pointer_array_32_to_64( + reader, array_size, (uint32_t *)orig_array, (uint64_t *)final_array); + MEM_freeN(orig_array); + } + else { + BLI_assert(false); + } + + *ptr_p = final_array; +} + +void BLO_expand_id(BlendExpander *expander, ID *id) +{ + expand_doit(expander->fd, expander->main, id); +} + /** \} */ diff --git a/source/blender/blenloader/intern/readfile.h b/source/blender/blenloader/intern/readfile.h index 5be7e703d6b..f698d642e33 100644 --- a/source/blender/blenloader/intern/readfile.h +++ b/source/blender/blenloader/intern/readfile.h @@ -85,11 +85,6 @@ typedef struct FileData { const char *buffer; /** Variables needed for reading from memfile (undo). */ struct MemFile *memfile; - /** Whether all data read from memfile so far was identical - * (i.e. shared with some previous undo step). - * Updated by `fd_read_from_memfile()`, user is responsible to reset it to true when needed. - * Used to detect unchanged IDs. */ - bool are_memchunks_identical; /** Whether we are undoing (< 0) or redoing (> 0), used to choose which 'unchanged' flag to use * to detect unchanged data from memfile. */ short undo_direction; @@ -204,12 +199,14 @@ void blo_do_versions_250(struct FileData *fd, struct Library *lib, struct Main * void blo_do_versions_260(struct FileData *fd, struct Library *lib, struct Main *bmain); void blo_do_versions_270(struct FileData *fd, struct Library *lib, struct Main *bmain); void blo_do_versions_280(struct FileData *fd, struct Library *lib, struct Main *bmain); +void blo_do_versions_290(struct FileData *fd, struct Library *lib, struct Main *bmain); void blo_do_versions_cycles(struct FileData *fd, struct Library *lib, struct Main *bmain); void do_versions_after_linking_250(struct Main *bmain); void do_versions_after_linking_260(struct Main *bmain); void do_versions_after_linking_270(struct Main *bmain); -void do_versions_after_linking_280(struct Main *bmain, ReportList *reports); +void do_versions_after_linking_280(struct Main *bmain, struct ReportList *reports); +void do_versions_after_linking_290(struct Main *bmain, struct ReportList *reports); void do_versions_after_linking_cycles(struct Main *bmain); #endif diff --git a/source/blender/blenloader/intern/undofile.c b/source/blender/blenloader/intern/undofile.c index 06469a0c087..28b37c4a737 100644 --- a/source/blender/blenloader/intern/undofile.c +++ b/source/blender/blenloader/intern/undofile.c @@ -41,10 +41,12 @@ #include "DNA_listBase.h" #include "BLI_blenlib.h" +#include "BLI_ghash.h" #include "BLO_readfile.h" #include "BLO_undofile.h" +#include "BKE_lib_id.h" #include "BKE_main.h" /* keep last */ @@ -92,13 +94,69 @@ void BLO_memfile_merge(MemFile *first, MemFile *second) BLO_memfile_free(first); } -void memfile_chunk_add(MemFile *memfile, const char *buf, uint size, MemFileChunk **compchunk_step) +/* Clear is_identical_future before adding next memfile. */ +void BLO_memfile_clear_future(MemFile *memfile) { + LISTBASE_FOREACH (MemFileChunk *, chunk, &memfile->chunks) { + chunk->is_identical_future = false; + } +} + +void BLO_memfile_write_init(MemFileWriteData *mem_data, + MemFile *written_memfile, + MemFile *reference_memfile) +{ + mem_data->written_memfile = written_memfile; + mem_data->reference_memfile = reference_memfile; + mem_data->reference_current_chunk = reference_memfile ? reference_memfile->chunks.first : NULL; + + /* If we have a reference memfile, we generate a mapping between the session_uuid's of the IDs + * stored in that previous undo step, and its first matching memchunk. + * This will allow us to easily find the existing undo memory storage of IDs even when some + * re-ordering in current Main data-base broke the order matching with the memchunks from + * previous step. */ + if (reference_memfile != NULL) { + mem_data->id_session_uuid_mapping = BLI_ghash_new( + BLI_ghashutil_inthash_p_simple, BLI_ghashutil_intcmp, __func__); + uint current_session_uuid = MAIN_ID_SESSION_UUID_UNSET; + LISTBASE_FOREACH (MemFileChunk *, mem_chunk, &reference_memfile->chunks) { + if (!ELEM(mem_chunk->id_session_uuid, MAIN_ID_SESSION_UUID_UNSET, current_session_uuid)) { + current_session_uuid = mem_chunk->id_session_uuid; + void **entry; + if (!BLI_ghash_ensure_p(mem_data->id_session_uuid_mapping, + POINTER_FROM_UINT(current_session_uuid), + &entry)) { + *entry = mem_chunk; + } + else { + BLI_assert(0); + } + } + } + } +} + +void BLO_memfile_write_finalize(MemFileWriteData *mem_data) +{ + if (mem_data->id_session_uuid_mapping != NULL) { + BLI_ghash_free(mem_data->id_session_uuid_mapping, NULL, NULL); + } +} + +void BLO_memfile_chunk_add(MemFileWriteData *mem_data, const char *buf, uint size) +{ + MemFile *memfile = mem_data->written_memfile; + MemFileChunk **compchunk_step = &mem_data->reference_current_chunk; + MemFileChunk *curchunk = MEM_mallocN(sizeof(MemFileChunk), "MemFileChunk"); curchunk->size = size; curchunk->buf = NULL; curchunk->is_identical = false; - curchunk->is_identical_future = false; + /* This is unsafe in the sense that an app handler or other code that does not + * perform an undo push may make changes after the last undo push that + * will then not be undo. Though it's not entirely clear that is wrong behavior. */ + curchunk->is_identical_future = true; + curchunk->id_session_uuid = mem_data->current_id_session_uuid; BLI_addtail(&memfile->chunks, curchunk); /* we compare compchunk with buf */ diff --git a/source/blender/blenloader/intern/versioning_250.c b/source/blender/blenloader/intern/versioning_250.c index fed0cbda466..eaeef0d52c1 100644 --- a/source/blender/blenloader/intern/versioning_250.c +++ b/source/blender/blenloader/intern/versioning_250.c @@ -61,7 +61,8 @@ #include "BLI_math.h" #include "BLI_utildefines.h" -#include "BKE_anim.h" +#include "BKE_anim_data.h" +#include "BKE_anim_visualization.h" #include "BKE_armature.h" #include "BKE_colortools.h" #include "BKE_global.h" // for G @@ -88,13 +89,13 @@ #define U (*((const UserDef *)&U)) /* 2.50 patch */ -static void area_add_header_region(ScrArea *sa, ListBase *lb) +static void area_add_header_region(ScrArea *area, ListBase *lb) { ARegion *region = MEM_callocN(sizeof(ARegion), "area region from do_versions"); BLI_addtail(lb, region); region->regiontype = RGN_TYPE_HEADER; - if (sa->headertype == 1) { + if (area->headertype == 1) { region->alignment = RGN_ALIGN_BOTTOM; } else { @@ -133,10 +134,10 @@ static void sequencer_init_preview_region(ARegion *region) region->v2d.keeptot = V2D_KEEPTOT_FREE; } -static void area_add_window_regions(ScrArea *sa, SpaceLink *sl, ListBase *lb) +static void area_add_window_regions(ScrArea *area, SpaceLink *sl, ListBase *lb) { ARegion *region; - ARegion *ar_main; + ARegion *region_main; if (sl) { /* first channels for ipo action nla... */ @@ -205,14 +206,14 @@ static void area_add_window_regions(ScrArea *sa, SpaceLink *sl, ListBase *lb) region->alignment = RGN_ALIGN_TOP; break; case SPACE_SEQ: - ar_main = (ARegion *)lb->first; - for (; ar_main; ar_main = ar_main->next) { - if (ar_main->regiontype == RGN_TYPE_WINDOW) { + region_main = (ARegion *)lb->first; + for (; region_main; region_main = region_main->next) { + if (region_main->regiontype == RGN_TYPE_WINDOW) { break; } } region = MEM_callocN(sizeof(ARegion), "preview area for sequencer"); - BLI_insertlinkbefore(lb, ar_main, region); + BLI_insertlinkbefore(lb, region_main, region); sequencer_init_preview_region(region); break; case SPACE_VIEW3D: @@ -256,7 +257,7 @@ static void area_add_window_regions(ScrArea *sa, SpaceLink *sl, ListBase *lb) region = MEM_callocN(sizeof(ARegion), "area region from do_versions"); BLI_addtail(lb, region); - region->winrct = sa->totrct; + region->winrct = area->totrct; region->regiontype = RGN_TYPE_WINDOW; @@ -303,7 +304,7 @@ static void area_add_window_regions(ScrArea *sa, SpaceLink *sl, ListBase *lb) SpaceNla *snla = (SpaceNla *)sl; memcpy(®ion->v2d, &snla->v2d, sizeof(View2D)); - region->v2d.tot.ymin = (float)(-sa->winy) / 3.0f; + region->v2d.tot.ymin = (float)(-area->winy) / 3.0f; region->v2d.tot.ymax = 0.0f; region->v2d.scroll |= (V2D_SCROLL_BOTTOM | V2D_SCROLL_HORIZONTAL_HANDLES); @@ -318,8 +319,8 @@ static void area_add_window_regions(ScrArea *sa, SpaceLink *sl, ListBase *lb) /* We totally reinit the view for the Action Editor, * as some old instances had some weird cruft set. */ region->v2d.tot.xmin = -20.0f; - region->v2d.tot.ymin = (float)(-sa->winy) / 3.0f; - region->v2d.tot.xmax = (float)((sa->winx > 120) ? (sa->winx) : 120); + region->v2d.tot.ymin = (float)(-area->winy) / 3.0f; + region->v2d.tot.xmax = (float)((area->winx > 120) ? (area->winx) : 120); region->v2d.tot.ymax = 0.0f; region->v2d.cur = region->v2d.tot; @@ -397,40 +398,40 @@ static void area_add_window_regions(ScrArea *sa, SpaceLink *sl, ListBase *lb) static void do_versions_windowmanager_2_50(bScreen *screen) { - ScrArea *sa; + ScrArea *area; SpaceLink *sl; /* add regions */ - for (sa = screen->areabase.first; sa; sa = sa->next) { + for (area = screen->areabase.first; area; area = area->next) { /* we keep headertype variable to convert old files only */ - if (sa->headertype) { - area_add_header_region(sa, &sa->regionbase); + if (area->headertype) { + area_add_header_region(area, &area->regionbase); } - area_add_window_regions(sa, sa->spacedata.first, &sa->regionbase); + area_add_window_regions(area, area->spacedata.first, &area->regionbase); /* space imageselect is deprecated */ - for (sl = sa->spacedata.first; sl; sl = sl->next) { + for (sl = area->spacedata.first; sl; sl = sl->next) { if (sl->spacetype == SPACE_IMASEL) { sl->spacetype = SPACE_EMPTY; /* spacedata then matches */ } } /* space sound is deprecated */ - for (sl = sa->spacedata.first; sl; sl = sl->next) { + for (sl = area->spacedata.first; sl; sl = sl->next) { if (sl->spacetype == SPACE_SOUND) { sl->spacetype = SPACE_EMPTY; /* spacedata then matches */ } } /* pushed back spaces also need regions! */ - if (sa->spacedata.first) { - sl = sa->spacedata.first; + if (area->spacedata.first) { + sl = area->spacedata.first; for (sl = sl->next; sl; sl = sl->next) { - if (sa->headertype) { - area_add_header_region(sa, &sl->regionbase); + if (area->headertype) { + area_add_header_region(area, &sl->regionbase); } - area_add_window_regions(sa, sl, &sl->regionbase); + area_add_window_regions(area, sl, &sl->regionbase); } } } @@ -455,12 +456,12 @@ static void versions_gpencil_add_main(ListBase *lb, ID *id, const char *name) static void do_versions_gpencil_2_50(Main *main, bScreen *screen) { - ScrArea *sa; + ScrArea *area; SpaceLink *sl; /* add regions */ - for (sa = screen->areabase.first; sa; sa = sa->next) { - for (sl = sa->spacedata.first; sl; sl = sl->next) { + for (area = screen->areabase.first; area; area = area->next) { + for (sl = area->spacedata.first; sl; sl = sl->next) { if (sl->spacetype == SPACE_VIEW3D) { View3D *v3d = (View3D *)sl; if (v3d->gpd) { @@ -514,7 +515,7 @@ static void do_version_mdef_250(Main *main) mmd->bindcagecos = mmd->bindcos; mmd->bindcos = NULL; - modifier_mdef_compact_influences(md); + BKE_modifier_mdef_compact_influences(md); } } } @@ -871,7 +872,7 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *bmain) for (ob = bmain->objects.first; ob; ob = ob->id.next) { /* fluid-sim stuff */ - FluidsimModifierData *fluidmd = (FluidsimModifierData *)modifiers_findByType( + FluidsimModifierData *fluidmd = (FluidsimModifierData *)BKE_modifiers_findby_type( ob, eModifierType_Fluidsim); if (fluidmd) { fluidmd->fss->fmd = fluidmd; @@ -918,8 +919,8 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *bmain) if (do_gravity) { for (md = ob->modifiers.first; md; md = md->next) { - ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, - eModifierType_Cloth); + ClothModifierData *clmd = (ClothModifierData *)BKE_modifiers_findby_type( + ob, eModifierType_Cloth); if (clmd) { clmd->sim_parms->effector_weights->global_gravity = clmd->sim_parms->gravity[2] / -9.81f; @@ -1079,12 +1080,12 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *bmain) { bScreen *screen; - ScrArea *sa; + ScrArea *area; SpaceLink *sl; for (screen = bmain->screens.first; screen; screen = screen->id.next) { - for (sa = screen->areabase.first; sa; sa = sa->next) { - for (sl = sa->spacedata.first; sl; sl = sl->next) { + for (area = screen->areabase.first; area; area = area->next) { + for (sl = area->spacedata.first; sl; sl = sl->next) { if (sl->spacetype == SPACE_VIEW3D) { View3D *v3d = (View3D *)sl; if (v3d->drawtype == OB_MATERIAL) { @@ -1154,7 +1155,7 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *bmain) } for (ob = bmain->objects.first; ob; ob = ob->id.next) { - MultiresModifierData *mmd = (MultiresModifierData *)modifiers_findByType( + MultiresModifierData *mmd = (MultiresModifierData *)BKE_modifiers_findby_type( ob, eModifierType_Multires); if (mmd) { @@ -1188,19 +1189,19 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *bmain) if (bmain->versionfile == 250 && bmain->subversionfile == 10) { /* fix for new view type in sequencer */ bScreen *screen; - ScrArea *sa; + ScrArea *area; SpaceLink *sl; /* remove all preview window in wrong spaces */ for (screen = bmain->screens.first; screen; screen = screen->id.next) { - for (sa = screen->areabase.first; sa; sa = sa->next) { - for (sl = sa->spacedata.first; sl; sl = sl->next) { + for (area = screen->areabase.first; area; area = area->next) { + for (sl = area->spacedata.first; sl; sl = sl->next) { if (sl->spacetype != SPACE_SEQ) { ARegion *region; ListBase *regionbase; - if (sl == sa->spacedata.first) { - regionbase = &sa->regionbase; + if (sl == area->spacedata.first) { + regionbase = &area->regionbase; } else { regionbase = &sl->regionbase; @@ -1227,20 +1228,20 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *bmain) { /* fix for new view type in sequencer */ bScreen *screen; - ScrArea *sa; + ScrArea *area; SpaceLink *sl; for (screen = bmain->screens.first; screen; screen = screen->id.next) { - for (sa = screen->areabase.first; sa; sa = sa->next) { - for (sl = sa->spacedata.first; sl; sl = sl->next) { + for (area = screen->areabase.first; area; area = area->next) { + for (sl = area->spacedata.first; sl; sl = sl->next) { if (sl->spacetype == SPACE_SEQ) { ARegion *region; - ARegion *ar_main; + ARegion *region_main; ListBase *regionbase; SpaceSeq *sseq = (SpaceSeq *)sl; - if (sl == sa->spacedata.first) { - regionbase = &sa->regionbase; + if (sl == area->spacedata.first) { + regionbase = &area->regionbase; } else { regionbase = &sl->regionbase; @@ -1253,14 +1254,14 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *bmain) sseq->mainb = SEQ_DRAW_IMG_IMBUF; } - ar_main = (ARegion *)regionbase->first; - for (; ar_main; ar_main = ar_main->next) { - if (ar_main->regiontype == RGN_TYPE_WINDOW) { + region_main = (ARegion *)regionbase->first; + for (; region_main; region_main = region_main->next) { + if (region_main->regiontype == RGN_TYPE_WINDOW) { break; } } region = MEM_callocN(sizeof(ARegion), "preview area for sequencer"); - BLI_insertlinkbefore(regionbase, ar_main, region); + BLI_insertlinkbefore(regionbase, region_main, region); sequencer_init_preview_region(region); } } @@ -1360,17 +1361,17 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *bmain) if (bmain->versionfile < 250 || (bmain->versionfile == 250 && bmain->subversionfile < 14)) { /* fix for bad View2D extents for Animation Editors */ bScreen *screen; - ScrArea *sa; + ScrArea *area; SpaceLink *sl; for (screen = bmain->screens.first; screen; screen = screen->id.next) { - for (sa = screen->areabase.first; sa; sa = sa->next) { - for (sl = sa->spacedata.first; sl; sl = sl->next) { + for (area = screen->areabase.first; area; area = area->next) { + for (sl = area->spacedata.first; sl; sl = sl->next) { ListBase *regionbase; ARegion *region; - if (sl == sa->spacedata.first) { - regionbase = &sa->regionbase; + if (sl == area->spacedata.first) { + regionbase = &area->regionbase; } else { regionbase = &sl->regionbase; @@ -1380,7 +1381,7 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *bmain) for (region = (ARegion *)regionbase->first; region; region = region->next) { if (region->regiontype == RGN_TYPE_WINDOW) { region->v2d.cur.ymax = region->v2d.tot.ymax = 0.0f; - region->v2d.cur.ymin = region->v2d.tot.ymin = (float)(-sa->winy) / 3.0f; + region->v2d.cur.ymin = region->v2d.tot.ymin = (float)(-area->winy) / 3.0f; } } } @@ -1426,31 +1427,31 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *bmain) /* sequencer changes */ { bScreen *screen; - ScrArea *sa; + ScrArea *area; SpaceLink *sl; for (screen = bmain->screens.first; screen; screen = screen->id.next) { - for (sa = screen->areabase.first; sa; sa = sa->next) { - for (sl = sa->spacedata.first; sl; sl = sl->next) { + for (area = screen->areabase.first; area; area = area->next) { + for (sl = area->spacedata.first; sl; sl = sl->next) { if (sl->spacetype == SPACE_SEQ) { - ARegion *ar_preview; + ARegion *region_preview; ListBase *regionbase; - if (sl == sa->spacedata.first) { - regionbase = &sa->regionbase; + if (sl == area->spacedata.first) { + regionbase = &area->regionbase; } else { regionbase = &sl->regionbase; } - ar_preview = (ARegion *)regionbase->first; - for (; ar_preview; ar_preview = ar_preview->next) { - if (ar_preview->regiontype == RGN_TYPE_PREVIEW) { + region_preview = (ARegion *)regionbase->first; + for (; region_preview; region_preview = region_preview->next) { + if (region_preview->regiontype == RGN_TYPE_PREVIEW) { break; } } - if (ar_preview && (ar_preview->regiontype == RGN_TYPE_PREVIEW)) { - sequencer_init_preview_region(ar_preview); + if (region_preview && (region_preview->regiontype == RGN_TYPE_PREVIEW)) { + sequencer_init_preview_region(region_preview); } } } @@ -1460,17 +1461,17 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *bmain) } if (bmain->versionfile <= 251) { /* 2.5.1 had no subversions */ - bScreen *sc; + bScreen *screen; /* Blender 2.5.2 - subversion 0 introduced a new setting: V3D_HIDE_OVERLAYS. * This bit was used in the past for V3D_TRANSFORM_SNAP, which is now deprecated. * Here we clear it for old files so they don't come in with V3D_HIDE_OVERLAYS set, * which would cause cameras, lights, etc to become invisible */ - for (sc = bmain->screens.first; sc; sc = sc->id.next) { - ScrArea *sa; - for (sa = sc->areabase.first; sa; sa = sa->next) { + for (screen = bmain->screens.first; screen; screen = screen->id.next) { + ScrArea *area; + for (area = screen->areabase.first; area; area = area->next) { SpaceLink *sl; - for (sl = sa->spacedata.first; sl; sl = sl->next) { + for (sl = area->spacedata.first; sl; sl = sl->next) { if (sl->spacetype == SPACE_VIEW3D) { View3D *v3d = (View3D *)sl; v3d->flag2 &= ~V3D_HIDE_OVERLAYS; @@ -1547,16 +1548,16 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *bmain) } if (bmain->versionfile < 252 || (bmain->versionfile == 252 && bmain->subversionfile < 5)) { - bScreen *sc; + bScreen *screen; /* Image editor scopes */ - for (sc = bmain->screens.first; sc; sc = sc->id.next) { - ScrArea *sa; + for (screen = bmain->screens.first; screen; screen = screen->id.next) { + ScrArea *area; - for (sa = sc->areabase.first; sa; sa = sa->next) { + for (area = screen->areabase.first; area; area = area->next) { SpaceLink *sl; - for (sl = sa->spacedata.first; sl; sl = sl->next) { + for (sl = area->spacedata.first; sl; sl = sl->next) { if (sl->spacetype == SPACE_IMAGE) { SpaceImage *sima = (SpaceImage *)sl; BKE_scopes_new(&sima->scopes); @@ -1569,23 +1570,23 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *bmain) if (bmain->versionfile < 253) { Object *ob; Scene *scene; - bScreen *sc; + bScreen *screen; Tex *tex; Brush *brush; - for (sc = bmain->screens.first; sc; sc = sc->id.next) { - ScrArea *sa; - for (sa = sc->areabase.first; sa; sa = sa->next) { + for (screen = bmain->screens.first; screen; screen = screen->id.next) { + ScrArea *area; + for (area = screen->areabase.first; area; area = area->next) { SpaceLink *sl; - for (sl = sa->spacedata.first; sl; sl = sl->next) { + for (sl = area->spacedata.first; sl; sl = sl->next) { if (sl->spacetype == SPACE_NODE) { SpaceNode *snode = (SpaceNode *)sl; ListBase *regionbase; ARegion *region; - if (sl == sa->spacedata.first) { - regionbase = &sa->regionbase; + if (sl == area->spacedata.first) { + regionbase = &area->regionbase; } else { regionbase = &sl->regionbase; @@ -1625,7 +1626,7 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *bmain) ArmatureModifierData *amd; bArmature *arm = (bArmature *)blo_do_versions_newlibadr(fd, lib, parent->data); - amd = (ArmatureModifierData *)modifier_new(eModifierType_Armature); + amd = (ArmatureModifierData *)BKE_modifier_new(eModifierType_Armature); amd->object = ob->parent; BLI_addtail((ListBase *)&ob->modifiers, amd); amd->deformflag = arm->deformflag; @@ -1634,7 +1635,7 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *bmain) else if (parent->type == OB_LATTICE && ob->partype == PARSKEL) { LatticeModifierData *lmd; - lmd = (LatticeModifierData *)modifier_new(eModifierType_Lattice); + lmd = (LatticeModifierData *)BKE_modifier_new(eModifierType_Lattice); lmd->object = ob->parent; BLI_addtail((ListBase *)&ob->modifiers, lmd); ob->partype = PAROBJECT; @@ -1642,7 +1643,7 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *bmain) else if (parent->type == OB_CURVE && ob->partype == PARCURVE) { CurveModifierData *cmd; - cmd = (CurveModifierData *)modifier_new(eModifierType_Curve); + cmd = (CurveModifierData *)BKE_modifier_new(eModifierType_Curve); cmd->object = ob->parent; BLI_addtail((ListBase *)&ob->modifiers, cmd); ob->partype = PAROBJECT; @@ -1833,7 +1834,7 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *bmain) if (bmain->versionfile < 255 || (bmain->versionfile == 255 && bmain->subversionfile < 1)) { Brush *br; ParticleSettings *part; - bScreen *sc; + bScreen *screen; for (br = bmain->brushes.first; br; br = br->id.next) { if (br->ob_mode == 0) { @@ -1850,18 +1851,18 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *bmain) part->kink_amp_clump = 1.f; /* keep old files looking similar */ } - for (sc = bmain->screens.first; sc; sc = sc->id.next) { - ScrArea *sa; - for (sa = sc->areabase.first; sa; sa = sa->next) { + for (screen = bmain->screens.first; screen; screen = screen->id.next) { + ScrArea *area; + for (area = screen->areabase.first; area; area = area->next) { SpaceLink *sl; - for (sl = sa->spacedata.first; sl; sl = sl->next) { + for (sl = area->spacedata.first; sl; sl = sl->next) { if (sl->spacetype == SPACE_INFO) { SpaceInfo *sinfo = (SpaceInfo *)sl; ARegion *region; sinfo->rpt_mask = INFO_RPT_OP; - for (region = sa->regionbase.first; region; region = region->next) { + for (region = area->regionbase.first; region; region = region->next) { if (region->regiontype == RGN_TYPE_WINDOW) { region->v2d.scroll = (V2D_SCROLL_RIGHT); region->v2d.align = V2D_ALIGN_NO_NEG_X | @@ -1896,16 +1897,16 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *bmain) } if (bmain->versionfile < 256) { - bScreen *sc; - ScrArea *sa; + bScreen *screen; + ScrArea *area; Key *key; /* Fix for sample line scope initializing with no height */ - for (sc = bmain->screens.first; sc; sc = sc->id.next) { - sa = sc->areabase.first; - while (sa) { + for (screen = bmain->screens.first; screen; screen = screen->id.next) { + area = screen->areabase.first; + while (area) { SpaceLink *sl; - for (sl = sa->spacedata.first; sl; sl = sl->next) { + for (sl = area->spacedata.first; sl; sl = sl->next) { if (sl->spacetype == SPACE_IMAGE) { SpaceImage *sima = (SpaceImage *)sl; if (sima->sample_line_hist.height == 0) { @@ -1913,7 +1914,7 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *bmain) } } } - sa = sa->next; + area = area->next; } } @@ -2040,18 +2041,18 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *bmain) } if (bmain->versionfile < 256 || (bmain->versionfile == 256 && bmain->subversionfile < 3)) { - bScreen *sc; + bScreen *screen; Brush *brush; Object *ob; ParticleSettings *part; /* redraws flag in SpaceTime has been moved to Screen level */ - for (sc = bmain->screens.first; sc; sc = sc->id.next) { - if (sc->redraws_flag == 0) { + for (screen = bmain->screens.first; screen; screen = screen->id.next) { + if (screen->redraws_flag == 0) { /* just initialize to default? */ /* XXX: we could also have iterated through areas, * and taken them from the first timeline available... */ - sc->redraws_flag = TIME_ALL_3D_WIN | TIME_ALL_ANIM_WIN; + screen->redraws_flag = TIME_ALL_3D_WIN | TIME_ALL_ANIM_WIN; } } @@ -2117,13 +2118,13 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *bmain) bScreen *screen; for (screen = bmain->screens.first; screen; screen = screen->id.next) { - ScrArea *sa; + ScrArea *area; /* add regions */ - for (sa = screen->areabase.first; sa; sa = sa->next) { - SpaceLink *sl = sa->spacedata.first; + for (area = screen->areabase.first; area; area = area->next) { + SpaceLink *sl = area->spacedata.first; if (sl->spacetype == SPACE_IMAGE) { ARegion *region; - for (region = sa->regionbase.first; region; region = region->next) { + for (region = area->regionbase.first; region; region = region->next) { if (region->regiontype == RGN_TYPE_WINDOW) { View2D *v2d = ®ion->v2d; v2d->minzoom = v2d->maxzoom = v2d->scroll = v2d->keeptot = v2d->keepzoom = @@ -2132,7 +2133,7 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *bmain) } } - for (sl = sa->spacedata.first; sl; sl = sl->next) { + for (sl = area->spacedata.first; sl; sl = sl->next) { if (sl->spacetype == SPACE_IMAGE) { ARegion *region; for (region = sl->regionbase.first; region; region = region->next) { @@ -2174,14 +2175,14 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *bmain) { bScreen *screen; for (screen = bmain->screens.first; screen; screen = screen->id.next) { - ScrArea *sa; + ScrArea *area; /* add regions */ - for (sa = screen->areabase.first; sa; sa = sa->next) { - SpaceLink *sl = sa->spacedata.first; + for (area = screen->areabase.first; area; area = area->next) { + SpaceLink *sl = area->spacedata.first; if (sl->spacetype == SPACE_SEQ) { ARegion *region; - for (region = sa->regionbase.first; region; region = region->next) { + for (region = area->regionbase.first; region; region = region->next) { if (region->regiontype == RGN_TYPE_WINDOW) { if (region->v2d.min[1] == 4.0f) { region->v2d.min[1] = 0.5f; @@ -2189,7 +2190,7 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *bmain) } } } - for (sl = sa->spacedata.first; sl; sl = sl->next) { + for (sl = area->spacedata.first; sl; sl = sl->next) { if (sl->spacetype == SPACE_SEQ) { ARegion *region; for (region = sl->regionbase.first; region; region = region->next) { @@ -2352,4 +2353,32 @@ void do_versions_after_linking_250(Main *bmain) } FOREACH_NODETREE_END; } + + if (!MAIN_VERSION_ATLEAST(bmain, 258, 0)) { + /* Some very old (original comments claim pre-2.57) versioning that was wrongly done in + * lib-linking code... Putting it here just to be sure (this is also checked at runtime anyway + * by `action_idcode_patch_check`). */ + ID *id; + FOREACH_MAIN_ID_BEGIN (bmain, id) { + AnimData *adt = BKE_animdata_from_id(id); + if (adt != NULL) { + /* Fix actions' id-roots (i.e. if they come from a pre 2.57 .blend file). */ + if ((adt->action) && (adt->action->idroot == 0)) { + adt->action->idroot = GS(id->name); + } + if ((adt->tmpact) && (adt->tmpact->idroot == 0)) { + adt->tmpact->idroot = GS(id->name); + } + + LISTBASE_FOREACH (NlaTrack *, nla_track, &adt->nla_tracks) { + LISTBASE_FOREACH (NlaStrip *, nla_strip, &nla_track->strips) { + if ((nla_strip->act) && (nla_strip->act->idroot == 0)) { + nla_strip->act->idroot = GS(id->name); + } + } + } + } + } + FOREACH_MAIN_ID_END; + } } diff --git a/source/blender/blenloader/intern/versioning_260.c b/source/blender/blenloader/intern/versioning_260.c index 26de003dc17..98e10bef470 100644 --- a/source/blender/blenloader/intern/versioning_260.c +++ b/source/blender/blenloader/intern/versioning_260.c @@ -52,7 +52,7 @@ #include "BLT_translation.h" -#include "BKE_anim.h" +#include "BKE_anim_visualization.h" #include "BKE_image.h" #include "BKE_main.h" // for Main #include "BKE_mesh.h" // for ME_ defines (patching) @@ -765,14 +765,14 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *bmain) { /* Tomato compatibility code. */ - bScreen *sc; + bScreen *screen; MovieClip *clip; - for (sc = bmain->screens.first; sc; sc = sc->id.next) { - ScrArea *sa; - for (sa = sc->areabase.first; sa; sa = sa->next) { + for (screen = bmain->screens.first; screen; screen = screen->id.next) { + ScrArea *area; + for (area = screen->areabase.first; area; area = area->next) { SpaceLink *sl; - for (sl = sa->spacedata.first; sl; sl = sl->next) { + for (sl = area->spacedata.first; sl; sl = sl->next) { if (sl->spacetype == SPACE_VIEW3D) { View3D *v3d = (View3D *)sl; if (v3d->bundle_size == 0.0f) { @@ -1188,20 +1188,20 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *bmain) } if (bmain->versionfile < 263 || (bmain->versionfile == 263 && bmain->subversionfile < 2)) { - bScreen *sc; + bScreen *screen; - for (sc = bmain->screens.first; sc; sc = sc->id.next) { - ScrArea *sa; - for (sa = sc->areabase.first; sa; sa = sa->next) { + for (screen = bmain->screens.first; screen; screen = screen->id.next) { + ScrArea *area; + for (area = screen->areabase.first; area; area = area->next) { SpaceLink *sl; - for (sl = sa->spacedata.first; sl; sl = sl->next) { + for (sl = area->spacedata.first; sl; sl = sl->next) { if (sl->spacetype == SPACE_CLIP) { SpaceClip *sclip = (SpaceClip *)sl; ARegion *region; bool hide = false; - for (region = sa->regionbase.first; region; region = region->next) { + for (region = area->regionbase.first; region; region = region->next) { if (region->regiontype == RGN_TYPE_PREVIEW) { if (region->alignment != RGN_ALIGN_NONE) { region->flag |= RGN_FLAG_HIDDEN; @@ -1368,15 +1368,15 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *bmain) } { - bScreen *sc; + bScreen *screen; - for (sc = bmain->screens.first; sc; sc = sc->id.next) { - ScrArea *sa; + for (screen = bmain->screens.first; screen; screen = screen->id.next) { + ScrArea *area; - for (sa = sc->areabase.first; sa; sa = sa->next) { + for (area = screen->areabase.first; area; area = area->next) { SpaceLink *sl; - for (sl = sa->spacedata.first; sl; sl = sl->next) { + for (sl = area->spacedata.first; sl; sl = sl->next) { if (sl->spacetype == SPACE_CLIP) { SpaceClip *sclip = (SpaceClip *)sl; @@ -1661,13 +1661,13 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *bmain) /* render border for viewport */ { - bScreen *sc; + bScreen *screen; - for (sc = bmain->screens.first; sc; sc = sc->id.next) { - ScrArea *sa; - for (sa = sc->areabase.first; sa; sa = sa->next) { + for (screen = bmain->screens.first; screen; screen = screen->id.next) { + ScrArea *area; + for (area = screen->areabase.first; area; area = area->next) { SpaceLink *sl; - for (sl = sa->spacedata.first; sl; sl = sl->next) { + for (sl = area->spacedata.first; sl; sl = sl->next) { if (sl->spacetype == SPACE_VIEW3D) { View3D *v3d = (View3D *)sl; if (v3d->render_border.xmin == 0.0f && v3d->render_border.ymin == 0.0f && @@ -1758,12 +1758,12 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *bmain) } if (bmain->versionfile < 265 || (bmain->versionfile == 265 && bmain->subversionfile < 3)) { - bScreen *sc; - for (sc = bmain->screens.first; sc; sc = sc->id.next) { - ScrArea *sa; - for (sa = sc->areabase.first; sa; sa = sa->next) { + bScreen *screen; + for (screen = bmain->screens.first; screen; screen = screen->id.next) { + ScrArea *area; + for (area = screen->areabase.first; area; area = area->next) { SpaceLink *sl; - for (sl = sa->spacedata.first; sl; sl = sl->next) { + for (sl = area->spacedata.first; sl; sl = sl->next) { switch (sl->spacetype) { case SPACE_VIEW3D: { View3D *v3d = (View3D *)sl; @@ -1943,12 +1943,12 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *bmain) } if (MAIN_VERSION_OLDER(bmain, 266, 2)) { - bScreen *sc; - for (sc = bmain->screens.first; sc; sc = sc->id.next) { - ScrArea *sa; - for (sa = sc->areabase.first; sa; sa = sa->next) { + bScreen *screen; + for (screen = bmain->screens.first; screen; screen = screen->id.next) { + ScrArea *area; + for (area = screen->areabase.first; area; area = area->next) { SpaceLink *sl; - for (sl = sa->spacedata.first; sl; sl = sl->next) { + for (sl = area->spacedata.first; sl; sl = sl->next) { if (sl->spacetype == SPACE_NODE) { SpaceNode *snode = (SpaceNode *)sl; @@ -2119,10 +2119,10 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *bmain) bNodeInstanceKey active_viewer_key = {0}; /* simply pick the first node space and use that for the active viewer key */ for (screen = bmain->screens.first; screen; screen = screen->id.next) { - ScrArea *sa; - for (sa = screen->areabase.first; sa; sa = sa->next) { + ScrArea *area; + for (area = screen->areabase.first; area; area = area->next) { SpaceLink *sl; - for (sl = sa->spacedata.first; sl; sl = sl->next) { + for (sl = area->spacedata.first; sl; sl = sl->next) { if (sl->spacetype == SPACE_NODE) { SpaceNode *snode = (SpaceNode *)sl; bNodeTreePath *path = snode->treepath.last; @@ -2199,7 +2199,7 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *bmain) } if (!MAIN_VERSION_ATLEAST(bmain, 268, 4)) { - bScreen *sc; + bScreen *screen; Object *ob; for (ob = bmain->objects.first; ob; ob = ob->id.next) { @@ -2240,11 +2240,11 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *bmain) * * We moved this check to the do versions to be sure the value makes any sense. */ - for (sc = bmain->screens.first; sc; sc = sc->id.next) { - ScrArea *sa; - for (sa = sc->areabase.first; sa; sa = sa->next) { + for (screen = bmain->screens.first; screen; screen = screen->id.next) { + ScrArea *area; + for (area = screen->areabase.first; area; area = area->next) { SpaceLink *sl; - for (sl = sa->spacedata.first; sl; sl = sl->next) { + for (sl = area->spacedata.first; sl; sl = sl->next) { if (sl->spacetype == SPACE_NODE) { SpaceNode *snode = (SpaceNode *)sl; if (snode->zoom < 0.02f) { @@ -2257,23 +2257,23 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *bmain) } if (!MAIN_VERSION_ATLEAST(bmain, 268, 5)) { - bScreen *sc; - ScrArea *sa; + bScreen *screen; + ScrArea *area; /* add missing (+) expander in node editor */ - for (sc = bmain->screens.first; sc; sc = sc->id.next) { - for (sa = sc->areabase.first; sa; sa = sa->next) { + for (screen = bmain->screens.first; screen; screen = screen->id.next) { + for (area = screen->areabase.first; area; area = area->next) { ARegion *region, *arnew; - if (sa->spacetype == SPACE_NODE) { - region = BKE_area_find_region_type(sa, RGN_TYPE_TOOLS); + if (area->spacetype == SPACE_NODE) { + region = BKE_area_find_region_type(area, RGN_TYPE_TOOLS); if (region) { continue; } /* add subdiv level; after header */ - region = BKE_area_find_region_type(sa, RGN_TYPE_HEADER); + region = BKE_area_find_region_type(area, RGN_TYPE_HEADER); /* is error! */ if (region == NULL) { @@ -2282,7 +2282,7 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *bmain) arnew = MEM_callocN(sizeof(ARegion), "node tools"); - BLI_insertlinkafter(&sa->regionbase, region, arnew); + BLI_insertlinkafter(&area->regionbase, region, arnew); arnew->regiontype = RGN_TYPE_TOOLS; arnew->alignment = RGN_ALIGN_LEFT; @@ -2338,15 +2338,15 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *bmain) } if (!MAIN_VERSION_ATLEAST(bmain, 269, 3)) { - bScreen *sc; - ScrArea *sa; + bScreen *screen; + ScrArea *area; SpaceLink *sl; Scene *scene; /* Update files using invalid (outdated) outlinevis Outliner values. */ - for (sc = bmain->screens.first; sc; sc = sc->id.next) { - for (sa = sc->areabase.first; sa; sa = sa->next) { - for (sl = sa->spacedata.first; sl; sl = sl->next) { + for (screen = bmain->screens.first; screen; screen = screen->id.next) { + for (area = screen->areabase.first; area; area = area->next) { + for (sl = area->spacedata.first; sl; sl = sl->next) { if (sl->spacetype == SPACE_OUTLINER) { SpaceOutliner *so = (SpaceOutliner *)sl; @@ -2542,20 +2542,20 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *bmain) } if (!MAIN_VERSION_ATLEAST(bmain, 269, 11)) { - bScreen *sc; + bScreen *screen; - for (sc = bmain->screens.first; sc; sc = sc->id.next) { - ScrArea *sa; - for (sa = sc->areabase.first; sa; sa = sa->next) { + for (screen = bmain->screens.first; screen; screen = screen->id.next) { + ScrArea *area; + for (area = screen->areabase.first; area; area = area->next) { SpaceLink *space_link; - for (space_link = sa->spacedata.first; space_link; space_link = space_link->next) { + for (space_link = area->spacedata.first; space_link; space_link = space_link->next) { if (space_link->spacetype == SPACE_IMAGE) { ARegion *region; ListBase *lb; - if (space_link == sa->spacedata.first) { - lb = &sa->regionbase; + if (space_link == area->spacedata.first) { + lb = &area->regionbase; } else { lb = &space_link->regionbase; diff --git a/source/blender/blenloader/intern/versioning_270.c b/source/blender/blenloader/intern/versioning_270.c index 80f75a7ac4a..0ca6fd34535 100644 --- a/source/blender/blenloader/intern/versioning_270.c +++ b/source/blender/blenloader/intern/versioning_270.c @@ -52,9 +52,10 @@ #include "DNA_genfile.h" +#include "BKE_anim_data.h" #include "BKE_animsys.h" #include "BKE_colortools.h" -#include "BKE_fcurve.h" +#include "BKE_fcurve_driver.h" #include "BKE_main.h" #include "BKE_mask.h" #include "BKE_modifier.h" @@ -257,7 +258,7 @@ static void do_version_action_editor_properties_region(ListBase *regionbase) static void do_version_bones_super_bbone(ListBase *lb) { - for (Bone *bone = lb->first; bone; bone = bone->next) { + LISTBASE_FOREACH (Bone *, bone, lb) { bone->scale_in_x = bone->scale_in_y = 1.0f; bone->scale_out_x = bone->scale_out_y = 1.0f; @@ -342,7 +343,7 @@ static void do_versions_compositor_render_passes_storage(bNode *node) static void do_versions_compositor_render_passes(bNodeTree *ntree) { - for (bNode *node = ntree->nodes.first; node; node = node->next) { + LISTBASE_FOREACH (bNode *, node, &ntree->nodes) { if (node->type == CMP_NODE_R_LAYERS) { /* First we make sure existing sockets have proper names. * This is important because otherwise verification will @@ -391,7 +392,7 @@ static void do_version_bbone_easing_fcurve_fix(ID *UNUSED(id), /* Driver -> Driver Vars (for bbone_in/out) */ if (fcu->driver) { - for (DriverVar *dvar = fcu->driver->variables.first; dvar; dvar = dvar->next) { + LISTBASE_FOREACH (DriverVar *, dvar, &fcu->driver->variables) { DRIVER_TARGETS_LOOPER_BEGIN (dvar) { if (dtar->rna_path) { dtar->rna_path = replace_bbone_easing_rnapath(dtar->rna_path); @@ -403,7 +404,7 @@ static void do_version_bbone_easing_fcurve_fix(ID *UNUSED(id), /* FModifiers -> Stepped (for frame_start/end) */ if (fcu->modifiers.first) { - for (FModifier *fcm = fcu->modifiers.first; fcm; fcm = fcm->next) { + LISTBASE_FOREACH (FModifier *, fcm, &fcu->modifiers) { if (fcm->type == FMODIFIER_TYPE_STEPPED) { FMod_Stepped *data = fcm->data; @@ -519,16 +520,16 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *bmain) * leading to corrupted files (see T39847). * This will always reset situation to a valid state. */ - bScreen *sc; + bScreen *screen; - for (sc = bmain->screens.first; sc; sc = sc->id.next) { - ScrArea *sa; - for (sa = sc->areabase.first; sa; sa = sa->next) { + for (screen = bmain->screens.first; screen; screen = screen->id.next) { + ScrArea *area; + for (area = screen->areabase.first; area; area = area->next) { SpaceLink *sl; - for (sl = sa->spacedata.first; sl; sl = sl->next) { + for (sl = area->spacedata.first; sl; sl = sl->next) { ARegion *region; - ListBase *lb = (sl == sa->spacedata.first) ? &sa->regionbase : &sl->regionbase; + ListBase *lb = (sl == area->spacedata.first) ? &area->regionbase : &sl->regionbase; for (region = lb->first; region; region = region->next) { BLI_listbase_clear(®ion->ui_previews); @@ -840,7 +841,7 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *bmain) for (ob = bmain->objects.first; ob != NULL; ob = ob->id.next) { ModifierData *md; for (md = ob->modifiers.last; md != NULL; md = md->prev) { - if (modifier_unique_name(&ob->modifiers, md)) { + if (BKE_modifier_unique_name(&ob->modifiers, md)) { printf( "Warning: Object '%s' had several modifiers with the " "same name, renamed one of them to '%s'.\n", @@ -852,15 +853,15 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *bmain) } if (!MAIN_VERSION_ATLEAST(bmain, 273, 9)) { - bScreen *scr; - ScrArea *sa; + bScreen *screen; + ScrArea *area; SpaceLink *sl; ARegion *region; /* Make sure sequencer preview area limits zoom */ - for (scr = bmain->screens.first; scr; scr = scr->id.next) { - for (sa = scr->areabase.first; sa; sa = sa->next) { - for (sl = sa->spacedata.first; sl; sl = sl->next) { + for (screen = bmain->screens.first; screen; screen = screen->id.next) { + for (area = screen->areabase.first; area; area = area->next) { + for (sl = area->spacedata.first; sl; sl = sl->next) { if (sl->spacetype == SPACE_SEQ) { for (region = sl->regionbase.first; region; region = region->next) { if (region->regiontype == RGN_TYPE_PREVIEW) { @@ -942,11 +943,11 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *bmain) } for (screen = bmain->screens.first; screen; screen = screen->id.next) { - ScrArea *sa; - for (sa = screen->areabase.first; sa; sa = sa->next) { + ScrArea *area; + for (area = screen->areabase.first; area; area = area->next) { SpaceLink *sl; - for (sl = sa->spacedata.first; sl; sl = sl->next) { + for (sl = area->spacedata.first; sl; sl = sl->next) { switch (sl->spacetype) { case SPACE_VIEW3D: { View3D *v3d = (View3D *)sl; @@ -996,12 +997,12 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *bmain) if (!DNA_struct_elem_find(fd->filesdna, "FileSelectParams", "int", "thumbnail_size")) { for (screen = bmain->screens.first; screen; screen = screen->id.next) { - ScrArea *sa; + ScrArea *area; - for (sa = screen->areabase.first; sa; sa = sa->next) { + for (area = screen->areabase.first; area; area = area->next) { SpaceLink *sl; - for (sl = sa->spacedata.first; sl; sl = sl->next) { + for (sl = area->spacedata.first; sl; sl = sl->next) { if (sl->spacetype == SPACE_FILE) { SpaceFile *sfile = (SpaceFile *)sl; @@ -1064,13 +1065,13 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *bmain) bScreen *screen; #define RV3D_VIEW_PERSPORTHO 7 for (screen = bmain->screens.first; screen; screen = screen->id.next) { - ScrArea *sa; - for (sa = screen->areabase.first; sa; sa = sa->next) { + ScrArea *area; + for (area = screen->areabase.first; area; area = area->next) { SpaceLink *sl; - for (sl = sa->spacedata.first; sl; sl = sl->next) { + for (sl = area->spacedata.first; sl; sl = sl->next) { if (sl->spacetype == SPACE_VIEW3D) { ARegion *region; - ListBase *lb = (sl == sa->spacedata.first) ? &sa->regionbase : &sl->regionbase; + ListBase *lb = (sl == area->spacedata.first) ? &area->regionbase : &sl->regionbase; for (region = lb->first; region; region = region->next) { if (region->regiontype == RGN_TYPE_WINDOW) { if (region->regiondata) { @@ -1152,7 +1153,7 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *bmain) * otherwise they could collide with any new persistent flag we may add in the future. */ a = set_listbasepointers(bmain, lbarray); while (a--) { - for (ID *id = lbarray[a]->first; id; id = id->next) { + LISTBASE_FOREACH (ID *, id, lbarray[a]) { id->flag &= LIB_FAKEUSER; } } @@ -1176,14 +1177,15 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *bmain) } for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) { - for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) { - for (SpaceLink *sl = sa->spacedata.first; sl; sl = sl->next) { - ListBase *regionbase = (sl == sa->spacedata.first) ? &sa->regionbase : &sl->regionbase; + LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { + LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) { + ListBase *regionbase = (sl == area->spacedata.first) ? &area->regionbase : + &sl->regionbase; /* Bug: Was possible to add preview region to sequencer view by using AZones. */ if (sl->spacetype == SPACE_SEQ) { SpaceSeq *sseq = (SpaceSeq *)sl; if (sseq->view == SEQ_VIEW_SEQUENCE) { - for (ARegion *region = regionbase->first; region; region = region->next) { + LISTBASE_FOREACH (ARegion *, region, regionbase) { /* remove preview region for sequencer-only view! */ if (region->regiontype == RGN_TYPE_PREVIEW) { region->flag |= RGN_FLAG_HIDDEN; @@ -1195,7 +1197,7 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *bmain) } /* Remove old deprecated region from filebrowsers */ else if (sl->spacetype == SPACE_FILE) { - for (ARegion *region = regionbase->first; region; region = region->next) { + LISTBASE_FOREACH (ARegion *, region, regionbase) { if (region->regiontype == RGN_TYPE_CHANNELS) { /* Free old deprecated 'channel' region... */ BKE_area_region_free(NULL, region); @@ -1243,9 +1245,9 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *bmain) /* Adding "Properties" region to DopeSheet */ for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) { - for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) { + LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { /* handle pushed-back space data first */ - for (SpaceLink *sl = sa->spacedata.first; sl; sl = sl->next) { + LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) { if (sl->spacetype == SPACE_ACTION) { SpaceAction *saction = (SpaceAction *)sl; do_version_action_editor_properties_region(&saction->regionbase); @@ -1253,8 +1255,8 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *bmain) } /* active spacedata info must be handled too... */ - if (sa->spacetype == SPACE_ACTION) { - do_version_action_editor_properties_region(&sa->regionbase); + if (area->spacetype == SPACE_ACTION) { + do_version_action_editor_properties_region(&area->regionbase); } } } @@ -1269,7 +1271,7 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *bmain) if (!DNA_struct_elem_find(fd->filesdna, "bPoseChannel", "float", "scaleIn")) { for (Object *ob = bmain->objects.first; ob; ob = ob->id.next) { if (ob->pose) { - for (bPoseChannel *pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) { + LISTBASE_FOREACH (bPoseChannel *, pchan, &ob->pose->chanbase) { /* see do_version_bones_super_bbone()... */ pchan->scale_in_x = pchan->scale_in_y = 1.0f; pchan->scale_out_x = pchan->scale_out_y = 1.0f; @@ -1559,8 +1561,8 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *bmain) if (!MAIN_VERSION_ATLEAST(bmain, 278, 5)) { /* Mask primitive adding code was not initializing correctly id_type of its points' parent. */ for (Mask *mask = bmain->masks.first; mask; mask = mask->id.next) { - for (MaskLayer *mlayer = mask->masklayers.first; mlayer; mlayer = mlayer->next) { - for (MaskSpline *mspline = mlayer->splines.first; mspline; mspline = mspline->next) { + LISTBASE_FOREACH (MaskLayer *, mlayer, &mask->masklayers) { + LISTBASE_FOREACH (MaskSpline *, mspline, &mlayer->splines) { int i = 0; for (MaskSplinePoint *mspoint = mspline->points; i < mspline->tot_point; mspoint++, i++) { @@ -1577,7 +1579,7 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *bmain) FOREACH_NODETREE_BEGIN (bmain, ntree, id) { if (ntree->type == NTREE_COMPOSIT) { ntreeSetTypes(NULL, ntree); - for (bNode *node = ntree->nodes.first; node; node = node->next) { + LISTBASE_FOREACH (bNode *, node, &ntree->nodes) { if (node->type == CMP_NODE_GLARE) { NodeGlare *ndg = node->storage; switch (ndg->type) { @@ -1599,7 +1601,7 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *bmain) if (!DNA_struct_elem_find(fd->filesdna, "SurfaceDeformModifierData", "float", "mat[4][4]")) { for (Object *ob = bmain->objects.first; ob; ob = ob->id.next) { - for (ModifierData *md = ob->modifiers.first; md; md = md->next) { + LISTBASE_FOREACH (ModifierData *, md, &ob->modifiers) { if (md->type == eModifierType_SurfaceDeform) { SurfaceDeformModifierData *smd = (SurfaceDeformModifierData *)md; unit_m4(smd->mat); @@ -1649,10 +1651,10 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *bmain) if (!MAIN_VERSION_ATLEAST(bmain, 279, 4)) { /* Fix for invalid state of screen due to bug in older versions. */ - for (bScreen *sc = bmain->screens.first; sc; sc = sc->id.next) { - for (ScrArea *sa = sc->areabase.first; sa; sa = sa->next) { - if (sa->full && sc->state == SCREENNORMAL) { - sa->full = NULL; + for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) { + LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { + if (area->full && screen->state == SCREENNORMAL) { + area->full = NULL; } } } @@ -1681,7 +1683,7 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *bmain) * Must set previous defaults. */ if (!DNA_struct_elem_find(fd->filesdna, "SimpleDeformModifierData", "char", "deform_axis")) { for (Object *ob = bmain->objects.first; ob; ob = ob->id.next) { - for (ModifierData *md = ob->modifiers.first; md; md = md->next) { + LISTBASE_FOREACH (ModifierData *, md, &ob->modifiers) { if (md->type == eModifierType_SimpleDeform) { SimpleDeformModifierData *smd = (SimpleDeformModifierData *)md; smd->deform_axis = 2; @@ -1710,7 +1712,7 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *bmain) if (!DNA_struct_elem_find( fd->filesdna, "ParticleInstanceModifierData", "float", "particle_amount")) { for (Object *ob = bmain->objects.first; ob; ob = ob->id.next) { - for (ModifierData *md = ob->modifiers.first; md; md = md->next) { + LISTBASE_FOREACH (ModifierData *, md, &ob->modifiers) { if (md->type == eModifierType_ParticleInstance) { ParticleInstanceModifierData *pimd = (ParticleInstanceModifierData *)md; pimd->space = eParticleInstanceSpace_World; @@ -1729,7 +1731,7 @@ void do_versions_after_linking_270(Main *bmain) FOREACH_NODETREE_BEGIN (bmain, ntree, id) { if (ntree->type == NTREE_COMPOSIT) { ntreeSetTypes(NULL, ntree); - for (bNode *node = ntree->nodes.first; node; node = node->next) { + LISTBASE_FOREACH (bNode *, node, &ntree->nodes) { if (node->type == CMP_NODE_HUE_SAT) { do_version_hue_sat_node(ntree, node); } diff --git a/source/blender/blenloader/intern/versioning_280.c b/source/blender/blenloader/intern/versioning_280.c index eda13dce084..6211c58d7d4 100644 --- a/source/blender/blenloader/intern/versioning_280.c +++ b/source/blender/blenloader/intern/versioning_280.c @@ -40,6 +40,7 @@ #include "DNA_constraint_types.h" #include "DNA_curve_types.h" #include "DNA_curveprofile_types.h" +#include "DNA_fluid_types.h" #include "DNA_freestyle_types.h" #include "DNA_genfile.h" #include "DNA_gpencil_modifier_types.h" @@ -74,6 +75,7 @@ #include "BKE_curveprofile.h" #include "BKE_customdata.h" #include "BKE_fcurve.h" +#include "BKE_fcurve_driver.h" #include "BKE_freestyle.h" #include "BKE_global.h" #include "BKE_gpencil.h" @@ -111,15 +113,44 @@ /* Make preferences read-only, use versioning_userdef.c. */ #define U (*((const UserDef *)&U)) +/** + * Rename if the ID doesn't exist. + */ +static ID *rename_id_for_versioning(Main *bmain, + const short id_type, + const char *name_src, + const char *name_dst) +{ + /* We can ignore libraries */ + ListBase *lb = which_libbase(bmain, id_type); + ID *id = NULL; + LISTBASE_FOREACH (ID *, idtest, lb) { + if (idtest->lib == NULL) { + if (STREQ(idtest->name + 2, name_src)) { + id = idtest; + } + if (STREQ(idtest->name + 2, name_dst)) { + return NULL; + } + } + } + if (id != NULL) { + BLI_strncpy(id->name + 2, name_dst, sizeof(id->name) - 2); + /* We know it's unique, this just sorts. */ + BLI_libblock_ensure_unique_name(bmain, id->name); + } + return id; +} + static bScreen *screen_parent_find(const bScreen *screen) { /* Can avoid lookup if screen state isn't maximized/full * (parent and child store the same state). */ if (ELEM(screen->state, SCREENMAXIMIZED, SCREENFULL)) { - for (const ScrArea *sa = screen->areabase.first; sa; sa = sa->next) { - if (sa->full && sa->full != screen) { - BLI_assert(sa->full->state == screen->state); - return sa->full; + LISTBASE_FOREACH (const ScrArea *, area, &screen->areabase) { + if (area->full && area->full != screen) { + BLI_assert(area->full->state == screen->state); + return area->full; } } } @@ -129,6 +160,8 @@ static bScreen *screen_parent_find(const bScreen *screen) static void do_version_workspaces_create_from_screens(Main *bmain) { + bmain->is_locked_for_linking = false; + for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) { const bScreen *screen_parent = screen_parent_find(screen); WorkSpace *workspace; @@ -150,6 +183,8 @@ static void do_version_workspaces_create_from_screens(Main *bmain) } BKE_workspace_layout_add(bmain, workspace, screen, screen->id.name + 2); } + + bmain->is_locked_for_linking = true; } static void do_version_area_change_space_to_space_action(ScrArea *area, const Scene *scene) @@ -159,7 +194,7 @@ static void do_version_area_change_space_to_space_action(ScrArea *area, const Sc ARegion *region_channels; /* Properly free current regions */ - for (ARegion *region = area->regionbase.first; region; region = region->next) { + LISTBASE_FOREACH (ARegion *, region, &area->regionbase) { BKE_area_region_free(area->type, region); } BLI_freelistN(&area->regionbase); @@ -199,7 +234,7 @@ static void do_version_workspaces_after_lib_link(Main *bmain) do_version_workspaces_create_from_screens(bmain); for (wmWindowManager *wm = bmain->wm.first; wm; wm = wm->id.next) { - for (wmWindow *win = wm->windows.first; win; win = win->next) { + LISTBASE_FOREACH (wmWindow *, win, &wm->windows) { bScreen *screen_parent = screen_parent_find(win->screen); bScreen *screen = screen_parent ? screen_parent : win->screen; @@ -222,7 +257,7 @@ static void do_version_workspaces_after_lib_link(Main *bmain) win->workspace_hook = BKE_workspace_instance_hook_create(bmain); BKE_workspace_active_set(win->workspace_hook, workspace); - BKE_workspace_active_layout_set(win->workspace_hook, layout); + BKE_workspace_active_layout_set(win->workspace_hook, workspace, layout); /* Move scene and view layer to window. */ Scene *scene = screen->scene; @@ -278,7 +313,7 @@ static void do_version_layer_collection_pre(ViewLayer *view_layer, GSet *selectable_set) { /* Convert from deprecated DISABLED to new layer collection and collection flags */ - for (LayerCollection *lc = lb->first; lc; lc = lc->next) { + LISTBASE_FOREACH (LayerCollection *, lc, lb) { if (lc->scene_collection) { if (!(lc->flag & COLLECTION_DEPRECATED_DISABLED)) { BLI_gset_insert(enabled_set, lc->scene_collection); @@ -300,7 +335,7 @@ static void do_version_layer_collection_post(ViewLayer *view_layer, GHash *collection_map) { /* Apply layer collection exclude flags. */ - for (LayerCollection *lc = lb->first; lc; lc = lc->next) { + LISTBASE_FOREACH (LayerCollection *, lc, lb) { if (!(lc->collection->flag & COLLECTION_IS_MASTER)) { SceneCollection *sc = BLI_ghash_lookup(collection_map, lc->collection); const bool enabled = (sc && BLI_gset_haskey(enabled_set, sc)); @@ -334,7 +369,7 @@ static void do_version_scene_collection_convert( nsc = nsc_next; } - for (LinkData *link = sc->objects.first; link; link = link->next) { + LISTBASE_FOREACH (LinkData *, link, &sc->objects) { Object *ob = link->data; if (ob) { BKE_collection_object_add(bmain, collection, ob); @@ -422,7 +457,7 @@ static void do_version_layers_to_collections(Main *bmain, Scene *scene) Collection *collections[20] = {NULL}; for (int layer = 0; layer < 20; layer++) { - for (Base *base = scene->base.first; base; base = base->next) { + LISTBASE_FOREACH (Base *, base, &scene->base) { if (base->lay & (1 << layer)) { /* Create collections when needed only. */ if (collections[layer] == NULL) { @@ -461,7 +496,7 @@ static void do_version_layers_to_collections(Main *bmain, Scene *scene) bool have_override = false; const bool need_default_renderlayer = scene->r.layers.first == NULL; - for (SceneRenderLayer *srl = scene->r.layers.first; srl; srl = srl->next) { + LISTBASE_FOREACH (SceneRenderLayer *, srl, &scene->r.layers) { ViewLayer *view_layer = BKE_view_layer_add(scene, srl->name, NULL, VIEWLAYER_ADD_NEW); if (srl->layflag & SCE_LAY_DISABLE) { @@ -493,7 +528,7 @@ static void do_version_layers_to_collections(Main *bmain, Scene *scene) /* Disable excluded layer. */ have_override = true; lc->flag |= LAYER_COLLECTION_EXCLUDE; - for (LayerCollection *nlc = lc->layer_collections.first; nlc; nlc = nlc->next) { + LISTBASE_FOREACH (LayerCollection *, nlc, &lc->layer_collections) { nlc->flag |= LAYER_COLLECTION_EXCLUDE; } } @@ -516,7 +551,7 @@ static void do_version_layers_to_collections(Main *bmain, Scene *scene) view_layer->basact = BKE_view_layer_base_find(view_layer, scene->basact->object); } - for (Base *base = view_layer->object_bases.first; base; base = base->next) { + LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) { if ((base->flag & BASE_SELECTABLE) && (base->object->flag & SELECT)) { base->flag |= BASE_SELECTED; } @@ -542,7 +577,7 @@ static void do_version_layers_to_collections(Main *bmain, Scene *scene) } /* convert selected bases */ - for (Base *base = view_layer->object_bases.first; base; base = base->next) { + LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) { if ((base->flag & BASE_SELECTABLE) && (base->object->flag & SELECT)) { base->flag |= BASE_SELECTED; } @@ -553,7 +588,7 @@ static void do_version_layers_to_collections(Main *bmain, Scene *scene) } /* remove bases once and for all */ - for (Base *base = scene->base.first; base; base = base->next) { + LISTBASE_FOREACH (Base *, base, &scene->base) { id_us_min(&base->object->id); } @@ -577,8 +612,8 @@ static void do_version_collection_propagate_lib_to_children(Collection *collecti /** convert old annotations colors */ static void do_versions_fix_annotations(bGPdata *gpd) { - for (const bGPDpalette *palette = gpd->palettes.first; palette; palette = palette->next) { - for (bGPDpalettecolor *palcolor = palette->colors.first; palcolor; palcolor = palcolor->next) { + LISTBASE_FOREACH (const bGPDpalette *, palette, &gpd->palettes) { + LISTBASE_FOREACH (bGPDpalettecolor *, palcolor, &palette->colors) { /* fix layers */ LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) { /* unlock/unhide layer */ @@ -609,9 +644,9 @@ static void do_versions_remove_region(ListBase *regionbase, ARegion *region) static void do_versions_remove_regions_by_type(ListBase *regionbase, int regiontype) { - ARegion *region, *ar_next; - for (region = regionbase->first; region; region = ar_next) { - ar_next = region->next; + ARegion *region, *region_next; + for (region = regionbase->first; region; region = region_next) { + region_next = region->next; if (region->regiontype == regiontype) { do_versions_remove_region(regionbase, region); } @@ -620,7 +655,7 @@ static void do_versions_remove_regions_by_type(ListBase *regionbase, int regiont static ARegion *do_versions_find_region_or_null(ListBase *regionbase, int regiontype) { - for (ARegion *region = regionbase->first; region; region = region->next) { + LISTBASE_FOREACH (ARegion *, region, regionbase) { if (region->regiontype == regiontype) { return region; } @@ -649,13 +684,14 @@ static void do_versions_area_ensure_tool_region(Main *bmain, const short region_flag) { for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) { - for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) { - for (SpaceLink *sl = sa->spacedata.first; sl; sl = sl->next) { + LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { + LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) { if (sl->spacetype == space_type) { - ListBase *regionbase = (sl == sa->spacedata.first) ? &sa->regionbase : &sl->regionbase; - ARegion *region = BKE_area_find_region_type(sa, RGN_TYPE_TOOLS); + ListBase *regionbase = (sl == area->spacedata.first) ? &area->regionbase : + &sl->regionbase; + ARegion *region = BKE_area_find_region_type(area, RGN_TYPE_TOOLS); if (!region) { - ARegion *header = BKE_area_find_region_type(sa, RGN_TYPE_HEADER); + ARegion *header = BKE_area_find_region_type(area, RGN_TYPE_HEADER); region = do_versions_add_region(RGN_TYPE_TOOLS, "tools region"); BLI_insertlinkafter(regionbase, header, region); region->alignment = RGN_ALIGN_LEFT; @@ -669,7 +705,7 @@ static void do_versions_area_ensure_tool_region(Main *bmain, static void do_version_bones_split_bbone_scale(ListBase *lb) { - for (Bone *bone = lb->first; bone; bone = bone->next) { + LISTBASE_FOREACH (Bone *, bone, lb) { bone->scale_in_y = bone->scale_in_x; bone->scale_out_y = bone->scale_out_x; @@ -679,7 +715,7 @@ static void do_version_bones_split_bbone_scale(ListBase *lb) static void do_version_bones_inherit_scale(ListBase *lb) { - for (Bone *bone = lb->first; bone; bone = bone->next) { + LISTBASE_FOREACH (Bone *, bone, lb) { if (bone->flag & BONE_NO_SCALE) { bone->inherit_scale_mode = BONE_INHERIT_SCALE_NONE_LEGACY; bone->flag &= ~BONE_NO_SCALE; @@ -723,7 +759,7 @@ static void do_version_bbone_scale_fcurve_fix(ListBase *curves, FCurve *fcu) /* Update F-Curve's path. */ if (replace_bbone_scale_rnapath(&fcu->rna_path)) { /* If matched, duplicate the curve and tweak name. */ - FCurve *second = copy_fcurve(fcu); + FCurve *second = BKE_fcurve_copy(fcu); second->rna_path[strlen(second->rna_path) - 1] = 'y'; @@ -749,7 +785,7 @@ static void do_version_bbone_scale_animdata_cb(ID *UNUSED(id), static void do_version_constraints_maintain_volume_mode_uniform(ListBase *lb) { - for (bConstraint *con = lb->first; con; con = con->next) { + LISTBASE_FOREACH (bConstraint *, con, lb) { if (con->type == CONSTRAINT_TYPE_SAMEVOL) { bSameVolumeConstraint *data = (bSameVolumeConstraint *)con->data; data->mode = SAMEVOL_UNIFORM; @@ -759,7 +795,7 @@ static void do_version_constraints_maintain_volume_mode_uniform(ListBase *lb) static void do_version_constraints_copy_scale_power(ListBase *lb) { - for (bConstraint *con = lb->first; con; con = con->next) { + LISTBASE_FOREACH (bConstraint *, con, lb) { if (con->type == CONSTRAINT_TYPE_SIZELIKE) { bSizeLikeConstraint *data = (bSizeLikeConstraint *)con->data; data->power = 1.0f; @@ -769,7 +805,7 @@ static void do_version_constraints_copy_scale_power(ListBase *lb) static void do_version_constraints_copy_rotation_mix_mode(ListBase *lb) { - for (bConstraint *con = lb->first; con; con = con->next) { + LISTBASE_FOREACH (bConstraint *, con, lb) { if (con->type == CONSTRAINT_TYPE_ROTLIKE) { bRotateLikeConstraint *data = (bRotateLikeConstraint *)con->data; data->mix_mode = (data->flag & ROTLIKE_OFFSET) ? ROTLIKE_MIX_OFFSET : ROTLIKE_MIX_REPLACE; @@ -1243,8 +1279,8 @@ void do_versions_after_linking_280(Main *bmain, ReportList *UNUSED(reports)) * so same layer as BKE_view_layer_default_view would return */ ViewLayer *layer = screen->scene->view_layers.first; - for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) { - for (SpaceLink *space = sa->spacedata.first; space; space = space->next) { + LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { + LISTBASE_FOREACH (SpaceLink *, space, &area->spacedata) { if (space->spacetype == SPACE_OUTLINER) { SpaceOutliner *soutliner = (SpaceOutliner *)space; @@ -1273,8 +1309,8 @@ void do_versions_after_linking_280(Main *bmain, ReportList *UNUSED(reports)) if (!MAIN_VERSION_ATLEAST(bmain, 280, 0)) { for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) { - for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) { - for (SpaceLink *space = sa->spacedata.first; space; space = space->next) { + LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { + LISTBASE_FOREACH (SpaceLink *, space, &area->spacedata) { if (space->spacetype == SPACE_IMAGE) { SpaceImage *sima = (SpaceImage *)space; if ((sima) && (sima->gpd)) { @@ -1304,7 +1340,7 @@ void do_versions_after_linking_280(Main *bmain, ReportList *UNUSED(reports)) /* Cleanup any remaining SceneRenderLayer data for files that were created * with Blender 2.8 before the SceneRenderLayer > RenderLayer refactor. */ for (Scene *scene = bmain->scenes.first; scene; scene = scene->id.next) { - for (SceneRenderLayer *srl = scene->r.layers.first; srl; srl = srl->next) { + LISTBASE_FOREACH (SceneRenderLayer *, srl, &scene->r.layers) { if (srl->prop) { IDP_FreeProperty(srl->prop); } @@ -1319,7 +1355,7 @@ void do_versions_after_linking_280(Main *bmain, ReportList *UNUSED(reports)) * no longer be visible. * Here we correct this by setting a default draw size for those files. */ for (Object *object = bmain->objects.first; object; object = object->id.next) { - for (ParticleSystem *psys = object->particlesystem.first; psys; psys = psys->next) { + LISTBASE_FOREACH (ParticleSystem *, psys, &object->particlesystem) { if (psys->part->draw_size == 0.0f) { psys->part->draw_size = 0.1f; } @@ -1331,7 +1367,7 @@ void do_versions_after_linking_280(Main *bmain, ReportList *UNUSED(reports)) for (Object *object = bmain->objects.first; object; object = object->id.next) { if (object->particlesystem.first) { object->duplicator_visibility_flag = OB_DUPLI_FLAG_VIEWPORT; - for (ParticleSystem *psys = object->particlesystem.first; psys; psys = psys->next) { + LISTBASE_FOREACH (ParticleSystem *, psys, &object->particlesystem) { if (psys->part->draw & PART_DRAW_EMITTER) { object->duplicator_visibility_flag |= OB_DUPLI_FLAG_RENDER; break; @@ -1362,9 +1398,9 @@ void do_versions_after_linking_280(Main *bmain, ReportList *UNUSED(reports)) * screens using the active scene of the window they're displayed in. * Next, update remaining screens using first scene in main listbase. */ - for (wmWindow *win = wm->windows.first; win; win = win->next) { + LISTBASE_FOREACH (wmWindow *, win, &wm->windows) { const bScreen *screen = BKE_workspace_active_screen_get(win->workspace_hook); - for (ScrArea *area = screen->areabase.first; area; area = area->next) { + LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { if (ELEM(area->butspacetype, SPACE_TIME, SPACE_LOGIC)) { do_version_area_change_space_to_space_action(area, win->scene); @@ -1376,7 +1412,7 @@ void do_versions_after_linking_280(Main *bmain, ReportList *UNUSED(reports)) } if (scene != NULL) { for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) { - for (ScrArea *area = screen->areabase.first; area; area = area->next) { + LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { if (ELEM(area->butspacetype, SPACE_TIME, SPACE_LOGIC)) { /* Areas that were already handled won't be handled again */ do_version_area_change_space_to_space_action(area, scene); @@ -1413,7 +1449,7 @@ void do_versions_after_linking_280(Main *bmain, ReportList *UNUSED(reports)) int new_count = BKE_keyblock_curve_element_count(&cu->nurb); - for (KeyBlock *block = cu->key->block.first; block; block = block->next) { + LISTBASE_FOREACH (KeyBlock *, block, &cu->key->block) { int old_count = block->totelem; void *old_data = block->data; @@ -1427,7 +1463,7 @@ void do_versions_after_linking_280(Main *bmain, ReportList *UNUSED(reports)) float *oldptr = old_data; float(*newptr)[3] = block->data; - for (Nurb *nu = cu->nurb.first; nu; nu = nu->next) { + LISTBASE_FOREACH (Nurb *, nu, &cu->nurb) { if (nu->bezt) { BezTriple *bezt = nu->bezt; @@ -1480,7 +1516,7 @@ void do_versions_after_linking_280(Main *bmain, ReportList *UNUSED(reports)) if (ob->pose && arm && arm->id.lib == ob->id.lib) { bool rebuild = false; - for (bPoseChannel *pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) { + LISTBASE_FOREACH (bPoseChannel *, pchan, &ob->pose->chanbase) { /* If the 2.7 flag is enabled, processing is needed. */ if (pchan->bone && (pchan->bboneflag & PCHAN_BBONE_CUSTOM_HANDLES)) { /* If the settings in the Bone are not set, copy. */ @@ -1632,14 +1668,42 @@ void do_versions_after_linking_280(Main *bmain, ReportList *UNUSED(reports)) if (!MAIN_VERSION_ATLEAST(bmain, 282, 2)) { /* Init all Vertex/Sculpt and Weight Paint brushes. */ - Brush *brush = BLI_findstring(&bmain->brushes, "Pencil", offsetof(ID, name) + 2); + Brush *brush; + Material *ma; + /* Pen Soft brush. */ + brush = (Brush *)rename_id_for_versioning(bmain, ID_BR, "Draw Soft", "Pencil Soft"); + if (brush) { + brush->gpencil_settings->icon_id = GP_BRUSH_ICON_PEN; + } + rename_id_for_versioning(bmain, ID_BR, "Draw Pencil", "Pencil"); + rename_id_for_versioning(bmain, ID_BR, "Draw Pen", "Pen"); + rename_id_for_versioning(bmain, ID_BR, "Draw Ink", "Ink Pen"); + rename_id_for_versioning(bmain, ID_BR, "Draw Noise", "Ink Pen Rough"); + rename_id_for_versioning(bmain, ID_BR, "Draw Marker", "Marker Bold"); + rename_id_for_versioning(bmain, ID_BR, "Draw Block", "Marker Chisel"); + + ma = BLI_findstring(&bmain->materials, "Black", offsetof(ID, name) + 2); + if (ma && ma->gp_style) { + rename_id_for_versioning(bmain, ID_MA, "Black", "Solid Stroke"); + } + ma = BLI_findstring(&bmain->materials, "Red", offsetof(ID, name) + 2); + if (ma && ma->gp_style) { + rename_id_for_versioning(bmain, ID_MA, "Red", "Squares Stroke"); + } + ma = BLI_findstring(&bmain->materials, "Grey", offsetof(ID, name) + 2); + if (ma && ma->gp_style) { + rename_id_for_versioning(bmain, ID_MA, "Grey", "Solid Fill"); + } + ma = BLI_findstring(&bmain->materials, "Black Dots", offsetof(ID, name) + 2); + if (ma && ma->gp_style) { + rename_id_for_versioning(bmain, ID_MA, "Black Dots", "Dots Stroke"); + } + + brush = BLI_findstring(&bmain->brushes, "Pencil", offsetof(ID, name) + 2); + for (Scene *scene = bmain->scenes.first; scene; scene = scene->id.next) { ToolSettings *ts = scene->toolsettings; - BKE_brush_gpencil_vertex_presets(bmain, ts); - BKE_brush_gpencil_sculpt_presets(bmain, ts); - BKE_brush_gpencil_weight_presets(bmain, ts); - /* Ensure new Paint modes. */ BKE_paint_ensure_from_paintmode(scene, PAINT_MODE_GPENCIL); BKE_paint_ensure_from_paintmode(scene, PAINT_MODE_VERTEX_GPENCIL); @@ -1653,8 +1717,6 @@ void do_versions_after_linking_280(Main *bmain, ReportList *UNUSED(reports)) /* Enable cursor by default. */ paint->flags |= PAINT_SHOW_BRUSH; } - /* Ensure Palette by default. */ - BKE_gpencil_palette_ensure(bmain, scene); } } @@ -1665,6 +1727,14 @@ void do_versions_after_linking_280(Main *bmain, ReportList *UNUSED(reports)) LISTBASE_FOREACH (Object *, ob, &bmain->objects) { BKE_fcurves_id_cb(&ob->id, do_version_fcurve_hide_viewport_fix, NULL); } + + /* Reset all grease pencil brushes. */ + LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) { + /* Ensure new Paint modes. */ + BKE_paint_ensure_from_paintmode(scene, PAINT_MODE_VERTEX_GPENCIL); + BKE_paint_ensure_from_paintmode(scene, PAINT_MODE_SCULPT_GPENCIL); + BKE_paint_ensure_from_paintmode(scene, PAINT_MODE_WEIGHT_GPENCIL); + } } /** @@ -1783,7 +1853,7 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) FOREACH_NODETREE_BEGIN (bmain, ntree, id) { if (ntree->type == NTREE_SHADER) { - for (bNode *node = ntree->nodes.first; node; node = node->next) { + LISTBASE_FOREACH (bNode *, node, &ntree->nodes) { if (node->type == 194 /* SH_NODE_EEVEE_METALLIC */ && STREQ(node->idname, "ShaderNodeOutputMetallic")) { BLI_strncpy(node->idname, "ShaderNodeEeveeMetallic", sizeof(node->idname)); @@ -1912,8 +1982,8 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) /* init grease pencil grids and paper */ if (!DNA_struct_elem_find(fd->filesdna, "View3DOverlay", "float", "gpencil_paper_color[3]")) { for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) { - for (ScrArea *area = screen->areabase.first; area; area = area->next) { - for (SpaceLink *sl = area->spacedata.first; sl; sl = sl->next) { + LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { + LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) { if (sl->spacetype == SPACE_VIEW3D) { View3D *v3d = (View3D *)sl; v3d->overlay.gpencil_paper_opacity = 0.5f; @@ -1927,14 +1997,14 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) if (!MAIN_VERSION_ATLEAST(bmain, 280, 6)) { if (DNA_struct_elem_find(fd->filesdna, "SpaceOutliner", "int", "filter") == false) { - bScreen *sc; - ScrArea *sa; + bScreen *screen; + ScrArea *area; SpaceLink *sl; /* Update files using invalid (outdated) outlinevis Outliner values. */ - for (sc = bmain->screens.first; sc; sc = sc->id.next) { - for (sa = sc->areabase.first; sa; sa = sa->next) { - for (sl = sa->spacedata.first; sl; sl = sl->next) { + for (screen = bmain->screens.first; screen; screen = screen->id.next) { + for (area = screen->areabase.first; area; area = area->next) { + for (sl = area->spacedata.first; sl; sl = sl->next) { if (sl->spacetype == SPACE_OUTLINER) { SpaceOutliner *so = (SpaceOutliner *)sl; @@ -1972,9 +2042,9 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) } } - for (bScreen *sc = bmain->screens.first; sc; sc = sc->id.next) { - for (ScrArea *sa = sc->areabase.first; sa; sa = sa->next) { - for (SpaceLink *sl = sa->spacedata.first; sl; sl = sl->next) { + for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) { + LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { + LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) { if (sl->spacetype == SPACE_VIEW3D) { View3D *v3d = (View3D *)sl; v3d->shading.light = V3D_LIGHTING_STUDIO; @@ -2026,7 +2096,7 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) { /* Calculate window width/height from screen vertices */ int win_width = 0, win_height = 0; - for (ScrVert *vert = screen->vertbase.first; vert; vert = vert->next) { + LISTBASE_FOREACH (ScrVert *, vert, &screen->vertbase) { win_width = MAX2(win_width, vert->vec.x); win_height = MAX2(win_height, vert->vec.y); } @@ -2066,10 +2136,11 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) if (!MAIN_VERSION_ATLEAST(bmain, 280, 12)) { /* Remove tool property regions. */ for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) { - for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) { - for (SpaceLink *sl = sa->spacedata.first; sl; sl = sl->next) { + LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { + LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) { if (ELEM(sl->spacetype, SPACE_VIEW3D, SPACE_CLIP)) { - ListBase *regionbase = (sl == sa->spacedata.first) ? &sa->regionbase : &sl->regionbase; + ListBase *regionbase = (sl == area->spacedata.first) ? &area->regionbase : + &sl->regionbase; for (ARegion *region = regionbase->first, *region_next; region; region = region_next) { region_next = region->next; @@ -2095,8 +2166,8 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) /* Initialize new view3D options. */ for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) { - for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) { - for (SpaceLink *sl = sa->spacedata.first; sl; sl = sl->next) { + LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { + LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) { if (sl->spacetype == SPACE_VIEW3D) { View3D *v3d = (View3D *)sl; v3d->shading.light = V3D_LIGHTING_STUDIO; @@ -2320,8 +2391,8 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) } for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) { - for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) { - for (SpaceLink *sl = sa->spacedata.first; sl; sl = sl->next) { + LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { + LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) { if (sl->spacetype == SPACE_OUTLINER) { SpaceOutliner *soops = (SpaceOutliner *)sl; soops->filter_id_type = ID_GR; @@ -2402,8 +2473,8 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) } for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) { - for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) { - for (SpaceLink *sl = sa->spacedata.first; sl; sl = sl->next) { + LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { + LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) { if (sl->spacetype == SPACE_VIEW3D) { View3D *v3d = (View3D *)sl; v3d->shading.flag |= V3D_SHADING_SPECULAR_HIGHLIGHT; @@ -2415,8 +2486,8 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) if (!DNA_struct_elem_find(fd->filesdna, "View3DShading", "float", "xray_alpha")) { for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) { - for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) { - for (SpaceLink *sl = sa->spacedata.first; sl; sl = sl->next) { + LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { + LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) { if (sl->spacetype == SPACE_VIEW3D) { View3D *v3d = (View3D *)sl; v3d->shading.xray_alpha = 0.5f; @@ -2430,8 +2501,8 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) /* when loading the internal file is loaded before the matcaps */ if (default_matcap) { for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) { - for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) { - for (SpaceLink *sl = sa->spacedata.first; sl; sl = sl->next) { + LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { + LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) { if (sl->spacetype == SPACE_VIEW3D) { View3D *v3d = (View3D *)sl; BLI_strncpy(v3d->shading.matcap, default_matcap->name, FILE_MAXFILE); @@ -2443,8 +2514,8 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) } if (!DNA_struct_elem_find(fd->filesdna, "View3DOverlay", "float", "wireframe_threshold")) { for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) { - for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) { - for (SpaceLink *sl = sa->spacedata.first; sl; sl = sl->next) { + LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { + LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) { if (sl->spacetype == SPACE_VIEW3D) { View3D *v3d = (View3D *)sl; v3d->overlay.wireframe_threshold = 0.5f; @@ -2455,8 +2526,8 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) } if (!DNA_struct_elem_find(fd->filesdna, "View3DShading", "float", "cavity_valley_factor")) { for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) { - for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) { - for (SpaceLink *sl = sa->spacedata.first; sl; sl = sl->next) { + LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { + LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) { if (sl->spacetype == SPACE_VIEW3D) { View3D *v3d = (View3D *)sl; v3d->shading.cavity_valley_factor = 1.0f; @@ -2468,8 +2539,8 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) } if (!DNA_struct_elem_find(fd->filesdna, "View3DOverlay", "float", "xray_alpha_bone")) { for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) { - for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) { - for (SpaceLink *sl = sa->spacedata.first; sl; sl = sl->next) { + LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { + LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) { if (sl->spacetype == SPACE_VIEW3D) { View3D *v3d = (View3D *)sl; v3d->overlay.xray_alpha_bone = 0.5f; @@ -2494,8 +2565,8 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) } if (!DNA_struct_elem_find(fd->filesdna, "SpaceAction", "char", "mode_prev")) { for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) { - for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) { - for (SpaceLink *sl = sa->spacedata.first; sl; sl = sl->next) { + LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { + LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) { if (sl->spacetype == SPACE_ACTION) { SpaceAction *saction = (SpaceAction *)sl; /* "Dopesheet" should be default here, @@ -2510,8 +2581,8 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) } for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) { - for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) { - for (SpaceLink *sl = sa->spacedata.first; sl; sl = sl->next) { + LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { + LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) { if (sl->spacetype == SPACE_VIEW3D) { View3D *v3d = (View3D *)sl; if (v3d->drawtype == OB_TEXTURE) { @@ -2535,8 +2606,8 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) if (!DNA_struct_elem_find( fd->filesdna, "View3DOverlay", "float", "texture_paint_mode_opacity")) { for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) { - for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) { - for (SpaceLink *sl = sa->spacedata.first; sl; sl = sl->next) { + LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { + LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) { if (sl->spacetype == SPACE_VIEW3D) { enum { V3D_SHOW_MODE_SHADE_OVERRIDE = (1 << 15), @@ -2554,8 +2625,8 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) if (!DNA_struct_elem_find(fd->filesdna, "View3DShading", "char", "background_type")) { for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) { - for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) { - for (SpaceLink *sl = sa->spacedata.first; sl; sl = sl->next) { + LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { + LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) { if (sl->spacetype == SPACE_VIEW3D) { View3D *v3d = (View3D *)sl; copy_v3_fl(v3d->shading.background_color, 0.05f); @@ -2619,8 +2690,8 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) if (!DNA_struct_elem_find(fd->filesdna, "View3DShading", "short", "type")) { for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) { - for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) { - for (SpaceLink *sl = sa->spacedata.first; sl; sl = sl->next) { + LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { + LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) { if (sl->spacetype == SPACE_VIEW3D) { View3D *v3d = (View3D *)sl; if (v3d->drawtype == OB_RENDER) { @@ -2641,9 +2712,9 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) } /* initialize grease pencil view data */ if (!DNA_struct_elem_find(fd->filesdna, "SpaceView3D", "float", "vertex_opacity")) { - for (bScreen *sc = bmain->screens.first; sc; sc = sc->id.next) { - for (ScrArea *sa = sc->areabase.first; sa; sa = sa->next) { - for (SpaceLink *sl = sa->spacedata.first; sl; sl = sl->next) { + for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) { + LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { + LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) { if (sl->spacetype == SPACE_VIEW3D) { View3D *v3d = (View3D *)sl; v3d->vertex_opacity = 1.0f; @@ -2674,8 +2745,8 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) } if (!DNA_struct_elem_find(fd->filesdna, "View3DOverlay", "float", "gpencil_paper_opacity")) { for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) { - for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) { - for (SpaceLink *sl = sa->spacedata.first; sl; sl = sl->next) { + LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { + LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) { if (sl->spacetype == SPACE_VIEW3D) { View3D *v3d = (View3D *)sl; v3d->overlay.gpencil_paper_opacity = 0.5f; @@ -2686,8 +2757,8 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) } if (!DNA_struct_elem_find(fd->filesdna, "View3DOverlay", "float", "gpencil_grid_opacity")) { for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) { - for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) { - for (SpaceLink *sl = sa->spacedata.first; sl; sl = sl->next) { + LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { + LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) { if (sl->spacetype == SPACE_VIEW3D) { View3D *v3d = (View3D *)sl; v3d->overlay.gpencil_grid_opacity = 0.5f; @@ -2711,7 +2782,7 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) /* Versioning code for Subsurf modifier. */ if (!DNA_struct_elem_find(fd->filesdna, "SubsurfModifier", "short", "uv_smooth")) { for (Object *object = bmain->objects.first; object != NULL; object = object->id.next) { - for (ModifierData *md = object->modifiers.first; md; md = md->next) { + LISTBASE_FOREACH (ModifierData *, md, &object->modifiers) { if (md->type == eModifierType_Subsurf) { SubsurfModifierData *smd = (SubsurfModifierData *)md; if (smd->flags & eSubsurfModifierFlag_SubsurfUv_DEPRECATED) { @@ -2727,7 +2798,7 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) if (!DNA_struct_elem_find(fd->filesdna, "SubsurfModifier", "short", "quality")) { for (Object *object = bmain->objects.first; object != NULL; object = object->id.next) { - for (ModifierData *md = object->modifiers.first; md; md = md->next) { + LISTBASE_FOREACH (ModifierData *, md, &object->modifiers) { if (md->type == eModifierType_Subsurf) { SubsurfModifierData *smd = (SubsurfModifierData *)md; smd->quality = min_ii(smd->renderLevels, 3); @@ -2738,7 +2809,7 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) /* Versioning code for Multires modifier. */ if (!DNA_struct_elem_find(fd->filesdna, "MultiresModifier", "short", "quality")) { for (Object *object = bmain->objects.first; object != NULL; object = object->id.next) { - for (ModifierData *md = object->modifiers.first; md; md = md->next) { + LISTBASE_FOREACH (ModifierData *, md, &object->modifiers) { if (md->type == eModifierType_Multires) { MultiresModifierData *mmd = (MultiresModifierData *)md; mmd->quality = 3; @@ -2755,7 +2826,7 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) if (!DNA_struct_elem_find(fd->filesdna, "ClothSimSettings", "short", "bending_model")) { for (Object *ob = bmain->objects.first; ob; ob = ob->id.next) { - for (ModifierData *md = ob->modifiers.first; md; md = md->next) { + LISTBASE_FOREACH (ModifierData *, md, &ob->modifiers) { ClothModifierData *clmd = NULL; if (md->type == eModifierType_Cloth) { clmd = (ClothModifierData *)md; @@ -2795,7 +2866,7 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) } for (Object *ob = bmain->objects.first; ob; ob = ob->id.next) { - for (ModifierData *md = ob->modifiers.first; md; md = md->next) { + LISTBASE_FOREACH (ModifierData *, md, &ob->modifiers) { if (md->type == eModifierType_Cloth) { ClothModifierData *clmd = (ClothModifierData *)md; @@ -2824,15 +2895,14 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) if (!MAIN_VERSION_ATLEAST(bmain, 280, 24)) { for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) { - for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) { - for (SpaceLink *sl = sa->spacedata.first; sl; sl = sl->next) { + LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { + LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) { if (sl->spacetype == SPACE_VIEW3D) { View3D *v3d = (View3D *)sl; v3d->overlay.edit_flag |= V3D_OVERLAY_EDIT_FACES | V3D_OVERLAY_EDIT_SEAMS | V3D_OVERLAY_EDIT_SHARP | V3D_OVERLAY_EDIT_FREESTYLE_EDGE | V3D_OVERLAY_EDIT_FREESTYLE_FACE | V3D_OVERLAY_EDIT_EDGES | - V3D_OVERLAY_EDIT_CREASES | V3D_OVERLAY_EDIT_BWEIGHTS | - V3D_OVERLAY_EDIT_CU_HANDLES | V3D_OVERLAY_EDIT_CU_NORMALS; + V3D_OVERLAY_EDIT_CREASES | V3D_OVERLAY_EDIT_BWEIGHTS; } } } @@ -2840,7 +2910,7 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) if (!DNA_struct_elem_find(fd->filesdna, "ShrinkwrapModifierData", "char", "shrinkMode")) { for (Object *ob = bmain->objects.first; ob; ob = ob->id.next) { - for (ModifierData *md = ob->modifiers.first; md; md = md->next) { + LISTBASE_FOREACH (ModifierData *, md, &ob->modifiers) { if (md->type == eModifierType_Shrinkwrap) { ShrinkwrapModifierData *smd = (ShrinkwrapModifierData *)md; if (smd->shrinkOpts & MOD_SHRINKWRAP_KEEP_ABOVE_SURFACE) { @@ -2858,7 +2928,7 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) ob->pd->pdef_cfrict = 5.0f; } - for (ModifierData *md = ob->modifiers.first; md; md = md->next) { + LISTBASE_FOREACH (ModifierData *, md, &ob->modifiers) { if (md->type == eModifierType_Cloth) { ClothModifierData *clmd = (ClothModifierData *)md; @@ -2870,8 +2940,8 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) if (!DNA_struct_elem_find(fd->filesdna, "View3DShading", "float", "xray_alpha_wire")) { for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) { - for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) { - for (SpaceLink *sl = sa->spacedata.first; sl; sl = sl->next) { + LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { + LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) { if (sl->spacetype == SPACE_VIEW3D) { View3D *v3d = (View3D *)sl; v3d->shading.flag |= V3D_SHADING_XRAY_WIREFRAME; @@ -2908,8 +2978,8 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) if (!MAIN_VERSION_ATLEAST(bmain, 280, 29)) { for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) { - for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) { - for (SpaceLink *sl = sa->spacedata.first; sl; sl = sl->next) { + LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { + LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) { if (sl->spacetype == SPACE_VIEW3D) { enum { V3D_OCCLUDE_WIRE = (1 << 14) }; View3D *v3d = (View3D *)sl; @@ -2931,12 +3001,13 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) */ if (!MAIN_VERSION_ATLEAST(bmain, 283, 1)) { for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) { - for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) { - for (SpaceLink *sl = sa->spacedata.first; sl; sl = sl->next) { - ListBase *regionbase = (sl == sa->spacedata.first) ? &sa->regionbase : &sl->regionbase; - ARegion *ar_header = do_versions_find_region_or_null(regionbase, RGN_TYPE_HEADER); + LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { + LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) { + ListBase *regionbase = (sl == area->spacedata.first) ? &area->regionbase : + &sl->regionbase; + ARegion *region_header = do_versions_find_region_or_null(regionbase, RGN_TYPE_HEADER); - if (!ar_header) { + if (!region_header) { /* Headers should always be first in the region list, except if there's also a * tool-header. These were only introduced in later versions though, so should be * fine to always insert headers first. */ @@ -2954,21 +3025,23 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) } for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) { - for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) { - for (SpaceLink *sl = sa->spacedata.first; sl; sl = sl->next) { + LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { + LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) { if (sl->spacetype == SPACE_PROPERTIES) { - ListBase *regionbase = (sl == sa->spacedata.first) ? &sa->regionbase : &sl->regionbase; + ListBase *regionbase = (sl == area->spacedata.first) ? &area->regionbase : + &sl->regionbase; ARegion *region = MEM_callocN(sizeof(ARegion), "navigation bar for properties"); - ARegion *ar_header = NULL; + ARegion *region_header = NULL; - for (ar_header = regionbase->first; ar_header; ar_header = ar_header->next) { - if (ar_header->regiontype == RGN_TYPE_HEADER) { + for (region_header = regionbase->first; region_header; + region_header = region_header->next) { + if (region_header->regiontype == RGN_TYPE_HEADER) { break; } } - BLI_assert(ar_header); + BLI_assert(region_header); - BLI_insertlinkafter(regionbase, ar_header, region); + BLI_insertlinkafter(regionbase, region_header, region); region->regiontype = RGN_TYPE_NAV_BAR; region->alignment = RGN_ALIGN_LEFT; @@ -2980,8 +3053,8 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) /* grease pencil fade layer opacity */ if (!DNA_struct_elem_find(fd->filesdna, "View3DOverlay", "float", "gpencil_fade_layer")) { for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) { - for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) { - for (SpaceLink *sl = sa->spacedata.first; sl; sl = sl->next) { + LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { + LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) { if (sl->spacetype == SPACE_VIEW3D) { View3D *v3d = (View3D *)sl; v3d->overlay.gpencil_fade_layer = 0.5f; @@ -3185,8 +3258,8 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) if (!MAIN_VERSION_ATLEAST(bmain, 280, 34)) { for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) { - for (ScrArea *area = screen->areabase.first; area; area = area->next) { - for (SpaceLink *slink = area->spacedata.first; slink; slink = slink->next) { + LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { + LISTBASE_FOREACH (SpaceLink *, slink, &area->spacedata) { if (slink->spacetype == SPACE_USERPREF) { ARegion *navigation_region = BKE_spacedata_find_region_type( slink, area, RGN_TYPE_NAV_BAR); @@ -3214,8 +3287,8 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) if (!MAIN_VERSION_ATLEAST(bmain, 280, 36)) { if (!DNA_struct_elem_find(fd->filesdna, "View3DShading", "float", "curvature_ridge_factor")) { for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) { - for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) { - for (SpaceLink *sl = sa->spacedata.first; sl; sl = sl->next) { + LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { + LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) { if (sl->spacetype == SPACE_VIEW3D) { View3D *v3d = (View3D *)sl; v3d->shading.curvature_ridge_factor = 1.0f; @@ -3246,8 +3319,8 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) /* Move studio_light selection to lookdev_light. */ if (!DNA_struct_elem_find(fd->filesdna, "View3DShading", "char", "lookdev_light[256]")) { for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) { - for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) { - for (SpaceLink *sl = sa->spacedata.first; sl; sl = sl->next) { + LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { + LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) { if (sl->spacetype == SPACE_VIEW3D) { View3D *v3d = (View3D *)sl; memcpy(v3d->shading.lookdev_light, v3d->shading.studio_light, sizeof(char) * 256); @@ -3300,8 +3373,8 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) } for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) { - for (ScrArea *area = screen->areabase.first; area; area = area->next) { - for (SpaceLink *sl = area->spacedata.first; sl; sl = sl->next) { + LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { + LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) { switch (sl->spacetype) { case SPACE_IMAGE: { SpaceImage *sima = (SpaceImage *)sl; @@ -3417,8 +3490,8 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) } for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) { - for (ScrArea *area = screen->areabase.first; area; area = area->next) { - for (SpaceLink *sl = area->spacedata.first; sl; sl = sl->next) { + LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { + LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) { switch (sl->spacetype) { case SPACE_VIEW3D: { enum { V3D_BACKFACE_CULLING = (1 << 10) }; @@ -3460,21 +3533,21 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) } for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) { - for (ScrArea *area = screen->areabase.first; area; area = area->next) { - for (SpaceLink *sl = area->spacedata.first; sl; sl = sl->next) { + LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { + LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) { if (sl->spacetype == SPACE_USERPREF) { ARegion *execute_region = BKE_spacedata_find_region_type(sl, area, RGN_TYPE_EXECUTE); if (!execute_region) { ListBase *regionbase = (sl == area->spacedata.first) ? &area->regionbase : &sl->regionbase; - ARegion *ar_navbar = BKE_spacedata_find_region_type(sl, area, RGN_TYPE_NAV_BAR); + ARegion *region_navbar = BKE_spacedata_find_region_type(sl, area, RGN_TYPE_NAV_BAR); execute_region = MEM_callocN(sizeof(ARegion), "execute region for properties"); - BLI_assert(ar_navbar); + BLI_assert(region_navbar); - BLI_insertlinkafter(regionbase, ar_navbar, execute_region); + BLI_insertlinkafter(regionbase, region_navbar, execute_region); execute_region->regiontype = RGN_TYPE_EXECUTE; execute_region->alignment = RGN_ALIGN_BOTTOM | RGN_SPLIT_PREV; @@ -3519,8 +3592,8 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) /* Add wireframe color. */ if (!DNA_struct_elem_find(fd->filesdna, "View3DShading", "char", "wire_color_type")) { for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) { - for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) { - for (SpaceLink *sl = sa->spacedata.first; sl; sl = sl->next) { + LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { + LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) { if (sl->spacetype == SPACE_VIEW3D) { View3D *v3d = (View3D *)sl; v3d->shading.wire_color_type = V3D_SHADING_SINGLE_COLOR; @@ -3622,7 +3695,7 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) if (!DNA_struct_elem_find(fd->filesdna, "TriangulateModifierData", "int", "min_vertices")) { for (Object *ob = bmain->objects.first; ob; ob = ob->id.next) { - for (ModifierData *md = ob->modifiers.first; md; md = md->next) { + LISTBASE_FOREACH (ModifierData *, md, &ob->modifiers) { if (md->type == eModifierType_Triangulate) { TriangulateModifierData *smd = (TriangulateModifierData *)md; smd->min_vertices = 4; @@ -3633,7 +3706,7 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) FOREACH_NODETREE_BEGIN (bmain, ntree, id) { if (ntree->type == NTREE_SHADER) { - for (bNode *node = ntree->nodes.first; node; node = node->next) { + LISTBASE_FOREACH (bNode *, node, &ntree->nodes) { /* Fix missing version patching from earlier changes. */ if (STREQ(node->idname, "ShaderNodeOutputLamp")) { STRNCPY(node->idname, "ShaderNodeOutputLight"); @@ -3672,7 +3745,7 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) if (!MAIN_VERSION_ATLEAST(bmain, 280, 54)) { for (Object *ob = bmain->objects.first; ob; ob = ob->id.next) { bool is_first_subdiv = true; - for (ModifierData *md = ob->modifiers.first; md; md = md->next) { + LISTBASE_FOREACH (ModifierData *, md, &ob->modifiers) { if (md->type == eModifierType_Subsurf) { SubsurfModifierData *smd = (SubsurfModifierData *)md; if (is_first_subdiv) { @@ -3699,10 +3772,11 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) if (!MAIN_VERSION_ATLEAST(bmain, 280, 55)) { for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) { - for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) { - for (SpaceLink *sl = sa->spacedata.first; sl; sl = sl->next) { + LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { + LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) { if (sl->spacetype == SPACE_TEXT) { - ListBase *regionbase = (sl == sa->spacedata.first) ? &sa->regionbase : &sl->regionbase; + ListBase *regionbase = (sl == area->spacedata.first) ? &area->regionbase : + &sl->regionbase; /* Remove multiple footers that were added by mistake. */ do_versions_remove_regions_by_type(regionbase, RGN_TYPE_FOOTER); @@ -3711,8 +3785,8 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) ARegion *region = do_versions_add_region(RGN_TYPE_FOOTER, "footer for text"); region->alignment = (U.uiflag & USER_HEADER_BOTTOM) ? RGN_ALIGN_TOP : RGN_ALIGN_BOTTOM; - ARegion *ar_header = do_versions_find_region(regionbase, RGN_TYPE_HEADER); - BLI_insertlinkafter(regionbase, ar_header, region); + ARegion *region_header = do_versions_find_region(regionbase, RGN_TYPE_HEADER); + BLI_insertlinkafter(regionbase, region_header, region); } } } @@ -3721,8 +3795,8 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) if (!MAIN_VERSION_ATLEAST(bmain, 280, 56)) { for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) { - for (ScrArea *area = screen->areabase.first; area; area = area->next) { - for (SpaceLink *sl = area->spacedata.first; sl; sl = sl->next) { + LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { + LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) { if (sl->spacetype == SPACE_VIEW3D) { View3D *v3d = (View3D *)sl; v3d->gizmo_show_armature = V3D_GIZMO_SHOW_ARMATURE_BBONE | @@ -3739,8 +3813,8 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) if (!MAIN_VERSION_ATLEAST(bmain, 280, 57)) { /* Enable Show Interpolation in dopesheet by default. */ for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) { - for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) { - for (SpaceLink *sl = sa->spacedata.first; sl; sl = sl->next) { + LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { + LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) { if (sl->spacetype == SPACE_ACTION) { SpaceAction *saction = (SpaceAction *)sl; if ((saction->flag & SACTION_SHOW_EXTREMES) == 0) { @@ -3778,8 +3852,8 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) /* enable the axis aligned ortho grid by default */ for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) { - for (ScrArea *area = screen->areabase.first; area; area = area->next) { - for (SpaceLink *sl = area->spacedata.first; sl; sl = sl->next) { + LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { + LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) { if (sl->spacetype == SPACE_VIEW3D) { View3D *v3d = (View3D *)sl; v3d->gridflag |= V3D_SHOW_ORTHO_GRID; @@ -3792,9 +3866,10 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) /* Keep un-versioned until we're finished adding space types. */ { for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) { - for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) { - for (SpaceLink *sl = sa->spacedata.first; sl; sl = sl->next) { - ListBase *regionbase = (sl == sa->spacedata.first) ? &sa->regionbase : &sl->regionbase; + LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { + LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) { + ListBase *regionbase = (sl == area->spacedata.first) ? &area->regionbase : + &sl->regionbase; /* All spaces that use tools must be eventually added. */ ARegion *region = NULL; if (ELEM(sl->spacetype, SPACE_VIEW3D, SPACE_IMAGE, SPACE_SEQ) && @@ -3804,8 +3879,8 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) region = do_versions_add_region(RGN_TYPE_TOOL_HEADER, "tool header"); region->alignment = (U.uiflag & USER_HEADER_BOTTOM) ? RGN_ALIGN_BOTTOM : RGN_ALIGN_TOP; - ARegion *ar_header = do_versions_find_region(regionbase, RGN_TYPE_HEADER); - BLI_insertlinkbefore(regionbase, ar_header, region); + ARegion *region_header = do_versions_find_region(regionbase, RGN_TYPE_HEADER); + BLI_insertlinkbefore(regionbase, region_header, region); /* Hide by default, enable for painting workspaces (startup only). */ region->flag |= RGN_FLAG_HIDDEN | RGN_FLAG_HIDDEN_BY_USER; } @@ -3822,8 +3897,8 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) if (!DNA_struct_elem_find(fd->filesdna, "bSplineIKConstraint", "short", "yScaleMode")) { for (Object *ob = bmain->objects.first; ob; ob = ob->id.next) { if (ob->pose) { - for (bPoseChannel *pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) { - for (bConstraint *con = pchan->constraints.first; con; con = con->next) { + LISTBASE_FOREACH (bPoseChannel *, pchan, &ob->pose->chanbase) { + LISTBASE_FOREACH (bConstraint *, con, &pchan->constraints) { if (con->type == CONSTRAINT_TYPE_SPLINEIK) { bSplineIKConstraint *data = (bSplineIKConstraint *)con->data; if ((data->flag & CONSTRAINT_SPLINEIK_SCALE_LIMITED) == 0) { @@ -3839,8 +3914,8 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) if (!DNA_struct_elem_find( fd->filesdna, "View3DOverlay", "float", "sculpt_mode_mask_opacity")) { for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) { - for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) { - for (SpaceLink *sl = sa->spacedata.first; sl; sl = sl->next) { + LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { + LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) { if (sl->spacetype == SPACE_VIEW3D) { View3D *v3d = (View3D *)sl; v3d->overlay.sculpt_mode_mask_opacity = 0.75f; @@ -3903,10 +3978,11 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) } for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) { - for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) { - for (SpaceLink *sl = sa->spacedata.first; sl; sl = sl->next) { + LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { + LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) { if (ELEM(sl->spacetype, SPACE_CLIP, SPACE_GRAPH, SPACE_SEQ)) { - ListBase *regionbase = (sl == sa->spacedata.first) ? &sa->regionbase : &sl->regionbase; + ListBase *regionbase = (sl == area->spacedata.first) ? &area->regionbase : + &sl->regionbase; ARegion *region = NULL; if (sl->spacetype == SPACE_CLIP) { @@ -3928,8 +4004,8 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) } for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) { - for (ScrArea *area = screen->areabase.first; area; area = area->next) { - for (SpaceLink *sl = area->spacedata.first; sl; sl = sl->next) { + LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { + LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) { if (sl->spacetype != SPACE_OUTLINER) { continue; } @@ -4039,7 +4115,7 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) if (!MAIN_VERSION_ATLEAST(bmain, 281, 1)) { LISTBASE_FOREACH (Object *, ob, &bmain->objects) { - for (ModifierData *md = ob->modifiers.first; md; md = md->next) { + LISTBASE_FOREACH (ModifierData *, md, &ob->modifiers) { if (md->type == eModifierType_DataTransfer) { /* Now datatransfer's mix factor is multiplied with weights when any, * instead of being ignored, @@ -4055,10 +4131,11 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) if (!MAIN_VERSION_ATLEAST(bmain, 281, 3)) { for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) { - for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) { - for (SpaceLink *sl = sa->spacedata.first; sl; sl = sl->next) { + LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { + LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) { if (sl->spacetype == SPACE_TEXT) { - ListBase *regionbase = (sl == sa->spacedata.first) ? &sa->regionbase : &sl->regionbase; + ListBase *regionbase = (sl == area->spacedata.first) ? &area->regionbase : + &sl->regionbase; ARegion *region = do_versions_find_region_or_null(regionbase, RGN_TYPE_UI); if (region) { region->alignment = RGN_ALIGN_RIGHT; @@ -4109,14 +4186,14 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) if (!MAIN_VERSION_ATLEAST(bmain, 281, 6)) { for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) { - for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) { - for (SpaceLink *sl = sa->spacedata.first; sl; sl = sl->next) { + LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { + LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) { if (sl->spacetype == SPACE_VIEW3D) { View3D *v3d = (View3D *)sl; v3d->shading.flag |= V3D_SHADING_SCENE_LIGHTS_RENDER | V3D_SHADING_SCENE_WORLD_RENDER; /* files by default don't have studio lights selected unless interacted - * with the shading popover. When no studiolight could be read, we will + * with the shading popover. When no studio-light could be read, we will * select the default world one. */ StudioLight *studio_light = BKE_studiolight_find(v3d->shading.lookdev_light, STUDIOLIGHT_TYPE_WORLD); @@ -4131,29 +4208,31 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) if (!MAIN_VERSION_ATLEAST(bmain, 281, 9)) { for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) { - for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) { - for (SpaceLink *sl = sa->spacedata.first; sl; sl = sl->next) { + LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { + LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) { if (sl->spacetype == SPACE_FILE) { SpaceFile *sfile = (SpaceFile *)sl; - ListBase *regionbase = (sl == sa->spacedata.first) ? &sa->regionbase : &sl->regionbase; - ARegion *ar_ui = do_versions_find_region(regionbase, RGN_TYPE_UI); - ARegion *ar_header = do_versions_find_region(regionbase, RGN_TYPE_HEADER); - ARegion *ar_toolprops = do_versions_find_region_or_null(regionbase, - RGN_TYPE_TOOL_PROPS); + ListBase *regionbase = (sl == area->spacedata.first) ? &area->regionbase : + &sl->regionbase; + ARegion *region_ui = do_versions_find_region(regionbase, RGN_TYPE_UI); + ARegion *region_header = do_versions_find_region(regionbase, RGN_TYPE_HEADER); + ARegion *region_toolprops = do_versions_find_region_or_null(regionbase, + RGN_TYPE_TOOL_PROPS); /* Reinsert UI region so that it spawns entire area width */ - BLI_remlink(regionbase, ar_ui); - BLI_insertlinkafter(regionbase, ar_header, ar_ui); + BLI_remlink(regionbase, region_ui); + BLI_insertlinkafter(regionbase, region_header, region_ui); - ar_ui->flag |= RGN_FLAG_DYNAMIC_SIZE; + region_ui->flag |= RGN_FLAG_DYNAMIC_SIZE; - if (ar_toolprops && (ar_toolprops->alignment == (RGN_ALIGN_BOTTOM | RGN_SPLIT_PREV))) { + if (region_toolprops && + (region_toolprops->alignment == (RGN_ALIGN_BOTTOM | RGN_SPLIT_PREV))) { SpaceType *stype = BKE_spacetype_from_id(sl->spacetype); /* Remove empty region at old location. */ BLI_assert(sfile->op == NULL); - BKE_area_region_free(stype, ar_toolprops); - BLI_freelinkN(regionbase, ar_toolprops); + BKE_area_region_free(stype, region_toolprops); + BLI_freelinkN(regionbase, region_toolprops); } if (sfile->params) { @@ -4183,11 +4262,11 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) } } - /* Added studiolight intensity */ + /* Added studio-light intensity. */ if (!DNA_struct_elem_find(fd->filesdna, "View3DShading", "float", "studiolight_intensity")) { for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) { - for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) { - for (SpaceLink *sl = sa->spacedata.first; sl; sl = sl->next) { + LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { + LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) { if (sl->spacetype == SPACE_VIEW3D) { View3D *v3d = (View3D *)sl; v3d->shading.studiolight_intensity = 1.0f; @@ -4224,14 +4303,13 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) } for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) { - for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) { - for (SpaceLink *sl = sa->spacedata.first; sl; sl = sl->next) { + LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { + LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) { if (sl->spacetype == SPACE_VIEW3D) { View3D *v3d = (View3D *)sl; - for (ScrArea *sa_other = screen->areabase.first; sa_other; sa_other = sa_other->next) { - for (SpaceLink *sl_other = sa_other->spacedata.first; sl_other; - sl_other = sl_other->next) { + LISTBASE_FOREACH (ScrArea *, area_other, &screen->areabase) { + LISTBASE_FOREACH (SpaceLink *, sl_other, &area_other->spacedata) { if (sl != sl_other && sl_other->spacetype == SPACE_VIEW3D) { View3D *v3d_other = (View3D *)sl_other; @@ -4243,25 +4321,27 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) } } else if (sl->spacetype == SPACE_FILE) { - ListBase *regionbase = (sl == sa->spacedata.first) ? &sa->regionbase : &sl->regionbase; - ARegion *ar_tools = do_versions_find_region_or_null(regionbase, RGN_TYPE_TOOLS); - ARegion *ar_header = do_versions_find_region(regionbase, RGN_TYPE_HEADER); + ListBase *regionbase = (sl == area->spacedata.first) ? &area->regionbase : + &sl->regionbase; + ARegion *region_tools = do_versions_find_region_or_null(regionbase, RGN_TYPE_TOOLS); + ARegion *region_header = do_versions_find_region(regionbase, RGN_TYPE_HEADER); - if (ar_tools) { - ARegion *ar_next = ar_tools->next; + if (region_tools) { + ARegion *region_next = region_tools->next; /* We temporarily had two tools regions, get rid of the second one. */ - if (ar_next && ar_next->regiontype == RGN_TYPE_TOOLS) { - do_versions_remove_region(regionbase, ar_next); + if (region_next && region_next->regiontype == RGN_TYPE_TOOLS) { + do_versions_remove_region(regionbase, region_next); } - BLI_remlink(regionbase, ar_tools); - BLI_insertlinkafter(regionbase, ar_header, ar_tools); + BLI_remlink(regionbase, region_tools); + BLI_insertlinkafter(regionbase, region_header, region_tools); } else { - ar_tools = do_versions_add_region(RGN_TYPE_TOOLS, "versioning file tools region"); - BLI_insertlinkafter(regionbase, ar_header, ar_tools); - ar_tools->alignment = RGN_ALIGN_LEFT; + region_tools = do_versions_add_region(RGN_TYPE_TOOLS, + "versioning file tools region"); + BLI_insertlinkafter(regionbase, region_header, region_tools); + region_tools->alignment = RGN_ALIGN_LEFT; } } } @@ -4279,8 +4359,8 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) do_version_curvemapping_walker(bmain, do_version_curvemapping_flag_extend_extrapolate); for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) { - for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) { - sa->flag &= ~AREA_FLAG_UNUSED_6; + LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { + area->flag &= ~AREA_FLAG_UNUSED_6; } } @@ -4297,7 +4377,7 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) /* Add custom curve profile to bevel modifier */ if (!DNA_struct_elem_find(fd->filesdna, "BevelModifier", "CurveProfile", "custom_profile")) { for (Object *object = bmain->objects.first; object != NULL; object = object->id.next) { - for (ModifierData *md = object->modifiers.first; md; md = md->next) { + LISTBASE_FOREACH (ModifierData *, md, &object->modifiers) { if (md->type == eModifierType_Bevel) { BevelModifierData *bmd = (BevelModifierData *)md; if (!bmd->custom_profile) { @@ -4325,7 +4405,7 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) /* Cloth pressure */ for (Object *ob = bmain->objects.first; ob; ob = ob->id.next) { - for (ModifierData *md = ob->modifiers.first; md; md = md->next) { + LISTBASE_FOREACH (ModifierData *, md, &ob->modifiers) { if (md->type == eModifierType_Cloth) { ClothModifierData *clmd = (ClothModifierData *)md; @@ -4350,8 +4430,8 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) } for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) { - for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) { - for (SpaceLink *sl = sa->spacedata.first; sl; sl = sl->next) { + LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { + LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) { if (sl->spacetype == SPACE_VIEW3D) { View3D *v3d = (View3D *)sl; v3d->shading.render_pass = SCE_PASS_COMBINED; @@ -4363,8 +4443,8 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) /* Make markers region visible by default. */ for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) { - for (ScrArea *area = screen->areabase.first; area; area = area->next) { - for (SpaceLink *sl = area->spacedata.first; sl; sl = sl->next) { + LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { + LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) { switch (sl->spacetype) { case SPACE_SEQ: { SpaceSeq *sseq = (SpaceSeq *)sl; @@ -4393,13 +4473,26 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) } if (!MAIN_VERSION_ATLEAST(bmain, 283, 3)) { + /* Color Management Look. */ + for (Scene *scene = bmain->scenes.first; scene; scene = scene->id.next) { + ColorManagedViewSettings *view_settings; + view_settings = &scene->view_settings; + if (BLI_str_startswith(view_settings->look, "Filmic - ")) { + char *src = view_settings->look + strlen("Filmic - "); + memmove(view_settings->look, src, strlen(src) + 1); + } + else if (BLI_str_startswith(view_settings->look, "Standard - ")) { + char *src = view_settings->look + strlen("Standard - "); + memmove(view_settings->look, src, strlen(src) + 1); + } + } /* Sequencer Tool region */ do_versions_area_ensure_tool_region(bmain, SPACE_SEQ, RGN_FLAG_HIDDEN); /* Cloth internal springs */ for (Object *ob = bmain->objects.first; ob; ob = ob->id.next) { - for (ModifierData *md = ob->modifiers.first; md; md = md->next) { + LISTBASE_FOREACH (ModifierData *, md, &ob->modifiers) { if (md->type == eModifierType_Cloth) { ClothModifierData *clmd = (ClothModifierData *)md; @@ -4425,8 +4518,8 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) /* UDIM Image Editor change. */ if (!DNA_struct_elem_find(fd->filesdna, "SpaceImage", "int", "tile_grid_shape[2]")) { for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) { - for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) { - for (SpaceLink *sl = sa->spacedata.first; sl; sl = sl->next) { + LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { + LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) { if (sl->spacetype == SPACE_IMAGE) { SpaceImage *sima = (SpaceImage *)sl; sima->tile_grid_shape[0] = 1; @@ -4488,7 +4581,7 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) /* Add 2D transform to UV Warp modifier. */ if (!DNA_struct_elem_find(fd->filesdna, "UVWarpModifierData", "float", "scale[2]")) { for (Object *ob = bmain->objects.first; ob; ob = ob->id.next) { - for (ModifierData *md = ob->modifiers.first; md; md = md->next) { + LISTBASE_FOREACH (ModifierData *, md, &ob->modifiers) { if (md->type == eModifierType_UVWarp) { UVWarpModifierData *umd = (UVWarpModifierData *)md; copy_v2_fl(umd->scale, 1.0f); @@ -4500,8 +4593,8 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) /* Add Lookdev blur property. */ if (!DNA_struct_elem_find(fd->filesdna, "View3DShading", "float", "studiolight_blur")) { for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) { - for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) { - for (SpaceLink *sl = sa->spacedata.first; sl; sl = sl->next) { + LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { + LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) { if (sl->spacetype == SPACE_VIEW3D) { View3D *v3d = (View3D *)sl; v3d->shading.studiolight_blur = 0.5f; @@ -4541,8 +4634,6 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) brush->gpencil_weight_tool = brush->gpencil_settings->brush_type; } } - - BKE_paint_toolslots_init_from_main(bmain); } LISTBASE_FOREACH (Material *, mat, &bmain->materials) { @@ -4774,8 +4865,8 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) if (!DNA_struct_elem_find( fd->filesdna, "View3DOverlay", "float", "sculpt_mode_face_sets_opacity")) { for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) { - for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) { - for (SpaceLink *sl = sa->spacedata.first; sl; sl = sl->next) { + LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { + LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) { if (sl->spacetype == SPACE_VIEW3D) { View3D *v3d = (View3D *)sl; v3d->overlay.sculpt_mode_face_sets_opacity = 1.0f; @@ -4805,7 +4896,7 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) /* Corrective smooth modifier scale*/ if (!DNA_struct_elem_find(fd->filesdna, "CorrectiveSmoothModifierData", "float", "scale")) { for (Object *ob = bmain->objects.first; ob; ob = ob->id.next) { - for (ModifierData *md = ob->modifiers.first; md; md = md->next) { + LISTBASE_FOREACH (ModifierData *, md, &ob->modifiers) { if (md->type == eModifierType_CorrectiveSmooth) { CorrectiveSmoothModifierData *csmd = (CorrectiveSmoothModifierData *)md; csmd->scale = 1.0f; @@ -4828,7 +4919,7 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) if (!MAIN_VERSION_ATLEAST(bmain, 283, 11)) { if (!DNA_struct_elem_find(fd->filesdna, "OceanModifierData", "float", "fetch_jonswap")) { for (Object *object = bmain->objects.first; object != NULL; object = object->id.next) { - for (ModifierData *md = object->modifiers.first; md; md = md->next) { + LISTBASE_FOREACH (ModifierData *, md, &object->modifiers) { if (md->type == eModifierType_Ocean) { OceanModifierData *omd = (OceanModifierData *)md; omd->fetch_jonswap = 120.0f; @@ -4852,6 +4943,125 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) wm->xr.session_settings.flag = XR_SESSION_USE_POSITION_TRACKING; } } + + /* Surface deform modifier strength*/ + if (!DNA_struct_elem_find(fd->filesdna, "SurfaceDeformModifierData", "float", "strength")) { + for (Object *ob = bmain->objects.first; ob; ob = ob->id.next) { + LISTBASE_FOREACH (ModifierData *, md, &ob->modifiers) { + if (md->type == eModifierType_SurfaceDeform) { + SurfaceDeformModifierData *sdmd = (SurfaceDeformModifierData *)md; + sdmd->strength = 1.0f; + } + } + } + } + } + + if (!MAIN_VERSION_ATLEAST(bmain, 283, 12)) { + /* Activate f-curve drawing in the sequencer. */ + for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) { + for (ScrArea *area = screen->areabase.first; area; area = area->next) { + for (SpaceLink *sl = area->spacedata.first; sl; sl = sl->next) { + if (sl->spacetype == SPACE_SEQ) { + SpaceSeq *sseq = (SpaceSeq *)sl; + sseq->flag |= SEQ_SHOW_FCURVES; + } + } + } + } + + /* Remesh Modifier Voxel Mode. */ + if (!DNA_struct_elem_find(fd->filesdna, "RemeshModifierData", "float", "voxel_size")) { + for (Object *ob = bmain->objects.first; ob; ob = ob->id.next) { + LISTBASE_FOREACH (ModifierData *, md, &ob->modifiers) { + if (md->type == eModifierType_Remesh) { + RemeshModifierData *rmd = (RemeshModifierData *)md; + rmd->voxel_size = 0.1f; + rmd->adaptivity = 0.0f; + } + } + } + } + } + + if (!MAIN_VERSION_ATLEAST(bmain, 283, 14)) { + /* Solidify modifier merge tolerance. */ + if (!DNA_struct_elem_find(fd->filesdna, "SolidifyModifierData", "float", "merge_tolerance")) { + for (Object *ob = bmain->objects.first; ob; ob = ob->id.next) { + for (ModifierData *md = ob->modifiers.first; md; md = md->next) { + if (md->type == eModifierType_Solidify) { + SolidifyModifierData *smd = (SolidifyModifierData *)md; + /* set to 0.0003 since that is what was used before, default now is 0.0001 */ + smd->merge_tolerance = 0.0003f; + } + } + } + } + + /* Enumerator was incorrect for a time in 2.83 development. + * Note that this only corrects values known to be invalid. */ + for (Object *ob = bmain->objects.first; ob; ob = ob->id.next) { + RigidBodyCon *rbc = ob->rigidbody_constraint; + if (rbc != NULL) { + enum { + INVALID_RBC_TYPE_SLIDER = 2, + INVALID_RBC_TYPE_6DOF_SPRING = 4, + INVALID_RBC_TYPE_MOTOR = 7, + }; + switch (rbc->type) { + case INVALID_RBC_TYPE_SLIDER: + rbc->type = RBC_TYPE_SLIDER; + break; + case INVALID_RBC_TYPE_6DOF_SPRING: + rbc->type = RBC_TYPE_6DOF_SPRING; + break; + case INVALID_RBC_TYPE_MOTOR: + rbc->type = RBC_TYPE_MOTOR; + break; + } + } + } + } + + /* Match scale of fluid modifier gravity with scene gravity. */ + if (!MAIN_VERSION_ATLEAST(bmain, 283, 15)) { + for (Object *ob = bmain->objects.first; ob; ob = ob->id.next) { + for (ModifierData *md = ob->modifiers.first; md; md = md->next) { + if (md->type == eModifierType_Fluid) { + FluidModifierData *fmd = (FluidModifierData *)md; + if (fmd->domain != NULL) { + mul_v3_fl(fmd->domain->gravity, 9.81f); + } + } + } + } + } + + if (!MAIN_VERSION_ATLEAST(bmain, 283, 16)) { + /* Init SMAA threshold for grease pencil render. */ + LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) { + scene->grease_pencil_settings.smaa_threshold = 1.0f; + } + } + + if (!MAIN_VERSION_ATLEAST(bmain, 283, 17)) { + /* Reset the cloth mass to 1.0 in brushes with an invalid value. */ + for (Brush *br = bmain->brushes.first; br; br = br->id.next) { + if (br->sculpt_tool == SCULPT_TOOL_CLOTH) { + if (br->cloth_mass == 0.0f) { + br->cloth_mass = 1.0f; + } + } + } + + /* Set Brush default color for grease pencil. */ + LISTBASE_FOREACH (Brush *, brush, &bmain->brushes) { + if (brush->gpencil_settings) { + brush->rgb[0] = 0.498f; + brush->rgb[1] = 1.0f; + brush->rgb[2] = 0.498f; + } + } } /** diff --git a/source/blender/blenloader/intern/versioning_290.c b/source/blender/blenloader/intern/versioning_290.c new file mode 100644 index 00000000000..ed23b69c623 --- /dev/null +++ b/source/blender/blenloader/intern/versioning_290.c @@ -0,0 +1,270 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/** \file + * \ingroup blenloader + */ +/* allow readfile to use deprecated functionality */ +#define DNA_DEPRECATED_ALLOW + +#include "BLI_listbase.h" +#include "BLI_utildefines.h" + +#include "DNA_brush_types.h" +#include "DNA_genfile.h" +#include "DNA_gpencil_modifier_types.h" +#include "DNA_modifier_types.h" +#include "DNA_object_types.h" +#include "DNA_screen_types.h" + +#include "BKE_collection.h" +#include "BKE_colortools.h" +#include "BKE_lib_id.h" +#include "BKE_main.h" + +#include "BLO_readfile.h" +#include "readfile.h" + +/* Make preferences read-only, use versioning_userdef.c. */ +#define U (*((const UserDef *)&U)) + +void do_versions_after_linking_290(Main *bmain, ReportList *UNUSED(reports)) +{ + if (!MAIN_VERSION_ATLEAST(bmain, 290, 1)) { + /* Patch old grease pencil modifiers material filter. */ + LISTBASE_FOREACH (Object *, ob, &bmain->objects) { + LISTBASE_FOREACH (GpencilModifierData *, md, &ob->greasepencil_modifiers) { + switch (md->type) { + case eGpencilModifierType_Array: { + ArrayGpencilModifierData *gpmd = (ArrayGpencilModifierData *)md; + if (gpmd->materialname[0] != '\0') { + gpmd->material = BLI_findstring( + &bmain->materials, gpmd->materialname, offsetof(ID, name) + 2); + gpmd->materialname[0] = '\0'; + } + break; + } + case eGpencilModifierType_Color: { + ColorGpencilModifierData *gpmd = (ColorGpencilModifierData *)md; + if (gpmd->materialname[0] != '\0') { + gpmd->material = BLI_findstring( + &bmain->materials, gpmd->materialname, offsetof(ID, name) + 2); + gpmd->materialname[0] = '\0'; + } + break; + } + case eGpencilModifierType_Hook: { + HookGpencilModifierData *gpmd = (HookGpencilModifierData *)md; + if (gpmd->materialname[0] != '\0') { + gpmd->material = BLI_findstring( + &bmain->materials, gpmd->materialname, offsetof(ID, name) + 2); + gpmd->materialname[0] = '\0'; + } + break; + } + case eGpencilModifierType_Lattice: { + LatticeGpencilModifierData *gpmd = (LatticeGpencilModifierData *)md; + if (gpmd->materialname[0] != '\0') { + gpmd->material = BLI_findstring( + &bmain->materials, gpmd->materialname, offsetof(ID, name) + 2); + gpmd->materialname[0] = '\0'; + } + break; + } + case eGpencilModifierType_Mirror: { + MirrorGpencilModifierData *gpmd = (MirrorGpencilModifierData *)md; + if (gpmd->materialname[0] != '\0') { + gpmd->material = BLI_findstring( + &bmain->materials, gpmd->materialname, offsetof(ID, name) + 2); + gpmd->materialname[0] = '\0'; + } + break; + } + case eGpencilModifierType_Multiply: { + MultiplyGpencilModifierData *gpmd = (MultiplyGpencilModifierData *)md; + if (gpmd->materialname[0] != '\0') { + gpmd->material = BLI_findstring( + &bmain->materials, gpmd->materialname, offsetof(ID, name) + 2); + gpmd->materialname[0] = '\0'; + } + break; + } + case eGpencilModifierType_Noise: { + NoiseGpencilModifierData *gpmd = (NoiseGpencilModifierData *)md; + if (gpmd->materialname[0] != '\0') { + gpmd->material = BLI_findstring( + &bmain->materials, gpmd->materialname, offsetof(ID, name) + 2); + gpmd->materialname[0] = '\0'; + } + break; + } + case eGpencilModifierType_Offset: { + OffsetGpencilModifierData *gpmd = (OffsetGpencilModifierData *)md; + if (gpmd->materialname[0] != '\0') { + gpmd->material = BLI_findstring( + &bmain->materials, gpmd->materialname, offsetof(ID, name) + 2); + gpmd->materialname[0] = '\0'; + } + break; + } + case eGpencilModifierType_Opacity: { + OpacityGpencilModifierData *gpmd = (OpacityGpencilModifierData *)md; + if (gpmd->materialname[0] != '\0') { + gpmd->material = BLI_findstring( + &bmain->materials, gpmd->materialname, offsetof(ID, name) + 2); + gpmd->materialname[0] = '\0'; + } + break; + } + case eGpencilModifierType_Simplify: { + SimplifyGpencilModifierData *gpmd = (SimplifyGpencilModifierData *)md; + if (gpmd->materialname[0] != '\0') { + gpmd->material = BLI_findstring( + &bmain->materials, gpmd->materialname, offsetof(ID, name) + 2); + gpmd->materialname[0] = '\0'; + } + break; + } + case eGpencilModifierType_Smooth: { + SmoothGpencilModifierData *gpmd = (SmoothGpencilModifierData *)md; + if (gpmd->materialname[0] != '\0') { + gpmd->material = BLI_findstring( + &bmain->materials, gpmd->materialname, offsetof(ID, name) + 2); + gpmd->materialname[0] = '\0'; + } + break; + } + case eGpencilModifierType_Subdiv: { + SubdivGpencilModifierData *gpmd = (SubdivGpencilModifierData *)md; + if (gpmd->materialname[0] != '\0') { + gpmd->material = BLI_findstring( + &bmain->materials, gpmd->materialname, offsetof(ID, name) + 2); + gpmd->materialname[0] = '\0'; + } + break; + } + case eGpencilModifierType_Texture: { + TextureGpencilModifierData *gpmd = (TextureGpencilModifierData *)md; + if (gpmd->materialname[0] != '\0') { + gpmd->material = BLI_findstring( + &bmain->materials, gpmd->materialname, offsetof(ID, name) + 2); + gpmd->materialname[0] = '\0'; + } + break; + } + case eGpencilModifierType_Thick: { + ThickGpencilModifierData *gpmd = (ThickGpencilModifierData *)md; + if (gpmd->materialname[0] != '\0') { + gpmd->material = BLI_findstring( + &bmain->materials, gpmd->materialname, offsetof(ID, name) + 2); + gpmd->materialname[0] = '\0'; + } + break; + } + default: + break; + } + } + } + } + + /** + * Versioning code until next subversion bump goes here. + * + * \note Be sure to check when bumping the version: + * - #blo_do_versions_290 in this file. + * - "versioning_userdef.c", #BLO_version_defaults_userpref_blend + * - "versioning_userdef.c", #do_versions_theme + * + * \note Keep this message at the bottom of the function. + */ + { + /* Keep this block, even when empty. */ + } +} + +void blo_do_versions_290(FileData *fd, Library *UNUSED(lib), Main *bmain) +{ + UNUSED_VARS(fd); + + /** Repair files from duplicate brushes added to blend files, see: T76738. */ + if (!MAIN_VERSION_ATLEAST(bmain, 290, 2)) { + { + short id_codes[] = {ID_BR, ID_PAL}; + for (int i = 0; i < ARRAY_SIZE(id_codes); i++) { + ListBase *lb = which_libbase(bmain, id_codes[i]); + BKE_main_id_repair_duplicate_names_listbase(lb); + } + } + + if (!DNA_struct_elem_find(fd->filesdna, "SpaceImage", "float", "uv_opacity")) { + for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) { + LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { + LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) { + if (sl->spacetype == SPACE_IMAGE) { + SpaceImage *sima = (SpaceImage *)sl; + sima->uv_opacity = 1.0f; + } + } + } + } + } + + /* Init Grease Pencil new random curves. */ + if (!DNA_struct_elem_find(fd->filesdna, "BrushGpencilSettings", "float", "random_hue")) { + LISTBASE_FOREACH (Brush *, brush, &bmain->brushes) { + if ((brush->gpencil_settings) && (brush->gpencil_settings->curve_rand_pressure == NULL)) { + brush->gpencil_settings->curve_rand_pressure = BKE_curvemapping_add( + 1, 0.0f, 0.0f, 1.0f, 1.0f); + brush->gpencil_settings->curve_rand_strength = BKE_curvemapping_add( + 1, 0.0f, 0.0f, 1.0f, 1.0f); + brush->gpencil_settings->curve_rand_uv = BKE_curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f); + brush->gpencil_settings->curve_rand_hue = BKE_curvemapping_add( + 1, 0.0f, 0.0f, 1.0f, 1.0f); + brush->gpencil_settings->curve_rand_saturation = BKE_curvemapping_add( + 1, 0.0f, 0.0f, 1.0f, 1.0f); + brush->gpencil_settings->curve_rand_value = BKE_curvemapping_add( + 1, 0.0f, 0.0f, 1.0f, 1.0f); + } + } + } + } + + if (!MAIN_VERSION_ATLEAST(bmain, 290, 4)) { + /* Clear old deprecated bit-flag from edit weights modifiers, we now use it for something else. + */ + LISTBASE_FOREACH (Object *, ob, &bmain->objects) { + LISTBASE_FOREACH (ModifierData *, md, &ob->modifiers) { + if (md->type == eModifierType_WeightVGEdit) { + ((WeightVGEditModifierData *)md)->edit_flags &= ~MOD_WVG_EDIT_WEIGHTS_NORMALIZE; + } + } + } + } + + /** + * Versioning code until next subversion bump goes here. + * + * \note Be sure to check when bumping the version: + * - "versioning_userdef.c", #BLO_version_defaults_userpref_blend + * - "versioning_userdef.c", #do_versions_theme + * + * \note Keep this message at the bottom of the function. + */ + { + /* Keep this block, even when empty. */ + } +} diff --git a/source/blender/blenloader/intern/versioning_cycles.c b/source/blender/blenloader/intern/versioning_cycles.c index 14a940b9297..ff3d4574561 100644 --- a/source/blender/blenloader/intern/versioning_cycles.c +++ b/source/blender/blenloader/intern/versioning_cycles.c @@ -173,7 +173,7 @@ static void square_roughness_node_insert(bNodeTree *ntree) bool need_update = false; /* Update default values */ - for (bNode *node = ntree->nodes.first; node; node = node->next) { + LISTBASE_FOREACH (bNode *, node, &ntree->nodes) { if (node_has_roughness(node)) { bNodeSocket *roughness_input = nodeFindSocket(node, SOCK_IN, "Roughness"); float *roughness_value = cycles_node_socket_float_value(roughness_input); @@ -256,7 +256,7 @@ static void ambient_occlusion_node_relink(bNodeTree *ntree) bool need_update = false; /* Set default values. */ - for (bNode *node = ntree->nodes.first; node; node = node->next) { + LISTBASE_FOREACH (bNode *, node, &ntree->nodes) { if (node->type == SH_NODE_AMBIENT_OCCLUSION) { node->custom1 = 1; /* samples */ node->custom2 &= ~SHD_AO_LOCAL; @@ -338,7 +338,7 @@ static void light_emission_node_to_energy(Light *light, float *energy, float col } bNode *emission_node = NULL; - for (bNodeLink *link = ntree->links.first; link; link = link->next) { + LISTBASE_FOREACH (bNodeLink *, link, &ntree->links) { if (link->tonode == output_node && link->fromnode->type == SH_NODE_EMISSION) { emission_node = link->fromnode; break; @@ -410,7 +410,7 @@ static void update_math_node_single_operand_operators(bNodeTree *ntree) { bool need_update = false; - for (bNode *node = ntree->nodes.first; node; node = node->next) { + LISTBASE_FOREACH (bNode *, node, &ntree->nodes) { if (node->type == SH_NODE_MATH) { if (ELEM(node->custom1, NODE_MATH_SQRT, @@ -459,7 +459,7 @@ static void update_vector_math_node_add_and_subtract_operators(bNodeTree *ntree) { bool need_update = false; - for (bNode *node = ntree->nodes.first; node; node = node->next) { + LISTBASE_FOREACH (bNode *, node, &ntree->nodes) { if (node->type == SH_NODE_VECTOR_MATH) { bNodeSocket *sockOutValue = nodeFindSocket(node, SOCK_OUT, "Value"); if (socket_is_used(sockOutValue) && @@ -511,7 +511,7 @@ static void update_vector_math_node_dot_product_operator(bNodeTree *ntree) { bool need_update = false; - for (bNode *node = ntree->nodes.first; node; node = node->next) { + LISTBASE_FOREACH (bNode *, node, &ntree->nodes) { if (node->type == SH_NODE_VECTOR_MATH) { bNodeSocket *sockOutVector = nodeFindSocket(node, SOCK_OUT, "Vector"); if (socket_is_used(sockOutVector) && node->custom1 == NODE_VECTOR_MATH_DOT_PRODUCT) { @@ -550,7 +550,7 @@ static void update_vector_math_node_cross_product_operator(bNodeTree *ntree) { bool need_update = false; - for (bNode *node = ntree->nodes.first; node; node = node->next) { + LISTBASE_FOREACH (bNode *, node, &ntree->nodes) { if (node->type == SH_NODE_VECTOR_MATH) { if (node->custom1 == NODE_VECTOR_MATH_CROSS_PRODUCT) { bNodeSocket *sockOutVector = nodeFindSocket(node, SOCK_OUT, "Vector"); @@ -616,7 +616,7 @@ static void update_vector_math_node_normalize_operator(bNodeTree *ntree) { bool need_update = false; - for (bNode *node = ntree->nodes.first; node; node = node->next) { + LISTBASE_FOREACH (bNode *, node, &ntree->nodes) { if (node->type == SH_NODE_VECTOR_MATH) { bNodeSocket *sockOutValue = nodeFindSocket(node, SOCK_OUT, "Value"); if (node->custom1 == NODE_VECTOR_MATH_NORMALIZE && socket_is_used(sockOutValue)) { @@ -675,7 +675,7 @@ static void update_vector_math_node_normalize_operator(bNodeTree *ntree) */ static void update_vector_math_node_operators_enum_mapping(bNodeTree *ntree) { - for (bNode *node = ntree->nodes.first; node; node = node->next) { + LISTBASE_FOREACH (bNode *, node, &ntree->nodes) { if (node->type == SH_NODE_VECTOR_MATH) { switch (node->custom1) { case 2: @@ -702,7 +702,7 @@ static void update_vector_math_node_average_operator(bNodeTree *ntree) { bool need_update = false; - for (bNode *node = ntree->nodes.first; node; node = node->next) { + LISTBASE_FOREACH (bNode *, node, &ntree->nodes) { if (node->type == SH_NODE_VECTOR_MATH) { /* See update_vector_math_node_operators_enum_mapping. */ if (node->custom1 == -1) { @@ -765,7 +765,7 @@ static void update_vector_math_node_average_operator(bNodeTree *ntree) */ static void update_noise_node_dimensions(bNodeTree *ntree) { - for (bNode *node = ntree->nodes.first; node; node = node->next) { + LISTBASE_FOREACH (bNode *, node, &ntree->nodes) { if (node->type == SH_NODE_TEX_NOISE && node->storage) { NodeTexNoise *tex = (NodeTexNoise *)node->storage; tex->dimensions = 3; @@ -853,7 +853,7 @@ static void update_mapping_node_inputs_and_properties(bNodeTree *ntree) { bool need_update = false; - for (bNode *node = ntree->nodes.first; node; node = node->next) { + LISTBASE_FOREACH (bNode *, node, &ntree->nodes) { /* If node->storage is NULL, then conversion has already taken place. * This can happen if a file with the new mapping node [saved from (2, 81, 8) or newer] * is opened in a blender version prior to (2, 81, 8) and saved from there again. */ @@ -949,7 +949,7 @@ static void update_mapping_node_inputs_and_properties(bNodeTree *ntree) */ static void update_musgrave_node_dimensions(bNodeTree *ntree) { - for (bNode *node = ntree->nodes.first; node; node = node->next) { + LISTBASE_FOREACH (bNode *, node, &ntree->nodes) { if (node->type == SH_NODE_TEX_MUSGRAVE && node->storage) { NodeTexMusgrave *tex = (NodeTexMusgrave *)node->storage; tex->dimensions = 3; @@ -977,7 +977,7 @@ static void update_musgrave_node_color_output(bNodeTree *ntree) */ static void update_voronoi_node_dimensions(bNodeTree *ntree) { - for (bNode *node = ntree->nodes.first; node; node = node->next) { + LISTBASE_FOREACH (bNode *, node, &ntree->nodes) { if (node->type == SH_NODE_TEX_VORONOI && node->storage) { NodeTexVoronoi *tex = (NodeTexVoronoi *)node->storage; tex->dimensions = 3; @@ -992,7 +992,7 @@ static void update_voronoi_node_dimensions(bNodeTree *ntree) */ static void update_voronoi_node_f3_and_f4(bNodeTree *ntree) { - for (bNode *node = ntree->nodes.first; node; node = node->next) { + LISTBASE_FOREACH (bNode *, node, &ntree->nodes) { if (node->type == SH_NODE_TEX_VORONOI && node->storage) { NodeTexVoronoi *tex = (NodeTexVoronoi *)node->storage; if (ELEM(tex->feature, 2, 3)) { @@ -1010,7 +1010,7 @@ static void update_voronoi_node_f3_and_f4(bNodeTree *ntree) */ static void update_voronoi_node_fac_output(bNodeTree *ntree) { - for (bNode *node = ntree->nodes.first; node; node = node->next) { + LISTBASE_FOREACH (bNode *, node, &ntree->nodes) { if (node->type == SH_NODE_TEX_VORONOI) { bNodeSocket *facOutput = BLI_findlink(&node->outputs, 1); strcpy(facOutput->identifier, "Distance"); @@ -1040,7 +1040,7 @@ static void update_voronoi_node_crackle(bNodeTree *ntree) { bool need_update = false; - for (bNode *node = ntree->nodes.first; node; node = node->next) { + LISTBASE_FOREACH (bNode *, node, &ntree->nodes) { if (node->type == SH_NODE_TEX_VORONOI && node->storage) { NodeTexVoronoi *tex = (NodeTexVoronoi *)node->storage; bNodeSocket *sockDistance = nodeFindSocket(node, SOCK_OUT, "Distance"); @@ -1169,7 +1169,7 @@ static void update_voronoi_node_square_distance(bNodeTree *ntree) { bool need_update = false; - for (bNode *node = ntree->nodes.first; node; node = node->next) { + LISTBASE_FOREACH (bNode *, node, &ntree->nodes) { if (node->type == SH_NODE_TEX_VORONOI && node->storage) { NodeTexVoronoi *tex = (NodeTexVoronoi *)node->storage; bNodeSocket *sockDistance = nodeFindSocket(node, SOCK_OUT, "Distance"); @@ -1213,7 +1213,7 @@ static void update_noise_and_wave_distortion(bNodeTree *ntree) { bool need_update = false; - for (bNode *node = ntree->nodes.first; node; node = node->next) { + LISTBASE_FOREACH (bNode *, node, &ntree->nodes) { if (node->type == SH_NODE_TEX_NOISE || node->type == SH_NODE_TEX_WAVE) { bNodeSocket *sockDistortion = nodeFindSocket(node, SOCK_IN, "Distortion"); @@ -1262,7 +1262,7 @@ static void update_noise_and_wave_distortion(bNodeTree *ntree) */ static void update_wave_node_directions_and_offset(bNodeTree *ntree) { - for (bNode *node = ntree->nodes.first; node; node = node->next) { + LISTBASE_FOREACH (bNode *, node, &ntree->nodes) { if (node->type == SH_NODE_TEX_WAVE) { NodeTexWave *tex = (NodeTexWave *)node->storage; tex->bands_direction = SHD_WAVE_BANDS_DIRECTION_DIAGONAL; @@ -1351,13 +1351,13 @@ void do_versions_after_linking_cycles(Main *bmain) if (!MAIN_VERSION_ATLEAST(bmain, 273, 5)) { /* Euler order was ZYX in previous versions. */ - for (bNode *node = ntree->nodes.first; node; node = node->next) { + LISTBASE_FOREACH (bNode *, node, &ntree->nodes) { mapping_node_order_flip(node); } } if (!MAIN_VERSION_ATLEAST(bmain, 276, 6)) { - for (bNode *node = ntree->nodes.first; node; node = node->next) { + LISTBASE_FOREACH (bNode *, node, &ntree->nodes) { vector_curve_node_remap(node); } } @@ -1368,7 +1368,7 @@ void do_versions_after_linking_cycles(Main *bmain) } if (!MAIN_VERSION_ATLEAST(bmain, 279, 3)) { - for (bNode *node = ntree->nodes.first; node; node = node->next) { + LISTBASE_FOREACH (bNode *, node, &ntree->nodes) { displacement_principled_nodes(node); } } @@ -1384,7 +1384,7 @@ void do_versions_after_linking_cycles(Main *bmain) } if (!MAIN_VERSION_ATLEAST(bmain, 280, 66)) { - for (bNode *node = ntree->nodes.first; node; node = node->next) { + LISTBASE_FOREACH (bNode *, node, &ntree->nodes) { image_node_colorspace(node); } } diff --git a/source/blender/blenloader/intern/versioning_defaults.c b/source/blender/blenloader/intern/versioning_defaults.c index 80395177100..91d89254c90 100644 --- a/source/blender/blenloader/intern/versioning_defaults.c +++ b/source/blender/blenloader/intern/versioning_defaults.c @@ -71,7 +71,7 @@ static ID *rename_id_for_versioning(Main *bmain, /* We can ignore libraries */ ListBase *lb = which_libbase(bmain, id_type); ID *id = NULL; - for (ID *idtest = lb->first; idtest; idtest = idtest->next) { + LISTBASE_FOREACH (ID *, idtest, lb) { if (idtest->lib == NULL) { if (STREQ(idtest->name + 2, name_src)) { id = idtest; @@ -101,8 +101,8 @@ static void blo_update_defaults_screen(bScreen *screen, const char *workspace_name) { /* For all app templates. */ - for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) { - for (ARegion *region = sa->regionbase.first; region; region = region->next) { + LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { + LISTBASE_FOREACH (ARegion *, region, &area->regionbase) { /* Some toolbars have been saved as initialized, * we don't want them to have odd zoom-level or scrolling set, see: T47047 */ if (ELEM(region->regiontype, RGN_TYPE_UI, RGN_TYPE_TOOLS, RGN_TYPE_TOOL_PROPS)) { @@ -111,7 +111,7 @@ static void blo_update_defaults_screen(bScreen *screen, } /* Set default folder. */ - for (SpaceLink *sl = sa->spacedata.first; sl; sl = sl->next) { + LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) { if (sl->spacetype == SPACE_FILE) { SpaceFile *sfile = (SpaceFile *)sl; if (sfile->params) { @@ -130,8 +130,8 @@ static void blo_update_defaults_screen(bScreen *screen, return; } - for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) { - for (ARegion *region = sa->regionbase.first; region; region = region->next) { + LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { + LISTBASE_FOREACH (ARegion *, region, &area->regionbase) { /* Remove all stored panels, we want to use defaults * (order, open/closed) as defined by UI code here! */ BKE_area_region_panels_free(®ion->panels); @@ -142,48 +142,48 @@ static void blo_update_defaults_screen(bScreen *screen, region->sizey = 0; } - if (sa->spacetype == SPACE_IMAGE) { + if (area->spacetype == SPACE_IMAGE) { if (STREQ(workspace_name, "UV Editing")) { - SpaceImage *sima = sa->spacedata.first; + SpaceImage *sima = area->spacedata.first; if (sima->mode == SI_MODE_VIEW) { sima->mode = SI_MODE_UV; } } } - else if (sa->spacetype == SPACE_ACTION) { + else if (area->spacetype == SPACE_ACTION) { /* Show markers region, hide channels and collapse summary in timelines. */ - SpaceAction *saction = sa->spacedata.first; + SpaceAction *saction = area->spacedata.first; saction->flag |= SACTION_SHOW_MARKERS; if (saction->mode == SACTCONT_TIMELINE) { saction->ads.flag |= ADS_FLAG_SUMMARY_COLLAPSED; - for (ARegion *region = sa->regionbase.first; region; region = region->next) { + LISTBASE_FOREACH (ARegion *, region, &area->regionbase) { if (region->regiontype == RGN_TYPE_CHANNELS) { region->flag |= RGN_FLAG_HIDDEN; } } } } - else if (sa->spacetype == SPACE_GRAPH) { - SpaceGraph *sipo = sa->spacedata.first; + else if (area->spacetype == SPACE_GRAPH) { + SpaceGraph *sipo = area->spacedata.first; sipo->flag |= SIPO_SHOW_MARKERS; } - else if (sa->spacetype == SPACE_NLA) { - SpaceNla *snla = sa->spacedata.first; + else if (area->spacetype == SPACE_NLA) { + SpaceNla *snla = area->spacedata.first; snla->flag |= SNLA_SHOW_MARKERS; } - else if (sa->spacetype == SPACE_SEQ) { - SpaceSeq *seq = sa->spacedata.first; - seq->flag |= SEQ_SHOW_MARKERS; + else if (area->spacetype == SPACE_SEQ) { + SpaceSeq *seq = area->spacedata.first; + seq->flag |= SEQ_SHOW_MARKERS | SEQ_SHOW_FCURVES; } - else if (sa->spacetype == SPACE_TEXT) { + else if (area->spacetype == SPACE_TEXT) { /* Show syntax and line numbers in Script workspace text editor. */ - SpaceText *stext = sa->spacedata.first; + SpaceText *stext = area->spacedata.first; stext->showsyntax = true; stext->showlinenrs = true; } - else if (sa->spacetype == SPACE_VIEW3D) { - View3D *v3d = sa->spacedata.first; + else if (area->spacetype == SPACE_VIEW3D) { + View3D *v3d = area->spacedata.first; /* Screen space cavity by default for faster performance. */ v3d->shading.cavity_type = V3D_SHADING_CAVITY_CURVATURE; v3d->shading.flag |= V3D_SHADING_SPECULAR_HIGHLIGHT; @@ -197,24 +197,27 @@ static void blo_update_defaults_screen(bScreen *screen, v3d->gp_flag |= V3D_GP_SHOW_EDIT_LINES; /* Remove dither pattern in wireframe mode. */ v3d->shading.xray_alpha_wire = 0.0f; + v3d->clip_start = 0.01f; /* Skip startups that use the viewport color by default. */ if (v3d->shading.background_type != V3D_SHADING_BACKGROUND_VIEWPORT) { copy_v3_fl(v3d->shading.background_color, 0.05f); } + /* Disable Curve Normals. */ + v3d->overlay.edit_flag &= ~V3D_OVERLAY_EDIT_CU_NORMALS; } - else if (sa->spacetype == SPACE_CLIP) { - SpaceClip *sclip = sa->spacedata.first; + else if (area->spacetype == SPACE_CLIP) { + SpaceClip *sclip = area->spacedata.first; sclip->around = V3D_AROUND_CENTER_MEDIAN; } } /* Show tool-header by default (for most cases at least, hide for others). */ const bool hide_image_tool_header = STREQ(workspace_name, "Rendering"); - for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) { - for (SpaceLink *sl = sa->spacedata.first; sl; sl = sl->next) { - ListBase *regionbase = (sl == sa->spacedata.first) ? &sa->regionbase : &sl->regionbase; + LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { + LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) { + ListBase *regionbase = (sl == area->spacedata.first) ? &area->regionbase : &sl->regionbase; - for (ARegion *region = regionbase->first; region; region = region->next) { + LISTBASE_FOREACH (ARegion *, region, regionbase) { if (region->regiontype == RGN_TYPE_TOOL_HEADER) { if ((sl->spacetype == SPACE_IMAGE) && hide_image_tool_header) { region->flag |= RGN_FLAG_HIDDEN; @@ -229,20 +232,18 @@ static void blo_update_defaults_screen(bScreen *screen, /* 2D animation template. */ if (app_template && STREQ(app_template, "2D_Animation")) { - for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) { - for (ARegion *region = sa->regionbase.first; region; region = region->next) { - if (sa->spacetype == SPACE_ACTION) { - SpaceAction *saction = sa->spacedata.first; - /* Enable Sliders. */ - saction->flag |= SACTION_SLIDERS; - } - else if (sa->spacetype == SPACE_VIEW3D) { - View3D *v3d = sa->spacedata.first; - /* Set Material Color by default. */ - v3d->shading.color_type = V3D_SHADING_MATERIAL_COLOR; - /* Enable Annotations. */ - v3d->flag2 |= V3D_SHOW_ANNOTATION; - } + LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { + if (area->spacetype == SPACE_ACTION) { + SpaceAction *saction = area->spacedata.first; + /* Enable Sliders. */ + saction->flag |= SACTION_SLIDERS; + } + else if (area->spacetype == SPACE_VIEW3D) { + View3D *v3d = area->spacedata.first; + /* Set Material Color by default. */ + v3d->shading.color_type = V3D_SHADING_MATERIAL_COLOR; + /* Enable Annotations. */ + v3d->flag2 |= V3D_SHOW_ANNOTATION; } } } @@ -250,8 +251,7 @@ static void blo_update_defaults_screen(bScreen *screen, void BLO_update_defaults_workspace(WorkSpace *workspace, const char *app_template) { - ListBase *layouts = BKE_workspace_layouts_get(workspace); - for (WorkSpaceLayout *layout = layouts->first; layout; layout = layout->next) { + LISTBASE_FOREACH (WorkSpaceLayout *, layout, &workspace->layouts) { if (layout->screen) { blo_update_defaults_screen(layout->screen, app_template, workspace->id.name + 2); } @@ -270,13 +270,13 @@ void BLO_update_defaults_workspace(WorkSpace *workspace, const char *app_templat /* For Sculpting template. */ if (STREQ(workspace->id.name + 2, "Sculpting")) { - for (WorkSpaceLayout *layout = layouts->first; layout; layout = layout->next) { + LISTBASE_FOREACH (WorkSpaceLayout *, layout, &workspace->layouts) { bScreen *screen = layout->screen; if (screen) { - for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) { - for (ARegion *region = sa->regionbase.first; region; region = region->next) { - if (sa->spacetype == SPACE_VIEW3D) { - View3D *v3d = sa->spacedata.first; + LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { + LISTBASE_FOREACH (ARegion *, region, &area->regionbase) { + if (area->spacetype == SPACE_VIEW3D) { + View3D *v3d = area->spacedata.first; v3d->shading.flag &= ~V3D_SHADING_CAVITY; copy_v3_fl(v3d->shading.single_color, 1.0f); STRNCPY(v3d->shading.matcap, "basic_1"); @@ -297,7 +297,7 @@ static void blo_update_defaults_scene(Main *bmain, Scene *scene) /* Don't enable compositing nodes. */ if (scene->nodetree) { - ntreeFreeNestedTree(scene->nodetree); + ntreeFreeEmbeddedTree(scene->nodetree); MEM_freeN(scene->nodetree); scene->nodetree = NULL; scene->use_nodes = false; @@ -368,7 +368,13 @@ static void blo_update_defaults_scene(Main *bmain, Scene *scene) /** * Update defaults in startup.blend, without having to save and embed the file. - * This function can be emptied each time the startup.blend is updated. */ + * This function can be emptied each time the startup.blend is updated. + * + * \note Screen data may be cleared at this point, this will happen in the case + * an app-template's data needs to be versioned when read-file is called with "Load UI" disabled. + * Versioning the screen data can be safely skipped without "Load UI" since the screen data + * will have been versioned when it was first loaded. + */ void BLO_update_defaults_startup_blend(Main *bmain, const char *app_template) { /* For all app templates. */ @@ -376,30 +382,132 @@ void BLO_update_defaults_startup_blend(Main *bmain, const char *app_template) BLO_update_defaults_workspace(workspace, app_template); } + /* New grease pencil brushes and vertex paint setup. */ + { + /* Update Grease Pencil brushes. */ + Brush *brush; + + /* Pencil brush. */ + rename_id_for_versioning(bmain, ID_BR, "Draw Pencil", "Pencil"); + + /* Pen brush. */ + rename_id_for_versioning(bmain, ID_BR, "Draw Pen", "Pen"); + + /* Pen Soft brush. */ + brush = (Brush *)rename_id_for_versioning(bmain, ID_BR, "Draw Soft", "Pencil Soft"); + if (brush) { + brush->gpencil_settings->icon_id = GP_BRUSH_ICON_PEN; + } + + /* Ink Pen brush. */ + rename_id_for_versioning(bmain, ID_BR, "Draw Ink", "Ink Pen"); + + /* Ink Pen Rough brush. */ + rename_id_for_versioning(bmain, ID_BR, "Draw Noise", "Ink Pen Rough"); + + /* Marker Bold brush. */ + rename_id_for_versioning(bmain, ID_BR, "Draw Marker", "Marker Bold"); + + /* Marker Chisel brush. */ + rename_id_for_versioning(bmain, ID_BR, "Draw Block", "Marker Chisel"); + + /* Remove useless Fill Area.001 brush. */ + brush = BLI_findstring(&bmain->brushes, "Fill Area.001", offsetof(ID, name) + 2); + if (brush) { + BKE_id_delete(bmain, brush); + } + + /* Rename and fix materials and enable default object lights on. */ + if (app_template && STREQ(app_template, "2D_Animation")) { + Material *ma = NULL; + rename_id_for_versioning(bmain, ID_MA, "Black", "Solid Stroke"); + rename_id_for_versioning(bmain, ID_MA, "Red", "Squares Stroke"); + rename_id_for_versioning(bmain, ID_MA, "Grey", "Solid Fill"); + rename_id_for_versioning(bmain, ID_MA, "Black Dots", "Dots Stroke"); + + /* Dots Stroke. */ + ma = BLI_findstring(&bmain->materials, "Dots Stroke", offsetof(ID, name) + 2); + if (ma == NULL) { + ma = BKE_gpencil_material_add(bmain, "Dots Stroke"); + } + ma->gp_style->mode = GP_MATERIAL_MODE_DOT; + + /* Squares Stroke. */ + ma = BLI_findstring(&bmain->materials, "Squares Stroke", offsetof(ID, name) + 2); + if (ma == NULL) { + ma = BKE_gpencil_material_add(bmain, "Squares Stroke"); + } + ma->gp_style->mode = GP_MATERIAL_MODE_SQUARE; + + /* Change Solid Stroke settings. */ + ma = BLI_findstring(&bmain->materials, "Solid Stroke", offsetof(ID, name) + 2); + if (ma != NULL) { + ma->gp_style->mix_rgba[3] = 1.0f; + ma->gp_style->texture_offset[0] = -0.5f; + ma->gp_style->mix_factor = 0.5f; + } + + /* Change Solid Fill settings. */ + ma = BLI_findstring(&bmain->materials, "Solid Fill", offsetof(ID, name) + 2); + if (ma != NULL) { + ma->gp_style->flag &= ~GP_MATERIAL_STROKE_SHOW; + ma->gp_style->mix_rgba[3] = 1.0f; + ma->gp_style->texture_offset[0] = -0.5f; + ma->gp_style->mix_factor = 0.5f; + } + + Object *ob = BLI_findstring(&bmain->objects, "Stroke", offsetof(ID, name) + 2); + if (ob && ob->type == OB_GPENCIL) { + ob->dtx |= OB_USE_GPENCIL_LIGHTS; + } + } + + /* Reset all grease pencil brushes. */ + Scene *scene = bmain->scenes.first; + BKE_brush_gpencil_paint_presets(bmain, scene->toolsettings, true); + BKE_brush_gpencil_sculpt_presets(bmain, scene->toolsettings, true); + BKE_brush_gpencil_vertex_presets(bmain, scene->toolsettings, true); + BKE_brush_gpencil_weight_presets(bmain, scene->toolsettings, true); + + /* Ensure new Paint modes. */ + BKE_paint_ensure_from_paintmode(scene, PAINT_MODE_VERTEX_GPENCIL); + BKE_paint_ensure_from_paintmode(scene, PAINT_MODE_SCULPT_GPENCIL); + BKE_paint_ensure_from_paintmode(scene, PAINT_MODE_WEIGHT_GPENCIL); + + /* Enable cursor. */ + GpPaint *gp_paint = scene->toolsettings->gp_paint; + gp_paint->paint.flags |= PAINT_SHOW_BRUSH; + + /* Ensure Palette by default. */ + BKE_gpencil_palette_ensure(bmain, scene); + } + /* For builtin templates only. */ if (!blo_is_builtin_template(app_template)) { return; } /* Workspaces. */ - wmWindow *win = ((wmWindowManager *)bmain->wm.first)->windows.first; - for (WorkSpace *workspace = bmain->workspaces.first; workspace; workspace = workspace->id.next) { - WorkSpaceLayout *layout = BKE_workspace_hook_layout_for_workspace_get(win->workspace_hook, - workspace); - - /* Name all screens by their workspaces (avoids 'Default.###' names). */ - /* Default only has one window. */ - if (layout->screen) { - bScreen *screen = layout->screen; - BLI_strncpy(screen->id.name + 2, workspace->id.name + 2, sizeof(screen->id.name) - 2); - BLI_libblock_ensure_unique_name(bmain, screen->id.name); - } + LISTBASE_FOREACH (wmWindowManager *, wm, &bmain->wm) { + LISTBASE_FOREACH (wmWindow *, win, &wm->windows) { + LISTBASE_FOREACH (WorkSpace *, workspace, &bmain->workspaces) { + WorkSpaceLayout *layout = BKE_workspace_active_layout_for_workspace_get( + win->workspace_hook, workspace); + /* Name all screens by their workspaces (avoids 'Default.###' names). */ + /* Default only has one window. */ + if (layout->screen) { + bScreen *screen = layout->screen; + BLI_strncpy(screen->id.name + 2, workspace->id.name + 2, sizeof(screen->id.name) - 2); + BLI_libblock_ensure_unique_name(bmain, screen->id.name); + } - /* For some reason we have unused screens, needed until re-saving. - * Clear unused layouts because they're visible in the outliner & Python API. */ - LISTBASE_FOREACH_MUTABLE (WorkSpaceLayout *, layout_iter, &workspace->layouts) { - if (layout != layout_iter) { - BKE_workspace_layout_remove(bmain, workspace, layout_iter); + /* For some reason we have unused screens, needed until re-saving. + * Clear unused layouts because they're visible in the outliner & Python API. */ + LISTBASE_FOREACH_MUTABLE (WorkSpaceLayout *, layout_iter, &workspace->layouts) { + if (layout != layout_iter) { + BKE_workspace_layout_remove(bmain, workspace, layout_iter); + } + } } } } @@ -472,7 +580,7 @@ void BLO_update_defaults_startup_blend(Main *bmain, const char *app_template) ma->roughness = 0.4f; if (ma->nodetree) { - for (bNode *node = ma->nodetree->nodes.first; node; node = node->next) { + LISTBASE_FOREACH (bNode *, node, &ma->nodetree->nodes) { if (node->type == SH_NODE_BSDF_PRINCIPLED) { bNodeSocket *roughness_socket = nodeFindSocket(node, SOCK_IN, "Roughness"); bNodeSocketValueFloat *roughness_data = roughness_socket->default_value; @@ -598,90 +706,4 @@ void BLO_update_defaults_startup_blend(Main *bmain, const char *app_template) } } } - - /* New grease pencil brushes and vertex paint setup. */ - { - /* Update Grease Pencil brushes. */ - Brush *brush; - - /* Pencil brush. */ - rename_id_for_versioning(bmain, ID_BR, "Draw Pencil", "Pencil"); - - /* Pen brush. */ - rename_id_for_versioning(bmain, ID_BR, "Draw Pen", "Pen"); - - /* Pen Soft brush. */ - brush = (Brush *)rename_id_for_versioning(bmain, ID_BR, "Draw Soft", "Pencil Soft"); - if (brush) { - brush->gpencil_settings->icon_id = GP_BRUSH_ICON_PEN; - } - - /* Ink Pen brush. */ - rename_id_for_versioning(bmain, ID_BR, "Draw Ink", "Ink Pen"); - - /* Ink Pen Rough brush. */ - rename_id_for_versioning(bmain, ID_BR, "Draw Noise", "Ink Pen Rough"); - - /* Marker Bold brush. */ - rename_id_for_versioning(bmain, ID_BR, "Draw Marker", "Marker Bold"); - - /* Marker Chisel brush. */ - rename_id_for_versioning(bmain, ID_BR, "Draw Block", "Marker Chisel"); - - /* Remove useless Fill Area.001 brush. */ - brush = BLI_findstring(&bmain->brushes, "Fill Area.001", offsetof(ID, name) + 2); - if (brush) { - BKE_id_delete(bmain, brush); - } - - /* Rename and fix materials and enable default object lights on. */ - if (app_template && STREQ(app_template, "2D_Animation")) { - Material *ma = NULL; - rename_id_for_versioning(bmain, ID_MA, "Black", "Solid Stroke"); - rename_id_for_versioning(bmain, ID_MA, "Red", "Squares Stroke"); - rename_id_for_versioning(bmain, ID_MA, "Grey", "Solid Fill"); - rename_id_for_versioning(bmain, ID_MA, "Black Dots", "Dots Stroke"); - - /* Dots Stroke. */ - ma = BLI_findstring(&bmain->materials, "Dots Stroke", offsetof(ID, name) + 2); - if (ma == NULL) { - ma = BKE_gpencil_material_add(bmain, "Dots Stroke"); - } - ma->gp_style->mode = GP_MATERIAL_MODE_DOT; - - /* Squares Stroke. */ - ma = BLI_findstring(&bmain->materials, "Squares Stroke", offsetof(ID, name) + 2); - if (ma == NULL) { - ma = BKE_gpencil_material_add(bmain, "Squares Stroke"); - } - ma->gp_style->mode = GP_MATERIAL_MODE_SQUARE; - - /* Change Solid Fill settings. */ - ma = BLI_findstring(&bmain->materials, "Solid Fill", offsetof(ID, name) + 2); - if (ma != NULL) { - ma->gp_style->flag &= ~GP_MATERIAL_STROKE_SHOW; - } - - Object *ob = BLI_findstring(&bmain->objects, "Stroke", offsetof(ID, name) + 2); - if (ob && ob->type == OB_GPENCIL) { - ob->dtx |= OB_USE_GPENCIL_LIGHTS; - } - } - - /* Reset all grease pencil brushes. */ - Scene *scene = bmain->scenes.first; - BKE_brush_gpencil_paint_presets(bmain, scene->toolsettings); - - /* Ensure new Paint modes. */ - BKE_paint_ensure_from_paintmode(scene, PAINT_MODE_VERTEX_GPENCIL); - BKE_paint_ensure_from_paintmode(scene, PAINT_MODE_SCULPT_GPENCIL); - BKE_paint_ensure_from_paintmode(scene, PAINT_MODE_WEIGHT_GPENCIL); - - /* Enable cursor. */ - GpPaint *gp_paint = scene->toolsettings->gp_paint; - gp_paint->paint.flags |= PAINT_SHOW_BRUSH; - - /* Ensure Palette by default. */ - BKE_gpencil_palette_ensure(bmain, scene); - } } diff --git a/source/blender/blenloader/intern/versioning_legacy.c b/source/blender/blenloader/intern/versioning_legacy.c index 29c4a0f3c9d..2cc811e213f 100644 --- a/source/blender/blenloader/intern/versioning_legacy.c +++ b/source/blender/blenloader/intern/versioning_legacy.c @@ -580,11 +580,11 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *bmain) if (bmain->versionfile <= 109) { /* new variable: gridlines */ - bScreen *sc = bmain->screens.first; - while (sc) { - ScrArea *sa = sc->areabase.first; - while (sa) { - SpaceLink *sl = sa->spacedata.first; + bScreen *screen = bmain->screens.first; + while (screen) { + ScrArea *area = screen->areabase.first; + while (area) { + SpaceLink *sl = area->spacedata.first; while (sl) { if (sl->spacetype == SPACE_VIEW3D) { View3D *v3d = (View3D *)sl; @@ -595,9 +595,9 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *bmain) } sl = sl->next; } - sa = sa->next; + area = area->next; } - sc = sc->id.next; + screen = screen->id.next; } } @@ -694,11 +694,11 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *bmain) } if (bmain->versionfile <= 169) { - bScreen *sc = bmain->screens.first; - while (sc) { - ScrArea *sa = sc->areabase.first; - while (sa) { - SpaceLink *sl = sa->spacedata.first; + bScreen *screen = bmain->screens.first; + while (screen) { + ScrArea *area = screen->areabase.first; + while (area) { + SpaceLink *sl = area->spacedata.first; while (sl) { if (sl->spacetype == SPACE_GRAPH) { SpaceGraph *sipo = (SpaceGraph *)sl; @@ -706,9 +706,9 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *bmain) } sl = sl->next; } - sa = sa->next; + area = area->next; } - sc = sc->id.next; + screen = screen->id.next; } } @@ -727,11 +727,11 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *bmain) } if (bmain->versionfile <= 171) { - bScreen *sc = bmain->screens.first; - while (sc) { - ScrArea *sa = sc->areabase.first; - while (sa) { - SpaceLink *sl = sa->spacedata.first; + bScreen *screen = bmain->screens.first; + while (screen) { + ScrArea *area = screen->areabase.first; + while (area) { + SpaceLink *sl = area->spacedata.first; while (sl) { if (sl->spacetype == SPACE_TEXT) { SpaceText *st = (SpaceText *)sl; @@ -739,9 +739,9 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *bmain) } sl = sl->next; } - sa = sa->next; + area = area->next; } - sc = sc->id.next; + screen = screen->id.next; } } @@ -866,7 +866,7 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *bmain) bSound *sound; Scene *sce; Mesh *me; - bScreen *sc; + bScreen *screen; for (sound = bmain->sounds.first; sound; sound = sound->id.next) { if (sound->packedfile) { @@ -889,13 +889,13 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *bmain) } /* some oldfile patch, moved from set_func_space */ - for (sc = bmain->screens.first; sc; sc = sc->id.next) { - ScrArea *sa; + for (screen = bmain->screens.first; screen; screen = screen->id.next) { + ScrArea *area; - for (sa = sc->areabase.first; sa; sa = sa->next) { + for (area = screen->areabase.first; area; area = area->next) { SpaceLink *sl; - for (sl = sa->spacedata.first; sl; sl = sl->next) { + for (sl = area->spacedata.first; sl; sl = sl->next) { if (sl->spacetype == SPACE_GRAPH) { SpaceSeq *sseq = (SpaceSeq *)sl; sseq->v2d.keeptot = 0; @@ -907,7 +907,7 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *bmain) if (bmain->versionfile <= 227) { Scene *sce; - bScreen *sc; + bScreen *screen; Object *ob; /* As of now, this insures that the transition from the old Track system @@ -962,13 +962,13 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *bmain) } /* patch for old wrong max view2d settings, allows zooming out more */ - for (sc = bmain->screens.first; sc; sc = sc->id.next) { - ScrArea *sa; + for (screen = bmain->screens.first; screen; screen = screen->id.next) { + ScrArea *area; - for (sa = sc->areabase.first; sa; sa = sa->next) { + for (area = screen->areabase.first; area; area = area->next) { SpaceLink *sl; - for (sl = sa->spacedata.first; sl; sl = sl->next) { + for (sl = area->spacedata.first; sl; sl = sl->next) { if (sl->spacetype == SPACE_ACTION) { SpaceAction *sac = (SpaceAction *)sl; sac->v2d.max[0] = 32000; @@ -983,7 +983,7 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *bmain) } if (bmain->versionfile <= 228) { - bScreen *sc; + bScreen *screen; Object *ob; /* As of now, this insures that the transition from the old Track system @@ -1029,13 +1029,13 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *bmain) } /* convert old mainb values for new button panels */ - for (sc = bmain->screens.first; sc; sc = sc->id.next) { - ScrArea *sa; + for (screen = bmain->screens.first; screen; screen = screen->id.next) { + ScrArea *area; - for (sa = sc->areabase.first; sa; sa = sa->next) { + for (area = screen->areabase.first; area; area = area->next) { SpaceLink *sl; - for (sl = sa->spacedata.first; sl; sl = sl->next) { + for (sl = area->spacedata.first; sl; sl = sl->next) { if (sl->spacetype == SPACE_PROPERTIES) { SpaceProperties *sbuts = (SpaceProperties *)sl; @@ -1096,16 +1096,16 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *bmain) */ if (bmain->versionfile <= 230) { - bScreen *sc; + bScreen *screen; /* new variable blockscale, for panels in any area */ - for (sc = bmain->screens.first; sc; sc = sc->id.next) { - ScrArea *sa; + for (screen = bmain->screens.first; screen; screen = screen->id.next) { + ScrArea *area; - for (sa = sc->areabase.first; sa; sa = sa->next) { + for (area = screen->areabase.first; area; area = area->next) { SpaceLink *sl; - for (sl = sa->spacedata.first; sl; sl = sl->next) { + for (sl = area->spacedata.first; sl; sl = sl->next) { /* added: 5x better zoom in for action */ if (sl->spacetype == SPACE_ACTION) { SpaceAction *sac = (SpaceAction *)sl; @@ -1117,14 +1117,14 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *bmain) } if (bmain->versionfile <= 231) { - bScreen *sc = bmain->screens.first; + bScreen *screen = bmain->screens.first; /* new bit flags for showing/hiding grid floor and axes */ - while (sc) { - ScrArea *sa = sc->areabase.first; - while (sa) { - SpaceLink *sl = sa->spacedata.first; + while (screen) { + ScrArea *area = screen->areabase.first; + while (area) { + SpaceLink *sl = area->spacedata.first; while (sl) { if (sl->spacetype == SPACE_VIEW3D) { View3D *v3d = (View3D *)sl; @@ -1138,16 +1138,16 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *bmain) } sl = sl->next; } - sa = sa->next; + area = area->next; } - sc = sc->id.next; + screen = screen->id.next; } } if (bmain->versionfile <= 232) { Tex *tex = bmain->textures.first; World *wrld = bmain->worlds.first; - bScreen *sc; + bScreen *screen; while (tex) { if ((tex->flag & (TEX_CHECKER_ODD + TEX_CHECKER_EVEN)) == 0) { @@ -1184,11 +1184,11 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *bmain) /* new variable blockscale, for panels in any area, do again because new * areas didn't initialize it to 0.7 yet */ - for (sc = bmain->screens.first; sc; sc = sc->id.next) { - ScrArea *sa; - for (sa = sc->areabase.first; sa; sa = sa->next) { + for (screen = bmain->screens.first; screen; screen = screen->id.next) { + ScrArea *area; + for (area = screen->areabase.first; area; area = area->next) { SpaceLink *sl; - for (sl = sa->spacedata.first; sl; sl = sl->next) { + for (sl = area->spacedata.first; sl; sl = sl->next) { /* added: 5x better zoom in for nla */ if (sl->spacetype == SPACE_NLA) { SpaceNla *snla = (SpaceNla *)sl; @@ -1200,13 +1200,13 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *bmain) } if (bmain->versionfile <= 233) { - bScreen *sc; + bScreen *screen; - for (sc = bmain->screens.first; sc; sc = sc->id.next) { - ScrArea *sa; - for (sa = sc->areabase.first; sa; sa = sa->next) { + for (screen = bmain->screens.first; screen; screen = screen->id.next) { + ScrArea *area; + for (area = screen->areabase.first; area; area = area->next) { SpaceLink *sl; - for (sl = sa->spacedata.first; sl; sl = sl->next) { + for (sl = area->spacedata.first; sl; sl = sl->next) { if (sl->spacetype == SPACE_VIEW3D) { View3D *v3d = (View3D *)sl; v3d->flag |= V3D_SELECT_OUTLINE; @@ -1217,13 +1217,13 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *bmain) } if (bmain->versionfile <= 234) { - bScreen *sc; + bScreen *screen; - for (sc = bmain->screens.first; sc; sc = sc->id.next) { - ScrArea *sa; - for (sa = sc->areabase.first; sa; sa = sa->next) { + for (screen = bmain->screens.first; screen; screen = screen->id.next) { + ScrArea *area; + for (area = screen->areabase.first; area; area = area->next) { SpaceLink *sl; - for (sl = sa->spacedata.first; sl; sl = sl->next) { + for (sl = area->spacedata.first; sl; sl = sl->next) { if (sl->spacetype == SPACE_TEXT) { SpaceText *st = (SpaceText *)sl; if (st->tabnumber == 0) { @@ -1351,7 +1351,8 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *bmain) }; if ((me->flag & ME_SUBSURF)) { - SubsurfModifierData *smd = (SubsurfModifierData *)modifier_new(eModifierType_Subsurf); + SubsurfModifierData *smd = (SubsurfModifierData *)BKE_modifier_new( + eModifierType_Subsurf); smd->levels = MAX2(1, me->subdiv); smd->renderLevels = MAX2(1, me->subdivr); @@ -1371,7 +1372,7 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *bmain) BLI_addtail(&ob->modifiers, smd); - modifier_unique_name(&ob->modifiers, (ModifierData *)smd); + BKE_modifier_unique_name(&ob->modifiers, (ModifierData *)smd); } } @@ -1428,18 +1429,19 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *bmain) } } - if ((ob->softflag & OB_SB_ENABLE) && !modifiers_findByType(ob, eModifierType_Softbody)) { + if ((ob->softflag & OB_SB_ENABLE) && + !BKE_modifiers_findby_type(ob, eModifierType_Softbody)) { if (ob->softflag & OB_SB_POSTDEF) { md = ob->modifiers.first; - while (md && modifierType_getInfo(md->type)->type == eModifierTypeType_OnlyDeform) { + while (md && BKE_modifier_get_info(md->type)->type == eModifierTypeType_OnlyDeform) { md = md->next; } - BLI_insertlinkbefore(&ob->modifiers, md, modifier_new(eModifierType_Softbody)); + BLI_insertlinkbefore(&ob->modifiers, md, BKE_modifier_new(eModifierType_Softbody)); } else { - BLI_addhead(&ob->modifiers, modifier_new(eModifierType_Softbody)); + BLI_addhead(&ob->modifiers, BKE_modifier_new(eModifierType_Softbody)); } ob->softflag &= ~OB_SB_ENABLE; @@ -1651,7 +1653,7 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *bmain) if (bmain->versionfile <= 242) { Scene *sce; - bScreen *sc; + bScreen *screen; Object *ob; Curve *cu; Material *ma; @@ -1663,13 +1665,13 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *bmain) bNodeTree *ntree; int a; - for (sc = bmain->screens.first; sc; sc = sc->id.next) { - ScrArea *sa; - sa = sc->areabase.first; - while (sa) { + for (screen = bmain->screens.first; screen; screen = screen->id.next) { + ScrArea *area; + area = screen->areabase.first; + while (area) { SpaceLink *sl; - for (sl = sa->spacedata.first; sl; sl = sl->next) { + for (sl = area->spacedata.first; sl; sl = sl->next) { if (sl->spacetype == SPACE_VIEW3D) { View3D *v3d = (View3D *)sl; if (v3d->gridsubdiv == 0) { @@ -1677,7 +1679,7 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *bmain) } } } - sa = sa->next; + area = area->next; } } @@ -1922,17 +1924,17 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *bmain) } if (bmain->versionfile <= 244) { - bScreen *sc; + bScreen *screen; if (bmain->versionfile != 244 || bmain->subversionfile < 2) { /* correct older action editors - incorrect scrolling */ - for (sc = bmain->screens.first; sc; sc = sc->id.next) { - ScrArea *sa; - sa = sc->areabase.first; - while (sa) { + for (screen = bmain->screens.first; screen; screen = screen->id.next) { + ScrArea *area; + area = screen->areabase.first; + while (area) { SpaceLink *sl; - for (sl = sa->spacedata.first; sl; sl = sl->next) { + for (sl = area->spacedata.first; sl; sl = sl->next) { if (sl->spacetype == SPACE_ACTION) { SpaceAction *saction = (SpaceAction *)sl; @@ -1943,7 +1945,7 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *bmain) saction->v2d.cur.ymax = 5.0; } } - sa = sa->next; + area = area->next; } } } @@ -2271,7 +2273,7 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *bmain) BLI_addtail(&ob->particlesystem, psys); - md = modifier_new(eModifierType_ParticleSystem); + md = BKE_modifier_new(eModifierType_ParticleSystem); BLI_snprintf(md->name, sizeof(md->name), "ParticleSystem %i", @@ -2357,7 +2359,7 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *bmain) } { - FluidsimModifierData *fluidmd = (FluidsimModifierData *)modifiers_findByType( + FluidsimModifierData *fluidmd = (FluidsimModifierData *)BKE_modifiers_findby_type( ob, eModifierType_Fluidsim); if (fluidmd && fluidmd->fss && fluidmd->fss->type == OB_FLUIDSIM_PARTICLE) { part->type = PART_FLUID; @@ -2483,7 +2485,7 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *bmain) for (ob = bmain->objects.first; ob; ob = ob->id.next) { if (ob->fluidsimSettings) { - FluidsimModifierData *fluidmd = (FluidsimModifierData *)modifier_new( + FluidsimModifierData *fluidmd = (FluidsimModifierData *)BKE_modifier_new( eModifierType_Fluidsim); BLI_addhead(&ob->modifiers, (ModifierData *)fluidmd); @@ -2540,16 +2542,16 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *bmain) } if (bmain->versionfile < 248 || (bmain->versionfile == 248 && bmain->subversionfile < 3)) { - bScreen *sc; + bScreen *screen; /* adjust default settings for Animation Editors */ - for (sc = bmain->screens.first; sc; sc = sc->id.next) { - ScrArea *sa; + for (screen = bmain->screens.first; screen; screen = screen->id.next) { + ScrArea *area; - for (sa = sc->areabase.first; sa; sa = sa->next) { + for (area = screen->areabase.first; area; area = area->next) { SpaceLink *sl; - for (sl = sa->spacedata.first; sl; sl = sl->next) { + for (sl = area->spacedata.first; sl; sl = sl->next) { switch (sl->spacetype) { case SPACE_ACTION: { SpaceAction *sact = (SpaceAction *)sl; diff --git a/source/blender/blenloader/intern/versioning_userdef.c b/source/blender/blenloader/intern/versioning_userdef.c index a88e4e20d68..1b0e41ec54a 100644 --- a/source/blender/blenloader/intern/versioning_userdef.c +++ b/source/blender/blenloader/intern/versioning_userdef.c @@ -22,9 +22,14 @@ #define DNA_DEPRECATED_ALLOW #include <string.h> +#include "BLI_listbase.h" #include "BLI_math.h" #include "BLI_utildefines.h" +#ifdef WITH_INTERNATIONAL +# include "BLT_translation.h" +#endif + #include "DNA_anim_types.h" #include "DNA_curve_types.h" #include "DNA_scene_types.h" @@ -533,7 +538,7 @@ void BLO_version_defaults_userpref_blend(Main *bmain, UserDef *userdef) userdef->gpu_viewport_quality = 0.6f; /* Reset theme, old themes will not be compatible with minor version updates from now on. */ - for (bTheme *btheme = userdef->themes.first; btheme; btheme = btheme->next) { + LISTBASE_FOREACH (bTheme *, btheme, &userdef->themes) { memcpy(btheme, &U_theme_default, sizeof(*btheme)); } @@ -551,8 +556,8 @@ void BLO_version_defaults_userpref_blend(Main *bmain, UserDef *userdef) if (!USER_VERSION_ATLEAST(280, 31)) { /* Remove select/action mouse from user defined keymaps. */ - for (wmKeyMap *keymap = userdef->user_keymaps.first; keymap; keymap = keymap->next) { - for (wmKeyMapDiffItem *kmdi = keymap->diff_items.first; kmdi; kmdi = kmdi->next) { + LISTBASE_FOREACH (wmKeyMap *, keymap, &userdef->user_keymaps) { + LISTBASE_FOREACH (wmKeyMapDiffItem *, kmdi, &keymap->diff_items) { if (kmdi->remove_item) { do_version_select_mouse(userdef, kmdi->remove_item); } @@ -561,7 +566,7 @@ void BLO_version_defaults_userpref_blend(Main *bmain, UserDef *userdef) } } - for (wmKeyMapItem *kmi = keymap->items.first; kmi; kmi = kmi->next) { + LISTBASE_FOREACH (wmKeyMapItem *, kmi, &keymap->items) { do_version_select_mouse(userdef, kmi); } } @@ -739,6 +744,15 @@ void BLO_version_defaults_userpref_blend(Main *bmain, UserDef *userdef) userdef->gpu_flag |= USER_GPU_FLAG_OVERLAY_SMOOTH_WIRE; } + if (!USER_VERSION_ATLEAST(283, 13)) { + /* If Translations is off then language should default to English. */ + if ((userdef->transopts & USER_DOTRANSLATE_DEPRECATED) == 0) { + userdef->language = ULANGUAGE_ENGLISH; + } + /* Clear this deprecated flag. */ + userdef->transopts &= ~USER_DOTRANSLATE_DEPRECATED; + } + /** * Versioning code until next subversion bump goes here. * @@ -750,13 +764,17 @@ void BLO_version_defaults_userpref_blend(Main *bmain, UserDef *userdef) */ { /* Keep this block, even when empty. */ + + if (userdef->collection_instance_empty_size == 0) { + userdef->collection_instance_empty_size = 1.0f; + } } if (userdef->pixelsize == 0.0f) { userdef->pixelsize = 1.0f; } - for (bTheme *btheme = userdef->themes.first; btheme; btheme = btheme->next) { + LISTBASE_FOREACH (bTheme *, btheme, &userdef->themes) { do_versions_theme(userdef, btheme); } #undef USER_VERSION_ATLEAST diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index 599e592c77d..73bab07a008 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -133,6 +133,7 @@ #include "DNA_sdna_types.h" #include "DNA_sequence_types.h" #include "DNA_shader_fx_types.h" +#include "DNA_simulation_types.h" #include "DNA_sound_types.h" #include "DNA_space_types.h" #include "DNA_speaker_types.h" @@ -156,14 +157,17 @@ #include "BKE_constraint.h" #include "BKE_curve.h" #include "BKE_fcurve.h" +#include "BKE_fcurve_driver.h" #include "BKE_global.h" // for G #include "BKE_gpencil_modifier.h" #include "BKE_idtype.h" #include "BKE_layer.h" +#include "BKE_lib_id.h" #include "BKE_lib_override.h" #include "BKE_main.h" #include "BKE_modifier.h" #include "BKE_node.h" +#include "BKE_object.h" #include "BKE_pointcache.h" #include "BKE_report.h" #include "BKE_sequencer.h" @@ -173,6 +177,7 @@ #include "BLO_blend_defs.h" #include "BLO_blend_validate.h" +#include "BLO_read_write.h" #include "BLO_readfile.h" #include "BLO_undofile.h" #include "BLO_writefile.h" @@ -323,12 +328,7 @@ typedef struct { bool error; /** #MemFile writing (used for undo). */ - struct { - MemFile *current; - MemFile *compare; - /** Use to de-duplicate chunks when writing. */ - MemFileChunk *compare_chunk; - } mem; + MemFileWriteData mem; /** When true, write to #WriteData.current, could also call 'is_undo'. */ bool use_memfile; @@ -340,6 +340,10 @@ typedef struct { WriteWrap *ww; } WriteData; +typedef struct BlendWriter { + WriteData *wd; +} BlendWriter; + static WriteData *writedata_new(WriteWrap *ww) { WriteData *wd = MEM_callocN(sizeof(*wd), "writedata"); @@ -367,7 +371,7 @@ static void writedata_do_write(WriteData *wd, const void *mem, int memlen) /* memory based save */ if (wd->use_memfile) { - memfile_chunk_add(wd->mem.current, mem, memlen, &wd->mem.compare_chunk); + BLO_memfile_chunk_add(&wd->mem, mem, memlen); } else { if (wd->ww->write(wd->ww, mem, memlen) != memlen) { @@ -468,9 +472,7 @@ static WriteData *mywrite_begin(WriteWrap *ww, MemFile *compare, MemFile *curren WriteData *wd = writedata_new(ww); if (current != NULL) { - wd->mem.current = current; - wd->mem.compare = compare; - wd->mem.compare_chunk = compare ? compare->chunks.first : NULL; + BLO_memfile_write_init(&wd->mem, current, compare); wd->use_memfile = true; } @@ -490,12 +492,58 @@ static bool mywrite_end(WriteData *wd) wd->buf_used_len = 0; } + if (wd->use_memfile) { + BLO_memfile_write_finalize(&wd->mem); + } + const bool err = wd->error; writedata_free(wd); return err; } +/** + * Start writing of data related to a single ID. + * + * Only does something when storing an undo step. + */ +static void mywrite_id_begin(WriteData *wd, ID *id) +{ + if (wd->use_memfile) { + wd->mem.current_id_session_uuid = id->session_uuid; + + /* If current next memchunk does not match the ID we are about to write, try to find the + * correct memchunk in the mapping using ID's session_uuid. */ + if (wd->mem.id_session_uuid_mapping != NULL && + (wd->mem.reference_current_chunk == NULL || + wd->mem.reference_current_chunk->id_session_uuid != id->session_uuid)) { + void *ref = BLI_ghash_lookup(wd->mem.id_session_uuid_mapping, + POINTER_FROM_UINT(id->session_uuid)); + if (ref != NULL) { + wd->mem.reference_current_chunk = ref; + } + /* Else, no existing memchunk found, i.e. this is supposed to be a new ID. */ + } + /* Otherwise, we try with the current memchunk in any case, whether it is matching current + * ID's session_uuid or not. */ + } +} + +/** + * Start writing of data related to a single ID. + * + * Only does something when storing an undo step. + */ +static void mywrite_id_end(WriteData *wd, ID *UNUSED(id)) +{ + if (wd->use_memfile) { + /* Very important to do it after every ID write now, otherwise we cannot know whether a + * specific ID changed or not. */ + mywrite_flush(wd); + wd->mem.current_id_session_uuid = MAIN_ID_SESSION_UUID_UNSET; + } +} + /** \} */ /* -------------------------------------------------------------------- */ @@ -631,79 +679,86 @@ static void writelist_id(WriteData *wd, int filecode, const char *structname, co * These functions are used by blender's .blend system for file saving/loading. * \{ */ -void IDP_WriteProperty_OnlyData(const IDProperty *prop, void *wd); -void IDP_WriteProperty(const IDProperty *prop, void *wd); +void IDP_WriteProperty_OnlyData(const IDProperty *prop, BlendWriter *writer); +void IDP_WriteProperty(const IDProperty *prop, WriteData *wd); +void IDP_WriteProperty_new_api(const IDProperty *prop, BlendWriter *writer); -static void IDP_WriteArray(const IDProperty *prop, void *wd) +static void IDP_WriteArray(const IDProperty *prop, BlendWriter *writer) { /*REMEMBER to set totalen to len in the linking code!!*/ if (prop->data.pointer) { - writedata(wd, DATA, MEM_allocN_len(prop->data.pointer), prop->data.pointer); + BLO_write_raw(writer, MEM_allocN_len(prop->data.pointer), prop->data.pointer); if (prop->subtype == IDP_GROUP) { IDProperty **array = prop->data.pointer; int a; for (a = 0; a < prop->len; a++) { - IDP_WriteProperty(array[a], wd); + IDP_WriteProperty_new_api(array[a], writer); } } } } -static void IDP_WriteIDPArray(const IDProperty *prop, void *wd) +static void IDP_WriteIDPArray(const IDProperty *prop, BlendWriter *writer) { /*REMEMBER to set totalen to len in the linking code!!*/ if (prop->data.pointer) { const IDProperty *array = prop->data.pointer; int a; - writestruct(wd, DATA, IDProperty, prop->len, array); + BLO_write_struct_array(writer, IDProperty, prop->len, array); for (a = 0; a < prop->len; a++) { - IDP_WriteProperty_OnlyData(&array[a], wd); + IDP_WriteProperty_OnlyData(&array[a], writer); } } } -static void IDP_WriteString(const IDProperty *prop, void *wd) +static void IDP_WriteString(const IDProperty *prop, BlendWriter *writer) { /*REMEMBER to set totalen to len in the linking code!!*/ - writedata(wd, DATA, prop->len, prop->data.pointer); + BLO_write_raw(writer, prop->len, prop->data.pointer); } -static void IDP_WriteGroup(const IDProperty *prop, void *wd) +static void IDP_WriteGroup(const IDProperty *prop, BlendWriter *writer) { IDProperty *loop; for (loop = prop->data.group.first; loop; loop = loop->next) { - IDP_WriteProperty(loop, wd); + IDP_WriteProperty_new_api(loop, writer); } } /* Functions to read/write ID Properties */ -void IDP_WriteProperty_OnlyData(const IDProperty *prop, void *wd) +void IDP_WriteProperty_OnlyData(const IDProperty *prop, BlendWriter *writer) { switch (prop->type) { case IDP_GROUP: - IDP_WriteGroup(prop, wd); + IDP_WriteGroup(prop, writer); break; case IDP_STRING: - IDP_WriteString(prop, wd); + IDP_WriteString(prop, writer); break; case IDP_ARRAY: - IDP_WriteArray(prop, wd); + IDP_WriteArray(prop, writer); break; case IDP_IDPARRAY: - IDP_WriteIDPArray(prop, wd); + IDP_WriteIDPArray(prop, writer); break; } } -void IDP_WriteProperty(const IDProperty *prop, void *wd) +void IDP_WriteProperty_new_api(const IDProperty *prop, BlendWriter *writer) { - writestruct(wd, DATA, IDProperty, 1, prop); - IDP_WriteProperty_OnlyData(prop, wd); + BLO_write_struct(writer, IDProperty, prop); + IDP_WriteProperty_OnlyData(prop, writer); +} + +void IDP_WriteProperty(const IDProperty *prop, WriteData *wd) +{ + BlendWriter writer = {wd}; + IDP_WriteProperty_new_api(prop, &writer); } static void write_iddata(WriteData *wd, ID *id) @@ -717,13 +772,11 @@ static void write_iddata(WriteData *wd, ID *id) writestruct(wd, DATA, IDOverrideLibrary, 1, id->override_library); writelist(wd, DATA, IDOverrideLibraryProperty, &id->override_library->properties); - for (IDOverrideLibraryProperty *op = id->override_library->properties.first; op; - op = op->next) { + LISTBASE_FOREACH (IDOverrideLibraryProperty *, op, &id->override_library->properties) { writedata(wd, DATA, strlen(op->rna_path) + 1, op->rna_path); writelist(wd, DATA, IDOverrideLibraryPropertyOperation, &op->operations); - for (IDOverrideLibraryPropertyOperation *opop = op->operations.first; opop; - opop = opop->next) { + LISTBASE_FOREACH (IDOverrideLibraryPropertyOperation *, opop, &op->operations) { if (opop->subitem_reference_name) { writedata( wd, DATA, strlen(opop->subitem_reference_name) + 1, opop->subitem_reference_name); @@ -734,11 +787,6 @@ static void write_iddata(WriteData *wd, ID *id) } } } - - /* Clear the accumulated recalc flags in case of undo step saving. */ - if (wd->use_memfile) { - id->recalc_undo_accumulated = 0; - } } static void write_previews(WriteData *wd, const PreviewImage *prv_orig) @@ -859,19 +907,19 @@ static void write_fcurves(WriteData *wd, ListBase *fcurves) } } -static void write_action(WriteData *wd, bAction *act) +static void write_action(WriteData *wd, bAction *act, const void *id_address) { if (act->id.us > 0 || wd->use_memfile) { - writestruct(wd, ID_AC, bAction, 1, act); + writestruct_at_address(wd, ID_AC, bAction, 1, id_address, act); write_iddata(wd, &act->id); write_fcurves(wd, &act->curves); - for (bActionGroup *grp = act->groups.first; grp; grp = grp->next) { + LISTBASE_FOREACH (bActionGroup *, grp, &act->groups) { writestruct(wd, DATA, bActionGroup, 1, grp); } - for (TimeMarker *marker = act->markers.first; marker; marker = marker->next) { + LISTBASE_FOREACH (TimeMarker *, marker, &act->markers) { writestruct(wd, DATA, TimeMarker, 1, marker); } } @@ -996,9 +1044,19 @@ static void write_node_socket_default_value(WriteData *wd, bNodeSocket *sock) case SOCK_STRING: writestruct(wd, DATA, bNodeSocketValueString, 1, sock->default_value); break; + case SOCK_OBJECT: + writestruct(wd, DATA, bNodeSocketValueObject, 1, sock->default_value); + break; + case SOCK_IMAGE: + writestruct(wd, DATA, bNodeSocketValueImage, 1, sock->default_value); + break; case __SOCK_MESH: case SOCK_CUSTOM: case SOCK_SHADER: + case SOCK_EMITTERS: + case SOCK_EVENTS: + case SOCK_FORCES: + case SOCK_CONTROL_FLOW: BLI_assert(false); break; } @@ -1139,11 +1197,6 @@ static void write_nodetree_nolib(WriteData *wd, bNodeTree *ntree) for (sock = ntree->outputs.first; sock; sock = sock->next) { write_node_socket_interface(wd, sock); } - - /* Clear the accumulated recalc flags in case of undo step saving. */ - if (wd->use_memfile) { - ntree->id.recalc_undo_accumulated = 0; - } } /** @@ -1235,14 +1288,14 @@ static void write_userdef(WriteData *wd, const UserDef *userdef) { writestruct(wd, USER, UserDef, 1, userdef); - for (const bTheme *btheme = userdef->themes.first; btheme; btheme = btheme->next) { + LISTBASE_FOREACH (const bTheme *, btheme, &userdef->themes) { writestruct(wd, DATA, bTheme, 1, btheme); } - for (const wmKeyMap *keymap = userdef->user_keymaps.first; keymap; keymap = keymap->next) { + LISTBASE_FOREACH (const wmKeyMap *, keymap, &userdef->user_keymaps) { writestruct(wd, DATA, wmKeyMap, 1, keymap); - for (const wmKeyMapDiffItem *kmdi = keymap->diff_items.first; kmdi; kmdi = kmdi->next) { + LISTBASE_FOREACH (const wmKeyMapDiffItem *, kmdi, &keymap->diff_items) { writestruct(wd, DATA, wmKeyMapDiffItem, 1, kmdi); if (kmdi->remove_item) { write_keymapitem(wd, kmdi->remove_item); @@ -1252,21 +1305,21 @@ static void write_userdef(WriteData *wd, const UserDef *userdef) } } - for (const wmKeyMapItem *kmi = keymap->items.first; kmi; kmi = kmi->next) { + LISTBASE_FOREACH (const wmKeyMapItem *, kmi, &keymap->items) { write_keymapitem(wd, kmi); } } - for (const wmKeyConfigPref *kpt = userdef->user_keyconfig_prefs.first; kpt; kpt = kpt->next) { + LISTBASE_FOREACH (const wmKeyConfigPref *, kpt, &userdef->user_keyconfig_prefs) { writestruct(wd, DATA, wmKeyConfigPref, 1, kpt); if (kpt->prop) { IDP_WriteProperty(kpt->prop, wd); } } - for (const bUserMenu *um = userdef->user_menus.first; um; um = um->next) { + LISTBASE_FOREACH (const bUserMenu *, um, &userdef->user_menus) { writestruct(wd, DATA, bUserMenu, 1, um); - for (const bUserMenuItem *umi = um->items.first; umi; umi = umi->next) { + LISTBASE_FOREACH (const bUserMenuItem *, umi, &um->items) { if (umi->type == USER_MENU_TYPE_OPERATOR) { const bUserMenuItem_Op *umi_op = (const bUserMenuItem_Op *)umi; writestruct(wd, DATA, bUserMenuItem_Op, 1, umi_op); @@ -1288,19 +1341,18 @@ static void write_userdef(WriteData *wd, const UserDef *userdef) } } - for (const bAddon *bext = userdef->addons.first; bext; bext = bext->next) { + LISTBASE_FOREACH (const bAddon *, bext, &userdef->addons) { writestruct(wd, DATA, bAddon, 1, bext); if (bext->prop) { IDP_WriteProperty(bext->prop, wd); } } - for (const bPathCompare *path_cmp = userdef->autoexec_paths.first; path_cmp; - path_cmp = path_cmp->next) { + LISTBASE_FOREACH (const bPathCompare *, path_cmp, &userdef->autoexec_paths) { writestruct(wd, DATA, bPathCompare, 1, path_cmp); } - for (const uiStyle *style = userdef->uistyles.first; style; style = style->next) { + LISTBASE_FOREACH (const uiStyle *, style, &userdef->uistyles) { writestruct(wd, DATA, uiStyle, 1, style); } } @@ -1396,11 +1448,11 @@ static void write_pointcaches(WriteData *wd, ListBase *ptcaches) } } -static void write_particlesettings(WriteData *wd, ParticleSettings *part) +static void write_particlesettings(WriteData *wd, ParticleSettings *part, const void *id_address) { if (part->id.us > 0 || wd->use_memfile) { /* write LibData */ - writestruct(wd, ID_PA, ParticleSettings, 1, part); + writestruct_at_address(wd, ID_PA, ParticleSettings, 1, id_address, part); write_iddata(wd, &part->id); if (part->adt) { @@ -1420,7 +1472,7 @@ static void write_particlesettings(WriteData *wd, ParticleSettings *part) write_curvemapping(wd, part->twistcurve); } - for (ParticleDupliWeight *dw = part->instance_weights.first; dw; dw = dw->next) { + LISTBASE_FOREACH (ParticleDupliWeight *, dw, &part->instance_weights) { /* update indices, but only if dw->ob is set (can be NULL after loading e.g.) */ if (dw->ob != NULL) { dw->index = 0; @@ -1440,7 +1492,7 @@ static void write_particlesettings(WriteData *wd, ParticleSettings *part) if (part->boids && part->phystype == PART_PHYS_BOIDS) { writestruct(wd, DATA, BoidSettings, 1, part->boids); - for (BoidState *state = part->boids->states.first; state; state = state->next) { + LISTBASE_FOREACH (BoidState *, state, &part->boids->states) { write_boid_state(wd, state); } } @@ -1625,14 +1677,14 @@ static void write_pose(WriteData *wd, bPose *pose) static void write_defgroups(WriteData *wd, ListBase *defbase) { - for (bDeformGroup *defgroup = defbase->first; defgroup; defgroup = defgroup->next) { + LISTBASE_FOREACH (bDeformGroup *, defgroup, defbase) { writestruct(wd, DATA, bDeformGroup, 1, defgroup); } } static void write_fmaps(WriteData *wd, ListBase *fbase) { - for (bFaceMap *fmap = fbase->first; fmap; fmap = fmap->next) { + LISTBASE_FOREACH (bFaceMap *, fmap, fbase) { writestruct(wd, DATA, bFaceMap, 1, fmap); } } @@ -1646,7 +1698,7 @@ static void write_modifiers(WriteData *wd, ListBase *modbase) } for (md = modbase->first; md; md = md->next) { - const ModifierTypeInfo *mti = modifierType_getInfo(md->type); + const ModifierTypeInfo *mti = BKE_modifier_get_info(md->type); if (mti == NULL) { return; } @@ -1829,7 +1881,7 @@ static void write_gpencil_modifiers(WriteData *wd, ListBase *modbase) } for (md = modbase->first; md; md = md->next) { - const GpencilModifierTypeInfo *mti = BKE_gpencil_modifierType_getInfo(md->type); + const GpencilModifierTypeInfo *mti = BKE_gpencil_modifier_get_info(md->type); if (mti == NULL) { return; } @@ -1896,7 +1948,7 @@ static void write_shaderfxs(WriteData *wd, ListBase *fxbase) } for (fx = fxbase->first; fx; fx = fx->next) { - const ShaderFxTypeInfo *fxi = BKE_shaderfxType_getInfo(fx->type); + const ShaderFxTypeInfo *fxi = BKE_shaderfx_get_info(fx->type); if (fxi == NULL) { return; } @@ -1905,11 +1957,14 @@ static void write_shaderfxs(WriteData *wd, ListBase *fxbase) } } -static void write_object(WriteData *wd, Object *ob) +static void write_object(WriteData *wd, Object *ob, const void *id_address) { if (ob->id.us > 0 || wd->use_memfile) { + /* Clean up, important in undo case to reduce false detection of changed datablocks. */ + BKE_object_runtime_reset(ob); + /* write LibData */ - writestruct(wd, ID_OB, Object, 1, ob); + writestruct_at_address(wd, ID_OB, Object, 1, id_address, ob); write_iddata(wd, &ob->id); if (ob->adt) { @@ -1970,11 +2025,15 @@ static void write_object(WriteData *wd, Object *ob) } } -static void write_vfont(WriteData *wd, VFont *vf) +static void write_vfont(WriteData *wd, VFont *vf, const void *id_address) { if (vf->id.us > 0 || wd->use_memfile) { + /* Clean up, important in undo case to reduce false detection of changed datablocks. */ + vf->data = NULL; + vf->temp_pf = NULL; + /* write LibData */ - writestruct(wd, ID_VF, VFont, 1, vf); + writestruct_at_address(wd, ID_VF, VFont, 1, id_address, vf); write_iddata(wd, &vf->id); /* direct data */ @@ -1986,11 +2045,11 @@ static void write_vfont(WriteData *wd, VFont *vf) } } -static void write_key(WriteData *wd, Key *key) +static void write_key(WriteData *wd, Key *key, const void *id_address) { if (key->id.us > 0 || wd->use_memfile) { /* write LibData */ - writestruct(wd, ID_KE, Key, 1, key); + writestruct_at_address(wd, ID_KE, Key, 1, id_address, key); write_iddata(wd, &key->id); if (key->adt) { @@ -1998,7 +2057,7 @@ static void write_key(WriteData *wd, Key *key) } /* direct data */ - for (KeyBlock *kb = key->block.first; kb; kb = kb->next) { + LISTBASE_FOREACH (KeyBlock *, kb, &key->block) { writestruct(wd, DATA, KeyBlock, 1, kb); if (kb->data) { writedata(wd, DATA, kb->totelem * key->elemsize, kb->data); @@ -2007,28 +2066,36 @@ static void write_key(WriteData *wd, Key *key) } } -static void write_camera(WriteData *wd, Camera *cam) +static void write_camera(WriteData *wd, Camera *cam, const void *id_address) { if (cam->id.us > 0 || wd->use_memfile) { /* write LibData */ - writestruct(wd, ID_CA, Camera, 1, cam); + writestruct_at_address(wd, ID_CA, Camera, 1, id_address, cam); write_iddata(wd, &cam->id); if (cam->adt) { write_animdata(wd, cam->adt); } - for (CameraBGImage *bgpic = cam->bg_images.first; bgpic; bgpic = bgpic->next) { + LISTBASE_FOREACH (CameraBGImage *, bgpic, &cam->bg_images) { writestruct(wd, DATA, CameraBGImage, 1, bgpic); } } } -static void write_mball(WriteData *wd, MetaBall *mb) +static void write_mball(WriteData *wd, MetaBall *mb, const void *id_address) { if (mb->id.us > 0 || wd->use_memfile) { + /* Clean up, important in undo case to reduce false detection of changed datablocks. */ + BLI_listbase_clear(&mb->disp); + mb->editelems = NULL; + /* Must always be cleared (meta's don't have their own edit-data). */ + mb->needs_flush_to_id = 0; + mb->lastelem = NULL; + mb->batch_cache = NULL; + /* write LibData */ - writestruct(wd, ID_MB, MetaBall, 1, mb); + writestruct_at_address(wd, ID_MB, MetaBall, 1, id_address, mb); write_iddata(wd, &mb->id); /* direct data */ @@ -2037,17 +2104,22 @@ static void write_mball(WriteData *wd, MetaBall *mb) write_animdata(wd, mb->adt); } - for (MetaElem *ml = mb->elems.first; ml; ml = ml->next) { + LISTBASE_FOREACH (MetaElem *, ml, &mb->elems) { writestruct(wd, DATA, MetaElem, 1, ml); } } } -static void write_curve(WriteData *wd, Curve *cu) +static void write_curve(WriteData *wd, Curve *cu, const void *id_address) { if (cu->id.us > 0 || wd->use_memfile) { + /* Clean up, important in undo case to reduce false detection of changed datablocks. */ + cu->editnurb = NULL; + cu->editfont = NULL; + cu->batch_cache = NULL; + /* write LibData */ - writestruct(wd, ID_CU, Curve, 1, cu); + writestruct_at_address(wd, ID_CU, Curve, 1, id_address, cu); write_iddata(wd, &cu->id); /* direct data */ @@ -2063,10 +2135,10 @@ static void write_curve(WriteData *wd, Curve *cu) } else { /* is also the order of reading */ - for (Nurb *nu = cu->nurb.first; nu; nu = nu->next) { + LISTBASE_FOREACH (Nurb *, nu, &cu->nurb) { writestruct(wd, DATA, Nurb, 1, nu); } - for (Nurb *nu = cu->nurb.first; nu; nu = nu->next) { + LISTBASE_FOREACH (Nurb *, nu, &cu->nurb) { if (nu->type == CU_BEZIER) { writestruct(wd, DATA, BezTriple, nu->pntsu, nu->bezt); } @@ -2186,7 +2258,7 @@ static void write_customdata(WriteData *wd, datasize = structnum * count; writestruct_id(wd, DATA, structname, datasize, layer->data); } - else { + else if (!wd->use_memfile) { /* Do not warn on undo. */ printf("%s error: layer '%s':%d - can't be written to file\n", __func__, structname, @@ -2200,19 +2272,14 @@ static void write_customdata(WriteData *wd, } } -static void write_mesh(WriteData *wd, Mesh *mesh) +static void write_mesh(WriteData *wd, Mesh *mesh, const void *id_address) { if (mesh->id.us > 0 || wd->use_memfile) { - /* Write a copy of the mesh with possibly reduced number of data layers. - * Don't edit the original since other threads might be reading it. */ - Mesh *old_mesh = mesh; - Mesh copy_mesh = *mesh; - mesh = ©_mesh; - /* cache only - don't write */ mesh->mface = NULL; mesh->totface = 0; memset(&mesh->fdata, 0, sizeof(mesh->fdata)); + memset(&mesh->runtime, 0, sizeof(mesh->runtime)); /* Reduce xdata layers, fill xlayers with layers to be written. * This makes xdata invalid for Blender, which is why we made a @@ -2229,7 +2296,7 @@ static void write_mesh(WriteData *wd, Mesh *mesh) CustomData_file_write_prepare(&mesh->ldata, &llayers, llayers_buff, ARRAY_SIZE(llayers_buff)); CustomData_file_write_prepare(&mesh->pdata, &players, players_buff, ARRAY_SIZE(players_buff)); - writestruct_at_address(wd, ID_ME, Mesh, 1, old_mesh, mesh); + writestruct_at_address(wd, ID_ME, Mesh, 1, id_address, mesh); write_iddata(wd, &mesh->id); /* direct data */ @@ -2247,9 +2314,6 @@ static void write_mesh(WriteData *wd, Mesh *mesh) write_customdata(wd, &mesh->id, mesh->totloop, &mesh->ldata, llayers, CD_MASK_MESH.lmask); write_customdata(wd, &mesh->id, mesh->totpoly, &mesh->pdata, players, CD_MASK_MESH.pmask); - /* restore pointer */ - mesh = old_mesh; - /* free temporary data */ if (vlayers && vlayers != vlayers_buff) { MEM_freeN(vlayers); @@ -2269,11 +2333,15 @@ static void write_mesh(WriteData *wd, Mesh *mesh) } } -static void write_lattice(WriteData *wd, Lattice *lt) +static void write_lattice(WriteData *wd, Lattice *lt, const void *id_address) { if (lt->id.us > 0 || wd->use_memfile) { + /* Clean up, important in undo case to reduce false detection of changed datablocks. */ + lt->editlatt = NULL; + lt->batch_cache = NULL; + /* write LibData */ - writestruct(wd, ID_LT, Lattice, 1, lt); + writestruct_at_address(wd, ID_LT, Lattice, 1, id_address, lt); write_iddata(wd, <->id); /* write animdata */ @@ -2288,7 +2356,7 @@ static void write_lattice(WriteData *wd, Lattice *lt) } } -static void write_image(WriteData *wd, Image *ima) +static void write_image(WriteData *wd, Image *ima, const void *id_address) { if (ima->id.us > 0 || wd->use_memfile) { ImagePackedFile *imapf; @@ -2301,7 +2369,7 @@ static void write_image(WriteData *wd, Image *ima) } /* write LibData */ - writestruct(wd, ID_IM, Image, 1, ima); + writestruct_at_address(wd, ID_IM, Image, 1, id_address, ima); write_iddata(wd, &ima->id); for (imapf = ima->packedfiles.first; imapf; imapf = imapf->next) { @@ -2315,7 +2383,7 @@ static void write_image(WriteData *wd, Image *ima) write_previews(wd, ima->preview); - for (ImageView *iv = ima->views.first; iv; iv = iv->next) { + LISTBASE_FOREACH (ImageView *, iv, &ima->views) { writestruct(wd, DATA, ImageView, 1, iv); } writestruct(wd, DATA, Stereo3dFormat, 1, ima->stereo3d_format); @@ -2328,11 +2396,11 @@ static void write_image(WriteData *wd, Image *ima) } } -static void write_texture(WriteData *wd, Tex *tex) +static void write_texture(WriteData *wd, Tex *tex, const void *id_address) { if (tex->id.us > 0 || wd->use_memfile) { /* write LibData */ - writestruct(wd, ID_TE, Tex, 1, tex); + writestruct_at_address(wd, ID_TE, Tex, 1, id_address, tex); write_iddata(wd, &tex->id); if (tex->adt) { @@ -2354,11 +2422,15 @@ static void write_texture(WriteData *wd, Tex *tex) } } -static void write_material(WriteData *wd, Material *ma) +static void write_material(WriteData *wd, Material *ma, const void *id_address) { if (ma->id.us > 0 || wd->use_memfile) { + /* Clean up, important in undo case to reduce false detection of changed datablocks. */ + ma->texpaintslot = NULL; + BLI_listbase_clear(&ma->gpumaterial); + /* write LibData */ - writestruct(wd, ID_MA, Material, 1, ma); + writestruct_at_address(wd, ID_MA, Material, 1, id_address, ma); write_iddata(wd, &ma->id); if (ma->adt) { @@ -2380,11 +2452,14 @@ static void write_material(WriteData *wd, Material *ma) } } -static void write_world(WriteData *wd, World *wrld) +static void write_world(WriteData *wd, World *wrld, const void *id_address) { if (wrld->id.us > 0 || wd->use_memfile) { + /* Clean up, important in undo case to reduce false detection of changed datablocks. */ + BLI_listbase_clear(&wrld->gpumaterial); + /* write LibData */ - writestruct(wd, ID_WO, World, 1, wrld); + writestruct_at_address(wd, ID_WO, World, 1, id_address, wrld); write_iddata(wd, &wrld->id); if (wrld->adt) { @@ -2401,11 +2476,11 @@ static void write_world(WriteData *wd, World *wrld) } } -static void write_light(WriteData *wd, Light *la) +static void write_light(WriteData *wd, Light *la, const void *id_address) { if (la->id.us > 0 || wd->use_memfile) { /* write LibData */ - writestruct(wd, ID_LA, Light, 1, la); + writestruct_at_address(wd, ID_LA, Light, 1, id_address, la); write_iddata(wd, &la->id); if (la->adt) { @@ -2431,25 +2506,26 @@ static void write_collection_nolib(WriteData *wd, Collection *collection) /* Shared function for collection data-blocks and scene master collection. */ write_previews(wd, collection->preview); - for (CollectionObject *cob = collection->gobject.first; cob; cob = cob->next) { + LISTBASE_FOREACH (CollectionObject *, cob, &collection->gobject) { writestruct(wd, DATA, CollectionObject, 1, cob); } - for (CollectionChild *child = collection->children.first; child; child = child->next) { + LISTBASE_FOREACH (CollectionChild *, child, &collection->children) { writestruct(wd, DATA, CollectionChild, 1, child); } - - /* Clear the accumulated recalc flags in case of undo step saving. */ - if (wd->use_memfile) { - collection->id.recalc_undo_accumulated = 0; - } } -static void write_collection(WriteData *wd, Collection *collection) +static void write_collection(WriteData *wd, Collection *collection, const void *id_address) { if (collection->id.us > 0 || wd->use_memfile) { + /* Clean up, important in undo case to reduce false detection of changed datablocks. */ + collection->flag &= ~COLLECTION_HAS_OBJECT_CACHE; + collection->tag = 0; + BLI_listbase_clear(&collection->object_cache); + BLI_listbase_clear(&collection->parents); + /* write LibData */ - writestruct(wd, ID_GR, Collection, 1, collection); + writestruct_at_address(wd, ID_GR, Collection, 1, id_address, collection); write_iddata(wd, &collection->id); write_collection_nolib(wd, collection); @@ -2507,7 +2583,7 @@ static void write_paint(WriteData *wd, Paint *p) static void write_layer_collections(WriteData *wd, ListBase *lb) { - for (LayerCollection *lc = lb->first; lc; lc = lc->next) { + LISTBASE_FOREACH (LayerCollection *, lc, lb) { writestruct(wd, DATA, LayerCollection, 1, lc); write_layer_collections(wd, &lc->layer_collections); @@ -2523,12 +2599,11 @@ static void write_view_layer(WriteData *wd, ViewLayer *view_layer) IDP_WriteProperty(view_layer->id_properties, wd); } - for (FreestyleModuleConfig *fmc = view_layer->freestyle_config.modules.first; fmc; - fmc = fmc->next) { + LISTBASE_FOREACH (FreestyleModuleConfig *, fmc, &view_layer->freestyle_config.modules) { writestruct(wd, DATA, FreestyleModuleConfig, 1, fmc); } - for (FreestyleLineSet *fls = view_layer->freestyle_config.linesets.first; fls; fls = fls->next) { + LISTBASE_FOREACH (FreestyleLineSet *, fls, &view_layer->freestyle_config.linesets) { writestruct(wd, DATA, FreestyleLineSet, 1, fls); } write_layer_collections(wd, &view_layer->layer_collections); @@ -2564,10 +2639,16 @@ static void write_lightcache(WriteData *wd, LightCache *cache) writestruct(wd, DATA, LightProbeCache, cache->cube_len, cache->cube_data); } -static void write_scene(WriteData *wd, Scene *sce) +static void write_scene(WriteData *wd, Scene *sce, const void *id_address) { + if (wd->use_memfile) { + /* Clean up, important in undo case to reduce false detection of changed datablocks. */ + /* XXX This UI data should not be stored in Scene at all... */ + memset(&sce->cursor, 0, sizeof(sce->cursor)); + } + /* write LibData */ - writestruct(wd, ID_SCE, Scene, 1, sce); + writestruct_at_address(wd, ID_SCE, Scene, 1, id_address, sce); write_iddata(wd, &sce->id); if (sce->adt) { @@ -2714,7 +2795,7 @@ static void write_scene(WriteData *wd, Scene *sce) SEQ_END; /* new; meta stack too, even when its nasty restore code */ - for (MetaStack *ms = ed->metastack.first; ms; ms = ms->next) { + LISTBASE_FOREACH (MetaStack *, ms, &ed->metastack) { writestruct(wd, DATA, MetaStack, 1, ms); } } @@ -2733,17 +2814,17 @@ static void write_scene(WriteData *wd, Scene *sce) } /* writing dynamic list of TimeMarkers to the blend file */ - for (TimeMarker *marker = sce->markers.first; marker; marker = marker->next) { + LISTBASE_FOREACH (TimeMarker *, marker, &sce->markers) { writestruct(wd, DATA, TimeMarker, 1, marker); } /* writing dynamic list of TransformOrientations to the blend file */ - for (TransformOrientation *ts = sce->transform_spaces.first; ts; ts = ts->next) { + LISTBASE_FOREACH (TransformOrientation *, ts, &sce->transform_spaces) { writestruct(wd, DATA, TransformOrientation, 1, ts); } /* writing MultiView to the blend file */ - for (SceneRenderView *srv = sce->r.views.first; srv; srv = srv->next) { + LISTBASE_FOREACH (SceneRenderView *, srv, &sce->r.views) { writestruct(wd, DATA, SceneRenderView, 1, srv); } @@ -2769,7 +2850,7 @@ static void write_scene(WriteData *wd, Scene *sce) write_previews(wd, sce->preview); write_curvemapping_curves(wd, &sce->r.mblur_shutter_curve); - for (ViewLayer *view_layer = sce->view_layers.first; view_layer; view_layer = view_layer->next) { + LISTBASE_FOREACH (ViewLayer *, view_layer, &sce->view_layers) { write_view_layer(wd, view_layer); } @@ -2790,11 +2871,19 @@ static void write_scene(WriteData *wd, Scene *sce) BLI_assert(sce->layer_properties == NULL); } -static void write_gpencil(WriteData *wd, bGPdata *gpd) +static void write_gpencil(WriteData *wd, bGPdata *gpd, const void *id_address) { if (gpd->id.us > 0 || wd->use_memfile) { + /* Clean up, important in undo case to reduce false detection of changed data-blocks. */ + /* XXX not sure why the whole run-time data is not cleared in reading code, + * for now mimicking it here. */ + gpd->runtime.sbuffer = NULL; + gpd->runtime.sbuffer_used = 0; + gpd->runtime.sbuffer_size = 0; + gpd->runtime.tot_cp_points = 0; + /* write gpd data block to file */ - writestruct(wd, ID_GD, bGPdata, 1, gpd); + writestruct_at_address(wd, ID_GD, bGPdata, 1, id_address, gpd); write_iddata(wd, &gpd->id); if (gpd->adt) { @@ -2914,35 +3003,33 @@ static void write_soops(WriteData *wd, SpaceOutliner *so) static void write_panel_list(WriteData *wd, ListBase *lb) { - for (Panel *pa = lb->first; pa; pa = pa->next) { - writestruct(wd, DATA, Panel, 1, pa); - write_panel_list(wd, &pa->children); + LISTBASE_FOREACH (Panel *, panel, lb) { + writestruct(wd, DATA, Panel, 1, panel); + write_panel_list(wd, &panel->children); } } static void write_area_regions(WriteData *wd, ScrArea *area) { - for (ARegion *region = area->regionbase.first; region; region = region->next) { + LISTBASE_FOREACH (ARegion *, region, &area->regionbase) { write_region(wd, region, area->spacetype); write_panel_list(wd, ®ion->panels); - for (PanelCategoryStack *pc_act = region->panels_category_active.first; pc_act; - pc_act = pc_act->next) { + LISTBASE_FOREACH (PanelCategoryStack *, pc_act, ®ion->panels_category_active) { writestruct(wd, DATA, PanelCategoryStack, 1, pc_act); } - for (uiList *ui_list = region->ui_lists.first; ui_list; ui_list = ui_list->next) { + LISTBASE_FOREACH (uiList *, ui_list, ®ion->ui_lists) { write_uilist(wd, ui_list); } - for (uiPreview *ui_preview = region->ui_previews.first; ui_preview; - ui_preview = ui_preview->next) { + LISTBASE_FOREACH (uiPreview *, ui_preview, ®ion->ui_previews) { writestruct(wd, DATA, uiPreview, 1, ui_preview); } } - for (SpaceLink *sl = area->spacedata.first; sl; sl = sl->next) { - for (ARegion *region = sl->regionbase.first; region; region = region->next) { + LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) { + LISTBASE_FOREACH (ARegion *, region, &sl->regionbase) { write_region(wd, region, sl->spacetype); } @@ -3055,7 +3142,7 @@ static void write_area_map(WriteData *wd, ScrAreaMap *area_map) { writelist(wd, DATA, ScrVert, &area_map->vertbase); writelist(wd, DATA, ScrEdge, &area_map->edgebase); - for (ScrArea *area = area_map->areabase.first; area; area = area->next) { + LISTBASE_FOREACH (ScrArea *, area, &area_map->areabase) { area->butspacetype = area->spacetype; /* Just for compatibility, will be reset below. */ writestruct(wd, DATA, ScrArea, 1, area); @@ -3070,13 +3157,13 @@ static void write_area_map(WriteData *wd, ScrAreaMap *area_map) } } -static void write_windowmanager(WriteData *wd, wmWindowManager *wm) +static void write_windowmanager(BlendWriter *writer, wmWindowManager *wm, const void *id_address) { - writestruct(wd, ID_WM, wmWindowManager, 1, wm); - write_iddata(wd, &wm->id); - write_wm_xr_data(wd, &wm->xr); + BLO_write_id_struct(writer, wmWindowManager, id_address, &wm->id); + write_iddata(writer->wd, &wm->id); + write_wm_xr_data(writer->wd, &wm->xr); - for (wmWindow *win = wm->windows.first; win; win = win->next) { + LISTBASE_FOREACH (wmWindow *, win, &wm->windows) { #ifndef WITH_GLOBAL_AREA_WRITING /* Don't write global areas yet, while we make changes to them. */ ScrAreaMap global_areas = win->global_areas; @@ -3086,12 +3173,12 @@ static void write_windowmanager(WriteData *wd, wmWindowManager *wm) /* update deprecated screen member (for so loading in 2.7x uses the correct screen) */ win->screen = BKE_workspace_active_screen_get(win->workspace_hook); - writestruct(wd, DATA, wmWindow, 1, win); - writestruct(wd, DATA, WorkSpaceInstanceHook, 1, win->workspace_hook); - writestruct(wd, DATA, Stereo3dFormat, 1, win->stereo3d_format); + BLO_write_struct(writer, wmWindow, win); + BLO_write_struct(writer, WorkSpaceInstanceHook, win->workspace_hook); + BLO_write_struct(writer, Stereo3dFormat, win->stereo3d_format); #ifdef WITH_GLOBAL_AREA_WRITING - write_area_map(wd, &win->global_areas); + write_area_map(writer->wd, &win->global_areas); #else win->global_areas = global_areas; #endif @@ -3101,19 +3188,19 @@ static void write_windowmanager(WriteData *wd, wmWindowManager *wm) } } -static void write_screen(WriteData *wd, bScreen *sc) +static void write_screen(WriteData *wd, bScreen *screen, const void *id_address) { /* Screens are reference counted, only saved if used by a workspace. */ - if (sc->id.us > 0 || wd->use_memfile) { + if (screen->id.us > 0 || wd->use_memfile) { /* write LibData */ /* in 2.50+ files, the file identifier for screens is patched, forward compatibility */ - writestruct(wd, ID_SCRN, bScreen, 1, sc); - write_iddata(wd, &sc->id); + writestruct_at_address(wd, ID_SCRN, bScreen, 1, id_address, screen); + write_iddata(wd, &screen->id); - write_previews(wd, sc->preview); + write_previews(wd, screen->preview); /* direct data */ - write_area_map(wd, AREAMAP_FROM_SCREEN(sc)); + write_area_map(wd, AREAMAP_FROM_SCREEN(screen)); } } @@ -3132,15 +3219,22 @@ static void write_bone(WriteData *wd, Bone *bone) } /* Write Children */ - for (Bone *cbone = bone->childbase.first; cbone; cbone = cbone->next) { + LISTBASE_FOREACH (Bone *, cbone, &bone->childbase) { write_bone(wd, cbone); } } -static void write_armature(WriteData *wd, bArmature *arm) +static void write_armature(WriteData *wd, bArmature *arm, const void *id_address) { if (arm->id.us > 0 || wd->use_memfile) { - writestruct(wd, ID_AR, bArmature, 1, arm); + /* Clean up, important in undo case to reduce false detection of changed datablocks. */ + arm->bonehash = NULL; + arm->edbo = NULL; + /* Must always be cleared (armatures don't have their own edit-data). */ + arm->needs_flush_to_id = 0; + arm->act_edbone = NULL; + + writestruct_at_address(wd, ID_AR, bArmature, 1, id_address, arm); write_iddata(wd, &arm->id); if (arm->adt) { @@ -3148,20 +3242,24 @@ static void write_armature(WriteData *wd, bArmature *arm) } /* Direct data */ - for (Bone *bone = arm->bonebase.first; bone; bone = bone->next) { + LISTBASE_FOREACH (Bone *, bone, &arm->bonebase) { write_bone(wd, bone); } } } -static void write_text(WriteData *wd, Text *text) +static void write_text(WriteData *wd, Text *text, const void *id_address) { + /* Note: we are clearing local temp data here, *not* the flag in the actual 'real' ID. */ if ((text->flags & TXT_ISMEM) && (text->flags & TXT_ISEXT)) { text->flags &= ~TXT_ISEXT; } + /* Clean up, important in undo case to reduce false detection of changed datablocks. */ + text->compiled = NULL; + /* write LibData */ - writestruct(wd, ID_TXT, Text, 1, text); + writestruct_at_address(wd, ID_TXT, Text, 1, id_address, text); write_iddata(wd, &text->id); if (text->name) { @@ -3170,21 +3268,21 @@ static void write_text(WriteData *wd, Text *text) if (!(text->flags & TXT_ISEXT)) { /* now write the text data, in two steps for optimization in the readfunction */ - for (TextLine *tmp = text->lines.first; tmp; tmp = tmp->next) { + LISTBASE_FOREACH (TextLine *, tmp, &text->lines) { writestruct(wd, DATA, TextLine, 1, tmp); } - for (TextLine *tmp = text->lines.first; tmp; tmp = tmp->next) { + LISTBASE_FOREACH (TextLine *, tmp, &text->lines) { writedata(wd, DATA, tmp->len + 1, tmp->line); } } } -static void write_speaker(WriteData *wd, Speaker *spk) +static void write_speaker(WriteData *wd, Speaker *spk, const void *id_address) { if (spk->id.us > 0 || wd->use_memfile) { /* write LibData */ - writestruct(wd, ID_SPK, Speaker, 1, spk); + writestruct_at_address(wd, ID_SPK, Speaker, 1, id_address, spk); write_iddata(wd, &spk->id); if (spk->adt) { @@ -3193,11 +3291,17 @@ static void write_speaker(WriteData *wd, Speaker *spk) } } -static void write_sound(WriteData *wd, bSound *sound) +static void write_sound(WriteData *wd, bSound *sound, const void *id_address) { if (sound->id.us > 0 || wd->use_memfile) { + /* Clean up, important in undo case to reduce false detection of changed datablocks. */ + sound->tags = 0; + sound->handle = NULL; + sound->playback_handle = NULL; + sound->spinlock = NULL; + /* write LibData */ - writestruct(wd, ID_SO, bSound, 1, sound); + writestruct_at_address(wd, ID_SO, bSound, 1, id_address, sound); write_iddata(wd, &sound->id); if (sound->packedfile) { @@ -3208,11 +3312,11 @@ static void write_sound(WriteData *wd, bSound *sound) } } -static void write_probe(WriteData *wd, LightProbe *prb) +static void write_probe(WriteData *wd, LightProbe *prb, const void *id_address) { if (prb->id.us > 0 || wd->use_memfile) { /* write LibData */ - writestruct(wd, ID_LP, LightProbe, 1, prb); + writestruct_at_address(wd, ID_LP, LightProbe, 1, id_address, prb); write_iddata(wd, &prb->id); if (prb->adt) { @@ -3221,10 +3325,18 @@ static void write_probe(WriteData *wd, LightProbe *prb) } } -static void write_nodetree(WriteData *wd, bNodeTree *ntree) +static void write_nodetree(WriteData *wd, bNodeTree *ntree, const void *id_address) { if (ntree->id.us > 0 || wd->use_memfile) { - writestruct(wd, ID_NT, bNodeTree, 1, ntree); + /* Clean up, important in undo case to reduce false detection of changed datablocks. */ + ntree->init = 0; /* to set callbacks and force setting types */ + ntree->is_updating = false; + ntree->typeinfo = NULL; + ntree->interface_type = NULL; + ntree->progress = NULL; + ntree->execdata = NULL; + + writestruct_at_address(wd, ID_NT, bNodeTree, 1, id_address, ntree); /* Note that trees directly used by other IDs (materials etc.) are not 'real' ID, they cannot * be linked, etc., so we write actual id data here only, for 'real' ID trees. */ write_iddata(wd, &ntree->id); @@ -3233,10 +3345,10 @@ static void write_nodetree(WriteData *wd, bNodeTree *ntree) } } -static void write_brush(WriteData *wd, Brush *brush) +static void write_brush(WriteData *wd, Brush *brush, const void *id_address) { if (brush->id.us > 0 || wd->use_memfile) { - writestruct(wd, ID_BR, Brush, 1, brush); + writestruct_at_address(wd, ID_BR, Brush, 1, id_address, brush); write_iddata(wd, &brush->id); if (brush->curve) { @@ -3255,6 +3367,24 @@ static void write_brush(WriteData *wd, Brush *brush) if (brush->gpencil_settings->curve_jitter) { write_curvemapping(wd, brush->gpencil_settings->curve_jitter); } + if (brush->gpencil_settings->curve_rand_pressure) { + write_curvemapping(wd, brush->gpencil_settings->curve_rand_pressure); + } + if (brush->gpencil_settings->curve_rand_strength) { + write_curvemapping(wd, brush->gpencil_settings->curve_rand_strength); + } + if (brush->gpencil_settings->curve_rand_uv) { + write_curvemapping(wd, brush->gpencil_settings->curve_rand_uv); + } + if (brush->gpencil_settings->curve_rand_hue) { + write_curvemapping(wd, brush->gpencil_settings->curve_rand_hue); + } + if (brush->gpencil_settings->curve_rand_saturation) { + write_curvemapping(wd, brush->gpencil_settings->curve_rand_saturation); + } + if (brush->gpencil_settings->curve_rand_value) { + write_curvemapping(wd, brush->gpencil_settings->curve_rand_value); + } } if (brush->gradient) { writestruct(wd, DATA, ColorBand, 1, brush->gradient); @@ -3262,11 +3392,11 @@ static void write_brush(WriteData *wd, Brush *brush) } } -static void write_palette(WriteData *wd, Palette *palette) +static void write_palette(WriteData *wd, Palette *palette, const void *id_address) { if (palette->id.us > 0 || wd->use_memfile) { PaletteColor *color; - writestruct(wd, ID_PAL, Palette, 1, palette); + writestruct_at_address(wd, ID_PAL, Palette, 1, id_address, palette); write_iddata(wd, &palette->id); for (color = palette->colors.first; color; color = color->next) { @@ -3275,10 +3405,10 @@ static void write_palette(WriteData *wd, Palette *palette) } } -static void write_paintcurve(WriteData *wd, PaintCurve *pc) +static void write_paintcurve(WriteData *wd, PaintCurve *pc, const void *id_address) { if (pc->id.us > 0 || wd->use_memfile) { - writestruct(wd, ID_PC, PaintCurve, 1, pc); + writestruct_at_address(wd, ID_PC, PaintCurve, 1, id_address, pc); write_iddata(wd, &pc->id); writestruct(wd, DATA, PaintCurvePoint, pc->tot_points, pc->points); @@ -3324,13 +3454,18 @@ static void write_movieReconstruction(WriteData *wd, MovieTrackingReconstruction } } -static void write_movieclip(WriteData *wd, MovieClip *clip) +static void write_movieclip(WriteData *wd, MovieClip *clip, const void *id_address) { if (clip->id.us > 0 || wd->use_memfile) { + /* Clean up, important in undo case to reduce false detection of changed datablocks. */ + clip->anim = NULL; + clip->tracking_context = NULL; + clip->tracking.stats = NULL; + MovieTracking *tracking = &clip->tracking; MovieTrackingObject *object; - writestruct(wd, ID_MC, MovieClip, 1, clip); + writestruct_at_address(wd, ID_MC, MovieClip, 1, id_address, clip); write_iddata(wd, &clip->id); if (clip->adt) { @@ -3354,12 +3489,12 @@ static void write_movieclip(WriteData *wd, MovieClip *clip) } } -static void write_mask(WriteData *wd, Mask *mask) +static void write_mask(WriteData *wd, Mask *mask, const void *id_address) { if (mask->id.us > 0 || wd->use_memfile) { MaskLayer *masklay; - writestruct(wd, ID_MSK, Mask, 1, mask); + writestruct_at_address(wd, ID_MSK, Mask, 1, id_address, mask); write_iddata(wd, &mask->id); if (mask->adt) { @@ -3661,10 +3796,10 @@ static void write_linestyle_geometry_modifiers(WriteData *wd, ListBase *modifier } } -static void write_linestyle(WriteData *wd, FreestyleLineStyle *linestyle) +static void write_linestyle(WriteData *wd, FreestyleLineStyle *linestyle, const void *id_address) { if (linestyle->id.us > 0 || wd->use_memfile) { - writestruct(wd, ID_LS, FreestyleLineStyle, 1, linestyle); + writestruct_at_address(wd, ID_LS, FreestyleLineStyle, 1, id_address, linestyle); write_iddata(wd, &linestyle->id); if (linestyle->adt) { @@ -3687,10 +3822,16 @@ static void write_linestyle(WriteData *wd, FreestyleLineStyle *linestyle) } } -static void write_cachefile(WriteData *wd, CacheFile *cache_file) +static void write_cachefile(WriteData *wd, CacheFile *cache_file, const void *id_address) { if (cache_file->id.us > 0 || wd->use_memfile) { - writestruct(wd, ID_CF, CacheFile, 1, cache_file); + /* Clean up, important in undo case to reduce false detection of changed datablocks. */ + BLI_listbase_clear(&cache_file->object_paths); + cache_file->handle = NULL; + memset(cache_file->handle_filepath, 0, sizeof(cache_file->handle_filepath)); + cache_file->handle_readers = NULL; + + writestruct_at_address(wd, ID_CF, CacheFile, 1, id_address, cache_file); if (cache_file->adt) { write_animdata(wd, cache_file->adt); @@ -3698,39 +3839,31 @@ static void write_cachefile(WriteData *wd, CacheFile *cache_file) } } -static void write_workspace(WriteData *wd, WorkSpace *workspace) +static void write_workspace(BlendWriter *writer, WorkSpace *workspace, const void *id_address) { - ListBase *layouts = BKE_workspace_layouts_get(workspace); - - writestruct(wd, ID_WS, WorkSpace, 1, workspace); - write_iddata(wd, &workspace->id); - writelist(wd, DATA, WorkSpaceLayout, layouts); - writelist(wd, DATA, WorkSpaceDataRelation, &workspace->hook_layout_relations); - writelist(wd, DATA, wmOwnerID, &workspace->owner_ids); - writelist(wd, DATA, bToolRef, &workspace->tools); - for (bToolRef *tref = workspace->tools.first; tref; tref = tref->next) { + BLO_write_id_struct(writer, WorkSpace, id_address, &workspace->id); + write_iddata(writer->wd, &workspace->id); + BLO_write_struct_list(writer, WorkSpaceLayout, &workspace->layouts); + BLO_write_struct_list(writer, WorkSpaceDataRelation, &workspace->hook_layout_relations); + BLO_write_struct_list(writer, wmOwnerID, &workspace->owner_ids); + BLO_write_struct_list(writer, bToolRef, &workspace->tools); + LISTBASE_FOREACH (bToolRef *, tref, &workspace->tools) { if (tref->properties) { - IDP_WriteProperty(tref->properties, wd); + IDP_WriteProperty_new_api(tref->properties, writer); } } } -static void write_hair(WriteData *wd, Hair *hair) +static void write_hair(WriteData *wd, Hair *hair, const void *id_address) { if (hair->id.us > 0 || wd->use_memfile) { - /* Write a copy of the hair with possibly reduced number of data layers. - * Don't edit the original since other threads might be reading it. */ - Hair *old_hair = hair; - Hair copy_hair = *hair; - hair = ©_hair; - CustomDataLayer *players = NULL, players_buff[CD_TEMP_CHUNK_SIZE]; CustomDataLayer *clayers = NULL, clayers_buff[CD_TEMP_CHUNK_SIZE]; CustomData_file_write_prepare(&hair->pdata, &players, players_buff, ARRAY_SIZE(players_buff)); CustomData_file_write_prepare(&hair->cdata, &clayers, clayers_buff, ARRAY_SIZE(clayers_buff)); /* Write LibData */ - writestruct_at_address(wd, ID_HA, Hair, 1, old_hair, hair); + writestruct_at_address(wd, ID_HA, Hair, 1, id_address, hair); write_iddata(wd, &hair->id); /* Direct data */ @@ -3748,27 +3881,18 @@ static void write_hair(WriteData *wd, Hair *hair) if (clayers && clayers != clayers_buff) { MEM_freeN(clayers); } - - /* restore pointer */ - hair = old_hair; } } -static void write_pointcloud(WriteData *wd, PointCloud *pointcloud) +static void write_pointcloud(WriteData *wd, PointCloud *pointcloud, const void *id_address) { if (pointcloud->id.us > 0 || wd->use_memfile) { - /* Write a copy of the pointcloud with possibly reduced number of data layers. - * Don't edit the original since other threads might be reading it. */ - PointCloud *old_pointcloud = pointcloud; - PointCloud copy_pointcloud = *pointcloud; - pointcloud = ©_pointcloud; - CustomDataLayer *players = NULL, players_buff[CD_TEMP_CHUNK_SIZE]; CustomData_file_write_prepare( &pointcloud->pdata, &players, players_buff, ARRAY_SIZE(players_buff)); /* Write LibData */ - writestruct_at_address(wd, ID_PT, PointCloud, 1, old_pointcloud, pointcloud); + writestruct_at_address(wd, ID_PT, PointCloud, 1, id_address, pointcloud); write_iddata(wd, &pointcloud->id); /* Direct data */ @@ -3786,11 +3910,14 @@ static void write_pointcloud(WriteData *wd, PointCloud *pointcloud) } } -static void write_volume(WriteData *wd, Volume *volume) +static void write_volume(WriteData *wd, Volume *volume, const void *id_address) { if (volume->id.us > 0 || wd->use_memfile) { + /* Clean up, important in undo case to reduce false detection of changed datablocks. */ + volume->runtime.grids = 0; + /* write LibData */ - writestruct(wd, ID_VO, Volume, 1, volume); + writestruct_at_address(wd, ID_VO, Volume, 1, id_address, volume); write_iddata(wd, &volume->id); /* direct data */ @@ -3807,6 +3934,24 @@ static void write_volume(WriteData *wd, Volume *volume) } } +static void write_simulation(WriteData *wd, Simulation *simulation) +{ + if (simulation->id.us > 0 || wd->use_memfile) { + writestruct(wd, ID_SIM, Simulation, 1, simulation); + write_iddata(wd, &simulation->id); + + if (simulation->adt) { + write_animdata(wd, simulation->adt); + } + + /* nodetree is integral part of simulation, no libdata */ + if (simulation->nodetree) { + writestruct(wd, DATA, bNodeTree, 1, simulation->nodetree); + write_nodetree_nolib(wd, simulation->nodetree); + } + } +} + /* Keep it last of write_foodata functions. */ static void write_libraries(WriteData *wd, Main *main) { @@ -3822,6 +3967,11 @@ static void write_libraries(WriteData *wd, Main *main) if (main->curlib && main->curlib->packedfile) { found_one = true; } + else if (wd->use_memfile) { + /* When writing undo step we always write all existing libraries, makes reading undo step + * much easier when dealing with purely indirectly used libraries. */ + found_one = true; + } else { found_one = false; while (!found_one && tot--) { @@ -3909,12 +4059,12 @@ static void write_global(WriteData *wd, int fileflags, Main *mainvar) fg.globalf = G.f; BLI_strncpy(fg.filename, mainvar->name, sizeof(fg.filename)); - sprintf(subvstr, "%4d", BLENDER_SUBVERSION); + sprintf(subvstr, "%4d", BLENDER_FILE_SUBVERSION); memcpy(fg.subvstr, subvstr, 4); - fg.subversion = BLENDER_SUBVERSION; - fg.minversion = BLENDER_MINVERSION; - fg.minsubversion = BLENDER_MINSUBVERSION; + fg.subversion = BLENDER_FILE_SUBVERSION; + fg.minversion = BLENDER_FILE_MIN_VERSION; + fg.minsubversion = BLENDER_FILE_MIN_SUBVERSION; #ifdef WITH_BUILDINFO { extern unsigned long build_commit_timestamp; @@ -3968,7 +4118,7 @@ static bool write_file_handle(Main *mainvar, "BLENDER%c%c%.3d", (sizeof(void *) == 8) ? '-' : '_', (ENDIAN_ORDER == B_ENDIAN) ? 'V' : 'v', - BLENDER_VERSION); + BLENDER_FILE_VERSION); mywrite(wd, buf, 12); @@ -3983,6 +4133,7 @@ static bool write_file_handle(Main *mainvar, OverrideLibraryStorage *override_storage = wd->use_memfile ? NULL : BKE_lib_override_library_operations_store_initialize(); +#define ID_BUFFER_STATIC_SIZE 8192 /* This outer loop allows to save first data-blocks from real mainvar, * then the temp ones from override process, * if needed, without duplicating whole code. */ @@ -3993,10 +4144,18 @@ static bool write_file_handle(Main *mainvar, while (a--) { ID *id = lbarray[a]->first; - if (id && GS(id->name) == ID_LI) { + if (id == NULL || GS(id->name) == ID_LI) { continue; /* Libraries are handled separately below. */ } + char id_buffer_static[ID_BUFFER_STATIC_SIZE]; + void *id_buffer = id_buffer_static; + const size_t idtype_struct_size = BKE_idtype_get_info_from_id(id)->struct_size; + if (idtype_struct_size > ID_BUFFER_STATIC_SIZE) { + BLI_assert(0); + id_buffer = MEM_mallocN(idtype_struct_size, __func__); + } + for (; id; id = id->next) { /* We should never attempt to write non-regular IDs * (i.e. all kind of temp/runtime ones). */ @@ -4009,117 +4168,155 @@ static bool write_file_handle(Main *mainvar, BKE_lib_override_library_operations_store_start(bmain, override_storage, id); } + if (wd->use_memfile) { + /* Record the changes that happened up to this undo push in + * recalc_up_to_undo_push, and clear recalc_after_undo_push again + * to start accumulating for the next undo push. */ + id->recalc_up_to_undo_push = id->recalc_after_undo_push; + id->recalc_after_undo_push = 0; + + bNodeTree *nodetree = ntreeFromID(id); + if (nodetree != NULL) { + nodetree->id.recalc_up_to_undo_push = nodetree->id.recalc_after_undo_push; + nodetree->id.recalc_after_undo_push = 0; + } + if (GS(id->name) == ID_SCE) { + Scene *scene = (Scene *)id; + if (scene->master_collection != NULL) { + scene->master_collection->id.recalc_up_to_undo_push = + scene->master_collection->id.recalc_after_undo_push; + scene->master_collection->id.recalc_after_undo_push = 0; + } + } + } + + mywrite_id_begin(wd, id); + + memcpy(id_buffer, id, idtype_struct_size); + + ((ID *)id_buffer)->tag = 0; + /* Those listbase data change every time we add/remove an ID, and also often when renaming + * one (due to re-sorting). This avoids generating a lot of false 'is changed' detections + * between undo steps. */ + ((ID *)id_buffer)->prev = NULL; + ((ID *)id_buffer)->next = NULL; + + BlendWriter writer = {wd}; + switch ((ID_Type)GS(id->name)) { case ID_WM: - write_windowmanager(wd, (wmWindowManager *)id); + write_windowmanager(&writer, (wmWindowManager *)id_buffer, id); break; case ID_WS: - write_workspace(wd, (WorkSpace *)id); + write_workspace(&writer, (WorkSpace *)id_buffer, id); break; case ID_SCR: - write_screen(wd, (bScreen *)id); + write_screen(wd, (bScreen *)id_buffer, id); break; case ID_MC: - write_movieclip(wd, (MovieClip *)id); + write_movieclip(wd, (MovieClip *)id_buffer, id); break; case ID_MSK: - write_mask(wd, (Mask *)id); + write_mask(wd, (Mask *)id_buffer, id); break; case ID_SCE: - write_scene(wd, (Scene *)id); + write_scene(wd, (Scene *)id_buffer, id); break; case ID_CU: - write_curve(wd, (Curve *)id); + write_curve(wd, (Curve *)id_buffer, id); break; case ID_MB: - write_mball(wd, (MetaBall *)id); + write_mball(wd, (MetaBall *)id_buffer, id); break; case ID_IM: - write_image(wd, (Image *)id); + write_image(wd, (Image *)id_buffer, id); break; case ID_CA: - write_camera(wd, (Camera *)id); + write_camera(wd, (Camera *)id_buffer, id); break; case ID_LA: - write_light(wd, (Light *)id); + write_light(wd, (Light *)id_buffer, id); break; case ID_LT: - write_lattice(wd, (Lattice *)id); + write_lattice(wd, (Lattice *)id_buffer, id); break; case ID_VF: - write_vfont(wd, (VFont *)id); + write_vfont(wd, (VFont *)id_buffer, id); break; case ID_KE: - write_key(wd, (Key *)id); + write_key(wd, (Key *)id_buffer, id); break; case ID_WO: - write_world(wd, (World *)id); + write_world(wd, (World *)id_buffer, id); break; case ID_TXT: - write_text(wd, (Text *)id); + write_text(wd, (Text *)id_buffer, id); break; case ID_SPK: - write_speaker(wd, (Speaker *)id); + write_speaker(wd, (Speaker *)id_buffer, id); break; case ID_LP: - write_probe(wd, (LightProbe *)id); + write_probe(wd, (LightProbe *)id_buffer, id); break; case ID_SO: - write_sound(wd, (bSound *)id); + write_sound(wd, (bSound *)id_buffer, id); break; case ID_GR: - write_collection(wd, (Collection *)id); + write_collection(wd, (Collection *)id_buffer, id); break; case ID_AR: - write_armature(wd, (bArmature *)id); + write_armature(wd, (bArmature *)id_buffer, id); break; case ID_AC: - write_action(wd, (bAction *)id); + write_action(wd, (bAction *)id_buffer, id); break; case ID_OB: - write_object(wd, (Object *)id); + write_object(wd, (Object *)id_buffer, id); break; case ID_MA: - write_material(wd, (Material *)id); + write_material(wd, (Material *)id_buffer, id); break; case ID_TE: - write_texture(wd, (Tex *)id); + write_texture(wd, (Tex *)id_buffer, id); break; case ID_ME: - write_mesh(wd, (Mesh *)id); + write_mesh(wd, (Mesh *)id_buffer, id); break; case ID_PA: - write_particlesettings(wd, (ParticleSettings *)id); + write_particlesettings(wd, (ParticleSettings *)id_buffer, id); break; case ID_NT: - write_nodetree(wd, (bNodeTree *)id); + write_nodetree(wd, (bNodeTree *)id_buffer, id); break; case ID_BR: - write_brush(wd, (Brush *)id); + write_brush(wd, (Brush *)id_buffer, id); break; case ID_PAL: - write_palette(wd, (Palette *)id); + write_palette(wd, (Palette *)id_buffer, id); break; case ID_PC: - write_paintcurve(wd, (PaintCurve *)id); + write_paintcurve(wd, (PaintCurve *)id_buffer, id); break; case ID_GD: - write_gpencil(wd, (bGPdata *)id); + write_gpencil(wd, (bGPdata *)id_buffer, id); break; case ID_LS: - write_linestyle(wd, (FreestyleLineStyle *)id); + write_linestyle(wd, (FreestyleLineStyle *)id_buffer, id); break; case ID_CF: - write_cachefile(wd, (CacheFile *)id); + write_cachefile(wd, (CacheFile *)id_buffer, id); break; case ID_HA: - write_hair(wd, (Hair *)id); + write_hair(wd, (Hair *)id_buffer, id); break; case ID_PT: - write_pointcloud(wd, (PointCloud *)id); + write_pointcloud(wd, (PointCloud *)id_buffer, id); break; case ID_VO: - write_volume(wd, (Volume *)id); + write_volume(wd, (Volume *)id_buffer, id); + break; + case ID_SIM: + write_simulation(wd, (Simulation *)id); break; case ID_LI: /* Do nothing, handled below - and should never be reached. */ @@ -4138,11 +4335,11 @@ static bool write_file_handle(Main *mainvar, BKE_lib_override_library_operations_store_end(override_storage, id); } - if (wd->use_memfile) { - /* Very important to do it after every ID write now, otherwise we cannot know whether a - * specific ID changed or not. */ - mywrite_flush(wd); - } + mywrite_id_end(wd, id); + } + + if (id_buffer != id_buffer_static) { + MEM_SAFE_FREE(id_buffer); } mywrite_flush(wd); @@ -4277,8 +4474,8 @@ bool BLO_write_file(Main *mainvar, BLI_split_dir_part(filepath, dir_dst, sizeof(dir_dst)); /* Just in case there is some subtle difference. */ - BLI_cleanup_path(mainvar->name, dir_dst); - BLI_cleanup_path(mainvar->name, dir_src); + BLI_path_normalize(mainvar->name, dir_dst); + BLI_path_normalize(mainvar->name, dir_src); if (G.relbase_valid && (BLI_path_cmp(dir_dst, dir_src) == 0)) { /* Saved to same path. Nothing to do. */ @@ -4353,4 +4550,98 @@ bool BLO_write_file_mem(Main *mainvar, MemFile *compare, MemFile *current, int w return (err == 0); } +void BLO_write_raw(BlendWriter *writer, int size_in_bytes, const void *data_ptr) +{ + writedata(writer->wd, DATA, size_in_bytes, data_ptr); +} + +void BLO_write_struct_by_name(BlendWriter *writer, const char *struct_name, const void *data_ptr) +{ + int struct_id = BLO_get_struct_id_by_name(writer, struct_name); + BLO_write_struct_by_id(writer, struct_id, data_ptr); +} + +void BLO_write_struct_array_by_name(BlendWriter *writer, + const char *struct_name, + int array_size, + const void *data_ptr) +{ + int struct_id = BLO_get_struct_id_by_name(writer, struct_name); + BLO_write_struct_array_by_id(writer, struct_id, array_size, data_ptr); +} + +void BLO_write_struct_by_id(BlendWriter *writer, int struct_id, const void *data_ptr) +{ + writestruct_nr(writer->wd, DATA, struct_id, 1, data_ptr); +} + +void BLO_write_struct_array_by_id(BlendWriter *writer, + int struct_id, + int array_size, + const void *data_ptr) +{ + writestruct_nr(writer->wd, DATA, struct_id, array_size, data_ptr); +} + +void BLO_write_struct_list_by_id(BlendWriter *writer, int struct_id, ListBase *list) +{ + writelist_nr(writer->wd, DATA, struct_id, list); +} + +void BLO_write_struct_list_by_name(BlendWriter *writer, const char *struct_name, ListBase *list) +{ + BLO_write_struct_list_by_id(writer, BLO_get_struct_id_by_name(writer, struct_name), list); +} + +void blo_write_id_struct(BlendWriter *writer, int struct_id, const void *id_address, const ID *id) +{ + writestruct_at_address_nr(writer->wd, GS(id->name), struct_id, 1, id_address, id); +} + +int BLO_get_struct_id_by_name(BlendWriter *writer, const char *struct_name) +{ + int struct_id = DNA_struct_find_nr(writer->wd->sdna, struct_name); + BLI_assert(struct_id >= 0); + return struct_id; +} + +void BLO_write_int32_array(BlendWriter *writer, int size, const int32_t *data_ptr) +{ + BLO_write_raw(writer, sizeof(int32_t) * size, data_ptr); +} + +void BLO_write_uint32_array(BlendWriter *writer, int size, const uint32_t *data_ptr) +{ + BLO_write_raw(writer, sizeof(uint32_t) * size, data_ptr); +} + +void BLO_write_float_array(BlendWriter *writer, int size, const float *data_ptr) +{ + BLO_write_raw(writer, sizeof(float) * size, data_ptr); +} + +void BLO_write_float3_array(BlendWriter *writer, int size, const float *data_ptr) +{ + BLO_write_raw(writer, sizeof(float) * 3 * size, data_ptr); +} + +/** + * Write a null terminated string. + */ +void BLO_write_string(BlendWriter *writer, const char *str) +{ + if (str != NULL) { + BLO_write_raw(writer, strlen(str) + 1, str); + } +} + +/** + * Sometimes different data is written depending on whether the file is saved to disk or used for + * undo. This function returns true when the current file-writing is done for undo. + */ +bool BLO_write_is_undo(BlendWriter *writer) +{ + return writer->wd->use_memfile; +} + /** \} */ |