Fix: Incorrect forward-compatible saving of face sets

There were two errors with the function used to convert face sets
to the legacy mesh format for keeping forward compatibility:
- It was moved before `CustomData_blend_write_prepare` so it
  operated on an empty span.
- It modified the mesh when it's only supposed to change the copy
  of the layers written to the file.

Differential Revision: https://developer.blender.org/D17210
This commit is contained in:
Hans Goudey 2023-02-05 18:09:22 -05:00
parent 501352ef05
commit b642dc7bc7
Notes: blender-bot 2023-02-17 19:54:32 +01:00
Referenced by commit 8b416f7f60, Fix #104869: Crash converting UV maps to legacy format
3 changed files with 14 additions and 11 deletions

View File

@ -36,7 +36,7 @@ void BKE_mesh_legacy_convert_uvs_to_generic(Mesh *mesh);
* Move face sets to the legacy type from a generic type.
*/
void BKE_mesh_legacy_face_set_from_generic(
Mesh *mesh, blender::MutableSpan<CustomDataLayer> poly_layers_to_write);
blender::MutableSpan<CustomDataLayer> poly_layers_to_write);
/**
* Copy face sets to the generic data type from the legacy type.
*/

View File

@ -270,7 +270,6 @@ static void mesh_blend_write(BlendWriter *writer, ID *id, const void *id_address
BKE_mesh_legacy_convert_selection_layers_to_flags(mesh);
BKE_mesh_legacy_convert_material_indices_to_mpoly(mesh);
BKE_mesh_legacy_bevel_weight_from_layers(mesh);
BKE_mesh_legacy_face_set_from_generic(mesh, poly_layers);
BKE_mesh_legacy_edge_crease_from_layers(mesh);
BKE_mesh_legacy_sharp_edges_to_flags(mesh);
BKE_mesh_legacy_attribute_strings_to_flags(mesh);
@ -292,6 +291,7 @@ static void mesh_blend_write(BlendWriter *writer, ID *id, const void *id_address
if (!BLO_write_is_undo(writer)) {
BKE_mesh_legacy_convert_uvs_to_struct(mesh, temp_arrays_for_legacy_format, loop_layers);
BKE_mesh_legacy_face_set_from_generic(poly_layers);
}
}

View File

@ -1224,23 +1224,26 @@ void BKE_mesh_tessface_ensure(struct Mesh *mesh)
/** \name Face Set Conversion
* \{ */
void BKE_mesh_legacy_face_set_from_generic(Mesh *mesh,
blender::MutableSpan<CustomDataLayer> poly_layers)
void BKE_mesh_legacy_face_set_from_generic(blender::MutableSpan<CustomDataLayer> poly_layers)
{
using namespace blender;
void *faceset_data = nullptr;
bool changed = false;
for (CustomDataLayer &layer : poly_layers) {
if (StringRef(layer.name) == ".sculpt_face_set") {
faceset_data = layer.data;
layer.data = nullptr;
CustomData_free_layer_named(&mesh->pdata, ".sculpt_face_set", mesh->totpoly);
layer.type = CD_SCULPT_FACE_SETS;
layer.name[0] = '\0';
changed = true;
break;
}
}
if (faceset_data != nullptr) {
CustomData_add_layer(
&mesh->pdata, CD_SCULPT_FACE_SETS, CD_ASSIGN, faceset_data, mesh->totpoly);
if (!changed) {
return;
}
/* #CustomData expects the layers to be sorted in increasing order based on type. */
std::stable_sort(
poly_layers.begin(),
poly_layers.end(),
[](const CustomDataLayer &a, const CustomDataLayer &b) { return a.type < b.type; });
}
void BKE_mesh_legacy_face_set_to_generic(Mesh *mesh)