[Bf-blender-cvs] [0f5c94bbd17] master: Armature: add Select Linked (Ctrl-L)

Campbell Barton noreply at git.blender.org
Tue Mar 31 09:22:19 CEST 2020


Commit: 0f5c94bbd1709f3942553281460673ba86e715fd
Author: Campbell Barton
Date:   Tue Mar 31 14:39:41 2020 +1100
Branches: master
https://developer.blender.org/rB0f5c94bbd1709f3942553281460673ba86e715fd

Armature: add Select Linked (Ctrl-L)

This matches select linked for other modes (curve, mesh)

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

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/armature/armature_intern.h
M	source/blender/editors/armature/armature_ops.c
M	source/blender/editors/armature/armature_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 bef054a1f1d..54936bf1fde 100644
--- a/release/scripts/presets/keyconfig/keymap_data/blender_default.py
+++ b/release/scripts/presets/keyconfig/keymap_data/blender_default.py
@@ -4560,10 +4560,11 @@ def km_armature(params):
         ("armature.select_more", {"type": 'NUMPAD_PLUS', "value": 'PRESS', "ctrl": True}, None),
         ("armature.select_less", {"type": 'NUMPAD_MINUS', "value": 'PRESS', "ctrl": True}, None),
         ("armature.select_similar", {"type": 'G', "value": 'PRESS', "shift": True}, None),
-        ("armature.select_linked", {"type": 'L', "value": 'PRESS'},
+        ("armature.select_linked_pick", {"type": 'L', "value": 'PRESS'},
          {"properties": [("deselect", False)]}),
-        ("armature.select_linked", {"type": 'L', "value": 'PRESS', "shift": True},
+        ("armature.select_linked_pick", {"type": 'L', "value": 'PRESS', "shift": True},
          {"properties": [("deselect", True)]}),
+        ("armature.select_linked", {"type": 'L', "value": 'PRESS', "ctrl": True}, None),
         ("armature.shortest_path_pick", {"type": params.select_mouse, "value": params.select_mouse_value, "ctrl": True}, None),
         # Editing.
         op_menu("VIEW3D_MT_edit_armature_delete", {"type": 'X', "value": 'PRESS'}),
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 15e526ea6a7..46beda12033 100644
--- a/release/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py
+++ b/release/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py
@@ -3535,7 +3535,7 @@ def km_armature(params):
         ("armature.select_less", {"type": 'DOWN_ARROW', "value": 'PRESS'}, None),
 
         ("armature.select_similar", {"type": 'G', "value": 'PRESS', "shift": True}, None),
-        ("armature.select_linked", {"type": 'RIGHT_BRACKET', "value": 'PRESS'},
+        ("armature.select_linked_pick", {"type": 'RIGHT_BRACKET', "value": 'PRESS'},
          {"properties": [("deselect", False)]}),
 
         ("armature.shortest_path_pick", {"type": 'LEFTMOUSE', "value": 'PRESS', "ctrl": True, "shift": True}, None),
@@ -3791,7 +3791,7 @@ def km_object_non_modal(params):
          {"properties": [("mode", 'PAINT_GPENCIL')]}),
         ("object.mode_set",{"type": 'FIVE', "value": 'PRESS'},
          {"properties": [("mode", 'WEIGHT_GPENCIL')]}),
-        
+
     ])
 
     return keymap
diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py
index 2d3b4af4ae5..142175ace51 100644
--- a/release/scripts/startup/bl_ui/space_view3d.py
+++ b/release/scripts/startup/bl_ui/space_view3d.py
@@ -1859,6 +1859,10 @@ class VIEW3D_MT_select_edit_armature(Menu):
 
         layout.separator()
 
+        layout.operator("armature.select_linked", text="Linked")
+
+        layout.separator()
+
         props = layout.operator("armature.select_hierarchy", text="Parent")
         props.extend = False
         props.direction = 'PARENT'
