diff options
author | Dalai Felinto <dfelinto@gmail.com> | 2018-11-09 19:26:58 +0300 |
---|---|---|
committer | Dalai Felinto <dfelinto@gmail.com> | 2018-11-09 21:40:43 +0300 |
commit | 221d07864128687858634aebcfb27798a494557a (patch) | |
tree | 98b2dd0bafce927616716b8a0c33f0c9ca0612e9 /source/blender/editors | |
parent | 983a928e1d481dd91c36f597e2c39daba6d0f8ad (diff) |
Multi-Objects Metaball: Selection refactor - fix pick and box selection
This is inspired/based on the code we use for armature bone selection.
Both pick selection, and box selection should be working now.
Diffstat (limited to 'source/blender/editors')
-rw-r--r-- | source/blender/editors/include/ED_mball.h | 7 | ||||
-rw-r--r-- | source/blender/editors/metaball/mball_edit.c | 148 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/view3d_select.c | 46 |
3 files changed, 140 insertions, 61 deletions
diff --git a/source/blender/editors/include/ED_mball.h b/source/blender/editors/include/ED_mball.h index 46c34d36efc..47ea3929883 100644 --- a/source/blender/editors/include/ED_mball.h +++ b/source/blender/editors/include/ED_mball.h @@ -51,4 +51,11 @@ void ED_mball_editmball_load(struct Object *obedit); /* editmball_undo.c */ void ED_mball_undosys_type(struct UndoType *ut); + +#define MBALLSEL_STIFF (1 << 29) +#define MBALLSEL_RADIUS (1 << 30) +#define MBALLSEL_ANY (MBALLSEL_STIFF | MBALLSEL_RADIUS) + +#define MBALL_NOSEL (1u << 31u) + #endif /* __ED_MBALL_H__ */ diff --git a/source/blender/editors/metaball/mball_edit.c b/source/blender/editors/metaball/mball_edit.c index 83e454c0d35..6d1ba2d3fe0 100644 --- a/source/blender/editors/metaball/mball_edit.c +++ b/source/blender/editors/metaball/mball_edit.c @@ -56,6 +56,7 @@ #include "DEG_depsgraph.h" #include "ED_mball.h" +#include "ED_object.h" #include "ED_screen.h" #include "ED_select_utils.h" #include "ED_view3d.h" @@ -676,10 +677,7 @@ void MBALL_OT_reveal_metaelems(wmOperatorType *ot) bool ED_mball_select_pick(bContext *C, const int mval[2], bool extend, bool deselect, bool toggle) { static MetaElem *startelem = NULL; - Object *obedit = CTX_data_edit_object(C); ViewContext vc; - MetaBall *mb = (MetaBall *)obedit->data; - MetaElem *ml, *ml_act = NULL; int a, hits; unsigned int buffer[MAXPICKBUF]; rcti rect; @@ -692,66 +690,116 @@ bool ED_mball_select_pick(bContext *C, const int mval[2], bool extend, bool dese &vc, buffer, MAXPICKBUF, &rect, VIEW3D_SELECT_PICK_NEAREST, VIEW3D_SELECT_FILTER_NOP); - /* does startelem exist? */ - ml = mb->editelems->first; - while (ml) { - if (ml == startelem) break; - ml = ml->next; - } - - if (ml == NULL) startelem = mb->editelems->first; + FOREACH_BASE_IN_EDIT_MODE_BEGIN (vc.view_layer, base) { + ED_view3d_viewcontext_init_object(&vc, base->object); + MetaBall *mb = (MetaBall *)base->object->data; + MetaElem *ml, *ml_act = NULL; - if (hits > 0) { - ml = startelem; + /* does startelem exist? */ + ml = mb->editelems->first; while (ml) { - for (a = 0; a < hits; a++) { - /* index converted for gl stuff */ - if (ml->selcol1 == buffer[4 * a + 3]) { - ml->flag |= MB_SCALE_RAD; - ml_act = ml; - } - if (ml->selcol2 == buffer[4 * a + 3]) { - ml->flag &= ~MB_SCALE_RAD; - ml_act = ml; - } - } - if (ml_act) break; - ml = ml->next; - if (ml == NULL) ml = mb->editelems->first; if (ml == startelem) break; + ml = ml->next; } - /* When some metaelem was found, then it is necessary to select or - * deselect it. */ - if (ml_act) { - if (extend) { - ml_act->flag |= SELECT; - } - else if (deselect) { - ml_act->flag &= ~SELECT; + if (ml == NULL) startelem = mb->editelems->first; + + if (hits > 0) { + int metaelem_id = 0; + ml = startelem; + while (ml) { + for (a = 0; a < hits; a++) { + int hitresult = buffer[(4 * a) + 3]; + if (hitresult == -1) { + continue; + } + else if (hitresult & MBALL_NOSEL) { + continue; + } + + const uint hit_object = hitresult & 0xFFFF; + if (vc.obedit->select_color != hit_object) { + continue; + } + + if (metaelem_id != (hitresult & 0xFFFF0000 & ~(MBALLSEL_ANY))) { + continue; + } + + if (hitresult & MBALLSEL_RADIUS) { + ml->flag |= MB_SCALE_RAD; + ml_act = ml; + break; + } + + if (hitresult & MBALLSEL_STIFF) { + ml->flag &= ~MB_SCALE_RAD; + ml_act = ml; + break; + } + } + + if (ml_act) break; + ml = ml->next; + if (ml == NULL) ml = mb->editelems->first; + if (ml == startelem) break; + + metaelem_id += 0x10000; } - else if (toggle) { - if (ml_act->flag & SELECT) + + /* When some metaelem was found, then it is necessary to select or + * deselect it. */ + if (ml_act) { + if (!extend && !deselect && !toggle) { + uint objects_len; + Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(vc.view_layer, &objects_len); + for (uint ob_index = 0; ob_index < objects_len; ob_index++) { + Object *ob_iter = objects[ob_index]; + + if (ob_iter == base->object) { + continue; + } + + BKE_mball_deselect_all((MetaBall *)ob_iter->data); + DEG_id_tag_update(ob_iter->data, DEG_TAG_SELECT_UPDATE); + WM_event_add_notifier(C, NC_GEOM | ND_SELECT, ob_iter->data); + } + MEM_freeN(objects); + } + + if (extend) { + ml_act->flag |= SELECT; + } + else if (deselect) { ml_act->flag &= ~SELECT; - else + } + else if (toggle) { + if (ml_act->flag & SELECT) + ml_act->flag &= ~SELECT; + else + ml_act->flag |= SELECT; + } + else { + /* Deselect all existing metaelems */ + BKE_mball_deselect_all(mb); + + /* Select only metaelem clicked on */ ml_act->flag |= SELECT; - } - else { - /* Deselect all existing metaelems */ - BKE_mball_deselect_all(mb); + } - /* Select only metaelem clicked on */ - ml_act->flag |= SELECT; - } + mb->lastelem = ml_act; - mb->lastelem = ml_act; + DEG_id_tag_update(&mb->id, DEG_TAG_SELECT_UPDATE); + WM_event_add_notifier(C, NC_GEOM | ND_SELECT, mb); - DEG_id_tag_update(&mb->id, DEG_TAG_SELECT_UPDATE); - WM_event_add_notifier(C, NC_GEOM | ND_SELECT, mb); + if (vc.view_layer->basact != base) { + ED_object_base_activate(C, base); + } - return true; + return true; + } } - } + } FOREACH_BASE_IN_EDIT_MODE_END; return false; } diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c index 230bbd11450..c421c96e530 100644 --- a/source/blender/editors/space_view3d/view3d_select.c +++ b/source/blender/editors/space_view3d/view3d_select.c @@ -2169,7 +2169,8 @@ static int do_meta_box_select( ViewContext *vc, const rcti *rect, const eSelectOp sel_op) { - MetaBall *mb = (MetaBall *)vc->obedit->data; + Object *ob = vc->obedit; + MetaBall *mb = (MetaBall *)ob->data; MetaElem *ml; int a; @@ -2184,27 +2185,50 @@ static int do_meta_box_select( BKE_mball_deselect_all(mb); } - for (ml = mb->editelems->first; ml; ml = ml->next) { - bool is_inside_1 = false; - bool is_inside_2 = false; + int metaelem_id = 0; + for (ml = mb->editelems->first; ml; ml = ml->next, metaelem_id += 0x10000) { + bool is_inside_radius = false; + bool is_inside_stiff = false; + for (a = 0; a < hits; a++) { - if (ml->selcol1 == buffer[(4 * a) + 3]) { - is_inside_1 = true; + int hitresult = buffer[(4 * a) + 3]; + + if (hitresult == -1) { + continue; + } + else if (hitresult & MBALL_NOSEL) { + continue; + } + + const uint hit_object = hitresult & 0xFFFF; + if (vc->obedit->select_color != hit_object) { + continue; + } + + if (metaelem_id != (hitresult & 0xFFFF0000 & ~(MBALLSEL_ANY))) { + continue; + } + + if (hitresult & MBALLSEL_RADIUS) { + is_inside_radius = true; break; } - if (ml->selcol2 == buffer[(4 * a) + 3]) { - is_inside_2 = true; + + if (hitresult & MBALLSEL_STIFF) { + is_inside_stiff = true; break; } } - if (is_inside_1) { + if (is_inside_radius) { ml->flag |= MB_SCALE_RAD; } - if (is_inside_2) { + if (is_inside_stiff) { ml->flag &= ~MB_SCALE_RAD; } + const bool is_select = (ml->flag & SELECT); - const bool is_inside = is_inside_1 || is_inside_2; + const bool is_inside = is_inside_radius || is_inside_stiff; + const int sel_op_result = ED_select_op_action_deselected(sel_op, is_select, is_inside); if (sel_op_result != -1) { SET_FLAG_FROM_TEST(ml->flag, sel_op_result, SELECT); |