[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(&region->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