diff --git a/source/blender/editors/armature/armature_intern.h b/source/blender/editors/armature/armature_intern.h
index ba914080d98..37f0c7197a9 100644
--- a/source/blender/editors/armature/armature_intern.h
+++ b/source/blender/editors/armature/armature_intern.h
@@ -59,6 +59,7 @@ void ARMATURE_OT_select_mirror(struct wmOperatorType *ot);
 void ARMATURE_OT_select_more(struct wmOperatorType *ot);
 void ARMATURE_OT_select_less(struct wmOperatorType *ot);
 void ARMATURE_OT_select_hierarchy(struct wmOperatorType *ot);
+void ARMATURE_OT_select_linked_pick(struct wmOperatorType *ot);
 void ARMATURE_OT_select_linked(struct wmOperatorType *ot);
 void ARMATURE_OT_select_similar(struct wmOperatorType *ot);
 void ARMATURE_OT_shortest_path_pick(struct wmOperatorType *ot);
diff --git a/source/blender/editors/armature/armature_ops.c b/source/blender/editors/armature/armature_ops.c
index 097d384a609..b304ce92a54 100644
--- a/source/blender/editors/armature/armature_ops.c
+++ b/source/blender/editors/armature/armature_ops.c
@@ -56,6 +56,7 @@ void ED_operatortypes_armature(void)
   WM_operatortype_append(ARMATURE_OT_select_less);
   WM_operatortype_append(ARMATURE_OT_select_hierarchy);
   WM_operatortype_append(ARMATURE_OT_select_linked);
+  WM_operatortype_append(ARMATURE_OT_select_linked_pick);
   WM_operatortype_append(ARMATURE_OT_select_similar);
   WM_operatortype_append(ARMATURE_OT_shortest_path_pick);
 
diff --git a/source/blender/editors/armature/armature_select.c b/source/blender/editors/armature/armature_select.c
index e927765304f..4eb63df09ab 100644
--- a/source/blender/editors/armature/armature_select.c
+++ b/source/blender/editors/armature/armature_select.c
@@ -293,25 +293,27 @@ void *get_nearest_bone(bContext *C, const int xy[2], bool findunsel, Base **r_ba
   return NULL;
 }
 
-/* **************** EditMode stuff ********************** */
+/* -------------------------------------------------------------------- */
+/** \name Select Linked Implementation
+ *
+ * Shared logic for select linked all/pick.
+ *
+ * Use #BONE_DONE flag to select linked.
+ * \{ */
 
