diff options
Diffstat (limited to 'source/blender/blenloader')
-rw-r--r-- | source/blender/blenloader/BLO_readfile.h | 24 | ||||
-rw-r--r-- | source/blender/blenloader/CMakeLists.txt | 6 | ||||
-rw-r--r-- | source/blender/blenloader/intern/readfile.c | 809 | ||||
-rw-r--r-- | source/blender/blenloader/intern/readfile.h | 4 | ||||
-rw-r--r-- | source/blender/blenloader/intern/versioning_250.c | 4 | ||||
-rw-r--r-- | source/blender/blenloader/intern/versioning_270.c | 21 | ||||
-rw-r--r-- | source/blender/blenloader/intern/versioning_280.c | 533 | ||||
-rw-r--r-- | source/blender/blenloader/intern/versioning_defaults.c | 45 | ||||
-rw-r--r-- | source/blender/blenloader/intern/versioning_legacy.c | 88 | ||||
-rw-r--r-- | source/blender/blenloader/intern/writefile.c | 155 |
10 files changed, 1263 insertions, 426 deletions
diff --git a/source/blender/blenloader/BLO_readfile.h b/source/blender/blenloader/BLO_readfile.h index 59bd7ed74f4..b639236e022 100644 --- a/source/blender/blenloader/BLO_readfile.h +++ b/source/blender/blenloader/BLO_readfile.h @@ -39,15 +39,18 @@ extern "C" { struct BlendThumbnail; struct bScreen; struct LinkNode; +struct ListBase; struct Main; struct MemFile; struct ReportList; struct Scene; +struct SceneLayer; struct UserDef; struct View3D; struct bContext; struct BHead; struct FileData; +struct wmWindowManager; typedef struct BlendHandle BlendHandle; @@ -64,13 +67,20 @@ typedef struct BlendFileData { int fileflags; int globalf; char filename[1024]; /* 1024 = FILE_MAX */ - - struct bScreen *curscreen; + + struct bScreen *curscreen; /* TODO think this isn't needed anymore? */ struct Scene *curscene; - + struct SceneLayer *cur_render_layer; /* layer to activate in workspaces when reading without UI */ + eBlenFileType type; } BlendFileData; +typedef struct WorkspaceConfigFileData { + struct Main *main; /* has to be freed when done reading file data */ + + struct ListBase workspaces; +} WorkspaceConfigFileData; + /* skip reading some data-block types (may want to skip screen data too). */ typedef enum eBLOReadSkip { @@ -114,9 +124,9 @@ struct ID *BLO_library_link_named_part(struct Main *mainl, BlendHandle **bh, con struct ID *BLO_library_link_named_part_ex( struct Main *mainl, BlendHandle **bh, const short idcode, const char *name, const short flag, - struct Scene *scene, struct View3D *v3d, + struct Scene *scene, struct SceneLayer *sl, const bool use_placeholders, const bool force_indirect); -void BLO_library_link_end(struct Main *mainl, BlendHandle **bh, short flag, struct Scene *scene, struct View3D *v3d); +void BLO_library_link_end(struct Main *mainl, BlendHandle **bh, short flag, struct Scene *scene, struct SceneLayer *sl); void BLO_library_link_copypaste(struct Main *mainl, BlendHandle *bh); @@ -125,7 +135,9 @@ void *BLO_library_read_struct(struct FileData *fd, struct BHead *bh, const char BlendFileData *blo_read_blendafterruntime(int file, const char *name, int actualsize, struct ReportList *reports); /* internal function but we need to expose it */ -void blo_lib_link_screen_restore(struct Main *newmain, struct bScreen *curscreen, struct Scene *curscene); +void blo_lib_link_restore( + struct Main *newmain, struct wmWindowManager *curwm, + struct Scene *curscene, struct SceneLayer *cur_render_layer); typedef void (*BLOExpandDoitCallback) (void *fdhandle, struct Main *mainvar, void *idv); diff --git a/source/blender/blenloader/CMakeLists.txt b/source/blender/blenloader/CMakeLists.txt index 3d2e8a306de..61d1aa18b3c 100644 --- a/source/blender/blenloader/CMakeLists.txt +++ b/source/blender/blenloader/CMakeLists.txt @@ -29,6 +29,7 @@ set(INC ../blenkernel ../blenlib ../blentranslation + ../depsgraph ../imbuf ../makesdna ../makesrna @@ -53,6 +54,7 @@ set(SRC intern/versioning_250.c intern/versioning_260.c intern/versioning_270.c + intern/versioning_280.c intern/versioning_defaults.c intern/versioning_legacy.c intern/writefile.c @@ -79,6 +81,10 @@ if(WITH_INTERNATIONAL) add_definitions(-DWITH_INTERNATIONAL) endif() +if(WITH_CLAY_ENGINE) + add_definitions(-DWITH_CLAY_ENGINE) +endif() + if(WITH_CODEC_FFMPEG) add_definitions(-DWITH_FFMPEG) endif() diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 646cf978453..ccf2dc1f4c4 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -53,6 +53,10 @@ /* allow readfile to use deprecated functionality */ #define DNA_DEPRECATED_ALLOW +/* Allow using DNA struct members that are marked as private for read/write. + * Note: Each header that uses this needs to define its own way of handling + * it. There's no generic implementation, direct use does nothing. */ +#define DNA_PRIVATE_READ_WRITE_ALLOW #include "DNA_anim_types.h" #include "DNA_armature_types.h" @@ -72,6 +76,7 @@ #include "DNA_ipo_types.h" #include "DNA_key_types.h" #include "DNA_lattice_types.h" +#include "DNA_layer_types.h" #include "DNA_lamp_types.h" #include "DNA_linestyle_types.h" #include "DNA_meta_types.h" @@ -84,6 +89,7 @@ #include "DNA_object_types.h" #include "DNA_packedFile_types.h" #include "DNA_particle_types.h" +#include "DNA_lightprobe_types.h" #include "DNA_property_types.h" #include "DNA_rigidbody_types.h" #include "DNA_text_types.h" @@ -98,10 +104,13 @@ #include "DNA_sound_types.h" #include "DNA_space_types.h" #include "DNA_vfont_types.h" +#include "DNA_workspace_types.h" #include "DNA_world_types.h" #include "DNA_movieclip_types.h" #include "DNA_mask_types.h" +#include "RNA_access.h" + #include "MEM_guardedalloc.h" #include "BLI_endian_switch.h" @@ -120,11 +129,11 @@ #include "BKE_constraint.h" #include "BKE_context.h" #include "BKE_curve.h" -#include "BKE_depsgraph.h" #include "BKE_effect.h" #include "BKE_fcurve.h" #include "BKE_global.h" // for G #include "BKE_group.h" +#include "BKE_layer.h" #include "BKE_library.h" // for which_libbase #include "BKE_library_idmap.h" #include "BKE_library_query.h" @@ -148,6 +157,9 @@ #include "BKE_outliner_treehash.h" #include "BKE_sound.h" #include "BKE_colortools.h" +#include "BKE_workspace.h" + +#include "DEG_depsgraph.h" #include "NOD_common.h" #include "NOD_socket.h" @@ -238,9 +250,9 @@ typedef struct OldNewMap { /* local prototypes */ static void *read_struct(FileData *fd, BHead *bh, const char *blockname); static void direct_link_modifiers(FileData *fd, ListBase *lb); -static void convert_tface_mt(FileData *fd, Main *main); static BHead *find_bhead_from_code_name(FileData *fd, const short idcode, const char *name); static BHead *find_bhead_from_idname(FileData *fd, const char *idname); +static SceneCollection *get_scene_collection_active_or_create(struct Scene *scene, struct SceneLayer *sl, const short flag); /* this function ensures that reports are printed, * in the case of libraray linking errors this is important! @@ -2210,6 +2222,7 @@ static void direct_link_id(FileData *fd, ID *id) /* 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; } /* ************ READ CurveMapping *************** */ @@ -2773,6 +2786,80 @@ static void direct_link_cachefile(FileData *fd, CacheFile *cache_file) direct_link_animdata(fd, cache_file->adt); } +/* ************ READ WORKSPACES *************** */ + +static void lib_link_workspaces(FileData *fd, Main *bmain) +{ + for (WorkSpace *workspace = bmain->workspaces.first; workspace; workspace = workspace->id.next) { + ListBase *layouts = BKE_workspace_layouts_get(workspace); + ID *id = (ID *)workspace; + + if ((id->tag & LIB_TAG_NEED_LINK) == 0) { + continue; + } + IDP_LibLinkProperty(id->properties, fd); + id_us_ensure_real(id); + + for (WorkSpaceLayout *layout = layouts->first, *layout_next; layout; layout = layout_next) { + bScreen *screen = newlibadr(fd, id->lib, BKE_workspace_layout_screen_get(layout)); + + layout_next = layout->next; + if (screen) { + BKE_workspace_layout_screen_set(layout, screen); + + if (ID_IS_LINKED_DATABLOCK(id)) { + screen->winid = 0; + if (screen->temp) { + /* delete temp layouts when appending */ + BKE_workspace_layout_remove(bmain, workspace, layout); + } + } + } + } + + id->tag &= ~LIB_TAG_NEED_LINK; + } +} + +static void direct_link_workspace(FileData *fd, WorkSpace *workspace, const Main *main) +{ + link_list(fd, BKE_workspace_layouts_get(workspace)); + link_list(fd, &workspace->hook_layout_relations); + link_list(fd, BKE_workspace_transform_orientations_get(workspace)); + + for (WorkSpaceDataRelation *relation = workspace->hook_layout_relations.first; + relation; + relation = relation->next) + { + relation->parent = newglobadr(fd, relation->parent); /* data from window - need to access through global oldnew-map */ + relation->value = newdataadr(fd, relation->value); + } + + if (ID_IS_LINKED_DATABLOCK(&workspace->id)) { + /* Appending workspace so render layer is likely from a different scene. Unset + * now, when activating workspace later we set a valid one from current scene. */ + BKE_workspace_render_layer_set(workspace, NULL); + } + + /* 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); + } + } + } +} + +static void lib_link_workspace_instance_hook(FileData *fd, WorkSpaceInstanceHook *hook, ID *id) +{ + WorkSpace *workspace = BKE_workspace_active_get(hook); + BKE_workspace_active_set(hook, newlibadr(fd, id->lib, workspace)); +} + + /* ************ READ MOTION PATHS *************** */ /* direct data for cache */ @@ -3340,7 +3427,7 @@ static void lib_link_pose(FileData *fd, Main *bmain, Object *ob, bPose *pose) if (rebuild) { - DAG_id_tag_update_ex(bmain, &ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME); + DEG_id_tag_update_ex(bmain, &ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME); BKE_pose_tag_recalc(bmain, pose); } } @@ -3418,6 +3505,11 @@ static void lib_link_camera(FileData *fd, Main *main) ca->dof_ob = newlibadr(fd, ca->id.lib, ca->dof_ob); + for (CameraBGImage *bgpic = ca->bg_images.first; bgpic; bgpic = bgpic->next) { + bgpic->ima = newlibadr_us(fd, ca->id.lib, bgpic->ima); + bgpic->clip = newlibadr_us(fd, ca->id.lib, bgpic->clip); + } + ca->id.tag &= ~LIB_TAG_NEED_LINK; } } @@ -3427,6 +3519,12 @@ static void direct_link_camera(FileData *fd, Camera *ca) { ca->adt = newdataadr(fd, ca->adt); direct_link_animdata(fd, ca->adt); + + link_list(fd, &ca->bg_images); + + for (CameraBGImage *bgpic = ca->bg_images.first; bgpic; bgpic = bgpic->next) { + bgpic->iuser.ok = 1; + } } @@ -3863,6 +3961,7 @@ static void direct_link_curve(FileData *fd, Curve *cu) cu->editnurb = NULL; cu->editfont = NULL; + cu->batch_cache = NULL; for (nu = cu->nurb.first; nu; nu = nu->next) { nu->bezt = newdataadr(fd, nu->bezt); @@ -4369,55 +4468,14 @@ static void direct_link_particlesystems(FileData *fd, ListBase *particles) psys->tree = NULL; psys->bvhtree = NULL; + + psys->batch_cache = NULL; } return; } /* ************ READ MESH ***************** */ -static void lib_link_mtface(FileData *fd, Mesh *me, MTFace *mtface, int totface) -{ - MTFace *tf= mtface; - int i; - - /* Add pseudo-references (not fake users!) to images used by texface. A - * little bogus; it would be better if each mesh consistently added one ref - * to each image it used. - z0r */ - for (i = 0; i < totface; i++, tf++) { - tf->tpage = newlibadr_real_us(fd, me->id.lib, tf->tpage); - } -} - -static void lib_link_customdata_mtface(FileData *fd, Mesh *me, CustomData *fdata, int totface) -{ - int i; - for (i = 0; i < fdata->totlayer; i++) { - CustomDataLayer *layer = &fdata->layers[i]; - - if (layer->type == CD_MTFACE) - lib_link_mtface(fd, me, layer->data, totface); - } - -} - -static void lib_link_customdata_mtpoly(FileData *fd, Mesh *me, CustomData *pdata, int totface) -{ - int i; - - for (i=0; i < pdata->totlayer; i++) { - CustomDataLayer *layer = &pdata->layers[i]; - - if (layer->type == CD_MTEXPOLY) { - MTexPoly *tf= layer->data; - int j; - - for (j = 0; j < totface; j++, tf++) { - tf->tpage = newlibadr_real_us(fd, me->id.lib, tf->tpage); - } - } - } -} - static void lib_link_mesh(FileData *fd, Main *main) { Mesh *me; @@ -4444,19 +4502,9 @@ static void lib_link_mesh(FileData *fd, Main *main) me->ipo = newlibadr_us(fd, me->id.lib, me->ipo); // XXX: deprecated: old anim sys me->key = newlibadr_us(fd, me->id.lib, me->key); me->texcomesh = newlibadr_us(fd, me->id.lib, me->texcomesh); - - lib_link_customdata_mtface(fd, me, &me->fdata, me->totface); - lib_link_customdata_mtpoly(fd, me, &me->pdata, me->totpoly); - if (me->mr && me->mr->levels.first) { - lib_link_customdata_mtface(fd, me, &me->mr->fdata, - ((MultiresLevel*)me->mr->levels.first)->totface); - } } } - /* convert texface options to material */ - convert_tface_mt(fd, main); - for (me = main->mesh.first; me; me = me->id.next) { if (me->id.tag & LIB_TAG_NEED_LINK) { /*check if we need to convert mfaces to mpolys*/ @@ -4612,7 +4660,6 @@ static void direct_link_mesh(FileData *fd, Mesh *mesh) mesh->dvert = newdataadr(fd, mesh->dvert); mesh->mloopcol = newdataadr(fd, mesh->mloopcol); mesh->mloopuv = newdataadr(fd, mesh->mloopuv); - mesh->mtpoly = newdataadr(fd, mesh->mtpoly); mesh->mselect = newdataadr(fd, mesh->mselect); /* animdata */ @@ -4631,18 +4678,13 @@ static void direct_link_mesh(FileData *fd, Mesh *mesh) mesh->bb = NULL; mesh->edit_btmesh = NULL; + mesh->batch_cache = NULL; /* happens with old files */ if (mesh->mselect == NULL) { mesh->totselect = 0; } - if (mesh->mloopuv || mesh->mtpoly) { - /* for now we have to ensure texpoly and mloopuv layers are aligned - * in the future we may allow non-aligned layers */ - BKE_mesh_cd_validate(mesh); - } - /* Multires data */ mesh->mr= newdataadr(fd, mesh->mr); if (mesh->mr) { @@ -4722,6 +4764,7 @@ static void direct_link_latt(FileData *fd, Lattice *lt) direct_link_dverts(fd, lt->pntsu*lt->pntsv*lt->pntsw, lt->dvert); lt->editlatt = NULL; + lt->batch_cache = NULL; lt->adt = newdataadr(fd, lt->adt); direct_link_animdata(fd, lt->adt); @@ -4764,7 +4807,15 @@ static void lib_link_object(FileData *fd, Main *main) ob->parent = newlibadr(fd, ob->id.lib, ob->parent); ob->track = newlibadr(fd, ob->id.lib, ob->track); ob->poselib = newlibadr_us(fd, ob->id.lib, ob->poselib); - ob->dup_group = newlibadr_us(fd, ob->id.lib, ob->dup_group); + + /* 2.8x drops support for non-empty dupli instances. */ + if (ob->type == OB_EMPTY) { + ob->dup_group = newlibadr_us(fd, ob->id.lib, ob->dup_group); + } + else { + ob->dup_group = NULL; + ob->transflag &= ~OB_DUPLIGROUP; + } ob->proxy = newlibadr_us(fd, ob->id.lib, ob->proxy); if (ob->proxy) { @@ -5070,6 +5121,8 @@ static void direct_link_pose(FileData *fd, bPose *pose) /* in case this value changes in future, clamp else we get undefined behavior */ CLAMP(pchan->rotmode, ROT_MODE_MIN, ROT_MODE_MAX); + + pchan->draw_data = NULL; } pose->ikdata = NULL; if (pose->ikparam != NULL) { @@ -5444,6 +5497,7 @@ static void direct_link_object(FileData *fd, Object *ob) direct_link_motionpath(fd, ob->mpath); link_list(fd, &ob->defbase); + link_list(fd, &ob->fmaps); // XXX deprecated - old animation system <<< direct_link_nlastrips(fd, &ob->nlastrips); link_list(fd, &ob->constraintChannels); @@ -5630,6 +5684,7 @@ static void direct_link_object(FileData *fd, Object *ob) ob->derivedDeform = NULL; ob->derivedFinal = NULL; BLI_listbase_clear(&ob->gpulamp); + BLI_listbase_clear(&ob->drawdata); link_list(fd, &ob->pc_ids); /* Runtime curve data */ @@ -5646,6 +5701,8 @@ static void direct_link_object(FileData *fd, Object *ob) ob->currentlod = ob->lodlevels.first; ob->preview = direct_link_preview_image(fd, ob->preview); + + ob->base_collection_properties = NULL; } /* ************ READ SCENE ***************** */ @@ -5710,6 +5767,23 @@ static bool scene_validate_setscene__liblink(Scene *sce, const int totscene) } #endif +static void lib_link_scene_collection(FileData *fd, Library *lib, SceneCollection *sc) +{ + for (LinkData *link = sc->objects.first; link; link = link->next) { + link->data = newlibadr_us(fd, lib, link->data); + BLI_assert(link->data); + } + + for (LinkData *link = sc->filter_objects.first; link; link = link->next) { + link->data = newlibadr_us(fd, lib, link->data); + BLI_assert(link->data); + } + + for (SceneCollection *nsc = sc->scene_collections.first; nsc; nsc = nsc->next) { + lib_link_scene_collection(fd, lib, nsc); + } +} + static void lib_link_scene(FileData *fd, Main *main) { #ifdef USE_SETSCENE_CHECK @@ -5757,17 +5831,17 @@ static void lib_link_scene(FileData *fd, Main *main) sce->toolsettings->particle.shape_object = newlibadr(fd, sce->id.lib, sce->toolsettings->particle.shape_object); - for (Base *next, *base = sce->base.first; base; base = next) { - next = base->next; + for (BaseLegacy *base_legacy_next, *base_legacy = sce->base.first; base_legacy; base_legacy = base_legacy_next) { + base_legacy_next = base_legacy->next; - base->object = newlibadr_us(fd, sce->id.lib, base->object); + base_legacy->object = newlibadr_us(fd, sce->id.lib, base_legacy->object); - if (base->object == NULL) { + if (base_legacy->object == NULL) { blo_reportf_wrap(fd->reports, RPT_WARNING, TIP_("LIB: object lost from scene: '%s'"), sce->id.name + 2); - BLI_remlink(&sce->base, base); - if (base == sce->basact) sce->basact = NULL; - MEM_freeN(base); + BLI_remlink(&sce->base, base_legacy); + if (base_legacy == sce->basact) sce->basact = NULL; + MEM_freeN(base_legacy); } } @@ -5856,6 +5930,19 @@ static void lib_link_scene(FileData *fd, Main *main) /* Motion Tracking */ sce->clip = newlibadr_us(fd, sce->id.lib, sce->clip); + lib_link_scene_collection(fd, sce->id.lib, sce->collection); + + for (SceneLayer *sl = sce->render_layers.first; sl; sl = sl->next) { + /* tag scene layer to update for collection tree evaluation */ + sl->flag |= SCENE_LAYER_ENGINE_DIRTY; + for (Base *base = sl->object_bases.first; base; base = base->next) { + /* we only bump the use count for the collection objects */ + base->object = newlibadr(fd, sce->id.lib, base->object); + base->flag |= BASE_DIRTY_ENGINE_SETTINGS; + base->collection_properties = NULL; + } + } + #ifdef USE_SETSCENE_CHECK if (sce->set != NULL) { /* link flag for scenes with set would be reset later, @@ -5959,18 +6046,69 @@ static void direct_link_view_settings(FileData *fd, ColorManagedViewSettings *vi direct_link_curvemapping(fd, view_settings->curve_mapping); } -static void direct_link_scene(FileData *fd, Scene *sce) +static void direct_link_scene_collection(FileData *fd, SceneCollection *sc) +{ + link_list(fd, &sc->objects); + link_list(fd, &sc->filter_objects); + link_list(fd, &sc->scene_collections); + + for (SceneCollection *nsc = sc->scene_collections.first; nsc; nsc = nsc->next) { + direct_link_scene_collection(fd, nsc); + } +} + +static void direct_link_layer_collections(FileData *fd, ListBase *lb) +{ + link_list(fd, lb); + for (LayerCollection *lc = lb->first; lc; lc = lc->next) { + lc->scene_collection = newdataadr(fd, lc->scene_collection); + + link_list(fd, &lc->object_bases); + + for (LinkData *link = lc->object_bases.first; link; link = link->next) { + link->data = newdataadr(fd, link->data); + } + + link_list(fd, &lc->overrides); + + if (lc->properties) { + lc->properties = newdataadr(fd, lc->properties); + IDP_DirectLinkGroup_OrFree(&lc->properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd); + BKE_layer_collection_engine_settings_validate_collection(lc); + } + lc->properties_evaluated = NULL; + + direct_link_layer_collections(fd, &lc->layer_collections); + } +} + +/** + * Workspaces store a render layer pointer which can only be read after scene is read. + */ +static void direct_link_workspace_link_scene_data( + FileData *fd, const Scene *scene, const ListBase *workspaces) +{ + for (WorkSpace *workspace = workspaces->first; workspace; workspace = workspace->id.next) { + SceneLayer *layer = newdataadr(fd, BKE_workspace_render_layer_get(workspace)); + /* only set when layer is from the scene we read */ + if (layer && (BLI_findindex(&scene->render_layers, layer) != -1)) { + BKE_workspace_render_layer_set(workspace, layer); + } + } +} + +static void direct_link_scene(FileData *fd, Scene *sce, Main *bmain) { Editing *ed; Sequence *seq; MetaStack *ms; RigidBodyWorld *rbw; + SceneLayer *sl; SceneRenderLayer *srl; - sce->theDag = NULL; - sce->depsgraph = NULL; + sce->depsgraph_legacy = NULL; + sce->depsgraph_hash = NULL; sce->obedit = NULL; - sce->stats = NULL; sce->fps_info = NULL; sce->customdata_mask_modal = 0; sce->lay_updated = 0; @@ -6002,6 +6140,7 @@ static void direct_link_scene(FileData *fd, Scene *sce) sce->toolsettings->imapaint.paintcursor = NULL; sce->toolsettings->particle.paintcursor = NULL; sce->toolsettings->particle.scene = NULL; + sce->toolsettings->particle.scene_layer = NULL; sce->toolsettings->particle.object = NULL; sce->toolsettings->gp_sculpt.paintcursor = NULL; @@ -6159,7 +6298,7 @@ static void direct_link_scene(FileData *fd, Scene *sce) } link_list(fd, &(sce->markers)); - link_list(fd, &(sce->transform_spaces)); + link_list(fd, &(sce->transform_spaces)); /* only for old files */ link_list(fd, &(sce->r.layers)); link_list(fd, &(sce->r.views)); @@ -6209,6 +6348,43 @@ static void direct_link_scene(FileData *fd, Scene *sce) sce->preview = direct_link_preview_image(fd, sce->preview); direct_link_curvemapping(fd, &sce->r.mblur_shutter_curve); + + /* this runs before the very first doversion */ + if (sce->collection) { + sce->collection = newdataadr(fd, sce->collection); + direct_link_scene_collection(fd, sce->collection); + } + + /* insert into global old-new map for reading without UI (link_global accesses it again) */ + link_glob_list(fd, &sce->render_layers); + for (sl = sce->render_layers.first; sl; sl = sl->next) { + sl->stats = NULL; + link_list(fd, &sl->object_bases); + sl->basact = newdataadr(fd, sl->basact); + direct_link_layer_collections(fd, &sl->layer_collections); + + if (sl->properties != NULL) { + sl->properties = newdataadr(fd, sl->properties); + BLI_assert(sl->properties != NULL); + IDP_DirectLinkGroup_OrFree(&sl->properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd); + BKE_scene_layer_engine_settings_validate_layer(sl); + } + + sl->properties_evaluated = NULL; + + BLI_listbase_clear(&sl->drawdata); + } + + sce->collection_properties = newdataadr(fd, sce->collection_properties); + IDP_DirectLinkGroup_OrFree(&sce->collection_properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd); + + sce->layer_properties = newdataadr(fd, sce->layer_properties); + IDP_DirectLinkGroup_OrFree(&sce->layer_properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd); + + BKE_layer_collection_engine_settings_validate_scene(sce); + BKE_scene_layer_engine_settings_validate_scene(sce); + + direct_link_workspace_link_scene_data(fd, sce, &bmain->workspaces); } /* ************ READ WM ***************** */ @@ -6221,6 +6397,12 @@ static void direct_link_windowmanager(FileData *fd, wmWindowManager *wm) link_list(fd, &wm->windows); for (win = wm->windows.first; win; win = win->next) { + WorkSpaceInstanceHook *hook = win->workspace_hook; + + win->workspace_hook = newdataadr(fd, hook); + /* we need to restore a pointer to this later when reading workspaces, so store in global oldnew-map */ + oldnewmap_insert(fd->globmap, hook, win->workspace_hook, 0); + win->ghostwin = NULL; win->eventstate = NULL; win->curswin = NULL; @@ -6285,6 +6467,11 @@ static void lib_link_windowmanager(FileData *fd, Main *main) if (wm->id.tag & LIB_TAG_NEED_LINK) { /* Note: WM IDProperties are never written to file, hence no need to read/link them here. */ for (win = wm->windows.first; win; win = win->next) { + if (win->workspace_hook) { /* NULL for old files */ + lib_link_workspace_instance_hook(fd, win->workspace_hook, &wm->id); + } + win->scene = newlibadr(fd, wm->id.lib, win->scene); + /* deprecated, but needed for versioning (will be NULL'ed then) */ win->screen = newlibadr(fd, NULL, win->screen); } @@ -6370,13 +6557,9 @@ static void lib_link_screen(FileData *fd, Main *main) IDP_LibLinkProperty(sc->id.properties, fd); id_us_ensure_real(&sc->id); + /* deprecated, but needed for versioning (will be NULL'ed then) */ sc->scene = newlibadr(fd, sc->id.lib, sc->scene); - /* this should not happen, but apparently it does somehow. Until we figure out the cause, - * just assign first available scene */ - if (!sc->scene) - sc->scene = main->scene.first; - sc->animtimer = NULL; /* saved in rare cases */ sc->scrubbing = false; @@ -6388,22 +6571,10 @@ static void lib_link_screen(FileData *fd, Main *main) case SPACE_VIEW3D: { View3D *v3d = (View3D*) sl; - BGpic *bgpic = NULL; v3d->camera= newlibadr(fd, sc->id.lib, v3d->camera); v3d->ob_centre= newlibadr(fd, sc->id.lib, v3d->ob_centre); - /* should be do_versions but not easy adding into the listbase */ - if (v3d->bgpic) { - v3d->bgpic = newlibadr(fd, sc->id.lib, v3d->bgpic); - BLI_addtail(&v3d->bgpicbase, bgpic); - v3d->bgpic = NULL; - } - - for (bgpic = v3d->bgpicbase.first; bgpic; bgpic = bgpic->next) { - bgpic->ima = newlibadr_us(fd, sc->id.lib, bgpic->ima); - bgpic->clip = newlibadr_us(fd, sc->id.lib, bgpic->clip); - } if (v3d->localvd) { v3d->localvd->camera = newlibadr(fd, sc->id.lib, v3d->localvd->camera); } @@ -6684,88 +6855,60 @@ static void lib_link_clipboard_restore(struct IDNameLib_Map *id_map) BKE_sequencer_base_recursive_apply(&seqbase_clipboard, lib_link_seq_clipboard_cb, id_map); } -/* called from kernel/blender.c */ -/* used to link a file (without UI) to the current UI */ -/* note that it assumes the old pointers in UI are still valid, so old Main is not freed */ -void blo_lib_link_screen_restore(Main *newmain, bScreen *curscreen, Scene *curscene) +static void lib_link_workspace_scene_data_restore(wmWindow *win, Scene *scene) { - wmWindow *win; - wmWindowManager *wm; - bScreen *sc; - ScrArea *sa; + bScreen *screen = BKE_workspace_active_screen_get(win->workspace_hook); - struct IDNameLib_Map *id_map = BKE_main_idmap_create(newmain); + for (ScrArea *area = screen->areabase.first; area; area = area->next) { + for (SpaceLink *sl = area->spacedata.first; sl; sl = sl->next) { + if (sl->spacetype == SPACE_VIEW3D) { + View3D *v3d = (View3D *)sl; - /* first windowmanager */ - for (wm = newmain->wm.first; wm; wm = wm->id.next) { - for (win= wm->windows.first; win; win= win->next) { - win->screen = restore_pointer_by_name(id_map, (ID *)win->screen, USER_REAL); - - if (win->screen == NULL) - win->screen = curscreen; - - win->screen->winid = win->winid; + if (v3d->camera == NULL || v3d->scenelock) { + v3d->camera = scene->camera; + } + + if (v3d->localvd) { + /*Base *base;*/ + + v3d->localvd->camera = scene->camera; + + /* localview can become invalid during undo/redo steps, so we exit it when no could be found */ +#if 0 /* XXX regionlocalview ? */ + for (base= sc->scene->base.first; base; base= base->next) { + if (base->lay & v3d->lay) break; + } + if (base==NULL) { + v3d->lay= v3d->localvd->lay; + v3d->layact= v3d->localvd->layact; + MEM_freeN(v3d->localvd); + v3d->localvd= NULL; + } +#endif + } + else if (v3d->scenelock) { + v3d->lay = scene->lay; + } + } } } - - - for (sc = newmain->screen.first; sc; sc = sc->id.next) { - Scene *oldscene = sc->scene; - - sc->scene= restore_pointer_by_name(id_map, (ID *)sc->scene, USER_REAL); - if (sc->scene == NULL) - sc->scene = curscene; - - /* keep cursor location through undo */ - copy_v3_v3(sc->scene->cursor, oldscene->cursor); - - for (sa = sc->areabase.first; sa; sa = sa->next) { - SpaceLink *sl; - - for (sl = sa->spacedata.first; sl; sl = sl->next) { +} + +static void lib_link_workspace_layout_restore(struct IDNameLib_Map *id_map, Main *newmain, WorkSpaceLayout *layout) +{ + bScreen *screen = BKE_workspace_layout_screen_get(layout); + + /* 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) { if (sl->spacetype == SPACE_VIEW3D) { View3D *v3d = (View3D *)sl; - BGpic *bgpic; ARegion *ar; - if (v3d->scenelock) - v3d->camera = NULL; /* always get from scene */ - else - v3d->camera = restore_pointer_by_name(id_map, (ID *)v3d->camera, USER_REAL); - if (v3d->camera == NULL) - v3d->camera = sc->scene->camera; + v3d->camera = restore_pointer_by_name(id_map, (ID *)v3d->camera, USER_REAL); v3d->ob_centre = restore_pointer_by_name(id_map, (ID *)v3d->ob_centre, USER_REAL); - - for (bgpic= v3d->bgpicbase.first; bgpic; bgpic= bgpic->next) { - if ((bgpic->ima = restore_pointer_by_name(id_map, (ID *)bgpic->ima, USER_IGNORE))) { - id_us_plus((ID *)bgpic->ima); - } - if ((bgpic->clip = restore_pointer_by_name(id_map, (ID *)bgpic->clip, USER_IGNORE))) { - id_us_plus((ID *)bgpic->clip); - } - } - if (v3d->localvd) { - /*Base *base;*/ - - v3d->localvd->camera = sc->scene->camera; - - /* localview can become invalid during undo/redo steps, so we exit it when no could be found */ -#if 0 /* XXX regionlocalview ? */ - for (base= sc->scene->base.first; base; base= base->next) { - if (base->lay & v3d->lay) break; - } - if (base==NULL) { - v3d->lay= v3d->localvd->lay; - v3d->layact= v3d->localvd->layact; - MEM_freeN(v3d->localvd); - v3d->localvd= NULL; - } -#endif - } - else if (v3d->scenelock) { - v3d->lay = sc->scene->lay; - } - + /* not very nice, but could help */ if ((v3d->layact & v3d->lay) == 0) v3d->layact = v3d->lay; @@ -6967,6 +7110,44 @@ void blo_lib_link_screen_restore(Main *newmain, bScreen *curscreen, Scene *cursc } } } +} + +/** + * Used to link a file (without UI) to the current UI. + * Note that it assumes the old pointers in UI are still valid, so old Main is not freed. + */ +void blo_lib_link_restore(Main *newmain, wmWindowManager *curwm, Scene *curscene, SceneLayer *cur_render_layer) +{ + struct IDNameLib_Map *id_map = BKE_main_idmap_create(newmain); + + 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) { + lib_link_workspace_layout_restore(id_map, newmain, layout); + } + BKE_workspace_render_layer_set(workspace, cur_render_layer); + } + + for (wmWindow *win = curwm->windows.first; win; win = win->next) { + WorkSpace *workspace = BKE_workspace_active_get(win->workspace_hook); + ID *workspace_id = (ID *)workspace; + Scene *oldscene = win->scene; + + workspace = restore_pointer_by_name(id_map, workspace_id, USER_REAL); + BKE_workspace_active_set(win->workspace_hook, workspace); + win->scene = restore_pointer_by_name(id_map, (ID *)win->scene, USER_REAL); + if (win->scene == NULL) { + win->scene = curscene; + } + BKE_workspace_active_set(win->workspace_hook, workspace); + + /* keep cursor location through undo */ + copy_v3_v3(win->scene->cursor, oldscene->cursor); + lib_link_workspace_scene_data_restore(win, win->scene); + + BLI_assert(win->screen == NULL); + } /* update IDs stored in all possible clipboards */ lib_link_clipboard_restore(id_map); @@ -7020,6 +7201,7 @@ static void direct_link_region(FileData *fd, ARegion *ar, int spacetype) rv3d->sms = NULL; rv3d->smooth_timer = NULL; rv3d->compositor = NULL; + rv3d->viewport = NULL; } } } @@ -7036,6 +7218,7 @@ static void direct_link_region(FileData *fd, ARegion *ar, int spacetype) ar->type = NULL; ar->swap = 0; ar->do_draw = 0; + ar->manipulator_map = NULL; ar->regiontimer = NULL; memset(&ar->drawrct, 0, sizeof(ar->drawrct)); } @@ -7082,6 +7265,8 @@ static bool direct_link_screen(FileData *fd, bScreen *sc) sc->mainwin = sc->subwinactive= 0; /* indices */ sc->swap = 0; + sc->preview = direct_link_preview_image(fd, sc->preview); + /* edges */ for (se = sc->edgebase.first; se; se = se->next) { se->v1 = newdataadr(fd, se->v1); @@ -7146,22 +7331,8 @@ static bool direct_link_screen(FileData *fd, bScreen *sc) if (sl->spacetype == SPACE_VIEW3D) { View3D *v3d= (View3D*) sl; - BGpic *bgpic; - v3d->flag |= V3D_INVALID_BACKBUF; - link_list(fd, &v3d->bgpicbase); - - /* should be do_versions except this doesnt fit well there */ - if (v3d->bgpic) { - bgpic = newdataadr(fd, v3d->bgpic); - BLI_addtail(&v3d->bgpicbase, bgpic); - v3d->bgpic = NULL; - } - - for (bgpic = v3d->bgpicbase.first; bgpic; bgpic = bgpic->next) - bgpic->iuser.ok = 1; - if (v3d->gpd) { v3d->gpd = newdataadr(fd, v3d->gpd); direct_link_gpencil(fd, v3d->gpd); @@ -7447,6 +7618,26 @@ static void fix_relpaths_library(const char *basepath, Main *main) } } +/* ************ READ PROBE ***************** */ + +static void lib_link_lightprobe(FileData *fd, Main *main) +{ + for (LightProbe *prb = main->speaker.first; prb; prb = prb->id.next) { + if (prb->id.tag & LIB_TAG_NEED_LINK) { + IDP_LibLinkProperty(prb->id.properties, fd); + lib_link_animdata(fd, &prb->id, prb->adt); + + prb->id.tag &= ~LIB_TAG_NEED_LINK; + } + } +} + +static void direct_link_lightprobe(FileData *fd, LightProbe *prb) +{ + prb->adt = newdataadr(fd, prb->adt); + direct_link_animdata(fd, prb->adt); +} + /* ************ READ SPEAKER ***************** */ static void lib_link_speaker(FileData *fd, Main *main) @@ -7547,7 +7738,7 @@ static void lib_link_group(FileData *fd, Main *main) if (add_us) { id_us_ensure_real(&group->id); } - BKE_group_object_unlink(group, NULL, NULL, NULL); /* removes NULL entries */ + BKE_group_object_unlink(group, NULL); /* removes NULL entries */ group->id.tag &= ~LIB_TAG_NEED_LINK; } @@ -8062,6 +8253,7 @@ static const char *dataname(short id_code) case ID_VF: return "Data from VF"; case ID_TXT : return "Data from TXT"; case ID_SPK: return "Data from SPK"; + case ID_LP: return "Data from LP"; case ID_SO: return "Data from SO"; case ID_NT: return "Data from NT"; case ID_BR: return "Data from BR"; @@ -8074,6 +8266,7 @@ static const char *dataname(short id_code) case ID_MSK: return "Data from MSK"; case ID_LS: return "Data from LS"; case ID_CF: return "Data from CF"; + case ID_WS: return "Data from WS"; } return "Data from Lib Block"; @@ -8237,7 +8430,7 @@ static BHead *read_libblock(FileData *fd, Main *main, BHead *bhead, const short wrong_id = direct_link_screen(fd, (bScreen *)id); break; case ID_SCE: - direct_link_scene(fd, (Scene *)id); + direct_link_scene(fd, (Scene *)id, main); break; case ID_OB: direct_link_object(fd, (Object *)id); @@ -8293,6 +8486,9 @@ static BHead *read_libblock(FileData *fd, Main *main, BHead *bhead, const short case ID_SO: direct_link_sound(fd, (bSound *)id); break; + case ID_LP: + direct_link_lightprobe(fd, (LightProbe *)id); + break; case ID_GR: direct_link_group(fd, (Group *)id); break; @@ -8332,6 +8528,9 @@ static BHead *read_libblock(FileData *fd, Main *main, BHead *bhead, const short case ID_CF: direct_link_cachefile(fd, (CacheFile *)id); break; + case ID_WS: + direct_link_workspace(fd, (WorkSpace *)id, main); + break; } oldnewmap_free_unused(fd->datamap); @@ -8377,7 +8576,8 @@ static BHead *read_global(BlendFileData *bfd, FileData *fd, BHead *bhead) bfd->curscreen = fg->curscreen; bfd->curscene = fg->curscene; - + bfd->cur_render_layer = fg->cur_render_layer; + MEM_freeN(fg); fd->globalf = bfd->globalf; @@ -8389,6 +8589,7 @@ static BHead *read_global(BlendFileData *bfd, FileData *fd, BHead *bhead) /* note, this has to be kept for reading older files... */ static void link_global(FileData *fd, BlendFileData *bfd) { + bfd->cur_render_layer = newglobadr(fd, bfd->cur_render_layer); bfd->curscreen = newlibadr(fd, NULL, bfd->curscreen); bfd->curscene = newlibadr(fd, NULL, bfd->curscene); // this happens in files older than 2.35 @@ -8397,26 +8598,6 @@ static void link_global(FileData *fd, BlendFileData *bfd) } } -static void convert_tface_mt(FileData *fd, Main *main) -{ - Main *gmain; - - /* this is a delayed do_version (so it can create new materials) */ - if (main->versionfile < 259 || (main->versionfile == 259 && main->subversionfile < 3)) { - //XXX hack, material.c uses G.main all over the place, instead of main - // temporarily set G.main to the current main - gmain = G.main; - G.main = main; - - if (!(do_version_tface(main))) { - BKE_report(fd->reports, RPT_WARNING, "Texface conversion problem (see error in console)"); - } - - //XXX hack, material.c uses G.main allover the place, instead of main - G.main = gmain; - } -} - /* initialize userdef with non-UI dependency stuff */ /* other initializers (such as theme color defaults) go to resources.c */ static void do_versions_userdef(FileData *fd, BlendFileData *bfd) @@ -8470,6 +8651,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main) blo_do_versions_250(fd, lib, main); blo_do_versions_260(fd, lib, main); blo_do_versions_270(fd, lib, main); + blo_do_versions_280(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! */ @@ -8483,6 +8665,7 @@ static void do_versions_after_linking(Main *main) // main->curlib ? "LIB" : "MAIN", main->versionfile, main->subversionfile); do_versions_after_linking_270(main); + do_versions_after_linking_280(main); } static void lib_link_all(FileData *fd, Main *main) @@ -8511,6 +8694,7 @@ static void lib_link_all(FileData *fd, Main *main) lib_link_text(fd, main); lib_link_camera(fd, main); lib_link_speaker(fd, main); + lib_link_lightprobe(fd, main); lib_link_sound(fd, main); lib_link_group(fd, main); lib_link_armature(fd, main); @@ -8526,6 +8710,7 @@ static void lib_link_all(FileData *fd, Main *main) lib_link_linestyle(fd, main); lib_link_gpencil(fd, main); lib_link_cachefiles(fd, main); + lib_link_workspaces(fd, main); lib_link_library(fd, main); /* only init users */ } @@ -8912,6 +9097,11 @@ static void expand_doit_library(void *fdhandle, Main *mainvar, void *old) } } else { + /* in 2.50+ file identifier for screens is patched, forward compatibility */ + if (bhead->code == ID_SCRN) { + bhead->code = ID_SCR; + } + id = is_yet_read(fd, mainvar, bhead); if (id == NULL) { read_libblock(fd, mainvar, bhead, LIB_TAG_TESTIND, NULL); @@ -9226,6 +9416,10 @@ static void expand_material(FileData *fd, Main *mainvar, Material *ma) if (ma->group) expand_doit(fd, mainvar, ma->group); + + if (ma->edit_image) { + expand_doit(fd, mainvar, ma->edit_image); + } } static void expand_lamp(FileData *fd, Main *mainvar, Lamp *la) @@ -9315,9 +9509,7 @@ static void expand_curve(FileData *fd, Main *mainvar, Curve *cu) static void expand_mesh(FileData *fd, Main *mainvar, Mesh *me) { - CustomDataLayer *layer; - TFace *tf; - int a, i; + int a; if (me->adt) expand_animdata(fd, mainvar, me->adt); @@ -9328,46 +9520,6 @@ static void expand_mesh(FileData *fd, Main *mainvar, Mesh *me) expand_doit(fd, mainvar, me->key); expand_doit(fd, mainvar, me->texcomesh); - - if (me->tface) { - tf = me->tface; - for (i=0; i<me->totface; i++, tf++) { - if (tf->tpage) - expand_doit(fd, mainvar, tf->tpage); - } - } - - if (me->mface && !me->mpoly) { - MTFace *mtf; - - for (a = 0; a < me->fdata.totlayer; a++) { - layer = &me->fdata.layers[a]; - - if (layer->type == CD_MTFACE) { - mtf = (MTFace *) layer->data; - for (i = 0; i < me->totface; i++, mtf++) { - if (mtf->tpage) - expand_doit(fd, mainvar, mtf->tpage); - } - } - } - } - else { - MTexPoly *mtp; - - for (a = 0; a < me->pdata.totlayer; a++) { - layer = &me->pdata.layers[a]; - - if (layer->type == CD_MTEXPOLY) { - mtp = (MTexPoly *) layer->data; - - for (i = 0; i < me->totpoly; i++, mtp++) { - if (mtp->tpage) - expand_doit(fd, mainvar, mtp->tpage); - } - } - } - } } /* temp struct used to transport needed info to expand_constraint_cb() */ @@ -9610,9 +9762,24 @@ static void expand_object(FileData *fd, Main *mainvar, Object *ob) } } +static void expand_scene_collection(FileData *fd, Main *mainvar, SceneCollection *sc) +{ + for (LinkData *link = sc->objects.first; link; link = link->next) { + expand_doit(fd, mainvar, link->data); + } + + for (LinkData *link = sc->filter_objects.first; link; link = link->next) { + expand_doit(fd, mainvar, link->data); + } + + for (SceneCollection *nsc= sc->scene_collections.first; nsc; nsc = nsc->next) { + expand_scene_collection(fd, mainvar, nsc); + } +} + static void expand_scene(FileData *fd, Main *mainvar, Scene *sce) { - Base *base; + BaseLegacy *base; SceneRenderLayer *srl; FreestyleModuleConfig *module; FreestyleLineSet *lineset; @@ -9681,6 +9848,8 @@ static void expand_scene(FileData *fd, Main *mainvar, Scene *sce) } expand_doit(fd, mainvar, sce->clip); + + expand_scene_collection(fd, mainvar, sce->collection); } static void expand_camera(FileData *fd, Main *mainvar, Camera *ca) @@ -9711,6 +9880,12 @@ static void expand_sound(FileData *fd, Main *mainvar, bSound *snd) expand_doit(fd, mainvar, snd->ipo); // XXX deprecated - old animation system } +static void expand_lightprobe(FileData *fd, Main *mainvar, LightProbe *prb) +{ + if (prb->adt) + expand_animdata(fd, mainvar, prb->adt); +} + static void expand_movieclip(FileData *fd, Main *mainvar, MovieClip *clip) { if (clip->adt) @@ -9784,6 +9959,15 @@ static void expand_gpencil(FileData *fd, Main *mainvar, bGPdata *gpd) expand_animdata(fd, mainvar, gpd->adt); } +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) { + expand_doit(fd, mainvar, BKE_workspace_layout_screen_get(layout)); + } +} + /** * Set the callback func used over all ID data found by \a BLO_expand_main func. * @@ -9862,6 +10046,9 @@ void BLO_expand_main(void *fdhandle, Main *mainvar) case ID_SO: expand_sound(fd, mainvar, (bSound *)id); break; + case ID_LP: + expand_lightprobe(fd, mainvar, (LightProbe *)id); + break; case ID_AR: expand_armature(fd, mainvar, (bArmature *)id); break; @@ -9898,6 +10085,8 @@ void BLO_expand_main(void *fdhandle, Main *mainvar) case ID_CF: expand_cachefile(fd, mainvar, (CacheFile *)id); break; + case ID_WS: + expand_workspace(fd, mainvar, (WorkSpace *)id); default: break; } @@ -9928,16 +10117,17 @@ static bool object_in_any_scene(Main *mainvar, Object *ob) return false; } -static void give_base_to_objects(Main *mainvar, Scene *scene, View3D *v3d, Library *lib, const short flag) +static void give_base_to_objects( + Main *mainvar, Scene *scene, SceneLayer *scene_layer, Library *lib, const short flag) { Object *ob; Base *base; - const unsigned int active_lay = (flag & FILE_ACTIVELAY) ? BKE_screen_view3d_layer_active(v3d, scene) : 0; + SceneCollection *scene_collection = NULL; const bool is_link = (flag & FILE_LINK) != 0; BLI_assert(scene); - /* give all objects which are LIB_TAG_INDIRECT a base, or for a group when *lib has been set */ + /* Give all objects which are LIB_TAG_INDIRECT a base, or for a group when *lib has been set. */ for (ob = mainvar->object.first; ob; ob = ob->id.next) { if ((ob->id.tag & LIB_TAG_INDIRECT) && (ob->id.tag & LIB_TAG_PRE_EXISTING) == 0) { bool do_it = false; @@ -9952,26 +10142,26 @@ static void give_base_to_objects(Main *mainvar, Scene *scene, View3D *v3d, Libra } if (do_it) { - base = MEM_callocN(sizeof(Base), __func__); - BLI_addtail(&scene->base, base); + CLAMP_MIN(ob->id.us, 0); - if (active_lay) { - ob->lay = active_lay; + if (scene_collection == NULL) { + scene_collection = get_scene_collection_active_or_create(scene, scene_layer, FILE_ACTIVE_COLLECTION); } + + BKE_collection_object_add(scene, scene_collection, ob); + base = BKE_scene_layer_base_find(scene_layer, ob); + BKE_scene_object_base_flag_sync_from_base(base); + if (flag & FILE_AUTOSELECT) { /* Note that link_object_postprocess() already checks for FILE_AUTOSELECT flag, * but it will miss objects from non-instanciated groups... */ - ob->flag |= SELECT; - /* do NOT make base active here! screws up GUI stuff, if you want it do it on src/ level */ + if (base->flag & BASE_SELECTABLED) { + base->flag |= BASE_SELECTED; + BKE_scene_base_flag_sync_from_base(base); + } + /* Do NOT make base active here! screws up GUI stuff, if you want it do it on src/ level. */ } - base->object = ob; - base->lay = ob->lay; - base->flag = ob->flag; - - CLAMP_MIN(ob->id.us, 0); - id_us_plus_no_lib((ID *)ob); - ob->id.tag &= ~LIB_TAG_INDIRECT; ob->id.tag |= LIB_TAG_EXTERN; } @@ -9980,32 +10170,38 @@ static void give_base_to_objects(Main *mainvar, Scene *scene, View3D *v3d, Libra } static void give_base_to_groups( - Main *mainvar, Scene *scene, View3D *v3d, Library *UNUSED(lib), const short UNUSED(flag)) + Main *mainvar, Scene *scene, SceneLayer *scene_layer, Library *UNUSED(lib), const short UNUSED(flag)) { Group *group; Base *base; Object *ob; - const unsigned int active_lay = BKE_screen_view3d_layer_active(v3d, scene); + SceneCollection *scene_collection; - /* give all objects which are tagged a base */ + /* If the group is empty this function is not even called, so it's safe to ensure a collection at this point. */ + scene_collection = get_scene_collection_active_or_create(scene, scene_layer, FILE_ACTIVE_COLLECTION); + + /* Give all objects which are tagged a base. */ for (group = mainvar->group.first; group; group = group->id.next) { if (group->id.tag & LIB_TAG_DOIT) { - /* any indirect group should not have been tagged */ + /* Any indirect group should not have been tagged. */ BLI_assert((group->id.tag & LIB_TAG_INDIRECT) == 0); - /* BKE_object_add(...) messes with the selection */ + /* BKE_object_add(...) messes with the selection. */ ob = BKE_object_add_only_object(mainvar, OB_EMPTY, group->id.name + 2); ob->type = OB_EMPTY; - ob->lay = active_lay; - /* assign the base */ - base = BKE_scene_base_add(scene, ob); - base->flag |= SELECT; - base->object->flag = base->flag; - DAG_id_tag_update(&ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME); - scene->basact = base; + BKE_collection_object_add(scene, scene_collection, ob); + base = BKE_scene_layer_base_find(scene_layer, ob); - /* assign the group */ + if (base->flag & BASE_SELECTABLED) { + base->flag |= BASE_SELECTED; + } + + BKE_scene_object_base_flag_sync_from_base(base); + DEG_id_tag_update(&ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME); + scene_layer->basact = base; + + /* Assign the group. */ ob->dup_group = group; ob->transflag |= OB_DUPLIGROUP; copy_v3_v3(ob->loc, scene->cursor); @@ -10080,31 +10276,42 @@ static ID *link_named_part( return id; } -static void link_object_postprocess(ID *id, Scene *scene, View3D *v3d, const short flag) +static SceneCollection *get_scene_collection_active_or_create(struct Scene *scene, struct SceneLayer *sl, const short flag) +{ + LayerCollection *lc = NULL; + + if (flag & FILE_ACTIVE_COLLECTION) { + lc = BKE_layer_collection_get_active_ensure(scene, sl); + } + else { + SceneCollection *sc = BKE_collection_add(scene, NULL, NULL); + lc = BKE_collection_link(sl, sc); + } + + return lc->scene_collection; +} + +static void link_object_postprocess(ID *id, Scene *scene, SceneLayer *sl, const short flag) { if (scene) { + /* link to scene */ Base *base; Object *ob; - - base = MEM_callocN(sizeof(Base), "app_nam_part"); - BLI_addtail(&scene->base, base); + SceneCollection *sc; ob = (Object *)id; - - /* link at active layer (view3d if available in context, else scene one */ - if (flag & FILE_ACTIVELAY) { - ob->lay = BKE_screen_view3d_layer_active(v3d, scene); - } - ob->mode = OB_MODE_OBJECT; - base->lay = ob->lay; - base->object = ob; - base->flag = ob->flag; - id_us_plus_no_lib((ID *)ob); + + sc = get_scene_collection_active_or_create(scene, sl, flag); + BKE_collection_object_add(scene, sc, ob); + base = BKE_scene_layer_base_find(sl, ob); + BKE_scene_object_base_flag_sync_from_base(base); if (flag & FILE_AUTOSELECT) { - base->flag |= SELECT; - base->object->flag = base->flag; + if (base->flag & BASE_SELECTABLED) { + base->flag |= BASE_SELECTED; + BKE_scene_base_flag_sync_from_base(base); + } /* do NOT make base active here! screws up GUI stuff, if you want it do it on src/ level */ } } @@ -10147,12 +10354,12 @@ void BLO_library_link_copypaste(Main *mainl, BlendHandle *bh) static ID *link_named_part_ex( Main *mainl, FileData *fd, const short idcode, const char *name, const short flag, - Scene *scene, View3D *v3d, const bool use_placeholders, const bool force_indirect) + Scene *scene, SceneLayer *sl, const bool use_placeholders, const bool force_indirect) { ID *id = link_named_part(mainl, fd, idcode, name, use_placeholders, force_indirect); if (id && (GS(id->name) == ID_OB)) { /* loose object: give a base */ - link_object_postprocess(id, scene, v3d, flag); + link_object_postprocess(id, scene, sl, flag); } else if (id && (GS(id->name) == ID_GR)) { /* tag as needing to be instantiated */ @@ -10196,11 +10403,11 @@ ID *BLO_library_link_named_part(Main *mainl, BlendHandle **bh, const short idcod ID *BLO_library_link_named_part_ex( Main *mainl, BlendHandle **bh, const short idcode, const char *name, const short flag, - Scene *scene, View3D *v3d, + Scene *scene, SceneLayer *sl, const bool use_placeholders, const bool force_indirect) { FileData *fd = (FileData*)(*bh); - return link_named_part_ex(mainl, fd, idcode, name, flag, scene, v3d, use_placeholders, force_indirect); + return link_named_part_ex(mainl, fd, idcode, name, flag, scene, sl, use_placeholders, force_indirect); } static void link_id_part(ReportList *reports, FileData *fd, Main *mainvar, ID *id, ID **r_id) @@ -10313,7 +10520,7 @@ static void split_main_newid(Main *mainptr, Main *main_newid) } /* scene and v3d may be NULL. */ -static void library_link_end(Main *mainl, FileData **fd, const short flag, Scene *scene, View3D *v3d) +static void library_link_end(Main *mainl, FileData **fd, const short flag, Scene *scene, SceneLayer *sl) { Main *mainvar; Library *curlib; @@ -10369,10 +10576,10 @@ static void library_link_end(Main *mainl, FileData **fd, const short flag, Scene * Only directly linked objects & groups are instantiated by `BLO_library_link_named_part_ex()` & co, * here we handle indirect ones and other possible edge-cases. */ if (scene) { - give_base_to_objects(mainvar, scene, v3d, curlib, flag); + give_base_to_objects(mainvar, scene, sl, curlib, flag); if (flag & FILE_GROUP_INSTANCE) { - give_base_to_groups(mainvar, scene, v3d, curlib, flag); + give_base_to_groups(mainvar, scene, sl, curlib, flag); } } else { @@ -10398,12 +10605,12 @@ static void library_link_end(Main *mainl, FileData **fd, const short flag, Scene * \param bh The blender file handle (WARNING! may be freed by this function!). * \param flag Options for linking, used for instantiating. * \param scene The scene in which to instantiate objects/groups (if NULL, no instantiation is done). - * \param v3d The active View3D (only to define active layers for instantiated objects & groups, can be NULL). + * \param sl The scene layer in which to instantiate objects/groups (if NULL, no instantiation is done). */ -void BLO_library_link_end(Main *mainl, BlendHandle **bh, short flag, Scene *scene, View3D *v3d) +void BLO_library_link_end(Main *mainl, BlendHandle **bh, short flag, Scene *scene, SceneLayer *sl) { FileData *fd = (FileData*)(*bh); - library_link_end(mainl, &fd, flag, scene, v3d); + library_link_end(mainl, &fd, flag, scene, sl); *bh = (BlendHandle*)fd; } diff --git a/source/blender/blenloader/intern/readfile.h b/source/blender/blenloader/intern/readfile.h index 62ce15a640e..299c66f2bbb 100644 --- a/source/blender/blenloader/intern/readfile.h +++ b/source/blender/blenloader/intern/readfile.h @@ -34,6 +34,8 @@ #define __READFILE_H__ #include "zlib.h" +#include "DNA_sdna_types.h" +#include "DNA_space_types.h" #include "DNA_windowmanager_types.h" /* for ReportType */ struct OldNewMap; @@ -171,8 +173,10 @@ void blo_do_versions_pre250(struct FileData *fd, struct Library *lib, struct Mai void blo_do_versions_250(struct FileData *fd, struct Library *lib, struct Main *main); void blo_do_versions_260(struct FileData *fd, struct Library *lib, struct Main *main); void blo_do_versions_270(struct FileData *fd, struct Library *lib, struct Main *main); +void blo_do_versions_280(struct FileData *fd, struct Library *lib, struct Main *main); void do_versions_after_linking_270(struct Main *main); +void do_versions_after_linking_280(struct Main *main); #endif diff --git a/source/blender/blenloader/intern/versioning_250.c b/source/blender/blenloader/intern/versioning_250.c index 1956a17d57b..0895b956563 100644 --- a/source/blender/blenloader/intern/versioning_250.c +++ b/source/blender/blenloader/intern/versioning_250.c @@ -736,7 +736,7 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *main) if (main->versionfile < 250) { bScreen *screen; Scene *scene; - Base *base; + BaseLegacy *base; Material *ma; Camera *cam; Mesh *me; @@ -1119,8 +1119,6 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *main) sce->gm.matmode = GAME_MAT_MULTITEX; else sce->gm.matmode = GAME_MAT_TEXFACE; - - sce->gm.flag |= GAME_DISPLAY_LISTS; } for (ob = main->object.first; ob; ob = ob->id.next) { diff --git a/source/blender/blenloader/intern/versioning_270.c b/source/blender/blenloader/intern/versioning_270.c index 095f21a5b06..b945f5bdcd3 100644 --- a/source/blender/blenloader/intern/versioning_270.c +++ b/source/blender/blenloader/intern/versioning_270.c @@ -1671,6 +1671,27 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main) for (Mesh *me = main->mesh.first; me; me = me->id.next) { CustomData_set_layer_name(&me->vdata, CD_MDEFORMVERT, 0, ""); } + + if (!DNA_struct_elem_find(fd->filesdna, "View3DDebug", "char", "background")) { + bScreen *screen; + + for (screen = main->screen.first; screen; screen = screen->id.next) { + ScrArea *sa; + for (sa = screen->areabase.first; sa; sa = sa->next) { + SpaceLink *sl; + + for (sl = sa->spacedata.first; sl; sl = sl->next) { + switch (sl->spacetype) { + case SPACE_VIEW3D: + { + View3D *v3d = (View3D *)sl; + v3d->debug.background = V3D_DEBUG_BACKGROUND_NONE; + } + } + } + } + } + } } { diff --git a/source/blender/blenloader/intern/versioning_280.c b/source/blender/blenloader/intern/versioning_280.c new file mode 100644 index 00000000000..2485309fb80 --- /dev/null +++ b/source/blender/blenloader/intern/versioning_280.c @@ -0,0 +1,533 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * 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. + * + * Contributor(s): Dalai Felinto + * + * ***** END GPL LICENSE BLOCK ***** + * + */ + +/** \file blender/blenloader/intern/versioning_280.c + * \ingroup blenloader + */ + +/* allow readfile to use deprecated functionality */ +#define DNA_DEPRECATED_ALLOW + +#include <string.h> + +#include "DNA_object_types.h" +#include "DNA_camera_types.h" +#include "DNA_gpu_types.h" +#include "DNA_lamp_types.h" +#include "DNA_layer_types.h" +#include "DNA_material_types.h" +#include "DNA_mesh_types.h" +#include "DNA_scene_types.h" +#include "DNA_screen_types.h" +#include "DNA_view3d_types.h" +#include "DNA_genfile.h" +#include "DNA_workspace_types.h" + +#include "BKE_collection.h" +#include "BKE_customdata.h" +#include "BKE_idprop.h" +#include "BKE_layer.h" +#include "BKE_main.h" +#include "BKE_mesh.h" +#include "BKE_node.h" +#include "BKE_report.h" +#include "BKE_scene.h" +#include "BKE_workspace.h" + +#include "BLI_listbase.h" +#include "BLI_mempool.h" +#include "BLI_string.h" +#include "BLI_utildefines.h" + +#include "BLO_readfile.h" +#include "readfile.h" + +#include "MEM_guardedalloc.h" + + +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; + } + } + } + + return NULL; +} + +static void do_version_workspaces_create_from_screens(Main *bmain) +{ + for (bScreen *screen = bmain->screen.first; screen; screen = screen->id.next) { + const bScreen *screen_parent = screen_parent_find(screen); + WorkSpace *workspace; + SceneLayer *layer = BKE_scene_layer_from_scene_get(screen->scene); + ListBase *transform_orientations; + + if (screen_parent) { + /* fullscreen with "Back to Previous" option, don't create + * a new workspace, add layout workspace containing parent */ + workspace = BLI_findstring( + &bmain->workspaces, screen_parent->id.name + 2, offsetof(ID, name) + 2); + } + else { + workspace = BKE_workspace_add(bmain, screen->id.name + 2); + } + BKE_workspace_layout_add(workspace, screen, screen->id.name + 2); + BKE_workspace_render_layer_set(workspace, layer); + +#ifdef WITH_CLAY_ENGINE + BLI_strncpy(workspace->view_render.engine_id, RE_engine_id_BLENDER_CLAY, + sizeof(workspace->view_render.engine_id)); +#else + BLI_strncpy(workspace->view_render.engine_id, RE_engine_id_BLENDER_EEVEE, + sizeof(workspace->view_render.engine_id)); +#endif + + transform_orientations = BKE_workspace_transform_orientations_get(workspace); + BLI_duplicatelist(transform_orientations, &screen->scene->transform_spaces); + } +} + +/** + * \brief After lib-link versioning for new workspace design. + * + * * Adds a workspace for (almost) each screen of the old file + * and adds the needed workspace-layout to wrap the screen. + * * Active screen isn't stored directly in window anymore, but in the active workspace. + * * Active scene isn't stored in screen anymore, but in window. + * * Create workspace instance hook for each window. + * + * \note Some of the created workspaces might be deleted again in case of reading the default startup.blend. + */ +static void do_version_workspaces_after_lib_link(Main *bmain) +{ + BLI_assert(BLI_listbase_is_empty(&bmain->workspaces)); + + 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) { + bScreen *screen_parent = screen_parent_find(win->screen); + bScreen *screen = screen_parent ? screen_parent : win->screen; + WorkSpace *workspace = BLI_findstring(&bmain->workspaces, screen->id.name + 2, offsetof(ID, name) + 2); + ListBase *layouts = BKE_workspace_layouts_get(workspace); + + 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, layouts->first); + + win->scene = screen->scene; + /* Deprecated from now on! */ + win->screen = NULL; + } + } + + for (bScreen *screen = bmain->screen.first; screen; screen = screen->id.next) { + /* Deprecated from now on! */ + BLI_freelistN(&screen->scene->transform_spaces); + screen->scene = NULL; + } +} + +void do_versions_after_linking_280(Main *main) +{ + if (!MAIN_VERSION_ATLEAST(main, 280, 0)) { + for (Scene *scene = main->scene.first; scene; scene = scene->id.next) { + /* since we don't have access to FileData we check the (always valid) first render layer instead */ + if (scene->render_layers.first == NULL) { + SceneCollection *sc_master = BKE_collection_master(scene); + BLI_strncpy(sc_master->name, "Master Collection", sizeof(sc_master->name)); + + SceneCollection *collections[20] = {NULL}; + bool is_visible[20]; + + int lay_used = 0; + for (int i = 0; i < 20; i++) { + char name[MAX_NAME]; + + BLI_snprintf(name, sizeof(collections[i]->name), "Collection %d", i + 1); + collections[i] = BKE_collection_add(scene, sc_master, name); + + is_visible[i] = (scene->lay & (1 << i)); + } + + for (Base *base = scene->base.first; base; base = base->next) { + lay_used |= base->lay & ((1 << 20) - 1); /* ignore localview */ + + for (int i = 0; i < 20; i++) { + if ((base->lay & (1 << i)) != 0) { + BKE_collection_object_add(scene, collections[i], base->object); + } + } + + if (base->flag & SELECT) { + base->object->flag |= SELECT; + } + else { + base->object->flag &= ~SELECT; + } + } + + scene->active_layer = 0; + + if (!BKE_scene_uses_blender_game(scene)) { + for (SceneRenderLayer *srl = scene->r.layers.first; srl; srl = srl->next) { + + SceneLayer *sl = BKE_scene_layer_add(scene, srl->name); + + if (srl->mat_override) { + BKE_collection_override_datablock_add((LayerCollection *)sl->layer_collections.first, "material", (ID *)srl->mat_override); + } + + if (srl->light_override && BKE_scene_uses_blender_internal(scene)) { + /* not sure how we handle this, pending until we design the override system */ + TODO_LAYER_OVERRIDE; + } + + if (srl->lay != scene->lay) { + /* unlink master collection */ + BKE_collection_unlink(sl, sl->layer_collections.first); + + /* add new collection bases */ + for (int i = 0; i < 20; i++) { + if ((srl->lay & (1 << i)) != 0) { + BKE_collection_link(sl, collections[i]); + } + } + } + + /* for convenience set the same active object in all the layers */ + if (scene->basact) { + sl->basact = BKE_scene_layer_base_find(sl, scene->basact->object); + } + + for (Base *base = sl->object_bases.first; base; base = base->next) { + if ((base->flag & BASE_SELECTABLED) && (base->object->flag & SELECT)) { + base->flag |= BASE_SELECTED; + } + } + + /* TODO: passes, samples, mask_layesr, exclude, ... */ + } + + if (BLI_findlink(&scene->render_layers, scene->r.actlay)) { + scene->active_layer = scene->r.actlay; + } + } + + SceneLayer *sl = BKE_scene_layer_add(scene, "Viewport"); + + /* In this particular case we can safely assume the data struct */ + LayerCollection *lc = ((LayerCollection *)sl->layer_collections.first)->layer_collections.first; + for (int i = 0; i < 20; i++) { + if (!is_visible[i]) { + lc->flag &= ~COLLECTION_VISIBLE; + } + lc = lc->next; + } + + /* convert active base */ + if (scene->basact) { + sl->basact = BKE_scene_layer_base_find(sl, scene->basact->object); + } + + /* convert selected bases */ + for (Base *base = scene->base.first; base; base = base->next) { + if ((base->flag & BASE_SELECTABLED) && (base->object->flag & SELECT)) { + base->flag |= BASE_SELECTED; + } + + /* keep lay around for forward compatibility (open those files in 2.79) */ + base->lay = base->object->lay; + } + + /* TODO: copy scene render data to layer */ + + /* Cleanup */ + for (int i = 0; i < 20; i++) { + if ((lay_used & (1 << i)) == 0) { + BKE_collection_remove(scene, collections[i]); + } + } + + /* Fallback name if only one layer was found in the original file */ + if (BLI_listbase_count_ex(&sc_master->scene_collections, 2) == 1) { + BKE_collection_rename(scene, sc_master->scene_collections.first, "Default Collection"); + } + + /* remove bases once and for all */ + for (Base *base = scene->base.first; base; base = base->next) { + id_us_min(&base->object->id); + } + BLI_freelistN(&scene->base); + scene->basact = NULL; + } + } + } + + if (!MAIN_VERSION_ATLEAST(main, 280, 0)) { + for (bScreen *screen = main->screen.first; screen; screen = screen->id.next) { + /* same render-layer as do_version_workspaces_after_lib_link will activate, + * so same layer as BKE_scene_layer_from_workspace_get would return */ + SceneLayer *layer = screen->scene->render_layers.first; + + for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) { + for (SpaceLink *sl = sa->spacedata.first; sl; sl = sl->next) { + if (sl->spacetype == SPACE_OUTLINER) { + SpaceOops *soutliner = (SpaceOops *)sl; + + soutliner->outlinevis = SO_ACT_LAYER; + + if (BLI_listbase_count_ex(&layer->layer_collections, 2) == 1) { + if (soutliner->treestore == NULL) { + soutliner->treestore = BLI_mempool_create( + sizeof(TreeStoreElem), 1, 512, BLI_MEMPOOL_ALLOW_ITER); + } + + /* Create a tree store element for the collection. This is normally + * done in check_persistent (outliner_tree.c), but we need to access + * it here :/ (expand element if it's the only one) */ + TreeStoreElem *tselem = BLI_mempool_calloc(soutliner->treestore); + tselem->type = TSE_LAYER_COLLECTION; + tselem->id = layer->layer_collections.first; + tselem->nr = tselem->used = 0; + tselem->flag &= ~TSE_CLOSED; + } + } + } + } + } + } + + /* New workspace design */ + if (!MAIN_VERSION_ATLEAST(main, 280, 1)) { + do_version_workspaces_after_lib_link(main); + } +} + +static void do_version_layer_collections_idproperties(ListBase *lb) +{ + IDPropertyTemplate val = {0}; + for (LayerCollection *lc = lb->first; lc; lc = lc->next) { + lc->properties = IDP_New(IDP_GROUP, &val, ROOT_PROP); + BKE_layer_collection_engine_settings_create(lc->properties); + + /* No overrides at first */ + for (IDProperty *prop = lc->properties->data.group.first; prop; prop = prop->next) { + while (prop->data.group.first) { + IDP_FreeFromGroup(prop, prop->data.group.first); + } + } + + /* Do it recursively */ + do_version_layer_collections_idproperties(&lc->layer_collections); + } +} + +void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *main) +{ + + if (!MAIN_VERSION_ATLEAST(main, 280, 0)) { + for (Scene *scene = main->scene.first; scene; scene = scene->id.next) { + if (STREQ(scene->r.engine, RE_engine_id_BLENDER_RENDER)) { +#ifdef WITH_CLAY_ENGINE + BLI_strncpy(scene->r.engine, RE_engine_id_BLENDER_CLAY, sizeof(scene->r.engine)); +#else + BLI_strncpy(scene->r.engine, RE_engine_id_BLENDER_EEVEE, sizeof(scene->r.engine)); +#endif + } + } + + if (!DNA_struct_elem_find(fd->filesdna, "Scene", "ListBase", "render_layers")) { + for (Scene *scene = main->scene.first; scene; scene = scene->id.next) { + /* Master Collection */ + scene->collection = MEM_callocN(sizeof(SceneCollection), "Master Collection"); + BLI_strncpy(scene->collection->name, "Master Collection", sizeof(scene->collection->name)); + } + } + + if (DNA_struct_elem_find(fd->filesdna, "LayerCollection", "ListBase", "engine_settings") && + !DNA_struct_elem_find(fd->filesdna, "LayerCollection", "IDProperty", "properties")) + { + for (Scene *scene = main->scene.first; scene; scene = scene->id.next) { + for (SceneLayer *sl = scene->render_layers.first; sl; sl = sl->next) { + do_version_layer_collections_idproperties(&sl->layer_collections); + } + } + } + } + + if (!MAIN_VERSION_ATLEAST(main, 280, 1)) { + if (!DNA_struct_elem_find(fd->filesdna, "Lamp", "float", "bleedexp")) { + for (Lamp *la = main->lamp.first; la; la = la->id.next) { + la->bleedexp = 2.5f; + } + } + + if (!DNA_struct_elem_find(fd->filesdna, "GPUDOFSettings", "float", "ratio")) { + for (Camera *ca = main->camera.first; ca; ca = ca->id.next) { + ca->gpu_dof.ratio = 1.0f; + } + } + + if (!DNA_struct_elem_find(fd->filesdna, "SceneLayer", "IDProperty", "*properties")) { + for (Scene *scene = main->scene.first; scene; scene = scene->id.next) { + for (SceneLayer *sl = scene->render_layers.first; sl; sl = sl->next) { + IDPropertyTemplate val = {0}; + sl->properties = IDP_New(IDP_GROUP, &val, ROOT_PROP); + BKE_scene_layer_engine_settings_create(sl->properties); + } + } + } + + /* MTexPoly now removed. */ + if (DNA_struct_find(fd->filesdna, "MTexPoly")) { + const int cd_mtexpoly = 15; /* CD_MTEXPOLY, deprecated */ + for (Mesh *me = main->mesh.first; me; me = me->id.next) { + /* If we have UV's, so this file will have MTexPoly layers too! */ + if (me->mloopuv != NULL) { + CustomData_update_typemap(&me->pdata); + CustomData_free_layers(&me->pdata, cd_mtexpoly, me->totpoly); + BKE_mesh_update_customdata_pointers(me, false); + } + } + } + } + + { + if (!DNA_struct_elem_find(fd->filesdna, "View3D", "short", "custom_orientation_index")) { + for (bScreen *screen = main->screen.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_VIEW3D) { + View3D *v3d = (View3D *)sl; + if (v3d->twmode >= V3D_MANIP_CUSTOM) { + v3d->custom_orientation_index = v3d->twmode - V3D_MANIP_CUSTOM; + v3d->twmode = V3D_MANIP_CUSTOM; + } + else { + v3d->custom_orientation_index = -1; + } + } + } + } + } + } + + if (!DNA_struct_elem_find(fd->filesdna, "Lamp", "float", "cascade_max_dist")) { + for (Lamp *la = main->lamp.first; la; la = la->id.next) { + la->cascade_max_dist = 1000.0f; + la->cascade_count = 4; + la->cascade_exponent = 0.8f; + la->cascade_fade = 0.1f; + } + } + + if (!DNA_struct_elem_find(fd->filesdna, "Lamp", "float", "contact_dist")) { + for (Lamp *la = main->lamp.first; la; la = la->id.next) { + la->contact_dist = 1.0f; + la->contact_bias = 0.03f; + la->contact_spread = 0.2f; + la->contact_thickness = 0.5f; + } + } + } + + { + typedef enum eNTreeDoVersionErrors { + NTREE_DOVERSION_NO_ERROR = 0, + NTREE_DOVERSION_NEED_OUTPUT = (1 << 0), + NTREE_DOVERSION_TRANSPARENCY_EMISSION = (1 << 1), + } eNTreeDoVersionErrors; + + /* Eevee shader nodes renamed because of the output node system. + * Note that a new output node is not being added here, because it would be overkill + * to handle this case in lib_verify_nodetree. + * + * Also, metallic node is now unified into the principled node. */ + eNTreeDoVersionErrors error = NTREE_DOVERSION_NO_ERROR; + + FOREACH_NODETREE(main, ntree, id) { + if (ntree->type == NTREE_SHADER) { + for (bNode *node = ntree->nodes.first; node; node = node->next) { + if (node->type == 194 /* SH_NODE_EEVEE_METALLIC */ && + STREQ(node->idname, "ShaderNodeOutputMetallic")) + { + BLI_strncpy(node->idname, "ShaderNodeEeveeMetallic", sizeof(node->idname)); + error |= NTREE_DOVERSION_NEED_OUTPUT; + } + + else if (node->type == SH_NODE_EEVEE_SPECULAR && STREQ(node->idname, "ShaderNodeOutputSpecular")) { + BLI_strncpy(node->idname, "ShaderNodeEeveeSpecular", sizeof(node->idname)); + error |= NTREE_DOVERSION_NEED_OUTPUT; + } + + else if (node->type == 196 /* SH_NODE_OUTPUT_EEVEE_MATERIAL */ && + STREQ(node->idname, "ShaderNodeOutputEeveeMaterial")) + { + node->type = SH_NODE_OUTPUT_MATERIAL; + BLI_strncpy(node->idname, "ShaderNodeOutputMaterial", sizeof(node->idname)); + } + + else if (node->type == 194 /* SH_NODE_EEVEE_METALLIC */ && + STREQ(node->idname, "ShaderNodeEeveeMetallic")) + { + node->type = SH_NODE_BSDF_PRINCIPLED; + BLI_strncpy(node->idname, "ShaderNodeBsdfPrincipled", sizeof(node->idname)); + node->custom1 = SHD_GLOSSY_MULTI_GGX; + error |= NTREE_DOVERSION_TRANSPARENCY_EMISSION; + } + } + } + } FOREACH_NODETREE_END + + if (error & NTREE_DOVERSION_NEED_OUTPUT) { + BKE_report(fd->reports, RPT_ERROR, "Eevee material conversion problem. Error in console"); + printf("You need to connect Principled and Eevee Specular shader nodes to new material output nodes.\n"); + } + + if (error & NTREE_DOVERSION_TRANSPARENCY_EMISSION) { + BKE_report(fd->reports, RPT_ERROR, "Eevee material conversion problem. Error in console"); + printf("You need to combine transparency and emission shaders to the converted Principled shader nodes.\n"); + } + } + + { + if (!DNA_struct_elem_find(fd->filesdna, "Scene", "ViewRender", "view_render")) { + for (Scene *scene = main->scene.first; scene; scene = scene->id.next) { + BLI_strncpy_utf8(scene->view_render.engine_id, scene->r.engine, + sizeof(scene->view_render.engine_id)); + } + + for (WorkSpace *workspace = main->workspaces.first; workspace; workspace = workspace->id.next) { + BKE_viewrender_init(&workspace->view_render); + } + } + } +} diff --git a/source/blender/blenloader/intern/versioning_defaults.c b/source/blender/blenloader/intern/versioning_defaults.c index 3d3e73eb470..925a87cb653 100644 --- a/source/blender/blenloader/intern/versioning_defaults.c +++ b/source/blender/blenloader/intern/versioning_defaults.c @@ -28,6 +28,7 @@ #include "BLI_utildefines.h" #include "BLI_listbase.h" #include "BLI_math.h" +#include "BLI_string.h" #include "DNA_brush_types.h" #include "DNA_freestyle_types.h" @@ -39,10 +40,13 @@ #include "DNA_mesh_types.h" #include "DNA_material_types.h" #include "DNA_object_types.h" +#include "DNA_workspace_types.h" #include "BKE_brush.h" #include "BKE_library.h" #include "BKE_main.h" +#include "BKE_scene.h" +#include "BKE_workspace.h" #include "BLO_readfile.h" @@ -86,11 +90,40 @@ void BLO_update_defaults_userpref_blend(void) } /** + * New workspace design: Remove all screens/workspaces except of "Default" one and rename the workspace to "General". + * For compatibility, a new workspace has been created for each screen of old files, + * we only want one workspace and one screen in the default startup file however. + */ +static void update_defaults_startup_workspaces(Main *bmain) +{ + WorkSpace *workspace_default = NULL; + + for (WorkSpace *workspace = bmain->workspaces.first, *workspace_next; workspace; workspace = workspace_next) { + workspace_next = workspace->id.next; + + if (STREQ(workspace->id.name + 2, "Default")) { + /* don't rename within iterator, renaming causes listbase to be re-sorted */ + workspace_default = workspace; + BKE_viewrender_init(&workspace->view_render); + } + else { + BKE_workspace_remove(bmain, workspace); + } + } + + /* rename "Default" workspace to "General" */ + BKE_libblock_rename(bmain, (ID *)workspace_default, "General"); + BLI_assert(BLI_listbase_count(BKE_workspace_layouts_get(workspace_default)) == 1); +} + +/** * 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. */ void BLO_update_defaults_startup_blend(Main *bmain) { for (Scene *scene = bmain->scene.first; scene; scene = scene->id.next) { + BLI_strncpy(scene->view_render.engine_id, RE_engine_id_BLENDER_EEVEE, sizeof(scene->view_render.engine_id)); + scene->r.im_format.planes = R_IMF_PLANES_RGBA; scene->r.im_format.compress = 15; @@ -191,20 +224,18 @@ void BLO_update_defaults_startup_blend(Main *bmain) linestyle->chain_count = 10; } - for (bScreen *screen = bmain->screen.first; screen; screen = screen->id.next) { - ScrArea *area; - for (area = screen->areabase.first; area; area = area->next) { - SpaceLink *space_link; - ARegion *ar; + update_defaults_startup_workspaces(bmain); - for (space_link = area->spacedata.first; space_link; space_link = space_link->next) { + for (bScreen *screen = bmain->screen.first; screen; screen = screen->id.next) { + for (ScrArea *area = screen->areabase.first; area; area = area->next) { + for (SpaceLink *space_link = area->spacedata.first; space_link; space_link = space_link->next) { if (space_link->spacetype == SPACE_CLIP) { SpaceClip *space_clip = (SpaceClip *) space_link; space_clip->flag &= ~SC_MANUAL_CALIBRATION; } } - for (ar = area->regionbase.first; ar; ar = ar->next) { + for (ARegion *ar = area->regionbase.first; ar; ar = ar->next) { /* Remove all stored panels, we want to use defaults (order, open/closed) as defined by UI code here! */ BLI_freelistN(&ar->panels); diff --git a/source/blender/blenloader/intern/versioning_legacy.c b/source/blender/blenloader/intern/versioning_legacy.c index ad37679800b..44b8ec780e8 100644 --- a/source/blender/blenloader/intern/versioning_legacy.c +++ b/source/blender/blenloader/intern/versioning_legacy.c @@ -319,55 +319,6 @@ static void idproperties_fix_group_lengths(ListBase idlist) } } -static void alphasort_version_246(FileData *fd, Library *lib, Mesh *me) -{ - Material *ma; - MFace *mf; - MTFace *tf; - int a, b, texalpha; - - /* verify we have a tface layer */ - for (b = 0; b < me->fdata.totlayer; b++) - if (me->fdata.layers[b].type == CD_MTFACE) - break; - - if (b == me->fdata.totlayer) - return; - - /* if we do, set alpha sort if the game engine did it before */ - for (a = 0, mf = me->mface; a < me->totface; a++, mf++) { - if (mf->mat_nr < me->totcol) { - ma = blo_do_versions_newlibadr(fd, lib, me->mat[mf->mat_nr]); - texalpha = 0; - - /* we can't read from this if it comes from a library, - * because direct_link might not have happened on it, - * so ma->mtex is not pointing to valid memory yet */ - if (ma && ma->id.lib) - ma = NULL; - - for (b = 0; ma && b < MAX_MTEX; b++) - if (ma->mtex[b] && ma->mtex[b]->mapto & MAP_ALPHA) - texalpha = 1; - } - else { - ma = NULL; - texalpha = 0; - } - - for (b = 0; b < me->fdata.totlayer; b++) { - if (me->fdata.layers[b].type == CD_MTFACE) { - tf = ((MTFace*)me->fdata.layers[b].data) + a; - - tf->mode &= ~TF_ALPHASORT; - if (ma && (ma->mode & MA_ZTRANSP)) - if (ELEM(tf->transp, TF_ALPHA, TF_ADD) || (texalpha && (tf->transp != TF_CLIP))) - tf->mode |= TF_ALPHASORT; - } - } - } -} - static void customdata_version_242(Mesh *me) { CustomDataLayer *layer; @@ -403,13 +354,6 @@ static void customdata_version_242(Mesh *me) for (a = 0; a < me->totface; a++, mtf++, tf++, mcol += 4) { memcpy(mcol, tf->col, sizeof(tf->col)); memcpy(mtf->uv, tf->uv, sizeof(tf->uv)); - - mtf->flag = tf->flag; - mtf->unwrap = tf->unwrap; - mtf->mode = tf->mode; - mtf->tile = tf->tile; - mtf->tpage = tf->tpage; - mtf->transp = tf->transp; } MEM_freeN(me->tface); @@ -916,23 +860,6 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main) } } - if (main->versionfile <= 196) { - Mesh *me = main->mesh.first; - int a, b; - while (me) { - if (me->tface) { - TFace *tface = me->tface; - for (a = 0; a < me->totface; a++, tface++) { - for (b = 0; b < 4; b++) { - tface->mode |= TF_DYNAMIC; - tface->mode &= ~TF_INVISIBLE; - } - } - } - me = me->id.next; - } - } - if (main->versionfile <= 200) { Object *ob = main->object.first; while (ob) { @@ -2529,13 +2456,8 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main) for (sa = sc->areabase.first; sa; sa = sa->next) { SpaceLink *sl; for (sl = sa->spacedata.first; sl; sl = sl->next) { - if (sl->spacetype == SPACE_IMAGE) + if (sl->spacetype == SPACE_IMAGE) { ((SpaceImage *)sl)->iuser.fie_ima = 2; - else if (sl->spacetype == SPACE_VIEW3D) { - View3D *v3d = (View3D *)sl; - BGpic *bgpic; - for (bgpic = v3d->bgpicbase.first; bgpic; bgpic = bgpic->next) - bgpic->iuser.fie_ima = 2; } } } @@ -3290,14 +3212,6 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main) } } - - if (main->versionfile < 246 || (main->versionfile == 246 && main->subversionfile < 1)) { - Mesh *me; - - for (me = main->mesh.first; me; me = me->id.next) - alphasort_version_246(fd, lib, me); - } - if (main->versionfile < 246 || (main->versionfile == 246 && main->subversionfile < 1)) { Object *ob; for (ob = main->object.first; ob; ob = ob->id.next) { diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index 2648ebdc395..da41433f6bc 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -102,6 +102,10 @@ /* allow writefile to use deprecated functionality (for forward compatibility code) */ #define DNA_DEPRECATED_ALLOW +/* Allow using DNA struct members that are marked as private for read/write. + * Note: Each header that uses this needs to define its own way of handling + * it. There's no generic implementation, direct use does nothing. */ +#define DNA_PRIVATE_READ_WRITE_ALLOW #include "DNA_anim_types.h" #include "DNA_armature_types.h" @@ -120,6 +124,7 @@ #include "DNA_key_types.h" #include "DNA_lattice_types.h" #include "DNA_lamp_types.h" +#include "DNA_layer_types.h" #include "DNA_linestyle_types.h" #include "DNA_meta_types.h" #include "DNA_mesh_types.h" @@ -130,6 +135,7 @@ #include "DNA_object_force.h" #include "DNA_packedFile_types.h" #include "DNA_particle_types.h" +#include "DNA_lightprobe_types.h" #include "DNA_property_types.h" #include "DNA_rigidbody_types.h" #include "DNA_scene_types.h" @@ -146,6 +152,7 @@ #include "DNA_vfont_types.h" #include "DNA_world_types.h" #include "DNA_windowmanager_types.h" +#include "DNA_workspace_types.h" #include "DNA_movieclip_types.h" #include "DNA_mask_types.h" @@ -172,6 +179,7 @@ #include "BKE_fcurve.h" #include "BKE_pointcache.h" #include "BKE_mesh.h" +#include "BKE_workspace.h" #ifdef USE_NODE_COMPAT_CUSTOMNODES #include "NOD_socket.h" /* for sock->default_value data */ @@ -1076,10 +1084,13 @@ static void write_nodetree_nolib(WriteData *wd, bNodeTree *ntree) * Take care using 'use_active_win', since we wont want the currently active window * to change which scene renders (currently only used for undo). */ -static void current_screen_compat(Main *mainvar, bScreen **r_screen, bool use_active_win) +static void current_screen_compat( + Main *mainvar, bool use_active_win, + bScreen **r_screen, Scene **r_scene, SceneLayer **r_render_layer) { wmWindowManager *wm; wmWindow *window = NULL; + WorkSpace *workspace; /* find a global current screen in the first open window, to have * a reasonable default for reading in older versions */ @@ -1103,8 +1114,11 @@ static void current_screen_compat(Main *mainvar, bScreen **r_screen, bool use_ac window = wm->windows.first; } } + workspace = (window) ? BKE_workspace_active_get(window->workspace_hook) : NULL; - *r_screen = (window) ? window->screen : NULL; + *r_screen = (window) ? BKE_workspace_active_screen_get(window->workspace_hook) : NULL; + *r_scene = (window) ? window->scene : NULL; + *r_render_layer = (window) ? BKE_workspace_render_layer_get(workspace) : NULL; } typedef struct RenderInfo { @@ -1120,13 +1134,11 @@ static void write_renderinfo(WriteData *wd, Main *mainvar) { bScreen *curscreen; Scene *sce, *curscene = NULL; + SceneLayer *render_layer; RenderInfo data; /* XXX in future, handle multiple windows with multiple screens? */ - current_screen_compat(mainvar, &curscreen, false); - if (curscreen) { - curscene = curscreen->scene; - } + current_screen_compat(mainvar, false, &curscreen, &curscene, &render_layer); for (sce = mainvar->scene.first; sce; sce = sce->id.next) { if (sce->id.lib == NULL && (sce == curscene || (sce->r.scemode & R_BG_RENDER))) { @@ -1687,6 +1699,13 @@ static void write_defgroups(WriteData *wd, ListBase *defbase) } } +static void write_fmaps(WriteData *wd, ListBase *fbase) +{ + for (bFaceMap *fmap = fbase->first; fmap; fmap = fmap->next) { + writestruct(wd, DATA, bFaceMap, 1, fmap); + } +} + static void write_modifiers(WriteData *wd, ListBase *modbase) { ModifierData *md; @@ -1724,6 +1743,8 @@ static void write_modifiers(WriteData *wd, ListBase *modbase) SmokeModifierData *smd = (SmokeModifierData *)md; if (smd->type & MOD_SMOKE_TYPE_DOMAIN) { + writestruct(wd, DATA, SmokeDomainSettings, 1, smd->domain); + if (smd->domain) { write_pointcaches(wd, &(smd->domain->ptcaches[0])); @@ -1737,11 +1758,8 @@ static void write_modifiers(WriteData *wd, ListBase *modbase) if (smd->domain->coba) { writestruct(wd, DATA, ColorBand, 1, smd->domain->coba); } - } - writestruct(wd, DATA, SmokeDomainSettings, 1, smd->domain); - if (smd->domain) { /* cleanup the fake pointcache */ BKE_ptcache_free_list(&smd->domain->ptcaches[1]); smd->domain->point_cache[1] = NULL; @@ -1891,6 +1909,7 @@ static void write_object(WriteData *wd, Object *ob) write_pose(wd, ob->pose); write_defgroups(wd, &ob->defbase); + write_fmaps(wd, &ob->fmaps); write_constraints(wd, &ob->constraints); write_motionpath(wd, ob->mpath); @@ -1973,6 +1992,10 @@ static void write_camera(WriteData *wd, Camera *cam) if (cam->adt) { write_animdata(wd, cam->adt); } + + for (CameraBGImage *bgpic = cam->bg_images.first; bgpic; bgpic = bgpic->next) { + writestruct(wd, DATA, CameraBGImage, 1, bgpic); + } } } @@ -2123,6 +2146,10 @@ static void write_customdata( else if (layer->type == CD_GRID_PAINT_MASK) { write_grid_paint_mask(wd, count, layer->data); } + else if (layer->type == CD_FACEMAP) { + const int *layer_data = layer->data; + writedata(wd, DATA, sizeof(*layer_data) * count, layer_data); + } else { CustomData_file_write_info(layer->type, &structname, &structnum); if (structnum) { @@ -2537,6 +2564,34 @@ static void write_paint(WriteData *wd, Paint *p) } } +static void write_scene_collection(WriteData *wd, SceneCollection *sc) +{ + writestruct(wd, DATA, SceneCollection, 1, sc); + + writelist(wd, DATA, LinkData, &sc->objects); + writelist(wd, DATA, LinkData, &sc->filter_objects); + + for (SceneCollection *nsc = sc->scene_collections.first; nsc; nsc = nsc->next) { + write_scene_collection(wd, nsc); + } +} + +static void write_layer_collections(WriteData *wd, ListBase *lb) +{ + for (LayerCollection *lc = lb->first; lc; lc = lc->next) { + writestruct(wd, DATA, LayerCollection, 1, lc); + + writelist(wd, DATA, LinkData, &lc->object_bases); + writelist(wd, DATA, CollectionOverride, &lc->overrides); + + if (lc->properties) { + IDP_WriteProperty(lc->properties, wd); + } + + write_layer_collections(wd, &lc->layer_collections); + } +} + static void write_scene(WriteData *wd, Scene *sce) { /* write LibData */ @@ -2549,8 +2604,8 @@ static void write_scene(WriteData *wd, Scene *sce) write_keyingsets(wd, &sce->keyingsets); /* direct data */ - for (Base *base = sce->base.first; base; base = base->next) { - writestruct(wd, DATA, Base, 1, base); + for (BaseLegacy *base = sce->base.first; base; base = base->next) { + writestruct(wd, DATA, BaseLegacy, 1, base); } ToolSettings *tos = sce->toolsettings; @@ -2697,11 +2752,6 @@ static void write_scene(WriteData *wd, Scene *sce) 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) { - writestruct(wd, DATA, TransformOrientation, 1, ts); - } - for (SceneRenderLayer *srl = sce->r.layers.first; srl; srl = srl->next) { writestruct(wd, DATA, SceneRenderLayer, 1, srl); if (srl->prop) { @@ -2736,6 +2786,24 @@ static void write_scene(WriteData *wd, Scene *sce) write_previews(wd, sce->preview); write_curvemapping_curves(wd, &sce->r.mblur_shutter_curve); + write_scene_collection(wd, sce->collection); + + for (SceneLayer *sl = sce->render_layers.first; sl; sl = sl->next) { + writestruct(wd, DATA, SceneLayer, 1, sl); + writelist(wd, DATA, Base, &sl->object_bases); + if (sl->properties) { + IDP_WriteProperty(sl->properties, wd); + } + write_layer_collections(wd, &sl->layer_collections); + } + + if (sce->layer_properties) { + IDP_WriteProperty(sce->layer_properties, wd); + } + + if (sce->collection_properties) { + IDP_WriteProperty(sce->collection_properties, wd); + } } static void write_gpencil(WriteData *wd, bGPdata *gpd) @@ -2777,8 +2845,19 @@ static void write_windowmanager(WriteData *wd, wmWindowManager *wm) write_iddata(wd, &wm->id); for (wmWindow *win = wm->windows.first; win; win = win->next) { + + /* update deprecated screen member (for so loading in 2.7x uses the correct screen) */ + win->screen = BKE_workspace_active_screen_get(win->workspace_hook); + if (win->screen) { + BLI_strncpy(win->screenname, win->screen->id.name + 2, sizeof(win->screenname)); + } + writestruct(wd, DATA, wmWindow, 1, win); + writestruct(wd, DATA, WorkSpaceInstanceHook, 1, win->workspace_hook); writestruct(wd, DATA, Stereo3dFormat, 1, win->stereo3d_format); + + /* data is written, clear deprecated data again */ + win->screen = NULL; } } @@ -2869,6 +2948,8 @@ static void write_screen(WriteData *wd, bScreen *sc) writestruct(wd, ID_SCRN, bScreen, 1, sc); write_iddata(wd, &sc->id); + write_previews(wd, sc->preview); + /* direct data */ for (ScrVert *sv = sc->vertbase.first; sv; sv = sv->next) { writestruct(wd, DATA, ScrVert, 1, sv); @@ -2915,11 +2996,8 @@ static void write_screen(WriteData *wd, bScreen *sc) if (sl->spacetype == SPACE_VIEW3D) { View3D *v3d = (View3D *)sl; - BGpic *bgpic; writestruct(wd, DATA, View3D, 1, v3d); - for (bgpic = v3d->bgpicbase.first; bgpic; bgpic = bgpic->next) { - writestruct(wd, DATA, BGpic, 1, bgpic); - } + if (v3d->localvd) { writestruct(wd, DATA, View3D, 1, v3d->localvd); } @@ -3117,6 +3195,19 @@ static void write_sound(WriteData *wd, bSound *sound) } } +static void write_probe(WriteData *wd, LightProbe *prb) +{ + if (prb->id.us > 0 || wd->current) { + /* write LibData */ + writestruct(wd, ID_LP, LightProbe, 1, prb); + write_iddata(wd, &prb->id); + + if (prb->adt) { + write_animdata(wd, prb->adt); + } + } +} + static void write_group(WriteData *wd, Group *group) { if (group->id.us > 0 || wd->current) { @@ -3662,6 +3753,17 @@ static void write_cachefile(WriteData *wd, CacheFile *cache_file) } } +static void write_workspace(WriteData *wd, WorkSpace *workspace) +{ + ListBase *layouts = BKE_workspace_layouts_get(workspace); + ListBase *transform_orientations = BKE_workspace_transform_orientations_get(workspace); + + writestruct(wd, ID_WS, WorkSpace, 1, workspace); + writelist(wd, DATA, WorkSpaceLayout, layouts); + writelist(wd, DATA, WorkSpaceDataRelation, &workspace->hook_layout_relations); + writelist(wd, DATA, TransformOrientation, transform_orientations); +} + /* Keep it last of write_foodata functions. */ static void write_libraries(WriteData *wd, Main *main) { @@ -3731,6 +3833,8 @@ static void write_global(WriteData *wd, int fileflags, Main *mainvar) const bool is_undo = (wd->current != NULL); FileGlobal fg; bScreen *screen; + Scene *scene; + SceneLayer *render_layer; char subvstr[8]; /* prevent mem checkers from complaining */ @@ -3738,11 +3842,12 @@ static void write_global(WriteData *wd, int fileflags, Main *mainvar) memset(fg.filename, 0, sizeof(fg.filename)); memset(fg.build_hash, 0, sizeof(fg.build_hash)); - current_screen_compat(mainvar, &screen, is_undo); + current_screen_compat(mainvar, is_undo, &screen, &scene, &render_layer); /* XXX still remap G */ fg.curscreen = screen; - fg.curscene = screen ? screen->scene : NULL; + fg.curscene = scene; + fg.cur_render_layer = render_layer; /* prevent to save this, is not good convention, and feature with concerns... */ fg.fileflags = (fileflags & ~G_FILE_FLAGS_RUNTIME); @@ -3841,6 +3946,9 @@ static bool write_file_handle( case ID_WM: write_windowmanager(wd, (wmWindowManager *)id); break; + case ID_WS: + write_workspace(wd, (WorkSpace *)id); + break; case ID_SCR: write_screen(wd, (bScreen *)id); break; @@ -3886,6 +3994,9 @@ static bool write_file_handle( case ID_SPK: write_speaker(wd, (Speaker *)id); break; + case ID_LP: + write_probe(wd, (LightProbe *)id); + break; case ID_SO: write_sound(wd, (bSound *)id); break; |