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:
-rw-r--r--source/blender/editors/armature/armature_select.c22
-rw-r--r--source/blender/editors/armature/pose_select.c26
-rw-r--r--source/blender/editors/curve/editcurve.c32
-rw-r--r--source/blender/editors/include/ED_select_utils.h6
-rw-r--r--source/blender/editors/lattice/editlattice_select.c31
-rw-r--r--source/blender/editors/mesh/editface.c10
-rw-r--r--source/blender/editors/mesh/editmesh_select.c29
-rw-r--r--source/blender/editors/metaball/mball_edit.c11
-rw-r--r--source/blender/editors/physics/particle_edit.c12
-rw-r--r--source/blender/editors/space_view3d/view3d_select.c176
-rw-r--r--source/blender/windowmanager/intern/wm_operator_props.c8
11 files changed, 221 insertions, 142 deletions
diff --git a/source/blender/editors/armature/armature_select.c b/source/blender/editors/armature/armature_select.c
index d1a5c128c35..08d5d6558e0 100644
--- a/source/blender/editors/armature/armature_select.c
+++ b/source/blender/editors/armature/armature_select.c
@@ -965,14 +965,20 @@ bool ED_armature_edit_select_pick_bone(bContext *C,
}
}
- if ((params->sel_op == SEL_OP_SET) && (found || params->deselect_all)) {
- /* Deselect everything. */
- uint bases_len = 0;
- Base **bases = BKE_view_layer_array_from_bases_in_edit_mode_unique_data(
- view_layer, v3d, &bases_len);
- ED_armature_edit_deselect_all_multi_ex(bases, bases_len);
- MEM_freeN(bases);
- changed = true;
+ if (params->sel_op == SEL_OP_SET) {
+ if ((found && params->select_passthrough) &&
+ (ED_armature_ebone_selectflag_get(ebone) & selmask)) {
+ found = false;
+ }
+ else if (found || params->deselect_all) {
+ /* Deselect everything. */
+ uint bases_len = 0;
+ Base **bases = BKE_view_layer_array_from_bases_in_edit_mode_unique_data(
+ view_layer, v3d, &bases_len);
+ ED_armature_edit_deselect_all_multi_ex(bases, bases_len);
+ MEM_freeN(bases);
+ changed = true;
+ }
}
if (found) {
diff --git a/source/blender/editors/armature/pose_select.c b/source/blender/editors/armature/pose_select.c
index 1cf56389580..8790a10f3e5 100644
--- a/source/blender/editors/armature/pose_select.c
+++ b/source/blender/editors/armature/pose_select.c
@@ -136,19 +136,25 @@ bool ED_armature_pose_select_pick_bone(ViewLayer *view_layer,
}
}
- if ((params->sel_op == SEL_OP_SET) && (found || params->deselect_all)) {
- /* Don't use 'BKE_object_pose_base_array_get_unique'
- * because we may be selecting from object mode. */
- FOREACH_VISIBLE_BASE_BEGIN (view_layer, v3d, base_iter) {
- Object *ob_iter = base_iter->object;
- if ((ob_iter->type == OB_ARMATURE) && (ob_iter->mode & OB_MODE_POSE)) {
- if (ED_pose_deselect_all(ob_iter, SEL_DESELECT, true)) {
- ED_pose_bone_select_tag_update(ob_iter);
+ if (params->sel_op == SEL_OP_SET) {
+ if ((found && params->select_passthrough) && (bone->flag & BONE_SELECTED)) {
+ found = false;
+ }
+ else if (found || params->deselect_all) {
+ /* Deselect everything. */
+ /* Don't use 'BKE_object_pose_base_array_get_unique'
+ * because we may be selecting from object mode. */
+ FOREACH_VISIBLE_BASE_BEGIN (view_layer, v3d, base_iter) {
+ Object *ob_iter = base_iter->object;
+ if ((ob_iter->type == OB_ARMATURE) && (ob_iter->mode & OB_MODE_POSE)) {
+ if (ED_pose_deselect_all(ob_iter, SEL_DESELECT, true)) {
+ ED_pose_bone_select_tag_update(ob_iter);
+ }
}
}
+ FOREACH_VISIBLE_BASE_END;
+ changed = true;
}
- FOREACH_VISIBLE_BASE_END;
- changed = true;
}
if (found) {
diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c
index 1c1783669c3..5ff63e767f6 100644
--- a/source/blender/editors/curve/editcurve.c
+++ b/source/blender/editors/curve/editcurve.c
@@ -4740,23 +4740,29 @@ bool ED_curve_editnurb_select_pick(bContext *C,
ED_view3d_viewcontext_init(C, &vc, depsgraph);
copy_v2_v2_int(vc.mval, mval);
- const bool found = ED_curve_pick_vert(&vc, 1, &nu, &bezt, &bp, &hand, &basact);
+ bool found = ED_curve_pick_vert(&vc, 1, &nu, &bezt, &bp, &hand, &basact);
- if ((params->sel_op == SEL_OP_SET) && (found || params->deselect_all)) {
- /* Deselect everything. */
- uint objects_len = 0;
- Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- vc.view_layer, vc.v3d, &objects_len);
- for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
- Object *ob_iter = objects[ob_index];
+ if (params->sel_op == SEL_OP_SET) {
+ if ((found && params->select_passthrough) &&
+ (((bezt ? (&bezt->f1)[hand] : bp->f1) & SELECT) != 0)) {
+ found = false;
+ }
+ else if (found || params->deselect_all) {
+ /* Deselect everything. */
+ uint objects_len = 0;
+ Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
+ vc.view_layer, vc.v3d, &objects_len);
+ for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
+ Object *ob_iter = objects[ob_index];
- ED_curve_deselect_all(((Curve *)ob_iter->data)->editnurb);
+ ED_curve_deselect_all(((Curve *)ob_iter->data)->editnurb);
- DEG_id_tag_update(ob_iter->data, ID_RECALC_SELECT | ID_RECALC_COPY_ON_WRITE);
- WM_event_add_notifier(C, NC_GEOM | ND_SELECT, ob_iter->data);
+ DEG_id_tag_update(ob_iter->data, ID_RECALC_SELECT | ID_RECALC_COPY_ON_WRITE);
+ WM_event_add_notifier(C, NC_GEOM | ND_SELECT, ob_iter->data);
+ }
+ MEM_freeN(objects);
+ changed = true;
}
- MEM_freeN(objects);
- changed = true;
}
if (found) {
diff --git a/source/blender/editors/include/ED_select_utils.h b/source/blender/editors/include/ED_select_utils.h
index c24c9168fe8..b9ef5c283aa 100644
--- a/source/blender/editors/include/ED_select_utils.h
+++ b/source/blender/editors/include/ED_select_utils.h
@@ -82,6 +82,12 @@ struct SelectPick_Params {
eSelectOp sel_op;
/** Deselect all, even when there is nothing found at the cursor location. */
bool deselect_all;
+ /**
+ * When selecting an element that is already selected, do nothing (passthrough).
+ * don't even make it active.
+ * Use to implement tweaking to move the selection without first de-selecting.
+ */
+ bool select_passthrough;
};
/**
diff --git a/source/blender/editors/lattice/editlattice_select.c b/source/blender/editors/lattice/editlattice_select.c
index bc3bca248a4..ea99c6e23ff 100644
--- a/source/blender/editors/lattice/editlattice_select.c
+++ b/source/blender/editors/lattice/editlattice_select.c
@@ -623,22 +623,27 @@ bool ED_lattice_select_pick(bContext *C, const int mval[2], const struct SelectP
vc.mval[1] = mval[1];
bp = findnearestLattvert(&vc, true, &basact);
- const bool found = (bp != NULL);
+ bool found = (bp != NULL);
- if ((params->sel_op == SEL_OP_SET) && (found || params->deselect_all)) {
- /* Deselect everything. */
- uint objects_len = 0;
- Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- vc.view_layer, vc.v3d, &objects_len);
- for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
- Object *ob = objects[ob_index];
- if (ED_lattice_flags_set(ob, 0)) {
- DEG_id_tag_update(ob->data, ID_RECALC_SELECT);
- WM_event_add_notifier(C, NC_GEOM | ND_SELECT, ob->data);
+ if (params->sel_op == SEL_OP_SET) {
+ if ((found && params->select_passthrough) && (bp->f1 & SELECT)) {
+ found = false;
+ }
+ else if (found || params->deselect_all) {
+ /* Deselect everything. */
+ uint objects_len = 0;
+ Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
+ vc.view_layer, vc.v3d, &objects_len);
+ for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
+ Object *ob = objects[ob_index];
+ if (ED_lattice_flags_set(ob, 0)) {
+ DEG_id_tag_update(ob->data, ID_RECALC_SELECT);
+ WM_event_add_notifier(C, NC_GEOM | ND_SELECT, ob->data);
+ }
}
+ MEM_freeN(objects);
+ changed = true;
}
- MEM_freeN(objects);
- changed = true;
}
if (found) {
diff --git a/source/blender/editors/mesh/editface.c b/source/blender/editors/mesh/editface.c
index 9832f7ba9cf..a5c6adaa43e 100644
--- a/source/blender/editors/mesh/editface.c
+++ b/source/blender/editors/mesh/editface.c
@@ -389,8 +389,14 @@ bool paintface_mouse_select(struct bContext *C,
}
}
- if ((params->sel_op == SEL_OP_SET) && (found || params->deselect_all)) {
- changed |= paintface_deselect_all_visible(C, ob, SEL_DESELECT, false);
+ if (params->sel_op == SEL_OP_SET) {
+ if ((found && params->select_passthrough) && (mpoly_sel->flag & ME_FACE_SEL)) {
+ found = false;
+ }
+ else if (found || params->deselect_all) {
+ /* Deselect everything. */
+ changed |= paintface_deselect_all_visible(C, ob, SEL_DESELECT, false);
+ }
}
if (found) {
diff --git a/source/blender/editors/mesh/editmesh_select.c b/source/blender/editors/mesh/editmesh_select.c
index fba6838fd99..9c8c5c45cb7 100644
--- a/source/blender/editors/mesh/editmesh_select.c
+++ b/source/blender/editors/mesh/editmesh_select.c
@@ -2034,19 +2034,24 @@ bool EDBM_select_pick(bContext *C, const int mval[2], const struct SelectPick_Pa
Base **bases = BKE_view_layer_array_from_bases_in_edit_mode(vc.view_layer, vc.v3d, &bases_len);
bool changed = false;
- const bool found = unified_findnearest(
- &vc, bases, bases_len, &base_index_active, &eve, &eed, &efa);
-
- if ((params->sel_op == SEL_OP_SET) && (found || params->deselect_all)) {
- /* Deselect everything. */
- for (uint base_index = 0; base_index < bases_len; base_index++) {
- Base *base_iter = bases[base_index];
- Object *ob_iter = base_iter->object;
- EDBM_flag_disable_all(BKE_editmesh_from_object(ob_iter), BM_ELEM_SELECT);
- DEG_id_tag_update(ob_iter->data, ID_RECALC_SELECT);
- WM_event_add_notifier(C, NC_GEOM | ND_SELECT, ob_iter->data);
+ bool found = unified_findnearest(&vc, bases, bases_len, &base_index_active, &eve, &eed, &efa);
+
+ if (params->sel_op == SEL_OP_SET) {
+ BMElem *ele = efa ? (BMElem *)efa : (eed ? (BMElem *)eed : (BMElem *)eve);
+ if ((found && params->select_passthrough) && BM_elem_flag_test(ele, BM_ELEM_SELECT)) {
+ found = false;
+ }
+ else if (found || params->deselect_all) {
+ /* Deselect everything. */
+ for (uint base_index = 0; base_index < bases_len; base_index++) {
+ Base *base_iter = bases[base_index];
+ Object *ob_iter = base_iter->object;
+ EDBM_flag_disable_all(BKE_editmesh_from_object(ob_iter), BM_ELEM_SELECT);
+ DEG_id_tag_update(ob_iter->data, ID_RECALC_SELECT);
+ WM_event_add_notifier(C, NC_GEOM | ND_SELECT, ob_iter->data);
+ }
+ changed = true;
}
- changed = true;
}
if (found) {
diff --git a/source/blender/editors/metaball/mball_edit.c b/source/blender/editors/metaball/mball_edit.c
index 55cae268e75..06a649e5b6c 100644
--- a/source/blender/editors/metaball/mball_edit.c
+++ b/source/blender/editors/metaball/mball_edit.c
@@ -854,9 +854,14 @@ bool ED_mball_select_pick(bContext *C, const int mval[2], const struct SelectPic
bool found = ed_mball_findnearest_metaelem(C, mval, true, &base, &ml, &selmask);
- if ((params->sel_op == SEL_OP_SET) && (found || params->deselect_all)) {
- /* Deselect everything. */
- changed |= ED_mball_deselect_all_multi(C);
+ if (params->sel_op == SEL_OP_SET) {
+ if ((found && params->select_passthrough) && (ml->flag & SELECT)) {
+ found = false;
+ }
+ else if (found || params->deselect_all) {
+ /* Deselect everything. */
+ changed |= ED_mball_deselect_all_multi(C);
+ }
}
if (found) {
diff --git a/source/blender/editors/physics/particle_edit.c b/source/blender/editors/physics/particle_edit.c
index 73885ab2a78..4a639e227f7 100644
--- a/source/blender/editors/physics/particle_edit.c
+++ b/source/blender/editors/physics/particle_edit.c
@@ -1879,10 +1879,16 @@ bool PE_mouse_particles(bContext *C, const int mval[2], const struct SelectPick_
PTCacheEditKey *key;
bool changed = false;
- const bool found = pe_nearest_point_and_key(C, mval, &point, &key);
+ bool found = pe_nearest_point_and_key(C, mval, &point, &key);
- if ((params->sel_op == SEL_OP_SET) && (found || params->deselect_all)) {
- changed |= PE_deselect_all_visible_ex(edit);
+ if (params->sel_op == SEL_OP_SET) {
+ if ((found && params->select_passthrough) && (key->flag & PEK_SELECT)) {
+ found = false;
+ }
+ else if (found || params->deselect_all) {
+ /* Deselect everything. */
+ changed |= PE_deselect_all_visible_ex(edit);
+ }
}
if (found) {
diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c
index 25e47f9f6b9..de078fdf78b 100644
--- a/source/blender/editors/space_view3d/view3d_select.c
+++ b/source/blender/editors/space_view3d/view3d_select.c
@@ -43,6 +43,7 @@
#include "IMB_imbuf.h"
#include "IMB_imbuf_types.h"
+#include "BKE_action.h"
#include "BKE_armature.h"
#include "BKE_context.h"
#include "BKE_curve.h"
@@ -2345,9 +2346,10 @@ static bool ed_object_select_pick(bContext *C,
// 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. */
- const bool has_bones = object ? false : selectbuffer_has_bones(buffer, hits);
/* NOTE: shift+alt goes to group-flush-selecting. */
if (enumerate) {
@@ -2362,75 +2364,86 @@ static bool ed_object_select_pick(bContext *C,
basact = mouse_select_eval_buffer(
&vc, buffer, hits, startbase, has_bones, do_nearest, NULL);
}
+ }
- if (has_bones && basact) {
- if (basact->object->type == OB_CAMERA) {
- MovieClip *clip = BKE_object_movieclip_get(scene, basact->object, false);
- if (clip != NULL && oldbasact == basact) {
- bool track_changed = false;
+ 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)) {
- for (int i = 0; i < hits; i++) {
- const int hitresult = buffer[i].id;
+ if (basact && (has_bones && (basact->object->type == OB_CAMERA))) {
+ MovieClip *clip = BKE_object_movieclip_get(scene, basact->object, false);
+ if (clip != NULL && oldbasact == basact) {
+ bool track_changed = false;
- /* if there's bundles in buffer select bundles first,
- * so non-camera elements should be ignored in buffer */
- if (basact->object->runtime.select_id != (hitresult & 0xFFFF)) {
- continue;
- }
+ for (int i = 0; i < hits; i++) {
+ const int hitresult = buffer[i].id;
+
+ /* if there's bundles in buffer select bundles first,
+ * so non-camera elements should be ignored in buffer */
+ if (basact->object->runtime.select_id != (hitresult & 0xFFFF)) {
+ continue;
+ }
- /* index of bundle is 1<<16-based. if there's no "bone" index
- * in height word, this buffer value belongs to camera. not to bundle
- */
- if (hitresult & 0xFFFF0000) {
- const bool extend = params->sel_op == SEL_OP_ADD;
- MovieTracking *tracking = &clip->tracking;
- ListBase *tracksbase;
- MovieTrackingTrack *track;
-
- track = BKE_tracking_track_get_indexed(
- &clip->tracking, hitresult >> 16, &tracksbase);
-
- if (TRACK_SELECTED(track) && extend) {
- track_changed = false;
- BKE_tracking_track_deselect(track, TRACK_AREA_ALL);
+ /* index of bundle is 1<<16-based. if there's no "bone" index
+ * in height word, this buffer value belongs to camera. not to bundle
+ */
+ if (hitresult & 0xFFFF0000) {
+ const bool extend = params->sel_op == SEL_OP_ADD;
+ MovieTracking *tracking = &clip->tracking;
+ ListBase *tracksbase;
+ MovieTrackingTrack *track;
+
+ track = BKE_tracking_track_get_indexed(
+ &clip->tracking, hitresult >> 16, &tracksbase);
+
+ if (TRACK_SELECTED(track) && extend) {
+ track_changed = false;
+ BKE_tracking_track_deselect(track, TRACK_AREA_ALL);
+ }
+ else {
+ int oldsel = TRACK_SELECTED(track) ? 1 : 0;
+ if (!extend) {
+ deselect_all_tracks(tracking);
}
- else {
- int oldsel = TRACK_SELECTED(track) ? 1 : 0;
- if (!extend) {
- deselect_all_tracks(tracking);
- }
- BKE_tracking_track_select(tracksbase, track, TRACK_AREA_ALL, extend);
+ BKE_tracking_track_select(tracksbase, track, TRACK_AREA_ALL, extend);
- if (oldsel != (TRACK_SELECTED(track) ? 1 : 0)) {
- track_changed = true;
- }
+ if (oldsel != (TRACK_SELECTED(track) ? 1 : 0)) {
+ track_changed = true;
}
+ }
- ED_object_base_select(basact, BA_SELECT);
+ ED_object_base_select(basact, BA_SELECT);
- changed = true;
+ changed = true;
- DEG_id_tag_update(&scene->id, ID_RECALC_SELECT);
- DEG_id_tag_update(&clip->id, ID_RECALC_SELECT);
- WM_event_add_notifier(C, NC_MOVIECLIP | ND_SELECT, track);
- WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
+ DEG_id_tag_update(&scene->id, ID_RECALC_SELECT);
+ DEG_id_tag_update(&clip->id, ID_RECALC_SELECT);
+ WM_event_add_notifier(C, NC_MOVIECLIP | ND_SELECT, track);
+ WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
- break;
- }
+ break;
}
+ }
- if (!track_changed) {
- /* fallback to regular object selection if no new bundles were selected,
- * allows to select object parented to reconstruction object */
- basact = mouse_select_eval_buffer(&vc, buffer, hits, startbase, 0, do_nearest, NULL);
- }
+ if (!track_changed) {
+ /* fallback to regular object selection if no new bundles were selected,
+ * allows to select object parented to reconstruction object */
+ basact = mouse_select_eval_buffer(&vc, buffer, hits, startbase, 0, do_nearest, NULL);
}
}
- else if (ED_armature_pose_select_pick_with_buffer(
- view_layer, v3d, basact, buffer, hits, params, do_nearest)) {
+ }
+ else if (ED_armature_pose_select_pick_with_buffer(view_layer,
+ v3d,
+ basact ? basact : (Base *)oldbasact,
+ buffer,
+ hits,
+ params,
+ do_nearest)) {
+ /* When there is no `baseact` this will have operated on `oldbasact`,
+ * no object operations are needed. */
+ if (basact != NULL) {
/* then bone is found */
-
/* we make the armature selected:
* not-selected active object in posemode won't work well for tools */
ED_object_base_select(basact, BA_SELECT);
@@ -2457,17 +2470,17 @@ static bool ed_object_select_pick(bContext *C,
basact = NULL;
}
}
+ }
- if (scene->toolsettings->object_flag & SCE_OBJECT_MODE_LOCK) {
- if (is_obedit == false) {
- if (basact && !BKE_object_is_mode_compat(basact->object, object_mode)) {
- if (object_mode == OB_MODE_OBJECT) {
- struct Main *bmain = CTX_data_main(C);
- ED_object_mode_generic_exit(bmain, vc.depsgraph, scene, basact->object);
- }
- if (!BKE_object_is_mode_compat(basact->object, object_mode)) {
- basact = NULL;
- }
+ if (scene->toolsettings->object_flag & SCE_OBJECT_MODE_LOCK) {
+ if (is_obedit == false) {
+ if (basact && !BKE_object_is_mode_compat(basact->object, object_mode)) {
+ if (object_mode == OB_MODE_OBJECT) {
+ struct Main *bmain = CTX_data_main(C);
+ ED_object_mode_generic_exit(bmain, vc.depsgraph, scene, basact->object);
+ }
+ if (!BKE_object_is_mode_compat(basact->object, object_mode)) {
+ basact = NULL;
}
}
}
@@ -2490,31 +2503,31 @@ static bool ed_object_select_pick(bContext *C,
/* Ensure code above doesn't change the active base. */
BLI_assert(oldbasact == (vc.obact ? BASACT(view_layer) : NULL));
+ bool found = (basact != NULL);
if (vc.obedit) {
/* Edit-mode, pass. */
}
else if (is_pose_mode && (basact == NULL || (basact->object->mode & OB_MODE_POSE))) {
/* Pose-mode, pass (or moved into pose mode). */
- if (changed == false) {
- /* Pose selection handles this but it wont run if there are no bones under the cursor. */
- const bool found = false;
- if ((params->sel_op == SEL_OP_SET) && (found || params->deselect_all)) {
- changed |= ED_pose_deselect_all_multi(C, SEL_DESELECT, false);
- }
- }
}
else {
/* Object-mode. */
- const bool found = (basact != NULL);
- if ((params->sel_op == SEL_OP_SET) && (found || params->deselect_all)) {
- /* `basact` may be NULL. */
- changed |= object_deselect_all_except(view_layer, basact);
- DEG_id_tag_update(&scene->id, ID_RECALC_SELECT);
+
+ if (params->sel_op == SEL_OP_SET) {
+ if ((found && params->select_passthrough) && (basact->flag & BASE_SELECTED)) {
+ found = false;
+ }
+ else if (found || params->deselect_all) {
+ /* Deselect everything. */
+ /* `basact` may be NULL. */
+ changed |= object_deselect_all_except(view_layer, basact);
+ DEG_id_tag_update(&scene->id, ID_RECALC_SELECT);
+ }
}
}
/* so, do we have something selected? */
- if (basact) {
+ if (found) {
changed = true;
if (vc.obedit) {
@@ -2626,8 +2639,14 @@ static bool ed_wpaint_vertex_select_pick(bContext *C,
bool found = ED_mesh_pick_vert(C, obact, mval, ED_MESH_PICK_DEFAULT_VERT_DIST, use_zbuf, &index);
- if ((params->sel_op == SEL_OP_SET) && (found || params->deselect_all)) {
- changed |= paintface_deselect_all_visible(C, obact, SEL_DESELECT, false);
+ if (params->sel_op == SEL_OP_SET) {
+ if ((found && params->select_passthrough) && (me->mvert[index].flag & SELECT)) {
+ found = false;
+ }
+ else if (found || params->deselect_all) {
+ /* Deselect everything. */
+ changed |= paintface_deselect_all_visible(C, obact, SEL_DESELECT, false);
+ }
}
if (found) {
@@ -2686,6 +2705,7 @@ static int view3d_select_exec(bContext *C, wmOperator *op)
RNA_boolean_get(op->ptr, "deselect"),
RNA_boolean_get(op->ptr, "toggle")),
.deselect_all = RNA_boolean_get(op->ptr, "deselect_all"),
+ .select_passthrough = RNA_boolean_get(op->ptr, "select_passthrough"),
};
bool center = RNA_boolean_get(op->ptr, "center");
diff --git a/source/blender/windowmanager/intern/wm_operator_props.c b/source/blender/windowmanager/intern/wm_operator_props.c
index 1c7e63749f8..dacc17c2c1e 100644
--- a/source/blender/windowmanager/intern/wm_operator_props.c
+++ b/source/blender/windowmanager/intern/wm_operator_props.c
@@ -518,6 +518,14 @@ void WM_operator_properties_mouse_select(wmOperatorType *ot)
"Deselect On Nothing",
"Deselect all when nothing under the cursor");
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+
+ /* TODO: currently only used for the 3D viewport. */
+ prop = RNA_def_boolean(ot->srna,
+ "select_passthrough",
+ false,
+ "Only Select Unselected",
+ "Ignore the select action when the element is already selected");
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
}
void WM_operator_properties_checker_interval(wmOperatorType *ot, bool nth_can_disable)