[Bf-blender-cvs] [1154b455267] master: UV: Add "Select Similar" operator in UV editor

Chris Blackbourn noreply at git.blender.org
Tue Jun 21 07:35:30 CEST 2022


Commit: 1154b45526797d6f5999d1be18f92124baf8107f
Author: Chris Blackbourn
Date:   Tue Jun 21 17:31:59 2022 +1200
Branches: master
https://developer.blender.org/rB1154b45526797d6f5999d1be18f92124baf8107f

UV: Add "Select Similar" operator in UV editor

Resolves T47437.

Differential Revision: https://developer.blender.org/D15164

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

M	release/scripts/presets/keyconfig/keymap_data/blender_default.py
M	release/scripts/startup/bl_ui/space_image.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 7d0929ef28f..1239f49473c 100644
--- a/release/scripts/presets/keyconfig/keymap_data/blender_default.py
+++ b/release/scripts/presets/keyconfig/keymap_data/blender_default.py
@@ -1265,6 +1265,7 @@ def km_uv_editor(params):
          {"properties": [("deselect", True)]}),
         ("uv.select_more", {"type": 'NUMPAD_PLUS', "value": 'PRESS', "ctrl": True, "repeat": True}, None),
         ("uv.select_less", {"type": 'NUMPAD_MINUS', "value": 'PRESS', "ctrl": True, "repeat": True}, None),
+        ("uv.select_similar", {"type": 'G', "value": 'PRESS', "shift": True}, None),
         *_template_items_select_actions(params, "uv.select_all"),
         *_template_items_hide_reveal_actions("uv.hide", "uv.reveal"),
         ("uv.select_pinned", {"type": 'P', "value": 'PRESS', "shift": True}, None),
diff --git a/release/scripts/startup/bl_ui/space_image.py b/release/scripts/startup/bl_ui/space_image.py
index 1f02e0f64d4..5d25d02d98e 100644
--- a/release/scripts/startup/bl_ui/space_image.py
+++ b/release/scripts/startup/bl_ui/space_image.py
@@ -159,6 +159,7 @@ class IMAGE_MT_select(Menu):
 
         layout.operator("uv.select_pinned")
         layout.menu("IMAGE_MT_select_linked")
+        layout.operator("uv.select_similar")
 
         layout.separator()
 
diff --git a/source/blender/editors/uvedit/uvedit_intern.h b/source/blender/editors/uvedit/uvedit_intern.h
index 181982f0b2c..04128cf378c 100644
--- a/source/blender/editors/uvedit/uvedit_intern.h
+++ b/source/blender/editors/uvedit/uvedit_intern.h
@@ -182,5 +182,6 @@ void UV_OT_select_circle(struct wmOperatorType *ot);
 void UV_OT_select_more(struct wmOperatorType *ot);
 void UV_OT_select_less(struct wmOperatorType *ot);
 void UV_OT_select_overlap(struct wmOperatorType *ot);
+void UV_OT_select_similar(struct wmOperatorType *ot);
 /* Used only when UV sync select is disabled. */
 void UV_OT_select_mode(struct wmOperatorType *ot);
diff --git a/source/blender/editors/uvedit/uvedit_ops.c b/source/blender/editors/uvedit/uvedit_ops.c
index fe6f9f0d513..0b5d6592426 100644
--- a/source/blender/editors/uvedit/uvedit_ops.c
+++ b/source/blender/editors/uvedit/uvedit_ops.c
@@ -2044,6 +2044,7 @@ void ED_operatortypes_uvedit(void)
   WM_operatortype_append(UV_OT_select_pinned);
   WM_operatortype_append(UV_OT_select_box);
   WM_operatortype_append(UV_OT_select_lasso);
+  WM_operatortype_append(UV_OT_select_similar);
   WM_operatortype_append(UV_OT_select_circle);
   WM_operatortype_append(UV_OT_select_more);
   WM_operatortype_append(UV_OT_select_less);
diff --git a/source/blender/editors/uvedit/uvedit_select.c b/source/blender/editors/uvedit/uvedit_select.c
index cea2bb05547..9080da9e1ed 100644
--- a/source/blender/editors/uvedit/uvedit_select.c
+++ b/source/blender/editors/uvedit/uvedit_select.c
@@ -12,6 +12,7 @@
 #include "MEM_guardedalloc.h"
 
 #include "DNA_image_types.h"
