Fix T100863, T100875: Vertex group reading broken for recent files

This patch consists of two related fixes. The first is a simple fix for
forward compatibility, setting the Mesh.dvert pointer when writing a
file allows old Blender versions to read vertex groups from newly saved
files.

The second part is a bit uglier and more complex. Normally mesh vertex
group data is read in mesh_blend_read_data, for backward compatibility
with very old files. However, after 05952aa94d the mesh.dvert
pointer was not set, so the data was not read. Reading vertex group
layers when reading custom data is enough to fix that issue. We need to
read the data from *both* places, but BKE_defvert_blend_read cannot run
twice without memory leaks, so first try reading from custom data, then
read the pointer if that fails.

Differential Revision: https://developer.blender.org/D15905
This commit is contained in:
Hans Goudey 2022-09-07 14:33:29 -05:00
parent e53405bf15
commit 0a32f6b76a
Notes: blender-bot 2023-02-14 06:05:22 +01:00
Referenced by issue #100875, Crash on undo in Heist production files after recent changes in mesh data
Referenced by issue #100863, Regression: Crash on opening the file containing weights
2 changed files with 9 additions and 4 deletions

View File

@ -5404,6 +5404,9 @@ void CustomData_blend_read(BlendDataReader *reader, CustomData *data, const int
else if (layer->type == CD_GRID_PAINT_MASK) {
blend_read_paint_mask(reader, count, static_cast<GridPaintMask *>(layer->data));
}
else if (layer->type == CD_MDEFORMVERT) {
BKE_defvert_blend_read(reader, count, static_cast<MDeformVert *>(layer->data));
}
i++;
}
}

View File

@ -249,7 +249,6 @@ static void mesh_blend_write(BlendWriter *writer, ID *id, const void *id_address
else {
Set<std::string> names_to_skip;
if (!BLO_write_is_undo(writer)) {
BKE_mesh_legacy_convert_hide_layers_to_flags(mesh);
BKE_mesh_legacy_convert_material_indices_to_mpoly(mesh);
/* When converting to the old mesh format, don't save redundant attributes. */
@ -260,6 +259,7 @@ static void mesh_blend_write(BlendWriter *writer, ID *id, const void *id_address
mesh->medge = const_cast<MEdge *>(mesh->edges().data());
mesh->mpoly = const_cast<MPoly *>(mesh->polys().data());
mesh->mloop = const_cast<MLoop *>(mesh->loops().data());
mesh->dvert = const_cast<MDeformVert *>(mesh->deform_verts().data());
}
CustomData_blend_write_prepare(mesh->vdata, vert_layers, names_to_skip);
@ -314,9 +314,6 @@ static void mesh_blend_read_data(BlendDataReader *reader, ID *id)
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);
BLO_read_list(reader, &mesh->vertex_group_names);
CustomData_blend_read(reader, &mesh->vdata, mesh->totvert);
@ -324,6 +321,11 @@ static void mesh_blend_read_data(BlendDataReader *reader, ID *id)
CustomData_blend_read(reader, &mesh->fdata, mesh->totface);
CustomData_blend_read(reader, &mesh->ldata, mesh->totloop);
CustomData_blend_read(reader, &mesh->pdata, mesh->totpoly);
if (mesh->deform_verts().is_empty()) {
/* Vertex group data was also an owning pointer in old Blender versions.
* Don't read them again if they were read as part of #CustomData. */
BKE_defvert_blend_read(reader, mesh->totvert, mesh->dvert);
}
mesh->texflag &= ~ME_AUTOSPACE_EVALUATED;
mesh->edit_mesh = nullptr;