Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2020-08-01 04:34:42 +0300
committerCampbell Barton <ideasman42@gmail.com>2020-08-01 05:15:05 +0300
commit72b422c1e101dce18ddff5a4221665a80e58d78d (patch)
tree53ff24cdfa1507790e4f573e10990dcc9d36c786 /source/blender
parent732434cb1faa70e8d7ba4a4fda6e76d5f1ce6255 (diff)
UV: support select linked with sync-select in vert/edge modes
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/editors/uvedit/uvedit_select.c81
1 files changed, 55 insertions, 26 deletions
diff --git a/source/blender/editors/uvedit/uvedit_select.c b/source/blender/editors/uvedit/uvedit_select.c
index aff891c4023..151c881a466 100644
--- a/source/blender/editors/uvedit/uvedit_select.c
+++ b/source/blender/editors/uvedit/uvedit_select.c
@@ -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");