|
|
|
@ -1263,11 +1263,13 @@ static void uv_select_linked_multi(Scene *scene,
|
|
|
|
|
Object **objects,
|
|
|
|
|
const uint objects_len,
|
|
|
|
|
UvNearestHit *hit_final,
|
|
|
|
|
bool extend,
|
|
|
|
|
const bool extend,
|
|
|
|
|
bool deselect,
|
|
|
|
|
bool toggle,
|
|
|
|
|
bool select_faces)
|
|
|
|
|
const bool toggle,
|
|
|
|
|
const bool select_faces)
|
|
|
|
|
{
|
|
|
|
|
const bool uv_sync_select = (scene->toolsettings->uv_flag & UV_SYNC_SELECTION);
|
|
|
|
|
|
|
|
|
|
/* loop over objects, or just use hit_final->ob */
|
|
|
|
|
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
|
|
|
|
|
if (hit_final && ob_index != 0) {
|
|
|
|
@ -1278,7 +1280,6 @@ static void uv_select_linked_multi(Scene *scene,
|
|
|
|
|
BMFace *efa;
|
|
|
|
|
BMLoop *l;
|
|
|
|
|
BMIter iter, liter;
|
|
|
|
|
MLoopUV *luv;
|
|
|
|
|
UvVertMap *vmap;
|
|
|
|
|
UvMapVert *vlist, *iterv, *startv;
|
|
|
|
|
int i, stacksize = 0, *stack;
|
|
|
|
@ -1296,7 +1297,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, !select_faces, false);
|
|
|
|
|
vmap = BM_uv_vert_map_create(em->bm, !uv_sync_select, false);
|
|
|
|
|
|
|
|
|
|
if (vmap == NULL) {
|
|
|
|
|
continue;
|
|
|
|
@ -1318,14 +1319,42 @@ static void uv_select_linked_multi(Scene *scene,
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
|
|
|
|
|
luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
|
|
|
|
|
|
|
|
|
|
if (luv->flag & MLOOPUV_VERTSEL) {
|
|
|
|
|
stack[stacksize] = a;
|
|
|
|
|
stacksize++;
|
|
|
|
|
flag[a] = 1;
|
|
|
|
|
if (uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) {
|
|
|
|
|
bool add_to_stack = true;
|
|
|
|
|
if (uv_sync_select && !select_faces) {
|
|
|
|
|
/* Special case, vertex/edge & sync select being enabled.
|
|
|
|
|
*
|
|
|
|
|
* Without this, a second linked select will 'grow' each time as each new
|
|
|
|
|
* selection reaches the boundaries of islands that share vertices but not UV's.
|
|
|
|
|
*
|
|
|
|
|
* Rules applied here:
|
|
|
|
|
* - This loops face isn't selected.
|
|
|
|
|
* - The only other fully selected face is connected or,
|
|
|
|
|
* - There are no connected fully selected faces UV-connected to this loop.
|
|
|
|
|
*/
|
|
|
|
|
if (uvedit_face_select_test(scene, l->f, cd_loop_uv_offset)) {
|
|
|
|
|
/* pass */
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
BMIter liter_other;
|
|
|
|
|
BMLoop *l_other;
|
|
|
|
|
BM_ITER_ELEM (l_other, &liter_other, l->v, BM_LOOPS_OF_VERT) {
|
|
|
|
|
if ((l != l_other) &&
|
|
|
|
|
!BM_loop_uv_share_vert_check(l, l_other, cd_loop_uv_offset) &&
|
|
|
|
|
uvedit_face_select_test(scene, l_other->f, cd_loop_uv_offset)) {
|
|
|
|
|
add_to_stack = false;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
if (add_to_stack) {
|
|
|
|
|
stack[stacksize] = a;
|
|
|
|
|
stacksize++;
|
|
|
|
|
flag[a] = 1;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -1394,10 +1423,9 @@ static void uv_select_linked_multi(Scene *scene,
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
|
|
|
|
|
luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
|
|
|
|
|
|
|
|
|
|
if (luv->flag & MLOOPUV_VERTSEL) {
|
|
|
|
|
if (uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) {
|
|
|
|
|
found_selected = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -1414,10 +1442,7 @@ static void uv_select_linked_multi(Scene *scene,
|
|
|
|
|
BM_face_select_set(em->bm, efa, value); \
|
|
|
|
|
} \
|
|
|
|
|
else { \
|
|
|
|
|
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { \
|
|
|
|
|
luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); \
|
|
|
|
|
luv->flag = (value) ? (luv->flag | MLOOPUV_VERTSEL) : (luv->flag & ~MLOOPUV_VERTSEL); \
|
|
|
|
|
} \
|
|
|
|
|
uvedit_face_select_set(scene, em, efa, value, false, cd_loop_uv_offset); \
|
|
|
|
|
} \
|
|
|
|
|
(void)0
|
|
|
|
|
|
|
|
|
@ -1442,6 +1467,17 @@ static void uv_select_linked_multi(Scene *scene,
|
|
|
|
|
MEM_freeN(stack);
|
|
|
|
|
MEM_freeN(flag);
|
|
|
|
|
BM_uv_vert_map_free(vmap);
|
|
|
|
|
|
|
|
|
|
if (uv_sync_select) {
|
|
|
|
|
if (deselect) {
|
|
|
|
|
EDBM_deselect_flush(em);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
if (!select_faces) {
|
|
|
|
|
EDBM_selectmode_flush(em);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -2263,13 +2299,6 @@ static int uv_select_linked_internal(bContext *C, wmOperator *op, const wmEvent
|
|
|
|
|
|
|
|
|
|
UvNearestHit hit = UV_NEAREST_HIT_INIT;
|
|
|
|
|
|
|
|
|
|
if ((ts->uv_flag & UV_SYNC_SELECTION) && !(ts->selectmode & SCE_SELECT_FACE)) {
|
|
|
|
|
BKE_report(op->reports,
|
|
|
|
|
RPT_ERROR,
|
|
|
|
|
"Select linked only works in face select mode when sync selection is enabled");
|
|
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (pick) {
|
|
|
|
|
extend = RNA_boolean_get(op->ptr, "extend");
|
|
|
|
|
deselect = RNA_boolean_get(op->ptr, "deselect");
|
|
|
|
|