Refactor: move CustomData .blend I/O to blenkernel
This is part of T76372.
This commit is contained in:
@@ -37,6 +37,8 @@ struct BMesh;
|
|||||||
struct CustomData;
|
struct CustomData;
|
||||||
struct CustomData_MeshMasks;
|
struct CustomData_MeshMasks;
|
||||||
struct ID;
|
struct ID;
|
||||||
|
struct BlendWriter;
|
||||||
|
struct BlendDataReader;
|
||||||
typedef uint64_t CustomDataMask;
|
typedef uint64_t CustomDataMask;
|
||||||
|
|
||||||
/*a data type large enough to hold 1 element from any customdata layer type*/
|
/*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,
|
void CustomData_data_transfer(const struct MeshPairRemap *me_remap,
|
||||||
const CustomDataTransferLayerMap *laymap);
|
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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -35,6 +35,8 @@
|
|||||||
#include "DNA_meshdata_types.h"
|
#include "DNA_meshdata_types.h"
|
||||||
#include "DNA_pointcloud_types.h"
|
#include "DNA_pointcloud_types.h"
|
||||||
|
|
||||||
|
#include "BLI_bitmap.h"
|
||||||
|
#include "BLI_endian_switch.h"
|
||||||
#include "BLI_math.h"
|
#include "BLI_math.h"
|
||||||
#include "BLI_math_color_blend.h"
|
#include "BLI_math_color_blend.h"
|
||||||
#include "BLI_mempool.h"
|
#include "BLI_mempool.h"
|
||||||
@@ -47,10 +49,14 @@
|
|||||||
|
|
||||||
#include "BKE_customdata.h"
|
#include "BKE_customdata.h"
|
||||||
#include "BKE_customdata_file.h"
|
#include "BKE_customdata_file.h"
|
||||||
|
#include "BKE_deform.h"
|
||||||
#include "BKE_main.h"
|
#include "BKE_main.h"
|
||||||
#include "BKE_mesh_mapping.h"
|
#include "BKE_mesh_mapping.h"
|
||||||
#include "BKE_mesh_remap.h"
|
#include "BKE_mesh_remap.h"
|
||||||
#include "BKE_multires.h"
|
#include "BKE_multires.h"
|
||||||
|
#include "BKE_subsurf.h"
|
||||||
|
|
||||||
|
#include "BLO_read_write.h"
|
||||||
|
|
||||||
#include "bmesh.h"
|
#include "bmesh.h"
|
||||||
|
|
||||||
@@ -5155,3 +5161,181 @@ void CustomData_data_transfer(const MeshPairRemap *me_remap,
|
|||||||
|
|
||||||
MEM_SAFE_FREE(tmp_data_src);
|
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);
|
||||||
|
}
|
||||||
|
|||||||
@@ -4126,88 +4126,6 @@ static void lib_link_mesh(BlendLibReader *reader, Mesh *me)
|
|||||||
BLO_read_id_address(reader, me->id.lib, &me->texcomesh);
|
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)
|
static void direct_link_mesh(BlendDataReader *reader, Mesh *mesh)
|
||||||
{
|
{
|
||||||
BLO_read_pointer_array(reader, (void **)&mesh->mat);
|
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);
|
BLO_read_data_address(reader, &mesh->adt);
|
||||||
BKE_animdata_blend_read_data(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. */
|
* but for backwards compatibility in do_versions to work we do it here. */
|
||||||
BKE_defvert_blend_read(reader, mesh->totvert, mesh->dvert);
|
BKE_defvert_blend_read(reader, mesh->totvert, mesh->dvert);
|
||||||
|
|
||||||
direct_link_customdata(reader, &mesh->vdata, mesh->totvert);
|
CustomData_blend_read(reader, &mesh->vdata, mesh->totvert);
|
||||||
direct_link_customdata(reader, &mesh->edata, mesh->totedge);
|
CustomData_blend_read(reader, &mesh->edata, mesh->totedge);
|
||||||
direct_link_customdata(reader, &mesh->fdata, mesh->totface);
|
CustomData_blend_read(reader, &mesh->fdata, mesh->totface);
|
||||||
direct_link_customdata(reader, &mesh->ldata, mesh->totloop);
|
CustomData_blend_read(reader, &mesh->ldata, mesh->totloop);
|
||||||
direct_link_customdata(reader, &mesh->pdata, mesh->totpoly);
|
CustomData_blend_read(reader, &mesh->pdata, mesh->totpoly);
|
||||||
|
|
||||||
mesh->texflag &= ~ME_AUTOSPACE_EVALUATED;
|
mesh->texflag &= ~ME_AUTOSPACE_EVALUATED;
|
||||||
mesh->edit_mesh = NULL;
|
mesh->edit_mesh = NULL;
|
||||||
@@ -4254,10 +4172,10 @@ static void direct_link_mesh(BlendDataReader *reader, Mesh *mesh)
|
|||||||
BLO_read_list(reader, &mesh->mr->levels);
|
BLO_read_list(reader, &mesh->mr->levels);
|
||||||
MultiresLevel *lvl = mesh->mr->levels.first;
|
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(
|
BKE_defvert_blend_read(
|
||||||
reader, lvl->totvert, CustomData_get(&mesh->mr->vdata, 0, CD_MDEFORMVERT));
|
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_flags);
|
||||||
BLO_read_data_address(reader, &mesh->mr->edge_creases);
|
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);
|
BKE_animdata_blend_read_data(reader, hair->adt);
|
||||||
|
|
||||||
/* Geometry */
|
/* Geometry */
|
||||||
direct_link_customdata(reader, &hair->pdata, hair->totpoint);
|
CustomData_blend_read(reader, &hair->pdata, hair->totpoint);
|
||||||
direct_link_customdata(reader, &hair->cdata, hair->totcurve);
|
CustomData_blend_read(reader, &hair->cdata, hair->totcurve);
|
||||||
BKE_hair_update_customdata_pointers(hair);
|
BKE_hair_update_customdata_pointers(hair);
|
||||||
|
|
||||||
/* Materials */
|
/* Materials */
|
||||||
@@ -8011,7 +7929,7 @@ static void direct_link_pointcloud(BlendDataReader *reader, PointCloud *pointclo
|
|||||||
BKE_animdata_blend_read_data(reader, pointcloud->adt);
|
BKE_animdata_blend_read_data(reader, pointcloud->adt);
|
||||||
|
|
||||||
/* Geometry */
|
/* Geometry */
|
||||||
direct_link_customdata(reader, &pointcloud->pdata, pointcloud->totpoint);
|
CustomData_blend_read(reader, &pointcloud->pdata, pointcloud->totpoint);
|
||||||
BKE_pointcloud_update_customdata_pointers(pointcloud);
|
BKE_pointcloud_update_customdata_pointers(pointcloud);
|
||||||
|
|
||||||
/* Materials */
|
/* Materials */
|
||||||
@@ -8072,7 +7990,7 @@ static void direct_link_simulation(BlendDataReader *reader, Simulation *simulati
|
|||||||
BLO_read_data_address(reader, &state->type);
|
BLO_read_data_address(reader, &state->type);
|
||||||
if (STREQ(state->type, SIM_TYPE_NAME_PARTICLE_SIMULATION)) {
|
if (STREQ(state->type, SIM_TYPE_NAME_PARTICLE_SIMULATION)) {
|
||||||
ParticleSimulationState *particle_state = (ParticleSimulationState *)state;
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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)
|
static void write_mesh(BlendWriter *writer, Mesh *mesh, const void *id_address)
|
||||||
{
|
{
|
||||||
if (mesh->id.us > 0 || BLO_write_is_undo(writer)) {
|
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->fdata, 0, sizeof(mesh->fdata));
|
||||||
memset(&mesh->runtime, 0, sizeof(mesh->runtime));
|
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);
|
BLO_write_id_struct(writer, Mesh, id_address, &mesh->id);
|
||||||
write_iddata(writer, &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_pointer_array(writer, mesh->totcol, mesh->mat);
|
||||||
BLO_write_raw(writer, sizeof(MSelect) * mesh->totselect, mesh->mselect);
|
BLO_write_raw(writer, sizeof(MSelect) * mesh->totselect, mesh->mselect);
|
||||||
|
|
||||||
write_customdata(writer, &mesh->id, mesh->totvert, &mesh->vdata, vlayers, CD_MASK_MESH.vmask);
|
CustomData_blend_write(writer, &mesh->vdata, mesh->totvert, CD_MASK_MESH.vmask, &mesh->id);
|
||||||
write_customdata(writer, &mesh->id, mesh->totedge, &mesh->edata, elayers, CD_MASK_MESH.emask);
|
CustomData_blend_write(writer, &mesh->edata, mesh->totedge, CD_MASK_MESH.emask, &mesh->id);
|
||||||
/* fdata is really a dummy - written so slots align */
|
/* fdata is really a dummy - written so slots align */
|
||||||
write_customdata(writer, &mesh->id, mesh->totface, &mesh->fdata, flayers, CD_MASK_MESH.fmask);
|
CustomData_blend_write(writer, &mesh->fdata, mesh->totface, CD_MASK_MESH.fmask, &mesh->id);
|
||||||
write_customdata(writer, &mesh->id, mesh->totloop, &mesh->ldata, llayers, CD_MASK_MESH.lmask);
|
CustomData_blend_write(writer, &mesh->ldata, mesh->totloop, CD_MASK_MESH.lmask, &mesh->id);
|
||||||
write_customdata(writer, &mesh->id, mesh->totpoly, &mesh->pdata, players, CD_MASK_MESH.pmask);
|
CustomData_blend_write(writer, &mesh->pdata, mesh->totpoly, CD_MASK_MESH.pmask, &mesh->id);
|
||||||
|
|
||||||
/* 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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -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)
|
static void write_hair(BlendWriter *writer, Hair *hair, const void *id_address)
|
||||||
{
|
{
|
||||||
if (hair->id.us > 0 || BLO_write_is_undo(writer)) {
|
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 */
|
/* Write LibData */
|
||||||
BLO_write_id_struct(writer, Hair, id_address, &hair->id);
|
BLO_write_id_struct(writer, Hair, id_address, &hair->id);
|
||||||
write_iddata(writer, &hair->id);
|
write_iddata(writer, &hair->id);
|
||||||
|
|
||||||
/* Direct data */
|
/* Direct data */
|
||||||
write_customdata(writer, &hair->id, hair->totpoint, &hair->pdata, players, CD_MASK_ALL);
|
CustomData_blend_write(writer, &hair->pdata, hair->totpoint, CD_MASK_ALL, &hair->id);
|
||||||
write_customdata(writer, &hair->id, hair->totcurve, &hair->cdata, clayers, CD_MASK_ALL);
|
CustomData_blend_write(writer, &hair->cdata, hair->totcurve, CD_MASK_ALL, &hair->id);
|
||||||
BLO_write_pointer_array(writer, hair->totcol, hair->mat);
|
BLO_write_pointer_array(writer, hair->totcol, hair->mat);
|
||||||
if (hair->adt) {
|
if (hair->adt) {
|
||||||
BKE_animdata_blend_write(writer, 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);
|
write_iddata(writer, &pointcloud->id);
|
||||||
|
|
||||||
/* Direct data */
|
/* Direct data */
|
||||||
write_customdata(
|
CustomData_blend_write(
|
||||||
writer, &pointcloud->id, pointcloud->totpoint, &pointcloud->pdata, players, CD_MASK_ALL);
|
writer, &pointcloud->pdata, pointcloud->totpoint, CD_MASK_ALL, &pointcloud->id);
|
||||||
BLO_write_pointer_array(writer, pointcloud->totcol, pointcloud->mat);
|
BLO_write_pointer_array(writer, pointcloud->totcol, pointcloud->mat);
|
||||||
if (pointcloud->adt) {
|
if (pointcloud->adt) {
|
||||||
BKE_animdata_blend_write(writer, 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;
|
ParticleSimulationState *particle_state = (ParticleSimulationState *)state;
|
||||||
BLO_write_struct(writer, ParticleSimulationState, particle_state);
|
BLO_write_struct(writer, ParticleSimulationState, particle_state);
|
||||||
|
|
||||||
CustomDataLayer *layers = NULL;
|
CustomData_blend_write(writer,
|
||||||
CustomDataLayer layers_buff[CD_TEMP_CHUNK_SIZE];
|
&particle_state->attributes,
|
||||||
CustomData_file_write_prepare(
|
particle_state->tot_particles,
|
||||||
&particle_state->attributes, &layers, layers_buff, ARRAY_SIZE(layers_buff));
|
CD_MASK_ALL,
|
||||||
|
&simulation->id);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (STREQ(state->type, SIM_TYPE_NAME_PARTICLE_MESH_EMITTER)) {
|
else if (STREQ(state->type, SIM_TYPE_NAME_PARTICLE_MESH_EMITTER)) {
|
||||||
ParticleMeshEmitterSimulationState *emitter_state = (ParticleMeshEmitterSimulationState *)
|
ParticleMeshEmitterSimulationState *emitter_state = (ParticleMeshEmitterSimulationState *)
|
||||||
|
|||||||
Reference in New Issue
Block a user