From dfeb425e518f9328d3ff972d91dc3a0200d957c7 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Fri, 18 Jul 2025 16:13:40 -0400 Subject: [PATCH] Cleanup: Improve BKE_mesh_uv_vert_map_create arguments Use Span and modern naming for mesh data. --- source/blender/blenkernel/BKE_mesh_mapping.hh | 8 ++-- .../blender/blenkernel/intern/mesh_mapping.cc | 37 +++++++++---------- .../intern/subdiv_converter_mesh.cc | 15 +++++--- .../blender/blenkernel/intern/subsurf_ccg.cc | 12 ++++-- 4 files changed, 41 insertions(+), 31 deletions(-) diff --git a/source/blender/blenkernel/BKE_mesh_mapping.hh b/source/blender/blenkernel/BKE_mesh_mapping.hh index 3f15823f929..e5992e21b23 100644 --- a/source/blender/blenkernel/BKE_mesh_mapping.hh +++ b/source/blender/blenkernel/BKE_mesh_mapping.hh @@ -100,10 +100,10 @@ struct MeshElemMap { /* mapping */ UvVertMap *BKE_mesh_uv_vert_map_create(blender::OffsetIndices faces, - const int *corner_verts, - const float (*mloopuv)[2], - unsigned int totvert, - const float limit[2], + blender::Span corner_verts, + blender::Span uv_map, + int verts_num, + const blender::float2 &limit, bool use_winding); UvMapVert *BKE_mesh_uv_vert_map_get_vert(UvVertMap *vmap, unsigned int v); diff --git a/source/blender/blenkernel/intern/mesh_mapping.cc b/source/blender/blenkernel/intern/mesh_mapping.cc index 090017f924e..62694ecdf63 100644 --- a/source/blender/blenkernel/intern/mesh_mapping.cc +++ b/source/blender/blenkernel/intern/mesh_mapping.cc @@ -35,17 +35,16 @@ /** \name Mesh Connectivity Mapping * \{ */ -UvVertMap *BKE_mesh_uv_vert_map_create(const blender::OffsetIndices faces, - const int *corner_verts, - const float (*mloopuv)[2], - uint totvert, - const float limit[2], - const bool use_winding) +UvVertMap *BKE_mesh_uv_vert_map_create(blender::OffsetIndices faces, + blender::Span corner_verts, + blender::Span uv_map, + int verts_num, + const blender::float2 &limit, + bool use_winding) { + using namespace blender; /* NOTE: N-gon version WIP, based on #BM_uv_vert_map_create. */ - UvVertMap *vmap; - UvMapVert *buf; int i, totuv, nverts; totuv = 0; @@ -59,9 +58,9 @@ UvVertMap *BKE_mesh_uv_vert_map_create(const blender::OffsetIndices faces, return nullptr; } - vmap = MEM_callocN("UvVertMap"); - buf = vmap->buf = MEM_calloc_arrayN(size_t(totuv), "UvMapVert"); - vmap->vert = MEM_calloc_arrayN(totvert, "UvMapVert*"); + UvVertMap *vmap = MEM_callocN("UvVertMap"); + UvMapVert *buf = vmap->buf = MEM_calloc_arrayN(size_t(totuv), "UvMapVert"); + vmap->vert = MEM_calloc_arrayN(size_t(verts_num), "UvMapVert*"); if (!vmap->vert || !vmap->buf) { BKE_mesh_uv_vert_map_free(vmap); @@ -73,9 +72,9 @@ UvVertMap *BKE_mesh_uv_vert_map_create(const blender::OffsetIndices faces, winding = MEM_calloc_arrayN(size_t(faces.size()), "winding"); } - blender::Vector face_uvs; + Vector face_uvs; for (const int64_t a : faces.index_range()) { - const blender::IndexRange face = faces[a]; + const IndexRange face = faces[a]; if (use_winding) { face_uvs.resize(face.size()); @@ -91,7 +90,7 @@ UvVertMap *BKE_mesh_uv_vert_map_create(const blender::OffsetIndices faces, vmap->vert[corner_verts[face[i]]] = buf; if (use_winding) { - copy_v2_v2(face_uvs[i], mloopuv[face[i]]); + copy_v2_v2(face_uvs[i], uv_map[face[i]]); } buf++; @@ -104,8 +103,8 @@ UvVertMap *BKE_mesh_uv_vert_map_create(const blender::OffsetIndices faces, } /* sort individual uvs for each vert */ - for (uint a = 0; a < totvert; a++) { - UvMapVert *newvlist = nullptr, *vlist = vmap->vert[a]; + for (const int64_t vert : IndexRange(verts_num)) { + UvMapVert *newvlist = nullptr, *vlist = vmap->vert[vert]; UvMapVert *iterv, *v, *lastv, *next; const float *uv, *uv2; float uvdiff[2]; @@ -116,14 +115,14 @@ UvVertMap *BKE_mesh_uv_vert_map_create(const blender::OffsetIndices faces, v->next = newvlist; newvlist = v; - uv = mloopuv[faces[v->face_index].start() + v->loop_of_face_index]; + uv = uv_map[faces[v->face_index].start() + v->loop_of_face_index]; lastv = nullptr; iterv = vlist; while (iterv) { next = iterv->next; - uv2 = mloopuv[faces[iterv->face_index].start() + iterv->loop_of_face_index]; + uv2 = uv_map[faces[iterv->face_index].start() + iterv->loop_of_face_index]; sub_v2_v2v2(uvdiff, uv2, uv); if (fabsf(uv[0] - uv2[0]) < limit[0] && fabsf(uv[1] - uv2[1]) < limit[1] && @@ -148,7 +147,7 @@ UvVertMap *BKE_mesh_uv_vert_map_create(const blender::OffsetIndices faces, newvlist->separate = true; } - vmap->vert[a] = newvlist; + vmap->vert[vert] = newvlist; } if (use_winding) { diff --git a/source/blender/blenkernel/intern/subdiv_converter_mesh.cc b/source/blender/blenkernel/intern/subdiv_converter_mesh.cc index 04f888dd03e..99785303bcb 100644 --- a/source/blender/blenkernel/intern/subdiv_converter_mesh.cc +++ b/source/blender/blenkernel/intern/subdiv_converter_mesh.cc @@ -188,17 +188,22 @@ static void precalc_uv_layer(const OpenSubdiv_Converter *converter, const int la { ConverterStorage *storage = static_cast(converter->user_data); const Mesh *mesh = storage->mesh; - const float(*mloopuv)[2] = static_cast( - CustomData_get_layer_n(&mesh->corner_data, CD_PROP_FLOAT2, layer_index)); + const bke::AttributeAccessor attributes = mesh->attributes(); + const StringRef name = CustomData_get_layer_name( + &mesh->corner_data, CD_PROP_FLOAT2, layer_index); + const VArraySpan uv_map = *attributes.lookup(name, bke::AttrDomain::Corner); const int num_vert = mesh->verts_num; - const float limit[2] = {STD_UV_CONNECT_LIMIT, STD_UV_CONNECT_LIMIT}; /* Initialize memory required for the operations. */ if (storage->loop_uv_indices == nullptr) { storage->loop_uv_indices = MEM_malloc_arrayN(size_t(mesh->corners_num), "loop uv vertex index"); } - UvVertMap *uv_vert_map = BKE_mesh_uv_vert_map_create( - storage->faces, storage->corner_verts.data(), mloopuv, num_vert, limit, true); + UvVertMap *uv_vert_map = BKE_mesh_uv_vert_map_create(storage->faces, + storage->corner_verts, + uv_map, + num_vert, + blender::float2(STD_UV_CONNECT_LIMIT), + true); /* NOTE: First UV vertex is supposed to be always marked as separate. */ storage->num_uv_coordinates = -1; for (int vertex_index = 0; vertex_index < num_vert; vertex_index++) { diff --git a/source/blender/blenkernel/intern/subsurf_ccg.cc b/source/blender/blenkernel/intern/subsurf_ccg.cc index 4f2ff75dd5e..5ab81e2932e 100644 --- a/source/blender/blenkernel/intern/subsurf_ccg.cc +++ b/source/blender/blenkernel/intern/subsurf_ccg.cc @@ -261,15 +261,21 @@ static int ss_sync_from_uv(CCGSubSurf *ss, UvMapVert *v; UvVertMap *vmap; blender::Vector fverts; - float limit[2]; float uv[3] = {0.0f, 0.0f, 0.0f}; /* only first 2 values are written into */ - limit[0] = limit[1] = STD_UV_CONNECT_LIMIT; + const int corners_num = faces.total_size(); + /* previous behavior here is without accounting for winding, however this causes stretching in * UV map in really simple cases with mirror + subsurf, see second part of #44530. * Also, initially intention is to treat merged vertices from mirror modifier as seams. * This fixes a very old regression (2.49 was correct here) */ - vmap = BKE_mesh_uv_vert_map_create(faces, corner_verts, mloopuv, totvert, limit, true); + vmap = BKE_mesh_uv_vert_map_create( + faces, + {corner_verts, corners_num}, + {reinterpret_cast(mloopuv), corners_num}, + totvert, + blender::float2(STD_UV_CONNECT_LIMIT), + true); if (!vmap) { return 0; }