[Bf-blender-cvs] [04aab7d5162] master: Animation: Add "Select Linked Vertices" to Weight Paint Mode

Christoph Lendenfeld noreply at git.blender.org
Thu Feb 2 16:17:26 CET 2023


Commit: 04aab7d51620d74c408d7e3e8f5296ce2af793f3
Author: Christoph Lendenfeld
Date:   Thu Feb 2 16:16:14 2023 +0100
Branches: master
https://developer.blender.org/rB04aab7d51620d74c408d7e3e8f5296ce2af793f3

Animation: Add "Select Linked Vertices" to Weight Paint Mode

Adds two operators to select linked  vertices in weight paint mode.
Similar to how it works in edit mode.
Press "L" to select vertices under the cursor,
or CTRL + "L" to select anything linked to the current selection.

Reviewed by: Sybren A. Stüvel, Hans Goudey, Marion Stalke
Differential Revision: https://developer.blender.org/D16848
Ref: D16848

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

M	release/scripts/presets/keyconfig/keymap_data/blender_default.py
M	release/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py
M	release/scripts/startup/bl_ui/space_view3d.py
M	source/blender/editors/include/ED_mesh.h
M	source/blender/editors/mesh/editface.cc
M	source/blender/editors/sculpt_paint/paint_intern.h
M	source/blender/editors/sculpt_paint/paint_ops.c
M	source/blender/editors/sculpt_paint/paint_utils.c

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

diff --git a/release/scripts/presets/keyconfig/keymap_data/blender_default.py b/release/scripts/presets/keyconfig/keymap_data/blender_default.py
index 01e6ac0f0c0..9c2ebfd6b4d 100644
--- a/release/scripts/presets/keyconfig/keymap_data/blender_default.py
+++ b/release/scripts/presets/keyconfig/keymap_data/blender_default.py
@@ -4421,6 +4421,11 @@ def km_weight_paint_vertex_selection(params):
         ("view3d.select_lasso", {"type": params.action_mouse, "value": 'CLICK_DRAG', "shift": True, "ctrl": True},
          {"properties": [("mode", 'SUB')]}),
         ("view3d.select_circle", {"type": 'C', "value": 'PRESS'}, None),
+        ("paint.vert_select_linked", {"type": 'L', "value": 'PRESS', "ctrl": True}, None),
+        ("paint.vert_select_linked_pick", {"type": 'L', "value": 'PRESS'},
+         {"properties": [("select", True)]}),
+        ("paint.vert_select_linked_pick", {"type": 'L', "value": 'PRESS', "shift": True},
+         {"properties": [("select", False)]}),
     ])
 
     return keymap
diff --git a/release/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py b/release/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py
index 0464f5dc317..98cee34519f 100644
--- a/release/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py
+++ b/release/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py
@@ -2972,6 +2972,11 @@ def km_weight_paint_vertex_selection(params):
         ("paint.vert_select_hide", {"type": 'H', "value": 'PRESS', "shift": True},
          {"properties": [("unselected", True)]}),
         ("paint.face_vert_reveal", {"type": 'H', "value": 'PRESS', "alt": True}, None),
+        ("paint.vert_select_linked", {"type": 'L', "value": 'PRESS', "ctrl": True}, None),
+        ("paint.vert_select_linked_pick", {"type": 'L', "value": 'PRESS'},
+         {"properties": [("select", True)]}),
+        ("paint.vert_select_linked_pick", {"type": 'L', "value": 'PRESS', "shift": True},
+         {"properties": [("select", False)]}),
     ])
 
     return keymap
diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py
index d5fe24c1b62..1ce457480e5 100644
--- a/release/scripts/startup/bl_ui/space_view3d.py
+++ b/release/scripts/startup/bl_ui/space_view3d.py
@@ -2038,6 +2038,7 @@ class VIEW3D_MT_select_paint_mask_vertex(Menu):
         layout.separator()
 
         layout.operator("paint.vert_select_ungrouped", text="Ungrouped Vertices")
+        layout.operator("paint.vert_select_linked", text="Select Linked")
 
 
 class VIEW3D_MT_select_edit_curves(Menu):
