Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <campbell@blender.org>2022-03-15 13:03:04 +0300
committerCampbell Barton <campbell@blender.org>2022-03-16 06:48:25 +0300
commit5e5285baf621a0c225cb5fc06fcec6ffed8302d7 (patch)
treefcdc655a6b063d32a7630b648e126c20ade295f2 /source/blender/editors/armature/pose_select.c
parent9a763d24f2b50ad38d22cad0a23d7344afe5f1c7 (diff)
View 3D: move picking arguments into a struct & minor refactor
- Add SelectPick_Params struct to make picking logic more straightforward and easier to extend. - Use `eSelectOp` instead of booleans (extend, deselect, toggle) which were used to represent 4 states (which wasn't obvious). - Handle deselect_all when pocking instead of view3d_select_exec, de-duplicate de-selection which was already needed in when replacing the selection in picking functions. - Handle outliner update & notifiers in the picking functions instead of view3d_select_exec. - Fix particle select deselect_all option which did nothing.
Diffstat (limited to 'source/blender/editors/armature/pose_select.c')
-rw-r--r--source/blender/editors/armature/pose_select.c166
1 files changed, 89 insertions, 77 deletions
diff --git a/source/blender/editors/armature/pose_select.c b/source/blender/editors/armature/pose_select.c
index 12238280b06..1cf56389580 100644
--- a/source/blender/editors/armature/pose_select.c
+++ b/source/blender/editors/armature/pose_select.c
@@ -121,104 +121,120 @@ void ED_pose_bone_select(Object *ob, bPoseChannel *pchan, bool select)
}
}
-void ED_armature_pose_select_pick_bone(ViewLayer *view_layer,
+bool ED_armature_pose_select_pick_bone(ViewLayer *view_layer,
View3D *v3d,
Object *ob,
Bone *bone,
- const bool extend,
- const bool deselect,
- const bool toggle)
+ const struct SelectPick_Params *params)
{
- 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;
+ bool found = false;
+ bool changed = false;
- /* Since we do unified select, we don't shift+select a bone if the
- * armature object was not active yet.
- * NOTE(campbell): 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. */
- 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 (ob || ob->pose) {
+ if (bone && ((bone->flag & BONE_UNSELECTABLE) == 0)) {
+ found = true;
}
}
- if (!extend && !deselect && !toggle) {
- {
- /* Don't use 'BKE_object_pose_base_array_get_unique'
- * because we may be selecting from object mode. */
- FOREACH_VISIBLE_BASE_BEGIN (view_layer, v3d, base_iter) {
- Object *ob_iter = base_iter->object;
- if ((ob_iter->type == OB_ARMATURE) && (ob_iter->mode & OB_MODE_POSE)) {
- if (ED_pose_deselect_all(ob_iter, SEL_DESELECT, true)) {
- ED_pose_bone_select_tag_update(ob_iter);
- }
+ if ((params->sel_op == SEL_OP_SET) && (found || params->deselect_all)) {
+ /* Don't use 'BKE_object_pose_base_array_get_unique'
+ * because we may be selecting from object mode. */
+ FOREACH_VISIBLE_BASE_BEGIN (view_layer, v3d, base_iter) {
+ Object *ob_iter = base_iter->object;
+ if ((ob_iter->type == OB_ARMATURE) && (ob_iter->mode & OB_MODE_POSE)) {
+ if (ED_pose_deselect_all(ob_iter, SEL_DESELECT, true)) {
+ ED_pose_bone_select_tag_update(ob_iter);
}
}
- FOREACH_VISIBLE_BASE_END;
}
- bone->flag |= (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
- arm->act_bone = bone;
+ FOREACH_VISIBLE_BASE_END;
+ changed = true;
}
- else {
- if (extend) {
- bone->flag |= (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
- arm->act_bone = bone;
- }
- else if (deselect) {
- bone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
+
+ if (found) {
+ 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. */
+ 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(campbell): 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. */
+ 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 (params->sel_op == SEL_OP_SET) {
+ /* Re-select the bone again later in this function. */
+ bone->flag &= ~BONE_SELECTED;
+ }
}
- else if (toggle) {
- if (bone->flag & BONE_SELECTED) {
- /* If not active, we make it active. */
- if (bone != arm->act_bone) {
- arm->act_bone = bone;
+
+ switch (params->sel_op) {
+ case SEL_OP_ADD: {
+ bone->flag |= (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
+ arm->act_bone = bone;
+ break;
+ }
+ case SEL_OP_SUB: {
+ bone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
+ break;
+ }
+ case SEL_OP_XOR: {
+ if (bone->flag & BONE_SELECTED) {
+ /* If not active, we make it active. */
+ if (bone != arm->act_bone) {
+ arm->act_bone = bone;
+ }
+ else {
+ bone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
+ }
}
else {
- bone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
+ bone->flag |= (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
+ arm->act_bone = bone;
}
+ break;
}
- else {
+ case SEL_OP_SET: {
bone->flag |= (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
arm->act_bone = bone;
+ break;
+ }
+ case SEL_OP_AND: {
+ BLI_assert_unreachable(); /* Doesn't make sense for picking. */
+ break;
}
}
- }
- if (ob_act) {
- /* In weightpaint we select the associated vertex group too. */
- if (ob_act->mode & OB_MODE_ALL_WEIGHT_PAINT) {
- if (bone == arm->act_bone) {
- ED_vgroup_select_by_name(ob_act, bone->name);
- DEG_id_tag_update(&ob_act->id, ID_RECALC_GEOMETRY);
+ if (ob_act) {
+ /* In weightpaint we select the associated vertex group too. */
+ if (ob_act->mode & OB_MODE_ALL_WEIGHT_PAINT) {
+ if (bone == arm->act_bone) {
+ ED_vgroup_select_by_name(ob_act, bone->name);
+ DEG_id_tag_update(&ob_act->id, ID_RECALC_GEOMETRY);
+ }
}
- }
- /* If there are some dependencies for visualizing armature state
- * (e.g. Mask Modifier in 'Armature' mode), force update.
- */
- else if (arm->flag & ARM_HAS_VIZ_DEPS) {
- /* NOTE: ob not ob_act here is intentional - it's the source of the
- * bones being selected [T37247]
+ /* If there are some dependencies for visualizing armature state
+ * (e.g. Mask Modifier in 'Armature' mode), force update.
*/
- DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
+ else if (arm->flag & ARM_HAS_VIZ_DEPS) {
+ /* NOTE: ob not ob_act here is intentional - it's the source of the
+ * bones being selected [T37247]
+ */
+ DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
+ }
+
+ /* Tag armature for copy-on-write update (since act_bone is in armature not object). */
+ DEG_id_tag_update(&arm->id, ID_RECALC_COPY_ON_WRITE);
}
- /* Tag armature for copy-on-write update (since act_bone is in armature not object). */
- DEG_id_tag_update(&arm->id, ID_RECALC_COPY_ON_WRITE);
+ changed = true;
}
+
+ return changed || found;
}
bool ED_armature_pose_select_pick_with_buffer(ViewLayer *view_layer,
@@ -226,9 +242,7 @@ bool ED_armature_pose_select_pick_with_buffer(ViewLayer *view_layer,
Base *base,
const struct GPUSelectResult *buffer,
const short hits,
- bool extend,
- bool deselect,
- bool toggle,
+ const struct SelectPick_Params *params,
bool do_nearest)
{
Object *ob = base->object;
@@ -243,9 +257,7 @@ bool ED_armature_pose_select_pick_with_buffer(ViewLayer *view_layer,
nearBone = ED_armature_pick_bone_from_selectbuffer(
&base, 1, buffer, hits, 1, do_nearest, &base_dummy);
- ED_armature_pose_select_pick_bone(view_layer, v3d, ob, nearBone, extend, deselect, toggle);
-
- return nearBone != NULL;
+ return ED_armature_pose_select_pick_bone(view_layer, v3d, ob, nearBone, params);
}
void ED_armature_pose_select_in_wpaint_mode(ViewLayer *view_layer, Base *base_select)