From f647e1a5b76e6d3b14e62c6239cf4716ae90bb66 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 29 Feb 2024 17:59:21 +1100 Subject: [PATCH] Weight Paint: expose all pose mode selection tools Pose-mode selection tools (box, lasso & circle select) now support pose-mode when weight-painting. Changes to the key-map [0] caused a regression where it was no longer possible to select multiple bones because Shift-LMB is now used for painting. The report #114981 proposes to support pose selection tools in weight paint mode. Note that in [1] added the tweak tool, this completes the change by supporting other tools & fixing W-key shortcut access. Resolves #114981. [0]: 6de6d7267f3d0eb913ce08675c9d73e27b8785e4 [1]: edcac1f48b92aee693f01a9bb4d23c03870a8f29 --- .../startup/bl_ui/space_toolsystem_toolbar.py | 2 +- .../editors/space_view3d/view3d_select.cc | 72 ++++++++++++++----- 2 files changed, 54 insertions(+), 20 deletions(-) diff --git a/scripts/startup/bl_ui/space_toolsystem_toolbar.py b/scripts/startup/bl_ui/space_toolsystem_toolbar.py index b505acd4883..94b4bb5fbb1 100644 --- a/scripts/startup/bl_ui/space_toolsystem_toolbar.py +++ b/scripts/startup/bl_ui/space_toolsystem_toolbar.py @@ -1672,7 +1672,7 @@ class _defs_weight_paint: ob.data.use_paint_mask_vertex)): return VIEW3D_PT_tools_active._tools_select elif context.pose_object: - return (_defs_view3d_select.select,) + return VIEW3D_PT_tools_active._tools_select return () @staticmethod diff --git a/source/blender/editors/space_view3d/view3d_select.cc b/source/blender/editors/space_view3d/view3d_select.cc index 4aeba399246..2ab147bb96e 100644 --- a/source/blender/editors/space_view3d/view3d_select.cc +++ b/source/blender/editors/space_view3d/view3d_select.cc @@ -468,11 +468,16 @@ static bool view3d_selectable_data(bContext *C) } } else { - if ((ob->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT | OB_MODE_TEXTURE_PAINT)) && + if ((ob->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_TEXTURE_PAINT)) && !BKE_paint_select_elem_test(ob)) { return false; } + if ((ob->mode & OB_MODE_WEIGHT_PAINT) && + !(BKE_paint_select_elem_test(ob) || BKE_object_pose_armature_get_with_wpaint_check(ob))) + { + return false; + } } } @@ -610,22 +615,37 @@ static bool do_lasso_select_objects(ViewContext *vc, */ static blender::Vector do_pose_tag_select_op_prepare(ViewContext *vc) { - blender::Vector bases; - - FOREACH_BASE_IN_MODE_BEGIN ( - vc->scene, vc->view_layer, vc->v3d, OB_ARMATURE, OB_MODE_POSE, base_iter) - { - Object *ob_iter = base_iter->object; - bArmature *arm = static_cast(ob_iter->data); - LISTBASE_FOREACH (bPoseChannel *, pchan, &ob_iter->pose->chanbase) { + auto bases_tag_and_append_fn = [](blender::Vector &bases, Base *base) { + Object *ob = base->object; + bArmature *arm = static_cast(ob->data); + LISTBASE_FOREACH (bPoseChannel *, pchan, &ob->pose->chanbase) { Bone *bone = pchan->bone; bone->flag &= ~BONE_DONE; } arm->id.tag |= LIB_TAG_DOIT; - ob_iter->id.tag &= ~LIB_TAG_DOIT; - bases.append(base_iter); + ob->id.tag &= ~LIB_TAG_DOIT; + bases.append(base); + }; + + blender::Vector bases; + + /* Special case, pose + weight paint mode. */ + if (vc->obact && (vc->obact->mode & OB_MODE_WEIGHT_PAINT)) { + Object *ob_pose = BKE_object_pose_armature_get_with_wpaint_check(vc->obact); + BLI_assert(ob_pose != nullptr); /* Caller is expected to check. */ + Base *base = BKE_view_layer_base_find(vc->view_layer, ob_pose); + if (base) { + bases_tag_and_append_fn(bases, base); + } + } + else { + FOREACH_BASE_IN_MODE_BEGIN ( + vc->scene, vc->view_layer, vc->v3d, OB_ARMATURE, OB_MODE_POSE, base_iter) + { + bases_tag_and_append_fn(bases, base_iter); + } + FOREACH_BASE_IN_MODE_END; } - FOREACH_BASE_IN_MODE_END; return bases; } @@ -1374,20 +1394,23 @@ static bool view3d_lasso_select(bContext *C, else if (BKE_paint_select_vert_test(ob)) { changed_multi |= do_lasso_select_paintvert(vc, wm_userdata, mcoords, mcoords_len, sel_op); } - else if (ob && - (ob->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT | OB_MODE_TEXTURE_PAINT))) - { - /* pass */ - } else if (ob && (ob->mode & OB_MODE_PARTICLE_EDIT)) { changed_multi |= PE_lasso_select(C, mcoords, mcoords_len, sel_op) != OPERATOR_CANCELLED; } - else if (ob && (ob->mode & OB_MODE_POSE)) { + else if (ob && + ((ob->mode & OB_MODE_POSE) | ((ob->mode & OB_MODE_WEIGHT_PAINT) && + BKE_object_pose_armature_get_with_wpaint_check(ob)))) + { changed_multi |= do_lasso_select_pose(vc, mcoords, mcoords_len, sel_op); if (changed_multi) { ED_outliner_select_sync_from_pose_bone_tag(C); } } + else if (ob && + (ob->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT | OB_MODE_TEXTURE_PAINT))) + { + /* pass */ + } else { changed_multi |= do_lasso_select_objects(vc, mcoords, mcoords_len, sel_op); if (changed_multi) { @@ -4342,7 +4365,10 @@ static int view3d_box_select_exec(bContext *C, wmOperator *op) else if (vc.obact && vc.obact->mode & OB_MODE_PARTICLE_EDIT) { changed_multi = PE_box_select(C, &rect, sel_op); } - else if (vc.obact && vc.obact->mode & OB_MODE_POSE) { + else if (vc.obact && ((vc.obact->mode & OB_MODE_POSE) || + ((vc.obact->mode & OB_MODE_WEIGHT_PAINT) && + BKE_object_pose_armature_get_with_wpaint_check(vc.obact)))) + { changed_multi = do_pose_box_select(C, &vc, &rect, sel_op); if (changed_multi) { ED_outliner_select_sync_from_pose_bone_tag(C); @@ -5306,6 +5332,14 @@ static int view3d_circle_select_exec(bContext *C, wmOperator *op) else if (obact && obact->mode & OB_MODE_SCULPT) { return OPERATOR_CANCELLED; } + else if (Object *obact_pose = (obact && (obact->mode & OB_MODE_WEIGHT_PAINT)) ? + BKE_object_pose_armature_get_with_wpaint_check(obact) : + nullptr) + { + ED_view3d_viewcontext_init_object(&vc, obact_pose); + pose_circle_select(&vc, sel_op, mval, float(radius)); + ED_outliner_select_sync_from_pose_bone_tag(C); + } else { if (object_circle_select(&vc, sel_op, mval, float(radius))) { DEG_id_tag_update(&vc.scene->id, ID_RECALC_SELECT);