-static int armature_select_linked_invoke(bContext *C, wmOperator *op, const wmEvent *event)
+/**
+ * \param all_forks: Control how chains are stepped over.
+ * true: select all connected bones traveling up & down forks.
+ * false: select all parents and all children, but not the children of the root bone.
+ */
+static bool armature_select_linked_impl(Object *ob, const bool select, const bool all_forks)
 {
-  const bool select = !RNA_boolean_get(op->ptr, "deselect");
-  /* true: select all connected bones traveling up & down forks.
-   * false: select all parents and all children, but not the children of the root bone. */
-  const bool all_forks = RNA_boolean_get(op->ptr, "all_forks");
-
-  view3d_operator_needs_opengl(C);
-  BKE_object_update_select_id(CTX_data_main(C));
-
-  Base *base = NULL;
-  EditBone *ebone_active = get_nearest_bone(C, event->mval, true, &base);
-  bArmature *arm = base->object->data;
+  bool changed = false;
+  bArmature *arm = ob->data;
 
-  if (ebone_active == NULL || !EBONE_SELECTABLE(arm, ebone_active)) {
-    return OPERATOR_CANCELLED;
-  }
+  /* Implementation note, this flood-fills selected bones with the 'TOUCH' flag,
+   * even though this is a loop-within a loop, walking up the parent chain only touches new bones.
+   * Bones that have been touched are skipped, so the complexity is OK. */
 
   enum {
     /* Bone has been walked over, it's LINK value can be read. */
@@ -320,36 +322,44 @@ static int armature_select_linked_invoke(bContext *C, wmOperator *op, const wmEv
     LINK = (1 << 1),
   };
 
-  for (EditBone *ebone = arm->edbo->first; ebone; ebone = ebone->next) {
-    ebone->temp.i = 0;
-  }
-
 #define CHECK_PARENT(ebone) \
   (((ebone)->flag & BONE_CONNECTED) && \
    ((ebone)->parent ? EBONE_SELECTABLE(arm, (ebone)->parent) : false))
 
+  for (EditBone *ebone = arm->edbo->first; ebone; ebone = ebone->next) {
+    ebone->temp.i = 0;
+  }
+
   /* Select parents. */
-  for (EditBone *ebone = ebone_active; ebone; ebone = CHECK_PARENT(ebone) ? ebone->parent : NULL) {
-    if ((ebone->flag & BONE_UNSELECTABLE) == 0) {
+  for (EditBone *ebone_iter = arm->edbo->first; ebone_iter; ebone_iter = ebone_iter->next) {
+    if (ebone_iter->temp.i & TOUCH) {
+      continue;
+    }
+    if ((ebone_iter->flag & BONE_DONE) == 0) {
+      continue;
+    }
+
+    ebone_iter->temp.i |= TOUCH | LINK;
+
+    /* We have an un-touched link. */
+    for (EditBone *ebone = ebone_iter; ebone; ebone = CHECK_PARENT(ebone) ? ebone->parent : NULL) {
       ED_armature_ebone_select_set(ebone, select);
+      changed = true;
+
       if (all_forks) {
-        ebone->temp.i = (TOUCH | LINK);
+        ebone->temp.i |= (TOUCH | LINK);
       }
       else {
-        ebone->temp.i = TOUCH;
+        ebone->temp.i |= TOUCH;
+      }
+      /* Don't walk onto links (messes up 'all_forks' logic). */
+      if (ebone->parent && ebone->parent->temp.i & LINK) {
+        break;
       }
     }
   }
 
-  if (all_forks == false) {
-    ebone_active->temp.i = LINK;
-  }
-
-  /* Select children.
-   *
-   * Implementation note, this flood-fills selected bones with the 'TOUCH' flag,
-   * even though this is a loop-within a loop, walking up the parent chain only touches new bones.
-   * Bones that have been touched are skipped, so the complexity is OK. */
+  /* Select children. */
   for (EditBone *ebone_iter = arm->edbo->first; ebone_iter; ebone_iter = ebone_iter->next) {
     /* No need to 'touch' this bone as it won't be walked over when scanning up the chain. */
     if (!CHECK_PARENT(ebone_iter)) {
@@ -374,6 +384,7 @@ static int armature_select_linked_invoke(bContext *C, wmOperator *op, const wmEv
         if ((ebone->temp.i & LINK) == 0) {
           ebone->temp.i |= LINK;
           ED_armature_ebone_select_set(ebone, select);
+          changed = true;
         }
       }
     }
@@ -381,32 +392,129 @@ static int armature_select_linked_invoke(bContext *C, wmOperator *op, const wmEv
 
 #undef CHECK_PARENT
 
-  ED_outliner_select_sync_from_edit_bone_tag(C);
+  if (changed) {
+    ED_armature_edit_sync_selection(arm->edbo);
+    DEG_id_tag_update(&arm->id, ID_RECALC_COPY_ON_WRITE);
+    WM_main_add_notifier(NC_GPENCIL | ND_DATA | NA_EDITED, ob);
+  }
 
-  ED_armature_edit_sync_selection(arm->edbo);
+  return changed;
+}
 
-  WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, base->object);
-  DEG_id_tag_update(&arm->id, ID_RECALC_COPY_ON_WRITE);
+/** \} */
 
+/* -------------------------------------------------------------------- */
+/** \name Select Linked Operator
+ * \{ */
+
+static int armature_select_linked_exec(bContext *C, wmOperator *op)
+{
+  const bool all_forks = RNA_boolean_get(op->ptr, "all_forks");
+
+  bool changed_multi = false;
+  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(
+      view_layer, CTX_wm_view3d(C), &objects_len);
+  for (uint ob_index

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list