UV: cleanup winding

Simplify `BM_uv_element_map_create` by using `BM_face_calc_area_uv_signed`.

Remove unused UV winding code in `BM_uv_vert_map_create`.

Fixes unlikely memory leak in `BKE_mesh_uv_vert_map_create`.

No functional changes.

Differential Revision: https://developer.blender.org/D17137
This commit is contained in:
Chris Blackbourn 2023-01-28 10:50:59 +13:00
parent 8336de03a6
commit cef03c867b
4 changed files with 13 additions and 58 deletions

View File

@ -47,7 +47,6 @@ UvVertMap *BKE_mesh_uv_vert_map_create(const MPoly *mpoly,
uint a;
int i, totuv, nverts;
bool *winding = nullptr;
BLI_buffer_declare_static(vec2f, tf_uv_buf, BLI_BUFFER_NOP, 32);
totuv = 0;
@ -67,15 +66,17 @@ UvVertMap *BKE_mesh_uv_vert_map_create(const MPoly *mpoly,
vmap = (UvVertMap *)MEM_callocN(sizeof(*vmap), "UvVertMap");
buf = vmap->buf = (UvMapVert *)MEM_callocN(sizeof(*vmap->buf) * size_t(totuv), "UvMapVert");
vmap->vert = (UvMapVert **)MEM_callocN(sizeof(*vmap->vert) * totvert, "UvMapVert*");
if (use_winding) {
winding = static_cast<bool *>(MEM_callocN(sizeof(*winding) * totpoly, "winding"));
}
if (!vmap->vert || !vmap->buf) {
BKE_mesh_uv_vert_map_free(vmap);
return nullptr;
}
bool *winding = nullptr;
if (use_winding) {
winding = static_cast<bool *>(MEM_callocN(sizeof(*winding) * totpoly, "winding"));
}
mp = mpoly;
for (a = 0; a < totpoly; a++, mp++) {
if (!selected || (!(hide_poly && hide_poly[a]) && (select_poly && select_poly[a]))) {

View File

@ -167,7 +167,7 @@ struct UvMapVert *BM_uv_vert_map_at_index(struct UvVertMap *vmap, unsigned int v
/**
* Return a new #UvVertMap from the edit-mesh.
*/
struct UvVertMap *BM_uv_vert_map_create(struct BMesh *bm, bool use_select, bool use_winding);
struct UvVertMap *BM_uv_vert_map_create(struct BMesh *bm, bool use_select);
void EDBM_flag_enable_all(struct BMEditMesh *em, char hflag);
void EDBM_flag_disable_all(struct BMEditMesh *em, char hflag);

View File

@ -444,7 +444,7 @@ void EDBM_flag_enable_all(BMEditMesh *em, const char hflag)
/** \name UV Vertex Map API
* \{ */
UvVertMap *BM_uv_vert_map_create(BMesh *bm, const bool use_select, const bool use_winding)
UvVertMap *BM_uv_vert_map_create(BMesh *bm, const bool use_select)
{
BMVert *ev;
BMFace *efa;
@ -452,7 +452,6 @@ UvVertMap *BM_uv_vert_map_create(BMesh *bm, const bool use_select, const bool us
BMIter iter, liter;
uint a;
const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_PROP_FLOAT2);
BLI_buffer_declare_static(vec2f, tf_uv_buf, BLI_BUFFER_NOP, BM_DEFAULT_NGON_STACK_SIZE);
BM_mesh_elem_index_ensure(bm, BM_VERT | BM_FACE);
@ -478,11 +477,6 @@ UvVertMap *BM_uv_vert_map_create(BMesh *bm, const bool use_select, const bool us
vmap->vert = (UvMapVert **)MEM_callocN(sizeof(*vmap->vert) * totverts, "UvMapVert_pt");
UvMapVert *buf = vmap->buf = (UvMapVert *)MEM_callocN(sizeof(*vmap->buf) * totuv, "UvMapVert");
bool *winding = NULL;
if (use_winding) {
winding = MEM_callocN(sizeof(*winding) * totfaces, "winding");
}
if (!vmap->vert || !vmap->buf) {
BKE_mesh_uv_vert_map_free(vmap);
return NULL;
@ -490,12 +484,6 @@ UvVertMap *BM_uv_vert_map_create(BMesh *bm, const bool use_select, const bool us
BM_ITER_MESH_INDEX (efa, &iter, bm, BM_FACES_OF_MESH, a) {
if ((use_select == false) || BM_elem_flag_test(efa, BM_ELEM_SELECT)) {
float(*tf_uv)[2] = NULL;
if (use_winding) {
tf_uv = (float(*)[2])BLI_buffer_reinit_data(&tf_uv_buf, vec2f, efa->len);
}
int i;
BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) {
buf->loop_of_poly_index = i;
@ -505,15 +493,6 @@ UvVertMap *BM_uv_vert_map_create(BMesh *bm, const bool use_select, const bool us
buf->next = vmap->vert[BM_elem_index_get(l->v)];
vmap->vert[BM_elem_index_get(l->v)] = buf;
buf++;
if (use_winding) {
const float(*luv)[2] = BM_ELEM_CD_GET_FLOAT2_P(l, cd_loop_uv_offset);
copy_v2_v2(tf_uv[i], *luv);
}
}
if (use_winding) {
winding[a] = cross_poly_v2(tf_uv, efa->len) > 0;
}
}
}
@ -544,8 +523,7 @@ UvVertMap *BM_uv_vert_map_create(BMesh *bm, const bool use_select, const bool us
l = BM_iter_at_index(bm, BM_LOOPS_OF_FACE, efa, iterv->loop_of_poly_index);
uv2 = BM_ELEM_CD_GET_FLOAT_P(l, cd_loop_uv_offset);
if (compare_v2v2(uv2, uv, STD_UV_CONNECT_LIMIT) &&
(!use_winding || winding[iterv->poly_index] == winding[v->poly_index])) {
if (compare_v2v2(uv2, uv, STD_UV_CONNECT_LIMIT)) {
if (lastv) {
lastv->next = next;
}
@ -568,12 +546,6 @@ UvVertMap *BM_uv_vert_map_create(BMesh *bm, const bool use_select, const bool us
vmap->vert[a] = newvlist;
}
if (use_winding) {
MEM_freeN(winding);
}
BLI_buffer_free(&tf_uv_buf);
return vmap;
}
@ -1007,7 +979,6 @@ UvElementMap *BM_uv_element_map_create(BMesh *bm,
BMVert *ev;
BMFace *efa;
BMIter iter, liter;
BLI_buffer_declare_static(vec2f, tf_uv_buf, BLI_BUFFER_NOP, BM_DEFAULT_NGON_STACK_SIZE);
const BMUVOffsets offsets = BM_uv_map_get_offsets(bm);
if (offsets.uv < 0) {
@ -1065,12 +1036,6 @@ UvElementMap *BM_uv_element_map_create(BMesh *bm,
continue;
}
float(*tf_uv)[2] = NULL;
if (use_winding) {
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) {
@ -1086,19 +1051,13 @@ UvElementMap *BM_uv_element_map_create(BMesh *bm,
buf->next = element_map->vertex[BM_elem_index_get(l->v)];
element_map->vertex[BM_elem_index_get(l->v)] = buf;
if (use_winding) {
const float *uv = BM_ELEM_CD_GET_FLOAT_P(l, offsets.uv);
copy_v2_v2(tf_uv[i], uv);
}
buf++;
}
if (winding) {
winding[j] = cross_poly_v2(tf_uv, efa->len) > 0;
winding[j] = BM_face_calc_area_uv_signed(efa, offsets.uv) > 0;
}
}
BLI_buffer_free(&tf_uv_buf);
GSet *seam_visited_gset = use_seams ? BLI_gset_ptr_new(__func__) : NULL;

View File

@ -1786,7 +1786,6 @@ static void uv_select_linked_multi(Scene *scene,
BMFace *efa;
BMLoop *l;
BMIter iter, liter;
UvVertMap *vmap;
UvMapVert *vlist, *iterv, *startv;
int i, stacksize = 0, *stack;
uint a;
@ -1807,8 +1806,7 @@ static void uv_select_linked_multi(Scene *scene,
*
* Better solve this by having a delimit option for select-linked operator,
* keeping island-select working as is. */
vmap = BM_uv_vert_map_create(em->bm, !uv_sync_select, false);
UvVertMap *vmap = BM_uv_vert_map_create(em->bm, !uv_sync_select);
if (vmap == NULL) {
continue;
}
@ -3304,11 +3302,10 @@ static void uv_select_flush_from_tag_face(const Scene *scene, Object *obedit, co
if ((ts->uv_flag & UV_SYNC_SELECTION) == 0 &&
ELEM(ts->uv_sticky, SI_STICKY_VERTEX, SI_STICKY_LOC)) {
struct UvVertMap *vmap;
uint efa_index;
BM_mesh_elem_table_ensure(em->bm, BM_FACE);
vmap = BM_uv_vert_map_create(em->bm, false, false);
struct UvVertMap *vmap = BM_uv_vert_map_create(em->bm, false);
if (vmap == NULL) {
return;
}
@ -3394,11 +3391,10 @@ static void uv_select_flush_from_tag_loop(const Scene *scene, Object *obedit, co
}
}
else if ((ts->uv_flag & UV_SYNC_SELECTION) == 0 && ts->uv_sticky == SI_STICKY_LOC) {
struct UvVertMap *vmap;
uint efa_index;
BM_mesh_elem_table_ensure(em->bm, BM_FACE);
vmap = BM_uv_vert_map_create(em->bm, false, false);
struct UvVertMap *vmap = BM_uv_vert_map_create(em->bm, false);
if (vmap == NULL) {
return;
}
@ -3449,13 +3445,12 @@ static void uv_select_flush_from_loop_edge_flag(const Scene *scene, BMEditMesh *
if ((ts->uv_flag & UV_SYNC_SELECTION) == 0 &&
ELEM(ts->uv_sticky, SI_STICKY_LOC, SI_STICKY_VERTEX)) {
/* Use UV edge selection to identify which verts must to be selected */
struct UvVertMap *vmap;
uint efa_index;
/* Clear UV vert flags */
bm_clear_uv_vert_selection(scene, em->bm, offsets);
BM_mesh_elem_table_ensure(em->bm, BM_FACE);
vmap = BM_uv_vert_map_create(em->bm, false, false);
struct UvVertMap *vmap = BM_uv_vert_map_create(em->bm, false);
if (vmap == NULL) {
return;
}