[Bf-blender-cvs] [035fa7985d2] soc-2021-uv-editor-improvements-edge-selection: UV: Edge selection support - Initial
Siddhartha Jejurkar
noreply at git.blender.org
Thu Aug 5 13:08:35 CEST 2021
Commit: 035fa7985d270fae197dfd155c7937b24e16e244
Author: Siddhartha Jejurkar
Date: Mon Jul 26 09:22:32 2021 +0530
Branches: soc-2021-uv-editor-improvements-edge-selection
https://developer.blender.org/rB035fa7985d270fae197dfd155c7937b24e16e244
UV: Edge selection support - Initial
* Add UV edge selection flag - MLOOPUV_EDGESEL
* Refactor existing UV element selection functions to use the edge
selection flag wherever required
* Refactor existing UV element check functions to ensure proper
selection states using the edge selection flag
* Refactor UV select all operator to use edge selection flag
* New functions for selecting vertices or edges that share the same
location, either on 3D mesh or in UV space.
* Add small penalty for finding the nearest UV edge. Ensures that UV edge
selection will select other edges sharing the same location in
successive selection attempts.
* Expose UV edge selection flag as boolean in Python
Differential Revision: https://developer.blender.org/D12028
===================================================================
M source/blender/editors/include/ED_uvedit.h
M source/blender/editors/uvedit/uvedit_intern.h
M source/blender/editors/uvedit/uvedit_path.c
M source/blender/editors/uvedit/uvedit_select.c
M source/blender/editors/uvedit/uvedit_smart_stitch.c
M source/blender/makesdna/DNA_meshdata_types.h
M source/blender/makesrna/intern/rna_mesh.c
M source/blender/python/bmesh/bmesh_py_types_meshdata.c
===================================================================
diff --git a/source/blender/editors/include/ED_uvedit.h b/source/blender/editors/include/ED_uvedit.h
index ea3d921f2c5..157fc450e70 100644
--- a/source/blender/editors/include/ED_uvedit.h
+++ b/source/blender/editors/include/ED_uvedit.h
@@ -145,6 +145,13 @@ void uvedit_edge_select_set_with_sticky(const struct SpaceImage *sima,
const bool select,
const bool do_history,
const uint cd_loop_uv_offset);
+void uvedit_edge_select_shared_location(const struct Scene *scene,
+ struct BMEditMesh *em,
+ struct BMLoop *l,
+ const bool select,
+ const bool use_mesh_location,
+ const bool do_history,
+ const uint cd_loop_uv_offset);
void uvedit_edge_select_set(const struct Scene *scene,
struct BMEditMesh *em,
struct BMLoop *l,
@@ -168,6 +175,13 @@ void uvedit_uv_select_set_with_sticky(const struct SpaceImage *sima,
const bool select,
const bool do_history,
const uint cd_loop_uv_offset);
+void uvedit_uv_select_shared_location(const struct Scene *scene,
+ struct BMEditMesh *em,
+ struct BMLoop *l,
+ const bool select,
+ const bool use_mesh_location,
+ const bool do_history,
+ const uint cd_loop_uv_offset);
void uvedit_uv_select_set(const struct Scene *scene,
struct BMEditMesh *em,
struct BMLoop *l,
diff --git a/source/blender/editors/uvedit/uvedit_intern.h b/source/blender/editors/uvedit/uvedit_intern.h
index cd8fbd00316..ea72b859f7c 100644
--- a/source/blender/editors/uvedit/uvedit_intern.h
+++ b/source/blender/editors/uvedit/uvedit_intern.h
@@ -86,11 +86,13 @@ bool uv_find_nearest_vert_multi(struct Scene *scene,
bool uv_find_nearest_edge(struct Scene *scene,
struct Object *obedit,
const float co[2],
+ const float penalty,
struct UvNearestHit *hit);
bool uv_find_nearest_edge_multi(struct Scene *scene,
struct Object **objects,
const uint objects_len,
const float co[2],
+ const float penalty,
struct UvNearestHit *hit);
bool uv_find_nearest_face_ex(struct Scene *scene,
diff --git a/source/blender/editors/uvedit/uvedit_path.c b/source/blender/editors/uvedit/uvedit_path.c
index 2613c5b23a0..1f3ba206103 100644
--- a/source/blender/editors/uvedit/uvedit_path.c
+++ b/source/blender/editors/uvedit/uvedit_path.c
@@ -627,7 +627,7 @@ static int uv_shortest_path_pick_invoke(bContext *C, wmOperator *op, const wmEve
else if (uv_selectmode & UV_SELECT_EDGE) {
UvNearestHit hit = UV_NEAREST_HIT_INIT_MAX(®ion->v2d);
- if (!uv_find_nearest_edge(scene, obedit, co, &hit)) {
+ if (!uv_find_nearest_edge(scene, obedit, co, 0.0f, &hit)) {
return OPERATOR_CANCELLED;
}
diff --git a/source/blender/editors/uvedit/uvedit_select.c b/source/blender/editors/uvedit/uvedit_select.c
index 4c597d80534..aac9b8a419d 100644
--- a/source/blender/editors/uvedit/uvedit_select.c
+++ b/source/blender/editors/uvedit/uvedit_select.c
@@ -246,6 +246,9 @@ bool uvedit_face_select_test_ex(const ToolSettings *ts, BMFace *efa, const int c
if (!(luv->flag & MLOOPUV_VERTSEL)) {
return false;
}
+ if (!(luv->flag & MLOOPUV_EDGESEL)) {
+ return false;
+ }
}
return true;
}
@@ -268,12 +271,33 @@ void uvedit_face_select_set_with_sticky(const SpaceImage *sima,
return;
}
- BMLoop *l_iter, *l_first;
- l_iter = l_first = BM_FACE_FIRST_LOOP(efa);
- do {
- uvedit_uv_select_set_with_sticky(
- sima, scene, em, l_iter, select, do_history, cd_loop_uv_offset);
- } while ((l_iter = l_iter->next) != l_first);
+ const int sticky = sima->sticky;
+ switch (sticky) {
+ case SI_STICKY_DISABLE: {
+ if (uvedit_face_visible_test(scene, efa)) {
+ uvedit_face_select_set(scene, em, efa, select, do_history, cd_loop_uv_offset);
+ }
+ break;
+ }
+ case SI_STICKY_LOC:
+ case SI_STICKY_VERTEX:
+ default: {
+ /* Sticky location and vertex modes. */
+ /* Fallback, in case sima->sticky is invalid */
+ BMLoop *l_iter, *l_first;
+ l_iter = l_first = BM_FACE_FIRST_LOOP(efa);
+ do {
+ uvedit_edge_select_shared_location(
+ scene, em, l_iter, select, false, do_history, cd_loop_uv_offset);
+
+ uvedit_uv_select_shared_location(
+ scene, em, l_iter, select, false, do_history, cd_loop_uv_offset);
+ uvedit_uv_select_shared_location(
+ scene, em, l_iter->next, select, false, do_history, cd_loop_uv_offset);
+ } while ((l_iter = l_iter->next) != l_first);
+ break;
+ }
+ }
}
void uvedit_face_select_set(const struct Scene *scene,
@@ -313,6 +337,7 @@ void uvedit_face_select_enable(const Scene *scene,
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
luv->flag |= MLOOPUV_VERTSEL;
+ luv->flag |= MLOOPUV_EDGESEL;
}
}
}
@@ -335,6 +360,7 @@ void uvedit_face_select_disable(const Scene *scene,
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
luv->flag &= ~MLOOPUV_VERTSEL;
+ luv->flag &= ~MLOOPUV_EDGESEL;
}
}
}
@@ -357,7 +383,12 @@ bool uvedit_edge_select_test_ex(const ToolSettings *ts, BMLoop *l, const int cd_
luv1 = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
luv2 = BM_ELEM_CD_GET_VOID_P(l->next, cd_loop_uv_offset);
- return (luv1->flag & MLOOPUV_VERTSEL) && (luv2->flag & MLOOPUV_VERTSEL);
+ /* UV edge is selected only if :
+ * - first UV vertex in luv1 is selected
+ * - second UV vertex in luv2 is selected
+ * - MLOOPUV_EDGESEL flag is set for luv1 */
+ return (luv1->flag & MLOOPUV_VERTSEL) && (luv2->flag & MLOOPUV_VERTSEL) &&
+ (luv1->flag & MLOOPUV_EDGESEL);
}
bool uvedit_edge_select_test(const Scene *scene, BMLoop *l, const int cd_loop_uv_offset)
{
@@ -378,9 +409,86 @@ void uvedit_edge_select_set_with_sticky(const struct SpaceImage *sima,
return;
}
- uvedit_uv_select_set_with_sticky(sima, scene, em, l, select, do_history, cd_loop_uv_offset);
- uvedit_uv_select_set_with_sticky(
- sima, scene, em, l->next, select, do_history, cd_loop_uv_offset);
+ const int sticky = sima->sticky;
+ switch (sticky) {
+ case SI_STICKY_DISABLE: {
+ if (uvedit_face_visible_test(scene, l->f)) {
+ uvedit_edge_select_set(scene, em, l, select, do_history, cd_loop_uv_offset);
+ }
+ break;
+ }
+ case SI_STICKY_VERTEX: {
+ BMLoop *l_radial_iter = l;
+ do {
+ if (uvedit_face_visible_test(scene, l_radial_iter->f)) {
+ uvedit_edge_select_set(scene, em, l_radial_iter, select, do_history, cd_loop_uv_offset);
+
+ uvedit_uv_select_shared_location(
+ scene, em, l_radial_iter, select, false, do_history, cd_loop_uv_offset);
+ uvedit_uv_select_shared_location(
+ scene, em, l_radial_iter->next, select, false, do_history, cd_loop_uv_offset);
+ }
+
+ } while ((l_radial_iter = l_radial_iter->radial_next) != l);
+ break;
+ }
+ default: {
+ /* SI_STICKY_LOC
+ * Fallback to SI_STICKY_LOC, in case sima->sticky is invalid */
+ uvedit_edge_select_shared_location(
+ scene, em, l, select, false, do_history, cd_loop_uv_offset);
+
+ /* NOTE: This is a case where we deviate from the logic of: "EDGE SELECTION MODE SHOULD
+ * IMPLY ONLY EDGES MUST BE SELECTED".
+ * The UV vertex selections done below are to avoid the cases of edge selections breaking
+ * away (/become separate entities) from the vertices/edges they were connected to */
+ uvedit_uv_select_shared_location(scene, em, l, select, false, do_history, cd_loop_uv_offset);
+ uvedit_uv_select_shared_location(
+ scene, em, l->next, select, false, do_history, cd_loop_uv_offset);
+
+ break;
+ }
+ }
+}
+
+/* Selects UV edges sharing the same location as l->e
+ *
+ * If use_mesh_location is :
+ * - true :- selects all UV edges sharing the same location on the 3D mesh
+ * - false :- selects all UV edges sharing the same location in UV space */
+void uvedit_edge_select_shared_location(const Scene *scene,
+ BMEditMesh *em,
+ BMLoop *l,
+ const bool select,
+ const bool use_mesh_location,
+ const bool do_history,
+ const uint cd_loop_uv_offset)
+{
+ const MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
+ BMLoop *l_radial_iter = l;
+ do {
+ if (uvedit_face_visible_test(scene, l_radial_iter->f)) {
+
+ if (use_mesh_location) {
+ uvedit_edge_select_set(scene, em, l_radial_iter, select, do_history, cd_loop_uv_offset);
+ }
+ else {
+ const MLoopUV *luv_other, *luv_next, *luv_other_next;
+ luv_other = BM_ELEM_CD_GET_VOID_P(l_radial_iter, cd_loop_uv_offset);
+ luv_next = BM_ELEM_CD_GET_VOID_P(l->next, cd_loop_uv_offset);
+ luv_other_next = BM_ELEM_CD_GET_VOID_P(l_radial_iter->next, cd_loop_uv_offset);
+ /* Check the current and next loop to account for the possibilty of opposite directions
+ * of a loop in a particular edge's radial cycle */
+ if (equals_v2v2(luv->uv, luv_oth
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list