From 91684f0de4540f15a8cf7938517702d53921d04a Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Thu, 12 Jun 2025 14:47:48 +0200 Subject: [PATCH] Mesh: 4.5 forward compatibility for active/default UV maps as names The transition to `AttributeStorage` requires the active and default UV map status to be stored separately, since currently they're stored as flags on `CustomDataLayer`. This commit adds forward compatible reading for when the status is written as attribute names on `Mesh` instead, which is what we already do for color attributes. Pull Request: https://projects.blender.org/blender/blender/pulls/140134 --- .../intern/attribute_legacy_convert.cc | 16 ++++++++++++++++ source/blender/blenkernel/intern/mesh.cc | 8 ++++++++ source/blender/makesdna/DNA_mesh_types.h | 11 +++++++++++ 3 files changed, 35 insertions(+) diff --git a/source/blender/blenkernel/intern/attribute_legacy_convert.cc b/source/blender/blenkernel/intern/attribute_legacy_convert.cc index 2004e85d54f..de5f8f7a61a 100644 --- a/source/blender/blenkernel/intern/attribute_legacy_convert.cc +++ b/source/blender/blenkernel/intern/attribute_legacy_convert.cc @@ -245,6 +245,22 @@ void mesh_convert_storage_to_customdata(Mesh &mesh) {AttrDomain::Edge, {mesh.edge_data, mesh.edges_num}}, {AttrDomain::Face, {mesh.face_data, mesh.faces_num}}, {AttrDomain::Corner, {mesh.corner_data, mesh.corners_num}}}); + if (const char *name = mesh.active_uv_map_attribute) { + const int layer_n = CustomData_get_named_layer(&mesh.corner_data, CD_PROP_FLOAT2, name); + if (layer_n != -1) { + CustomData_set_layer_active(&mesh.corner_data, CD_PROP_FLOAT2, layer_n); + } + MEM_freeN(mesh.active_uv_map_attribute); + mesh.active_uv_map_attribute = nullptr; + } + if (const char *name = mesh.default_uv_map_attribute) { + const int layer_n = CustomData_get_named_layer(&mesh.corner_data, CD_PROP_FLOAT2, name); + if (layer_n != -1) { + CustomData_set_layer_render(&mesh.corner_data, CD_PROP_FLOAT2, layer_n); + } + MEM_freeN(mesh.default_uv_map_attribute); + mesh.default_uv_map_attribute = nullptr; + } } void mesh_convert_customdata_to_storage(Mesh &mesh) { diff --git a/source/blender/blenkernel/intern/mesh.cc b/source/blender/blenkernel/intern/mesh.cc index 8f63f68bde5..888ae5527f8 100644 --- a/source/blender/blenkernel/intern/mesh.cc +++ b/source/blender/blenkernel/intern/mesh.cc @@ -201,6 +201,10 @@ static void mesh_copy_data(Main *bmain, MEM_dupallocN(mesh_src->active_color_attribute)); mesh_dst->default_color_attribute = static_cast( MEM_dupallocN(mesh_src->default_color_attribute)); + mesh_dst->active_uv_map_attribute = static_cast( + MEM_dupallocN(mesh_src->active_uv_map_attribute)); + mesh_dst->default_uv_map_attribute = static_cast( + MEM_dupallocN(mesh_src->default_uv_map_attribute)); CustomData_init_from( &mesh_src->vert_data, &mesh_dst->vert_data, mask.vmask, mesh_dst->verts_num); @@ -248,6 +252,8 @@ static void mesh_free_data(ID *id) BLI_freelistN(&mesh->vertex_group_names); MEM_SAFE_FREE(mesh->active_color_attribute); MEM_SAFE_FREE(mesh->default_color_attribute); + MEM_SAFE_FREE(mesh->active_uv_map_attribute); + MEM_SAFE_FREE(mesh->default_uv_map_attribute); mesh->attribute_storage.wrap().~AttributeStorage(); if (mesh->face_offset_indices) { blender::implicit_sharing::free_shared_data(&mesh->face_offset_indices, @@ -464,6 +470,8 @@ static void mesh_blend_read_data(BlendDataReader *reader, ID *id) } BLO_read_string(reader, &mesh->active_color_attribute); BLO_read_string(reader, &mesh->default_color_attribute); + BLO_read_string(reader, &mesh->active_uv_map_attribute); + BLO_read_string(reader, &mesh->default_uv_map_attribute); /* Forward compatibility. To be removed when runtime format changes. */ blender::bke::mesh_convert_storage_to_customdata(*mesh); diff --git a/source/blender/makesdna/DNA_mesh_types.h b/source/blender/makesdna/DNA_mesh_types.h index 871fa0ce8e6..ba0c52ed3ca 100644 --- a/source/blender/makesdna/DNA_mesh_types.h +++ b/source/blender/makesdna/DNA_mesh_types.h @@ -178,6 +178,17 @@ typedef struct Mesh { /** The color attribute used by default (i.e. for rendering) if no name is given explicitly. */ char *default_color_attribute; + /** + * The UV map currently selected in the list and edited by a user. + * Currently only used for file forward compatibility (see #AttributeStorage). + */ + char *active_uv_map_attribute; + /** + * The UV map used by default (i.e. for rendering) if no name is given explicitly. + * Currently only used for file forward compatibility (see #AttributeStorage). + */ + char *default_uv_map_attribute; + /** * User-defined symmetry flag (#eMeshSymmetryType) that causes editing operations to maintain * symmetrical geometry. Supported by operations such as transform and weight-painting.