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/writefile.c')
-rw-r--r--source/blender/blenloader/intern/writefile.c1029
1 files changed, 499 insertions, 530 deletions
diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c
index 0e67bde6883..1a33b9440b5 100644
--- a/source/blender/blenloader/intern/writefile.c
+++ b/source/blender/blenloader/intern/writefile.c
@@ -102,16 +102,18 @@
/* allow writefile to use deprecated functionality (for forward compatibility code) */
#define DNA_DEPRECATED_ALLOW
+/* Allow using DNA struct members that are marked as private for read/write.
+ * Note: Each header that uses this needs to define its own way of handling
+ * it. There's no generic implementation, direct use does nothing. */
+#define DNA_PRIVATE_READ_WRITE_ALLOW
#include "DNA_anim_types.h"
#include "DNA_armature_types.h"
-#include "DNA_actuator_types.h"
#include "DNA_brush_types.h"
#include "DNA_cachefile_types.h"
#include "DNA_camera_types.h"
#include "DNA_cloth_types.h"
#include "DNA_constraint_types.h"
-#include "DNA_controller_types.h"
#include "DNA_dynamicpaint_types.h"
#include "DNA_genfile.h"
#include "DNA_group_types.h"
@@ -120,6 +122,7 @@
#include "DNA_key_types.h"
#include "DNA_lattice_types.h"
#include "DNA_lamp_types.h"
+#include "DNA_layer_types.h"
#include "DNA_linestyle_types.h"
#include "DNA_meta_types.h"
#include "DNA_mesh_types.h"
@@ -130,12 +133,11 @@
#include "DNA_object_force_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_scene_types.h"
#include "DNA_sdna_types.h"
#include "DNA_sequence_types.h"
-#include "DNA_sensor_types.h"
#include "DNA_smoke_types.h"
#include "DNA_space_types.h"
#include "DNA_screen_types.h"
@@ -146,6 +148,7 @@
#include "DNA_vfont_types.h"
#include "DNA_world_types.h"
#include "DNA_windowmanager_types.h"
+#include "DNA_workspace_types.h"
#include "DNA_movieclip_types.h"
#include "DNA_mask_types.h"
@@ -159,10 +162,12 @@
#include "BKE_blender_version.h"
#include "BKE_bpath.h"
#include "BKE_curve.h"
+#include "BKE_collection.h"
#include "BKE_constraint.h"
#include "BKE_global.h" // for G
#include "BKE_idcode.h"
#include "BKE_library.h" // for set_listbasepointers
+#include "BKE_library_override.h"
#include "BKE_main.h"
#include "BKE_node.h"
#include "BKE_report.h"
@@ -172,6 +177,7 @@
#include "BKE_fcurve.h"
#include "BKE_pointcache.h"
#include "BKE_mesh.h"
+#include "BKE_workspace.h"
#ifdef USE_NODE_COMPAT_CUSTOMNODES
#include "NOD_socket.h" /* for sock->default_value data */
@@ -713,6 +719,25 @@ static void write_iddata(void *wd, const ID *id)
if (id->properties && !ELEM(GS(id->name), ID_WM)) {
IDP_WriteProperty(id->properties, wd);
}
+
+ if (id->override_static) {
+ writestruct(wd, DATA, IDOverrideStatic, 1, id->override_static);
+
+ writelist(wd, DATA, IDOverrideStaticProperty, &id->override_static->properties);
+ for (IDOverrideStaticProperty *op = id->override_static->properties.first; op; op = op->next) {
+ writedata(wd, DATA, strlen(op->rna_path) + 1, op->rna_path);
+
+ writelist(wd, DATA, IDOverrideStaticPropertyOperation, &op->operations);
+ for (IDOverrideStaticPropertyOperation *opop = op->operations.first; opop; opop = opop->next) {
+ if (opop->subitem_reference_name) {
+ writedata(wd, DATA, strlen(opop->subitem_reference_name) + 1, opop->subitem_reference_name);
+ }
+ if (opop->subitem_local_name) {
+ writedata(wd, DATA, strlen(opop->subitem_local_name) + 1, opop->subitem_local_name);
+ }
+ }
+ }
+ }
}
static void write_previews(WriteData *wd, const PreviewImage *prv_orig)
@@ -1116,10 +1141,13 @@ static void write_nodetree_nolib(WriteData *wd, bNodeTree *ntree)
* Take care using 'use_active_win', since we wont want the currently active window
* to change which scene renders (currently only used for undo).
*/
-static void current_screen_compat(Main *mainvar, bScreen **r_screen, bool use_active_win)
+static void current_screen_compat(
+ Main *mainvar, bool use_active_win,
+ bScreen **r_screen, Scene **r_scene, ViewLayer **r_render_layer)
{
wmWindowManager *wm;
wmWindow *window = NULL;
+ WorkSpace *workspace;
/* find a global current screen in the first open window, to have
* a reasonable default for reading in older versions */
@@ -1143,8 +1171,11 @@ static void current_screen_compat(Main *mainvar, bScreen **r_screen, bool use_ac
window = wm->windows.first;
}
}
+ workspace = (window) ? BKE_workspace_active_get(window->workspace_hook) : NULL;
- *r_screen = (window) ? window->screen : NULL;
+ *r_screen = (window) ? BKE_workspace_active_screen_get(window->workspace_hook) : NULL;
+ *r_scene = (window) ? window->scene : NULL;
+ *r_render_layer = (window) ? BKE_workspace_view_layer_get(workspace, *r_scene) : NULL;
}
typedef struct RenderInfo {
@@ -1160,13 +1191,11 @@ static void write_renderinfo(WriteData *wd, Main *mainvar)
{
bScreen *curscreen;
Scene *sce, *curscene = NULL;
+ ViewLayer *render_layer;
RenderInfo data;
/* XXX in future, handle multiple windows with multiple screens? */
- current_screen_compat(mainvar, &curscreen, false);
- if (curscreen) {
- curscene = curscreen->scene;
- }
+ current_screen_compat(mainvar, false, &curscreen, &curscene, &render_layer);
for (sce = mainvar->scene.first; sce; sce = sce->id.next) {
if (sce->id.lib == NULL && (sce == curscene || (sce->r.scemode & R_BG_RENDER))) {
@@ -1215,6 +1244,22 @@ static void write_userdef(WriteData *wd, const UserDef *userdef)
}
}
+ for (const bUserMenu *um = userdef->user_menus.first; um; um = um->next) {
+ writestruct(wd, DATA, bUserMenu, 1, um);
+ for (const bUserMenuItem *umi = um->items.first; umi; umi = umi->next) {
+ if (umi->type == USER_MENU_TYPE_OPERATOR) {
+ const bUserMenuItem_Op *umi_op = (const bUserMenuItem_Op *)umi;
+ writestruct(wd, DATA, bUserMenuItem_Op, 1, umi_op);
+ if (umi_op->prop) {
+ IDP_WriteProperty(umi_op->prop, wd);
+ }
+ }
+ else {
+ writestruct(wd, DATA, bUserMenuItem, 1, umi);
+ }
+ }
+ }
+
for (const bAddon *bext = userdef->addons.first; bext; bext = bext->next) {
writestruct(wd, DATA, bAddon, 1, bext);
if (bext->prop) {
@@ -1351,9 +1396,13 @@ static void write_particlesettings(WriteData *wd, ParticleSettings *part)
if (dw->ob != NULL) {
dw->index = 0;
if (part->dup_group) { /* can be NULL if lining fails or set to None */
- for (GroupObject *go = part->dup_group->gobject.first;
- go && go->ob != dw->ob;
- go = go->next, dw->index++);
+ FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN(part->dup_group, object)
+ {
+ if (object != dw->ob) {
+ dw->index++;
+ }
+ }
+ FOREACH_COLLECTION_OBJECT_RECURSIVE_END;
}
}
writestruct(wd, DATA, ParticleDupliWeight, 1, dw);
@@ -1430,180 +1479,6 @@ static void write_particlesystems(WriteData *wd, ListBase *particles)
}
}
-static void write_properties(WriteData *wd, ListBase *lb)
-{
- bProperty *prop;
-
- prop = lb->first;
- while (prop) {
- writestruct(wd, DATA, bProperty, 1, prop);
-
- if (prop->poin && prop->poin != &prop->data) {
- writedata(wd, DATA, MEM_allocN_len(prop->poin), prop->poin);
- }
-
- prop = prop->next;
- }
-}
-
-static void write_sensors(WriteData *wd, ListBase *lb)
-{
- bSensor *sens;
-
- sens = lb->first;
- while (sens) {
- writestruct(wd, DATA, bSensor, 1, sens);
-
- writedata(wd, DATA, sizeof(void *) * sens->totlinks, sens->links);
-
- switch (sens->type) {
- case SENS_NEAR:
- writestruct(wd, DATA, bNearSensor, 1, sens->data);
- break;
- case SENS_MOUSE:
- writestruct(wd, DATA, bMouseSensor, 1, sens->data);
- break;
- case SENS_KEYBOARD:
- writestruct(wd, DATA, bKeyboardSensor, 1, sens->data);
- break;
- case SENS_PROPERTY:
- writestruct(wd, DATA, bPropertySensor, 1, sens->data);
- break;
- case SENS_ARMATURE:
- writestruct(wd, DATA, bArmatureSensor, 1, sens->data);
- break;
- case SENS_ACTUATOR:
- writestruct(wd, DATA, bActuatorSensor, 1, sens->data);
- break;
- case SENS_DELAY:
- writestruct(wd, DATA, bDelaySensor, 1, sens->data);
- break;
- case SENS_COLLISION:
- writestruct(wd, DATA, bCollisionSensor, 1, sens->data);
- break;
- case SENS_RADAR:
- writestruct(wd, DATA, bRadarSensor, 1, sens->data);
- break;
- case SENS_RANDOM:
- writestruct(wd, DATA, bRandomSensor, 1, sens->data);
- break;
- case SENS_RAY:
- writestruct(wd, DATA, bRaySensor, 1, sens->data);
- break;
- case SENS_MESSAGE:
- writestruct(wd, DATA, bMessageSensor, 1, sens->data);
- break;
- case SENS_JOYSTICK:
- writestruct(wd, DATA, bJoystickSensor, 1, sens->data);
- break;
- default:
- ; /* error: don't know how to write this file */
- }
-
- sens = sens->next;
- }
-}
-
-static void write_controllers(WriteData *wd, ListBase *lb)
-{
- bController *cont;
-
- cont = lb->first;
- while (cont) {
- writestruct(wd, DATA, bController, 1, cont);
-
- writedata(wd, DATA, sizeof(void *) * cont->totlinks, cont->links);
-
- switch (cont->type) {
- case CONT_EXPRESSION:
- writestruct(wd, DATA, bExpressionCont, 1, cont->data);
- break;
- case CONT_PYTHON:
- writestruct(wd, DATA, bPythonCont, 1, cont->data);
- break;
- default:
- ; /* error: don't know how to write this file */
- }
-
- cont = cont->next;
- }
-}
-
-static void write_actuators(WriteData *wd, ListBase *lb)
-{
- bActuator *act;
-
- act = lb->first;
- while (act) {
- writestruct(wd, DATA, bActuator, 1, act);
-
- switch (act->type) {
- case ACT_ACTION:
- case ACT_SHAPEACTION:
- writestruct(wd, DATA, bActionActuator, 1, act->data);
- break;
- case ACT_SOUND:
- writestruct(wd, DATA, bSoundActuator, 1, act->data);
- break;
- case ACT_OBJECT:
- writestruct(wd, DATA, bObjectActuator, 1, act->data);
- break;
- case ACT_PROPERTY:
- writestruct(wd, DATA, bPropertyActuator, 1, act->data);
- break;
- case ACT_CAMERA:
- writestruct(wd, DATA, bCameraActuator, 1, act->data);
- break;
- case ACT_CONSTRAINT:
- writestruct(wd, DATA, bConstraintActuator, 1, act->data);
- break;
- case ACT_EDIT_OBJECT:
- writestruct(wd, DATA, bEditObjectActuator, 1, act->data);
- break;
- case ACT_SCENE:
- writestruct(wd, DATA, bSceneActuator, 1, act->data);
- break;
- case ACT_GROUP:
- writestruct(wd, DATA, bGroupActuator, 1, act->data);
- break;
- case ACT_RANDOM:
- writestruct(wd, DATA, bRandomActuator, 1, act->data);
- break;
- case ACT_MESSAGE:
- writestruct(wd, DATA, bMessageActuator, 1, act->data);
- break;
- case ACT_GAME:
- writestruct(wd, DATA, bGameActuator, 1, act->data);
- break;
- case ACT_VISIBILITY:
- writestruct(wd, DATA, bVisibilityActuator, 1, act->data);
- break;
- case ACT_2DFILTER:
- writestruct(wd, DATA, bTwoDFilterActuator, 1, act->data);
- break;
- case ACT_PARENT:
- writestruct(wd, DATA, bParentActuator, 1, act->data);
- break;
- case ACT_STATE:
- writestruct(wd, DATA, bStateActuator, 1, act->data);
- break;
- case ACT_ARMATURE:
- writestruct(wd, DATA, bArmatureActuator, 1, act->data);
- break;
- case ACT_STEERING:
- writestruct(wd, DATA, bSteeringActuator, 1, act->data);
- break;
- case ACT_MOUSE:
- writestruct(wd, DATA, bMouseActuator, 1, act->data);
- break;
- default:
- ; /* error: don't know how to write this file */
- }
-
- act = act->next;
- }
-}
-
static void write_motionpath(WriteData *wd, bMotionPath *mpath)
{
/* sanity checks */
@@ -1722,6 +1597,13 @@ static void write_defgroups(WriteData *wd, ListBase *defbase)
}
}
+static void write_fmaps(WriteData *wd, ListBase *fbase)
+{
+ for (bFaceMap *fmap = fbase->first; fmap; fmap = fmap->next) {
+ writestruct(wd, DATA, bFaceMap, 1, fmap);
+ }
+}
+
static void write_modifiers(WriteData *wd, ListBase *modbase)
{
ModifierData *md;
@@ -1759,6 +1641,8 @@ static void write_modifiers(WriteData *wd, ListBase *modbase)
SmokeModifierData *smd = (SmokeModifierData *)md;
if (smd->type & MOD_SMOKE_TYPE_DOMAIN) {
+ writestruct(wd, DATA, SmokeDomainSettings, 1, smd->domain);
+
if (smd->domain) {
write_pointcaches(wd, &(smd->domain->ptcaches[0]));
@@ -1772,11 +1656,8 @@ static void write_modifiers(WriteData *wd, ListBase *modbase)
if (smd->domain->coba) {
writestruct(wd, DATA, ColorBand, 1, smd->domain->coba);
}
- }
- writestruct(wd, DATA, SmokeDomainSettings, 1, smd->domain);
- if (smd->domain) {
/* cleanup the fake pointcache */
BKE_ptcache_free_list(&smd->domain->ptcaches[1]);
smd->domain->point_cache[1] = NULL;
@@ -1912,10 +1793,6 @@ static void write_object(WriteData *wd, Object *ob)
writedata(wd, DATA, sizeof(void *) * ob->totcol, ob->mat);
writedata(wd, DATA, sizeof(char) * ob->totcol, ob->matbits);
/* write_effects(wd, &ob->effect); */ /* not used anymore */
- write_properties(wd, &ob->prop);
- write_sensors(wd, &ob->sensors);
- write_controllers(wd, &ob->controllers);
- write_actuators(wd, &ob->actuators);
if (ob->type == OB_ARMATURE) {
bArmature *arm = ob->data;
@@ -1926,6 +1803,7 @@ static void write_object(WriteData *wd, Object *ob)
write_pose(wd, ob->pose);
write_defgroups(wd, &ob->defbase);
+ write_fmaps(wd, &ob->fmaps);
write_constraints(wd, &ob->constraints);
write_motionpath(wd, ob->mpath);
@@ -1935,7 +1813,6 @@ static void write_object(WriteData *wd, Object *ob)
write_pointcaches(wd, &ob->soft->ptcaches);
writestruct(wd, DATA, EffectorWeights, 1, ob->soft->effector_weights);
}
- writestruct(wd, DATA, BulletSoftBody, 1, ob->bsoft);
if (ob->rigidbody_object) {
/* TODO: if any extra data is added to handle duplis, will need separate function then */
@@ -2008,6 +1885,10 @@ static void write_camera(WriteData *wd, Camera *cam)
if (cam->adt) {
write_animdata(wd, cam->adt);
}
+
+ for (CameraBGImage *bgpic = cam->bg_images.first; bgpic; bgpic = bgpic->next) {
+ writestruct(wd, DATA, CameraBGImage, 1, bgpic);
+ }
}
}
@@ -2158,6 +2039,10 @@ static void write_customdata(
else if (layer->type == CD_GRID_PAINT_MASK) {
write_grid_paint_mask(wd, count, layer->data);
}
+ else if (layer->type == CD_FACEMAP) {
+ const int *layer_data = layer->data;
+ writedata(wd, DATA, sizeof(*layer_data) * count, layer_data);
+ }
else {
CustomData_file_write_info(layer->type, &structname, &structnum);
if (structnum) {
@@ -2391,6 +2276,8 @@ static void write_image(WriteData *wd, Image *ima)
writestruct(wd, DATA, Stereo3dFormat, 1, ima->stereo3d_format);
ima->packedfile = NULL;
+
+ writelist(wd, DATA, RenderSlot, &ima->renderslots);
}
}
@@ -2409,24 +2296,6 @@ static void write_texture(WriteData *wd, Tex *tex)
if (tex->coba) {
writestruct(wd, DATA, ColorBand, 1, tex->coba);
}
- if (tex->type == TEX_ENVMAP && tex->env) {
- writestruct(wd, DATA, EnvMap, 1, tex->env);
- }
- if (tex->type == TEX_POINTDENSITY && tex->pd) {
- writestruct(wd, DATA, PointDensity, 1, tex->pd);
- if (tex->pd->coba) {
- writestruct(wd, DATA, ColorBand, 1, tex->pd->coba);
- }
- if (tex->pd->falloff_curve) {
- write_curvemapping(wd, tex->pd->falloff_curve);
- }
- }
- if (tex->type == TEX_VOXELDATA) {
- writestruct(wd, DATA, VoxelData, 1, tex->vd);
- }
- if (tex->type == TEX_OCEAN && tex->ot) {
- writestruct(wd, DATA, OceanTex, 1, tex->ot);
- }
/* nodetree is integral part of texture, no libdata */
if (tex->nodetree) {
@@ -2449,19 +2318,6 @@ static void write_material(WriteData *wd, Material *ma)
write_animdata(wd, ma->adt);
}
- for (int a = 0; a < MAX_MTEX; a++) {
- if (ma->mtex[a]) {
- writestruct(wd, DATA, MTex, 1, ma->mtex[a]);
- }
- }
-
- if (ma->ramp_col) {
- writestruct(wd, DATA, ColorBand, 1, ma->ramp_col);
- }
- if (ma->ramp_spec) {
- writestruct(wd, DATA, ColorBand, 1, ma->ramp_spec);
- }
-
/* nodetree is integral part of material, no libdata */
if (ma->nodetree) {
writestruct(wd, DATA, bNodeTree, 1, ma->nodetree);
@@ -2483,12 +2339,6 @@ static void write_world(WriteData *wd, World *wrld)
write_animdata(wd, wrld->adt);
}
- for (int a = 0; a < MAX_MTEX; a++) {
- if (wrld->mtex[a]) {
- writestruct(wd, DATA, MTex, 1, wrld->mtex[a]);
- }
- }
-
/* nodetree is integral part of world, no libdata */
if (wrld->nodetree) {
writestruct(wd, DATA, bNodeTree, 1, wrld->nodetree);
@@ -2510,13 +2360,6 @@ static void write_lamp(WriteData *wd, Lamp *la)
write_animdata(wd, la->adt);
}
- /* direct data */
- for (int a = 0; a < MAX_MTEX; a++) {
- if (la->mtex[a]) {
- writestruct(wd, DATA, MTex, 1, la->mtex[a]);
- }
- }
-
if (la->curfalloff) {
write_curvemapping(wd, la->curfalloff);
}
@@ -2531,6 +2374,31 @@ static void write_lamp(WriteData *wd, Lamp *la)
}
}
+static void write_collection_nolib(WriteData *wd, Collection *collection)
+{
+ /* Shared function for collection datablocks and scene master collection. */
+ write_previews(wd, collection->preview);
+
+ for (CollectionObject *cob = collection->gobject.first; cob; cob = cob->next) {
+ writestruct(wd, DATA, CollectionObject, 1, cob);
+ }
+
+ for (CollectionChild *child = collection->children.first; child; child = child->next) {
+ writestruct(wd, DATA, CollectionChild, 1, child);
+ }
+}
+
+static void write_collection(WriteData *wd, Collection *collection)
+{
+ if (collection->id.us > 0 || wd->use_memfile) {
+ /* write LibData */
+ writestruct(wd, ID_GR, Collection, 1, collection);
+ write_iddata(wd, &collection->id);
+
+ write_collection_nolib(wd, collection);
+ }
+}
+
static void write_sequence_modifiers(WriteData *wd, ListBase *modbase)
{
SequenceModifierData *smd;
@@ -2572,6 +2440,34 @@ static void write_paint(WriteData *wd, Paint *p)
}
}
+static void write_layer_collections(WriteData *wd, ListBase *lb)
+{
+ for (LayerCollection *lc = lb->first; lc; lc = lc->next) {
+ writestruct(wd, DATA, LayerCollection, 1, lc);
+
+ write_layer_collections(wd, &lc->layer_collections);
+ }
+}
+
+static void write_view_layer(WriteData *wd, ViewLayer *view_layer)
+{
+ writestruct(wd, DATA, ViewLayer, 1, view_layer);
+ writelist(wd, DATA, Base, &view_layer->object_bases);
+
+ if (view_layer->id_properties) {
+ IDP_WriteProperty(view_layer->id_properties, wd);
+ }
+
+ for (FreestyleModuleConfig *fmc = view_layer->freestyle_config.modules.first; fmc; fmc = fmc->next) {
+ writestruct(wd, DATA, FreestyleModuleConfig, 1, fmc);
+ }
+
+ for (FreestyleLineSet *fls = view_layer->freestyle_config.linesets.first; fls; fls = fls->next) {
+ writestruct(wd, DATA, FreestyleLineSet, 1, fls);
+ }
+ write_layer_collections(wd, &view_layer->layer_collections);
+}
+
static void write_scene(WriteData *wd, Scene *sce)
{
/* write LibData */
@@ -2584,10 +2480,6 @@ static void write_scene(WriteData *wd, Scene *sce)
write_keyingsets(wd, &sce->keyingsets);
/* direct data */
- for (Base *base = sce->base.first; base; base = base->next) {
- writestruct(wd, DATA, Base, 1, base);
- }
-
ToolSettings *tos = sce->toolsettings;
writestruct(wd, DATA, ToolSettings, 1, tos);
if (tos->vpaint) {
@@ -2740,19 +2632,6 @@ static void write_scene(WriteData *wd, Scene *sce)
writestruct(wd, DATA, TransformOrientation, 1, ts);
}
- for (SceneRenderLayer *srl = sce->r.layers.first; srl; srl = srl->next) {
- writestruct(wd, DATA, SceneRenderLayer, 1, srl);
- if (srl->prop) {
- IDP_WriteProperty(srl->prop, wd);
- }
- for (FreestyleModuleConfig *fmc = srl->freestyleConfig.modules.first; fmc; fmc = fmc->next) {
- writestruct(wd, DATA, FreestyleModuleConfig, 1, fmc);
- }
- for (FreestyleLineSet *fls = srl->freestyleConfig.linesets.first; fls; fls = fls->next) {
- writestruct(wd, DATA, FreestyleLineSet, 1, fls);
- }
- }
-
/* writing MultiView to the blend file */
for (SceneRenderView *srv = sce->r.views.first; srv; srv = srv->next) {
writestruct(wd, DATA, SceneRenderView, 1, srv);
@@ -2774,6 +2653,18 @@ static void write_scene(WriteData *wd, Scene *sce)
write_previews(wd, sce->preview);
write_curvemapping_curves(wd, &sce->r.mblur_shutter_curve);
+
+ for (ViewLayer *view_layer = sce->view_layers.first; view_layer; view_layer = view_layer->next) {
+ write_view_layer(wd, view_layer);
+ }
+
+ if (sce->master_collection) {
+ writestruct(wd, DATA, Collection, 1, sce->master_collection);
+ write_collection_nolib(wd, sce->master_collection);
+ }
+
+ /* Freed on doversion. */
+ BLI_assert(sce->layer_properties == NULL);
}
static void write_gpencil(WriteData *wd, bGPdata *gpd)
@@ -2809,17 +2700,6 @@ static void write_gpencil(WriteData *wd, bGPdata *gpd)
}
}
-static void write_windowmanager(WriteData *wd, wmWindowManager *wm)
-{
- writestruct(wd, ID_WM, wmWindowManager, 1, wm);
- write_iddata(wd, &wm->id);
-
- for (wmWindow *win = wm->windows.first; win; win = win->next) {
- writestruct(wd, DATA, wmWindow, 1, win);
- writestruct(wd, DATA, Stereo3dFormat, 1, win->stereo3d_format);
- }
-}
-
static void write_region(WriteData *wd, ARegion *ar, int spacetype)
{
writestruct(wd, DATA, ARegion, 1, ar);
@@ -2904,170 +2784,210 @@ static void write_soops(WriteData *wd, SpaceOops *so)
}
}
-static void write_screen(WriteData *wd, bScreen *sc)
+static void write_panel_list(WriteData *wd, ListBase *lb)
{
- /* write LibData */
- /* in 2.50+ files, the file identifier for screens is patched, forward compatibility */
- writestruct(wd, ID_SCRN, bScreen, 1, sc);
- write_iddata(wd, &sc->id);
-
- /* direct data */
- for (ScrVert *sv = sc->vertbase.first; sv; sv = sv->next) {
- writestruct(wd, DATA, ScrVert, 1, sv);
+ for (Panel *pa = lb->first; pa; pa = pa->next) {
+ writestruct(wd, DATA, Panel, 1, pa);
+ write_panel_list(wd, &pa->children);
}
+}
- for (ScrEdge *se = sc->edgebase.first; se; se = se->next) {
- writestruct(wd, DATA, ScrEdge, 1, se);
- }
+static void write_area_regions(WriteData *wd, ScrArea *area)
+{
+ for (ARegion *region = area->regionbase.first; region; region = region->next) {
+ write_region(wd, region, area->spacetype);
+ write_panel_list(wd, &region->panels);
+
+ for (PanelCategoryStack *pc_act = region->panels_category_active.first; pc_act; pc_act = pc_act->next) {
+ writestruct(wd, DATA, PanelCategoryStack, 1, pc_act);
+ }
+
+ for (uiList *ui_list = region->ui_lists.first; ui_list; ui_list = ui_list->next) {
+ write_uilist(wd, ui_list);
+ }
- for (ScrArea *sa = sc->areabase.first; sa; sa = sa->next) {
- SpaceLink *sl;
- Panel *pa;
- uiList *ui_list;
- uiPreview *ui_preview;
- PanelCategoryStack *pc_act;
- ARegion *ar;
+ for (uiPreview *ui_preview = region->ui_previews.first; ui_preview; ui_preview = ui_preview->next) {
+ writestruct(wd, DATA, uiPreview, 1, ui_preview);
+ }
+ }
- writestruct(wd, DATA, ScrArea, 1, sa);
+ for (SpaceLink *sl = area->spacedata.first; sl; sl = sl->next) {
+ for (ARegion *region = sl->regionbase.first; region; region = region->next) {
+ write_region(wd, region, sl->spacetype);
+ }
- for (ar = sa->regionbase.first; ar; ar = ar->next) {
- write_region(wd, ar, sa->spacetype);
+ if (sl->spacetype == SPACE_VIEW3D) {
+ View3D *v3d = (View3D *)sl;
+ writestruct(wd, DATA, View3D, 1, v3d);
- for (pa = ar->panels.first; pa; pa = pa->next) {
- writestruct(wd, DATA, Panel, 1, pa);
+ if (v3d->localvd) {
+ writestruct(wd, DATA, View3D, 1, v3d->localvd);
}
- for (pc_act = ar->panels_category_active.first; pc_act; pc_act = pc_act->next) {
- writestruct(wd, DATA, PanelCategoryStack, 1, pc_act);
+ if (v3d->fx_settings.ssao) {
+ writestruct(wd, DATA, GPUSSAOSettings, 1, v3d->fx_settings.ssao);
+ }
+ if (v3d->fx_settings.dof) {
+ writestruct(wd, DATA, GPUDOFSettings, 1, v3d->fx_settings.dof);
}
+ }
+ else if (sl->spacetype == SPACE_IPO) {
+ SpaceIpo *sipo = (SpaceIpo *)sl;
+ ListBase tmpGhosts = sipo->ghostCurves;
- for (ui_list = ar->ui_lists.first; ui_list; ui_list = ui_list->next) {
- write_uilist(wd, ui_list);
+ /* temporarily disable ghost curves when saving */
+ sipo->ghostCurves.first = sipo->ghostCurves.last = NULL;
+
+ writestruct(wd, DATA, SpaceIpo, 1, sl);
+ if (sipo->ads) {
+ writestruct(wd, DATA, bDopeSheet, 1, sipo->ads);
}
- for (ui_preview = ar->ui_previews.first; ui_preview; ui_preview = ui_preview->next) {
- writestruct(wd, DATA, uiPreview, 1, ui_preview);
+ /* reenable ghost curves */
+ sipo->ghostCurves = tmpGhosts;
+ }
+ else if (sl->spacetype == SPACE_BUTS) {
+ writestruct(wd, DATA, SpaceButs, 1, sl);
+ }
+ else if (sl->spacetype == SPACE_FILE) {
+ SpaceFile *sfile = (SpaceFile *)sl;
+
+ writestruct(wd, DATA, SpaceFile, 1, sl);
+ if (sfile->params) {
+ writestruct(wd, DATA, FileSelectParams, 1, sfile->params);
}
}
+ else if (sl->spacetype == SPACE_SEQ) {
+ writestruct(wd, DATA, SpaceSeq, 1, sl);
+ }
+ else if (sl->spacetype == SPACE_OUTLINER) {
+ SpaceOops *so = (SpaceOops *)sl;
+ write_soops(wd, so);
+ }
+ else if (sl->spacetype == SPACE_IMAGE) {
+ writestruct(wd, DATA, SpaceImage, 1, sl);
+ }
+ else if (sl->spacetype == SPACE_TEXT) {
+ writestruct(wd, DATA, SpaceText, 1, sl);
+ }
+ else if (sl->spacetype == SPACE_SCRIPT) {
+ SpaceScript *scr = (SpaceScript *)sl;
+ scr->but_refs = NULL;
+ writestruct(wd, DATA, SpaceScript, 1, sl);
+ }
+ else if (sl->spacetype == SPACE_ACTION) {
+ writestruct(wd, DATA, SpaceAction, 1, sl);
+ }
+ else if (sl->spacetype == SPACE_NLA) {
+ SpaceNla *snla = (SpaceNla *)sl;
- for (sl = sa->spacedata.first; sl; sl = sl->next) {
- for (ar = sl->regionbase.first; ar; ar = ar->next) {
- write_region(wd, ar, sl->spacetype);
+ writestruct(wd, DATA, SpaceNla, 1, snla);
+ if (snla->ads) {
+ writestruct(wd, DATA, bDopeSheet, 1, snla->ads);
}
+ }
+ else if (sl->spacetype == SPACE_NODE) {
+ SpaceNode *snode = (SpaceNode *)sl;
+ bNodeTreePath *path;
+ writestruct(wd, DATA, SpaceNode, 1, snode);
- if (sl->spacetype == SPACE_VIEW3D) {
- View3D *v3d = (View3D *)sl;
- BGpic *bgpic;
- writestruct(wd, DATA, View3D, 1, v3d);
- for (bgpic = v3d->bgpicbase.first; bgpic; bgpic = bgpic->next) {
- writestruct(wd, DATA, BGpic, 1, bgpic);
- }
- if (v3d->localvd) {
- writestruct(wd, DATA, View3D, 1, v3d->localvd);
- }
+ for (path = snode->treepath.first; path; path = path->next) {
+ writestruct(wd, DATA, bNodeTreePath, 1, path);
+ }
+ }
+ else if (sl->spacetype == SPACE_CONSOLE) {
+ SpaceConsole *con = (SpaceConsole *)sl;
+ ConsoleLine *cl;
- if (v3d->fx_settings.ssao) {
- writestruct(wd, DATA, GPUSSAOSettings, 1, v3d->fx_settings.ssao);
- }
- if (v3d->fx_settings.dof) {
- writestruct(wd, DATA, GPUDOFSettings, 1, v3d->fx_settings.dof);
- }
+ for (cl = con->history.first; cl; cl = cl->next) {
+ /* 'len_alloc' is invalid on write, set from 'len' on read */
+ writestruct(wd, DATA, ConsoleLine, 1, cl);
+ writedata(wd, DATA, cl->len + 1, cl->line);
}
- else if (sl->spacetype == SPACE_IPO) {
- SpaceIpo *sipo = (SpaceIpo *)sl;
- ListBase tmpGhosts = sipo->ghostCurves;
+ writestruct(wd, DATA, SpaceConsole, 1, sl);
+ }
+#ifdef WITH_GLOBAL_AREA_WRITING
+ else if (sl->spacetype == SPACE_TOPBAR) {
+ writestruct(wd, DATA, SpaceTopBar, 1, sl);
+ }
+ else if (sl->spacetype == SPACE_STATUSBAR) {
+ writestruct(wd, DATA, SpaceStatusBar, 1, sl);
+ }
+#endif
+ else if (sl->spacetype == SPACE_USERPREF) {
+ writestruct(wd, DATA, SpaceUserPref, 1, sl);
+ }
+ else if (sl->spacetype == SPACE_CLIP) {
+ writestruct(wd, DATA, SpaceClip, 1, sl);
+ }
+ else if (sl->spacetype == SPACE_INFO) {
+ writestruct(wd, DATA, SpaceInfo, 1, sl);
+ }
+ }
+}
- /* temporarily disable ghost curves when saving */
- sipo->ghostCurves.first = sipo->ghostCurves.last = NULL;
+static void write_area_map(WriteData *wd, ScrAreaMap *area_map)
+{
+ writelist(wd, DATA, ScrVert, &area_map->vertbase);
+ writelist(wd, DATA, ScrEdge, &area_map->edgebase);
+ for (ScrArea *area = area_map->areabase.first; area; area = area->next) {
+ area->butspacetype = area->spacetype; /* Just for compatibility, will be reset below. */
- writestruct(wd, DATA, SpaceIpo, 1, sl);
- if (sipo->ads) {
- writestruct(wd, DATA, bDopeSheet, 1, sipo->ads);
- }
+ writestruct(wd, DATA, ScrArea, 1, area);
- /* reenable ghost curves */
- sipo->ghostCurves = tmpGhosts;
- }
- else if (sl->spacetype == SPACE_BUTS) {
- writestruct(wd, DATA, SpaceButs, 1, sl);
- }
- else if (sl->spacetype == SPACE_FILE) {
- SpaceFile *sfile = (SpaceFile *)sl;
+#ifdef WITH_GLOBAL_AREA_WRITING
+ writestruct(wd, DATA, ScrGlobalAreaData, 1, area->global);
+#endif
- writestruct(wd, DATA, SpaceFile, 1, sl);
- if (sfile->params) {
- writestruct(wd, DATA, FileSelectParams, 1, sfile->params);
- }
- }
- else if (sl->spacetype == SPACE_SEQ) {
- writestruct(wd, DATA, SpaceSeq, 1, sl);
- }
- else if (sl->spacetype == SPACE_OUTLINER) {
- SpaceOops *so = (SpaceOops *)sl;
- write_soops(wd, so);
- }
- else if (sl->spacetype == SPACE_IMAGE) {
- writestruct(wd, DATA, SpaceImage, 1, sl);
- }
- else if (sl->spacetype == SPACE_TEXT) {
- writestruct(wd, DATA, SpaceText, 1, sl);
- }
- else if (sl->spacetype == SPACE_SCRIPT) {
- SpaceScript *scr = (SpaceScript *)sl;
- scr->but_refs = NULL;
- writestruct(wd, DATA, SpaceScript, 1, sl);
- }
- else if (sl->spacetype == SPACE_ACTION) {
- writestruct(wd, DATA, SpaceAction, 1, sl);
- }
- else if (sl->spacetype == SPACE_NLA) {
- SpaceNla *snla = (SpaceNla *)sl;
+ write_area_regions(wd, area);
- writestruct(wd, DATA, SpaceNla, 1, snla);
- if (snla->ads) {
- writestruct(wd, DATA, bDopeSheet, 1, snla->ads);
- }
- }
- else if (sl->spacetype == SPACE_TIME) {
- writestruct(wd, DATA, SpaceTime, 1, sl);
- }
- else if (sl->spacetype == SPACE_NODE) {
- SpaceNode *snode = (SpaceNode *)sl;
- bNodeTreePath *path;
- writestruct(wd, DATA, SpaceNode, 1, snode);
+ area->butspacetype = SPACE_EMPTY; /* Unset again, was changed above. */
+ }
+}
- for (path = snode->treepath.first; path; path = path->next) {
- writestruct(wd, DATA, bNodeTreePath, 1, path);
- }
- }
- else if (sl->spacetype == SPACE_LOGIC) {
- writestruct(wd, DATA, SpaceLogic, 1, sl);
- }
- else if (sl->spacetype == SPACE_CONSOLE) {
- SpaceConsole *con = (SpaceConsole *)sl;
- ConsoleLine *cl;
-
- for (cl = con->history.first; cl; cl = cl->next) {
- /* 'len_alloc' is invalid on write, set from 'len' on read */
- writestruct(wd, DATA, ConsoleLine, 1, cl);
- writedata(wd, DATA, cl->len + 1, cl->line);
- }
- writestruct(wd, DATA, SpaceConsole, 1, sl);
+static void write_windowmanager(WriteData *wd, wmWindowManager *wm)
+{
+ writestruct(wd, ID_WM, wmWindowManager, 1, wm);
+ write_iddata(wd, &wm->id);
- }
- else if (sl->spacetype == SPACE_USERPREF) {
- writestruct(wd, DATA, SpaceUserPref, 1, sl);
- }
- else if (sl->spacetype == SPACE_CLIP) {
- writestruct(wd, DATA, SpaceClip, 1, sl);
- }
- else if (sl->spacetype == SPACE_INFO) {
- writestruct(wd, DATA, SpaceInfo, 1, sl);
- }
- }
+ for (wmWindow *win = wm->windows.first; win; win = win->next) {
+#ifndef WITH_GLOBAL_AREA_WRITING
+ /* Don't write global areas yet, while we make changes to them. */
+ ScrAreaMap global_areas = win->global_areas;
+ memset(&win->global_areas, 0, sizeof(win->global_areas));
+#endif
+
+ /* update deprecated screen member (for so loading in 2.7x uses the correct screen) */
+ win->screen = BKE_workspace_active_screen_get(win->workspace_hook);
+
+ writestruct(wd, DATA, wmWindow, 1, win);
+ writestruct(wd, DATA, WorkSpaceInstanceHook, 1, win->workspace_hook);
+ writestruct(wd, DATA, Stereo3dFormat, 1, win->stereo3d_format);
+
+#ifdef WITH_GLOBAL_AREA_WRITING
+ write_area_map(wd, &win->global_areas);
+#else
+ win->global_areas = global_areas;
+#endif
+
+ /* data is written, clear deprecated data again */
+ win->screen = NULL;
}
}
+static void write_screen(WriteData *wd, bScreen *sc)
+{
+ /* write LibData */
+ /* in 2.50+ files, the file identifier for screens is patched, forward compatibility */
+ writestruct(wd, ID_SCRN, bScreen, 1, sc);
+ write_iddata(wd, &sc->id);
+
+ write_previews(wd, sc->preview);
+
+ /* direct data */
+ write_area_map(wd, AREAMAP_FROM_SCREEN(sc));
+}
+
static void write_bone(WriteData *wd, Bone *bone)
{
/* PATCH for upward compatibility after 2.37+ armature recode */
@@ -3159,17 +3079,15 @@ static void write_sound(WriteData *wd, bSound *sound)
}
}
-static void write_group(WriteData *wd, Group *group)
+static void write_probe(WriteData *wd, LightProbe *prb)
{
- if (group->id.us > 0 || wd->use_memfile) {
+ if (prb->id.us > 0 || wd->use_memfile) {
/* write LibData */
- writestruct(wd, ID_GR, Group, 1, group);
- write_iddata(wd, &group->id);
-
- write_previews(wd, group->preview);
+ writestruct(wd, ID_LP, LightProbe, 1, prb);
+ write_iddata(wd, &prb->id);
- for (GroupObject *go = group->gobject.first; go; go = go->next) {
- writestruct(wd, DATA, GroupObject, 1, go);
+ if (prb->adt) {
+ write_animdata(wd, prb->adt);
}
}
}
@@ -3704,6 +3622,23 @@ static void write_cachefile(WriteData *wd, CacheFile *cache_file)
}
}
+static void write_workspace(WriteData *wd, WorkSpace *workspace)
+{
+ ListBase *layouts = BKE_workspace_layouts_get(workspace);
+
+ writestruct(wd, ID_WS, WorkSpace, 1, workspace);
+ writelist(wd, DATA, WorkSpaceLayout, layouts);
+ writelist(wd, DATA, WorkSpaceDataRelation, &workspace->hook_layout_relations);
+ writelist(wd, DATA, WorkSpaceSceneRelation, &workspace->scene_layer_relations);
+ writelist(wd, DATA, wmOwnerID, &workspace->owner_ids);
+ writelist(wd, DATA, bToolRef, &workspace->tools);
+ for (bToolRef *tref = workspace->tools.first; tref; tref = tref->next) {
+ if (tref->properties) {
+ IDP_WriteProperty(tref->properties, wd);
+ }
+ }
+}
+
/* Keep it last of write_foodata functions. */
static void write_libraries(WriteData *wd, Main *main)
{
@@ -3735,6 +3670,8 @@ static void write_libraries(WriteData *wd, Main *main)
/* XXX needs rethink, just like save UI in undo files now - would be nice to append things only for the]
* quit.blend and temp saves */
if (found_one) {
+ /* Not overridable. */
+
writestruct(wd, ID_LI, Library, 1, main->curlib);
write_iddata(wd, &main->curlib->id);
@@ -3773,18 +3710,22 @@ static void write_global(WriteData *wd, int fileflags, Main *mainvar)
const bool is_undo = wd->use_memfile;
FileGlobal fg;
bScreen *screen;
+ Scene *scene;
+ ViewLayer *render_layer;
char subvstr[8];
/* prevent mem checkers from complaining */
memset(fg.pad, 0, sizeof(fg.pad));
memset(fg.filename, 0, sizeof(fg.filename));
memset(fg.build_hash, 0, sizeof(fg.build_hash));
+ fg.pad1 = NULL;
- current_screen_compat(mainvar, &screen, is_undo);
+ current_screen_compat(mainvar, is_undo, &screen, &scene, &render_layer);
/* XXX still remap G */
fg.curscreen = screen;
- fg.curscene = screen ? screen->scene : NULL;
+ fg.curscene = scene;
+ fg.cur_view_layer = render_layer;
/* prevent to save this, is not good convention, and feature with concerns... */
fg.fileflags = (fileflags & ~G_FILE_FLAGS_RUNTIME);
@@ -3872,131 +3813,159 @@ static bool write_file_handle(
* avoid thumbnail detecting changes because of this. */
mywrite_flush(wd);
- ListBase *lbarray[MAX_LIBARRAY];
- int a = set_listbasepointers(mainvar, lbarray);
- while (a--) {
- ID *id = lbarray[a]->first;
+ OverrideStaticStorage *override_storage = wd->use_memfile ? NULL : BKE_override_static_operations_store_initialize();
- if (id && GS(id->name) == ID_LI) {
- continue; /* Libraries are handled separately below. */
- }
+ /* This outer loop allows to save first datablocks from real mainvar, then the temp ones from override process,
+ * if needed, without duplicating whole code. */
+ Main *bmain = mainvar;
+ do {
+ ListBase *lbarray[MAX_LIBARRAY];
+ int a = set_listbasepointers(bmain, lbarray);
+ while (a--) {
+ ID *id = lbarray[a]->first;
- for (; id; id = id->next) {
- /* We should never attempt to write non-regular IDs (i.e. all kind of temp/runtime ones). */
- BLI_assert((id->tag & (LIB_TAG_NO_MAIN | LIB_TAG_NO_USER_REFCOUNT | LIB_TAG_NOT_ALLOCATED)) == 0);
+ if (id && GS(id->name) == ID_LI) {
+ continue; /* Libraries are handled separately below. */
+ }
- switch ((ID_Type)GS(id->name)) {
- case ID_WM:
- write_windowmanager(wd, (wmWindowManager *)id);
- break;
- case ID_SCR:
- write_screen(wd, (bScreen *)id);
- break;
- case ID_MC:
- write_movieclip(wd, (MovieClip *)id);
- break;
- case ID_MSK:
- write_mask(wd, (Mask *)id);
- break;
- case ID_SCE:
- write_scene(wd, (Scene *)id);
- break;
- case ID_CU:
- write_curve(wd, (Curve *)id);
- break;
- case ID_MB:
- write_mball(wd, (MetaBall *)id);
- break;
- case ID_IM:
- write_image(wd, (Image *)id);
- break;
- case ID_CA:
- write_camera(wd, (Camera *)id);
- break;
- case ID_LA:
- write_lamp(wd, (Lamp *)id);
- break;
- case ID_LT:
- write_lattice(wd, (Lattice *)id);
- break;
- case ID_VF:
- write_vfont(wd, (VFont *)id);
- break;
- case ID_KE:
- write_key(wd, (Key *)id);
- break;
- case ID_WO:
- write_world(wd, (World *)id);
- break;
- case ID_TXT:
- write_text(wd, (Text *)id);
- break;
- case ID_SPK:
- write_speaker(wd, (Speaker *)id);
- break;
- case ID_SO:
- write_sound(wd, (bSound *)id);
- break;
- case ID_GR:
- write_group(wd, (Group *)id);
- break;
- case ID_AR:
- write_armature(wd, (bArmature *)id);
- break;
- case ID_AC:
- write_action(wd, (bAction *)id);
- break;
- case ID_OB:
- write_object(wd, (Object *)id);
- break;
- case ID_MA:
- write_material(wd, (Material *)id);
- break;
- case ID_TE:
- write_texture(wd, (Tex *)id);
- break;
- case ID_ME:
- write_mesh(wd, (Mesh *)id);
- break;
- case ID_PA:
- write_particlesettings(wd, (ParticleSettings *)id);
- break;
- case ID_NT:
- write_nodetree(wd, (bNodeTree *)id);
- break;
- case ID_BR:
- write_brush(wd, (Brush *)id);
- break;
- case ID_PAL:
- write_palette(wd, (Palette *)id);
- break;
- case ID_PC:
- write_paintcurve(wd, (PaintCurve *)id);
- break;
- case ID_GD:
- write_gpencil(wd, (bGPdata *)id);
- break;
- case ID_LS:
- write_linestyle(wd, (FreestyleLineStyle *)id);
- break;
- case ID_CF:
- write_cachefile(wd, (CacheFile *)id);
- break;
- case ID_LI:
- /* Do nothing, handled below - and should never be reached. */
- BLI_assert(0);
- break;
- case ID_IP:
- /* Do nothing, deprecated. */
- break;
- default:
- /* Should never be reached. */
- BLI_assert(0);
- break;
+ for (; id; id = id->next) {
+ /* We should never attempt to write non-regular IDs (i.e. all kind of temp/runtime ones). */
+ BLI_assert((id->tag & (LIB_TAG_NO_MAIN | LIB_TAG_NO_USER_REFCOUNT | LIB_TAG_NOT_ALLOCATED)) == 0);
+
+ const bool do_override = !ELEM(override_storage, NULL, bmain) && id->override_static;
+
+ if (do_override) {
+ BKE_override_static_operations_store_start(override_storage, id);
+ }
+
+ switch ((ID_Type)GS(id->name)) {
+ case ID_WM:
+ write_windowmanager(wd, (wmWindowManager *)id);
+ break;
+ case ID_WS:
+ write_workspace(wd, (WorkSpace *)id);
+ break;
+ case ID_SCR:
+ write_screen(wd, (bScreen *)id);
+ break;
+ case ID_MC:
+ write_movieclip(wd, (MovieClip *)id);
+ break;
+ case ID_MSK:
+ write_mask(wd, (Mask *)id);
+ break;
+ case ID_SCE:
+ write_scene(wd, (Scene *)id);
+ break;
+ case ID_CU:
+ write_curve(wd, (Curve *)id);
+ break;
+ case ID_MB:
+ write_mball(wd, (MetaBall *)id);
+ break;
+ case ID_IM:
+ write_image(wd, (Image *)id);
+ break;
+ case ID_CA:
+ write_camera(wd, (Camera *)id);
+ break;
+ case ID_LA:
+ write_lamp(wd, (Lamp *)id);
+ break;
+ case ID_LT:
+ write_lattice(wd, (Lattice *)id);
+ break;
+ case ID_VF:
+ write_vfont(wd, (VFont *)id);
+ break;
+ case ID_KE:
+ write_key(wd, (Key *)id);
+ break;
+ case ID_WO:
+ write_world(wd, (World *)id);
+ break;
+ case ID_TXT:
+ write_text(wd, (Text *)id);
+ break;
+ case ID_SPK:
+ write_speaker(wd, (Speaker *)id);
+ break;
+ case ID_LP:
+ write_probe(wd, (LightProbe *)id);
+ break;
+ case ID_SO:
+ write_sound(wd, (bSound *)id);
+ break;
+ case ID_GR:
+ write_collection(wd, (Collection *)id);
+ break;
+ case ID_AR:
+ write_armature(wd, (bArmature *)id);
+ break;
+ case ID_AC:
+ write_action(wd, (bAction *)id);
+ break;
+ case ID_OB:
+ write_object(wd, (Object *)id);
+ break;
+ case ID_MA:
+ write_material(wd, (Material *)id);
+ break;
+ case ID_TE:
+ write_texture(wd, (Tex *)id);
+ break;
+ case ID_ME:
+ write_mesh(wd, (Mesh *)id);
+ break;
+ case ID_PA:
+ write_particlesettings(wd, (ParticleSettings *)id);
+ break;
+ case ID_NT:
+ write_nodetree(wd, (bNodeTree *)id);
+ break;
+ case ID_BR:
+ write_brush(wd, (Brush *)id);
+ break;
+ case ID_PAL:
+ write_palette(wd, (Palette *)id);
+ break;
+ case ID_PC:
+ write_paintcurve(wd, (PaintCurve *)id);
+ break;
+ case ID_GD:
+ write_gpencil(wd, (bGPdata *)id);
+ break;
+ case ID_LS:
+ write_linestyle(wd, (FreestyleLineStyle *)id);
+ break;
+ case ID_CF:
+ write_cachefile(wd, (CacheFile *)id);
+ break;
+ case ID_LI:
+ /* Do nothing, handled below - and should never be reached. */
+ BLI_assert(0);
+ break;
+ case ID_IP:
+ /* Do nothing, deprecated. */
+ break;
+ default:
+ /* Should never be reached. */
+ BLI_assert(0);
+ break;
+ }
+
+ if (do_override) {
+ BKE_override_static_operations_store_end(override_storage, id);
+ }
}
+
+ mywrite_flush(wd);
}
+ } while ((bmain != override_storage) && (bmain = override_storage));
- mywrite_flush(wd);
+ if (override_storage) {
+ BKE_override_static_operations_store_finalize(override_storage);
+ override_storage = NULL;
}
/* Special handling, operating over split Mains... */