[Bf-blender-cvs] [69ec7ab873f] blender-v2.90-release: UV: path select support with sync-select enabled

Campbell Barton noreply at git.blender.org
Thu Jul 30 04:07:40 CEST 2020


Commit: 69ec7ab873f3e75d46077f303396b194c728479e
Author: Campbell Barton
Date:   Thu Jul 30 11:02:46 2020 +1000
Branches: blender-v2.90-release
https://developer.blender.org/rB69ec7ab873f3e75d46077f303396b194c728479e

UV: path select support with sync-select enabled

Also improve region fill with edge-select enabled which often failed
to include both vertices from each edge in the resulting region.

===================================================================

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

===================================================================

diff --git a/source/blender/editors/include/ED_uvedit.h b/source/blender/editors/include/ED_uvedit.h
index c89a9fe0e99..935b99ba8e8 100644
--- a/source/blender/editors/include/ED_uvedit.h
+++ b/source/blender/editors/include/ED_uvedit.h
@@ -217,6 +217,9 @@ struct BMLoop *ED_uvedit_active_vert_loop_get(struct BMesh *bm);
 void ED_uvedit_active_edge_loop_set(struct BMesh *bm, struct BMLoop *l);
 struct BMLoop *ED_uvedit_active_edge_loop_get(struct BMesh *bm);
 
+char ED_uvedit_select_mode_get(const Scene *scene);
+void ED_uvedit_select_sync_flush(const ToolSettings *ts, struct BMEditMesh *em, const bool select);
+
 /* uvedit_unwrap_ops.c */
 void ED_uvedit_live_unwrap_begin(struct Scene *scene, struct Object *obedit);
 void ED_uvedit_live_unwrap_re_solve(void);
diff --git a/source/blender/editors/uvedit/uvedit_intern.h b/source/blender/editors/uvedit/uvedit_intern.h
index d5e7dd08fd1..abbb0aa330c 100644
--- a/source/blender/editors/uvedit/uvedit_intern.h
+++ b/source/blender/editors/uvedit/uvedit_intern.h
@@ -88,6 +88,15 @@ bool uv_find_nearest_face_multi(struct Scene *scene,
                                 const float co[2],
                                 struct UvNearestHit *hit_final);
 
