From fb7ef40006b938bab25f4bb60d8a23fc9ef2e8dc Mon Sep 17 00:00:00 2001 From: Chris Blackbourn Date: Thu, 11 Aug 2022 11:20:00 +1200 Subject: Cleanup: refactoring uvislands to prepare for python api Add #bm_uv_ensure_head_table See also: D15598 --- source/blender/blenkernel/BKE_mesh_mapping.h | 3 ++ source/blender/editors/mesh/editmesh_utils.c | 50 +++++++++++++++++----------- 2 files changed, 34 insertions(+), 19 deletions(-) diff --git a/source/blender/blenkernel/BKE_mesh_mapping.h b/source/blender/blenkernel/BKE_mesh_mapping.h index 2bc6289af85..455f42366cc 100644 --- a/source/blender/blenkernel/BKE_mesh_mapping.h +++ b/source/blender/blenkernel/BKE_mesh_mapping.h @@ -71,6 +71,9 @@ typedef struct UvElementMap { /* If Non-NULL, address UvElements by `BM_elem_index_get(BMVert*)`. */ struct UvElement **vertex; + /* If Non-NULL, pointer to local head of each unique UV. */ + struct UvElement **head_table; + /* Number of Islands in the mesh */ int totalIslands; /* Stores the starting index in buf where each island begins */ diff --git a/source/blender/editors/mesh/editmesh_utils.c b/source/blender/editors/mesh/editmesh_utils.c index c446fb8b3e1..a0e20e4db8a 100644 --- a/source/blender/editors/mesh/editmesh_utils.c +++ b/source/blender/editors/mesh/editmesh_utils.c @@ -593,6 +593,31 @@ UvMapVert *BM_uv_vert_map_at_index(UvVertMap *vmap, uint v) return vmap->vert[v]; } +static void bm_uv_ensure_head_table(UvElementMap *element_map) +{ + if (element_map->head_table) { + return; + } + + /* For each UvElement, locate the "separate" UvElement that precedes it in the linked list. */ + element_map->head_table = MEM_mallocN(sizeof(*element_map->head_table) * element_map->total_uvs, + "uv_element_map_head_table"); + UvElement **head_table = element_map->head_table; + for (int i = 0; i < element_map->total_uvs; i++) { + UvElement *head = element_map->storage + i; + if (head->separate) { + UvElement *element = head; + while (element) { + head_table[element - element_map->storage] = head; + element = element->next; + if (element && element->separate) { + break; + } + } + } + } +} + #define INVALID_ISLAND ((unsigned int)-1) static void bm_uv_assign_island(UvElementMap *element_map, @@ -620,23 +645,9 @@ static int bm_uv_edge_select_build_islands(UvElementMap *element_map, bool uv_selected, int cd_loop_uv_offset) { - int total_uvs = element_map->total_uvs; + bm_uv_ensure_head_table(element_map); - /* For each UvElement, locate the "separate" UvElement that precedes it in the linked list. */ - UvElement **head_table = MEM_mallocN(sizeof(*head_table) * total_uvs, "uv_island_head_table"); - for (int i = 0; i < total_uvs; i++) { - UvElement *head = element_map->storage + i; - if (head->separate) { - UvElement *element = head; - while (element) { - head_table[element - element_map->storage] = head; - element = element->next; - if (element && element->separate) { - break; - } - } - } - } + int total_uvs = element_map->total_uvs; /* Depth first search the graph, building islands as we go. */ int nislands = 0; @@ -676,7 +687,7 @@ static int bm_uv_edge_select_build_islands(UvElementMap *element_map, if (!uv_selected || uvedit_edge_select_test(scene, element->l, cd_loop_uv_offset)) { UvElement *next = BM_uv_element_get(element_map, element->l->next->f, element->l->next); if (next->island == INVALID_ISLAND) { - UvElement *tail = head_table[next - element_map->storage]; + UvElement *tail = element_map->head_table[next - element_map->storage]; stack_uv[stacksize_uv++] = tail; while (tail) { bm_uv_assign_island(element_map, tail, nislands, map, islandbuf, islandbufsize++); @@ -692,7 +703,7 @@ static int bm_uv_edge_select_build_islands(UvElementMap *element_map, if (!uv_selected || uvedit_edge_select_test(scene, element->l->prev, cd_loop_uv_offset)) { UvElement *prev = BM_uv_element_get(element_map, element->l->prev->f, element->l->prev); if (prev->island == INVALID_ISLAND) { - UvElement *tail = head_table[prev - element_map->storage]; + UvElement *tail = element_map->head_table[prev - element_map->storage]; stack_uv[stacksize_uv++] = tail; while (tail) { bm_uv_assign_island(element_map, tail, nislands, map, islandbuf, islandbufsize++); @@ -716,7 +727,7 @@ static int bm_uv_edge_select_build_islands(UvElementMap *element_map, BLI_assert(islandbufsize == total_uvs); MEM_SAFE_FREE(stack_uv); - MEM_SAFE_FREE(head_table); + MEM_SAFE_FREE(element_map->head_table); return nislands; } @@ -1047,6 +1058,7 @@ void BM_uv_element_map_free(UvElementMap *element_map) if (element_map) { MEM_SAFE_FREE(element_map->storage); MEM_SAFE_FREE(element_map->vertex); + MEM_SAFE_FREE(element_map->head_table); MEM_SAFE_FREE(element_map->islandIndices); MEM_SAFE_FREE(element_map); } -- cgit v1.2.3