Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <campbell@blender.org>2022-03-22 09:12:41 +0300
committerCampbell Barton <campbell@blender.org>2022-03-22 09:34:37 +0300
commit6d9de230df124732dba7774cc4c0c87836c06d46 (patch)
tree73dcce8d7ed0611d04e5e137f9acbe4b3e76583b /source/blender/editors/space_view3d/view3d_select.c
parentfa96f7381c3dddefb43a75c845444ac4d5e8fb5a (diff)
Cleanup: refactor 3D view selection picking to early exit for menus
Selecting that opens a menu is now returns early. Handling the menu selection in-line made this function more difficult to follow. Also split out selecting an object by it's center into it's own function.
Diffstat (limited to 'source/blender/editors/space_view3d/view3d_select.c')
-rw-r--r--source/blender/editors/space_view3d/view3d_select.c199
1 files changed, 118 insertions, 81 deletions
diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c
index b51adb7cb5b..84890096102 100644
--- a/source/blender/editors/space_view3d/view3d_select.c
+++ b/source/blender/editors/space_view3d/view3d_select.c
@@ -1550,12 +1550,16 @@ void VIEW3D_OT_select_menu(wmOperatorType *ot)
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
}
-static Base *object_mouse_select_menu(bContext *C,
- ViewContext *vc,
- const GPUSelectResult *buffer,
- const int hits,
- const int mval[2],
- const struct SelectPick_Params *params)
+/**
+ * \return True when a menu was activated.
+ */
+static bool object_mouse_select_menu(bContext *C,
+ ViewContext *vc,
+ const GPUSelectResult *buffer,
+ const int hits,
+ const int mval[2],
+ const struct SelectPick_Params *params,
+ Base **r_basact)
{
int base_count = 0;
bool ok;
@@ -1596,13 +1600,16 @@ static Base *object_mouse_select_menu(bContext *C,
}
CTX_DATA_END;
+ *r_basact = NULL;
+
if (base_count == 0) {
- return NULL;
+ return false;
}
if (base_count == 1) {
Base *base = (Base *)linklist.list->link;
BLI_linklist_free(linklist.list, NULL);
- return base;
+ *r_basact = base;
+ return false;
}
/* UI, full in static array values that we later use in an enum function */
@@ -1631,7 +1638,7 @@ static Base *object_mouse_select_menu(bContext *C,
WM_operator_properties_free(&ptr);
BLI_linklist_free(linklist.list, NULL);
- return NULL;
+ return true;
}
static int bone_select_menu_exec(bContext *C, wmOperator *op)
@@ -1735,6 +1742,10 @@ void VIEW3D_OT_bone_select_menu(wmOperatorType *ot)
prop = RNA_def_boolean(ot->srna, "toggle", 0, "Toggle", "");
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
}
+
+/**
+ * \return True when a menu was activated.
+ */
static bool bone_mouse_select_menu(bContext *C,
const GPUSelectResult *buffer,
const int hits,
@@ -2189,6 +2200,49 @@ static Base *mouse_select_eval_buffer(ViewContext *vc,
return basact;
}
+static Base *mouse_select_object_center(ViewContext *vc, Base *startbase, const int mval[2])
+{
+ ARegion *region = vc->region;
+ ViewLayer *view_layer = vc->view_layer;
+ View3D *v3d = vc->v3d;
+
+ Base *oldbasact = BASACT(view_layer);
+
+ const float mval_fl[2] = {(float)mval[0], (float)mval[1]};
+ float dist = ED_view3d_select_dist_px() * 1.3333f;
+ Base *basact = NULL;
+
+ /* Put the active object at a disadvantage to cycle through other objects. */
+ const float penalty_dist = 10.0f * UI_DPI_FAC;
+ Base *base = startbase;
+ while (base) {
+ if (BASE_SELECTABLE(v3d, base)) {
+ float screen_co[2];
+ if (ED_view3d_project_float_global(
+ region, base->object->obmat[3], screen_co, V3D_PROJ_TEST_CLIP_DEFAULT) ==
+ V3D_PROJ_RET_OK) {
+ float dist_test = len_manhattan_v2v2(mval_fl, screen_co);
+ if (base == oldbasact) {
+ dist_test += penalty_dist;
+ }
+ if (dist_test < dist) {
+ dist = dist_test;
+ basact = base;
+ }
+ }
+ }
+ base = base->next;
+
+ if (base == NULL) {
+ base = FIRSTBASE(view_layer);
+ }
+ if (base == startbase) {
+ break;
+ }
+ }
+ return basact;
+}
+
static Base *ed_view3d_give_base_under_cursor_ex(bContext *C,
const int mval[2],
int *r_material_slot)
@@ -2377,17 +2431,14 @@ static bool ed_object_select_pick(bContext *C,
/* Setup view context for argument to callbacks. */
ED_view3d_viewcontext_init(C, &vc, depsgraph);
- const ARegion *region = CTX_wm_region(C);
Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
View3D *v3d = CTX_wm_view3d(C);
/* Don't set when the context has no active object (hidden), see: T60807. */
const Base *oldbasact = vc.obact ? BASACT(view_layer) : NULL;
- Base *base, *startbase = NULL, *basact = NULL;
+ Base *startbase = NULL, *basact = NULL, *basact_override = NULL;
const eObjectMode object_mode = oldbasact ? oldbasact->object->mode : OB_MODE_OBJECT;
const bool is_obedit = (vc.obedit != NULL);
- float dist = ED_view3d_select_dist_px() * 1.3333f;
- const float mval_fl[2] = {(float)mval[0], (float)mval[1]};
/* Handle setting the new base active */
bool use_activate_selected_base = false;
@@ -2410,87 +2461,73 @@ static bool ed_object_select_pick(bContext *C,
startbase = oldbasact->next;
}
- /* This block uses the control key to make the object selected
- * by its center point rather than its contents */
-
- /* In edit-mode do not activate. */
- if (obcenter) {
-
- /* NOTE: shift+alt goes to group-flush-selecting. */
- if (enumerate) {
- basact = object_mouse_select_menu(C, &vc, NULL, 0, mval, params);
- }
- else {
- /* Put the active object at a disadvantage to cycle through other objects. */
- const float penalty_dist = 10.0f * U.dpi_fac;
- base = startbase;
- while (base) {
- if (BASE_SELECTABLE(v3d, base)) {
- float screen_co[2];
- if (ED_view3d_project_float_global(
- region, base->object->obmat[3], screen_co, V3D_PROJ_TEST_CLIP_DEFAULT) ==
- V3D_PROJ_RET_OK) {
- float dist_test = len_manhattan_v2v2(mval_fl, screen_co);
- if (base == oldbasact) {
- dist_test += penalty_dist;
- }
- if (dist_test < dist) {
- dist = dist_test;
- basact = base;
- }
- }
- }
- base = base->next;
-
- if (base == NULL) {
- base = FIRSTBASE(view_layer);
- }
- if (base == startbase) {
- break;
- }
- }
- }
- }
- else {
- GPUSelectResult buffer[MAXPICKELEMS];
- bool do_nearest;
-
- // TIMEIT_START(select_time);
+ GPUSelectResult buffer[MAXPICKELEMS];
+ int hits = 0;
+ bool do_nearest = false;
+ bool has_bones = false;
- /* if objects have pose-mode set, the bones are in the same selection buffer */
+ if (obcenter == false) {
+ /* If objects have pose-mode set, the bones are in the same selection buffer. */
const eV3DSelectObjectFilter select_filter = ((object == false) ?
ED_view3d_select_filter_from_mode(scene,
vc.obact) :
VIEW3D_SELECT_FILTER_NOP);
- const int hits = mixed_bones_object_selectbuffer_extended(
+ hits = mixed_bones_object_selectbuffer_extended(
&vc, buffer, ARRAY_SIZE(buffer), mval, select_filter, true, enumerate, &do_nearest);
+ has_bones = (object && hits > 0) ? false : selectbuffer_has_bones(buffer, hits);
+ }
- // TIMEIT_END(select_time);
-
- const bool has_bones = (object && hits > 0) ? false : selectbuffer_has_bones(buffer, hits);
-
- if (hits > 0) {
- /* NOTE: bundles are handling in the same way as bones. */
-
- /* NOTE: shift+alt goes to group-flush-selecting. */
- if (enumerate) {
+ /* First handle menu selection, early exit when a menu was opened.
+ * Otherwise fall through to regular selection. */
+ if (enumerate) {
+ bool has_menu = false;
+ if (obcenter) {
+ if (object_mouse_select_menu(C, &vc, NULL, 0, mval, params, &basact_override)) {
+ has_menu = true;
+ }
+ }
+ else {
+ if (hits != 0) {
if (has_bones && bone_mouse_select_menu(C, buffer, hits, false, params)) {
- handled = true;
+ has_menu = true;
}
- else {
- basact = object_mouse_select_menu(C, &vc, buffer, hits, mval, params);
+ else if (object_mouse_select_menu(C, &vc, buffer, hits, mval, params, &basact_override)) {
+ has_menu = true;
}
}
- else {
- basact = mouse_select_eval_buffer(
- &vc, buffer, hits, startbase, has_bones, do_nearest, NULL);
- }
}
- if ((handled == false) &&
- (((hits > 0) && has_bones) ||
- /* Special case, even when there are no hits, pose logic may de-select all bones. */
- ((hits == 0) && is_pose_mode))) {
+ /* Let the menu handle any further actions. */
+ if (has_menu) {
+ return false;
+ }
+ }
+
+ /* This block uses the control key to make the object selected
+ * by its center point rather than its contents */
+
+ /* In edit-mode do not activate. */
+ if (obcenter) {
+ if (basact_override) {
+ basact = basact_override;
+ }
+ else {
+ basact = mouse_select_object_center(&vc, startbase, mval);
+ }
+ }
+ else {
+ if (basact_override) {
+ basact = basact_override;
+ }
+ else {
+ basact = (hits > 0) ? mouse_select_eval_buffer(
+ &vc, buffer, hits, startbase, has_bones, do_nearest, NULL) :
+ NULL;
+ }
+
+ if (((hits > 0) && has_bones) ||
+ /* Special case, even when there are no hits, pose logic may de-select all bones. */
+ ((hits == 0) && is_pose_mode)) {
if (basact && (has_bones && (basact->object->type == OB_CAMERA))) {
MovieClip *clip = BKE_object_movieclip_get(scene, basact->object, false);