+BMLoop *uv_find_nearest_loop_from_vert(struct Scene *scene,
+                                       struct Object *obedit,
+                                       struct BMVert *v,
+                                       const float co[2]);
+BMLoop *uv_find_nearest_loop_from_edge(struct Scene *scene,
+                                       struct Object *obedit,
+                                       struct BMEdge *e,
+                                       const float co[2]);
+
 /* utility tool functions */
 
 void uvedit_live_unwrap_update(struct SpaceImage *sima,
diff --git a/source/blender/editors/uvedit/uvedit_path.c b/source/blender/editors/uvedit/uvedit_path.c
index 1c7da7af0f4..546aad078aa 100644
--- a/source/blender/editors/uvedit/uvedit_path.c
+++ b/source/blender/editors/uvedit/uvedit_path.c
@@ -69,9 +69,6 @@
 
 #include "bmesh_tools.h"
 
-/* TODO(campbell): region filling, matching mesh selection. */
-#define USE_FILL
-
 /* -------------------------------------------------------------------- */
 /** \name Local Utilities
  * \{ */
@@ -84,8 +81,12 @@
  *
  * While the code below is a bit awkward, it's significantly less overhead than
  * adding full edge selection which is nearly the same as vertex path in the case of UV's.
+ *
+ * \param use_nearest: When false use the post distant pair of loops,
+ * use when filling a region as we want both verts from each edge to be included in the region.
  */
-static void bm_loop_calc_vert_pair_from_edge_pair(const int cd_loop_uv_offset,
+static void bm_loop_calc_vert_pair_from_edge_pair(const bool use_nearest,
+                                                  const int cd_loop_uv_offset,
                                                   const float aspect_y,
                                                   BMElem **ele_src_p,
                                                   BMElem **ele_dst_p,
@@ -116,8 +117,15 @@ static void bm_loop_calc_vert_pair_from_edge_pair(const int cd_loop_uv_offset,
   };
   int i_best = 0;
   for (int i = 1; i < ARRAY_SIZE(tests); i++) {
-    if (tests[i].len_sq < tests[i_best].len_sq) {
-      i_best = i;
+    if (use_nearest) {
+      if (tests[i].len_sq < tests[i_best].len_sq) {
+        i_best = i;
+      }
+    }
+    else {
+      if (tests[i].len_sq > tests[i_best].len_sq) {
+        i_best = i;
+      }
     }
   }
 
@@ -139,14 +147,13 @@ struct PathSelectParams {
   bool track_active;
   bool use_topology_distance;
   bool use_face_step;
-#ifdef USE_FILL
   bool use_fill;
-#endif
   struct CheckerIntervalParams interval_params;
 };
 
 struct UserData_UV {
   Scene *scene;
+  BMEditMesh *em;
   uint cd_loop_uv_offset;
 };
 
@@ -162,13 +169,11 @@ static void path_select_properties(wmOperatorType *ot)
                   false,
                   "Topology Distance",
                   "Find the minimum number of steps, ignoring spatial distance");
-#ifdef USE_FILL
   RNA_def_boolean(ot->srna,
                   "use_fill",
                   false,
                   "Fill Region",
                   "Select all paths between the source/destination elements");
-#endif
 
   WM_operator_properties_checker_interval(ot, true);
 }
@@ -177,9 +182,7 @@ static void path_select_params_from_op(wmOperator *op, struct PathSelectParams *
 {
   op_params->track_active = false;
   op_params->use_face_step = RNA_boolean_get(op->ptr, "use_face_step");
-#ifdef USE_FILL
   op_params->use_fill = RNA_boolean_get(op->ptr, "use_fill");
-#endif
   op_params->use_topology_distance = RNA_boolean_get(op->ptr, "use_topology_distance");
   WM_operator_properties_checker_interval_from_op(op, &op_params->interval_params);
 }
@@ -200,6 +203,7 @@ static bool looptag_test_cb(BMLoop *l, void *user_data_v)
 {
   /* All connected loops are selected or we return false. */
   struct UserData_UV *user_data = user_data_v;
+  const Scene *scene = user_data->scene;
   const uint cd_loop_uv_offset = user_data->cd_loop_uv_offset;
   const MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
   BMIter iter;
@@ -208,7 +212,7 @@ static bool looptag_test_cb(BMLoop *l, void *user_data_v)
     if (looptag_filter_cb(l_iter, user_data)) {
       const MLoopUV *luv_iter = BM_ELEM_CD_GET_VOID_P(l_iter, cd_loop_uv_offset);
       if (equals_v2v2(luv->uv, luv_iter->uv)) {
-        if ((luv_iter->flag & MLOOPUV_VERTSEL) == 0) {
+        if (!uvedit_uv_select_test(scene, l_iter, cd_loop_uv_offset)) {
           return false;
         }
       }
@@ -219,6 +223,8 @@ static bool looptag_test_cb(BMLoop *l, void *user_data_v)
 static void looptag_set_cb(BMLoop *l, bool val, void *user_data_v)
 {
   struct UserData_UV *user_data = user_data_v;
+  const Scene *scene = user_data->scene;
+  BMEditMesh *em = user_data->em;
   const uint cd_loop_uv_offset = user_data->cd_loop_uv_offset;
   const MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
   BMIter iter;
@@ -227,28 +233,56 @@ static void looptag_set_cb(BMLoop *l, bool val, void *user_data_v)
     if (looptag_filter_cb(l_iter, user_data)) {
       MLoopUV *luv_iter = BM_ELEM_CD_GET_VOID_P(l_iter, cd_loop_uv_offset);
       if (equals_v2v2(luv->uv, luv_iter->uv)) {
-        SET_FLAG_FROM_TEST(luv_iter->flag, val, MLOOPUV_VERTSEL);
+        uvedit_uv_select_set(scene, em, l_iter, val, false, cd_loop_uv_offset);
       }
     }
   }
 }
 
-static void mouse_mesh_uv_shortest_path_vert(Scene *scene,
-                                             Object *obedit,
-                                             const struct PathSelectParams *op_params,
-                                             BMLoop *l_src,
-                                             BMLoop *l_dst,
-                                             BMLoop *l_dst_add_to_path,
-                                             const float aspect_y,
-                                             const int cd_loop_uv_offset)
+static int mouse_mesh_uv_shortest_path_vert(Scene *scene,
+                                            Object *obedit,
+                                            const struct PathSelectParams *op_params,
+                                            BMLoop *l_src,
+                                            BMLoop *l_dst,
+                                            const float aspect_y,
+                                            const int cd_loop_uv_offset)
 {
-  const ToolSettings *ts = scene->toolsettings;
-  const bool use_fake_edge_select = (ts->uv_selectmode & UV_SELECT_EDGE);
+  const char uv_selectmode = ED_uvedit_select_mode_get(scene);
+  const bool use_fake_edge_select = (uv_selectmode & UV_SELECT_EDGE);
   BMEditMesh *em = BKE_editmesh_from_object(obedit);
   BMesh *bm = em->bm;
+  int flush = 0;
+
+  /* Variables to use when `use_fake_edge_select` is set. */
+  struct {
+    BMLoop *l_dst_activate;
+    BMLoop *l_dst_add_to_path;
+  } fake_edge_select = {NULL};
+
+  if (use_fake_edge_select) {
+    fake_edge_select.l_dst_activate = l_dst;
+
+    /* Use most distant when doing region selection.
+     * without this we get dangling edges outside the region. */
+    bool use_neaerst = (op_params->use_fill == false);
+    BMElem *ele_src = (BMElem *)l_src;
+    BMElem *ele_dst = (BMElem *)l_dst;
+    BMElem *ele_dst_final = NULL;
+    bm_loop_calc_vert_pair_from_edge_pair(
+        use_neaerst, cd_loop_uv_offset, aspect_y, &ele_src, &ele_dst, &ele_dst_final);
+
+    if (op_params->use_fill == false) {
+      /* Always activate the item under the cursor. */
+      fake_edge_select.l_dst_add_to_path = (BMLoop *)ele_dst_final;
+    }
+
+    l_src = (BMLoop *)ele_src;
+    l_dst = (BMLoop *)ele_dst;
+  }
 
   struct UserData_UV user_data = {
       .scene = scene,
+      .em = em,
       .cd_loop_uv_offset = cd_loop_uv_offset,
   };
 
@@ -280,11 +314,14 @@ static void mouse_mesh_uv_shortest_path_vert(Scene *scene,
   BMLoop *l_dst_last = l_dst;
 
   if (path) {
-    if ((l_dst_add_to_path != NULL) && (BLI_linklist_index(path, l_dst_add_to_path) == -1)) {
-      /* Append, this isn't optimal compared to #BLI_linklist_append, it's a one-off lookup. */
-      LinkNode *path_last = BLI_linklist_find_last(path);
-      BLI_linklist_insert_after(&path_last, l_dst_add_to_path);
-      BLI_assert(BLI_linklist_find_last(path)->link == l_dst_add_to_path);
+    if (use_fake_edge_select) {
+      if ((fake_edge_select.l_dst_add_to_path != NULL) &&
+          (BLI_linklist_index(path, fake_edge_select.l_dst_add_to_path) == -1)) {
+        /* Append, this isn't optimal compared to #BLI_linklist_append, it's a one-off lookup. */
+        LinkNode *path_last = BLI_linklist_find_last(path);
+        BLI_linklist_insert_after(&path_last, fake_edge_select.l_dst_add_to_path);
+        BLI_assert(BLI_linklist_find_last(path)->link == fake_edge_select.l_dst_add_to_path);
+      }
     }
 
     /* toggle the flag */
@@ -310,6 +347,7 @@ static void mouse_mesh_uv_shortest_path_vert(Scene *scene,
     } while ((void)depth++, (node = node->next));
 
     BLI_linklist_free(path, NULL);
+    flush = all_set ? -1 : 

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list