diff options
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/blenkernel/BKE_customdata.h | 10 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/customdata.c | 184 | ||||
-rw-r--r-- | source/blender/blenloader/intern/readfile.c | 106 | ||||
-rw-r--r-- | source/blender/blenloader/intern/writefile.c | 177 |
4 files changed, 220 insertions, 257 deletions
diff --git a/source/blender/blenkernel/BKE_customdata.h b/source/blender/blenkernel/BKE_customdata.h index 92bfa3a9490..25360d4b3fa 100644 --- a/source/blender/blenkernel/BKE_customdata.h +++ b/source/blender/blenkernel/BKE_customdata.h @@ -37,6 +37,8 @@ struct BMesh; struct CustomData; struct CustomData_MeshMasks; struct ID; +struct BlendWriter; +struct BlendDataReader; typedef uint64_t CustomDataMask; /*a data type large enough to hold 1 element from any customdata layer type*/ @@ -571,6 +573,14 @@ typedef struct CustomDataTransferLayerMap { void CustomData_data_transfer(const struct MeshPairRemap *me_remap, const CustomDataTransferLayerMap *laymap); +/* .blend file I/O */ +void CustomData_blend_write(struct BlendWriter *writer, + struct CustomData *data, + int count, + CustomDataMask cddata_mask, + struct ID *id); +void CustomData_blend_read(struct BlendDataReader *reader, struct CustomData *data, int count); + #ifdef __cplusplus } #endif diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c index f728436a759..b75efb6cdf1 100644 --- a/source/blender/blenkernel/intern/customdata.c +++ b/source/blender/blenkernel/intern/customdata.c @@ -35,6 +35,8 @@ #include "DNA_meshdata_types.h" #include "DNA_pointcloud_types.h" +#include "BLI_bitmap.h" +#include "BLI_endian_switch.h" #include "BLI_math.h" #include "BLI_math_color_blend.h" #include "BLI_mempool.h" @@ -47,10 +49,14 @@ #include "BKE_customdata.h" #include "BKE_customdata_file.h" +#include "BKE_deform.h" #include "BKE_main.h" #include "BKE_mesh_mapping.h" #include "BKE_mesh_remap.h" #include "BKE_multires.h" +#include "BKE_subsurf.h" + +#include "BLO_read_write.h" #include "bmesh.h" @@ -5155,3 +5161,181 @@ void CustomData_data_transfer(const MeshPairRemap *me_remap, MEM_SAFE_FREE(tmp_data_src); } + +static void write_mdisps(BlendWriter *writer, int count, MDisps *mdlist, int external) +{ + if (mdlist) { + BLO_write_struct_array(writer, MDisps, count, mdlist); + for (int i = 0; i < count; i++) { + MDisps *md = &mdlist[i]; + if (md->disps) { + if (!external) { + BLO_write_float3_array(writer, md->totdisp, &md->disps[0][0]); + } + } + + if (md->hidden) { + BLO_write_raw(writer, BLI_BITMAP_SIZE(md->totdisp), md->hidden); + } + } + } +} + +static void write_grid_paint_mask(BlendWriter *writer, int count, GridPaintMask *grid_paint_mask) +{ + if (grid_paint_mask) { + BLO_write_struct_array(writer, GridPaintMask, count, grid_paint_mask); + for (int i = 0; i < count; i++) { + GridPaintMask *gpm = &grid_paint_mask[i]; + if (gpm->data) { + const int gridsize = BKE_ccg_gridsize(gpm->level); + BLO_write_raw(writer, sizeof(*gpm->data) * gridsize * gridsize, gpm->data); + } + } + } +} + +void CustomData_blend_write( + BlendWriter *writer, CustomData *data, int count, CustomDataMask cddata_mask, ID *id) +{ + CustomDataLayer *layers = NULL; + CustomDataLayer layers_buff[CD_TEMP_CHUNK_SIZE]; + CustomData_file_write_prepare(data, &layers, layers_buff, ARRAY_SIZE(layers_buff)); + + /* write external customdata (not for undo) */ + if (data->external && !BLO_write_is_undo(writer)) { + CustomData_external_write(data, id, cddata_mask, count, 0); + } + + BLO_write_struct_array_at_address(writer, CustomDataLayer, data->totlayer, data->layers, layers); + + for (int i = 0; i < data->totlayer; i++) { + CustomDataLayer *layer = &layers[i]; + + if (layer->type == CD_MDEFORMVERT) { + /* layer types that allocate own memory need special handling */ + BKE_defvert_blend_write(writer, count, layer->data); + } + else if (layer->type == CD_MDISPS) { + write_mdisps(writer, count, layer->data, layer->flag & CD_FLAG_EXTERNAL); + } + else if (layer->type == CD_PAINT_MASK) { + const float *layer_data = layer->data; + BLO_write_raw(writer, sizeof(*layer_data) * count, layer_data); + } + else if (layer->type == CD_SCULPT_FACE_SETS) { + const float *layer_data = layer->data; + BLO_write_raw(writer, sizeof(*layer_data) * count, layer_data); + } + else if (layer->type == CD_GRID_PAINT_MASK) { + write_grid_paint_mask(writer, count, layer->data); + } + else if (layer->type == CD_FACEMAP) { + const int *layer_data = layer->data; + BLO_write_raw(writer, sizeof(*layer_data) * count, layer_data); + } + else { + const char *structname; + int structnum; + CustomData_file_write_info(layer->type, &structname, &structnum); + if (structnum) { + int datasize = structnum * count; + BLO_write_struct_array_by_name(writer, structname, datasize, layer->data); + } + else if (!BLO_write_is_undo(writer)) { /* Do not warn on undo. */ + printf("%s error: layer '%s':%d - can't be written to file\n", + __func__, + structname, + layer->type); + } + } + } + + if (data->external) { + BLO_write_struct(writer, CustomDataExternal, data->external); + } + + if (!ELEM(layers, NULL, layers_buff)) { + MEM_freeN(layers); + } +} + +static void blend_read_mdisps(BlendDataReader *reader, int count, MDisps *mdisps, int external) +{ + if (mdisps) { + for (int i = 0; i < count; i++) { + BLO_read_data_address(reader, &mdisps[i].disps); + BLO_read_data_address(reader, &mdisps[i].hidden); + + if (mdisps[i].totdisp && !mdisps[i].level) { + /* this calculation is only correct for loop mdisps; + * if loading pre-BMesh face mdisps this will be + * overwritten with the correct value in + * bm_corners_to_loops() */ + float gridsize = sqrtf(mdisps[i].totdisp); + mdisps[i].level = (int)(logf(gridsize - 1.0f) / (float)M_LN2) + 1; + } + + if (BLO_read_requires_endian_switch(reader) && (mdisps[i].disps)) { + /* DNA_struct_switch_endian doesn't do endian swap for (*disps)[] */ + /* this does swap for data written at write_mdisps() - readfile.c */ + BLI_endian_switch_float_array(*mdisps[i].disps, mdisps[i].totdisp * 3); + } + if (!external && !mdisps[i].disps) { + mdisps[i].totdisp = 0; + } + } + } +} + +static void blend_read_paint_mask(BlendDataReader *reader, + int count, + GridPaintMask *grid_paint_mask) +{ + if (grid_paint_mask) { + for (int i = 0; i < count; i++) { + GridPaintMask *gpm = &grid_paint_mask[i]; + if (gpm->data) { + BLO_read_data_address(reader, &gpm->data); + } + } + } +} + +void CustomData_blend_read(BlendDataReader *reader, CustomData *data, int count) +{ + BLO_read_data_address(reader, &data->layers); + + /* annoying workaround for bug [#31079] loading legacy files with + * no polygons _but_ have stale customdata */ + if (UNLIKELY(count == 0 && data->layers == NULL && data->totlayer != 0)) { + CustomData_reset(data); + return; + } + + BLO_read_data_address(reader, &data->external); + + int i = 0; + while (i < data->totlayer) { + CustomDataLayer *layer = &data->layers[i]; + + if (layer->flag & CD_FLAG_EXTERNAL) { + layer->flag &= ~CD_FLAG_IN_MEMORY; + } + + layer->flag &= ~CD_FLAG_NOFREE; + + if (CustomData_verify_versions(data, i)) { + BLO_read_data_address(reader, &layer->data); + if (layer->type == CD_MDISPS) { + blend_read_mdisps(reader, count, layer->data, layer->flag & CD_FLAG_EXTERNAL); + } + else if (layer->type == CD_GRID_PAINT_MASK) { + blend_read_paint_mask(reader, count, layer->data); + } + i++; + } + } + + CustomData_update_typemap(data); +} diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index eed85546ab4..0e134d172c2 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -4126,88 +4126,6 @@ static void lib_link_mesh(BlendLibReader *reader, Mesh *me) BLO_read_id_address(reader, me->id.lib, &me->texcomesh); } -static void direct_link_mdisps(BlendDataReader *reader, int count, MDisps *mdisps, int external) -{ - if (mdisps) { - for (int i = 0; i < count; i++) { - BLO_read_data_address(reader, &mdisps[i].disps); - BLO_read_data_address(reader, &mdisps[i].hidden); - - if (mdisps[i].totdisp && !mdisps[i].level) { - /* this calculation is only correct for loop mdisps; - * if loading pre-BMesh face mdisps this will be - * overwritten with the correct value in - * bm_corners_to_loops() */ - float gridsize = sqrtf(mdisps[i].totdisp); - mdisps[i].level = (int)(logf(gridsize - 1.0f) / (float)M_LN2) + 1; - } - - if (BLO_read_requires_endian_switch(reader) && (mdisps[i].disps)) { - /* DNA_struct_switch_endian doesn't do endian swap for (*disps)[] */ - /* this does swap for data written at write_mdisps() - readfile.c */ - BLI_endian_switch_float_array(*mdisps[i].disps, mdisps[i].totdisp * 3); - } - if (!external && !mdisps[i].disps) { - mdisps[i].totdisp = 0; - } - } - } -} - -static void direct_link_grid_paint_mask(BlendDataReader *reader, - int count, - GridPaintMask *grid_paint_mask) -{ - if (grid_paint_mask) { - for (int i = 0; i < count; i++) { - GridPaintMask *gpm = &grid_paint_mask[i]; - if (gpm->data) { - BLO_read_data_address(reader, &gpm->data); - } - } - } -} - -/*this isn't really a public api function, so prototyped here*/ -static void direct_link_customdata(BlendDataReader *reader, CustomData *data, int count) -{ - - BLO_read_data_address(reader, &data->layers); - - /* annoying workaround for bug [#31079] loading legacy files with - * no polygons _but_ have stale customdata */ - if (UNLIKELY(count == 0 && data->layers == NULL && data->totlayer != 0)) { - CustomData_reset(data); - return; - } - - BLO_read_data_address(reader, &data->external); - - int i = 0; - while (i < data->totlayer) { - CustomDataLayer *layer = &data->layers[i]; - - if (layer->flag & CD_FLAG_EXTERNAL) { - layer->flag &= ~CD_FLAG_IN_MEMORY; - } - - layer->flag &= ~CD_FLAG_NOFREE; - - if (CustomData_verify_versions(data, i)) { - BLO_read_data_address(reader, &layer->data); - if (layer->type == CD_MDISPS) { - direct_link_mdisps(reader, count, layer->data, layer->flag & CD_FLAG_EXTERNAL); - } - else if (layer->type == CD_GRID_PAINT_MASK) { - direct_link_grid_paint_mask(reader, count, layer->data); - } - i++; - } - } - - CustomData_update_typemap(data); -} - static void direct_link_mesh(BlendDataReader *reader, Mesh *mesh) { BLO_read_pointer_array(reader, (void **)&mesh->mat); @@ -4229,15 +4147,15 @@ static void direct_link_mesh(BlendDataReader *reader, Mesh *mesh) BLO_read_data_address(reader, &mesh->adt); BKE_animdata_blend_read_data(reader, mesh->adt); - /* Normally BKE_defvert_blend_read should be called in direct_link_customdata, + /* Normally BKE_defvert_blend_read should be called in CustomData_blend_read, * but for backwards compatibility in do_versions to work we do it here. */ BKE_defvert_blend_read(reader, mesh->totvert, mesh->dvert); - direct_link_customdata(reader, &mesh->vdata, mesh->totvert); - direct_link_customdata(reader, &mesh->edata, mesh->totedge); - direct_link_customdata(reader, &mesh->fdata, mesh->totface); - direct_link_customdata(reader, &mesh->ldata, mesh->totloop); - direct_link_customdata(reader, &mesh->pdata, mesh->totpoly); + CustomData_blend_read(reader, &mesh->vdata, mesh->totvert); + CustomData_blend_read(reader, &mesh->edata, mesh->totedge); + CustomData_blend_read(reader, &mesh->fdata, mesh->totface); + CustomData_blend_read(reader, &mesh->ldata, mesh->totloop); + CustomData_blend_read(reader, &mesh->pdata, mesh->totpoly); mesh->texflag &= ~ME_AUTOSPACE_EVALUATED; mesh->edit_mesh = NULL; @@ -4254,10 +4172,10 @@ static void direct_link_mesh(BlendDataReader *reader, Mesh *mesh) BLO_read_list(reader, &mesh->mr->levels); MultiresLevel *lvl = mesh->mr->levels.first; - direct_link_customdata(reader, &mesh->mr->vdata, lvl->totvert); + CustomData_blend_read(reader, &mesh->mr->vdata, lvl->totvert); BKE_defvert_blend_read( reader, lvl->totvert, CustomData_get(&mesh->mr->vdata, 0, CD_MDEFORMVERT)); - direct_link_customdata(reader, &mesh->mr->fdata, lvl->totface); + CustomData_blend_read(reader, &mesh->mr->fdata, lvl->totface); BLO_read_data_address(reader, &mesh->mr->edge_flags); BLO_read_data_address(reader, &mesh->mr->edge_creases); @@ -7984,8 +7902,8 @@ static void direct_link_hair(BlendDataReader *reader, Hair *hair) BKE_animdata_blend_read_data(reader, hair->adt); /* Geometry */ - direct_link_customdata(reader, &hair->pdata, hair->totpoint); - direct_link_customdata(reader, &hair->cdata, hair->totcurve); + CustomData_blend_read(reader, &hair->pdata, hair->totpoint); + CustomData_blend_read(reader, &hair->cdata, hair->totcurve); BKE_hair_update_customdata_pointers(hair); /* Materials */ @@ -8011,7 +7929,7 @@ static void direct_link_pointcloud(BlendDataReader *reader, PointCloud *pointclo BKE_animdata_blend_read_data(reader, pointcloud->adt); /* Geometry */ - direct_link_customdata(reader, &pointcloud->pdata, pointcloud->totpoint); + CustomData_blend_read(reader, &pointcloud->pdata, pointcloud->totpoint); BKE_pointcloud_update_customdata_pointers(pointcloud); /* Materials */ @@ -8072,7 +7990,7 @@ static void direct_link_simulation(BlendDataReader *reader, Simulation *simulati BLO_read_data_address(reader, &state->type); if (STREQ(state->type, SIM_TYPE_NAME_PARTICLE_SIMULATION)) { ParticleSimulationState *particle_state = (ParticleSimulationState *)state; - direct_link_customdata(reader, &particle_state->attributes, particle_state->tot_particles); + CustomData_blend_read(reader, &particle_state->attributes, particle_state->tot_particles); } } diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index e69f46735d4..c764f2d9e05 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -1785,100 +1785,6 @@ static void write_curve(BlendWriter *writer, Curve *cu, const void *id_address) } } -static void write_mdisps(BlendWriter *writer, int count, MDisps *mdlist, int external) -{ - if (mdlist) { - BLO_write_struct_array(writer, MDisps, count, mdlist); - for (int i = 0; i < count; i++) { - MDisps *md = &mdlist[i]; - if (md->disps) { - if (!external) { - BLO_write_float3_array(writer, md->totdisp, &md->disps[0][0]); - } - } - - if (md->hidden) { - BLO_write_raw(writer, BLI_BITMAP_SIZE(md->totdisp), md->hidden); - } - } - } -} - -static void write_grid_paint_mask(BlendWriter *writer, int count, GridPaintMask *grid_paint_mask) -{ - if (grid_paint_mask) { - BLO_write_struct_array(writer, GridPaintMask, count, grid_paint_mask); - for (int i = 0; i < count; i++) { - GridPaintMask *gpm = &grid_paint_mask[i]; - if (gpm->data) { - const int gridsize = BKE_ccg_gridsize(gpm->level); - BLO_write_raw(writer, sizeof(*gpm->data) * gridsize * gridsize, gpm->data); - } - } - } -} - -static void write_customdata(BlendWriter *writer, - ID *id, - int count, - CustomData *data, - CustomDataLayer *layers, - CustomDataMask cddata_mask) -{ - /* write external customdata (not for undo) */ - if (data->external && !BLO_write_is_undo(writer)) { - CustomData_external_write(data, id, cddata_mask, count, 0); - } - - BLO_write_struct_array_at_address(writer, CustomDataLayer, data->totlayer, data->layers, layers); - - for (int i = 0; i < data->totlayer; i++) { - CustomDataLayer *layer = &layers[i]; - const char *structname; - int structnum, datasize; - - if (layer->type == CD_MDEFORMVERT) { - /* layer types that allocate own memory need special handling */ - BKE_defvert_blend_write(writer, count, layer->data); - } - else if (layer->type == CD_MDISPS) { - write_mdisps(writer, count, layer->data, layer->flag & CD_FLAG_EXTERNAL); - } - else if (layer->type == CD_PAINT_MASK) { - const float *layer_data = layer->data; - BLO_write_raw(writer, sizeof(*layer_data) * count, layer_data); - } - else if (layer->type == CD_SCULPT_FACE_SETS) { - const float *layer_data = layer->data; - BLO_write_raw(writer, sizeof(*layer_data) * count, layer_data); - } - else if (layer->type == CD_GRID_PAINT_MASK) { - write_grid_paint_mask(writer, count, layer->data); - } - else if (layer->type == CD_FACEMAP) { - const int *layer_data = layer->data; - BLO_write_raw(writer, sizeof(*layer_data) * count, layer_data); - } - else { - CustomData_file_write_info(layer->type, &structname, &structnum); - if (structnum) { - datasize = structnum * count; - BLO_write_struct_array_by_name(writer, structname, datasize, layer->data); - } - else if (!BLO_write_is_undo(writer)) { /* Do not warn on undo. */ - printf("%s error: layer '%s':%d - can't be written to file\n", - __func__, - structname, - layer->type); - } - } - } - - if (data->external) { - BLO_write_struct(writer, CustomDataExternal, data->external); - } -} - static void write_mesh(BlendWriter *writer, Mesh *mesh, const void *id_address) { if (mesh->id.us > 0 || BLO_write_is_undo(writer)) { @@ -1888,21 +1794,6 @@ static void write_mesh(BlendWriter *writer, Mesh *mesh, const void *id_address) memset(&mesh->fdata, 0, sizeof(mesh->fdata)); memset(&mesh->runtime, 0, sizeof(mesh->runtime)); - /* Reduce xdata layers, fill xlayers with layers to be written. - * This makes xdata invalid for Blender, which is why we made a - * temporary local copy. */ - CustomDataLayer *vlayers = NULL, vlayers_buff[CD_TEMP_CHUNK_SIZE]; - CustomDataLayer *elayers = NULL, elayers_buff[CD_TEMP_CHUNK_SIZE]; - CustomDataLayer *flayers = NULL, flayers_buff[CD_TEMP_CHUNK_SIZE]; - CustomDataLayer *llayers = NULL, llayers_buff[CD_TEMP_CHUNK_SIZE]; - CustomDataLayer *players = NULL, players_buff[CD_TEMP_CHUNK_SIZE]; - - CustomData_file_write_prepare(&mesh->vdata, &vlayers, vlayers_buff, ARRAY_SIZE(vlayers_buff)); - CustomData_file_write_prepare(&mesh->edata, &elayers, elayers_buff, ARRAY_SIZE(elayers_buff)); - flayers = flayers_buff; - 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)); - BLO_write_id_struct(writer, Mesh, id_address, &mesh->id); write_iddata(writer, &mesh->id); @@ -1914,29 +1805,12 @@ static void write_mesh(BlendWriter *writer, Mesh *mesh, const void *id_address) BLO_write_pointer_array(writer, mesh->totcol, mesh->mat); BLO_write_raw(writer, sizeof(MSelect) * mesh->totselect, mesh->mselect); - write_customdata(writer, &mesh->id, mesh->totvert, &mesh->vdata, vlayers, CD_MASK_MESH.vmask); - write_customdata(writer, &mesh->id, mesh->totedge, &mesh->edata, elayers, CD_MASK_MESH.emask); + CustomData_blend_write(writer, &mesh->vdata, mesh->totvert, CD_MASK_MESH.vmask, &mesh->id); + CustomData_blend_write(writer, &mesh->edata, mesh->totedge, CD_MASK_MESH.emask, &mesh->id); /* fdata is really a dummy - written so slots align */ - write_customdata(writer, &mesh->id, mesh->totface, &mesh->fdata, flayers, CD_MASK_MESH.fmask); - write_customdata(writer, &mesh->id, mesh->totloop, &mesh->ldata, llayers, CD_MASK_MESH.lmask); - write_customdata(writer, &mesh->id, mesh->totpoly, &mesh->pdata, players, CD_MASK_MESH.pmask); - - /* free temporary data */ - if (vlayers && vlayers != vlayers_buff) { - MEM_freeN(vlayers); - } - if (elayers && elayers != elayers_buff) { - MEM_freeN(elayers); - } - if (flayers && flayers != flayers_buff) { - MEM_freeN(flayers); - } - if (llayers && llayers != llayers_buff) { - MEM_freeN(llayers); - } - if (players && players != players_buff) { - MEM_freeN(players); - } + CustomData_blend_write(writer, &mesh->fdata, mesh->totface, CD_MASK_MESH.fmask, &mesh->id); + CustomData_blend_write(writer, &mesh->ldata, mesh->totloop, CD_MASK_MESH.lmask, &mesh->id); + CustomData_blend_write(writer, &mesh->pdata, mesh->totpoly, CD_MASK_MESH.pmask, &mesh->id); } } @@ -3468,30 +3342,17 @@ static void write_workspace(BlendWriter *writer, WorkSpace *workspace, const voi static void write_hair(BlendWriter *writer, Hair *hair, const void *id_address) { if (hair->id.us > 0 || BLO_write_is_undo(writer)) { - 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 */ BLO_write_id_struct(writer, Hair, id_address, &hair->id); write_iddata(writer, &hair->id); /* Direct data */ - write_customdata(writer, &hair->id, hair->totpoint, &hair->pdata, players, CD_MASK_ALL); - write_customdata(writer, &hair->id, hair->totcurve, &hair->cdata, clayers, CD_MASK_ALL); + CustomData_blend_write(writer, &hair->pdata, hair->totpoint, CD_MASK_ALL, &hair->id); + CustomData_blend_write(writer, &hair->cdata, hair->totcurve, CD_MASK_ALL, &hair->id); BLO_write_pointer_array(writer, hair->totcol, hair->mat); if (hair->adt) { BKE_animdata_blend_write(writer, hair->adt); } - - /* Remove temporary data. */ - if (players && players != players_buff) { - MEM_freeN(players); - } - if (clayers && clayers != clayers_buff) { - MEM_freeN(clayers); - } } } @@ -3507,8 +3368,8 @@ static void write_pointcloud(BlendWriter *writer, PointCloud *pointcloud, const write_iddata(writer, &pointcloud->id); /* Direct data */ - write_customdata( - writer, &pointcloud->id, pointcloud->totpoint, &pointcloud->pdata, players, CD_MASK_ALL); + CustomData_blend_write( + writer, &pointcloud->pdata, pointcloud->totpoint, CD_MASK_ALL, &pointcloud->id); BLO_write_pointer_array(writer, pointcloud->totcol, pointcloud->mat); if (pointcloud->adt) { BKE_animdata_blend_write(writer, pointcloud->adt); @@ -3569,21 +3430,11 @@ static void write_simulation(BlendWriter *writer, Simulation *simulation, const ParticleSimulationState *particle_state = (ParticleSimulationState *)state; BLO_write_struct(writer, ParticleSimulationState, particle_state); - CustomDataLayer *layers = NULL; - CustomDataLayer layers_buff[CD_TEMP_CHUNK_SIZE]; - CustomData_file_write_prepare( - &particle_state->attributes, &layers, layers_buff, ARRAY_SIZE(layers_buff)); - - write_customdata(writer, - &simulation->id, - particle_state->tot_particles, - &particle_state->attributes, - layers, - CD_MASK_ALL); - - if (layers != NULL && layers != layers_buff) { - MEM_freeN(layers); - } + CustomData_blend_write(writer, + &particle_state->attributes, + particle_state->tot_particles, + CD_MASK_ALL, + &simulation->id); } else if (STREQ(state->type, SIM_TYPE_NAME_PARTICLE_MESH_EMITTER)) { ParticleMeshEmitterSimulationState *emitter_state = (ParticleMeshEmitterSimulationState *) |