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:
parent
9b924b2a23
commit
bb8488c62c
|
@ -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 */
|
||||
|
|
|
@ -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?
|
||||
|
|
|
@ -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)];
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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++;
|
||||
|
|
Loading…
Reference in New Issue