From 3ddd2dff3723dc947e572f27dc725c471ce6d6e2 Mon Sep 17 00:00:00 2001 From: Philipp Oeser Date: Tue, 17 Jun 2025 12:05:19 +0200 Subject: [PATCH] Fix #140210: Edit Bone selection cycling wrong for active but unselected Unlike object or posemode (where items not only need to be active but also selected to be treated as a starting point for cycling through to the next item behind it on the next click), armature editmode would treat active (but unselected) bones as a starting point as well. Leading to confusion if you just clear your selection prior. For reference to the expected behavior, look at these comments in `mouse_select_eval_buffer` >/* Only exclude active object when it is selected. */ >/* When the active object is unselected or not in `buffer`, use the nearest. */ Now for editbones, the way `get_nearest_editbonepoint` works, there were actually two things preventing stuff from happening as expected: - [1] we would still get "use_cycle" behavior if we have an unselected (active) bone -> this is now checked for by looking at active bone selection flags (NOTE: tip/root needs to be looked at as well). These checks were once there, bd59781c66e1 removed them though. - [2] without "use_cycle" behavior, we are still looping all hit bones and there could be the situation where we could accept a first bone (in the `bias > bias_max` condition -- that one could be the closest already but does not set the `min_depth`), but continue to loop (now entering the "bias == bias_max && do_nearest" condition and `min_depth` could still be at INT_MAX) and accept a bone that is actually further away... That logic is from 328ec2b172e8 Both points have now been addressed. Pull Request: https://projects.blender.org/blender/blender/pulls/140348 --- source/blender/editors/armature/armature_select.cc | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/source/blender/editors/armature/armature_select.cc b/source/blender/editors/armature/armature_select.cc index c97f3fe17ef..2dbf13b0a3b 100644 --- a/source/blender/editors/armature/armature_select.cc +++ b/source/blender/editors/armature/armature_select.cc @@ -657,10 +657,14 @@ static EditBone *get_nearest_editbonepoint( result_bias.base = nullptr; result_bias.ebone = nullptr; - /* find the bone after the current active bone, so as to bump up its chances in selection. - * this way overlapping bones will cycle selection state as with objects. */ + /* Find the bone after the current (selected) active bone, so as to bump up its chances in + * selection. this way overlapping bones will cycle selection state as with objects. */ Object *obedit_orig = vc->obedit; EditBone *ebone_active_orig = static_cast(obedit_orig->data)->act_edbone; + if ((ebone_active_orig->flag & (BONE_SELECTED | BONE_ROOTSEL | BONE_TIPSEL)) == 0) { + ebone_active_orig = nullptr; + } + if (ebone_active_orig == nullptr) { use_cycle = false; } @@ -816,6 +820,7 @@ cache_end: if (bias > bias_max) { bias_max = bias; + min_depth = hit_result.depth; result_bias.select_id = select_id; result_bias.base = base; result_bias.ebone = ebone;