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:
authorHans Goudey <h.goudey@me.com>2022-10-07 07:26:44 +0300
committerHans Goudey <h.goudey@me.com>2022-10-07 07:26:44 +0300
commit2c803124d371bbbd564dd4c5051258f53b799d36 (patch)
tree2fc642f1aa96ed9464483a7a7c57cf82f7531578 /source/blender/editors/space_view3d/view3d_select.cc
parent846d8ef8568c035cd7d4e1a8168a4ba391de9119 (diff)
parentcafd204af6d9969654bdee5ae14fef220640487c (diff)
Merge branch 'master' into refactor-mesh-position-generic
Diffstat (limited to 'source/blender/editors/space_view3d/view3d_select.cc')
-rw-r--r--source/blender/editors/space_view3d/view3d_select.cc170
1 files changed, 107 insertions, 63 deletions
diff --git a/source/blender/editors/space_view3d/view3d_select.cc b/source/blender/editors/space_view3d/view3d_select.cc
index a3917e0ed44..ed7d6e74bb0 100644
--- a/source/blender/editors/space_view3d/view3d_select.cc
+++ b/source/blender/editors/space_view3d/view3d_select.cc
@@ -28,6 +28,7 @@
#include "BLI_linklist.h"
#include "BLI_listbase.h"
#include "BLI_math.h"
+#include "BLI_math_bits.h"
#include "BLI_rect.h"
#include "BLI_string.h"
#include "BLI_utildefines.h"
@@ -574,11 +575,16 @@ static bool do_lasso_select_objects(ViewContext *vc,
BKE_view_layer_synced_ensure(vc->scene, vc->view_layer);
LISTBASE_FOREACH (Base *, base, BKE_view_layer_object_bases_get(vc->view_layer)) {
if (BASE_SELECTABLE(v3d, base)) { /* Use this to avoid unnecessary lasso look-ups. */
- short region_co[2];
+ float region_co[2];
const bool is_select = base->flag & BASE_SELECTED;
- const bool is_inside =
- (ED_view3d_project_base(vc->region, base, region_co) == V3D_PROJ_RET_OK) &&
- BLI_lasso_is_point_inside(mcoords, mcoords_len, region_co[0], region_co[1], IS_CLIPPED);
+ const bool is_inside = (ED_view3d_project_base(vc->region, base, region_co) ==
+ V3D_PROJ_RET_OK) &&
+ BLI_lasso_is_point_inside(mcoords,
+ mcoords_len,
+ int(region_co[0]),
+ int(region_co[1]),
+ /* Dummy value. */
+ INT_MAX);
const int sel_op_result = ED_select_op_action_deselected(sel_op, is_select, is_inside);
if (sel_op_result != -1) {
ED_object_base_select(base, sel_op_result ? BA_SELECT : BA_DESELECT);
@@ -696,7 +702,7 @@ static bool do_lasso_select_pose(ViewContext *vc,
static void do_lasso_select_mesh__doSelectVert(void *userData,
BMVert *eve,
const float screen_co[2],
- int UNUSED(index))
+ int /*index*/)
{
LassoSelectUserData *data = static_cast<LassoSelectUserData *>(userData);
const bool is_select = BM_elem_flag_test(eve, BM_ELEM_SELECT);
@@ -775,7 +781,7 @@ static void do_lasso_select_mesh__doSelectEdge_pass1(void *user_data,
static void do_lasso_select_mesh__doSelectFace(void *userData,
BMFace *efa,
const float screen_co[2],
- int UNUSED(index))
+ int /*index*/)
{
LassoSelectUserData *data = static_cast<LassoSelectUserData *>(userData);
const bool is_select = BM_elem_flag_test(efa, BM_ELEM_SELECT);
@@ -883,7 +889,7 @@ static bool do_lasso_select_mesh(ViewContext *vc,
}
static void do_lasso_select_curve__doSelect(void *userData,
- Nurb *UNUSED(nu),
+ Nurb * /*nu*/,
BPoint *bp,
BezTriple *bezt,
int beztindex,
@@ -1442,8 +1448,8 @@ static SelMenuItemF object_mouse_select_menu_data[SEL_MENU_SIZE];
/* special (crappy) operator only for menu select */
static const EnumPropertyItem *object_select_menu_enum_itemf(bContext *C,
- PointerRNA *UNUSED(ptr),
- PropertyRNA *UNUSED(prop),
+ PointerRNA * /*ptr*/,
+ PropertyRNA * /*prop*/,
bool *r_free)
{
EnumPropertyItem *item = nullptr, item_tmp = {0};
@@ -1588,13 +1594,24 @@ static bool object_mouse_select_menu(bContext *C,
const SelectPick_Params *params,
Base **r_basact)
{
+
+ const float mval_fl[2] = {float(mval[0]), float(mval[1])};
+ /* Distance from object center to use for selection. */
+ const float dist_threshold_sq = square_f(15 * U.pixelsize);
int base_count = 0;
- bool ok;
- LinkNodePair linklist = {nullptr, nullptr};
+
+ struct BaseRefWithDepth {
+ struct BaseRefWithDepth *next, *prev;
+ Base *base;
+ /** The scale isn't defined, simply use for sorting. */
+ uint depth_id;
+ };
+ ListBase base_ref_list = {nullptr, nullptr}; /* List of #BaseRefWithDepth. */
/* handle base->object->select_id */
CTX_DATA_BEGIN (C, Base *, base, selectable_bases) {
- ok = false;
+ bool ok = false;
+ uint depth_id;
/* two selection methods, the CTRL select uses max dist of 15 */
if (buffer) {
@@ -1602,28 +1619,29 @@ static bool object_mouse_select_menu(bContext *C,
/* index was converted */
if (base->object->runtime.select_id == (buffer[a].id & ~0xFFFF0000)) {
ok = true;
+ depth_id = buffer[a].depth;
break;
}
}
}
else {
- const int dist = 15 * U.pixelsize;
- short region_co[2];
+ float region_co[2];
if (ED_view3d_project_base(vc->region, base, region_co) == V3D_PROJ_RET_OK) {
- const int delta_px[2] = {region_co[0] - mval[0], region_co[1] - mval[1]};
- if (len_manhattan_v2_int(delta_px) < dist) {
+ const float dist_test_sq = len_squared_v2v2(mval_fl, region_co);
+ if (dist_test_sq < dist_threshold_sq) {
ok = true;
+ /* Match GPU depth logic, as the float is always positive, it can be sorted as an int. */
+ depth_id = float_as_uint(dist_test_sq);
}
}
}
if (ok) {
base_count++;
- BLI_linklist_append(&linklist, base);
-
- if (base_count == SEL_MENU_SIZE) {
- break;
- }
+ BaseRefWithDepth *base_ref = MEM_new<BaseRefWithDepth>(__func__);
+ base_ref->base = base;
+ base_ref->depth_id = depth_id;
+ BLI_addtail(&base_ref_list, (void *)base_ref);
}
}
CTX_DATA_END;
@@ -1634,20 +1652,30 @@ static bool object_mouse_select_menu(bContext *C,
return false;
}
if (base_count == 1) {
- Base *base = (Base *)linklist.list->link;
- BLI_linklist_free(linklist.list, nullptr);
+ Base *base = ((BaseRefWithDepth *)base_ref_list.first)->base;
+ BLI_freelistN(&base_ref_list);
*r_basact = base;
return false;
}
+ /* Sort by depth or distance to cursor. */
+ BLI_listbase_sort(&base_ref_list, [](const void *a, const void *b) {
+ return int(static_cast<const BaseRefWithDepth *>(a)->depth_id >
+ static_cast<const BaseRefWithDepth *>(b)->depth_id);
+ });
+
+ while (base_count > SEL_MENU_SIZE) {
+ BLI_freelinkN(&base_ref_list, base_ref_list.last);
+ base_count -= 1;
+ }
+
/* UI, full in static array values that we later use in an enum function */
- LinkNode *node;
- int i;
memset(object_mouse_select_menu_data, 0, sizeof(object_mouse_select_menu_data));
- for (node = linklist.list, i = 0; node; node = node->next, i++) {
- Base *base = static_cast<Base *>(node->link);
+ int i;
+ LISTBASE_FOREACH_INDEX (BaseRefWithDepth *, base_ref, &base_ref_list, i) {
+ Base *base = base_ref->base;
Object *ob = base->object;
const char *name = ob->id.name + 2;
@@ -1665,7 +1693,7 @@ static bool object_mouse_select_menu(bContext *C,
WM_operator_name_call_ptr(C, ot, WM_OP_INVOKE_DEFAULT, &ptr, nullptr);
WM_operator_properties_free(&ptr);
- BLI_linklist_free(linklist.list, nullptr);
+ BLI_freelistN(&base_ref_list);
return true;
}
@@ -1782,8 +1810,20 @@ static bool bone_mouse_select_menu(bContext *C,
BLI_assert(buffer);
int bone_count = 0;
- LinkNodePair base_list = {nullptr, nullptr};
- LinkNodePair bone_list = {nullptr, nullptr};
+
+ struct BoneRefWithDepth {
+ struct BoneRefWithDepth *next, *prev;
+ Base *base;
+ union {
+ EditBone *ebone;
+ bPoseChannel *pchan;
+ void *bone_ptr;
+ };
+ /** The scale isn't defined, simply use for sorting. */
+ uint depth_id;
+ };
+ ListBase bone_ref_list = {nullptr, nullptr};
+
GSet *added_bones = BLI_gset_ptr_new("Bone mouse select menu");
/* Select logic taken from ed_armature_pick_bone_from_selectbuffer_impl in armature_select.c */
@@ -1815,18 +1855,16 @@ static bool bone_mouse_select_menu(bContext *C,
/* Determine what the current bone is */
if (is_editmode) {
- EditBone *ebone;
const uint hit_bone = (hitresult & ~BONESEL_ANY) >> 16;
bArmature *arm = static_cast<bArmature *>(bone_base->object->data);
- ebone = static_cast<EditBone *>(BLI_findlink(arm->edbo, hit_bone));
+ EditBone *ebone = static_cast<EditBone *>(BLI_findlink(arm->edbo, hit_bone));
if (ebone && !(ebone->flag & BONE_UNSELECTABLE)) {
bone_ptr = ebone;
}
}
else {
- bPoseChannel *pchan;
const uint hit_bone = (hitresult & ~BONESEL_ANY) >> 16;
- pchan = static_cast<bPoseChannel *>(
+ bPoseChannel *pchan = static_cast<bPoseChannel *>(
BLI_findlink(&bone_base->object->pose->chanbase, hit_bone));
if (pchan && !(pchan->bone->flag & BONE_UNSELECTABLE)) {
bone_ptr = pchan;
@@ -1842,13 +1880,13 @@ static bool bone_mouse_select_menu(bContext *C,
if (!is_duplicate_bone) {
bone_count++;
- BLI_linklist_append(&base_list, bone_base);
- BLI_linklist_append(&bone_list, bone_ptr);
- BLI_gset_insert(added_bones, bone_ptr);
+ BoneRefWithDepth *bone_ref = MEM_new<BoneRefWithDepth>(__func__);
+ bone_ref->base = bone_base;
+ bone_ref->bone_ptr = bone_ptr;
+ bone_ref->depth_id = buffer[a].depth;
+ BLI_addtail(&bone_ref_list, (void *)bone_ref);
- if (bone_count == SEL_MENU_SIZE) {
- break;
- }
+ BLI_gset_insert(added_bones, bone_ptr);
}
}
@@ -1858,31 +1896,38 @@ static bool bone_mouse_select_menu(bContext *C,
return false;
}
if (bone_count == 1) {
- BLI_linklist_free(base_list.list, nullptr);
- BLI_linklist_free(bone_list.list, nullptr);
+ BLI_freelistN(&bone_ref_list);
return false;
}
- /* UI, full in static array values that we later use in an enum function */
- LinkNode *bone_node, *base_node;
- int i;
+ /* Sort by depth or distance to cursor. */
+ BLI_listbase_sort(&bone_ref_list, [](const void *a, const void *b) {
+ return int(static_cast<const BoneRefWithDepth *>(a)->depth_id >
+ static_cast<const BoneRefWithDepth *>(b)->depth_id);
+ });
+ while (bone_count > SEL_MENU_SIZE) {
+ BLI_freelinkN(&bone_ref_list, bone_ref_list.last);
+ bone_count -= 1;
+ }
+
+ /* UI, full in static array values that we later use in an enum function */
memset(object_mouse_select_menu_data, 0, sizeof(object_mouse_select_menu_data));
- for (base_node = base_list.list, bone_node = bone_list.list, i = 0; bone_node;
- base_node = base_node->next, bone_node = bone_node->next, i++) {
+ int i;
+ LISTBASE_FOREACH_INDEX (BoneRefWithDepth *, bone_ref, &bone_ref_list, i) {
char *name;
- object_mouse_select_menu_data[i].base_ptr = static_cast<Base *>(base_node->link);
+ object_mouse_select_menu_data[i].base_ptr = bone_ref->base;
if (is_editmode) {
- EditBone *ebone = static_cast<EditBone *>(bone_node->link);
- object_mouse_select_menu_data[i].item_ptr = ebone;
+ EditBone *ebone = bone_ref->ebone;
+ object_mouse_select_menu_data[i].item_ptr = static_cast<void *>(ebone);
name = ebone->name;
}
else {
- bPoseChannel *pchan = static_cast<bPoseChannel *>(bone_node->link);
- object_mouse_select_menu_data[i].item_ptr = pchan;
+ bPoseChannel *pchan = bone_ref->pchan;
+ object_mouse_select_menu_data[i].item_ptr = static_cast<void *>(pchan);
name = pchan->name;
}
@@ -1900,8 +1945,7 @@ static bool bone_mouse_select_menu(bContext *C,
WM_operator_name_call_ptr(C, ot, WM_OP_INVOKE_DEFAULT, &ptr, nullptr);
WM_operator_properties_free(&ptr);
- BLI_linklist_free(base_list.list, nullptr);
- BLI_linklist_free(bone_list.list, nullptr);
+ BLI_freelistN(&bone_ref_list);
return true;
}
@@ -1916,7 +1960,7 @@ static bool selectbuffer_has_bones(const GPUSelectResult *buffer, const uint hit
}
/* utility function for mixed_bones_object_selectbuffer */
-static int selectbuffer_ret_hits_15(GPUSelectResult *UNUSED(buffer), const int hits15)
+static int selectbuffer_ret_hits_15(GPUSelectResult * /*buffer*/, const int hits15)
{
return hits15;
}
@@ -3260,7 +3304,7 @@ static bool do_paintface_box_select(ViewContext *vc,
}
static void do_nurbs_box_select__doSelect(void *userData,
- Nurb *UNUSED(nu),
+ Nurb * /*nu*/,
BPoint *bp,
BezTriple *bezt,
int beztindex,
@@ -3360,7 +3404,7 @@ static bool do_lattice_box_select(ViewContext *vc, rcti *rect, const eSelectOp s
static void do_mesh_box_select__doSelectVert(void *userData,
BMVert *eve,
const float screen_co[2],
- int UNUSED(index))
+ int /*index*/)
{
BoxSelectUserData *data = static_cast<BoxSelectUserData *>(userData);
const bool is_select = BM_elem_flag_test(eve, BM_ELEM_SELECT);
@@ -3427,7 +3471,7 @@ static void do_mesh_box_select__doSelectEdge_pass1(
static void do_mesh_box_select__doSelectFace(void *userData,
BMFace *efa,
const float screen_co[2],
- int UNUSED(index))
+ int /*index*/)
{
BoxSelectUserData *data = static_cast<BoxSelectUserData *>(userData);
const bool is_select = BM_elem_flag_test(efa, BM_ELEM_SELECT);
@@ -3995,7 +4039,7 @@ static void view3d_userdata_circleselect_init(CircleSelectUserData *r_data,
static void mesh_circle_doSelectVert(void *userData,
BMVert *eve,
const float screen_co[2],
- int UNUSED(index))
+ int /*index*/)
{
CircleSelectUserData *data = static_cast<CircleSelectUserData *>(userData);
@@ -4008,7 +4052,7 @@ static void mesh_circle_doSelectEdge(void *userData,
BMEdge *eed,
const float screen_co_a[2],
const float screen_co_b[2],
- int UNUSED(index))
+ int /*index*/)
{
CircleSelectUserData *data = static_cast<CircleSelectUserData *>(userData);
@@ -4020,7 +4064,7 @@ static void mesh_circle_doSelectEdge(void *userData,
static void mesh_circle_doSelectFace(void *userData,
BMFace *efa,
const float screen_co[2],
- int UNUSED(index))
+ int /*index*/)
{
CircleSelectUserData *data = static_cast<CircleSelectUserData *>(userData);
@@ -4240,11 +4284,11 @@ static bool paint_vertsel_circle_select(ViewContext *vc,
}
static void nurbscurve_circle_doSelect(void *userData,
- Nurb *UNUSED(nu),
+ Nurb * /*nu*/,
BPoint *bp,
BezTriple *bezt,
int beztindex,
- bool UNUSED(handles_visible),
+ bool /*handles_visible*/,
const float screen_co[2])
{
CircleSelectUserData *data = static_cast<CircleSelectUserData *>(userData);