+#include "DNA_material_types.h"
 #include "DNA_meshdata_types.h"
 #include "DNA_node_types.h"
 #include "DNA_object_types.h"
@@ -22,6 +23,7 @@
 #include "BLI_blenlib.h"
 #include "BLI_hash.h"
 #include "BLI_kdopbvh.h"
+#include "BLI_kdtree.h"
 #include "BLI_lasso_2d.h"
 #include "BLI_math.h"
 #include "BLI_polyfill_2d.h"
@@ -31,6 +33,7 @@
 #include "BKE_customdata.h"
 #include "BKE_editmesh.h"
 #include "BKE_layer.h"
+#include "BKE_material.h"
 #include "BKE_mesh.h"
 #include "BKE_mesh_mapping.h"
 #include "BKE_report.h"
@@ -75,6 +78,16 @@ static void uv_select_tag_update_for_object(Depsgraph *depsgraph,
                                             const ToolSettings *ts,
                                             Object *obedit);
 
+typedef enum {
+  UV_SSIM_AREA_UV = 1000,
+  UV_SSIM_AREA_3D,
+  UV_SSIM_LENGTH_UV,
+  UV_SSIM_LENGTH_3D,
+  UV_SSIM_SIDES,
+  UV_SSIM_PIN,
+  UV_SSIM_MATERIAL,
+} eUVSelectSimilar;
+
 /* -------------------------------------------------------------------- */
 /** \name Active Selection Tracking
  *
@@ -586,12 +599,25 @@ bool uvedit_uv_select_test_ex(const ToolSettings *ts, BMLoop *l, const int cd_lo
     if (ts->selectmode & SCE_SELECT_FACE) {
       return BM_elem_flag_test_bool(l->f, BM_ELEM_SELECT);
     }
+    if (ts->selectmode & SCE_SELECT_EDGE) {
+      /* Are you looking for `uvedit_edge_select_test(...)` instead? */
+    }
     return BM_elem_flag_test_bool(l->v, BM_ELEM_SELECT);
   }
 
   MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
+
+  if (ts->selectmode & SCE_SELECT_FACE) {
+    /* Are you looking for `uvedit_face_select_test(...)` instead? */
+  }
+
+  if (ts->selectmode & SCE_SELECT_EDGE) {
+    /* Are you looking for `uvedit_edge_select_test(...)` instead? */
+  }
+
   return (luv->flag & MLOOPUV_VERTSEL) != 0;
 }
