diff options
author | Jacques Lucke <jacques@blender.org> | 2020-08-28 16:45:11 +0300 |
---|---|---|
committer | Jacques Lucke <jacques@blender.org> | 2020-08-28 16:49:14 +0300 |
commit | 8815996418f0259b9abb9446da9bc137145de7d6 (patch) | |
tree | 7a62aa9cf197f1934a622ee8506ba0d0e024c8d2 /source/blender/blenkernel/intern | |
parent | 5db5ac611a5cc2645d4c8638c640bc1c2372a6bd (diff) |
Refactor: move Mesh .blend I/O to IDTypeInfo callbacks
I'm also adding `BKE_id_blend_write`, so that it can be accessed
outside of `readfile.c`.
Diffstat (limited to 'source/blender/blenkernel/intern')
-rw-r--r-- | source/blender/blenkernel/intern/lib_id.c | 29 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/mesh.c | 167 |
2 files changed, 192 insertions, 4 deletions
diff --git a/source/blender/blenkernel/intern/lib_id.c b/source/blender/blenkernel/intern/lib_id.c index 7fb19458eec..678f717efe4 100644 --- a/source/blender/blenkernel/intern/lib_id.c +++ b/source/blender/blenkernel/intern/lib_id.c @@ -75,6 +75,8 @@ #include "RNA_access.h" +#include "BLO_read_write.h" + #include "atomic_ops.h" //#define DEBUG_TIME @@ -2326,3 +2328,30 @@ void BKE_id_reorder(const ListBase *lb, ID *id, ID *relative, bool after) *id_order = relative_order - 1; } } + +void BKE_id_blend_write(BlendWriter *writer, ID *id) +{ + /* ID_WM's id->properties are considered runtime only, and never written in .blend file. */ + if (id->properties && !ELEM(GS(id->name), ID_WM)) { + IDP_BlendWrite(writer, id->properties); + } + + if (id->override_library) { + BLO_write_struct(writer, IDOverrideLibrary, id->override_library); + + BLO_write_struct_list(writer, IDOverrideLibraryProperty, &id->override_library->properties); + LISTBASE_FOREACH (IDOverrideLibraryProperty *, op, &id->override_library->properties) { + BLO_write_string(writer, op->rna_path); + + BLO_write_struct_list(writer, IDOverrideLibraryPropertyOperation, &op->operations); + LISTBASE_FOREACH (IDOverrideLibraryPropertyOperation *, opop, &op->operations) { + if (opop->subitem_reference_name) { + BLO_write_string(writer, opop->subitem_reference_name); + } + if (opop->subitem_local_name) { + BLO_write_string(writer, opop->subitem_local_name); + } + } + } + } +} diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c index b6e77c100f0..3e606a5a512 100644 --- a/source/blender/blenkernel/intern/mesh.c +++ b/source/blender/blenkernel/intern/mesh.c @@ -23,6 +23,9 @@ #include "MEM_guardedalloc.h" +/* allow using deprecated functionality for .blend file I/O */ +#define DNA_DEPRECATED_ALLOW + #include "DNA_defaults.h" #include "DNA_key_types.h" #include "DNA_material_types.h" @@ -32,6 +35,7 @@ #include "BLI_bitmap.h" #include "BLI_edgehash.h" +#include "BLI_endian_switch.h" #include "BLI_ghash.h" #include "BLI_hash.h" #include "BLI_linklist.h" @@ -43,6 +47,7 @@ #include "BLT_translation.h" #include "BKE_anim_data.h" +#include "BKE_deform.h" #include "BKE_editmesh.h" #include "BKE_global.h" #include "BKE_idtype.h" @@ -63,6 +68,8 @@ #include "DEG_depsgraph.h" #include "DEG_depsgraph_query.h" +#include "BLO_read_write.h" + static void mesh_clear_geometry(Mesh *mesh); static void mesh_tessface_clear_intern(Mesh *mesh, int free_customdata); @@ -163,6 +170,158 @@ static void mesh_foreach_id(ID *id, LibraryForeachIDData *data) } } +static void mesh_blend_write(BlendWriter *writer, ID *id, const void *id_address) +{ + Mesh *mesh = (Mesh *)id; + if (mesh->id.us > 0 || BLO_write_is_undo(writer)) { + /* cache only - don't write */ + mesh->mface = NULL; + mesh->totface = 0; + memset(&mesh->fdata, 0, sizeof(mesh->fdata)); + memset(&mesh->runtime, 0, sizeof(mesh->runtime)); + + BLO_write_id_struct(writer, Mesh, id_address, &mesh->id); + BKE_id_blend_write(writer, &mesh->id); + + /* direct data */ + if (mesh->adt) { + BKE_animdata_blend_write(writer, mesh->adt); + } + + BLO_write_pointer_array(writer, mesh->totcol, mesh->mat); + BLO_write_raw(writer, sizeof(MSelect) * mesh->totselect, mesh->mselect); + + 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 */ + 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); + } +} + +static void mesh_blend_read_data(BlendDataReader *reader, ID *id) +{ + Mesh *mesh = (Mesh *)id; + BLO_read_pointer_array(reader, (void **)&mesh->mat); + + BLO_read_data_address(reader, &mesh->mvert); + BLO_read_data_address(reader, &mesh->medge); + BLO_read_data_address(reader, &mesh->mface); + BLO_read_data_address(reader, &mesh->mloop); + BLO_read_data_address(reader, &mesh->mpoly); + BLO_read_data_address(reader, &mesh->tface); + BLO_read_data_address(reader, &mesh->mtface); + BLO_read_data_address(reader, &mesh->mcol); + BLO_read_data_address(reader, &mesh->dvert); + BLO_read_data_address(reader, &mesh->mloopcol); + BLO_read_data_address(reader, &mesh->mloopuv); + BLO_read_data_address(reader, &mesh->mselect); + + /* animdata */ + BLO_read_data_address(reader, &mesh->adt); + BKE_animdata_blend_read_data(reader, mesh->adt); + + /* 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); + + 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; + BKE_mesh_runtime_reset(mesh); + + /* happens with old files */ + if (mesh->mselect == NULL) { + mesh->totselect = 0; + } + + /* Multires data */ + BLO_read_data_address(reader, &mesh->mr); + if (mesh->mr) { + BLO_read_list(reader, &mesh->mr->levels); + MultiresLevel *lvl = mesh->mr->levels.first; + + CustomData_blend_read(reader, &mesh->mr->vdata, lvl->totvert); + BKE_defvert_blend_read( + reader, lvl->totvert, CustomData_get(&mesh->mr->vdata, 0, CD_MDEFORMVERT)); + 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); + + BLO_read_data_address(reader, &mesh->mr->verts); + + /* If mesh has the same number of vertices as the + * highest multires level, load the current mesh verts + * into multires and discard the old data. Needed + * because some saved files either do not have a verts + * array, or the verts array contains out-of-date + * data. */ + if (mesh->totvert == ((MultiresLevel *)mesh->mr->levels.last)->totvert) { + if (mesh->mr->verts) { + MEM_freeN(mesh->mr->verts); + } + mesh->mr->verts = MEM_dupallocN(mesh->mvert); + } + + for (; lvl; lvl = lvl->next) { + BLO_read_data_address(reader, &lvl->verts); + BLO_read_data_address(reader, &lvl->faces); + BLO_read_data_address(reader, &lvl->edges); + BLO_read_data_address(reader, &lvl->colfaces); + } + } + + /* if multires is present but has no valid vertex data, + * there's no way to recover it; silently remove multires */ + if (mesh->mr && !mesh->mr->verts) { + multires_free(mesh->mr); + mesh->mr = NULL; + } + + if ((BLO_read_requires_endian_switch(reader)) && mesh->tface) { + TFace *tf = mesh->tface; + for (int i = 0; i < mesh->totface; i++, tf++) { + BLI_endian_switch_uint32_array(tf->col, 4); + } + } +} + +static void mesh_blend_read_lib(BlendLibReader *reader, ID *id) +{ + Mesh *me = (Mesh *)id; + /* this check added for python created meshes */ + if (me->mat) { + for (int i = 0; i < me->totcol; i++) { + BLO_read_id_address(reader, me->id.lib, &me->mat[i]); + } + } + else { + me->totcol = 0; + } + + BLO_read_id_address(reader, me->id.lib, &me->ipo); // XXX: deprecated: old anim sys + BLO_read_id_address(reader, me->id.lib, &me->key); + BLO_read_id_address(reader, me->id.lib, &me->texcomesh); +} + +static void mesh_read_expand(BlendExpander *expander, ID *id) +{ + Mesh *me = (Mesh *)id; + for (int a = 0; a < me->totcol; a++) { + BLO_expand(expander, me->mat[a]); + } + + BLO_expand(expander, me->key); + BLO_expand(expander, me->texcomesh); +} + IDTypeInfo IDType_ID_ME = { .id_code = ID_ME, .id_filter = FILTER_ID_ME, @@ -180,10 +339,10 @@ IDTypeInfo IDType_ID_ME = { .foreach_id = mesh_foreach_id, .foreach_cache = NULL, - .blend_write = NULL, - .blend_read_data = NULL, - .blend_read_lib = NULL, - .blend_read_expand = NULL, + .blend_write = mesh_blend_write, + .blend_read_data = mesh_blend_read_data, + .blend_read_lib = mesh_blend_read_lib, + .blend_read_expand = mesh_read_expand, }; enum { |