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:
Diffstat (limited to 'source/blender/editors/space_view3d/view3d_select.c')
-rw-r--r--source/blender/editors/space_view3d/view3d_select.c176
1 files changed, 98 insertions, 78 deletions
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");