[Bf-blender-cvs] [1dd381828fa] master: UV: edge-ring selection support

Campbell Barton noreply at git.blender.org
Sat Jul 18 08:09:38 CEST 2020


Commit: 1dd381828fa3f0f642086bc2bfa0c7d65efbeecb
Author: Campbell Barton
Date:   Sat Jul 18 16:00:28 2020 +1000
Branches: master
https://developer.blender.org/rB1dd381828fa3f0f642086bc2bfa0c7d65efbeecb

UV: edge-ring selection support

Matches edit-mesh edge-ring selection.

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

M	release/scripts/presets/keyconfig/keymap_data/blender_default.py
M	source/blender/editors/uvedit/uvedit_intern.h
M	source/blender/editors/uvedit/uvedit_ops.c
M	source/blender/editors/uvedit/uvedit_select.c

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

diff --git a/release/scripts/presets/keyconfig/keymap_data/blender_default.py b/release/scripts/presets/keyconfig/keymap_data/blender_default.py
index f9c5e077625..9db47de8520 100644
--- a/release/scripts/presets/keyconfig/keymap_data/blender_default.py
+++ b/release/scripts/presets/keyconfig/keymap_data/blender_default.py
@@ -861,6 +861,10 @@ def km_uv_editor(params):
          {"properties": [("extend", False)]}),
         ("uv.select_loop", {"type": params.select_mouse, "value": params.select_mouse_value, "shift": True, "alt": True},
          {"properties": [("extend", True)]}),
