Fix T99659: Improve UV Island calculation with hidden faces.
Simplify interface, regularize implementation and some light cleanup. See also: T79304 and D15419.
This commit is contained in:
parent
d0a552b5c6
commit
8f543a73ab
|
@ -69,8 +69,6 @@ typedef struct UvElementMap {
|
|||
int *islandIndices;
|
||||
} UvElementMap;
|
||||
|
||||
#define INVALID_ISLAND ((unsigned int)-1)
|
||||
|
||||
/* Connectivity data */
|
||||
typedef struct MeshElemMap {
|
||||
int *indices;
|
||||
|
|
|
@ -137,7 +137,6 @@ void EDBM_update_extern(struct Mesh *me, bool do_tessellation, bool is_destructi
|
|||
*/
|
||||
struct UvElementMap *BM_uv_element_map_create(struct BMesh *bm,
|
||||
const struct Scene *scene,
|
||||
bool face_selected,
|
||||
bool uv_selected,
|
||||
bool use_winding,
|
||||
bool do_islands);
|
||||
|
|
|
@ -593,13 +593,17 @@ UvMapVert *BM_uv_vert_map_at_index(UvVertMap *vmap, uint v)
|
|||
return vmap->vert[v];
|
||||
}
|
||||
|
||||
#define INVALID_ISLAND ((unsigned int)-1)
|
||||
|
||||
UvElementMap *BM_uv_element_map_create(BMesh *bm,
|
||||
const Scene *scene,
|
||||
const bool face_selected,
|
||||
const bool uv_selected,
|
||||
const bool use_winding,
|
||||
const bool do_islands)
|
||||
{
|
||||
/* In uv sync selection, all UVs are visible. */
|
||||
const bool face_selected = !(scene->toolsettings->uv_flag & UV_SYNC_SELECTION);
|
||||
|
||||
BMVert *ev;
|
||||
BMFace *efa;
|
||||
BMLoop *l;
|
||||
|
@ -623,15 +627,21 @@ UvElementMap *BM_uv_element_map_create(BMesh *bm,
|
|||
|
||||
/* generate UvElement array */
|
||||
BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
|
||||
if (!face_selected || BM_elem_flag_test(efa, BM_ELEM_SELECT)) {
|
||||
if (!uv_selected) {
|
||||
totuv += efa->len;
|
||||
}
|
||||
else {
|
||||
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
|
||||
if (uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) {
|
||||
totuv++;
|
||||
}
|
||||
if (BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (face_selected && !BM_elem_flag_test(efa, BM_ELEM_SELECT)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!uv_selected) {
|
||||
totuv += efa->len;
|
||||
}
|
||||
else {
|
||||
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
|
||||
if (uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) {
|
||||
totuv++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -649,46 +659,48 @@ UvElementMap *BM_uv_element_map_create(BMesh *bm,
|
|||
"UvElement");
|
||||
|
||||
if (use_winding) {
|
||||
winding = MEM_mallocN(sizeof(*winding) * totfaces, "winding");
|
||||
winding = MEM_callocN(sizeof(*winding) * totfaces, "winding");
|
||||
}
|
||||
|
||||
BM_ITER_MESH_INDEX (efa, &iter, bm, BM_FACES_OF_MESH, j) {
|
||||
|
||||
if (use_winding) {
|
||||
winding[j] = false;
|
||||
if (BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!face_selected || BM_elem_flag_test(efa, BM_ELEM_SELECT)) {
|
||||
float(*tf_uv)[2] = NULL;
|
||||
if (face_selected && !BM_elem_flag_test(efa, BM_ELEM_SELECT)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
float(*tf_uv)[2] = NULL;
|
||||
|
||||
if (use_winding) {
|
||||
tf_uv = (float(*)[2])BLI_buffer_reinit_data(&tf_uv_buf, vec2f, efa->len);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
if (use_winding) {
|
||||
tf_uv = (float(*)[2])BLI_buffer_reinit_data(&tf_uv_buf, vec2f, efa->len);
|
||||
luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
|
||||
copy_v2_v2(tf_uv[i], luv->uv);
|
||||
}
|
||||
|
||||
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++;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
if (use_winding) {
|
||||
luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
|
||||
copy_v2_v2(tf_uv[i], luv->uv);
|
||||
}
|
||||
|
||||
buf++;
|
||||
}
|
||||
|
||||
if (use_winding) {
|
||||
winding[j] = cross_poly_v2(tf_uv, efa->len) > 0;
|
||||
}
|
||||
if (winding) {
|
||||
winding[j] = cross_poly_v2(tf_uv, efa->len) > 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -500,20 +500,10 @@ static UvSculptData *uv_sculpt_stroke_init(bContext *C, wmOperator *op, const wm
|
|||
|
||||
if (do_island_optimization) {
|
||||
/* We will need island information */
|
||||
if (ts->uv_flag & UV_SYNC_SELECTION) {
|
||||
data->elementMap = BM_uv_element_map_create(bm, scene, false, false, true, true);
|
||||
}
|
||||
else {
|
||||
data->elementMap = BM_uv_element_map_create(bm, scene, true, false, true, true);
|
||||
}
|
||||
data->elementMap = BM_uv_element_map_create(bm, scene, false, true, true);
|
||||
}
|
||||
else {
|
||||
if (ts->uv_flag & UV_SYNC_SELECTION) {
|
||||
data->elementMap = BM_uv_element_map_create(bm, scene, false, false, true, false);
|
||||
}
|
||||
else {
|
||||
data->elementMap = BM_uv_element_map_create(bm, scene, true, false, true, false);
|
||||
}
|
||||
data->elementMap = BM_uv_element_map_create(bm, scene, false, true, false);
|
||||
}
|
||||
|
||||
if (!data->elementMap) {
|
||||
|
|
|
@ -238,7 +238,6 @@ void createTransUVs(bContext *C, TransInfo *t)
|
|||
{
|
||||
SpaceImage *sima = CTX_wm_space_image(C);
|
||||
Scene *scene = t->scene;
|
||||
ToolSettings *ts = CTX_data_tool_settings(C);
|
||||
|
||||
const bool is_prop_edit = (t->flag & T_PROP_EDIT) != 0;
|
||||
const bool is_prop_connected = (t->flag & T_PROP_CONNECTED) != 0;
|
||||
|
@ -266,8 +265,7 @@ void createTransUVs(bContext *C, TransInfo *t)
|
|||
/* count */
|
||||
if (is_island_center) {
|
||||
/* create element map with island information */
|
||||
const bool use_facesel = (ts->uv_flag & UV_SYNC_SELECTION) == 0;
|
||||
elementmap = BM_uv_element_map_create(em->bm, scene, use_facesel, true, false, true);
|
||||
elementmap = BM_uv_element_map_create(em->bm, scene, true, false, true);
|
||||
if (elementmap == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -544,7 +544,7 @@ static bool uvedit_uv_straighten(Scene *scene, BMesh *bm, eUVWeldAlign tool)
|
|||
return false;
|
||||
}
|
||||
|
||||
UvElementMap *element_map = BM_uv_element_map_create(bm, scene, false, true, false, true);
|
||||
UvElementMap *element_map = BM_uv_element_map_create(bm, scene, true, false, true);
|
||||
if (element_map == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -5223,7 +5223,7 @@ static void uv_isolate_selected_islands(const Scene *scene,
|
|||
BLI_assert((scene->toolsettings->uv_flag & UV_SYNC_SELECTION) == 0);
|
||||
BMFace *efa;
|
||||
BMIter iter, liter;
|
||||
UvElementMap *elementmap = BM_uv_element_map_create(em->bm, scene, true, false, false, true);
|
||||
UvElementMap *elementmap = BM_uv_element_map_create(em->bm, scene, false, false, true);
|
||||
if (elementmap == NULL) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -1902,15 +1902,7 @@ static StitchState *stitch_init(bContext *C,
|
|||
* for stitch this isn't useful behavior, see T86924. */
|
||||
const int selectmode_orig = scene->toolsettings->selectmode;
|
||||
scene->toolsettings->selectmode = SCE_SELECT_VERTEX;
|
||||
|
||||
/* in uv synch selection, all uv's are visible */
|
||||
if (ts->uv_flag & UV_SYNC_SELECTION) {
|
||||
state->element_map = BM_uv_element_map_create(state->em->bm, scene, false, false, true, true);
|
||||
}
|
||||
else {
|
||||
state->element_map = BM_uv_element_map_create(state->em->bm, scene, true, false, true, true);
|
||||
}
|
||||
|
||||
state->element_map = BM_uv_element_map_create(state->em->bm, scene, false, true, true);
|
||||
scene->toolsettings->selectmode = selectmode_orig;
|
||||
|
||||
if (!state->element_map) {
|
||||
|
|
Loading…
Reference in New Issue