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:
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
|
@ -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.
|
||||
*/
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue