WIP: Select Through #105787
|
@ -889,7 +889,7 @@ class VIEW3D_HT_header(Header):
|
|||
sub.active = overlay.show_overlays
|
||||
sub.popover(panel="VIEW3D_PT_overlay", text="")
|
||||
|
||||
row = layout.row()
|
||||
row = layout.row(align=True)
|
||||
row.active = (object_mode == 'EDIT') or (shading.type in {'WIREFRAME', 'SOLID'})
|
||||
|
||||
# While exposing `shading.show_xray(_wireframe)` is correct.
|
||||
|
@ -906,6 +906,7 @@ class VIEW3D_HT_header(Header):
|
|||
icon='XRAY',
|
||||
depress=draw_depressed,
|
||||
)
|
||||
row.popover(panel="VIEW3D_PT_xray", text="")
|
||||
|
||||
row = layout.row(align=True)
|
||||
row.prop(shading, "type", text="", expand=True)
|
||||
|
@ -6068,17 +6069,7 @@ class VIEW3D_PT_shading_options(Panel):
|
|||
|
||||
row = col.row(align=True)
|
||||
|
||||
if shading.type == 'WIREFRAME':
|
||||
row.prop(shading, "show_xray_wireframe", text="")
|
||||
sub = row.row()
|
||||
sub.active = shading.show_xray_wireframe
|
||||
sub.prop(shading, "xray_alpha_wireframe", text="X-Ray")
|
||||
elif shading.type == 'SOLID':
|
||||
row.prop(shading, "show_xray", text="")
|
||||
sub = row.row()
|
||||
sub.active = shading.show_xray
|
||||
sub.prop(shading, "xray_alpha", text="X-Ray")
|
||||
# X-ray mode is off when alpha is 1.0
|
||||
if shading.type == 'SOLID':
|
||||
xray_active = shading.show_xray and shading.xray_alpha != 1
|
||||
|
||||
row = col.row(align=True)
|
||||
|
@ -6263,6 +6254,56 @@ class VIEW3D_PT_gizmo_display(Panel):
|
|||
col.prop(view, "show_gizmo_camera_dof_distance", text="Focus Distance")
|
||||
|
||||
|
||||
class VIEW3D_PT_xray(Panel):
|
||||
bl_space_type = 'VIEW_3D'
|
||||
bl_region_type = 'HEADER'
|
||||
bl_label = "X-Ray"
|
||||
bl_ui_units_x = 13
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
layout.label(text="X-Ray Settings")
|
||||
shading = VIEW3D_PT_shading.get_shading(context)
|
||||
|
||||
col = layout.column()
|
||||
row = col.row(align=True)
|
||||
if shading.type == 'WIREFRAME':
|
||||
row.prop(shading, "show_xray_wireframe", text="")
|
||||
sub = row.row()
|
||||
sub.active = shading.show_xray_wireframe
|
||||
sub.prop(shading, "xray_alpha_wireframe", text="X-Ray Wireframe")
|
||||
elif shading.type == 'SOLID':
|
||||
row.prop(shading, "show_xray", text="")
|
||||
sub = row.row()
|
||||
sub.active = shading.show_xray
|
||||
sub.prop(shading, "xray_alpha", text="X-Ray Solid")
|
||||
|
||||
|
||||
class VIEW3D_PT_select_through(Panel):
|
||||
bl_space_type = 'VIEW_3D'
|
||||
bl_region_type = 'HEADER'
|
||||
bl_parent_id = 'VIEW3D_PT_xray'
|
||||
bl_label = "Select Through"
|
||||
bl_ui_units_x = 10
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
tool_settings = context.tool_settings
|
||||
|
||||
row = layout.row()
|
||||
row.prop(tool_settings, "select_through", text="Enable")
|
||||
sub = row.row()
|
||||
sub.active = tool_settings.select_through
|
||||
sub.prop(tool_settings, "select_through_object", text="Object")
|
||||
sub.prop(tool_settings, "select_through_edit", text="Edit")
|
||||
row = layout.row()
|
||||
sub = row.row(align=True)
|
||||
sub.active = tool_settings.select_through
|
||||
sub.prop(tool_settings, "select_through_box", text="Box", toggle=True)
|
||||
sub.prop(tool_settings, "select_through_lasso", text="Lasso", toggle=True)
|
||||
sub.prop(tool_settings, "select_through_circle", text="Circle", toggle=True)
|
||||
|
||||
|
||||
class VIEW3D_PT_overlay(Panel):
|
||||
bl_space_type = 'VIEW_3D'
|
||||
bl_region_type = 'HEADER'
|
||||
|
@ -8209,6 +8250,8 @@ classes = (
|
|||
VIEW3D_PT_shading_render_pass,
|
||||
VIEW3D_PT_shading_compositor,
|
||||
VIEW3D_PT_gizmo_display,
|
||||
VIEW3D_PT_xray,
|
||||
VIEW3D_PT_select_through,
|
||||
VIEW3D_PT_overlay,
|
||||
VIEW3D_PT_overlay_guides,
|
||||
VIEW3D_PT_overlay_object,
|
||||
|
|
|
@ -373,6 +373,13 @@ static void blo_update_defaults_scene(Main *bmain, Scene *scene)
|
|||
if (idprop) {
|
||||
IDP_ClearProperty(idprop);
|
||||
}
|
||||
|
||||
/* Select through */
|
||||
ts->select_through = true;
|
||||
ts->select_through_object = true;
|
||||
ts->select_through_box = true;
|
||||
ts->select_through_lasso = true;
|
||||
ts->select_through_circle = true;
|
||||
}
|
||||
|
||||
void BLO_update_defaults_startup_blend(Main *bmain, const char *app_template)
|
||||
|
|
|
@ -562,42 +562,219 @@ static void do_lasso_tag_pose(ViewContext *vc,
|
|||
V3D_PROJ_TEST_CLIP_DEFAULT | V3D_PROJ_TEST_CLIP_CONTENT_DEFAULT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare result of 'GPU_select': 'GPUSelectResult',
|
||||
* Needed for stable sorting, so cycling through all items near the cursor behaves predictably.
|
||||
*/
|
||||
static int gpu_select_buffer_depth_id_cmp(const void *sel_a_p, const void *sel_b_p)
|
||||
{
|
||||
GPUSelectResult *a = (GPUSelectResult *)sel_a_p;
|
||||
GPUSelectResult *b = (GPUSelectResult *)sel_b_p;
|
||||
|
||||
if (a->depth < b->depth) {
|
||||
return -1;
|
||||
}
|
||||
if (a->depth > b->depth) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Depths match, sort by id. */
|
||||
uint sel_a = a->id;
|
||||
uint sel_b = b->id;
|
||||
|
||||
#ifdef __BIG_ENDIAN__
|
||||
BLI_endian_switch_uint32(&sel_a);
|
||||
BLI_endian_switch_uint32(&sel_b);
|
||||
#endif
|
||||
|
||||
if (sel_a < sel_b) {
|
||||
return -1;
|
||||
}
|
||||
if (sel_a > sel_b) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool do_lasso_select_objects(ViewContext *vc,
|
||||
const int mcoords[][2],
|
||||
const int mcoords_len,
|
||||
const eSelectOp sel_op)
|
||||
const eSelectOp sel_op,
|
||||
int circle_data[3])
|
||||
{
|
||||
View3D *v3d = vc->v3d;
|
||||
|
||||
bool changed = false;
|
||||
if (SEL_OP_USE_PRE_DESELECT(sel_op)) {
|
||||
changed |= object_deselect_all_visible(vc->scene, vc->view_layer, vc->v3d);
|
||||
int totobj = MAXPICKELEMS; /* XXX solve later */
|
||||
/* Selection buffer has bones potentially too, so we add #MAXPICKELEMS. */
|
||||
GPUSelectResult *buffer = static_cast<GPUSelectResult *>(
|
||||
MEM_mallocN((totobj + MAXPICKELEMS) * sizeof(GPUSelectResult), __func__));
|
||||
ToolSettings *ts = vc->scene->toolsettings;
|
||||
const bool select_through = circle_data == NULL ? ts->select_through && ts->select_through_object &&
|
||||
ts->select_through_lasso :
|
||||
ts->select_through && ts->select_through_object &&
|
||||
ts->select_through_circle;
|
||||
float region_co[2];
|
||||
float mval_fl[2];
|
||||
if (circle_data != NULL) {
|
||||
mval_fl[0] = circle_data[0];
|
||||
mval_fl[1] = circle_data[1];
|
||||
}
|
||||
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. */
|
||||
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,
|
||||
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);
|
||||
changed = true;
|
||||
bool changed = false;
|
||||
|
||||
if (select_through && circle_data == NULL) {
|
||||
if (SEL_OP_USE_PRE_DESELECT(sel_op)) {
|
||||
changed |= object_deselect_all_visible(vc->scene, vc->view_layer, vc->v3d);
|
||||
}
|
||||
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. */
|
||||
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,
|
||||
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);
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (changed) {
|
||||
DEG_id_tag_update(&vc->scene->id, ID_RECALC_SELECT);
|
||||
WM_main_add_notifier(NC_SCENE | ND_OB_SELECT, vc->scene);
|
||||
}
|
||||
}
|
||||
|
||||
if (changed) {
|
||||
DEG_id_tag_update(&vc->scene->id, ID_RECALC_SELECT);
|
||||
WM_main_add_notifier(NC_SCENE | ND_OB_SELECT, vc->scene);
|
||||
else {
|
||||
int hits = 0;
|
||||
rcti rect_data;
|
||||
rcti *rect = &rect_data;
|
||||
blender::Vector<Base *> bases;
|
||||
|
||||
if (circle_data != NULL) {
|
||||
int point[4][2] = {};
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
float angle = 6.28f * (i + 1) / 4;
|
||||
point[i][0] = circle_data[0] + circle_data[2] * cosf(angle);
|
||||
point[i][1] = circle_data[1] + circle_data[2] * sinf(angle);
|
||||
}
|
||||
rect->xmin = rect->xmax = point[0][0];
|
||||
rect->ymin = rect->ymax = point[0][1];
|
||||
uint a;
|
||||
for (a = 1; a < 4; a++) {
|
||||
if (point[a][0] < rect->xmin) {
|
||||
rect->xmin = point[a][0];
|
||||
}
|
||||
else if (point[a][0] > rect->xmax) {
|
||||
rect->xmax = point[a][0];
|
||||
}
|
||||
if (point[a][1] < rect->ymin) {
|
||||
rect->ymin = point[a][1];
|
||||
}
|
||||
else if (point[a][1] > rect->ymax) {
|
||||
rect->ymax = point[a][1];
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
BLI_lasso_boundbox(rect, mcoords, mcoords_len);
|
||||
}
|
||||
const eV3DSelectObjectFilter select_filter = ED_view3d_select_filter_from_mode(vc->scene,
|
||||
vc->obact);
|
||||
if (XRAY_FLAG_ENABLED(vc->v3d) || select_through) {
|
||||
hits = view3d_opengl_select(
|
||||
vc, buffer, (totobj + MAXPICKELEMS), rect, VIEW3D_SELECT_ALL, select_filter);
|
||||
}
|
||||
else {
|
||||
hits = view3d_opengl_select(
|
||||
vc, buffer, (totobj + MAXPICKELEMS), rect, VIEW3D_SELECT_PICK_NEAREST, select_filter);
|
||||
}
|
||||
BKE_view_layer_synced_ensure(vc->scene, vc->view_layer);
|
||||
LISTBASE_FOREACH (Base *, base, BKE_view_layer_object_bases_get(vc->view_layer)) {
|
||||
base->object->id.tag &= ~LIB_TAG_DOIT;
|
||||
}
|
||||
if (SEL_OP_USE_PRE_DESELECT(sel_op)) {
|
||||
changed |= object_deselect_all_visible(vc->scene, vc->view_layer, vc->v3d);
|
||||
}
|
||||
|
||||
ListBase *object_bases = BKE_view_layer_object_bases_get(vc->view_layer);
|
||||
if ((hits == -1) && !SEL_OP_USE_OUTSIDE(sel_op)) {
|
||||
goto finally;
|
||||
}
|
||||
|
||||
LISTBASE_FOREACH (Base *, base, object_bases) {
|
||||
if (BASE_SELECTABLE(v3d, base)) {
|
||||
if ((base->object->runtime.select_id & 0x0000FFFF) != 0) {
|
||||
bases.append(base);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* The draw order doesn't always match the order we populate the engine, see: T51695. */
|
||||
qsort(buffer, hits, sizeof(GPUSelectResult), gpu_select_buffer_depth_id_cmp);
|
||||
|
||||
for (const GPUSelectResult *buf_iter = buffer, *buf_end = buf_iter + hits; buf_iter < buf_end;
|
||||
buf_iter++) {
|
||||
bPoseChannel *pchan_dummy;
|
||||
Base *base = ED_armature_base_and_pchan_from_select_buffer(
|
||||
bases.data(), bases.size(), buf_iter->id, &pchan_dummy);
|
||||
if (base != nullptr) {
|
||||
base->object->id.tag |= LIB_TAG_DOIT;
|
||||
}
|
||||
}
|
||||
|
||||
for (Base *base = static_cast<Base *>(object_bases->first); base && hits; base = base->next) {
|
||||
if (BASE_SELECTABLE(v3d, base)) {
|
||||
const bool is_select = base->flag & BASE_SELECTED;
|
||||
bool is_inside = false;
|
||||
|
||||
if (circle_data == NULL) {
|
||||
is_inside = base->object->id.tag & LIB_TAG_DOIT &&
|
||||
(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);
|
||||
}
|
||||
else {
|
||||
is_inside = base->object->id.tag & LIB_TAG_DOIT ?
|
||||
(ED_view3d_project_float_global(vc->region,
|
||||
base->object->object_to_world[3],
|
||||
region_co,
|
||||
V3D_PROJ_TEST_CLIP_DEFAULT) ==
|
||||
V3D_PROJ_RET_OK) &&
|
||||
len_squared_v2v2(mval_fl, region_co) <=
|
||||
circle_data[2] * circle_data[2] :
|
||||
false;
|
||||
}
|
||||
|
||||
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);
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
finally:
|
||||
|
||||
MEM_freeN(buffer);
|
||||
|
||||
if (changed) {
|
||||
DEG_id_tag_update(&vc->scene->id, ID_RECALC_SELECT);
|
||||
WM_event_add_notifier(vc->C, NC_SCENE | ND_OB_SELECT, vc->scene);
|
||||
}
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
|
@ -826,7 +1003,7 @@ static bool do_lasso_select_mesh(ViewContext *vc,
|
|||
|
||||
GPU_matrix_set(vc->rv3d->viewmat);
|
||||
|
||||
const bool use_zbuf = !XRAY_FLAG_ENABLED(vc->v3d);
|
||||
const bool use_zbuf = !XRAY_FLAG_ENABLED(vc->v3d) && !(ts->select_through && ts->select_through_edit && ts->select_through_lasso);
|
||||
|
||||
EditSelectBuf_Cache *esel = static_cast<EditSelectBuf_Cache *>(wm_userdata->data);
|
||||
if (use_zbuf) {
|
||||
|
@ -1331,7 +1508,7 @@ static bool view3d_lasso_select(bContext *C,
|
|||
}
|
||||
}
|
||||
else {
|
||||
changed_multi |= do_lasso_select_objects(vc, mcoords, mcoords_len, sel_op);
|
||||
changed_multi |= do_lasso_select_objects(vc, mcoords, mcoords_len, sel_op, NULL);
|
||||
if (changed_multi) {
|
||||
ED_outliner_select_sync_from_object_tag(C);
|
||||
}
|
||||
|
@ -2139,40 +2316,6 @@ static int mixed_bones_object_selectbuffer_extended(ViewContext *vc,
|
|||
return hits;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare result of 'GPU_select': 'GPUSelectResult',
|
||||
* Needed for stable sorting, so cycling through all items near the cursor behaves predictably.
|
||||
*/
|
||||
static int gpu_select_buffer_depth_id_cmp(const void *sel_a_p, const void *sel_b_p)
|
||||
{
|
||||
GPUSelectResult *a = (GPUSelectResult *)sel_a_p;
|
||||
GPUSelectResult *b = (GPUSelectResult *)sel_b_p;
|
||||
|
||||
if (a->depth < b->depth) {
|
||||
return -1;
|
||||
}
|
||||
if (a->depth > b->depth) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Depths match, sort by id. */
|
||||
uint sel_a = a->id;
|
||||
uint sel_b = b->id;
|
||||
|
||||
#ifdef __BIG_ENDIAN__
|
||||
BLI_endian_switch_uint32(&sel_a);
|
||||
BLI_endian_switch_uint32(&sel_b);
|
||||
#endif
|
||||
|
||||
if (sel_a < sel_b) {
|
||||
return -1;
|
||||
}
|
||||
if (sel_a > sel_b) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* \param has_bones: When true, skip non-bone hits, also allow bases to be used
|
||||
* that are visible but not select-able,
|
||||
|
@ -3587,7 +3730,8 @@ static bool do_mesh_box_select(ViewContext *vc,
|
|||
|
||||
GPU_matrix_set(vc->rv3d->viewmat);
|
||||
|
||||
const bool use_zbuf = !XRAY_FLAG_ENABLED(vc->v3d);
|
||||
const bool use_zbuf = !XRAY_FLAG_ENABLED(vc->v3d) &&
|
||||
!(ts->select_through && ts->select_through_edit && ts->select_through_box);
|
||||
|
||||
EditSelectBuf_Cache *esel = static_cast<EditSelectBuf_Cache *>(wm_userdata->data);
|
||||
if (use_zbuf) {
|
||||
|
@ -3806,14 +3950,24 @@ static bool do_object_box_select(bContext *C, ViewContext *vc, rcti *rect, const
|
|||
{
|
||||
View3D *v3d = vc->v3d;
|
||||
int totobj = MAXPICKELEMS; /* XXX solve later */
|
||||
ToolSettings *ts = vc->scene->toolsettings;
|
||||
|
||||
/* Selection buffer has bones potentially too, so we add #MAXPICKELEMS. */
|
||||
GPUSelectResult *buffer = static_cast<GPUSelectResult *>(
|
||||
MEM_mallocN((totobj + MAXPICKELEMS) * sizeof(GPUSelectResult), __func__));
|
||||
const eV3DSelectObjectFilter select_filter = ED_view3d_select_filter_from_mode(vc->scene,
|
||||
vc->obact);
|
||||
const int hits = view3d_opengl_select(
|
||||
vc, buffer, (totobj + MAXPICKELEMS), rect, VIEW3D_SELECT_ALL, select_filter);
|
||||
|
||||
int hits = 0;
|
||||
if (XRAY_FLAG_ENABLED(vc->v3d) ||
|
||||
ts->select_through && ts->select_through_object && ts->select_through_box) {
|
||||
hits = view3d_opengl_select(
|
||||
vc, buffer, (totobj + MAXPICKELEMS), rect, VIEW3D_SELECT_ALL, select_filter);
|
||||
}
|
||||
else {
|
||||
hits = view3d_opengl_select(
|
||||
vc, buffer, (totobj + MAXPICKELEMS), rect, VIEW3D_SELECT_PICK_NEAREST, select_filter);
|
||||
}
|
||||
BKE_view_layer_synced_ensure(vc->scene, vc->view_layer);
|
||||
LISTBASE_FOREACH (Base *, base, BKE_view_layer_object_bases_get(vc->view_layer)) {
|
||||
base->object->id.tag &= ~LIB_TAG_DOIT;
|
||||
|
@ -4197,7 +4351,7 @@ static bool mesh_circle_select(ViewContext *vc,
|
|||
|
||||
view3d_userdata_circleselect_init(&data, vc, select, mval, rad);
|
||||
|
||||
const bool use_zbuf = !XRAY_FLAG_ENABLED(vc->v3d);
|
||||
const bool use_zbuf = !XRAY_FLAG_ENABLED(vc->v3d) && !(ts->select_through && ts->select_through_edit && ts->select_through_circle);
|
||||
|
||||
if (use_zbuf) {
|
||||
if (wm_userdata->data == nullptr) {
|
||||
|
@ -4908,9 +5062,14 @@ static int view3d_circle_select_exec(bContext *C, wmOperator *op)
|
|||
|
||||
const eSelectOp sel_op = ED_select_op_modal(
|
||||
static_cast<eSelectOp>(RNA_enum_get(op->ptr, "mode")), WM_gesture_is_modal_first(gesture));
|
||||
|
||||
ED_view3d_viewcontext_init(C, &vc, depsgraph);
|
||||
|
||||
ToolSettings *ts = vc.scene->toolsettings;
|
||||
bool default_select = ts->select_through && ts->select_through_object && ts->select_through_circle;
|
||||
|
||||
if (!default_select) {
|
||||
BKE_object_update_select_id(CTX_data_main(C));
|
||||
}
|
||||
Object *obact = vc.obact;
|
||||
Object *obedit = vc.obedit;
|
||||
|
||||
|
@ -4956,11 +5115,17 @@ static int view3d_circle_select_exec(bContext *C, wmOperator *op)
|
|||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
else {
|
||||
if (object_circle_select(&vc, sel_op, mval, float(radius))) {
|
||||
DEG_id_tag_update(&vc.scene->id, ID_RECALC_SELECT);
|
||||
WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, vc.scene);
|
||||
if (default_select) {
|
||||
if (object_circle_select(&vc, sel_op, mval, float(radius))) {
|
||||
DEG_id_tag_update(&vc.scene->id, ID_RECALC_SELECT);
|
||||
WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, vc.scene);
|
||||
|
||||
ED_outliner_select_sync_from_object_tag(C);
|
||||
ED_outliner_select_sync_from_object_tag(C);
|
||||
}
|
||||
}
|
||||
else {
|
||||
int circle_data[3] = {mval[0], mval[1], radius};
|
||||
do_lasso_select_objects(&vc, NULL, NULL, sel_op, circle_data);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -366,6 +366,13 @@
|
|||
/* UV painting */ \
|
||||
.uv_sculpt_settings = 0, \
|
||||
.uv_relax_method = UV_SCULPT_TOOL_RELAX_LAPLACIAN, \
|
||||
\
|
||||
/* Select through */ \
|
||||
.select_through = true, \
|
||||
.select_through_object = true, \
|
||||
.select_through_box = true, \
|
||||
.select_through_lasso = true, \
|
||||
.select_through_circle = true, \
|
||||
}
|
||||
|
||||
/* clang-format off */
|
||||
|
|
|
@ -1557,7 +1557,15 @@ typedef struct ToolSettings {
|
|||
char gpencil_v3d_align;
|
||||
/** General 2D Editor. */
|
||||
char gpencil_v2d_align;
|
||||
char _pad0[2];
|
||||
|
||||
/* Select Through */
|
||||
char select_through;
|
||||
char select_through_object;
|
||||
char select_through_edit;
|
||||
char select_through_box;
|
||||
char select_through_lasso;
|
||||
char select_through_circle;
|
||||
char _pad0[4];
|
||||
|
||||
/* Annotations. */
|
||||
/** Stroke placement settings - 3D View. */
|
||||
|
|
|
@ -3725,6 +3725,39 @@ static void rna_def_tool_settings(BlenderRNA *brna)
|
|||
RNA_def_property_ui_text(prop, "Normal Vector", "Normal Vector used to copy, add or multiply");
|
||||
RNA_def_property_ui_range(prop, -10000.0, 10000.0, 1, 3);
|
||||
|
||||
/* Select Through */
|
||||
prop = RNA_def_property(srna, "select_through", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "select_through", 0);
|
||||
RNA_def_property_ui_text(prop, "Select Through", "Select occluded objects and mesh elements with drag select");
|
||||
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL);
|
||||
|
||||
prop = RNA_def_property(srna, "select_through_object", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "select_through_object", 0);
|
||||
RNA_def_property_ui_text(prop, "Select Through Object", "Select through in object mode");
|
||||
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL);
|
||||
|
||||
prop = RNA_def_property(srna, "select_through_edit", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "select_through_edit", 0);
|
||||
RNA_def_property_ui_text(prop, "Select Through Edit", "Select through in edit mode");
|
||||
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL);
|
||||
|
||||
prop = RNA_def_property(srna, "select_through_box", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "select_through_box", 0);
|
||||
RNA_def_property_ui_text(prop, "Select Through Box", "Select occluded objects and mesh elements with box select");
|
||||
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL);
|
||||
|
||||
prop = RNA_def_property(srna, "select_through_lasso", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "select_through_lasso", 0);
|
||||
RNA_def_property_ui_text(
|
||||
prop, "Select Through Lasso", "Select occluded objects and mesh elements with lasso select");
|
||||
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL);
|
||||
|
||||
prop = RNA_def_property(srna, "select_through_circle", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "select_through_circle", 0);
|
||||
RNA_def_property_ui_text(
|
||||
prop, "Select Through Circle", "Select occluded objects and mesh elements with circle select");
|
||||
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL);
|
||||
|
||||
/* Unified Paint Settings */
|
||||
prop = RNA_def_property(srna, "unified_paint_settings", PROP_POINTER, PROP_NONE);
|
||||
RNA_def_property_flag(prop, PROP_NEVER_NULL);
|
||||
|
|
Loading…
Reference in New Issue