diff --git a/source/blender/editors/include/ED_mesh.h b/source/blender/editors/include/ED_mesh.h
index 70e553abb50..248ce8ec6b5 100644
--- a/source/blender/editors/include/ED_mesh.h
+++ b/source/blender/editors/include/ED_mesh.h
@@ -437,7 +437,13 @@ void paintvert_select_ungrouped(struct Object *ob, bool extend, bool flush_flags
  */
 void paintvert_flush_flags(struct Object *ob);
 void paintvert_tag_select_update(struct bContext *C, struct Object *ob);
-
+/* Select vertices that are connected to already selected vertices. */
+void paintvert_select_linked(struct bContext *C, struct Object *ob);
+/* Select vertices that are linked to the vertex under the given region space coordinates. */
+void paintvert_select_linked_pick(struct bContext *C,
+                                  struct Object *ob,
+                                  const int region_coordinates[2],
+                                  bool select);
 void paintvert_hide(struct bContext *C, struct Object *ob, bool unselected);
 void paintvert_reveal(struct bContext *C, struct Object *ob, bool select);
 
diff --git a/source/blender/editors/mesh/editface.cc b/source/blender/editors/mesh/editface.cc
index af968b2aeba..c479145e8df 100644
--- a/source/blender/editors/mesh/editface.cc
+++ b/source/blender/editors/mesh/editface.cc
@@ -6,9 +6,11 @@
 
 #include "MEM_guardedalloc.h"
 
+#include "BLI_atomic_disjoint_set.hh"
 #include "BLI_bitmap.h"
 #include "BLI_blenlib.h"
 #include "BLI_math.h"
+#include "BLI_task.hh"
 
 #include "IMB_imbuf.h"
 #include "IMB_imbuf_types.h"
@@ -536,6 +538,92 @@ void paintvert_flush_flags(Object *ob)
   BKE_mesh_batch_cache_dirty_tag(me, BKE_MESH_BATCH_DIRTY_ALL);
 }
 
