[Bf-blender-cvs] [5e77ff79ccd] master: Add ability to get a selection list of bones

Sebastian Parborg noreply at git.blender.org
Thu Apr 8 17:26:37 CEST 2021


Commit: 5e77ff79ccdaffb2df4d54c97f17359c017c9b85
Author: Sebastian Parborg
Date:   Thu Apr 8 17:21:01 2021 +0200
Branches: master
https://developer.blender.org/rB5e77ff79ccdaffb2df4d54c97f17359c017c9b85

Add ability to get a selection list of bones

This adds the ability to get a selection list for both edit mode bones
and pose mode bones.

To do this the selection menu list logic had to be reworked a bit.
Before it only stored the names of objects. This might work will of
objects, however as stated in the code, it might fail for linked objects
(so multiple object can have the same name in some corner cases).

For bones it is a very common occurance where you can have multiple
armature that has the same bone names. So now it also stores the object
and bone pointers for this case.

Reviewed By: Sybren

Differential Revision: http://developer.blender.org/D10570

Fix T85796

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

M	source/blender/editors/armature/armature_select.c
M	source/blender/editors/armature/pose_select.c
M	source/blender/editors/include/ED_armature.h
M	source/blender/editors/space_view3d/view3d_intern.h
M	source/blender/editors/space_view3d/view3d_ops.c
M	source/blender/editors/space_view3d/view3d_select.c

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

diff --git a/source/blender/editors/armature/armature_select.c b/source/blender/editors/armature/armature_select.c
index 226253cc063..9b598872d8b 100644
--- a/source/blender/editors/armature/armature_select.c
+++ b/source/blender/editors/armature/armature_select.c
@@ -961,131 +961,145 @@ bool ED_armature_edit_deselect_all_visible_multi(bContext *C)
 /** \name Select Cursor Pick API
  * \{ */
 
