From 5e5285baf621a0c225cb5fc06fcec6ffed8302d7 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 15 Mar 2022 21:03:04 +1100 Subject: 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. --- source/blender/editors/physics/particle_edit.c | 159 ++++++++++++++----------- 1 file changed, 90 insertions(+), 69 deletions(-) (limited to 'source/blender/editors/physics/particle_edit.c') diff --git a/source/blender/editors/physics/particle_edit.c b/source/blender/editors/physics/particle_edit.c index fc815ebe682..73885ab2a78 100644 --- a/source/blender/editors/physics/particle_edit.c +++ b/source/blender/editors/physics/particle_edit.c @@ -487,6 +487,8 @@ typedef struct PEData { int select_action; int select_toggle_action; bool is_changed; + + void *user_data; } PEData; static void PE_set_data(bContext *C, PEData *data) @@ -1721,46 +1723,6 @@ static void select_keys(PEData *data, point->flag |= PEP_EDIT_RECALC; } -static void extend_key_select(PEData *data, int point_index, int key_index, bool UNUSED(is_inside)) -{ - PTCacheEdit *edit = data->edit; - PTCacheEditPoint *point = edit->points + point_index; - PTCacheEditKey *key = point->keys + key_index; - - if ((key->flag & PEK_SELECT) == 0) { - key->flag |= PEK_SELECT; - point->flag |= PEP_EDIT_RECALC; - data->is_changed = true; - } -} - -static void deselect_key_select(PEData *data, - int point_index, - int key_index, - bool UNUSED(is_inside)) -{ - PTCacheEdit *edit = data->edit; - PTCacheEditPoint *point = edit->points + point_index; - PTCacheEditKey *key = point->keys + key_index; - - if ((key->flag & PEK_SELECT) != 0) { - key->flag &= ~PEK_SELECT; - point->flag |= PEP_EDIT_RECALC; - data->is_changed = true; - } -} - -static void toggle_key_select(PEData *data, int point_index, int key_index, bool UNUSED(is_inside)) -{ - PTCacheEdit *edit = data->edit; - PTCacheEditPoint *point = edit->points + point_index; - PTCacheEditKey *key = point->keys + key_index; - - key->flag ^= PEK_SELECT; - point->flag |= PEP_EDIT_RECALC; - data->is_changed = true; -} - /** \} */ /* -------------------------------------------------------------------- */ @@ -1862,13 +1824,50 @@ void PARTICLE_OT_select_all(wmOperatorType *ot) /** \name Pick Select Operator * \{ */ -bool PE_mouse_particles(bContext *C, const int mval[2], bool extend, bool deselect, bool toggle) +struct NearestParticleData { + PTCacheEditPoint *point; + PTCacheEditKey *key; +}; + +static void nearest_key_fn(PEData *data, int point_index, int key_index, bool UNUSED(is_inside)) +{ + PTCacheEdit *edit = data->edit; + PTCacheEditPoint *point = edit->points + point_index; + PTCacheEditKey *key = point->keys + key_index; + + struct NearestParticleData *user_data = data->user_data; + user_data->point = point; + user_data->key = key; + data->is_changed = true; +} + +static bool pe_nearest_point_and_key(bContext *C, + const int mval[2], + PTCacheEditPoint **r_point, + PTCacheEditKey **r_key) +{ + struct NearestParticleData user_data = {NULL}; + + PEData data; + PE_set_view3d_data(C, &data); + data.mval = mval; + data.rad = ED_view3d_select_dist_px(); + + data.user_data = &user_data; + for_mouse_hit_keys(&data, nearest_key_fn, PSEL_NEAREST); + bool found = data.is_changed; + PE_data_free(&data); + + *r_point = user_data.point; + *r_key = user_data.key; + return found; +} + +bool PE_mouse_particles(bContext *C, const int mval[2], const struct SelectPick_Params *params) { Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C); Scene *scene = CTX_data_scene(C); Object *ob = CTX_data_active_object(C); - POINT_P; - KEY_K; PTCacheEdit *edit = PE_get_current(depsgraph, scene, ob); @@ -1876,39 +1875,61 @@ bool PE_mouse_particles(bContext *C, const int mval[2], bool extend, bool desele return false; } - if (!extend && !deselect && !toggle) { - LOOP_VISIBLE_POINTS { - LOOP_SELECTED_KEYS { - key->flag &= ~PEK_SELECT; - point->flag |= PEP_EDIT_RECALC; - } - } - } + PTCacheEditPoint *point; + PTCacheEditKey *key; - PEData data; - PE_set_view3d_data(C, &data); - data.mval = mval; - data.rad = ED_view3d_select_dist_px(); + bool changed = false; + const bool found = pe_nearest_point_and_key(C, mval, &point, &key); - /* 1 = nearest only */ - if (extend) { - for_mouse_hit_keys(&data, extend_key_select, PSEL_NEAREST); - } - else if (deselect) { - for_mouse_hit_keys(&data, deselect_key_select, PSEL_NEAREST); - } - else { - for_mouse_hit_keys(&data, toggle_key_select, PSEL_NEAREST); + if ((params->sel_op == SEL_OP_SET) && (found || params->deselect_all)) { + changed |= PE_deselect_all_visible_ex(edit); } - if (data.is_changed) { - PE_update_selection(data.depsgraph, scene, ob, 1); - WM_event_add_notifier(C, NC_OBJECT | ND_PARTICLE | NA_SELECTED, data.ob); + if (found) { + switch (params->sel_op) { + case SEL_OP_ADD: { + if ((key->flag & PEK_SELECT) == 0) { + key->flag |= PEK_SELECT; + point->flag |= PEP_EDIT_RECALC; + changed = true; + } + break; + } + case SEL_OP_SUB: { + if ((key->flag & PEK_SELECT) != 0) { + key->flag &= ~PEK_SELECT; + point->flag |= PEP_EDIT_RECALC; + changed = true; + } + break; + } + case SEL_OP_XOR: { + key->flag ^= PEK_SELECT; + point->flag |= PEP_EDIT_RECALC; + changed = true; + break; + } + case SEL_OP_SET: { + if ((key->flag & PEK_SELECT) == 0) { + key->flag |= PEK_SELECT; + point->flag |= PEP_EDIT_RECALC; + changed = true; + } + break; + } + case SEL_OP_AND: { + BLI_assert_unreachable(); /* Doesn't make sense for picking. */ + break; + } + } } - PE_data_free(&data); + if (changed) { + PE_update_selection(depsgraph, scene, ob, 1); + WM_event_add_notifier(C, NC_OBJECT | ND_PARTICLE | NA_SELECTED, ob); + } - return true; + return changed || found; } /** \} */ -- cgit v1.2.3