Tweak write code to allow cleaning up runtime data before write.

This basically generalizes what was being done in `write_mesh`,
since we need to clean up ID tags anyway, it's easier to do it for all IDs.

Then ID write funcs themsleves can do whatever they want on the passed
struct, without risking interferring with regular Blender operations.

Note that Text write function is doing a suspicious change on one of its
flags, but this seems to be by-passed anyway by read code currently, so
think it's OK to not do that on orig data-block.

Reviewed By: brecht

Differential Revision: https://developer.blender.org/D7294
This commit is contained in:
Bastien Montagne 2020-04-01 09:40:11 +02:00 committed by Bastien Montagne
parent 7952274cf0
commit 2ad0ae8dad
1 changed files with 130 additions and 136 deletions

View File

@ -854,10 +854,10 @@ static void write_fcurves(WriteData *wd, ListBase *fcurves)
}
}
static void write_action(WriteData *wd, bAction *act)
static void write_action(WriteData *wd, bAction *act, const void *id_address)
{
if (act->id.us > 0 || wd->use_memfile) {
writestruct(wd, ID_AC, bAction, 1, act);
writestruct_at_address(wd, ID_AC, bAction, 1, id_address, act);
write_iddata(wd, &act->id);
write_fcurves(wd, &act->curves);
@ -1391,11 +1391,11 @@ static void write_pointcaches(WriteData *wd, ListBase *ptcaches)
}
}
static void write_particlesettings(WriteData *wd, ParticleSettings *part)
static void write_particlesettings(WriteData *wd, ParticleSettings *part, const void *id_address)
{
if (part->id.us > 0 || wd->use_memfile) {
/* write LibData */
writestruct(wd, ID_PA, ParticleSettings, 1, part);
writestruct_at_address(wd, ID_PA, ParticleSettings, 1, id_address, part);
write_iddata(wd, &part->id);
if (part->adt) {
@ -1900,11 +1900,11 @@ static void write_shaderfxs(WriteData *wd, ListBase *fxbase)
}
}
static void write_object(WriteData *wd, Object *ob)
static void write_object(WriteData *wd, Object *ob, const void *id_address)
{
if (ob->id.us > 0 || wd->use_memfile) {
/* write LibData */
writestruct(wd, ID_OB, Object, 1, ob);
writestruct_at_address(wd, ID_OB, Object, 1, id_address, ob);
write_iddata(wd, &ob->id);
if (ob->adt) {
@ -1965,11 +1965,11 @@ static void write_object(WriteData *wd, Object *ob)
}
}
static void write_vfont(WriteData *wd, VFont *vf)
static void write_vfont(WriteData *wd, VFont *vf, const void *id_address)
{
if (vf->id.us > 0 || wd->use_memfile) {
/* write LibData */
writestruct(wd, ID_VF, VFont, 1, vf);
writestruct_at_address(wd, ID_VF, VFont, 1, id_address, vf);
write_iddata(wd, &vf->id);
/* direct data */
@ -1981,11 +1981,11 @@ static void write_vfont(WriteData *wd, VFont *vf)
}
}
static void write_key(WriteData *wd, Key *key)
static void write_key(WriteData *wd, Key *key, const void *id_address)
{
if (key->id.us > 0 || wd->use_memfile) {
/* write LibData */
writestruct(wd, ID_KE, Key, 1, key);
writestruct_at_address(wd, ID_KE, Key, 1, id_address, key);
write_iddata(wd, &key->id);
if (key->adt) {
@ -2002,11 +2002,11 @@ static void write_key(WriteData *wd, Key *key)
}
}
static void write_camera(WriteData *wd, Camera *cam)
static void write_camera(WriteData *wd, Camera *cam, const void *id_address)
{
if (cam->id.us > 0 || wd->use_memfile) {
/* write LibData */
writestruct(wd, ID_CA, Camera, 1, cam);
writestruct_at_address(wd, ID_CA, Camera, 1, id_address, cam);
write_iddata(wd, &cam->id);
if (cam->adt) {
@ -2019,11 +2019,11 @@ static void write_camera(WriteData *wd, Camera *cam)
}
}
static void write_mball(WriteData *wd, MetaBall *mb)
static void write_mball(WriteData *wd, MetaBall *mb, const void *id_address)
{
if (mb->id.us > 0 || wd->use_memfile) {
/* write LibData */
writestruct(wd, ID_MB, MetaBall, 1, mb);
writestruct_at_address(wd, ID_MB, MetaBall, 1, id_address, mb);
write_iddata(wd, &mb->id);
/* direct data */
@ -2038,11 +2038,11 @@ static void write_mball(WriteData *wd, MetaBall *mb)
}
}
static void write_curve(WriteData *wd, Curve *cu)
static void write_curve(WriteData *wd, Curve *cu, const void *id_address)
{
if (cu->id.us > 0 || wd->use_memfile) {
/* write LibData */
writestruct(wd, ID_CU, Curve, 1, cu);
writestruct_at_address(wd, ID_CU, Curve, 1, id_address, cu);
write_iddata(wd, &cu->id);
/* direct data */
@ -2195,15 +2195,9 @@ static void write_customdata(WriteData *wd,
}
}
static void write_mesh(WriteData *wd, Mesh *mesh)
static void write_mesh(WriteData *wd, Mesh *mesh, const void *id_address)
{
if (mesh->id.us > 0 || wd->use_memfile) {
/* Write a copy of the mesh with possibly reduced number of data layers.
* Don't edit the original since other threads might be reading it. */
Mesh *old_mesh = mesh;
Mesh copy_mesh = *mesh;
mesh = &copy_mesh;
/* cache only - don't write */
mesh->mface = NULL;
mesh->totface = 0;
@ -2225,7 +2219,7 @@ static void write_mesh(WriteData *wd, Mesh *mesh)
CustomData_file_write_prepare(&mesh->ldata, &llayers, llayers_buff, ARRAY_SIZE(llayers_buff));
CustomData_file_write_prepare(&mesh->pdata, &players, players_buff, ARRAY_SIZE(players_buff));
writestruct_at_address(wd, ID_ME, Mesh, 1, old_mesh, mesh);
writestruct_at_address(wd, ID_ME, Mesh, 1, id_address, mesh);
write_iddata(wd, &mesh->id);
/* direct data */
@ -2243,9 +2237,6 @@ static void write_mesh(WriteData *wd, Mesh *mesh)
write_customdata(wd, &mesh->id, mesh->totloop, &mesh->ldata, llayers, CD_MASK_MESH.lmask);
write_customdata(wd, &mesh->id, mesh->totpoly, &mesh->pdata, players, CD_MASK_MESH.pmask);
/* restore pointer */
mesh = old_mesh;
/* free temporary data */
if (vlayers && vlayers != vlayers_buff) {
MEM_freeN(vlayers);
@ -2265,11 +2256,11 @@ static void write_mesh(WriteData *wd, Mesh *mesh)
}
}
static void write_lattice(WriteData *wd, Lattice *lt)
static void write_lattice(WriteData *wd, Lattice *lt, const void *id_address)
{
if (lt->id.us > 0 || wd->use_memfile) {
/* write LibData */
writestruct(wd, ID_LT, Lattice, 1, lt);
writestruct_at_address(wd, ID_LT, Lattice, 1, id_address, lt);
write_iddata(wd, &lt->id);
/* write animdata */
@ -2284,7 +2275,7 @@ static void write_lattice(WriteData *wd, Lattice *lt)
}
}
static void write_image(WriteData *wd, Image *ima)
static void write_image(WriteData *wd, Image *ima, const void *id_address)
{
if (ima->id.us > 0 || wd->use_memfile) {
ImagePackedFile *imapf;
@ -2297,7 +2288,7 @@ static void write_image(WriteData *wd, Image *ima)
}
/* write LibData */
writestruct(wd, ID_IM, Image, 1, ima);
writestruct_at_address(wd, ID_IM, Image, 1, id_address, ima);
write_iddata(wd, &ima->id);
for (imapf = ima->packedfiles.first; imapf; imapf = imapf->next) {
@ -2324,11 +2315,11 @@ static void write_image(WriteData *wd, Image *ima)
}
}
static void write_texture(WriteData *wd, Tex *tex)
static void write_texture(WriteData *wd, Tex *tex, const void *id_address)
{
if (tex->id.us > 0 || wd->use_memfile) {
/* write LibData */
writestruct(wd, ID_TE, Tex, 1, tex);
writestruct_at_address(wd, ID_TE, Tex, 1, id_address, tex);
write_iddata(wd, &tex->id);
if (tex->adt) {
@ -2350,11 +2341,11 @@ static void write_texture(WriteData *wd, Tex *tex)
}
}
static void write_material(WriteData *wd, Material *ma)
static void write_material(WriteData *wd, Material *ma, const void *id_address)
{
if (ma->id.us > 0 || wd->use_memfile) {
/* write LibData */
writestruct(wd, ID_MA, Material, 1, ma);
writestruct_at_address(wd, ID_MA, Material, 1, id_address, ma);
write_iddata(wd, &ma->id);
if (ma->adt) {
@ -2376,11 +2367,11 @@ static void write_material(WriteData *wd, Material *ma)
}
}
static void write_world(WriteData *wd, World *wrld)
static void write_world(WriteData *wd, World *wrld, const void *id_address)
{
if (wrld->id.us > 0 || wd->use_memfile) {
/* write LibData */
writestruct(wd, ID_WO, World, 1, wrld);
writestruct_at_address(wd, ID_WO, World, 1, id_address, wrld);
write_iddata(wd, &wrld->id);
if (wrld->adt) {
@ -2397,11 +2388,11 @@ static void write_world(WriteData *wd, World *wrld)
}
}
static void write_light(WriteData *wd, Light *la)
static void write_light(WriteData *wd, Light *la, const void *id_address)
{
if (la->id.us > 0 || wd->use_memfile) {
/* write LibData */
writestruct(wd, ID_LA, Light, 1, la);
writestruct_at_address(wd, ID_LA, Light, 1, id_address, la);
write_iddata(wd, &la->id);
if (la->adt) {
@ -2441,11 +2432,11 @@ static void write_collection_nolib(WriteData *wd, Collection *collection)
}
}
static void write_collection(WriteData *wd, Collection *collection)
static void write_collection(WriteData *wd, Collection *collection, const void *id_address)
{
if (collection->id.us > 0 || wd->use_memfile) {
/* write LibData */
writestruct(wd, ID_GR, Collection, 1, collection);
writestruct_at_address(wd, ID_GR, Collection, 1, id_address, collection);
write_iddata(wd, &collection->id);
write_collection_nolib(wd, collection);
@ -2560,10 +2551,10 @@ static void write_lightcache(WriteData *wd, LightCache *cache)
writestruct(wd, DATA, LightProbeCache, cache->cube_len, cache->cube_data);
}
static void write_scene(WriteData *wd, Scene *sce)
static void write_scene(WriteData *wd, Scene *sce, const void *id_address)
{
/* write LibData */
writestruct(wd, ID_SCE, Scene, 1, sce);
writestruct_at_address(wd, ID_SCE, Scene, 1, id_address, sce);
write_iddata(wd, &sce->id);
if (sce->adt) {
@ -2786,11 +2777,11 @@ static void write_scene(WriteData *wd, Scene *sce)
BLI_assert(sce->layer_properties == NULL);
}
static void write_gpencil(WriteData *wd, bGPdata *gpd)
static void write_gpencil(WriteData *wd, bGPdata *gpd, const void *id_address)
{
if (gpd->id.us > 0 || wd->use_memfile) {
/* write gpd data block to file */
writestruct(wd, ID_GD, bGPdata, 1, gpd);
writestruct_at_address(wd, ID_GD, bGPdata, 1, id_address, gpd);
write_iddata(wd, &gpd->id);
if (gpd->adt) {
@ -3066,9 +3057,9 @@ static void write_area_map(WriteData *wd, ScrAreaMap *area_map)
}
}
static void write_windowmanager(WriteData *wd, wmWindowManager *wm)
static void write_windowmanager(WriteData *wd, wmWindowManager *wm, const void *id_address)
{
writestruct(wd, ID_WM, wmWindowManager, 1, wm);
writestruct_at_address(wd, ID_WM, wmWindowManager, 1, id_address, wm);
write_iddata(wd, &wm->id);
write_wm_xr_data(wd, &wm->xr);
@ -3097,13 +3088,13 @@ static void write_windowmanager(WriteData *wd, wmWindowManager *wm)
}
}
static void write_screen(WriteData *wd, bScreen *sc)
static void write_screen(WriteData *wd, bScreen *sc, const void *id_address)
{
/* Screens are reference counted, only saved if used by a workspace. */
if (sc->id.us > 0 || wd->use_memfile) {
/* write LibData */
/* in 2.50+ files, the file identifier for screens is patched, forward compatibility */
writestruct(wd, ID_SCRN, bScreen, 1, sc);
writestruct_at_address(wd, ID_SCRN, bScreen, 1, id_address, sc);
write_iddata(wd, &sc->id);
write_previews(wd, sc->preview);
@ -3133,10 +3124,10 @@ static void write_bone(WriteData *wd, Bone *bone)
}
}
static void write_armature(WriteData *wd, bArmature *arm)
static void write_armature(WriteData *wd, bArmature *arm, const void *id_address)
{
if (arm->id.us > 0 || wd->use_memfile) {
writestruct(wd, ID_AR, bArmature, 1, arm);
writestruct_at_address(wd, ID_AR, bArmature, 1, id_address, arm);
write_iddata(wd, &arm->id);
if (arm->adt) {
@ -3150,14 +3141,15 @@ static void write_armature(WriteData *wd, bArmature *arm)
}
}
static void write_text(WriteData *wd, Text *text)
static void write_text(WriteData *wd, Text *text, const void *id_address)
{
/* Note: we are clearing local temp data here, *not* the flag in the actual 'real' ID. */
if ((text->flags & TXT_ISMEM) && (text->flags & TXT_ISEXT)) {
text->flags &= ~TXT_ISEXT;
}
/* write LibData */
writestruct(wd, ID_TXT, Text, 1, text);
writestruct_at_address(wd, ID_TXT, Text, 1, id_address, text);
write_iddata(wd, &text->id);
if (text->name) {
@ -3176,11 +3168,11 @@ static void write_text(WriteData *wd, Text *text)
}
}
static void write_speaker(WriteData *wd, Speaker *spk)
static void write_speaker(WriteData *wd, Speaker *spk, const void *id_address)
{
if (spk->id.us > 0 || wd->use_memfile) {
/* write LibData */
writestruct(wd, ID_SPK, Speaker, 1, spk);
writestruct_at_address(wd, ID_SPK, Speaker, 1, id_address, spk);
write_iddata(wd, &spk->id);
if (spk->adt) {
@ -3189,11 +3181,11 @@ static void write_speaker(WriteData *wd, Speaker *spk)
}
}
static void write_sound(WriteData *wd, bSound *sound)
static void write_sound(WriteData *wd, bSound *sound, const void *id_address)
{
if (sound->id.us > 0 || wd->use_memfile) {
/* write LibData */
writestruct(wd, ID_SO, bSound, 1, sound);
writestruct_at_address(wd, ID_SO, bSound, 1, id_address, sound);
write_iddata(wd, &sound->id);
if (sound->packedfile) {
@ -3204,11 +3196,11 @@ static void write_sound(WriteData *wd, bSound *sound)
}
}
static void write_probe(WriteData *wd, LightProbe *prb)
static void write_probe(WriteData *wd, LightProbe *prb, const void *id_address)
{
if (prb->id.us > 0 || wd->use_memfile) {
/* write LibData */
writestruct(wd, ID_LP, LightProbe, 1, prb);
writestruct_at_address(wd, ID_LP, LightProbe, 1, id_address, prb);
write_iddata(wd, &prb->id);
if (prb->adt) {
@ -3217,10 +3209,10 @@ static void write_probe(WriteData *wd, LightProbe *prb)
}
}
static void write_nodetree(WriteData *wd, bNodeTree *ntree)
static void write_nodetree(WriteData *wd, bNodeTree *ntree, const void *id_address)
{
if (ntree->id.us > 0 || wd->use_memfile) {
writestruct(wd, ID_NT, bNodeTree, 1, ntree);
writestruct_at_address(wd, ID_NT, bNodeTree, 1, id_address, ntree);
/* Note that trees directly used by other IDs (materials etc.) are not 'real' ID, they cannot
* be linked, etc., so we write actual id data here only, for 'real' ID trees. */
write_iddata(wd, &ntree->id);
@ -3229,10 +3221,10 @@ static void write_nodetree(WriteData *wd, bNodeTree *ntree)
}
}
static void write_brush(WriteData *wd, Brush *brush)
static void write_brush(WriteData *wd, Brush *brush, const void *id_address)
{
if (brush->id.us > 0 || wd->use_memfile) {
writestruct(wd, ID_BR, Brush, 1, brush);
writestruct_at_address(wd, ID_BR, Brush, 1, id_address, brush);
write_iddata(wd, &brush->id);
if (brush->curve) {
@ -3258,11 +3250,11 @@ static void write_brush(WriteData *wd, Brush *brush)
}
}
static void write_palette(WriteData *wd, Palette *palette)
static void write_palette(WriteData *wd, Palette *palette, const void *id_address)
{
if (palette->id.us > 0 || wd->use_memfile) {
PaletteColor *color;
writestruct(wd, ID_PAL, Palette, 1, palette);
writestruct_at_address(wd, ID_PAL, Palette, 1, id_address, palette);
write_iddata(wd, &palette->id);
for (color = palette->colors.first; color; color = color->next) {
@ -3271,10 +3263,10 @@ static void write_palette(WriteData *wd, Palette *palette)
}
}
static void write_paintcurve(WriteData *wd, PaintCurve *pc)
static void write_paintcurve(WriteData *wd, PaintCurve *pc, const void *id_address)
{
if (pc->id.us > 0 || wd->use_memfile) {
writestruct(wd, ID_PC, PaintCurve, 1, pc);
writestruct_at_address(wd, ID_PC, PaintCurve, 1, id_address, pc);
write_iddata(wd, &pc->id);
writestruct(wd, DATA, PaintCurvePoint, pc->tot_points, pc->points);
@ -3320,13 +3312,13 @@ static void write_movieReconstruction(WriteData *wd, MovieTrackingReconstruction
}
}
static void write_movieclip(WriteData *wd, MovieClip *clip)
static void write_movieclip(WriteData *wd, MovieClip *clip, const void *id_address)
{
if (clip->id.us > 0 || wd->use_memfile) {
MovieTracking *tracking = &clip->tracking;
MovieTrackingObject *object;
writestruct(wd, ID_MC, MovieClip, 1, clip);
writestruct_at_address(wd, ID_MC, MovieClip, 1, id_address, clip);
write_iddata(wd, &clip->id);
if (clip->adt) {
@ -3350,12 +3342,12 @@ static void write_movieclip(WriteData *wd, MovieClip *clip)
}
}
static void write_mask(WriteData *wd, Mask *mask)
static void write_mask(WriteData *wd, Mask *mask, const void *id_address)
{
if (mask->id.us > 0 || wd->use_memfile) {
MaskLayer *masklay;
writestruct(wd, ID_MSK, Mask, 1, mask);
writestruct_at_address(wd, ID_MSK, Mask, 1, id_address, mask);
write_iddata(wd, &mask->id);
if (mask->adt) {
@ -3657,10 +3649,10 @@ static void write_linestyle_geometry_modifiers(WriteData *wd, ListBase *modifier
}
}
static void write_linestyle(WriteData *wd, FreestyleLineStyle *linestyle)
static void write_linestyle(WriteData *wd, FreestyleLineStyle *linestyle, const void *id_address)
{
if (linestyle->id.us > 0 || wd->use_memfile) {
writestruct(wd, ID_LS, FreestyleLineStyle, 1, linestyle);
writestruct_at_address(wd, ID_LS, FreestyleLineStyle, 1, id_address, linestyle);
write_iddata(wd, &linestyle->id);
if (linestyle->adt) {
@ -3683,10 +3675,10 @@ static void write_linestyle(WriteData *wd, FreestyleLineStyle *linestyle)
}
}
static void write_cachefile(WriteData *wd, CacheFile *cache_file)
static void write_cachefile(WriteData *wd, CacheFile *cache_file, const void *id_address)
{
if (cache_file->id.us > 0 || wd->use_memfile) {
writestruct(wd, ID_CF, CacheFile, 1, cache_file);
writestruct_at_address(wd, ID_CF, CacheFile, 1, id_address, cache_file);
if (cache_file->adt) {
write_animdata(wd, cache_file->adt);
@ -3694,11 +3686,11 @@ static void write_cachefile(WriteData *wd, CacheFile *cache_file)
}
}
static void write_workspace(WriteData *wd, WorkSpace *workspace)
static void write_workspace(WriteData *wd, WorkSpace *workspace, const void *id_address)
{
ListBase *layouts = BKE_workspace_layouts_get(workspace);
writestruct(wd, ID_WS, WorkSpace, 1, workspace);
writestruct_at_address(wd, ID_WS, WorkSpace, 1, id_address, workspace);
write_iddata(wd, &workspace->id);
writelist(wd, DATA, WorkSpaceLayout, layouts);
writelist(wd, DATA, WorkSpaceDataRelation, &workspace->hook_layout_relations);
@ -3711,22 +3703,16 @@ static void write_workspace(WriteData *wd, WorkSpace *workspace)
}
}
static void write_hair(WriteData *wd, Hair *hair)
static void write_hair(WriteData *wd, Hair *hair, const void *id_address)
{
if (hair->id.us > 0 || wd->use_memfile) {
/* Write a copy of the hair with possibly reduced number of data layers.
* Don't edit the original since other threads might be reading it. */
Hair *old_hair = hair;
Hair copy_hair = *hair;
hair = &copy_hair;
CustomDataLayer *players = NULL, players_buff[CD_TEMP_CHUNK_SIZE];
CustomDataLayer *clayers = NULL, clayers_buff[CD_TEMP_CHUNK_SIZE];
CustomData_file_write_prepare(&hair->pdata, &players, players_buff, ARRAY_SIZE(players_buff));
CustomData_file_write_prepare(&hair->cdata, &clayers, clayers_buff, ARRAY_SIZE(clayers_buff));
/* Write LibData */
writestruct_at_address(wd, ID_HA, Hair, 1, old_hair, hair);
writestruct_at_address(wd, ID_HA, Hair, 1, id_address, hair);
write_iddata(wd, &hair->id);
/* Direct data */
@ -3744,27 +3730,18 @@ static void write_hair(WriteData *wd, Hair *hair)
if (clayers && clayers != clayers_buff) {
MEM_freeN(clayers);
}
/* restore pointer */
hair = old_hair;
}
}
static void write_pointcloud(WriteData *wd, PointCloud *pointcloud)
static void write_pointcloud(WriteData *wd, PointCloud *pointcloud, const void *id_address)
{
if (pointcloud->id.us > 0 || wd->use_memfile) {
/* Write a copy of the pointcloud with possibly reduced number of data layers.
* Don't edit the original since other threads might be reading it. */
PointCloud *old_pointcloud = pointcloud;
PointCloud copy_pointcloud = *pointcloud;
pointcloud = &copy_pointcloud;
CustomDataLayer *players = NULL, players_buff[CD_TEMP_CHUNK_SIZE];
CustomData_file_write_prepare(
&pointcloud->pdata, &players, players_buff, ARRAY_SIZE(players_buff));
/* Write LibData */
writestruct_at_address(wd, ID_PT, PointCloud, 1, old_pointcloud, pointcloud);
writestruct_at_address(wd, ID_PT, PointCloud, 1, id_address, pointcloud);
write_iddata(wd, &pointcloud->id);
/* Direct data */
@ -3782,11 +3759,11 @@ static void write_pointcloud(WriteData *wd, PointCloud *pointcloud)
}
}
static void write_volume(WriteData *wd, Volume *volume)
static void write_volume(WriteData *wd, Volume *volume, const void *id_address)
{
if (volume->id.us > 0 || wd->use_memfile) {
/* write LibData */
writestruct(wd, ID_VO, Volume, 1, volume);
writestruct_at_address(wd, ID_VO, Volume, 1, id_address, volume);
write_iddata(wd, &volume->id);
/* direct data */
@ -3979,6 +3956,7 @@ static bool write_file_handle(Main *mainvar,
OverrideLibraryStorage *override_storage =
wd->use_memfile ? NULL : BKE_lib_override_library_operations_store_initialize();
#define ID_BUFFER_STATIC_SIZE 8192
/* This outer loop allows to save first data-blocks from real mainvar,
* then the temp ones from override process,
* if needed, without duplicating whole code. */
@ -3989,10 +3967,18 @@ static bool write_file_handle(Main *mainvar,
while (a--) {
ID *id = lbarray[a]->first;
if (id && GS(id->name) == ID_LI) {
if (id == NULL || GS(id->name) == ID_LI) {
continue; /* Libraries are handled separately below. */
}
char id_buffer_static[ID_BUFFER_STATIC_SIZE];
void *id_buffer = id_buffer_static;
const size_t idtype_struct_size = BKE_idtype_get_info_from_id(id)->struct_size;
if (idtype_struct_size > ID_BUFFER_STATIC_SIZE) {
BLI_assert(0);
id_buffer = MEM_mallocN(idtype_struct_size, __func__);
}
for (; id; id = id->next) {
/* We should never attempt to write non-regular IDs
* (i.e. all kind of temp/runtime ones). */
@ -4005,117 +3991,121 @@ static bool write_file_handle(Main *mainvar,
BKE_lib_override_library_operations_store_start(bmain, override_storage, id);
}
memcpy(id_buffer, id, idtype_struct_size);
((ID *)id_buffer)->tag = 0;
switch ((ID_Type)GS(id->name)) {
case ID_WM:
write_windowmanager(wd, (wmWindowManager *)id);
write_windowmanager(wd, (wmWindowManager *)id_buffer, id);
break;
case ID_WS:
write_workspace(wd, (WorkSpace *)id);
write_workspace(wd, (WorkSpace *)id_buffer, id);
break;
case ID_SCR:
write_screen(wd, (bScreen *)id);
write_screen(wd, (bScreen *)id_buffer, id);
break;
case ID_MC:
write_movieclip(wd, (MovieClip *)id);
write_movieclip(wd, (MovieClip *)id_buffer, id);
break;
case ID_MSK:
write_mask(wd, (Mask *)id);
write_mask(wd, (Mask *)id_buffer, id);
break;
case ID_SCE:
write_scene(wd, (Scene *)id);
write_scene(wd, (Scene *)id_buffer, id);
break;
case ID_CU:
write_curve(wd, (Curve *)id);
write_curve(wd, (Curve *)id_buffer, id);
break;
case ID_MB:
write_mball(wd, (MetaBall *)id);
write_mball(wd, (MetaBall *)id_buffer, id);
break;
case ID_IM:
write_image(wd, (Image *)id);
write_image(wd, (Image *)id_buffer, id);
break;
case ID_CA:
write_camera(wd, (Camera *)id);
write_camera(wd, (Camera *)id_buffer, id);
break;
case ID_LA:
write_light(wd, (Light *)id);
write_light(wd, (Light *)id_buffer, id);
break;
case ID_LT:
write_lattice(wd, (Lattice *)id);
write_lattice(wd, (Lattice *)id_buffer, id);
break;
case ID_VF:
write_vfont(wd, (VFont *)id);
write_vfont(wd, (VFont *)id_buffer, id);
break;
case ID_KE:
write_key(wd, (Key *)id);
write_key(wd, (Key *)id_buffer, id);
break;
case ID_WO:
write_world(wd, (World *)id);
write_world(wd, (World *)id_buffer, id);
break;
case ID_TXT:
write_text(wd, (Text *)id);
write_text(wd, (Text *)id_buffer, id);
break;
case ID_SPK:
write_speaker(wd, (Speaker *)id);
write_speaker(wd, (Speaker *)id_buffer, id);
break;
case ID_LP:
write_probe(wd, (LightProbe *)id);
write_probe(wd, (LightProbe *)id_buffer, id);
break;
case ID_SO:
write_sound(wd, (bSound *)id);
write_sound(wd, (bSound *)id_buffer, id);
break;
case ID_GR:
write_collection(wd, (Collection *)id);
write_collection(wd, (Collection *)id_buffer, id);
break;
case ID_AR:
write_armature(wd, (bArmature *)id);
write_armature(wd, (bArmature *)id_buffer, id);
break;
case ID_AC:
write_action(wd, (bAction *)id);
write_action(wd, (bAction *)id_buffer, id);
break;
case ID_OB:
write_object(wd, (Object *)id);
write_object(wd, (Object *)id_buffer, id);
break;
case ID_MA:
write_material(wd, (Material *)id);
write_material(wd, (Material *)id_buffer, id);
break;
case ID_TE:
write_texture(wd, (Tex *)id);
write_texture(wd, (Tex *)id_buffer, id);
break;
case ID_ME:
write_mesh(wd, (Mesh *)id);
write_mesh(wd, (Mesh *)id_buffer, id);
break;
case ID_PA:
write_particlesettings(wd, (ParticleSettings *)id);
write_particlesettings(wd, (ParticleSettings *)id_buffer, id);
break;
case ID_NT:
write_nodetree(wd, (bNodeTree *)id);
write_nodetree(wd, (bNodeTree *)id_buffer, id);
break;
case ID_BR:
write_brush(wd, (Brush *)id);
write_brush(wd, (Brush *)id_buffer, id);
break;
case ID_PAL:
write_palette(wd, (Palette *)id);
write_palette(wd, (Palette *)id_buffer, id);
break;
case ID_PC:
write_paintcurve(wd, (PaintCurve *)id);
write_paintcurve(wd, (PaintCurve *)id_buffer, id);
break;
case ID_GD:
write_gpencil(wd, (bGPdata *)id);
write_gpencil(wd, (bGPdata *)id_buffer, id);
break;
case ID_LS:
write_linestyle(wd, (FreestyleLineStyle *)id);
write_linestyle(wd, (FreestyleLineStyle *)id_buffer, id);
break;
case ID_CF:
write_cachefile(wd, (CacheFile *)id);
write_cachefile(wd, (CacheFile *)id_buffer, id);
break;
case ID_HA:
write_hair(wd, (Hair *)id);
write_hair(wd, (Hair *)id_buffer, id);
break;
case ID_PT:
write_pointcloud(wd, (PointCloud *)id);
write_pointcloud(wd, (PointCloud *)id_buffer, id);
break;
case ID_VO:
write_volume(wd, (Volume *)id);
write_volume(wd, (Volume *)id_buffer, id);
break;
case ID_LI:
/* Do nothing, handled below - and should never be reached. */
@ -4144,6 +4134,10 @@ static bool write_file_handle(Main *mainvar,
}
}
if (id_buffer != id_buffer_static) {
MEM_SAFE_FREE(id_buffer);
}
mywrite_flush(wd);
}
} while ((bmain != override_storage) && (bmain = override_storage));