-/* context: editmode armature in view3d */
-bool ED_armature_edit_select_pick(
-    bContext *C, const int mval[2], bool extend, bool deselect, bool toggle)
+bool ED_armature_edit_select_pick_bone(bContext *C,
+                                       Base *basact,
+                                       EditBone *ebone,
+                                       const int selmask,
+                                       const bool extend,
+                                       const bool deselect,
+                                       const bool toggle)
 {
-  Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
-  ViewContext vc;
-  EditBone *nearBone = NULL;
-  int selmask;
-  Base *basact = NULL;
+  if (!ebone) {
+    return false;
+  }
 
-  ED_view3d_viewcontext_init(C, &vc, depsgraph);
-  vc.mval[0] = mval[0];
-  vc.mval[1] = mval[1];
+  ViewLayer *view_layer = CTX_data_view_layer(C);
+  View3D *v3d = CTX_wm_view3d(C);
 
-  nearBone = get_nearest_editbonepoint(&vc, true, true, &basact, &selmask);
-  if (nearBone) {
-    ED_view3d_viewcontext_init_object(&vc, basact->object);
-    bArmature *arm = vc.obedit->data;
+  BLI_assert(BKE_object_is_in_editmode(basact->object));
+  bArmature *arm = basact->object->data;
 
-    if (!EBONE_SELECTABLE(arm, nearBone)) {
-      return false;
-    }
+  if (!EBONE_SELECTABLE(arm, ebone)) {
+    return false;
+  }
 
-    if (!extend && !deselect && !toggle) {
-      uint bases_len = 0;
-      Base **bases = BKE_view_layer_array_from_bases_in_edit_mode_unique_data(
-          vc.view_layer, vc.v3d, &bases_len);
-      ED_armature_edit_deselect_all_multi_ex(bases, bases_len);
-      MEM_freeN(bases);
-    }
+  if (!extend && !deselect && !toggle) {
+    uint bases_len = 0;
+    Base **bases = BKE_view_layer_array_from_bases_in_edit_mode_unique_data(
+        view_layer, v3d, &bases_len);
+    ED_armature_edit_deselect_all_multi_ex(bases, bases_len);
+    MEM_freeN(bases);
+  }
 
-    /* by definition the non-root connected bones have no root point drawn,
-     * so a root selection needs to be delivered to the parent tip */
+  /* By definition the non-root connected bones have no root point drawn,
+   * so a root selection needs to be delivered to the parent tip. */
 
-    if (selmask & BONE_SELECTED) {
-      if (nearBone->parent && (nearBone->flag & BONE_CONNECTED)) {
-        /* click in a chain */
-        if (extend) {
-          /* select this bone */
-          nearBone->flag |= BONE_TIPSEL;
-          nearBone->parent->flag |= BONE_TIPSEL;
-        }
-        else if (deselect) {
-          /* deselect this bone */
-          nearBone->flag &= ~(BONE_TIPSEL | BONE_SELECTED);
-          /* only deselect parent tip if it is not selected */
-          if (!(nearBone->parent->flag & BONE_SELECTED)) {
-            nearBone->parent->flag &= ~BONE_TIPSEL;
-          }
+  if (selmask & BONE_SELECTED) {
+    if (ebone->parent && (ebone->flag & BONE_CONNECTED)) {
+      /* Bone is in a chain. */
+      if (extend) {
+        /* Select this bone. */
+        ebone->flag |= BONE_TIPSEL;
+        ebone->parent->flag |= BONE_TIPSEL;
+      }
+      else if (deselect) {
+        /* Deselect this bone. */
+        ebone->flag &= ~(BONE_TIPSEL | BONE_SELECTED);
+        /* Only deselect parent tip if it is not selected. */
+        if (!(ebone->parent->flag & BONE_SELECTED)) {
+          ebone->parent->flag &= ~BONE_TIPSEL;
         }
-        else if (toggle) {
-          /* hold shift inverts this bone's selection */
-          if (nearBone->flag & BONE_SELECTED) {
-            /* deselect this bone */
-            nearBone->flag &= ~(BONE_TIPSEL | BONE_SELECTED);
-            /* only deselect parent tip if it is not selected */
-            if (!(nearBone->parent->flag & BONE_SELECTED)) {
-              nearBone->parent->flag &= ~BONE_TIPSEL;
-            }
-          }
-          else {
-            /* select this bone */
-            nearBone->flag |= BONE_TIPSEL;
-            nearBone->parent->flag |= BONE_TIPSEL;
+      }
+      else if (toggle) {
+        /* Toggle inverts this bone's selection. */
+        if (ebone->flag & BONE_SELECTED) {
+          /* Deselect this bone. */
+          ebone->flag &= ~(BONE_TIPSEL | BONE_SELECTED);
+          /* Only deselect parent tip if it is not selected. */
+          if (!(ebone->parent->flag & BONE_SELECTED)) {
+            ebone->parent->flag &= ~BONE_TIPSEL;
           }
         }
         else {
-          /* select this bone */
-          nearBone->flag |= BONE_TIPSEL;
-          nearBone->parent->flag |= BONE_TIPSEL;
+          /* Select this bone. */
+          ebone->flag |= BONE_TIPSEL;
+          ebone->parent->flag |= BONE_TIPSEL;
         }
       }
       else {
-        if (extend) {
-          nearBone->flag |= (BONE_TIPSEL | BONE_ROOTSEL);
-        }
-        else if (deselect) {
-          nearBone->flag &= ~(BONE_TIPSEL | BONE_ROOTSEL);
-        }
-        else if (toggle) {
-          /* hold shift inverts this bone's selection */
-          if (nearBone->flag & BONE_SELECTED) {
-            nearBone->flag &= ~(BONE_TIPSEL | BONE_ROOTSEL);
-          }
-          else {
-            nearBone->flag |= (BONE_TIPSEL | BONE_ROOTSEL);
-          }
-        }
-        else {
-          nearBone->flag |= (BONE_TIPSEL | BONE_ROOTSEL);
-        }
+        /* Select this bone. */
+        ebone->flag |= BONE_TIPSEL;
+        ebone->parent->flag |= BONE_TIPSEL;
       }
     }
     else {
       if (extend) {
-        nearBone->flag |= selmask;
+        ebone->flag |= (BONE_TIPSEL | BONE_ROOTSEL);
       }
       else if (deselect) {
-        nearBone->flag &= ~selmask;
+        ebone->flag &= ~(BONE_TIPSEL | BONE_ROOTSEL);
       }
-      else if (toggle && (nearBone->flag & selmask)) {
-        nearBone->flag &= ~selmask;
+      else if (toggle) {
+        /* Toggle inverts this bone's selection. */
+        if (ebone->flag & BONE_SELECTED) {
+          ebone->flag &= ~(BONE_TIPSEL | BONE_ROOTSEL);
+        }
+        else {
+          ebone->flag |= (BONE_TIPSEL | BONE_ROOTSEL);
+        }
       }
       else {
-        nearBone->flag |= selmask;
+        ebone->flag |= (BONE_TIPSEL | BONE_ROOTSEL);
       }
     }
-
-    ED_armature_edit_sync_selection(arm->edbo);
-
-    /* then now check for active status */
-    if (ED_armature_ebone_selectflag_get(nearBone)) {
-      arm->act_edbone = nearBone;
+  }
+  else {
+    if (extend) {
+      ebone->flag |= selmask;
     }
-
-    if (vc.view_layer->basact != basact) {
-      ED_object_base_activate(C, basact);
+    else if (deselect) {
+      ebone->flag &= ~selmask;
+    }
+    else if (toggle && (ebone->flag & selmask)) {
+      ebone->flag &= ~selmask;
     }
+    else {
+      ebone->flag |= selmask;
+    }
+  }
 
-    WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, basact->object);
-    DEG_id_tag_update(&arm->id, ID_RECALC_COPY_ON_WRITE);
-    return true;
+  ED_armature_edit_sync_selection(arm->edbo);
+
+  /* Then now check for active status. */
+  if (ED_armature_ebone_selectflag_get(ebone)) {
+    arm->act_edbone = ebone;
+  }
+
+  if (view_layer->basact != basact) {
+    ED_object_base_activate(C, basact);
   }
 
-  return false;
+  WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, basact->object);
+  DEG_id_tag_update(&arm->id, ID_RECALC_COPY_ON_WRITE);
+  return true;
+}
+
+/* context: editmode armature in view3d */
+bool ED_armature_edit_select_pick(
+    bContext *C, const int mval[2], bool extend, bool deselect, bool toggle)
+{
+  Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
+  ViewContext vc;
+  EditBone *nearBone = NULL;
+  int selmask;
+  Base *basact = NULL;
+
+  ED_view3d_viewcontext_init(C, &vc, depsgraph);
+  vc.mval[0] = mval[0];
+  vc.mval[1] = mval[1];
+
+  nearBone = get_nearest_editbonepoint(&vc, true, true, &basact, &selmask);
+  return ED_armature_edit_select_pick_bone(C, basact, nearBone, selmask, extend, deselect, toggle);
 }
 
 /** \} */
diff --git a/source/blender/editors/armature/pose_select.c b/source/blender/editors/armature/pose_select.c
index a3f97000509..0b0f1925746 100644
--- a/source/blender/editors/armature/pose_select.c
+++ b/source/blender/editors/armature/pose_select.c
@@ -138,6 +138,106 @@ void ED_pose_bone_select(Object *ob, bPoseChannel *pchan, bool select)
   }
 }
 
+void ED_armature_pose_select_pick_bone(ViewLayer *view_layer,
+                                       View3D *v3d,
+                                       Object *ob,
+                                       Bone *bone,
+                                       const bool extend,
+                                       const bool deselect,
+                                       const bool toggle)
+{
+  if (!ob || !ob->pose) {
+    return;
+  }
+
+  Object *ob_act = OBACT(view_layer);
+  BLI_assert(OBEDIT_FROM_VIEW_LAYER(view_layer) == NULL);
+
+  /* If the bone cannot be affected, don't do anything. */
+  if (bone == NULL || (bone->flag & BONE_UNSELECTABLE)) {
+    return;
+  }
+  bArmature *arm = ob->data;
+
+  /* Since we do unified select, we don't shift+select a bone if the
+   * armature object was not active yet.
+   * Note, special exception for armature mode so we can do multi-select
+   * we could check for multi-select explicitly but think its fine to
+   * always give predictable behavior in weight paint mode - campbell */
+  if ((ob_act == NULL) || ((ob_act != ob) && (ob_act->mode & OB_MODE_ALL_WEIGHT_PAINT) == 0)) {
+    /* When we are entering into posemode via toggle-select,
+     * from another active object - always select the bone. */
+    if (!extend && !deselect && toggle) {
+      /* Re-select the bone again later in this function. */
+      bone->flag &= ~BONE_SELECTED;
+    }
+  }
+
+  if (!extend && !deselect && !toggle) {
+    {
+      /* Don't use 'B

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list