diff options
author | Campbell Barton <campbell@blender.org> | 2022-03-23 05:34:41 +0300 |
---|---|---|
committer | Campbell Barton <campbell@blender.org> | 2022-03-23 05:44:15 +0300 |
commit | 694fe9f77b90e1db1ae6a0a48d86beca56850cfc (patch) | |
tree | 660ff0f4dd79ea46800ecb031bafe2fbc498ab21 /source | |
parent | 5f350a4acd48b31838d83d55590d6840e37b01b6 (diff) |
Fix outliner/selection updates when selecting in the 3D view
The checks for calling outliner flushing didn't account for
entering pose mode for the first time or that pose-bone selection
can also change the object selection.
Resolve by recording what changed and refresh accordingly.
Also de-duplicate calls to DEG_id_tag_update.
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/editors/space_view3d/view3d_select.c | 51 |
1 files changed, 32 insertions, 19 deletions
diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c index 7bc24b75877..6f55acff6a2 100644 --- a/source/blender/editors/space_view3d/view3d_select.c +++ b/source/blender/editors/space_view3d/view3d_select.c @@ -2536,7 +2536,13 @@ static bool ed_object_select_pick(bContext *C, /* When enabled, don't attempt any further selection. */ bool handled = false; - bool changed = false; + + /* Split `changed` into data-types so their associated updates can be properly performed. + * This is also needed as multiple changes may happen at once. + * Selecting a pose-bone or track can also select the object for e.g. */ + bool changed_object = false; + bool changed_pose = false; + bool changed_track = false; /* Handle setting the new base active (even when `handled == true`). */ bool use_activate_selected_base = false; @@ -2572,9 +2578,10 @@ static bool ed_object_select_pick(bContext *C, if (ed_object_select_pick_camera_track( C, scene, basact, clip, gpu->buffer, gpu->hits, params)) { ED_object_base_select(basact, BA_SELECT); - /* Don't set `handled` here as the object activation may be necessary. */ - changed = true; + changed_object = true; + + changed_track = true; } else { /* Fallback to regular object selection if no new bundles were selected, @@ -2591,6 +2598,9 @@ static bool ed_object_select_pick(bContext *C, gpu->hits, params, gpu->do_nearest)) { + + changed_pose = true; + /* When there is no `baseact` this will have operated on `oldbasact`, * allowing #SelectPick_Params.deselect_all work in pose-mode. * In this case no object operations are needed. */ @@ -2599,10 +2609,10 @@ static bool ed_object_select_pick(bContext *C, * While leaving it unselected will work, leaving pose-mode would leave the object * active + unselected which isn't ideal when performing other actions on the object. */ ED_object_base_select(basact, BA_SELECT); + changed_object = true; WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, basact->object); WM_event_add_notifier(C, NC_OBJECT | ND_BONE_ACTIVE, basact->object); - DEG_id_tag_update(&scene->id, ID_RECALC_BASE_FLAGS); /* In weight-paint, we use selected bone to select vertex-group. * In this case the active object mustn't change as it would leave weight-paint mode. */ @@ -2683,20 +2693,22 @@ static bool ed_object_select_pick(bContext *C, else if (found || params->deselect_all) { /* Deselect everything. */ /* `basact` may be NULL. */ - changed |= object_deselect_all_except(view_layer, basact); - DEG_id_tag_update(&scene->id, ID_RECALC_SELECT); + if (object_deselect_all_except(view_layer, basact)) { + changed_object = true; + } } } } if ((handled == false) && found) { - changed = true; if (vc.obedit) { /* Only do the select (use for setting vertex parents & hooks). * In edit-mode do not activate. */ object_deselect_all_except(view_layer, basact); ED_object_base_select(basact, BA_SELECT); + + changed_object = true; } /* Also prevent making it active on mouse selection. */ else if (BASE_SELECTABLE(v3d, basact)) { @@ -2733,36 +2745,37 @@ static bool ed_object_select_pick(bContext *C, break; } } - } - DEG_id_tag_update(&scene->id, ID_RECALC_SELECT); - WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene); + changed_object = true; + } } /* Perform the activation even when 'handled', since this is used to ensure * the object from the pose-bone selected is also activated. */ if (use_activate_selected_base && (basact != NULL)) { - changed = true; + changed_object = true; ED_object_base_activate(C, basact); /* adds notifier */ if ((scene->toolsettings->object_flag & SCE_OBJECT_MODE_LOCK) == 0) { WM_toolsystem_update_from_context_view3d(C); } } - if (changed) { - if (vc.obact && vc.obact->mode & OB_MODE_POSE) { - ED_outliner_select_sync_from_pose_bone_tag(C); - } - else { - ED_outliner_select_sync_from_object_tag(C); - } + if (changed_object) { + DEG_id_tag_update(&scene->id, ID_RECALC_SELECT); + WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene); + + ED_outliner_select_sync_from_object_tag(C); + } + + if (changed_pose) { + ED_outliner_select_sync_from_pose_bone_tag(C); } if (gpu != NULL) { MEM_freeN(gpu); } - return changed; + return (changed_object || changed_pose || changed_track); } /** |