+        ("uv.select_edge_ring", {"type": params.select_mouse, "value": params.select_mouse_value, "ctrl": True, "alt": True},
+         {"properties": [("extend", False)]}),
+        ("uv.select_edge_ring", {"type": params.select_mouse, "value": params.select_mouse_value, "ctrl": True, "shift": True, "alt": True},
+         {"properties": [("extend", True)]}),
         ("uv.shortest_path_pick", {"type": params.select_mouse, "value": params.select_mouse_value, "ctrl": True},
          {"properties": [("use_fill", False)]}),
         ("uv.shortest_path_pick", {"type": params.select_mouse, "value": params.select_mouse_value, "ctrl": True, "shift": True},
diff --git a/source/blender/editors/uvedit/uvedit_intern.h b/source/blender/editors/uvedit/uvedit_intern.h
index 6a5f5162dff..d5e7dd08fd1 100644
--- a/source/blender/editors/uvedit/uvedit_intern.h
+++ b/source/blender/editors/uvedit/uvedit_intern.h
@@ -126,6 +126,7 @@ const float *uvedit_first_selected_uv_from_vertex(struct Scene *scene,
 void UV_OT_select_all(struct wmOperatorType *ot);
 void UV_OT_select(struct wmOperatorType *ot);
 void UV_OT_select_loop(struct wmOperatorType *ot);
+void UV_OT_select_edge_ring(struct wmOperatorType *ot);
 void UV_OT_select_linked(struct wmOperatorType *ot);
 void UV_OT_select_linked_pick(struct wmOperatorType *ot);
 void UV_OT_select_split(struct wmOperatorType *ot);
diff --git a/source/blender/editors/uvedit/uvedit_ops.c b/source/blender/editors/uvedit/uvedit_ops.c
index 6003d4d5d95..faf8e5013dd 100644
--- a/source/blender/editors/uvedit/uvedit_ops.c
+++ b/source/blender/editors/uvedit/uvedit_ops.c
@@ -2071,6 +2071,7 @@ void ED_operatortypes_uvedit(void)
   WM_operatortype_append(UV_OT_select_all);
   WM_operatortype_append(UV_OT_select);
   WM_operatortype_append(UV_OT_select_loop);
+  WM_operatortype_append(UV_OT_select_edge_ring);
   WM_operatortype_append(UV_OT_select_linked);
   WM_operatortype_append(UV_OT_select_linked_pick);
   WM_operatortype_append(UV_OT_select_split);
diff --git a/source/blender/editors/uvedit/uvedit_select.c b/source/blender/editors/uvedit/uvedit_select.c
index b1b6821419b..77529ca0275 100644
--- a/source/blender/editors/uvedit/uvedit_select.c
+++ b/source/blender/editors/uvedit/uvedit_select.c
@@ -558,6 +558,32 @@ void uvedit_uv_select_disable(const Scene *scene,
   }
 }
 
+static BMLoop *uvedit_loop_find_other_radial_loop_with_visible_face(Scene *scene,
+                                                                    BMLoop *l_src,
+                                                                    const float limit[2],
+                                                                    const int cd_loop_uv_offset)
+{
+  BMLoop *l_other = NULL;
+  BMLoop *l_iter = l_src->radial_next;
+  if (l_iter != l_src) {
+    do {
+      if (uvedit_face_visible_test(scene, l_iter->f) &&
+          BM_loop_uv_share_edge_check_with_limit(l_src, l_iter, limit, cd_loop_uv_offset)) {
+        /* Check UV's are contiguous. */
+        if (l_other == NULL) {
+          l_other = l_iter;
+        }
+        else {
+          /* Only use when there is a single alternative. */
+          l_other = NULL;
+          break;
+        }
+      }
+    } while ((l_iter = l_iter->radial_next) != l_src);
+  }
+  return l_other;
+}
+
 /** \} */
 
 /* -------------------------------------------------------------------- */
@@ -1034,6 +1060,63 @@ static int uv_select_edgeloop(
 
 /** \} */
 
+/* -------------------------------------------------------------------- */
+/** \name Edge Ring Select
+ * \{ */
+
+static int uv_select_edgering(const SpaceImage *sima,
+                              Scene *scene,
+                              Object *obedit,
+                              UvNearestHit *hit,
+                              const float limit[2],
+                              const bool extend)
+{
+  BMEditMesh *em = BKE_editmesh_from_object(obedit);
+  bool select;
+
+  const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
+
+  if (!extend) {
+    uv_select_all_perform(scene, obedit, SEL_DESELECT);
+  }
+
+  BM_mesh_elem_hflag_disable_all(em->bm, BM_FACE, BM_ELEM_TAG, false);
+
+  if (extend) {
+    select = !(uvedit_uv_select_test(scene, hit->l, cd_loop_uv_offset));
+  }
+  else {
+    select = true;
+  }
+
+  BMLoop *l_pair[2] = {
+      hit->l,
+      uvedit_loop_find_other_radial_loop_with_visible_face(
+          scene, hit->l, limit, cd_loop_uv_offset),
+  };
+
+  for (int side = 0; side < 2; side++) {
+    BMLoop *l_step = l_pair[side];
+    while (l_step && l_step->f->len == 4) {
+      if (BM_elem_flag_test(l_step->f, BM_ELEM_TAG) ||
+          !uvedit_face_visible_test(scene, l_step->f)) {
+        break;
+      }
+
+      uvedit_face_select_set_with_sticky(
+          sima, scene, em, l_step->f, select, false, limit, cd_loop_uv_offset);
+
+      BM_elem_flag_enable(l_step->f, BM_ELEM_TAG);
+      l_step = uvedit_loop_find_other_radial_loop_with_visible_face(
+          scene, l_step->next->next, limit, cd_loop_uv_offset);
+    }
+  }
+
+  return (select) ? 1 : -1;
+}
+
+/** \} */
+
 /* -------------------------------------------------------------------- */
 /** \name Select Linked
  * \{ */
@@ -1941,11 +2024,20 @@ void UV_OT_select(wmOperatorType *ot)
 /** \} */
 
 /* -------------------------------------------------------------------- */
-/** \name Loop Select Operator
+/** \name Shared Edge Loop/Ring Select Operator Functions
  * \{ */
 
-static int uv_mouse_select_loop_multi(
-    bContext *C, Object **objects, uint objects_len, const float co[2], const bool extend)
+enum eUVLoopGenericType {
+  UV_LOOP_SELECT = 1,
+  UV_RING_SELECT = 2,
+};
+
+static int uv_mouse_select_loop_generic_multi(bContext *C,
+                                              Object **objects,
+                                              uint objects_len,
+                                              const float co[2],
+                                              const bool extend,
+                                              enum eUVLoopGenericType loop_type)
 {
   SpaceImage *sima = CTX_wm_space_image(C);
   Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
@@ -1973,7 +2065,16 @@ static int uv_mouse_select_loop_multi(
     /* TODO(MULTI_EDIT): We only need to de-select non-active */
     uv_select_all_perform_multi(scene, objects, objects_len, SEL_DESELECT);
   }
-  flush = uv_select_edgeloop(scene, obedit, &hit, limit, extend);
+
+  if (loop_type == UV_LOOP_SELECT) {
+    flush = uv_select_edgeloop(scene, obedit, &hit, limit, extend);
+  }
+  else if (loop_type == UV_RING_SELECT) {
+    flush = uv_select_edgering(sima, scene, obedit, &hit, limit, extend);
+  }
+  else {
+    BLI_assert(0);
+  }
 
   if (ts->uv_flag & UV_SYNC_SELECTION) {
     if (flush != 0) {
@@ -1988,17 +2089,26 @@ static int uv_mouse_select_loop_multi(
 
   return OPERATOR_PASS_THROUGH | OPERATOR_FINISHED;
 }
-static int uv_mouse_select_loop(bContext *C, const float co[2], const bool extend)
+static int uv_mouse_select_loop_generic(bContext *C,
+                                        const float co[2],
+                                        const bool extend,
+                                        enum eUVLoopGenericType loop_type)
 {
   ViewLayer *view_layer = CTX_data_view_layer(C);
   uint objects_len = 0;
   Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs(
       view_layer, ((View3D *)NULL), &objects_len);
-  int ret = uv_mouse_select_loop_multi(C, objects, objects_len, co, extend);
+  int ret = uv_mouse_select_loop_generic_multi(C, objects, objects_len, co, extend, loop_type);
   MEM_freeN(objects);
   return ret;
 }
 
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Edge Loop Select Operator
+ * \{ */
+
 static int uv_select_loop_exec(bContext *C, wmOperator *op)
 {
   float co[2];
@@ -2006,7 +2116,7 @@ static int uv_select_loop_exec(bContext *C, wmOperator *op)
   RNA_float_get_array(op->ptr, "location", co);
   const bool extend = RNA_boolean_get(op->ptr, "extend");
 
-  return uv_mouse_select_loop(C, co, extend);
+  return uv_mouse_select_loop_generic(C, co, extend, UV_LOOP_SELECT);
 }
 
 static int uv_select_loop_invoke(bContext *C, wmOperator *op, const wmEvent *event)
@@ -2054,6 +2164,63 @@ void UV_OT_select_loop(wmOperatorType *ot)
 
 /** \} */
 
+/* -------------------------------------------------------------------- */
+/** \name Edge Ring Select Operator
+ * \{ */
+
+static int uv_select_edge_ring_exec(bContext *C, wmOperator *op)
+{
+  float co[2];
+  RNA_float_get_array(op->ptr, "location", co);
+  const bool extend = RNA_boolean_get(op->ptr, "extend");
+  return uv_mouse_select_loop_generic(C, co, extend, UV_RING_SELECT);
+}
+
+static int uv_select_edge_ring_invoke(bContext *C, wmOperator *op, const wmEvent *event)
+{
+  const ARegion *region = CTX_wm_region(C);
+  float co[2];
+
+  UI_view2d_region_to_view(&region->v2d, event->mval[0], event->mval[1], &co[0], &co[1]);
+  RNA_float_set_array(op->ptr, "location", co);
+
+  return uv_select_edge_ring_exec(C, op);
+}
+
+void UV_OT_select_edge_ring(wmOperatorType *ot)
+{
+  /* identifiers */
+  ot->name = "Edge Ring Select";
+  ot->description = "Select an edge ring of connected UV vertices";
+  ot->idname = "UV_OT_select_edge_ring";
+  ot->flag = OPTYPE_UNDO;
+
+  /* api callbacks */
+  ot->exec = uv_select_edge_ring_exec;
+  ot->invoke = uv_select_edge_ring_invoke;
+  ot->poll = ED_operator_uvedit; /* requires space image */
+
+  /* properties */
+  RNA_def_boolean(ot->srna,
+                  "extend",
+  

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list