Cleanup: refactoring uvislands to prepare for python api

Rename vert -> vertex.
Add `BM_uv_element_get_head`.

See also: D15598
This commit is contained in:
Chris Blackbourn 2022-08-08 11:47:30 +12:00
parent 9b924b2a23
commit bb8488c62c
5 changed files with 74 additions and 98 deletions

View File

@ -61,14 +61,16 @@ typedef struct UvElement {
* the number of uvs per island.
*/
typedef struct UvElementMap {
/* address UvElements by their vertex */
struct UvElement **vert;
/** UvElement Storage. */
struct UvElement *storage;
/** Total number of UVs. */
int total_uvs;
/** Total number of unique UVs. */
int total_unique_uvs;
/* If Non-NULL, address UvElements by `BM_elem_index_get(BMVert*)`. */
struct UvElement **vertex;
/* Number of Islands in the mesh */
int totalIslands;
/* Stores the starting index in buf where each island begins */

View File

@ -144,6 +144,7 @@ void BM_uv_element_map_free(struct UvElementMap *element_map);
struct UvElement *BM_uv_element_get(struct UvElementMap *map,
struct BMFace *efa,
struct BMLoop *l);
struct UvElement *BM_uv_element_get_head(struct UvElementMap *map, struct UvElement *child);
/**
* Can we edit UV's for this mesh?

View File

@ -732,25 +732,18 @@ UvElementMap *BM_uv_element_map_create(BMesh *bm,
BMVert *ev;
BMFace *efa;
BMLoop *l;
BMIter iter, liter;
/* vars from original func */
UvElementMap *element_map;
bool *winding = NULL;
BLI_buffer_declare_static(vec2f, tf_uv_buf, BLI_BUFFER_NOP, BM_DEFAULT_NGON_STACK_SIZE);
MLoopUV *luv;
int totverts, totfaces, i, totuv, j;
const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
if (cd_loop_uv_offset < 0) {
return NULL;
}
BM_mesh_elem_index_ensure(bm, BM_VERT | BM_FACE);
totfaces = bm->totface;
totverts = bm->totvert;
totuv = 0;
/* generate UvElement array */
/* Count total uvs. */
int totuv = 0;
BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
if (BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) {
continue;
@ -764,6 +757,7 @@ UvElementMap *BM_uv_element_map_create(BMesh *bm,
totuv += efa->len;
}
else {
BMLoop *l;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
if (uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) {
totuv++;
@ -776,18 +770,17 @@ UvElementMap *BM_uv_element_map_create(BMesh *bm,
return NULL;
}
element_map = (UvElementMap *)MEM_callocN(sizeof(*element_map), "UvElementMap");
UvElementMap *element_map = (UvElementMap *)MEM_callocN(sizeof(*element_map), "UvElementMap");
element_map->total_uvs = totuv;
element_map->vert = (UvElement **)MEM_callocN(sizeof(*element_map->vert) * totverts,
"UvElementVerts");
element_map->vertex = (UvElement **)MEM_callocN(sizeof(*element_map->vertex) * bm->totvert,
"UvElementVerts");
element_map->storage = (UvElement *)MEM_callocN(sizeof(*element_map->storage) * totuv,
"UvElement");
if (use_winding) {
winding = MEM_callocN(sizeof(*winding) * totfaces, "winding");
}
bool *winding = use_winding ? MEM_callocN(sizeof(*winding) * bm->totface, "winding") : NULL;
UvElement *buf = element_map->storage;
int j;
BM_ITER_MESH_INDEX (efa, &iter, bm, BM_FACES_OF_MESH, j) {
if (BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) {
@ -804,18 +797,20 @@ UvElementMap *BM_uv_element_map_create(BMesh *bm,
tf_uv = (float(*)[2])BLI_buffer_reinit_data(&tf_uv_buf, vec2f, efa->len);
}
int i;
BMLoop *l;
BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) {
if (uv_selected && !uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) {
continue;
}
buf->l = l;
buf->separate = 0;
buf->island = INVALID_ISLAND;
buf->loop_of_poly_index = i;
buf->next = element_map->vert[BM_elem_index_get(l->v)];
element_map->vert[BM_elem_index_get(l->v)] = buf;
/* Insert to head of linked list associated with BMVert. */
buf->next = element_map->vertex[BM_elem_index_get(l->v)];
element_map->vertex[BM_elem_index_get(l->v)] = buf;
if (use_winding) {
luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
@ -830,34 +825,33 @@ UvElementMap *BM_uv_element_map_create(BMesh *bm,
}
}
/* sort individual uvs for each vert */
/* For each BMVert, sort associated linked list into unique uvs. */
int i;
BM_ITER_MESH_INDEX (ev, &iter, bm, BM_VERTS_OF_MESH, i) {
UvElement *newvlist = NULL, *vlist = element_map->vert[i];
UvElement *iterv, *v, *lastv, *next;
const float *uv, *uv2;
bool uv_vert_sel, uv2_vert_sel;
UvElement *newvlist = NULL;
UvElement *vlist = element_map->vertex[i];
while (vlist) {
v = vlist;
/* Detach head from unsorted list. */
UvElement *v = vlist;
vlist = vlist->next;
v->next = newvlist;
newvlist = v;
UvElement *newvlist = v;
l = v->l;
luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
uv = luv->uv;
uv_vert_sel = uvedit_uv_select_test(scene, l, cd_loop_uv_offset);
luv = BM_ELEM_CD_GET_VOID_P(v->l, cd_loop_uv_offset);
const float *uv = luv->uv;
bool uv_vert_sel = uvedit_uv_select_test(scene, v->l, cd_loop_uv_offset);
lastv = NULL;
iterv = vlist;
UvElement *lastv = NULL;
UvElement *iterv = vlist;
/* Scan through unsorted list, finding UvElements which match `v`. */
while (iterv) {
next = iterv->next;
UvElement *next = iterv->next;
l = iterv->l;
luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
uv2 = luv->uv;
uv2_vert_sel = uvedit_uv_select_test(scene, l, cd_loop_uv_offset);
luv = BM_ELEM_CD_GET_VOID_P(iterv->l, cd_loop_uv_offset);
const float *uv2 = luv->uv;
const bool uv2_vert_sel = uvedit_uv_select_test(scene, iterv->l, cd_loop_uv_offset);
/* Check if the uv loops share the same selection state (if not, they are not connected as
* they have been ripped or other edit commands have separated them). */
@ -886,18 +880,15 @@ UvElementMap *BM_uv_element_map_create(BMesh *bm,
newvlist->separate = true;
}
element_map->vert[i] = newvlist;
/* Write back sorted list. */
element_map->vertex[i] = newvlist;
}
if (use_winding) {
MEM_freeN(winding);
}
MEM_SAFE_FREE(winding);
if (do_islands) {
uint *map;
UvElement *islandbuf;
/* island number for faces */
int *island_number = NULL;
int nislands = 0, islandbufsize = 0;
@ -905,8 +896,10 @@ UvElementMap *BM_uv_element_map_create(BMesh *bm,
map = MEM_mallocN(sizeof(*map) * totuv, "uvelement_remap");
BMFace **stack = MEM_mallocN(sizeof(*stack) * bm->totface, "uv_island_face_stack");
islandbuf = MEM_callocN(sizeof(*islandbuf) * totuv, "uvelement_island_buffer");
island_number = MEM_mallocN(sizeof(*island_number) * totfaces, "uv_island_number_face");
copy_vn_i(island_number, totfaces, INVALID_ISLAND);
/* Island number for BMFaces. */
int *island_number = MEM_callocN(sizeof(*island_number) * bm->totface,
"uv_island_number_face");
copy_vn_i(island_number, bm->totface, INVALID_ISLAND);
const bool use_uv_edge_connectivity = scene->toolsettings->uv_flag & UV_SYNC_SELECTION ?
scene->toolsettings->selectmode & SCE_SELECT_EDGE :
@ -930,14 +923,15 @@ UvElementMap *BM_uv_element_map_create(BMesh *bm,
while (stacksize > 0) {
efa = stack[--stacksize];
BMLoop *l;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
if (uv_selected && !uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) {
continue;
}
UvElement *element, *initelement = element_map->vert[BM_elem_index_get(l->v)];
UvElement *initelement = element_map->vertex[BM_elem_index_get(l->v)];
for (element = initelement; element; element = element->next) {
for (UvElement *element = initelement; element; element = element->next) {
if (element->separate) {
initelement = element;
}
@ -968,13 +962,13 @@ UvElementMap *BM_uv_element_map_create(BMesh *bm,
}
}
MEM_freeN(island_number);
MEM_SAFE_FREE(island_number);
/* remap */
for (i = 0; i < bm->totvert; i++) {
/* important since we may do selection only. Some of these may be NULL */
if (element_map->vert[i]) {
element_map->vert[i] = &islandbuf[map[element_map->vert[i] - element_map->storage]];
if (element_map->vertex[i]) {
element_map->vertex[i] = &islandbuf[map[element_map->vertex[i] - element_map->storage]];
}
}
@ -1032,24 +1026,35 @@ void BM_uv_vert_map_free(UvVertMap *vmap)
void BM_uv_element_map_free(UvElementMap *element_map)
{
if (element_map) {
MEM_SAFE_FREE(element_map->vert);
MEM_SAFE_FREE(element_map->storage);
MEM_SAFE_FREE(element_map->vertex);
MEM_SAFE_FREE(element_map->islandIndices);
MEM_SAFE_FREE(element_map);
}
}
UvElement *BM_uv_element_get(UvElementMap *map, BMFace *efa, BMLoop *l)
UvElement *BM_uv_element_get(UvElementMap *element_map, BMFace *efa, BMLoop *l)
{
for (UvElement *element = map->vert[BM_elem_index_get(l->v)]; element; element = element->next) {
UvElement *element = element_map->vertex[BM_elem_index_get(l->v)];
while (element) {
if (element->l->f == efa) {
return element;
}
element = element->next;
}
return NULL;
}
UvElement *BM_uv_element_get_head(UvElementMap *element_map, UvElement *child)
{
if (!child) {
return NULL;
}
return element_map->vertex[BM_elem_index_get(child->l->v)];
}
/** \} */
/* -------------------------------------------------------------------- */

View File

@ -549,7 +549,7 @@ static UvSculptData *uv_sculpt_stroke_init(bContext *C, wmOperator *op, const wm
int counter = -1;
/* initialize the unique UVs */
for (int i = 0; i < bm->totvert; i++) {
UvElement *element = data->elementMap->vert[i];
UvElement *element = data->elementMap->vertex[i];
for (; element; element = element->next) {
if (element->separate) {
if (do_island_optimization && (element->island != island_index)) {

View File

@ -569,22 +569,14 @@ static void stitch_island_calculate_vert_rotation(UvElement *element,
StitchState *state,
IslandStitchData *island_stitch_data)
{
int index;
UvElement *element_iter;
float rotation = 0, rotation_neg = 0;
int rot_elem = 0, rot_elem_neg = 0;
BMLoop *l;
if (element->island == ssc->static_island && !ssc->midpoints) {
return;
}
l = element->l;
index = BM_elem_index_get(l->v);
element_iter = state->element_map->vert[index];
UvElement *element_iter = BM_uv_element_get_head(state->element_map, element);
for (; element_iter; element_iter = element_iter->next) {
if (element_iter->separate &&
stitch_check_uvs_state_stitchable(element, element_iter, ssc, state)) {
@ -690,7 +682,7 @@ static void stitch_uv_edge_generate_linked_edges(GHash *edge_hash, StitchState *
UvElement *element2 = state->uvs[edge->uv2];
/* Now iterate through all faces and try to find edges sharing the same vertices */
UvElement *iter1 = element_map->vert[BM_elem_index_get(element1->l->v)];
UvElement *iter1 = BM_uv_element_get_head(state->element_map, element1);
UvEdge *last_set = edge;
int elemindex2 = BM_elem_index_get(element2->l->v);
@ -758,15 +750,7 @@ static void determine_uv_stitchability(UvElement *element,
StitchState *state,
IslandStitchData *island_stitch_data)
{
int vert_index;
UvElement *element_iter;
BMLoop *l;
l = element->l;
vert_index = BM_elem_index_get(l->v);
element_iter = state->element_map->vert[vert_index];
UvElement *element_iter = BM_uv_element_get_head(state->element_map, element);
for (; element_iter; element_iter = element_iter->next) {
if (element_iter->separate) {
if (stitch_check_uvs_stitchable(element, element_iter, ssc, state)) {
@ -847,16 +831,7 @@ static void stitch_validate_uv_stitchability(UvElement *element,
return;
}
UvElement *element_iter;
int vert_index;
BMLoop *l;
l = element->l;
vert_index = BM_elem_index_get(l->v);
element_iter = state->element_map->vert[vert_index];
UvElement *element_iter = BM_uv_element_get_head(state->element_map, element);
for (; element_iter; element_iter = element_iter->next) {
if (element_iter->separate) {
if (element_iter == element) {
@ -1273,7 +1248,6 @@ static int stitch_process_data(StitchStateContainer *ssc,
if (element->flag & STITCH_STITCHABLE) {
BMLoop *l;
MLoopUV *luv;
UvElement *element_iter;
l = element->l;
luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV);
@ -1287,8 +1261,7 @@ static int stitch_process_data(StitchStateContainer *ssc,
continue;
}
element_iter = state->element_map->vert[BM_elem_index_get(l->v)];
UvElement *element_iter = state->element_map->vertex[BM_elem_index_get(l->v)];
for (; element_iter; element_iter = element_iter->next) {
if (element_iter->separate) {
if (stitch_check_uvs_state_stitchable(element, element_iter, ssc, state)) {
@ -1585,13 +1558,8 @@ static void stitch_select_edge(UvEdge *edge, StitchState *state, int always_sele
/* Select all common uvs */
static void stitch_select_uv(UvElement *element, StitchState *state, int always_select)
{
BMLoop *l;
UvElement *element_iter;
UvElement **selection_stack = (UvElement **)state->selection_stack;
l = element->l;
element_iter = state->element_map->vert[BM_elem_index_get(l->v)];
UvElement *element_iter = BM_uv_element_get_head(state->element_map, element);
/* first deselect all common uvs */
for (; element_iter; element_iter = element_iter->next) {
if (element_iter->separate) {
@ -1934,7 +1902,7 @@ static StitchState *stitch_init(bContext *C,
int counter = -1;
/* initialize the unique UVs and map */
for (int i = 0; i < em->bm->totvert; i++) {
UvElement *element = state->element_map->vert[i];
UvElement *element = state->element_map->vertex[i];
for (; element; element = element->next) {
if (element->separate) {
counter++;