Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/blenloader/intern/readfile.c')
-rw-r--r--source/blender/blenloader/intern/readfile.c2877
1 files changed, 1451 insertions, 1426 deletions
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index c57817c275a..aa7c48f4873 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -54,15 +54,17 @@
/* 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"
-#include "DNA_actuator_types.h"
#include "DNA_brush_types.h"
#include "DNA_camera_types.h"
#include "DNA_cachefile_types.h"
#include "DNA_cloth_types.h"
-#include "DNA_controller_types.h"
#include "DNA_constraint_types.h"
#include "DNA_dynamicpaint_types.h"
#include "DNA_effect_types.h"
@@ -73,6 +75,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"
@@ -85,12 +88,11 @@
#include "DNA_object_types.h"
#include "DNA_packedFile_types.h"
#include "DNA_particle_types.h"
-#include "DNA_property_types.h"
+#include "DNA_lightprobe_types.h"
#include "DNA_rigidbody_types.h"
#include "DNA_text_types.h"
#include "DNA_view3d_types.h"
#include "DNA_screen_types.h"
-#include "DNA_sensor_types.h"
#include "DNA_sdna_types.h"
#include "DNA_scene_types.h"
#include "DNA_sequence_types.h"
@@ -99,10 +101,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"
@@ -118,22 +123,24 @@
#include "BKE_brush.h"
#include "BKE_cachefile.h"
#include "BKE_cloth.h"
+#include "BKE_collection.h"
#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_override.h"
#include "BKE_library_query.h"
#include "BKE_idcode.h"
#include "BKE_idprop.h"
#include "BKE_material.h"
#include "BKE_main.h" // for Main
#include "BKE_mesh.h" // for ME_ defines (patching)
+#include "BKE_mesh_runtime.h"
#include "BKE_modifier.h"
#include "BKE_multires.h"
#include "BKE_node.h" // for tree type defines
@@ -142,13 +149,15 @@
#include "BKE_particle.h"
#include "BKE_pointcache.h"
#include "BKE_report.h"
-#include "BKE_sca.h" // for init_actuator
#include "BKE_scene.h"
#include "BKE_screen.h"
#include "BKE_sequencer.h"
#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"
@@ -248,10 +257,13 @@ 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);
+#ifdef USE_COLLECTION_COMPAT_28
+static void expand_scene_collection(FileData *fd, Main *mainvar, SceneCollection *sc);
+#endif
+
/* this function ensures that reports are printed,
* in the case of libraray linking errors this is important!
*
@@ -1634,9 +1646,9 @@ void blo_make_image_pointer_map(FileData *fd, Main *oldmain)
oldnewmap_insert(fd->imamap, ima->gputexture[a], ima->gputexture[a], 0);
if (ima->rr)
oldnewmap_insert(fd->imamap, ima->rr, ima->rr, 0);
- for (a=0; a < IMA_MAX_RENDER_SLOT; a++)
- if (ima->renders[a])
- oldnewmap_insert(fd->imamap, ima->renders[a], ima->renders[a], 0);
+ LISTBASE_FOREACH(RenderSlot *, slot, &ima->renderslots)
+ if (slot->render)
+ oldnewmap_insert(fd->imamap, slot->render, slot->render, 0);
}
for (; sce; sce = sce->id.next) {
if (sce->nodetree && sce->nodetree->previews) {
@@ -1669,13 +1681,12 @@ void blo_end_image_pointer_map(FileData *fd, Main *oldmain)
if (ima->cache == NULL) {
ima->tpageflag &= ~IMA_GLBIND_IS_DATA;
for (i = 0; i < TEXTARGET_COUNT; i++) {
- ima->bindcode[i] = 0;
ima->gputexture[i] = NULL;
}
ima->rr = NULL;
}
- for (i = 0; i < IMA_MAX_RENDER_SLOT; i++)
- ima->renders[i] = newimaadr(fd, ima->renders[i]);
+ LISTBASE_FOREACH(RenderSlot *, slot, &ima->renderslots)
+ slot->render = newimaadr(fd, slot->render);
for (i = 0; i < TEXTARGET_COUNT; i++)
ima->gputexture[i] = newimaadr(fd, ima->gputexture[i]);
@@ -2234,6 +2245,42 @@ static PreviewImage *direct_link_preview_image(FileData *fd, PreviewImage *old_p
/* ************ READ ID *************** */
+static void lib_link_id(FileData *fd, Main *main)
+{
+ ListBase *lbarray[MAX_LIBARRAY];
+ int base_count, i;
+
+ base_count = set_listbasepointers(main, lbarray);
+
+ for (i = 0; i < base_count; i++) {
+ ListBase *lb = lbarray[i];
+ ID *id;
+
+ for (id = lb->first; id; id = id->next) {
+ if (id->override_static) {
+ id->override_static->reference = newlibadr_us(fd, id->lib, id->override_static->reference);
+ id->override_static->storage = newlibadr_us(fd, id->lib, id->override_static->storage);
+ }
+ }
+ }
+}
+
+static void direct_link_id_override_property_operation_cb(FileData *fd, void *data)
+{
+ IDOverrideStaticPropertyOperation *opop = data;
+
+ opop->subitem_reference_name = newdataadr(fd, opop->subitem_reference_name);
+ opop->subitem_local_name = newdataadr(fd, opop->subitem_local_name);
+}
+
+static void direct_link_id_override_property_cb(FileData *fd, void *data)
+{
+ IDOverrideStaticProperty *op = data;
+
+ op->rna_path = newdataadr(fd, op->rna_path);
+ link_list_ex(fd, &op->operations, direct_link_id_override_property_operation_cb);
+}
+
static void direct_link_id(FileData *fd, ID *id)
{
/*link direct data of ID properties*/
@@ -2247,6 +2294,12 @@ static void direct_link_id(FileData *fd, ID *id)
/* That way datablock reading not going through main read_libblock() function are still in a clear tag state.
* (glowering at certain nodetree fake datablock here...). */
id->tag = 0;
+
+ /* Link direct data of overrides. */
+ if (id->override_static) {
+ id->override_static = newdataadr(fd, id->override_static);
+ link_list_ex(fd, &id->override_static->properties, direct_link_id_override_property_cb);
+ }
}
/* ************ READ CurveMapping *************** */
@@ -2766,6 +2819,7 @@ static void direct_link_animdata(FileData *fd, AnimData *adt)
/* link drivers */
link_list(fd, &adt->drivers);
direct_link_fcurves(fd, &adt->drivers);
+ adt->driver_array = NULL;
/* link overrides */
// TODO...
@@ -2810,6 +2864,97 @@ static void direct_link_cachefile(FileData *fd, CacheFile *cache_file)
direct_link_animdata(fd, cache_file->adt);
}
+/* ************ READ WORKSPACES *************** */
+
+static void lib_link_workspace_scene_data(FileData *fd, WorkSpace *workspace)
+{
+ for (WorkSpaceSceneRelation *relation = workspace->scene_layer_relations.first;
+ relation != NULL;
+ relation = relation->next)
+ {
+ relation->scene = newlibadr(fd, workspace->id.lib, relation->scene);
+ }
+
+ /* Free any relations that got lost due to missing datablocks. */
+ BKE_workspace_scene_relations_free_invalid(workspace);
+}
+
+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);
+
+ lib_link_workspace_scene_data(fd, workspace);
+
+ 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(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, &workspace->scene_layer_relations);
+ link_list(fd, &workspace->owner_ids);
+ link_list(fd, &workspace->tools);
+
+ 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);
+ }
+
+ /* 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);
+ }
+ }
+ }
+
+ for (bToolRef *tref = workspace->tools.first; tref; tref = tref->next) {
+ tref->runtime = NULL;
+ tref->properties = newdataadr(fd, tref->properties);
+ IDP_DirectLinkGroup_OrFree(&tref->properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
+ }
+}
+
+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 */
@@ -2821,6 +2966,10 @@ static void direct_link_motionpath(FileData *fd, bMotionPath *mpath)
/* relink points cache */
mpath->points = newdataadr(fd, mpath->points);
+
+ mpath->points_vbo = NULL;
+ mpath->batch_line = NULL;
+ mpath->batch_points = NULL;
}
/* ************ READ NODE TREE *************** */
@@ -3260,6 +3409,11 @@ static void lib_link_constraints(FileData *fd, ID *id, ListBase *conlist)
}
/* own ipo, all constraints have it */
con->ipo = newlibadr_us(fd, id->lib, con->ipo); // XXX deprecated - old animation system
+
+ /* If linking from a library, clear 'local' static override flag. */
+ if (id->lib != NULL) {
+ con->flag &= ~CONSTRAINT_STATICOVERRIDE_LOCAL;
+ }
}
/* relink all ID-blocks used by the constraints */
@@ -3377,7 +3531,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);
}
}
@@ -3429,7 +3583,6 @@ static void direct_link_armature(FileData *fd, bArmature *arm)
link_list(fd, &arm->bonebase);
arm->edbo = NULL;
- arm->sketch = NULL;
arm->adt = newdataadr(fd, arm->adt);
direct_link_animdata(fd, arm->adt);
@@ -3455,6 +3608,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;
}
}
@@ -3464,6 +3622,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;
+ }
}
@@ -3476,14 +3640,6 @@ static void lib_link_lamp(FileData *fd, Main *main)
IDP_LibLinkProperty(la->id.properties, fd);
lib_link_animdata(fd, &la->id, la->adt);
- for (int a = 0; a < MAX_MTEX; a++) {
- MTex *mtex = la->mtex[a];
- if (mtex) {
- mtex->tex = newlibadr_us(fd, la->id.lib, mtex->tex);
- mtex->object = newlibadr(fd, la->id.lib, mtex->object);
- }
- }
-
la->ipo = newlibadr_us(fd, la->id.lib, la->ipo); // XXX deprecated - old animation system
if (la->nodetree) {
@@ -3498,15 +3654,9 @@ static void lib_link_lamp(FileData *fd, Main *main)
static void direct_link_lamp(FileData *fd, Lamp *la)
{
- int a;
-
la->adt = newdataadr(fd, la->adt);
direct_link_animdata(fd, la->adt);
- for (a=0; a<MAX_MTEX; a++) {
- la->mtex[a] = newdataadr(fd, la->mtex[a]);
- }
-
la->curfalloff = newdataadr(fd, la->curfalloff);
if (la->curfalloff)
direct_link_curvemapping(fd, la->curfalloff);
@@ -3631,6 +3781,7 @@ static void direct_link_mball(FileData *fd, MetaBall *mb)
mb->editelems = NULL;
/* mb->edit_elems.first= mb->edit_elems.last= NULL;*/
mb->lastelem = NULL;
+ mb->batch_cache = NULL;
}
/* ************ READ WORLD ***************** */
@@ -3644,14 +3795,6 @@ static void lib_link_world(FileData *fd, Main *main)
wrld->ipo = newlibadr_us(fd, wrld->id.lib, wrld->ipo); // XXX deprecated - old animation system
- for (int a = 0; a < MAX_MTEX; a++) {
- MTex *mtex = wrld->mtex[a];
- if (mtex) {
- mtex->tex = newlibadr_us(fd, wrld->id.lib, mtex->tex);
- mtex->object = newlibadr(fd, wrld->id.lib, mtex->object);
- }
- }
-
if (wrld->nodetree) {
lib_link_ntree(fd, &wrld->id, wrld->nodetree);
wrld->nodetree->id.lib = wrld->id.lib;
@@ -3664,15 +3807,9 @@ static void lib_link_world(FileData *fd, Main *main)
static void direct_link_world(FileData *fd, World *wrld)
{
- int a;
-
wrld->adt = newdataadr(fd, wrld->adt);
direct_link_animdata(fd, wrld->adt);
- for (a = 0; a < MAX_MTEX; a++) {
- wrld->mtex[a] = newdataadr(fd, wrld->mtex[a]);
- }
-
wrld->nodetree = newdataadr(fd, wrld->nodetree);
if (wrld->nodetree) {
direct_link_id(fd, &wrld->nodetree->id);
@@ -3779,23 +3916,22 @@ static void direct_link_image(FileData *fd, Image *ima)
if (!ima->cache) {
ima->tpageflag &= ~IMA_GLBIND_IS_DATA;
for (int i = 0; i < TEXTARGET_COUNT; i++) {
- ima->bindcode[i] = 0;
ima->gputexture[i] = NULL;
}
ima->rr = NULL;
}
- ima->repbind = NULL;
-
/* undo system, try to restore render buffers */
+ link_list(fd, &(ima->renderslots));
if (fd->imamap) {
- int a;
-
- for (a = 0; a < IMA_MAX_RENDER_SLOT; a++)
- ima->renders[a] = newimaadr(fd, ima->renders[a]);
+ LISTBASE_FOREACH(RenderSlot *, slot, &ima->renderslots) {
+ slot->render = newimaadr(fd, slot->render);
+ }
}
else {
- memset(ima->renders, 0, sizeof(ima->renders));
+ LISTBASE_FOREACH(RenderSlot *, slot, &ima->renderslots) {
+ slot->render = NULL;
+ }
ima->last_render_slot = ima->render_slot;
}
@@ -3899,6 +4035,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);
@@ -3925,14 +4062,6 @@ static void lib_link_texture(FileData *fd, Main *main)
tex->ima = newlibadr_us(fd, tex->id.lib, tex->ima);
tex->ipo = newlibadr_us(fd, tex->id.lib, tex->ipo); // XXX deprecated - old animation system
- if (tex->env)
- tex->env->object = newlibadr(fd, tex->id.lib, tex->env->object);
- if (tex->pd)
- tex->pd->object = newlibadr(fd, tex->id.lib, tex->pd->object);
- if (tex->vd)
- tex->vd->object = newlibadr(fd, tex->id.lib, tex->vd->object);
- if (tex->ot)
- tex->ot->object = newlibadr(fd, tex->id.lib, tex->ot->object);
if (tex->nodetree) {
lib_link_ntree(fd, &tex->id, tex->nodetree);
@@ -3950,34 +4079,6 @@ static void direct_link_texture(FileData *fd, Tex *tex)
direct_link_animdata(fd, tex->adt);
tex->coba = newdataadr(fd, tex->coba);
- tex->env = newdataadr(fd, tex->env);
- if (tex->env) {
- tex->env->ima = NULL;
- memset(tex->env->cube, 0, 6 * sizeof(void *));
- tex->env->ok= 0;
- }
- tex->pd = newdataadr(fd, tex->pd);
- if (tex->pd) {
- tex->pd->point_tree = NULL;
- tex->pd->coba = newdataadr(fd, tex->pd->coba);
- tex->pd->falloff_curve = newdataadr(fd, tex->pd->falloff_curve);
- if (tex->pd->falloff_curve) {
- direct_link_curvemapping(fd, tex->pd->falloff_curve);
- }
- tex->pd->point_data = NULL; /* runtime data */
- }
-
- tex->vd = newdataadr(fd, tex->vd);
- if (tex->vd) {
- tex->vd->dataset = NULL;
- tex->vd->ok = 0;
- }
- else {
- if (tex->type == TEX_VOXELDATA)
- tex->vd = MEM_callocN(sizeof(VoxelData), "direct_link_texture VoxelData");
- }
-
- tex->ot = newdataadr(fd, tex->ot);
tex->nodetree = newdataadr(fd, tex->nodetree);
if (tex->nodetree) {
@@ -4002,15 +4103,6 @@ static void lib_link_material(FileData *fd, Main *main)
lib_link_animdata(fd, &ma->id, ma->adt);
ma->ipo = newlibadr_us(fd, ma->id.lib, ma->ipo); // XXX deprecated - old animation system
- ma->group = newlibadr_us(fd, ma->id.lib, ma->group);
-
- for (int a = 0; a < MAX_MTEX; a++) {
- MTex *mtex = ma->mtex[a];
- if (mtex) {
- mtex->tex = newlibadr_us(fd, ma->id.lib, mtex->tex);
- mtex->object = newlibadr(fd, ma->id.lib, mtex->object);
- }
- }
if (ma->nodetree) {
lib_link_ntree(fd, &ma->id, ma->nodetree);
@@ -4024,19 +4116,11 @@ static void lib_link_material(FileData *fd, Main *main)
static void direct_link_material(FileData *fd, Material *ma)
{
- int a;
-
ma->adt = newdataadr(fd, ma->adt);
direct_link_animdata(fd, ma->adt);
- for (a = 0; a < MAX_MTEX; a++) {
- ma->mtex[a] = newdataadr(fd, ma->mtex[a]);
- }
ma->texpaintslot = NULL;
- ma->ramp_col = newdataadr(fd, ma->ramp_col);
- ma->ramp_spec = newdataadr(fd, ma->ramp_spec);
-
ma->nodetree = newdataadr(fd, ma->nodetree);
if (ma->nodetree) {
direct_link_id(fd, &ma->nodetree->id);
@@ -4380,7 +4464,6 @@ static void direct_link_particlesystems(FileData *fd, ListBase *particles)
BLI_listbase_clear(&psys->pathcachebufs);
BLI_listbase_clear(&psys->childcachebufs);
psys->pdd = NULL;
- psys->renderdata = NULL;
if (psys->clmd) {
psys->clmd = newdataadr(fd, psys->clmd);
@@ -4396,7 +4479,7 @@ static void direct_link_particlesystems(FileData *fd, ListBase *particles)
psys->clmd->sim_parms->presets = 0;
}
- psys->hair_in_dm = psys->hair_out_dm = NULL;
+ psys->hair_in_mesh = psys->hair_out_mesh = NULL;
psys->clmd->solver_result = NULL;
}
@@ -4407,55 +4490,15 @@ static void direct_link_particlesystems(FileData *fd, ListBase *particles)
psys->tree = NULL;
psys->bvhtree = NULL;
+
+ psys->orig_psys = 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;
@@ -4482,19 +4525,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*/
@@ -4650,7 +4683,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 */
@@ -4669,18 +4701,13 @@ static void direct_link_mesh(FileData *fd, Mesh *mesh)
mesh->bb = NULL;
mesh->edit_btmesh = NULL;
+ BKE_mesh_runtime_reset(mesh);
/* 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) {
@@ -4760,6 +4787,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);
@@ -4781,6 +4809,14 @@ static void lib_link_modifiers__linkModifiers(
static void lib_link_modifiers(FileData *fd, Object *ob)
{
modifiers_foreachIDLink(ob, lib_link_modifiers__linkModifiers, fd);
+
+ /* If linking from a library, clear 'local' static override flag. */
+ if (ob->id.lib != NULL) {
+ for (ModifierData *mod = ob->modifiers.first; mod != NULL; mod = mod->next) {
+ mod->flag &= ~eModifierFlag_StaticOverride_Local;
+ }
+ }
+
}
static void lib_link_object(FileData *fd, Main *main)
@@ -4802,7 +4838,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_DUPLICOLLECTION;
+ }
ob->proxy = newlibadr_us(fd, ob->id.lib, ob->proxy);
if (ob->proxy) {
@@ -4865,7 +4909,6 @@ static void lib_link_object(FileData *fd, Main *main)
}
ob->gpd = newlibadr_us(fd, ob->id.lib, ob->gpd);
- ob->duplilist = NULL;
ob->id.tag &= ~LIB_TAG_NEED_LINK;
/* if id.us==0 a new base will be created later on */
@@ -4885,143 +4928,6 @@ static void lib_link_object(FileData *fd, Main *main)
}
}
- for (bSensor *sens = ob->sensors.first; sens; sens = sens->next) {
- for (a = 0; a < sens->totlinks; a++)
- sens->links[a] = newglobadr(fd, sens->links[a]);
-
- if (sens->type == SENS_MESSAGE) {
- bMessageSensor *ms = sens->data;
- ms->fromObject =
- newlibadr(fd, ob->id.lib, ms->fromObject);
- }
- }
-
- for (bController *cont = ob->controllers.first; cont; cont = cont->next) {
- for (a=0; a < cont->totlinks; a++)
- cont->links[a] = newglobadr(fd, cont->links[a]);
-
- if (cont->type == CONT_PYTHON) {
- bPythonCont *pc = cont->data;
- pc->text = newlibadr(fd, ob->id.lib, pc->text);
- }
- cont->slinks = NULL;
- cont->totslinks = 0;
- }
-
- for (bActuator *act = ob->actuators.first; act; act = act->next) {
- switch (act->type) {
- case ACT_SOUND:
- {
- bSoundActuator *sa = act->data;
- sa->sound = newlibadr_us(fd, ob->id.lib, sa->sound);
- break;
- }
- case ACT_GAME:
- /* bGameActuator *ga= act->data; */
- break;
- case ACT_CAMERA:
- {
- bCameraActuator *ca = act->data;
- ca->ob = newlibadr(fd, ob->id.lib, ca->ob);
- break;
- }
- /* leave this one, it's obsolete but necessary to read for conversion */
- case ACT_ADD_OBJECT:
- {
- bAddObjectActuator *eoa = act->data;
- if (eoa)
- eoa->ob = newlibadr(fd, ob->id.lib, eoa->ob);
- break;
- }
- case ACT_OBJECT:
- {
- bObjectActuator *oa = act->data;
- if (oa == NULL) {
- init_actuator(act);
- }
- else {
- oa->reference = newlibadr(fd, ob->id.lib, oa->reference);
- }
- break;
- }
- case ACT_EDIT_OBJECT:
- {
- bEditObjectActuator *eoa = act->data;
- if (eoa == NULL) {
- init_actuator(act);
- }
- else {
- eoa->ob = newlibadr(fd, ob->id.lib, eoa->ob);
- eoa->me = newlibadr(fd, ob->id.lib, eoa->me);
- }
- break;
- }
- case ACT_SCENE:
- {
- bSceneActuator *sa = act->data;
- sa->camera = newlibadr(fd, ob->id.lib, sa->camera);
- sa->scene = newlibadr(fd, ob->id.lib, sa->scene);
- break;
- }
- case ACT_ACTION:
- {
- bActionActuator *aa = act->data;
- aa->act = newlibadr_us(fd, ob->id.lib, aa->act);
- break;
- }
- case ACT_SHAPEACTION:
- {
- bActionActuator *aa = act->data;
- aa->act = newlibadr_us(fd, ob->id.lib, aa->act);
- break;
- }
- case ACT_PROPERTY:
- {
- bPropertyActuator *pa = act->data;
- pa->ob = newlibadr(fd, ob->id.lib, pa->ob);
- break;
- }
- case ACT_MESSAGE:
- {
- bMessageActuator *ma = act->data;
- ma->toObject = newlibadr(fd, ob->id.lib, ma->toObject);
- break;
- }
- case ACT_2DFILTER:
- {
- bTwoDFilterActuator *_2dfa = act->data;
- _2dfa->text = newlibadr(fd, ob->id.lib, _2dfa->text);
- break;
- }
- case ACT_PARENT:
- {
- bParentActuator *parenta = act->data;
- parenta->ob = newlibadr(fd, ob->id.lib, parenta->ob);
- break;
- }
- case ACT_STATE:
- /* bStateActuator *statea = act->data; */
- break;
- case ACT_ARMATURE:
- {
- bArmatureActuator *arma= act->data;
- arma->target = newlibadr(fd, ob->id.lib, arma->target);
- arma->subtarget = newlibadr(fd, ob->id.lib, arma->subtarget);
- break;
- }
- case ACT_STEERING:
- {
- bSteeringActuator *steeringa = act->data;
- steeringa->target = newlibadr(fd, ob->id.lib, steeringa->target);
- steeringa->navmesh = newlibadr(fd, ob->id.lib, steeringa->navmesh);
- break;
- }
- case ACT_MOUSE:
- /* bMouseActuator *moa = act->data; */
- break;
- }
- }
-
{
FluidsimModifierData *fluidmd = (FluidsimModifierData *)modifiers_findByType(ob, eModifierType_Fluidsim);
@@ -5109,6 +5015,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) {
@@ -5124,7 +5032,6 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb)
for (md=lb->first; md; md=md->next) {
md->error = NULL;
- md->scene = NULL;
/* if modifiers disappear, or for upward compatibility */
if (NULL == modifierType_getInfo(md->type))
@@ -5190,6 +5097,7 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb)
smd->domain->shadow = NULL;
smd->domain->tex = NULL;
smd->domain->tex_shadow = NULL;
+ smd->domain->tex_flame = NULL;
smd->domain->tex_wt = NULL;
smd->domain->coba = newdataadr(fd, smd->domain->coba);
@@ -5305,7 +5213,7 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb)
else if (md->type == eModifierType_Surface) {
SurfaceModifierData *surmd = (SurfaceModifierData *)md;
- surmd->dm = NULL;
+ surmd->mesh = NULL;
surmd->bvhtree = NULL;
surmd->x = NULL;
surmd->v = NULL;
@@ -5327,8 +5235,8 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb)
else if (md->type == eModifierType_ParticleSystem) {
ParticleSystemModifierData *psmd = (ParticleSystemModifierData *)md;
- psmd->dm_final = NULL;
- psmd->dm_deformed = NULL;
+ psmd->mesh_final = NULL;
+ psmd->mesh_original = NULL;
psmd->psys= newdataadr(fd, psmd->psys);
psmd->flag &= ~eParticleSystemFlag_psys_updated;
psmd->flag |= eParticleSystemFlag_file_loaded;
@@ -5443,18 +5351,6 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb)
static void direct_link_object(FileData *fd, Object *ob)
{
PartEff *paf;
- bProperty *prop;
- bSensor *sens;
- bController *cont;
- bActuator *act;
-
- /* weak weak... this was only meant as draw flag, now is used in give_base_to_objects too */
- ob->flag &= ~OB_FROMGROUP;
-
- /* This is a transient flag; clear in order to avoid unneeded object update pending from
- * time when file was saved.
- */
- ob->recalc = 0;
/* XXX This should not be needed - but seems like it can happen in some cases, so for now play safe... */
ob->proxy_from = NULL;
@@ -5483,6 +5379,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);
@@ -5572,7 +5469,6 @@ static void direct_link_object(FileData *fd, Object *ob)
direct_link_pointcache_list(fd, &sb->ptcaches, &sb->pointcache, 0);
}
- ob->bsoft = newdataadr(fd, ob->bsoft);
ob->fluidsimSettings= newdataadr(fd, ob->fluidsimSettings); /* NT */
ob->rigidbody_object = newdataadr(fd, ob->rigidbody_object);
@@ -5592,43 +5488,8 @@ static void direct_link_object(FileData *fd, Object *ob)
link_list(fd, &ob->particlesystem);
direct_link_particlesystems(fd, &ob->particlesystem);
- link_list(fd, &ob->prop);
- for (prop = ob->prop.first; prop; prop = prop->next) {
- prop->poin = newdataadr(fd, prop->poin);
- if (prop->poin == NULL)
- prop->poin = &prop->data;
- }
-
- link_list(fd, &ob->sensors);
- for (sens = ob->sensors.first; sens; sens = sens->next) {
- sens->data = newdataadr(fd, sens->data);
- sens->links = newdataadr(fd, sens->links);
- test_pointer_array(fd, (void **)&sens->links);
- }
-
direct_link_constraints(fd, &ob->constraints);
- link_glob_list(fd, &ob->controllers);
- if (ob->init_state) {
- /* if a known first state is specified, set it so that the game will start ok */
- ob->state = ob->init_state;
- }
- else if (!ob->state) {
- ob->state = 1;
- }
- for (cont = ob->controllers.first; cont; cont = cont->next) {
- cont->data = newdataadr(fd, cont->data);
- cont->links = newdataadr(fd, cont->links);
- test_pointer_array(fd, (void **)&cont->links);
- if (cont->state_mask == 0)
- cont->state_mask = 1;
- }
-
- link_glob_list(fd, &ob->actuators);
- for (act = ob->actuators.first; act; act = act->next) {
- act->data = newdataadr(fd, act->data);
- }
-
link_list(fd, &ob->hooks);
while (ob->hooks.first) {
ObHook *hook = ob->hooks.first;
@@ -5668,7 +5529,9 @@ static void direct_link_object(FileData *fd, Object *ob)
ob->bb = NULL;
ob->derivedDeform = NULL;
ob->derivedFinal = NULL;
+ BKE_object_runtime_reset(ob);
BLI_listbase_clear(&ob->gpulamp);
+ BLI_listbase_clear(&ob->drawdata);
link_list(fd, &ob->pc_ids);
/* Runtime curve data */
@@ -5687,6 +5550,205 @@ static void direct_link_object(FileData *fd, Object *ob)
ob->preview = direct_link_preview_image(fd, ob->preview);
}
+static void direct_link_view_settings(FileData *fd, ColorManagedViewSettings *view_settings)
+{
+ view_settings->curve_mapping = newdataadr(fd, view_settings->curve_mapping);
+
+ if (view_settings->curve_mapping)
+ direct_link_curvemapping(fd, view_settings->curve_mapping);
+}
+
+/* ***************** READ VIEW LAYER *************** */
+
+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) {
+#ifdef USE_COLLECTION_COMPAT_28
+ lc->scene_collection = newdataadr(fd, lc->scene_collection);
+#endif
+
+ /* Master collection is not a real datablock. */
+ if (master) {
+ lc->collection = newdataadr(fd, lc->collection);
+ }
+
+ lc->runtime_flag = 0;
+
+ direct_link_layer_collections(fd, &lc->layer_collections, false);
+ }
+}
+
+static void direct_link_view_layer(FileData *fd, ViewLayer *view_layer)
+{
+ view_layer->stats = NULL;
+ link_list(fd, &view_layer->object_bases);
+ view_layer->basact = newdataadr(fd, view_layer->basact);
+
+ direct_link_layer_collections(fd, &view_layer->layer_collections, true);
+ view_layer->active_collection = newdataadr(fd, view_layer->active_collection);
+
+ view_layer->id_properties = newdataadr(fd, view_layer->id_properties);
+ IDP_DirectLinkGroup_OrFree(&view_layer->id_properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
+
+ link_list(fd, &(view_layer->freestyle_config.modules));
+ link_list(fd, &(view_layer->freestyle_config.linesets));
+
+ BLI_listbase_clear(&view_layer->drawdata);
+ view_layer->object_bases_array = NULL;
+ view_layer->object_bases_hash = NULL;
+ view_layer->runtime_flag = 0;
+}
+
+static void lib_link_layer_collection(FileData *fd, Library *lib, LayerCollection *layer_collection, bool master)
+{
+ /* Master collection is not a real datablock. */
+ if (!master) {
+ layer_collection->collection = newlibadr(fd, lib, layer_collection->collection);
+ }
+
+ for (LayerCollection *layer_collection_nested = layer_collection->layer_collections.first;
+ layer_collection_nested != NULL;
+ layer_collection_nested = layer_collection_nested->next)
+ {
+ lib_link_layer_collection(fd, lib, layer_collection_nested, false);
+ }
+}
+
+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) {
+ fmc->script = newlibadr(fd, lib, fmc->script);
+ }
+
+ for (FreestyleLineSet *fls = view_layer->freestyle_config.linesets.first; fls; fls = fls->next) {
+ fls->linestyle = newlibadr_us(fd, lib, fls->linestyle);
+ fls->group = newlibadr_us(fd, lib, fls->group);
+ }
+
+ for (Base *base = view_layer->object_bases.first, *base_next = NULL; base; base = base_next) {
+ base_next = base->next;
+
+ /* we only bump the use count for the collection objects */
+ base->object = newlibadr(fd, lib, base->object);
+
+ if (base->object == NULL) {
+ /* Free in case linked object got lost. */
+ BLI_freelinkN(&view_layer->object_bases, base);
+ }
+ }
+
+ for (LayerCollection *layer_collection = view_layer->layer_collections.first;
+ layer_collection != NULL;
+ layer_collection = layer_collection->next)
+ {
+ lib_link_layer_collection(fd, lib, layer_collection, true);
+ }
+
+ IDP_LibLinkProperty(view_layer->id_properties, fd);
+}
+
+/* ***************** READ COLLECTION *************** */
+
+#ifdef USE_COLLECTION_COMPAT_28
+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) {
+ 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) {
+ 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);
+ }
+}
+#endif
+
+static void direct_link_collection(FileData *fd, Collection *collection)
+{
+ link_list(fd, &collection->gobject);
+ link_list(fd, &collection->children);
+
+ collection->preview = direct_link_preview_image(fd, collection->preview);
+
+ collection->flag &= ~COLLECTION_HAS_OBJECT_CACHE;
+ BLI_listbase_clear(&collection->object_cache);
+ BLI_listbase_clear(&collection->parents);
+
+#ifdef USE_COLLECTION_COMPAT_28
+ /* This runs before the very first doversion. */
+ collection->collection = newdataadr(fd, collection->collection);
+ if (collection->collection != NULL) {
+ direct_link_scene_collection(fd, collection->collection);
+ }
+
+ collection->view_layer = newdataadr(fd, collection->view_layer);
+ if (collection->view_layer != NULL) {
+ direct_link_view_layer(fd, collection->view_layer);
+ }
+#endif
+}
+
+static void lib_link_collection_data(FileData *fd, Library *lib, Collection *collection)
+{
+ for (CollectionObject *cob = collection->gobject.first, *cob_next = NULL; cob; cob = cob_next) {
+ cob_next = cob->next;
+ cob->ob = newlibadr_us(fd, lib, cob->ob);
+
+ if (cob->ob == NULL) {
+ BLI_freelinkN(&collection->gobject, cob);
+ }
+ }
+
+ for (CollectionChild *child = collection->children.first, *child_next = NULL; child; child = child_next) {
+ child_next = child->next;
+ child->collection = newlibadr_us(fd, lib, child->collection);
+
+ if (child->collection == NULL ||
+ BKE_collection_find_cycle(collection, child->collection))
+ {
+ BLI_freelinkN(&collection->children, child);
+ }
+ else {
+ CollectionParent *cparent = MEM_callocN(sizeof(CollectionParent), "CollectionParent");
+ cparent->collection = collection;
+ BLI_addtail(&child->collection->parents, cparent);
+ }
+ }
+}
+
+static void lib_link_collection(FileData *fd, Main *main)
+{
+ for (Collection *collection = main->collection.first; collection; collection = collection->id.next) {
+ if (collection->id.tag & LIB_TAG_NEED_LINK) {
+ collection->id.tag &= ~LIB_TAG_NEED_LINK;
+ IDP_LibLinkProperty(collection->id.properties, fd);
+
+#ifdef USE_COLLECTION_COMPAT_28
+ if (collection->collection) {
+ lib_link_scene_collection(fd, collection->id.lib, collection->collection);
+ }
+
+ if (collection->view_layer) {
+ lib_link_view_layer(fd, collection->id.lib, collection->view_layer);
+ }
+#endif
+
+ lib_link_collection_data(fd, collection->id.lib, collection);
+ }
+ }
+}
+
/* ************ READ SCENE ***************** */
/* patch for missing scene IDs, can't be in do-versions */
@@ -5792,21 +5854,19 @@ static void lib_link_scene(FileData *fd, Main *main)
sce->toolsettings->imapaint.canvas =
newlibadr_us(fd, sce->id.lib, sce->toolsettings->imapaint.canvas);
- sce->toolsettings->skgen_template = newlibadr(fd, sce->id.lib, sce->toolsettings->skgen_template);
-
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 (Base *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);
}
}
@@ -5861,7 +5921,7 @@ static void lib_link_scene(FileData *fd, Main *main)
BKE_sequencer_update_sound_bounds_all(sce);
- /* rigidbody world relies on it's linked groups */
+ /* rigidbody world relies on it's linked collections */
if (sce->rigidbody_world) {
RigidBodyWorld *rbw = sce->rigidbody_world;
if (rbw->group)
@@ -5880,7 +5940,6 @@ static void lib_link_scene(FileData *fd, Main *main)
for (SceneRenderLayer *srl = sce->r.layers.first; srl; srl = srl->next) {
srl->mat_override = newlibadr_us(fd, sce->id.lib, srl->mat_override);
- srl->light_override = newlibadr_us(fd, sce->id.lib, srl->light_override);
for (FreestyleModuleConfig *fmc = srl->freestyleConfig.modules.first; fmc; fmc = fmc->next) {
fmc->script = newlibadr(fd, sce->id.lib, fmc->script);
}
@@ -5889,12 +5948,23 @@ static void lib_link_scene(FileData *fd, Main *main)
fls->group = newlibadr_us(fd, sce->id.lib, fls->group);
}
}
- /*Game Settings: Dome Warp Text*/
- sce->gm.dome.warptext = newlibadr(fd, sce->id.lib, sce->gm.dome.warptext);
-
/* Motion Tracking */
sce->clip = newlibadr_us(fd, sce->id.lib, sce->clip);
+#ifdef USE_COLLECTION_COMPAT_28
+ if (sce->collection) {
+ lib_link_scene_collection(fd, sce->id.lib, sce->collection);
+ }
+#endif
+
+ if (sce->master_collection) {
+ lib_link_collection_data(fd, sce->id.lib, sce->master_collection);
+ }
+
+ for (ViewLayer *view_layer = sce->view_layers.first; view_layer; view_layer = view_layer->next) {
+ lib_link_view_layer(fd, sce->id.lib, view_layer);
+ }
+
#ifdef USE_SETSCENE_CHECK
if (sce->set != NULL) {
/* link flag for scenes with set would be reset later,
@@ -5990,26 +6060,16 @@ static void direct_link_sequence_modifiers(FileData *fd, ListBase *lb)
}
}
-static void direct_link_view_settings(FileData *fd, ColorManagedViewSettings *view_settings)
-{
- view_settings->curve_mapping = newdataadr(fd, view_settings->curve_mapping);
-
- if (view_settings->curve_mapping)
- direct_link_curvemapping(fd, view_settings->curve_mapping);
-}
-
static void direct_link_scene(FileData *fd, Scene *sce)
{
Editing *ed;
Sequence *seq;
MetaStack *ms;
RigidBodyWorld *rbw;
+ ViewLayer *view_layer;
SceneRenderLayer *srl;
- sce->theDag = NULL;
- sce->depsgraph = NULL;
- sce->obedit = NULL;
- sce->stats = NULL;
+ sce->depsgraph_hash = NULL;
sce->fps_info = NULL;
sce->customdata_mask_modal = 0;
sce->lay_updated = 0;
@@ -6187,11 +6247,6 @@ static void direct_link_scene(FileData *fd, Scene *sce)
}
}
-#ifdef DURIAN_CAMERA_SWITCH
- /* Runtime */
- sce->r.mode &= ~R_NO_CAMERA_SWITCH;
-#endif
-
sce->r.avicodecdata = newdataadr(fd, sce->r.avicodecdata);
if (sce->r.avicodecdata) {
sce->r.avicodecdata->lpFormat = newdataadr(fd, sce->r.avicodecdata->lpFormat);
@@ -6211,11 +6266,7 @@ static void direct_link_scene(FileData *fd, Scene *sce)
for (srl = sce->r.layers.first; srl; srl = srl->next) {
srl->prop = newdataadr(fd, srl->prop);
IDP_DirectLinkGroup_OrFree(&srl->prop, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
- }
- for (srl = sce->r.layers.first; srl; srl = srl->next) {
link_list(fd, &(srl->freestyleConfig.modules));
- }
- for (srl = sce->r.layers.first; srl; srl = srl->next) {
link_list(fd, &(srl->freestyleConfig.linesets));
}
@@ -6253,89 +6304,28 @@ 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);
-}
-
-/* ************ READ WM ***************** */
-
-static void direct_link_windowmanager(FileData *fd, wmWindowManager *wm)
-{
- wmWindow *win;
-
- id_us_ensure_real(&wm->id);
- link_list(fd, &wm->windows);
- for (win = wm->windows.first; win; win = win->next) {
- win->ghostwin = NULL;
- win->eventstate = NULL;
- win->curswin = NULL;
- win->tweak = NULL;
-#ifdef WIN32
- win->ime_data = NULL;
+#ifdef USE_COLLECTION_COMPAT_28
+ /* this runs before the very first doversion */
+ if (sce->collection) {
+ sce->collection = newdataadr(fd, sce->collection);
+ direct_link_scene_collection(fd, sce->collection);
+ }
#endif
- BLI_listbase_clear(&win->queue);
- BLI_listbase_clear(&win->handlers);
- BLI_listbase_clear(&win->modalhandlers);
- BLI_listbase_clear(&win->subwindows);
- BLI_listbase_clear(&win->gesture);
- BLI_listbase_clear(&win->drawdata);
-
- win->drawmethod = -1;
- win->drawfail = 0;
- win->active = 0;
-
- win->cursor = 0;
- win->lastcursor = 0;
- win->modalcursor = 0;
- win->grabcursor = 0;
- win->addmousemove = true;
- win->multisamples = 0;
- win->stereo3d_format = newdataadr(fd, win->stereo3d_format);
-
- /* multiview always fallback to anaglyph at file opening
- * otherwise quadbuffer saved files can break Blender */
- if (win->stereo3d_format) {
- win->stereo3d_format->display_mode = S3D_DISPLAY_ANAGLYPH;
- }
+ if (sce->master_collection) {
+ sce->master_collection = newdataadr(fd, sce->master_collection);
+ direct_link_collection(fd, sce->master_collection);
}
- BLI_listbase_clear(&wm->timers);
- BLI_listbase_clear(&wm->operators);
- BLI_listbase_clear(&wm->paintcursors);
- BLI_listbase_clear(&wm->queue);
- BKE_reports_init(&wm->reports, RPT_STORE);
-
- BLI_listbase_clear(&wm->keyconfigs);
- wm->defaultconf = NULL;
- wm->addonconf = NULL;
- wm->userconf = NULL;
- wm->undo_stack = NULL;
-
- BLI_listbase_clear(&wm->jobs);
- BLI_listbase_clear(&wm->drags);
-
- wm->windrawable = NULL;
- wm->winactive = NULL;
- wm->initialized = 0;
- wm->op_undo_depth = 0;
- wm->is_interface_locked = 0;
-}
-
-static void lib_link_windowmanager(FileData *fd, Main *main)
-{
- wmWindowManager *wm;
- wmWindow *win;
-
- for (wm = main->wm.first; wm; wm = wm->id.next) {
- 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) {
- win->screen = newlibadr(fd, NULL, win->screen);
- }
-
- wm->id.tag &= ~LIB_TAG_NEED_LINK;
- }
+ /* insert into global old-new map for reading without UI (link_global accesses it again) */
+ link_glob_list(fd, &sce->view_layers);
+ for (view_layer = sce->view_layers.first; view_layer; view_layer = view_layer->next) {
+ direct_link_view_layer(fd, view_layer);
}
+
+ sce->layer_properties = newdataadr(fd, sce->layer_properties);
+ IDP_DirectLinkGroup_OrFree(&sce->layer_properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
}
/* ****************** READ GREASE PENCIL ***************** */
@@ -6404,228 +6394,654 @@ static void direct_link_gpencil(FileData *fd, bGPdata *gpd)
}
}
-/* ****************** READ SCREEN ***************** */
+/* *********** READ AREA **************** */
-/* note: file read without screens option G_FILE_NO_UI;
- * check lib pointers in call below */
-static void lib_link_screen(FileData *fd, Main *main)
+static void direct_link_panel_list(FileData *fd, ListBase *lb)
{
- for (bScreen *sc = main->screen.first; sc; sc = sc->id.next) {
- if (sc->id.tag & LIB_TAG_NEED_LINK) {
- IDP_LibLinkProperty(sc->id.properties, fd);
- id_us_ensure_real(&sc->id);
+ link_list(fd, lb);
- sc->scene = newlibadr(fd, sc->id.lib, sc->scene);
+ for (Panel *pa = lb->first; pa; pa = pa->next) {
+ pa->paneltab = newdataadr(fd, pa->paneltab);
+ pa->runtime_flag = 0;
+ pa->activedata = NULL;
+ pa->type = NULL;
+ direct_link_panel_list(fd, &pa->children);
+ }
+}
- /* 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;
+static void direct_link_region(FileData *fd, ARegion *ar, int spacetype)
+{
+ uiList *ui_list;
- sc->animtimer = NULL; /* saved in rare cases */
- sc->tool_tip = NULL;
- sc->scrubbing = false;
+ direct_link_panel_list(fd, &ar->panels);
- for (ScrArea *sa = sc->areabase.first; sa; sa = sa->next) {
- sa->full = newlibadr(fd, sc->id.lib, sa->full);
+ link_list(fd, &ar->panels_category_active);
- for (SpaceLink *sl = sa->spacedata.first; sl; sl= sl->next) {
- switch (sl->spacetype) {
- case SPACE_VIEW3D:
- {
- View3D *v3d = (View3D*) sl;
- BGpic *bgpic = NULL;
+ link_list(fd, &ar->ui_lists);
- v3d->camera= newlibadr(fd, sc->id.lib, v3d->camera);
- v3d->ob_centre= newlibadr(fd, sc->id.lib, v3d->ob_centre);
+ for (ui_list = ar->ui_lists.first; ui_list; ui_list = ui_list->next) {
+ ui_list->type = NULL;
+ ui_list->dyn_data = NULL;
+ ui_list->properties = newdataadr(fd, ui_list->properties);
+ IDP_DirectLinkGroup_OrFree(&ui_list->properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
+ }
- /* 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;
- }
+ link_list(fd, &ar->ui_previews);
- 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);
- }
- break;
- }
- case SPACE_IPO:
- {
- SpaceIpo *sipo = (SpaceIpo *)sl;
- bDopeSheet *ads = sipo->ads;
-
- if (ads) {
- ads->source = newlibadr(fd, sc->id.lib, ads->source);
- ads->filter_grp = newlibadr(fd, sc->id.lib, ads->filter_grp);
- }
- break;
- }
- case SPACE_BUTS:
- {
- SpaceButs *sbuts = (SpaceButs *)sl;
- sbuts->pinid = newlibadr(fd, sc->id.lib, sbuts->pinid);
- if (sbuts->pinid == NULL) {
- sbuts->flag &= ~SB_PIN_CONTEXT;
- }
- break;
- }
- case SPACE_FILE:
- break;
- case SPACE_ACTION:
- {
- SpaceAction *saction = (SpaceAction *)sl;
- bDopeSheet *ads = &saction->ads;
-
- if (ads) {
- ads->source = newlibadr(fd, sc->id.lib, ads->source);
- ads->filter_grp = newlibadr(fd, sc->id.lib, ads->filter_grp);
- }
+ if (spacetype == SPACE_EMPTY) {
+ /* unkown space type, don't leak regiondata */
+ ar->regiondata = NULL;
+ }
+ else if (ar->flag & RGN_FLAG_TEMP_REGIONDATA) {
+ /* Runtime data, don't use. */
+ ar->regiondata = NULL;
+ }
+ else {
+ ar->regiondata = newdataadr(fd, ar->regiondata);
+ if (ar->regiondata) {
+ if (spacetype == SPACE_VIEW3D) {
+ RegionView3D *rv3d = ar->regiondata;
- saction->action = newlibadr(fd, sc->id.lib, saction->action);
- break;
- }
- case SPACE_IMAGE:
- {
- SpaceImage *sima = (SpaceImage *)sl;
+ rv3d->localvd = newdataadr(fd, rv3d->localvd);
+ rv3d->clipbb = newdataadr(fd, rv3d->clipbb);
- sima->image = newlibadr_real_us(fd, sc->id.lib, sima->image);
- sima->mask_info.mask = newlibadr_real_us(fd, sc->id.lib, sima->mask_info.mask);
+ rv3d->depths = NULL;
+ rv3d->gpuoffscreen = NULL;
+ rv3d->render_engine = NULL;
+ rv3d->sms = NULL;
+ rv3d->smooth_timer = NULL;
+ }
+ }
+ }
- /* NOTE: pre-2.5, this was local data not lib data, but now we need this as lib data
- * so fingers crossed this works fine!
- */
- sima->gpd = newlibadr_us(fd, sc->id.lib, sima->gpd);
- break;
- }
- case SPACE_SEQ:
- {
- SpaceSeq *sseq = (SpaceSeq *)sl;
-
- /* NOTE: pre-2.5, this was local data not lib data, but now we need this as lib data
- * so fingers crossed this works fine!
- */
- sseq->gpd = newlibadr_us(fd, sc->id.lib, sseq->gpd);
- break;
- }
- case SPACE_NLA:
- {
- SpaceNla *snla= (SpaceNla *)sl;
- bDopeSheet *ads= snla->ads;
-
- if (ads) {
- ads->source = newlibadr(fd, sc->id.lib, ads->source);
- ads->filter_grp = newlibadr(fd, sc->id.lib, ads->filter_grp);
- }
- break;
- }
- case SPACE_TEXT:
- {
- SpaceText *st= (SpaceText *)sl;
+ ar->v2d.tab_offset = NULL;
+ ar->v2d.tab_num = 0;
+ ar->v2d.tab_cur = 0;
+ ar->v2d.sms = NULL;
+ ar->v2d.alpha_hor = ar->v2d.alpha_vert = 255; /* visible by default */
+ ar->v2d.size_hor = ar->v2d.size_vert = 0;
+ BLI_listbase_clear(&ar->panels_category);
+ BLI_listbase_clear(&ar->handlers);
+ BLI_listbase_clear(&ar->uiblocks);
+ ar->headerstr = NULL;
+ ar->visible = 0;
+ ar->type = NULL;
+ ar->do_draw = 0;
+ ar->manipulator_map = NULL;
+ ar->regiontimer = NULL;
+ ar->draw_buffer = NULL;
+ memset(&ar->drawrct, 0, sizeof(ar->drawrct));
+}
- st->text= newlibadr(fd, sc->id.lib, st->text);
- break;
- }
- case SPACE_SCRIPT:
- {
- SpaceScript *scpt = (SpaceScript *)sl;
- /*scpt->script = NULL; - 2.45 set to null, better re-run the script */
- if (scpt->script) {
- scpt->script = newlibadr(fd, sc->id.lib, scpt->script);
- if (scpt->script) {
- SCRIPT_SET_NULL(scpt->script);
- }
- }
- break;
- }
- case SPACE_OUTLINER:
- {
- SpaceOops *so= (SpaceOops *)sl;
- so->search_tse.id = newlibadr(fd, NULL, so->search_tse.id);
-
- if (so->treestore) {
- TreeStoreElem *tselem;
- BLI_mempool_iter iter;
-
- BLI_mempool_iternew(so->treestore, &iter);
- while ((tselem = BLI_mempool_iterstep(&iter))) {
- tselem->id = newlibadr(fd, NULL, tselem->id);
- }
- if (so->treehash) {
- /* rebuild hash table, because it depends on ids too */
- so->storeflag |= SO_TREESTORE_REBUILD;
- }
- }
- break;
- }
- case SPACE_NODE:
- {
- SpaceNode *snode = (SpaceNode *)sl;
- bNodeTreePath *path, *path_next;
- bNodeTree *ntree;
-
- /* node tree can be stored locally in id too, link this first */
- snode->id = newlibadr(fd, sc->id.lib, snode->id);
- snode->from = newlibadr(fd, sc->id.lib, snode->from);
-
- ntree = snode->id ? ntreeFromID(snode->id) : NULL;
- snode->nodetree = ntree ? ntree : newlibadr_us(fd, sc->id.lib, snode->nodetree);
-
- for (path = snode->treepath.first; path; path = path->next) {
- if (path == snode->treepath.first) {
- /* first nodetree in path is same as snode->nodetree */
- path->nodetree = snode->nodetree;
- }
- else
- path->nodetree = newlibadr_us(fd, sc->id.lib, path->nodetree);
+static void direct_link_area(FileData *fd, ScrArea *area)
+{
+ SpaceLink *sl;
+ ARegion *ar;
- if (!path->nodetree)
- break;
- }
+ link_list(fd, &(area->spacedata));
+ link_list(fd, &(area->regionbase));
- /* remaining path entries are invalid, remove */
- for (; path; path = path_next) {
- path_next = path->next;
+ BLI_listbase_clear(&area->handlers);
+ area->type = NULL; /* spacetype callbacks */
+ area->butspacetype = SPACE_EMPTY; /* Should always be unset so that rna_Area_type_get works correctly */
+ area->region_active_win = -1;
- BLI_remlink(&snode->treepath, path);
- MEM_freeN(path);
- }
+ area->global = newdataadr(fd, area->global);
- /* edittree is just the last in the path,
- * set this directly since the path may have been shortened above */
- if (snode->treepath.last) {
- path = snode->treepath.last;
- snode->edittree = path->nodetree;
- }
- else {
- snode->edittree = NULL;
- }
- break;
- }
- case SPACE_CLIP:
- {
- SpaceClip *sclip = (SpaceClip *)sl;
+ /* if we do not have the spacetype registered we cannot
+ * free it, so don't allocate any new memory for such spacetypes. */
+ if (!BKE_spacetype_exists(area->spacetype)) {
+ area->butspacetype = area->spacetype; /* Hint for versioning code to replace deprecated space types. */
+ area->spacetype = SPACE_EMPTY;
+ }
- sclip->clip = newlibadr_real_us(fd, sc->id.lib, sclip->clip);
- sclip->mask_info.mask = newlibadr_real_us(fd, sc->id.lib, sclip->mask_info.mask);
- break;
- }
- case SPACE_LOGIC:
- {
- SpaceLogic *slogic = (SpaceLogic *)sl;
+ for (ar = area->regionbase.first; ar; ar = ar->next) {
+ direct_link_region(fd, ar, area->spacetype);
+ }
- slogic->gpd = newlibadr_us(fd, sc->id.lib, slogic->gpd);
- break;
- }
- default:
- break;
+ /* accident can happen when read/save new file with older version */
+ /* 2.50: we now always add spacedata for info */
+ if (area->spacedata.first == NULL) {
+ SpaceInfo *sinfo= MEM_callocN(sizeof(SpaceInfo), "spaceinfo");
+ area->spacetype= sinfo->spacetype= SPACE_INFO;
+ BLI_addtail(&area->spacedata, sinfo);
+ }
+ /* add local view3d too */
+ else if (area->spacetype == SPACE_VIEW3D) {
+ blo_do_versions_view3d_split_250(area->spacedata.first, &area->regionbase);
+ }
+
+ for (sl = area->spacedata.first; sl; sl = sl->next) {
+ link_list(fd, &(sl->regionbase));
+
+ /* if we do not have the spacetype registered we cannot
+ * free it, so don't allocate any new memory for such spacetypes. */
+ if (!BKE_spacetype_exists(sl->spacetype))
+ sl->spacetype = SPACE_EMPTY;
+
+ for (ar = sl->regionbase.first; ar; ar = ar->next)
+ direct_link_region(fd, ar, sl->spacetype);
+
+ if (sl->spacetype == SPACE_VIEW3D) {
+ View3D *v3d= (View3D*) sl;
+
+ v3d->flag |= V3D_INVALID_BACKBUF;
+
+ if (v3d->gpd) {
+ v3d->gpd = newdataadr(fd, v3d->gpd);
+ direct_link_gpencil(fd, v3d->gpd);
+ }
+ v3d->localvd = newdataadr(fd, v3d->localvd);
+ v3d->properties_storage = NULL;
+
+ /* render can be quite heavy, set to solid on load */
+ if (v3d->drawtype == OB_RENDER)
+ v3d->drawtype = OB_SOLID;
+ v3d->prev_drawtype = OB_SOLID;
+
+ if (v3d->fx_settings.dof)
+ v3d->fx_settings.dof = newdataadr(fd, v3d->fx_settings.dof);
+ if (v3d->fx_settings.ssao)
+ v3d->fx_settings.ssao = newdataadr(fd, v3d->fx_settings.ssao);
+
+ blo_do_versions_view3d_split_250(v3d, &sl->regionbase);
+ }
+ else if (sl->spacetype == SPACE_IPO) {
+ SpaceIpo *sipo = (SpaceIpo *)sl;
+
+ sipo->ads = newdataadr(fd, sipo->ads);
+ BLI_listbase_clear(&sipo->ghostCurves);
+ }
+ else if (sl->spacetype == SPACE_NLA) {
+ SpaceNla *snla = (SpaceNla *)sl;
+
+ snla->ads = newdataadr(fd, snla->ads);
+ }
+ else if (sl->spacetype == SPACE_OUTLINER) {
+ SpaceOops *soops = (SpaceOops *) sl;
+
+ /* use newdataadr_no_us and do not free old memory avoiding double
+ * frees and use of freed memory. this could happen because of a
+ * bug fixed in revision 58959 where the treestore memory address
+ * was not unique */
+ TreeStore *ts = newdataadr_no_us(fd, soops->treestore);
+ soops->treestore = NULL;
+ if (ts) {
+ TreeStoreElem *elems = newdataadr_no_us(fd, ts->data);
+
+ soops->treestore = BLI_mempool_create(sizeof(TreeStoreElem), ts->usedelem,
+ 512, BLI_MEMPOOL_ALLOW_ITER);
+ if (ts->usedelem && elems) {
+ int i;
+ for (i = 0; i < ts->usedelem; i++) {
+ TreeStoreElem *new_elem = BLI_mempool_alloc(soops->treestore);
+ *new_elem = elems[i];
}
}
+ /* we only saved what was used */
+ soops->storeflag |= SO_TREESTORE_CLEANUP; // at first draw
+ }
+ soops->treehash = NULL;
+ soops->tree.first = soops->tree.last= NULL;
+ }
+ else if (sl->spacetype == SPACE_IMAGE) {
+ SpaceImage *sima = (SpaceImage *)sl;
+
+ sima->iuser.scene = NULL;
+ sima->iuser.ok = 1;
+ sima->scopes.waveform_1 = NULL;
+ sima->scopes.waveform_2 = NULL;
+ sima->scopes.waveform_3 = NULL;
+ sima->scopes.vecscope = NULL;
+ sima->scopes.ok = 0;
+
+ /* WARNING: gpencil data is no longer stored directly in sima after 2.5
+ * 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);
+#endif
+ }
+ else if (sl->spacetype == SPACE_NODE) {
+ SpaceNode *snode = (SpaceNode *)sl;
+
+ if (snode->gpd) {
+ snode->gpd = newdataadr(fd, snode->gpd);
+ direct_link_gpencil(fd, snode->gpd);
+ }
+
+ link_list(fd, &snode->treepath);
+ snode->edittree = NULL;
+ snode->iofsd = NULL;
+ BLI_listbase_clear(&snode->linkdrag);
+ }
+ else if (sl->spacetype == SPACE_TEXT) {
+ SpaceText *st= (SpaceText *)sl;
+
+ st->drawcache = NULL;
+ st->scroll_accum[0] = 0.0f;
+ st->scroll_accum[1] = 0.0f;
+ }
+ else if (sl->spacetype == SPACE_SEQ) {
+ SpaceSeq *sseq = (SpaceSeq *)sl;
+
+ /* grease pencil data is not a direct data and can't be linked from direct_link*
+ * functions, it should be linked from lib_link* functions instead
+ *
+ * otherwise it'll lead to lost grease data on open because it'll likely be
+ * read from file after all other users of grease pencil and newdataadr would
+ * simple return NULL here (sergey)
+ */
+#if 0
+ 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;
+ sseq->scopes.waveform_ibuf = NULL;
+ sseq->scopes.sep_waveform_ibuf = NULL;
+ sseq->scopes.vector_ibuf = NULL;
+ sseq->scopes.histogram_ibuf = NULL;
+ sseq->compositor = NULL;
+ }
+ else if (sl->spacetype == SPACE_BUTS) {
+ SpaceButs *sbuts = (SpaceButs *)sl;
+
+ sbuts->path= NULL;
+ sbuts->texuser= NULL;
+ sbuts->mainbo = sbuts->mainb;
+ sbuts->mainbuser = sbuts->mainb;
+ }
+ else if (sl->spacetype == SPACE_CONSOLE) {
+ SpaceConsole *sconsole = (SpaceConsole *)sl;
+ ConsoleLine *cl, *cl_next;
+
+ link_list(fd, &sconsole->scrollback);
+ link_list(fd, &sconsole->history);
+
+ //for (cl= sconsole->scrollback.first; cl; cl= cl->next)
+ // cl->line= newdataadr(fd, cl->line);
+
+ /* comma expressions, (e.g. expr1, expr2, expr3) evaluate each expression,
+ * from left to right. the right-most expression sets the result of the comma
+ * expression as a whole*/
+ for (cl = sconsole->history.first; cl; cl = cl_next) {
+ cl_next = cl->next;
+ cl->line = newdataadr(fd, cl->line);
+ if (cl->line) {
+ /* the allocted length is not written, so reset here */
+ cl->len_alloc = cl->len + 1;
+ }
+ else {
+ BLI_remlink(&sconsole->history, cl);
+ MEM_freeN(cl);
+ }
+ }
+ }
+ else if (sl->spacetype == SPACE_FILE) {
+ SpaceFile *sfile = (SpaceFile *)sl;
+
+ /* this sort of info is probably irrelevant for reloading...
+ * plus, it isn't saved to files yet!
+ */
+ sfile->folders_prev = sfile->folders_next = NULL;
+ sfile->files = NULL;
+ sfile->layout = NULL;
+ sfile->op = NULL;
+ sfile->previews_timer = NULL;
+ sfile->params = newdataadr(fd, sfile->params);
+ }
+ else if (sl->spacetype == SPACE_CLIP) {
+ SpaceClip *sclip = (SpaceClip *)sl;
+
+ sclip->scopes.track_search = NULL;
+ sclip->scopes.track_preview = NULL;
+ sclip->scopes.ok = 0;
+ }
+ }
+
+ BLI_listbase_clear(&area->actionzones);
+
+ area->v1 = newdataadr(fd, area->v1);
+ area->v2 = newdataadr(fd, area->v2);
+ area->v3 = newdataadr(fd, area->v3);
+ area->v4 = newdataadr(fd, area->v4);
+}
+
+static void lib_link_area(FileData *fd, ID *parent_id, ScrArea *area)
+{
+ area->full = newlibadr(fd, parent_id->lib, area->full);
+
+ memset(&area->runtime, 0x0, sizeof(area->runtime));
+
+ for (SpaceLink *sl = area->spacedata.first; sl; sl= sl->next) {
+ switch (sl->spacetype) {
+ case SPACE_VIEW3D:
+ {
+ View3D *v3d = (View3D*) sl;
+
+ v3d->camera= newlibadr(fd, parent_id->lib, v3d->camera);
+ v3d->ob_centre= newlibadr(fd, parent_id->lib, v3d->ob_centre);
+
+ if (v3d->localvd) {
+ v3d->localvd->camera = newlibadr(fd, parent_id->lib, v3d->localvd->camera);
+ }
+ break;
+ }
+ case SPACE_IPO:
+ {
+ SpaceIpo *sipo = (SpaceIpo *)sl;
+ bDopeSheet *ads = sipo->ads;
+
+ if (ads) {
+ ads->source = newlibadr(fd, parent_id->lib, ads->source);
+ ads->filter_grp = newlibadr(fd, parent_id->lib, ads->filter_grp);
+ }
+ break;
+ }
+ case SPACE_BUTS:
+ {
+ SpaceButs *sbuts = (SpaceButs *)sl;
+ sbuts->pinid = newlibadr(fd, parent_id->lib, sbuts->pinid);
+ if (sbuts->pinid == NULL) {
+ sbuts->flag &= ~SB_PIN_CONTEXT;
+ }
+ break;
+ }
+ case SPACE_FILE:
+ break;
+ case SPACE_ACTION:
+ {
+ SpaceAction *saction = (SpaceAction *)sl;
+ bDopeSheet *ads = &saction->ads;
+
+ if (ads) {
+ ads->source = newlibadr(fd, parent_id->lib, ads->source);
+ ads->filter_grp = newlibadr(fd, parent_id->lib, ads->filter_grp);
+ }
+
+ saction->action = newlibadr(fd, parent_id->lib, saction->action);
+ break;
+ }
+ case SPACE_IMAGE:
+ {
+ SpaceImage *sima = (SpaceImage *)sl;
+
+ sima->image = newlibadr_real_us(fd, parent_id->lib, sima->image);
+ sima->mask_info.mask = newlibadr_real_us(fd, parent_id->lib, sima->mask_info.mask);
+
+ /* NOTE: pre-2.5, this was local data not lib data, but now we need this as lib data
+ * so fingers crossed this works fine!
+ */
+ sima->gpd = newlibadr_us(fd, parent_id->lib, sima->gpd);
+ break;
+ }
+ case SPACE_SEQ:
+ {
+ SpaceSeq *sseq = (SpaceSeq *)sl;
+
+ /* NOTE: pre-2.5, this was local data not lib data, but now we need this as lib data
+ * so fingers crossed this works fine!
+ */
+ sseq->gpd = newlibadr_us(fd, parent_id->lib, sseq->gpd);
+ break;
+ }
+ case SPACE_NLA:
+ {
+ SpaceNla *snla= (SpaceNla *)sl;
+ bDopeSheet *ads= snla->ads;
+
+ if (ads) {
+ ads->source = newlibadr(fd, parent_id->lib, ads->source);
+ ads->filter_grp = newlibadr(fd, parent_id->lib, ads->filter_grp);
+ }
+ break;
+ }
+ case SPACE_TEXT:
+ {
+ SpaceText *st= (SpaceText *)sl;
+
+ st->text= newlibadr(fd, parent_id->lib, st->text);
+ break;
+ }
+ case SPACE_SCRIPT:
+ {
+ SpaceScript *scpt = (SpaceScript *)sl;
+ /*scpt->script = NULL; - 2.45 set to null, better re-run the script */
+ if (scpt->script) {
+ scpt->script = newlibadr(fd, parent_id->lib, scpt->script);
+ if (scpt->script) {
+ SCRIPT_SET_NULL(scpt->script);
+ }
+ }
+ break;
+ }
+ case SPACE_OUTLINER:
+ {
+ SpaceOops *so= (SpaceOops *)sl;
+ so->search_tse.id = newlibadr(fd, NULL, so->search_tse.id);
+
+ if (so->treestore) {
+ TreeStoreElem *tselem;
+ BLI_mempool_iter iter;
+
+ BLI_mempool_iternew(so->treestore, &iter);
+ while ((tselem = BLI_mempool_iterstep(&iter))) {
+ tselem->id = newlibadr(fd, NULL, tselem->id);
+ }
+ if (so->treehash) {
+ /* rebuild hash table, because it depends on ids too */
+ so->storeflag |= SO_TREESTORE_REBUILD;
+ }
+ }
+ break;
+ }
+ case SPACE_NODE:
+ {
+ SpaceNode *snode = (SpaceNode *)sl;
+ bNodeTreePath *path, *path_next;
+ bNodeTree *ntree;
+
+ /* node tree can be stored locally in id too, link this first */
+ snode->id = newlibadr(fd, parent_id->lib, snode->id);
+ snode->from = newlibadr(fd, parent_id->lib, snode->from);
+
+ ntree = snode->id ? ntreeFromID(snode->id) : NULL;
+ snode->nodetree = ntree ? ntree : newlibadr_us(fd, parent_id->lib, snode->nodetree);
+
+ for (path = snode->treepath.first; path; path = path->next) {
+ if (path == snode->treepath.first) {
+ /* first nodetree in path is same as snode->nodetree */
+ path->nodetree = snode->nodetree;
+ }
+ else
+ path->nodetree = newlibadr_us(fd, parent_id->lib, path->nodetree);
+
+ if (!path->nodetree)
+ break;
+ }
+
+ /* remaining path entries are invalid, remove */
+ for (; path; path = path_next) {
+ path_next = path->next;
+
+ BLI_remlink(&snode->treepath, path);
+ MEM_freeN(path);
+ }
+
+ /* edittree is just the last in the path,
+ * set this directly since the path may have been shortened above */
+ if (snode->treepath.last) {
+ path = snode->treepath.last;
+ snode->edittree = path->nodetree;
+ }
+ else {
+ snode->edittree = NULL;
+ }
+ break;
+ }
+ case SPACE_CLIP:
+ {
+ SpaceClip *sclip = (SpaceClip *)sl;
+ sclip->clip = newlibadr_real_us(fd, parent_id->lib, sclip->clip);
+ sclip->mask_info.mask = newlibadr_real_us(fd, parent_id->lib, sclip->mask_info.mask);
+ break;
+ }
+ default:
+ break;
+ }
+ }
+}
+
+/**
+ * \return false on error.
+ */
+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) {
+ direct_link_area(fd, area);
+ }
+
+ /* edges */
+ for (ScrEdge *se = area_map->edgebase.first; se; se = se->next) {
+ se->v1 = newdataadr(fd, se->v1);
+ se->v2 = newdataadr(fd, se->v2);
+ BKE_screen_sort_scrvert(&se->v1, &se->v2);
+
+ if (se->v1 == NULL) {
+ BLI_remlink(&area_map->edgebase, se);
+
+ return false;
+ }
+ }
+
+ return true;
+}
+
+/* ************ READ WM ***************** */
+
+static void direct_link_windowmanager(FileData *fd, wmWindowManager *wm)
+{
+ wmWindow *win;
+
+ id_us_ensure_real(&wm->id);
+ 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);
+
+ direct_link_area_map(fd, &win->global_areas);
+
+ win->ghostwin = NULL;
+ win->gwnctx = NULL;
+ win->eventstate = NULL;
+ win->tweak = NULL;
+#ifdef WIN32
+ win->ime_data = NULL;
+#endif
+
+ BLI_listbase_clear(&win->queue);
+ BLI_listbase_clear(&win->handlers);
+ BLI_listbase_clear(&win->modalhandlers);
+ BLI_listbase_clear(&win->gesture);
+
+ win->active = 0;
+
+ win->cursor = 0;
+ win->lastcursor = 0;
+ win->modalcursor = 0;
+ win->grabcursor = 0;
+ win->addmousemove = true;
+ win->stereo3d_format = newdataadr(fd, win->stereo3d_format);
+
+ /* multiview always fallback to anaglyph at file opening
+ * otherwise quadbuffer saved files can break Blender */
+ if (win->stereo3d_format) {
+ win->stereo3d_format->display_mode = S3D_DISPLAY_ANAGLYPH;
+ }
+ }
+
+ BLI_listbase_clear(&wm->timers);
+ BLI_listbase_clear(&wm->operators);
+ BLI_listbase_clear(&wm->paintcursors);
+ BLI_listbase_clear(&wm->queue);
+ BKE_reports_init(&wm->reports, RPT_STORE);
+
+ BLI_listbase_clear(&wm->keyconfigs);
+ wm->defaultconf = NULL;
+ wm->addonconf = NULL;
+ wm->userconf = NULL;
+ wm->undo_stack = NULL;
+
+ wm->message_bus = NULL;
+
+ BLI_listbase_clear(&wm->jobs);
+ BLI_listbase_clear(&wm->drags);
+
+ wm->windrawable = NULL;
+ wm->winactive = NULL;
+ wm->initialized = 0;
+ wm->op_undo_depth = 0;
+ wm->is_interface_locked = 0;
+}
+
+static void lib_link_windowmanager(FileData *fd, Main *main)
+{
+ wmWindowManager *wm;
+ wmWindow *win;
+
+ for (wm = main->wm.first; wm; wm = wm->id.next) {
+ 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);
+
+ for (ScrArea *area = win->global_areas.areabase.first; area; area = area->next) {
+ lib_link_area(fd, &wm->id, area);
+ }
+ }
+
+ wm->id.tag &= ~LIB_TAG_NEED_LINK;
+ }
+ }
+}
+
+/* ****************** READ SCREEN ***************** */
+
+/* note: file read without screens option G_FILE_NO_UI;
+ * check lib pointers in call below */
+static void lib_link_screen(FileData *fd, Main *main)
+{
+ for (bScreen *sc = main->screen.first; sc; sc = sc->id.next) {
+ if (sc->id.tag & LIB_TAG_NEED_LINK) {
+ 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);
+
+ sc->animtimer = NULL; /* saved in rare cases */
+ sc->tool_tip = NULL;
+ sc->scrubbing = false;
+
+ for (ScrArea *area = sc->areabase.first; area; area = area->next) {
+ lib_link_area(fd, &sc->id, area);
}
sc->id.tag &= ~LIB_TAG_NEED_LINK;
}
@@ -6730,88 +7146,73 @@ 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(struct IDNameLib_Map *id_map, WorkSpace *workspace)
{
- wmWindow *win;
- wmWindowManager *wm;
- bScreen *sc;
- ScrArea *sa;
-
- struct IDNameLib_Map *id_map = BKE_main_idmap_create(newmain);
+ for (WorkSpaceSceneRelation *relation = workspace->scene_layer_relations.first;
+ relation != NULL;
+ relation = relation->next)
+ {
+ relation->scene = restore_pointer_by_name(id_map, &relation->scene->id, USER_IGNORE);
+ }
- /* 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);
+ /* Free any relations that got lost due to missing datablocks or view layers. */
+ BKE_workspace_scene_relations_free_invalid(workspace);
+}
- if (win->screen == NULL)
- win->screen = curscreen;
+static void lib_link_window_scene_data_restore(wmWindow *win, Scene *scene)
+{
+ bScreen *screen = BKE_workspace_active_screen_get(win->workspace_hook);
- win->screen->winid = win->winid;
- }
- }
+ 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->camera == NULL || v3d->scenelock) {
+ v3d->camera = scene->camera;
+ }
- for (sc = newmain->screen.first; sc; sc = sc->id.next) {
- Scene *oldscene = sc->scene;
+ if (v3d->localvd) {
+ /*Base *base;*/
- sc->scene= restore_pointer_by_name(id_map, (ID *)sc->scene, USER_REAL);
- if (sc->scene == NULL)
- sc->scene = curscene;
+ v3d->localvd->camera = scene->camera;
- /* keep cursor location through undo */
- copy_v3_v3(sc->scene->cursor, oldscene->cursor);
+ /* 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 (sa = sc->areabase.first; sa; sa = sa->next) {
- SpaceLink *sl;
+static void lib_link_workspace_layout_restore(struct IDNameLib_Map *id_map, Main *newmain, WorkSpaceLayout *layout)
+{
+ bScreen *screen = BKE_workspace_layout_screen_get(layout);
- for (sl = sa->spacedata.first; sl; sl = sl->next) {
+ /* 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;
@@ -7006,89 +7407,55 @@ void blo_lib_link_screen_restore(Main *newmain, bScreen *curscreen, Scene *cursc
sclip->scopes.ok = 0;
}
- else if (sl->spacetype == SPACE_LOGIC) {
- SpaceLogic *slogic = (SpaceLogic *)sl;
-
- slogic->gpd = restore_pointer_by_name(id_map, (ID *)slogic->gpd, USER_REAL);
- }
}
}
}
-
- /* update IDs stored in all possible clipboards */
- lib_link_clipboard_restore(id_map);
-
- BKE_main_idmap_destroy(id_map);
}
-static void direct_link_region(FileData *fd, ARegion *ar, int spacetype)
+/**
+ * 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, ViewLayer *cur_view_layer)
{
- Panel *pa;
- uiList *ui_list;
-
- link_list(fd, &ar->panels);
-
- for (pa = ar->panels.first; pa; pa = pa->next) {
- pa->paneltab = newdataadr(fd, pa->paneltab);
- pa->runtime_flag = 0;
- pa->activedata = NULL;
- pa->type = NULL;
- }
+ struct IDNameLib_Map *id_map = BKE_main_idmap_create(newmain);
- link_list(fd, &ar->panels_category_active);
+ for (WorkSpace *workspace = newmain->workspaces.first; workspace; workspace = workspace->id.next) {
+ lib_link_workspace_scene_data_restore(id_map, workspace);
+ BKE_workspace_view_layer_set(workspace, cur_view_layer, curscene);
- link_list(fd, &ar->ui_lists);
+ ListBase *layouts = BKE_workspace_layouts_get(workspace);
- for (ui_list = ar->ui_lists.first; ui_list; ui_list = ui_list->next) {
- ui_list->type = NULL;
- ui_list->dyn_data = NULL;
- ui_list->properties = newdataadr(fd, ui_list->properties);
- IDP_DirectLinkGroup_OrFree(&ui_list->properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
+ for (WorkSpaceLayout *layout = layouts->first; layout; layout = layout->next) {
+ lib_link_workspace_layout_restore(id_map, newmain, layout);
+ }
}
- link_list(fd, &ar->ui_previews);
+ 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;
- if (spacetype == SPACE_EMPTY) {
- /* unkown space type, don't leak regiondata */
- ar->regiondata = NULL;
- }
- else if (ar->flag & RGN_FLAG_TEMP_REGIONDATA) {
- /* Runtime data, don't use. */
- ar->regiondata = NULL;
- }
- else {
- ar->regiondata = newdataadr(fd, ar->regiondata);
- if (ar->regiondata) {
- if (spacetype == SPACE_VIEW3D) {
- RegionView3D *rv3d = ar->regiondata;
+ 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);
- rv3d->localvd = newdataadr(fd, rv3d->localvd);
- rv3d->clipbb = newdataadr(fd, rv3d->clipbb);
+ /* keep cursor location through undo */
+ copy_v3_v3(win->scene->cursor.location, oldscene->cursor.location);
+ copy_qt_qt(win->scene->cursor.rotation, oldscene->cursor.rotation);
+ lib_link_window_scene_data_restore(win, win->scene);
- rv3d->depths = NULL;
- rv3d->gpuoffscreen = NULL;
- rv3d->render_engine = NULL;
- rv3d->sms = NULL;
- rv3d->smooth_timer = NULL;
- rv3d->compositor = NULL;
- }
- }
+ BLI_assert(win->screen == NULL);
}
- ar->v2d.tab_offset = NULL;
- ar->v2d.tab_num = 0;
- ar->v2d.tab_cur = 0;
- ar->v2d.sms = NULL;
- BLI_listbase_clear(&ar->panels_category);
- BLI_listbase_clear(&ar->handlers);
- BLI_listbase_clear(&ar->uiblocks);
- ar->headerstr = NULL;
- ar->swinid = 0;
- ar->type = NULL;
- ar->swap = 0;
- ar->do_draw = 0;
- ar->regiontimer = NULL;
- memset(&ar->drawrct, 0, sizeof(ar->drawrct));
+ /* update IDs stored in all possible clipboards */
+ lib_link_clipboard_restore(id_map);
+
+ BKE_main_idmap_destroy(id_map);
}
/* for the saved 2.50 files without regiondata */
@@ -7111,308 +7478,23 @@ void blo_do_versions_view3d_split_250(View3D *v3d, ListBase *regions)
}
/* this was not initialized correct always */
- if (v3d->twtype == 0)
- v3d->twtype = V3D_MANIP_TRANSLATE;
if (v3d->gridsubdiv == 0)
v3d->gridsubdiv = 10;
}
static bool direct_link_screen(FileData *fd, bScreen *sc)
{
- ScrArea *sa;
- ScrVert *sv;
- ScrEdge *se;
bool wrong_id = false;
- link_list(fd, &(sc->vertbase));
- link_list(fd, &(sc->edgebase));
- link_list(fd, &(sc->areabase));
sc->regionbase.first = sc->regionbase.last= NULL;
sc->context = NULL;
+ sc->active_region = NULL;
- sc->mainwin = sc->subwinactive= 0; /* indices */
- sc->swap = 0;
-
- /* edges */
- for (se = sc->edgebase.first; se; se = se->next) {
- se->v1 = newdataadr(fd, se->v1);
- se->v2 = newdataadr(fd, se->v2);
- if ((intptr_t)se->v1 > (intptr_t)se->v2) {
- sv = se->v1;
- se->v1 = se->v2;
- se->v2 = sv;
- }
-
- if (se->v1 == NULL) {
- printf("Error reading Screen %s... removing it.\n", sc->id.name+2);
- BLI_remlink(&sc->edgebase, se);
- wrong_id = true;
- }
- }
-
- /* areas */
- for (sa = sc->areabase.first; sa; sa = sa->next) {
- SpaceLink *sl;
- ARegion *ar;
-
- link_list(fd, &(sa->spacedata));
- link_list(fd, &(sa->regionbase));
-
- BLI_listbase_clear(&sa->handlers);
- sa->type = NULL; /* spacetype callbacks */
- sa->region_active_win = -1;
-
- /* if we do not have the spacetype registered (game player), we cannot
- * free it, so don't allocate any new memory for such spacetypes. */
- if (!BKE_spacetype_exists(sa->spacetype))
- sa->spacetype = SPACE_EMPTY;
-
- for (ar = sa->regionbase.first; ar; ar = ar->next)
- direct_link_region(fd, ar, sa->spacetype);
-
- /* accident can happen when read/save new file with older version */
- /* 2.50: we now always add spacedata for info */
- if (sa->spacedata.first==NULL) {
- SpaceInfo *sinfo= MEM_callocN(sizeof(SpaceInfo), "spaceinfo");
- sa->spacetype= sinfo->spacetype= SPACE_INFO;
- BLI_addtail(&sa->spacedata, sinfo);
- }
- /* add local view3d too */
- else if (sa->spacetype == SPACE_VIEW3D)
- blo_do_versions_view3d_split_250(sa->spacedata.first, &sa->regionbase);
-
- /* incase we set above */
- sa->butspacetype = sa->spacetype;
-
- for (sl = sa->spacedata.first; sl; sl = sl->next) {
- link_list(fd, &(sl->regionbase));
-
- /* if we do not have the spacetype registered (game player), we cannot
- * free it, so don't allocate any new memory for such spacetypes. */
- if (!BKE_spacetype_exists(sl->spacetype))
- sl->spacetype = SPACE_EMPTY;
-
- for (ar = sl->regionbase.first; ar; ar = ar->next)
- direct_link_region(fd, ar, sl->spacetype);
-
- 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);
- }
- v3d->localvd = newdataadr(fd, v3d->localvd);
- BLI_listbase_clear(&v3d->afterdraw_transp);
- BLI_listbase_clear(&v3d->afterdraw_xray);
- BLI_listbase_clear(&v3d->afterdraw_xraytransp);
- v3d->properties_storage = NULL;
- v3d->defmaterial = NULL;
-
- /* render can be quite heavy, set to solid on load */
- if (v3d->drawtype == OB_RENDER)
- v3d->drawtype = OB_SOLID;
- v3d->prev_drawtype = OB_SOLID;
-
- if (v3d->fx_settings.dof)
- v3d->fx_settings.dof = newdataadr(fd, v3d->fx_settings.dof);
- if (v3d->fx_settings.ssao)
- v3d->fx_settings.ssao = newdataadr(fd, v3d->fx_settings.ssao);
-
- blo_do_versions_view3d_split_250(v3d, &sl->regionbase);
- }
- else if (sl->spacetype == SPACE_IPO) {
- SpaceIpo *sipo = (SpaceIpo *)sl;
-
- sipo->ads = newdataadr(fd, sipo->ads);
- BLI_listbase_clear(&sipo->ghostCurves);
- }
- else if (sl->spacetype == SPACE_NLA) {
- SpaceNla *snla = (SpaceNla *)sl;
-
- snla->ads = newdataadr(fd, snla->ads);
- }
- else if (sl->spacetype == SPACE_OUTLINER) {
- SpaceOops *soops = (SpaceOops *) sl;
-
- /* use newdataadr_no_us and do not free old memory avoiding double
- * frees and use of freed memory. this could happen because of a
- * bug fixed in revision 58959 where the treestore memory address
- * was not unique */
- TreeStore *ts = newdataadr_no_us(fd, soops->treestore);
- soops->treestore = NULL;
- if (ts) {
- TreeStoreElem *elems = newdataadr_no_us(fd, ts->data);
-
- soops->treestore = BLI_mempool_create(sizeof(TreeStoreElem), ts->usedelem,
- 512, BLI_MEMPOOL_ALLOW_ITER);
- if (ts->usedelem && elems) {
- int i;
- for (i = 0; i < ts->usedelem; i++) {
- TreeStoreElem *new_elem = BLI_mempool_alloc(soops->treestore);
- *new_elem = elems[i];
- }
- }
- /* we only saved what was used */
- soops->storeflag |= SO_TREESTORE_CLEANUP; // at first draw
- }
- soops->treehash = NULL;
- soops->tree.first = soops->tree.last= NULL;
- }
- else if (sl->spacetype == SPACE_IMAGE) {
- SpaceImage *sima = (SpaceImage *)sl;
-
- sima->iuser.scene = NULL;
- sima->iuser.ok = 1;
- sima->scopes.waveform_1 = NULL;
- sima->scopes.waveform_2 = NULL;
- sima->scopes.waveform_3 = NULL;
- sima->scopes.vecscope = NULL;
- sima->scopes.ok = 0;
-
- /* WARNING: gpencil data is no longer stored directly in sima after 2.5
- * 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);
-#endif
- }
- else if (sl->spacetype == SPACE_NODE) {
- SpaceNode *snode = (SpaceNode *)sl;
-
- if (snode->gpd) {
- snode->gpd = newdataadr(fd, snode->gpd);
- direct_link_gpencil(fd, snode->gpd);
- }
-
- link_list(fd, &snode->treepath);
- snode->edittree = NULL;
- snode->iofsd = NULL;
- BLI_listbase_clear(&snode->linkdrag);
- }
- else if (sl->spacetype == SPACE_TEXT) {
- SpaceText *st= (SpaceText *)sl;
-
- st->drawcache = NULL;
- st->scroll_accum[0] = 0.0f;
- st->scroll_accum[1] = 0.0f;
- }
- else if (sl->spacetype == SPACE_TIME) {
- SpaceTime *stime = (SpaceTime *)sl;
- BLI_listbase_clear(&stime->caches);
- }
- else if (sl->spacetype == SPACE_LOGIC) {
- SpaceLogic *slogic = (SpaceLogic *)sl;
-
- /* XXX: this is new stuff, which shouldn't be directly linking to gpd... */
- if (slogic->gpd) {
- slogic->gpd = newdataadr(fd, slogic->gpd);
- direct_link_gpencil(fd, slogic->gpd);
- }
- }
- else if (sl->spacetype == SPACE_SEQ) {
- SpaceSeq *sseq = (SpaceSeq *)sl;
-
- /* grease pencil data is not a direct data and can't be linked from direct_link*
- * functions, it should be linked from lib_link* functions instead
- *
- * otherwise it'll lead to lost grease data on open because it'll likely be
- * read from file after all other users of grease pencil and newdataadr would
- * simple return NULL here (sergey)
- */
-#if 0
- 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;
- sseq->scopes.waveform_ibuf = NULL;
- sseq->scopes.sep_waveform_ibuf = NULL;
- sseq->scopes.vector_ibuf = NULL;
- sseq->scopes.histogram_ibuf = NULL;
- sseq->compositor = NULL;
- }
- else if (sl->spacetype == SPACE_BUTS) {
- SpaceButs *sbuts = (SpaceButs *)sl;
-
- sbuts->path= NULL;
- sbuts->texuser= NULL;
- sbuts->mainbo = sbuts->mainb;
- sbuts->mainbuser = sbuts->mainb;
- }
- else if (sl->spacetype == SPACE_CONSOLE) {
- SpaceConsole *sconsole = (SpaceConsole *)sl;
- ConsoleLine *cl, *cl_next;
-
- link_list(fd, &sconsole->scrollback);
- link_list(fd, &sconsole->history);
-
- //for (cl= sconsole->scrollback.first; cl; cl= cl->next)
- // cl->line= newdataadr(fd, cl->line);
-
- /* comma expressions, (e.g. expr1, expr2, expr3) evaluate each expression,
- * from left to right. the right-most expression sets the result of the comma
- * expression as a whole*/
- for (cl = sconsole->history.first; cl; cl = cl_next) {
- cl_next = cl->next;
- cl->line = newdataadr(fd, cl->line);
- if (cl->line) {
- /* the allocted length is not written, so reset here */
- cl->len_alloc = cl->len + 1;
- }
- else {
- BLI_remlink(&sconsole->history, cl);
- MEM_freeN(cl);
- }
- }
- }
- else if (sl->spacetype == SPACE_FILE) {
- SpaceFile *sfile = (SpaceFile *)sl;
-
- /* this sort of info is probably irrelevant for reloading...
- * plus, it isn't saved to files yet!
- */
- sfile->folders_prev = sfile->folders_next = NULL;
- sfile->files = NULL;
- sfile->layout = NULL;
- sfile->op = NULL;
- sfile->previews_timer = NULL;
- sfile->params = newdataadr(fd, sfile->params);
- }
- else if (sl->spacetype == SPACE_CLIP) {
- SpaceClip *sclip = (SpaceClip *)sl;
-
- sclip->scopes.track_search = NULL;
- sclip->scopes.track_preview = NULL;
- sclip->scopes.ok = 0;
- }
- }
-
- BLI_listbase_clear(&sa->actionzones);
+ sc->preview = direct_link_preview_image(fd, sc->preview);
- sa->v1 = newdataadr(fd, sa->v1);
- sa->v2 = newdataadr(fd, sa->v2);
- sa->v3 = newdataadr(fd, sa->v3);
- sa->v4 = newdataadr(fd, sa->v4);
+ 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;
}
return wrong_id;
@@ -7506,6 +7588,28 @@ 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->lightprobe.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->visibility_grp = newlibadr(fd, prb->id.lib, prb->visibility_grp);
+
+ 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)
@@ -7578,40 +7682,6 @@ static void lib_link_sound(FileData *fd, Main *main)
}
}
}
-/* ***************** READ GROUP *************** */
-
-static void direct_link_group(FileData *fd, Group *group)
-{
- link_list(fd, &group->gobject);
-
- group->preview = direct_link_preview_image(fd, group->preview);
-}
-
-static void lib_link_group(FileData *fd, Main *bmain)
-{
- for (Group *group = bmain->group.first; group; group = group->id.next) {
- if (group->id.tag & LIB_TAG_NEED_LINK) {
- IDP_LibLinkProperty(group->id.properties, fd);
-
- bool add_us = false;
-
- for (GroupObject *go = group->gobject.first; go; go = go->next) {
- go->ob = newlibadr_real_us(fd, group->id.lib, go->ob);
- if (go->ob) {
- go->ob->flag |= OB_FROMGROUP;
- /* if group has an object, it increments user... */
- add_us = true;
- }
- }
- if (add_us) {
- id_us_ensure_real(&group->id);
- }
- BKE_group_object_unlink(bmain, group, NULL, NULL, NULL); /* removes NULL entries */
-
- group->id.tag &= ~LIB_TAG_NEED_LINK;
- }
- }
-}
/* ***************** READ MOVIECLIP *************** */
@@ -8121,6 +8191,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";
@@ -8133,6 +8204,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";
@@ -8255,6 +8327,7 @@ static BHead *read_libblock(FileData *fd, Main *main, BHead *bhead, const short
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->recalc = 0;
/* this case cannot be direct_linked: it's just the ID part */
@@ -8342,8 +8415,11 @@ 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);
+ direct_link_collection(fd, (Collection *)id);
break;
case ID_AR:
direct_link_armature(fd, (bArmature*)id);
@@ -8381,6 +8457,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);
@@ -8426,6 +8505,7 @@ static BHead *read_global(BlendFileData *bfd, FileData *fd, BHead *bhead)
bfd->curscreen = fg->curscreen;
bfd->curscene = fg->curscene;
+ bfd->cur_view_layer = fg->cur_view_layer;
MEM_freeN(fg);
@@ -8438,6 +8518,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_view_layer = newglobadr(fd, bfd->cur_view_layer);
bfd->curscreen = newlibadr(fd, NULL, bfd->curscreen);
bfd->curscene = newlibadr(fd, NULL, bfd->curscene);
// this happens in files older than 2.35
@@ -8446,27 +8527,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
- /* XXX NOTE: this hack should not beneeded anymore... but will check/remove this in 2.8 code rather */
- // 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)
@@ -8520,6 +8580,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! */
@@ -8533,12 +8594,15 @@ 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)
{
oldnewmap_sort(fd);
+ lib_link_id(fd, main);
+
/* No load UI for undo memfiles */
if (fd->memfile == NULL) {
lib_link_windowmanager(fd, main);
@@ -8561,8 +8625,9 @@ 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_collection(fd, main);
lib_link_armature(fd, main);
lib_link_action(fd, main);
lib_link_vfont(fd, main);
@@ -8576,6 +8641,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 */
}
@@ -8613,6 +8679,7 @@ static BHead *read_userdef(BlendFileData *bfd, FileData *fd, BHead *bhead)
link_list(fd, &user->themes);
link_list(fd, &user->user_keymaps);
+ link_list(fd, &user->user_menus);
link_list(fd, &user->addons);
link_list(fd, &user->autoexec_paths);
@@ -8638,6 +8705,17 @@ static BHead *read_userdef(BlendFileData *bfd, FileData *fd, BHead *bhead)
direct_link_keymapitem(fd, kmi);
}
+ for (bUserMenu *um = user->user_menus.first; um; um = um->next) {
+ link_list(fd, &um->items);
+ for (bUserMenuItem *umi = um->items.first; umi; umi = umi->next) {
+ if (umi->type == USER_MENU_TYPE_OPERATOR) {
+ bUserMenuItem_Op *umi_op = (bUserMenuItem_Op *)umi;
+ umi_op->prop = newdataadr(fd, umi_op->prop);
+ IDP_DirectLinkGroup_OrFree(&umi_op->prop, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
+ }
+ }
+ }
+
for (addon = user->addons.first; addon; addon = addon->next) {
addon->prop = newdataadr(fd, addon->prop);
IDP_DirectLinkGroup_OrFree(&addon->prop, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
@@ -8768,6 +8846,14 @@ BlendFileData *blo_read_file_internal(FileData *fd, const char *filepath)
BKE_main_id_tag_all(bfd->main, LIB_TAG_NEW, false);
+ /* Now that all our data-blocks are loaded, we can re-generate overrides from their references. */
+ if (fd->memfile == NULL) {
+ /* Do not apply in undo case! */
+ lib_verify_nodetree(bfd->main, true); /* Needed to ensure we have typeinfo in nodes... */
+ BKE_main_override_static_update(bfd->main);
+ BKE_collections_after_lib_link(bfd->main);
+ }
+
lib_verify_nodetree(bfd->main, true);
fix_relpaths_library(fd->relabase, bfd->main); /* make all relative paths, relative to the open blend file */
@@ -8968,6 +9054,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);
@@ -9004,6 +9095,14 @@ static void expand_constraint_channels(FileData *fd, Main *mainvar, ListBase *ch
}
}
+static void expand_id(FileData *fd, Main *mainvar, ID *id)
+{
+ if (id->override_static) {
+ expand_doit(fd, mainvar, id->override_static->reference);
+ expand_doit(fd, mainvar, id->override_static->storage);
+ }
+}
+
static void expand_idprops(FileData *fd, Main *mainvar, IDProperty *prop)
{
if (!prop)
@@ -9194,13 +9293,21 @@ static void expand_particlesettings(FileData *fd, Main *mainvar, ParticleSetting
}
}
-static void expand_group(FileData *fd, Main *mainvar, Group *group)
+static void expand_collection(FileData *fd, Main *mainvar, Collection *collection)
{
- GroupObject *go;
+ for (CollectionObject *cob = collection->gobject.first; cob; cob = cob->next) {
+ expand_doit(fd, mainvar, cob->ob);
+ }
+
+ for (CollectionChild *child = collection->children.first; child; child = child->next) {
+ expand_doit(fd, mainvar, child->collection);
+ }
- for (go = group->gobject.first; go; go = go->next) {
- expand_doit(fd, mainvar, go->ob);
+#ifdef USE_COLLECTION_COMPAT_28
+ if (collection->collection != NULL) {
+ expand_scene_collection(fd, mainvar, collection->collection);
}
+#endif
}
static void expand_key(FileData *fd, Main *mainvar, Key *key)
@@ -9263,15 +9370,6 @@ static void expand_brush(FileData *fd, Main *mainvar, Brush *brush)
static void expand_material(FileData *fd, Main *mainvar, Material *ma)
{
- int a;
-
- for (a = 0; a < MAX_MTEX; a++) {
- if (ma->mtex[a]) {
- expand_doit(fd, mainvar, ma->mtex[a]->tex);
- expand_doit(fd, mainvar, ma->mtex[a]->object);
- }
- }
-
expand_doit(fd, mainvar, ma->ipo); // XXX deprecated - old animation system
if (ma->adt)
@@ -9279,22 +9377,10 @@ static void expand_material(FileData *fd, Main *mainvar, Material *ma)
if (ma->nodetree)
expand_nodetree(fd, mainvar, ma->nodetree);
-
- if (ma->group)
- expand_doit(fd, mainvar, ma->group);
}
static void expand_lamp(FileData *fd, Main *mainvar, Lamp *la)
{
- int a;
-
- for (a = 0; a < MAX_MTEX; a++) {
- if (la->mtex[a]) {
- expand_doit(fd, mainvar, la->mtex[a]->tex);
- expand_doit(fd, mainvar, la->mtex[a]->object);
- }
- }
-
expand_doit(fd, mainvar, la->ipo); // XXX deprecated - old animation system
if (la->adt)
@@ -9316,15 +9402,6 @@ static void expand_lattice(FileData *fd, Main *mainvar, Lattice *lt)
static void expand_world(FileData *fd, Main *mainvar, World *wrld)
{
- int a;
-
- for (a = 0; a < MAX_MTEX; a++) {
- if (wrld->mtex[a]) {
- expand_doit(fd, mainvar, wrld->mtex[a]->tex);
- expand_doit(fd, mainvar, wrld->mtex[a]->object);
- }
- }
-
expand_doit(fd, mainvar, wrld->ipo); // XXX deprecated - old animation system
if (wrld->adt)
@@ -9371,9 +9448,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);
@@ -9384,46 +9459,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() */
@@ -9503,9 +9538,6 @@ static void expand_object_expandModifiers(
static void expand_object(FileData *fd, Main *mainvar, Object *ob)
{
ParticleSystem *psys;
- bSensor *sens;
- bController *cont;
- bActuator *act;
bActionStrip *strip;
PartEff *paf;
int a;
@@ -9562,84 +9594,6 @@ static void expand_object(FileData *fd, Main *mainvar, Object *ob)
for (psys = ob->particlesystem.first; psys; psys = psys->next)
expand_doit(fd, mainvar, psys->part);
- for (sens = ob->sensors.first; sens; sens = sens->next) {
- if (sens->type == SENS_MESSAGE) {
- bMessageSensor *ms = sens->data;
- expand_doit(fd, mainvar, ms->fromObject);
- }
- }
-
- for (cont = ob->controllers.first; cont; cont = cont->next) {
- if (cont->type == CONT_PYTHON) {
- bPythonCont *pc = cont->data;
- expand_doit(fd, mainvar, pc->text);
- }
- }
-
- for (act = ob->actuators.first; act; act = act->next) {
- if (act->type == ACT_SOUND) {
- bSoundActuator *sa = act->data;
- expand_doit(fd, mainvar, sa->sound);
- }
- else if (act->type == ACT_CAMERA) {
- bCameraActuator *ca = act->data;
- expand_doit(fd, mainvar, ca->ob);
- }
- else if (act->type == ACT_EDIT_OBJECT) {
- bEditObjectActuator *eoa = act->data;
- if (eoa) {
- expand_doit(fd, mainvar, eoa->ob);
- expand_doit(fd, mainvar, eoa->me);
- }
- }
- else if (act->type == ACT_OBJECT) {
- bObjectActuator *oa = act->data;
- expand_doit(fd, mainvar, oa->reference);
- }
- else if (act->type == ACT_ADD_OBJECT) {
- bAddObjectActuator *aoa = act->data;
- expand_doit(fd, mainvar, aoa->ob);
- }
- else if (act->type == ACT_SCENE) {
- bSceneActuator *sa = act->data;
- expand_doit(fd, mainvar, sa->camera);
- expand_doit(fd, mainvar, sa->scene);
- }
- else if (act->type == ACT_2DFILTER) {
- bTwoDFilterActuator *tdfa = act->data;
- expand_doit(fd, mainvar, tdfa->text);
- }
- else if (act->type == ACT_ACTION) {
- bActionActuator *aa = act->data;
- expand_doit(fd, mainvar, aa->act);
- }
- else if (act->type == ACT_SHAPEACTION) {
- bActionActuator *aa = act->data;
- expand_doit(fd, mainvar, aa->act);
- }
- else if (act->type == ACT_PROPERTY) {
- bPropertyActuator *pa = act->data;
- expand_doit(fd, mainvar, pa->ob);
- }
- else if (act->type == ACT_MESSAGE) {
- bMessageActuator *ma = act->data;
- expand_doit(fd, mainvar, ma->toObject);
- }
- else if (act->type==ACT_PARENT) {
- bParentActuator *pa = act->data;
- expand_doit(fd, mainvar, pa->ob);
- }
- else if (act->type == ACT_ARMATURE) {
- bArmatureActuator *arma = act->data;
- expand_doit(fd, mainvar, arma->target);
- }
- else if (act->type == ACT_STEERING) {
- bSteeringActuator *sta = act->data;
- expand_doit(fd, mainvar, sta->target);
- expand_doit(fd, mainvar, sta->navmesh);
- }
- }
-
if (ob->pd) {
expand_doit(fd, mainvar, ob->pd->tex);
expand_doit(fd, mainvar, ob->pd->f_source);
@@ -9666,15 +9620,27 @@ 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) {
+ expand_doit(fd, mainvar, link->data);
+ }
+
+ for (SceneCollection *nsc = sc->scene_collections.first; nsc; nsc = nsc->next) {
+ expand_scene_collection(fd, mainvar, nsc);
+ }
+}
+#endif
+
static void expand_scene(FileData *fd, Main *mainvar, Scene *sce)
{
- Base *base;
SceneRenderLayer *srl;
FreestyleModuleConfig *module;
FreestyleLineSet *lineset;
- for (base = sce->base.first; base; base = base->next) {
- expand_doit(fd, mainvar, base->object);
+ for (Base *base_legacy = sce->base.first; base_legacy; base_legacy = base_legacy->next) {
+ expand_doit(fd, mainvar, base_legacy->object);
}
expand_doit(fd, mainvar, sce->camera);
expand_doit(fd, mainvar, sce->world);
@@ -9691,7 +9657,6 @@ static void expand_scene(FileData *fd, Main *mainvar, Scene *sce)
for (srl = sce->r.layers.first; srl; srl = srl->next) {
expand_doit(fd, mainvar, srl->mat_override);
- expand_doit(fd, mainvar, srl->light_override);
for (module = srl->freestyleConfig.modules.first; module; module = module->next) {
if (module->script)
expand_doit(fd, mainvar, module->script);
@@ -9703,8 +9668,22 @@ static void expand_scene(FileData *fd, Main *mainvar, Scene *sce)
}
}
- if (sce->r.dometext)
- expand_doit(fd, mainvar, sce->gm.dome.warptext);
+ for (ViewLayer *view_layer = sce->view_layers.first; view_layer; view_layer = view_layer->next) {
+ expand_idprops(fd, mainvar, view_layer->id_properties);
+
+ for (module = view_layer->freestyle_config.modules.first; module; module = module->next) {
+ if (module->script) {
+ expand_doit(fd, mainvar, module->script);
+ }
+ }
+
+ for (lineset = view_layer->freestyle_config.linesets.first; lineset; lineset = lineset->next) {
+ if (lineset->group) {
+ expand_doit(fd, mainvar, lineset->group);
+ }
+ expand_doit(fd, mainvar, lineset->linestyle);
+ }
+ }
if (sce->gpd)
expand_doit(fd, mainvar, sce->gpd);
@@ -9737,6 +9716,16 @@ static void expand_scene(FileData *fd, Main *mainvar, Scene *sce)
}
expand_doit(fd, mainvar, sce->clip);
+
+#ifdef USE_COLLECTION_COMPAT_28
+ if (sce->collection) {
+ expand_scene_collection(fd, mainvar, sce->collection);
+ }
+#endif
+
+ if (sce->master_collection) {
+ expand_collection(fd, mainvar, sce->master_collection);
+ }
}
static void expand_camera(FileData *fd, Main *mainvar, Camera *ca)
@@ -9767,6 +9756,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)
@@ -9840,6 +9835,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.
*
@@ -9873,6 +9877,7 @@ void BLO_expand_main(void *fdhandle, Main *mainvar)
id = lbarray[a]->first;
while (id) {
if (id->tag & LIB_TAG_NEED_EXPAND) {
+ expand_id(fd, mainvar, id);
expand_idprops(fd, mainvar, id->properties);
switch (GS(id->name)) {
@@ -9918,6 +9923,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;
@@ -9925,7 +9933,7 @@ void BLO_expand_main(void *fdhandle, Main *mainvar)
expand_action(fd, mainvar, (bAction *)id); // XXX deprecated - old animation system
break;
case ID_GR:
- expand_group(fd, mainvar, (Group *)id);
+ expand_collection(fd, mainvar, (Collection *)id);
break;
case ID_NT:
expand_nodetree(fd, mainvar, (bNodeTree *)id);
@@ -9954,6 +9962,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;
}
@@ -9971,12 +9981,12 @@ void BLO_expand_main(void *fdhandle, Main *mainvar)
/* ***************************** */
-static bool object_in_any_scene(Main *mainvar, Object *ob)
+static bool object_in_any_scene(Main *bmain, Object *ob)
{
Scene *sce;
- for (sce = mainvar->scene.first; sce; sce = sce->id.next) {
- if (BKE_scene_base_find(sce, ob)) {
+ for (sce = bmain->scene.first; sce; sce = sce->id.next) {
+ if (BKE_scene_object_find(sce, ob)) {
return true;
}
}
@@ -9984,50 +9994,59 @@ 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 Collection *get_collection_active(
+ Main *bmain, Scene *scene, ViewLayer *view_layer, const int flag)
+{
+ if (flag & FILE_ACTIVE_COLLECTION) {
+ LayerCollection *lc = BKE_layer_collection_get_active(view_layer);
+ return lc->collection;
+ }
+ else {
+ return BKE_collection_add(bmain, scene->master_collection, NULL);
+ }
+}
+
+static void add_loose_objects_to_scene(
+ Main *mainvar, Main *bmain, Scene *scene, ViewLayer *view_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;
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 */
- for (ob = mainvar->object.first; ob; ob = ob->id.next) {
+ /* Give all objects which are LIB_TAG_INDIRECT a base, or for a collection when *lib has been set. */
+ for (Object *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;
- if (ob->id.us == 0) {
- do_it = true;
- }
- else if (!is_link && (ob->id.lib == lib) && (object_in_any_scene(mainvar, ob) == 0)) {
- /* When appending, make sure any indirectly loaded objects get a base, else they cant be accessed at all
- * (see T27437). */
- do_it = true;
+ if (!is_link) {
+ if (ob->id.us == 0) {
+ do_it = true;
+ }
+ else if ((ob->id.lib == lib) && (object_in_any_scene(bmain, ob) == 0)) {
+ /* When appending, make sure any indirectly loaded objects get a base, else they cant be accessed at all
+ * (see T27437). */
+ do_it = true;
+ }
}
if (do_it) {
- base = MEM_callocN(sizeof(Base), __func__);
- BLI_addtail(&scene->base, base);
+ CLAMP_MIN(ob->id.us, 0);
+
+ Collection *active_collection = get_collection_active(bmain, scene, view_layer, FILE_ACTIVE_COLLECTION);
+ BKE_collection_object_add(bmain, active_collection, ob);
+ Base *base = BKE_view_layer_base_find(view_layer, ob);
+ BKE_scene_object_base_flag_sync_from_base(base);
- if (active_lay) {
- ob->lay = active_lay;
- }
if (flag & FILE_AUTOSELECT) {
/* Note that link_object_postprocess() already checks for FILE_AUTOSELECT flag,
- * but it will miss objects from non-instantiated groups... */
- ob->flag |= SELECT;
- /* do NOT make base active here! screws up GUI stuff, if you want it do it on src/ level */
+ * but it will miss objects from non-instantiated collections... */
+ if (base->flag & BASE_SELECTABLED) {
+ base->flag |= BASE_SELECTED;
+ BKE_scene_object_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;
}
@@ -10035,36 +10054,46 @@ 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))
+static void add_collections_to_scene(
+ Main *mainvar, Main *bmain, Scene *scene, ViewLayer *view_layer, Library *UNUSED(lib), const short flag)
{
- Group *group;
- Base *base;
- Object *ob;
- const unsigned int active_lay = BKE_screen_view3d_layer_active(v3d, scene);
+ Collection *active_collection = get_collection_active(bmain, scene, view_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 */
- BLI_assert((group->id.tag & LIB_TAG_INDIRECT) == 0);
+ /* Give all objects which are tagged a base. */
+ for (Collection *collection = mainvar->collection.first; collection; collection = collection->id.next) {
+ if (collection->id.tag & LIB_TAG_DOIT) {
+ if (flag & FILE_GROUP_INSTANCE) {
+ /* Any indirect collection should not have been tagged. */
+ BLI_assert((collection->id.tag & LIB_TAG_INDIRECT) == 0);
- /* 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;
+ /* 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;
- /* 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(bmain, active_collection, ob);
+ Base *base = BKE_view_layer_base_find(view_layer, ob);
+
+ 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);
+ view_layer->basact = base;
+
+ /* Assign the collection. */
+ ob->dup_group = collection;
+ id_us_plus(&collection->id);
+ ob->transflag |= OB_DUPLICOLLECTION;
+ copy_v3_v3(ob->loc, scene->cursor.location);
+ }
+ else {
+ /* Add collection as child of active collection. */
+ BKE_collection_child_add(bmain, active_collection, collection);
- /* assign the group */
- ob->dup_group = group;
- ob->transflag |= OB_DUPLIGROUP;
- copy_v3_v3(ob->loc, scene->cursor);
+ collection->id.tag &= ~LIB_TAG_INDIRECT;
+ collection->id.tag |= LIB_TAG_EXTERN;
+ }
}
}
}
@@ -10138,31 +10167,27 @@ static ID *link_named_part(
return id;
}
-static void link_object_postprocess(ID *id, Scene *scene, View3D *v3d, const int flag)
+static void link_object_postprocess(ID *id, Main *bmain, Scene *scene, ViewLayer *view_layer, const int flag)
{
if (scene) {
+ /* link to scene */
Base *base;
Object *ob;
-
- base = MEM_callocN(sizeof(Base), "app_nam_part");
- BLI_addtail(&scene->base, base);
+ Collection *collection;
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);
+
+ collection = get_collection_active(bmain, scene, view_layer, flag);
+ BKE_collection_object_add(bmain, collection, ob);
+ base = BKE_view_layer_base_find(view_layer, 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_object_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 */
}
}
@@ -10192,11 +10217,11 @@ void BLO_library_link_copypaste(Main *mainl, BlendHandle *bh)
id_sort_by_name(lb, id);
if (bhead->code == ID_OB) {
- /* Instead of instancing Base's directly, postpone until after groups are loaded
- * otherwise the base's flag is set incorrectly when groups are used */
+ /* Instead of instancing Base's directly, postpone until after collections are loaded
+ * otherwise the base's flag is set incorrectly when collections are used */
Object *ob = (Object *)id;
ob->mode = OB_MODE_OBJECT;
- /* ensure give_base_to_objects runs on this object */
+ /* ensure add_loose_objects_to_scene runs on this object */
BLI_assert(id->us == 0);
}
}
@@ -10205,17 +10230,16 @@ 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 int flag,
- Scene *scene, View3D *v3d)
+ Main *bmain, Scene *scene, ViewLayer *view_layer)
{
ID *id = link_named_part(mainl, fd, idcode, name, flag);
if (id && (GS(id->name) == ID_OB)) { /* loose object: give a base */
- link_object_postprocess(id, scene, v3d, flag);
+ link_object_postprocess(id, bmain, scene, view_layer, flag);
}
else if (id && (GS(id->name) == ID_GR)) {
- /* tag as needing to be instantiated */
- if (flag & FILE_GROUP_INSTANCE)
- id->tag |= LIB_TAG_DOIT;
+ /* tag as needing to be instantiated or linked */
+ id->tag |= LIB_TAG_DOIT;
}
return id;
@@ -10238,24 +10262,24 @@ ID *BLO_library_link_named_part(Main *mainl, BlendHandle **bh, const short idcod
/**
* Link a named datablock from an external blend file.
- * Optionally instantiate the object/group in the scene when the flags are set.
+ * Optionally instantiate the object/collection in the scene when the flags are set.
*
* \param mainl The main database to link from (not the active one).
* \param bh The blender file handle.
* \param idcode The kind of datablock to link.
* \param name The name of the datablock (without the 2 char ID prefix).
* \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 scene The scene in which to instantiate objects/collections (if NULL, no instantiation is done).
+ * \param v3d The active View3D (only to define active layers for instantiated objects & collections, can be NULL).
* \return the linked ID when found.
*/
ID *BLO_library_link_named_part_ex(
Main *mainl, BlendHandle **bh,
const short idcode, const char *name, const int flag,
- Scene *scene, View3D *v3d)
+ Main *bmain, Scene *scene, ViewLayer *view_layer)
{
FileData *fd = (FileData*)(*bh);
- return link_named_part_ex(mainl, fd, idcode, name, flag, scene, v3d);
+ return link_named_part_ex(mainl, fd, idcode, name, flag, bmain, scene, view_layer);
}
static void link_id_part(ReportList *reports, FileData *fd, Main *mainvar, ID *id, ID **r_id)
@@ -10308,8 +10332,8 @@ static Main *library_link_begin(Main *mainvar, FileData **fd, const char *filepa
(*fd)->mainlist = MEM_callocN(sizeof(ListBase), "FileData.mainlist");
- /* clear for group instantiating tag */
- BKE_main_id_tag_listbase(&(mainvar->group), LIB_TAG_DOIT, false);
+ /* clear for collection instantiating tag */
+ BKE_main_id_tag_listbase(&(mainvar->collection), LIB_TAG_DOIT, false);
/* make mains */
blo_split_main((*fd)->mainlist, mainvar);
@@ -10368,7 +10392,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, Main *bmain, Scene *scene, ViewLayer *view_layer)
{
Main *mainvar;
Library *curlib;
@@ -10398,19 +10422,21 @@ static void library_link_end(Main *mainl, FileData **fd, const short flag, Scene
mainl = NULL; /* blo_join_main free's mainl, cant use anymore */
lib_link_all(*fd, mainvar);
+ BKE_collections_after_lib_link(mainvar);
/* Yep, second splitting... but this is a very cheap operation, so no big deal. */
blo_split_main((*fd)->mainlist, mainvar);
- Main main_newid = {0};
+ Main *main_newid = BKE_main_new();
for (mainvar = ((Main *)(*fd)->mainlist->first)->next; mainvar; mainvar = mainvar->next) {
BLI_assert(mainvar->versionfile != 0);
/* We need to split out IDs already existing, or they will go again through do_versions - bad, very bad! */
- split_main_newid(mainvar, &main_newid);
+ split_main_newid(mainvar, main_newid);
- do_versions_after_linking(&main_newid);
+ do_versions_after_linking(main_newid);
- add_main_to_main(mainvar, &main_newid);
+ add_main_to_main(mainvar, main_newid);
}
+ BKE_main_free(main_newid);
blo_join_main((*fd)->mainlist);
mainvar = (*fd)->mainlist->first;
MEM_freeN((*fd)->mainlist);
@@ -10420,22 +10446,19 @@ static void library_link_end(Main *mainl, FileData **fd, const short flag, Scene
lib_verify_nodetree(mainvar, false);
fix_relpaths_library(BKE_main_blendfile_path(mainvar), mainvar); /* make all relative paths, relative to the open blend file */
- /* Give a base to loose objects. If group append, do it for objects too.
- * Only directly linked objects & groups are instantiated by `BLO_library_link_named_part_ex()` & co,
+ /* Give a base to loose objects and collections.
+ * Only directly linked objects & collections 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);
-
- if (flag & FILE_GROUP_INSTANCE) {
- give_base_to_groups(mainvar, scene, v3d, curlib, flag);
- }
+ add_collections_to_scene(mainvar, bmain, scene, view_layer, curlib, flag);
+ add_loose_objects_to_scene(mainvar, bmain, scene, view_layer, curlib, flag);
}
else {
/* printf("library_append_end, scene is NULL (objects wont get bases)\n"); */
}
- /* clear group instantiating tag */
- BKE_main_id_tag_listbase(&(mainvar->group), LIB_TAG_DOIT, false);
+ /* clear collection instantiating tag */
+ BKE_main_id_tag_listbase(&(mainvar->collection), LIB_TAG_DOIT, false);
/* patch to prevent switch_endian happens twice */
if ((*fd)->flags & FD_FLAGS_SWITCH_ENDIAN) {
@@ -10446,19 +10469,20 @@ static void library_link_end(Main *mainl, FileData **fd, const short flag, Scene
/**
* Finalize linking from a given .blend file (library).
- * Optionally instance the indirect object/group in the scene when the flags are set.
+ * Optionally instance the indirect object/collection in the scene when the flags are set.
* \note Do not use \a bh after calling this function, it may frees it.
*
* \param mainl The main database to link from (not the active one).
* \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 bmain The main database in which to instantiate objects/collections
+ * \param scene The scene in which to instantiate objects/collections (if NULL, no instantiation is done).
+ * \param view_layer The scene layer in which to instantiate objects/collections (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, int flag, Main *bmain, Scene *scene, ViewLayer *view_layer)
{
FileData *fd = (FileData*)(*bh);
- library_link_end(mainl, &fd, flag, scene, v3d);
+ library_link_end(mainl, &fd, flag, bmain, scene, view_layer);
*bh = (BlendHandle*)fd;
}
@@ -10676,19 +10700,19 @@ static void read_libraries(FileData *basefd, ListBase *mainlist)
}
/* do versions, link, and free */
- Main main_newid = {0};
+ Main *main_newid = BKE_main_new();
for (mainptr = mainl->next; mainptr; mainptr = mainptr->next) {
/* some mains still have to be read, then versionfile is still zero! */
if (mainptr->versionfile) {
/* We need to split out IDs already existing, or they will go again through do_versions - bad, very bad! */
- split_main_newid(mainptr, &main_newid);
+ split_main_newid(mainptr, main_newid);
if (mainptr->curlib->filedata) // can be zero... with shift+f1 append
- do_versions(mainptr->curlib->filedata, mainptr->curlib, &main_newid);
+ do_versions(mainptr->curlib->filedata, mainptr->curlib, main_newid);
else
- do_versions(basefd, NULL, &main_newid);
+ do_versions(basefd, NULL, main_newid);
- add_main_to_main(mainptr, &main_newid);
+ add_main_to_main(mainptr, main_newid);
}
if (mainptr->curlib->filedata)
@@ -10697,6 +10721,7 @@ static void read_libraries(FileData *basefd, ListBase *mainlist)
if (mainptr->curlib->filedata) blo_freefiledata(mainptr->curlib->filedata);
mainptr->curlib->filedata = NULL;
}
+ BKE_main_free(main_newid);
}