+static void paintvert_select_linked_vertices(bContext *C,
+                                             Object *ob,
+                                             const blender::Span<int> vertex_indices,
+                                             const bool select)
+{
+  using namespace blender;
+
+  Mesh *mesh = BKE_mesh_from_object(ob);
+  if (mesh == nullptr || mesh->totpoly == 0) {
+    return;
+  }
+
+  /* AtomicDisjointSet is used to store connection information in vertex indices. */
+  AtomicDisjointSet islands(mesh->totvert);
+  const Span<MEdge> edges = mesh->edges();
+
+  /* By calling join() on the vertices of all edges, the AtomicDisjointSet contains information on
+   * which parts of the mesh are connected. */
+  threading::parallel_for(edges.index_range(), 1024, [&](const IndexRange range) {
+    for (const MEdge &edge : edges.slice(range)) {
+      islands.join(edge.v1, edge.v2);
+    }
+  });
+
+  bke::MutableAttributeAccessor attributes = mesh->attributes_for_write();
+  bke::SpanAttributeWriter<bool> select_vert = attributes.lookup_or_add_for_write_span<bool>(
+      ".select_vert", ATTR_DOMAIN_POINT);
+
+  Set<int> selected_roots;
+
+  for (const int i : vertex_indices) {
+    const int root = islands.find_root(i);
+    selected_roots.add(root);
+  }
+
+  threading::parallel_for(select_vert.span.index_range(), 1024, [&](const IndexRange range) {
+    for (const int i : range) {
+      const int root = islands.find_root(i);
+      if (selected_roots.contains(root)) {
+        select_vert.span[i] = select;
+      }
+    }
+  });
+
+  select_vert.finish();
+
+  paintvert_flush_flags(ob);
+  paintvert_tag_select_update(C, ob);
+}
+
+void paintvert_select_linked_pick(bContext *C,
+                                  Object *ob,
+                                  const int region_coordinates[2],
+                                  const bool select)
+{
+  uint index = uint(-1);
+  if (!ED_mesh_pick_vert(
+          C, ob, region_coordinates, ED_MESH_PICK_DEFAULT_VERT_DIST, true, &index)) {
+    return;
+  }
+
+  paintvert_select_linked_vertices(C, ob, {int(index)}, select);
+}
+
+void paintvert_select_linked(bContext *C, Object *ob)
+{
+  Mesh *mesh = BKE_mesh_from_object(ob);
+  if (mesh == nullptr || mesh->totpoly == 0) {
+    return;
+  }
+
+  blender::bke::MutableAttributeAccessor attributes = mesh->attributes_for_write();
+  blender::bke::SpanAttributeWriter<bool> select_vert =
+      attributes.lookup_or_add_for_write_span<bool>(".select_vert", ATTR_DOMAIN_POINT);
+
+  blender::Vector<int> indices;
+  for (const int i : select_vert.span.index_range()) {
+    if (!select_vert.span[i]) {
+      continue;
+    }
+    indices.append(i);
+  }
+  select_vert.finish();
+  paintvert_select_linked_vertices(C, ob, indices, true);
+}
+
 void paintvert_tag_select_update(bContext *C, Object *ob)
 {
   DEG_id_tag_update(static_cast<ID *>(ob->data), ID_RECALC_COPY_ON_WRITE | ID_RECALC_SELECT);
diff --git a/source/blender/editors/sculpt_paint/paint_intern.h b/source/blender/editors/sculpt_paint/paint_intern.h
index fbb69b1fc5b..c31ba869e7f 100644
--- a/source/blender/editors/sculpt_paint/paint_intern.h
+++ b/source/blender/editors/sculpt_paint/paint_intern.h
@@ -383,6 +383,8 @@ void PAINT_OT_face_vert_reveal(struct wmOperatorType *ot);
 void PAINT_OT_vert_select_all(struct wmOperatorType *ot);
 void PAINT_OT_vert_select_ungrouped(struct wmOperatorType *ot);
 void PAINT_OT_vert_select_hide(struct wmOperatorType *ot);
+void PAINT_OT_vert_select_linked(struct wmOperatorType *ot);
+void PAINT_OT_vert_select_linked_pick(struct wmOperatorType *ot);
 
 bool vert_paint_poll(struct bContext *C);
 bool mask_paint_poll(struct bContext *C);
diff --git a/source/blender/editors/sculpt_paint/paint_ops.c b/source/blender/editors/sculpt_paint/paint_ops.c
index b78c60e7964..06a725d703a 100644
--- a/source/blender/editors/sculpt_paint/paint_ops.c
+++ b/source/blender/editors/sculpt_paint/paint_ops.c
@@ -1457,6 +1457,8 @@ void ED_operatortypes_paint(void)
   WM_operatortype_append(PAINT_OT_vert_select_all);
   WM_operatortype_append(PAINT_OT_vert_select_ungrouped);
   WM_operatortype_append(PAINT_OT_vert_select_hide);
+  WM_operatortype_append(PAINT_OT_vert_select_linked);
+  WM_operatortype_append(PAINT_OT_vert_select_linked_pick);
 
   /* vertex */
   WM_operatortype_append(PAINT_OT_vertex_paint_toggle);
diff --git a/source/blender/editors/sculpt_paint/paint_utils.c b/source/blender/editors/sculpt_paint/paint_utils.c
index ccfdd0c0e49..98fefd86d95 100644
--- a/source/blender/editors/sculpt_paint/paint_utils.c
+++ b/source/blender/editors/sculpt_paint/paint_utils.c
@@ -733,6 +733,53 @@ void PAINT_OT_vert_select_ungrouped(wmOperatorType *ot)
   RNA_def_boolean(ot->srna, "extend", false, "Extend", "Extend the selection");
 }
 
+static int paintvert_select_linked_exec(bContext *C, wmOperator *UNUSED(op))
+{
+  paintvert_select_linked(C, CTX_data_active_object(C));
+  ED_region_tag_redraw(CTX_wm_region(C));
+  return OPERATOR_FINISHED;
+}
+
+void PAINT_OT_vert_select_linked(wmOperatorType *ot)
+{
+  ot->name = "Select Linked Vertices";
+  ot->description = "Select linked vertices";
+  ot->idname = "PAINT_OT_vert_select_linked";
+
+  ot->exec = paintvert_select_linked_exec;
+  ot->poll = vert_paint_poll;
+
+  ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
+static int paintvert_select_linked_pick_invoke(bContext *C, wmOperator *op, const wmEvent *event)
+{
+  const bool select = RNA_boolean_get(op->ptr, "select");
+  view3d_operator_needs_opengl(C);
+
+  paintvert_select_linked_pick(C, CTX_data_active_object(C), event->mval, select);
+  ED_region_tag_redraw(CTX_wm_region(C));
+  return OPERATOR_FINISHED;
+}
+
+void PAINT_OT_vert_select_linked_pick(wmOperatorType *ot)
+{
+  ot->name = "Select Linked Vertices Pick";
+  ot->description = "Select linked vertices under the cursor";
+  ot->idname = "PAINT_OT_vert_select_linked_pick";
+
+  ot->invoke = paintvert_select_lin

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list