+
 bool uvedit_uv_select_test(const Scene *scene, BMLoop *l, const int cd_loop_uv_offset)
 {
   return uvedit_uv_select_test_ex(scene->toolsettings, l, cd_loop_uv_offset);
@@ -699,6 +725,10 @@ void uvedit_uv_select_enable(const Scene *scene,
 {
   const ToolSettings *ts = scene->toolsettings;
 
+  if (ts->selectmode & SCE_SELECT_EDGE) {
+    /* Are you looking for `uvedit_edge_select_set(...)` instead? */
+  }
+
   if (ts->uv_flag & UV_SYNC_SELECTION) {
     if (ts->selectmode & SCE_SELECT_FACE) {
       BM_face_select_set(em->bm, l->f, true);
@@ -4411,6 +4441,551 @@ void UV_OT_select_overlap(wmOperatorType *ot)
                   "Extend selection rather than clearing the existing selection");
 }
 
+/** \} */
+/** \name Select Similar Operator
+ * \{ */
+
+static float get_uv_vert_needle(const eUVSelectSimilar type,
+                             BMVert *vert,
+                             const float ob_m3[3][3],
+                             MLoopUV *luv,
+                             const int cd_loop_uv_offset)
+{
+  float result = 0.0f;
+  switch (type) {
+    case UV_SSIM_AREA_UV: {
+      BMFace *f;
+      BMIter iter;
+      BM_ITER_ELEM (f, &iter, vert, BM_FACES_OF_VERT) {
+        result += BM_face_calc_area_uv(f, cd_loop_uv_offset);
+      }
+    } break;
+    case UV_SSIM_AREA_3D: {
+      BMFace *f;
+      BMIter iter;
+      BM_ITER_ELEM (f, &iter, vert, BM_FACES_OF_VERT) {
+        result += BM_face_calc_area_with_mat3(f, ob_m3);
+      }
+    } break;
+    case UV_SSIM_SIDES: {
+      BMEdge *e;
+      BMIter iter;
+      BM_ITER_ELEM (e, &iter, vert, BM_EDGES_OF_VERT) {
+        result += 1.0f;
+      }
+    } break;
+    case UV_SSIM_PIN:
+      return (luv->flag & MLOOPUV_PINNED) ? 1.0f : 0.0f;
+    default:
+      BLI_assert_unreachable();
+      return false;
+  }
+
+  return result;
+}
+
+static float get_uv_edge_needle(const eUVSelectSimilar type,
+                             BMEdge *edge,
+                             const float ob_m3[3][3],
+                             MLoopUV *luv_a,
+                             MLoopUV *luv_b,
+                             const int cd_loop_uv_offset)
+{
+  float result = 0.0f;
+  switch (type) {
+    case UV_SSIM_AREA_UV: {
+      BMFace *f;
+      BMIter iter;
+      BM_ITER_ELEM (f, &iter, edge, BM_FACES_OF_EDGE) {
+        result += BM_face_calc_area_uv(f, cd_loop_uv_offset);
+      }
+    } break;
+    case UV_SSIM_AREA_3D: {
+      BMFace *f;
+      BMIter iter;
+      BM_ITER_ELEM (f, &iter, edge, BM_FACES_OF_EDGE) {
+        result += BM_face_calc_area_with_mat3(f, ob_m3);
+      }
+    } break;
+    case UV_SSIM_LENGTH_UV:
+      return len_v2v2(luv_a->uv, luv_b->uv);
+    case UV_SSIM_LENGTH_3D:
+      return len_v3v3(edge->v1->co, edge->v2->co);
+    case UV_SSIM_SIDES: {
+      BMEdge *e;
+      BMIter iter;
+      BM_ITER_ELEM (e, &iter, edge, BM_FACES_OF_EDGE) {
+        result += 1.0f;
+      }
+    } break;
+    case UV_SSIM_PIN:
+      if (luv_a->flag & MLOOPUV_PINNED) {
+        result += 1.0f;
+      }
+      if (luv_b->flag & MLOOPUV_PINNED) {
+        result += 1.0f;
+      }
+      break;
+    default:
+      BLI_assert_unreachable();
+      return false;
+  }
+
+  return result;
+}
+
+static float get_uv_face_needle(const eUVSelectSimilar type,
+                             BMFace *face,
+                             const float ob_m3[3][3],
+                             const int cd_loop_uv_offset)
+{
+  float result = 0.0f;
+  switch (type) {
+    case UV_SSIM_AREA_UV:
+      return BM_face_calc_area_uv(face, cd_loop_uv_offset);
+    case UV_SSIM_AREA_3D:
+      return BM_face_calc_area_with_mat3(face, ob_m3);
+    case UV_SSIM_SIDES:
+      return face->len;
+    case UV_SSIM_PIN: {
+      BMLoop *l;
+      BMIter liter;
+      BM_ITER_ELEM (l, &liter, face, BM_LOOPS_OF_FACE) {
+        MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
+        if (luv->flag & MLOOPUV_PINNED) {
+          result += 1.0f;
+        }
+      }
+    } break;
+    case UV_SSIM_MATERIAL:
+      return face->mat_nr;
+    default:
+      BLI_assert_unreachable();
+      return false;
+  }
+  return result;
+}
+
+static int uv_select_similar_vert_exec(bContext *C, wmOperator *op)
+{
+  Scene *scene = CTX_data_scene(C);
+  ViewLayer *view_layer = CTX_data_view_layer(C);
+  Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
+  ToolSettings *ts = CTX_data_tool_settings(C);
+
+  const eUVSelectSimilar type = RNA_enum_get(op->ptr, "type");
+  const float threshold = RNA_float_get(op->ptr, "threshold");
+  const eSimilarCmp compare = RNA_enum_get(op->ptr, "compare");
+
+  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 max_verts_selected_all = 0;
+  for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
+    Object *ob = objects[ob_index];
+    BMEditMesh *em = BKE_editmesh_from_object(ob);
+    BMFace *face;
+    BMIter iter;
+    BM_ITER_MESH (face, &iter, em->bm, BM_FACES_OF_MESH) {
+      if (!uvedit_face_visible_test(scene, face)) {
+        continue;
+      }
+      max_verts_selected_all += face->len;
+    }
+    /* TODO: Get a tighter bounds */
+  }
+
+  int tree_index = 0;
+  KDTree_1d *tree_1d = BLI_kdtree_1d_new(max_verts_selected_all);
+
+  for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
+

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list