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
path: root/source
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2018-06-19 17:41:18 +0300
committerCampbell Barton <ideasman42@gmail.com>2018-06-19 17:43:01 +0300
commit750a78be9cfa71713bac5b73f9a61c40deeb994c (patch)
treeaefaf46f8869e949f5a8098b9c0625baed0082c5 /source
parent0116c95d4c9114bc9eae03401c0471fba265cd46 (diff)
3D View: improve selection locking
Locked selection would still occlude with objects which could not be selected.
Diffstat (limited to 'source')
-rw-r--r--source/blender/draw/DRW_engine.h5
-rw-r--r--source/blender/draw/intern/draw_manager.c17
-rw-r--r--source/blender/editors/armature/armature_select.c12
-rw-r--r--source/blender/editors/include/ED_view3d.h9
-rw-r--r--source/blender/editors/metaball/mball_edit.c6
-rw-r--r--source/blender/editors/space_view3d/view3d_select.c36
-rw-r--r--source/blender/editors/space_view3d/view3d_view.c31
7 files changed, 96 insertions, 20 deletions
diff --git a/source/blender/draw/DRW_engine.h b/source/blender/draw/DRW_engine.h
index 524a94e5886..d126dcb71aa 100644
--- a/source/blender/draw/DRW_engine.h
+++ b/source/blender/draw/DRW_engine.h
@@ -94,6 +94,8 @@ void DRW_notify_view_update(const DRWUpdateContext *update_ctx);
typedef enum eDRWSelectStage { DRW_SELECT_PASS_PRE = 1, DRW_SELECT_PASS_POST, } eDRWSelectStage;
typedef bool (*DRW_SelectPassFn)(
eDRWSelectStage stage, void *user_data);
+typedef bool (*DRW_ObjectFilterFn)(
+ struct Object *ob, void *user_data);
void DRW_draw_view(const struct bContext *C);
@@ -118,7 +120,8 @@ void DRW_draw_select_loop(
struct Depsgraph *depsgraph,
struct ARegion *ar, struct View3D *v3d,
bool use_obedit_skip, bool use_nearest, const struct rcti *rect,
- DRW_SelectPassFn select_pass_fn, void *select_pass_user_data);
+ DRW_SelectPassFn select_pass_fn, void *select_pass_user_data,
+ DRW_ObjectFilterFn object_filter_fn, void *object_filter_user_data);
void DRW_draw_depth_loop(
struct Depsgraph *depsgraph,
struct ARegion *ar, struct View3D *v3d);
diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c
index ef42b88fd72..fcdc4a3a016 100644
--- a/source/blender/draw/intern/draw_manager.c
+++ b/source/blender/draw/intern/draw_manager.c
@@ -1634,7 +1634,8 @@ void DRW_draw_select_loop(
struct Depsgraph *depsgraph,
ARegion *ar, View3D *v3d,
bool UNUSED(use_obedit_skip), bool UNUSED(use_nearest), const rcti *rect,
- DRW_SelectPassFn select_pass_fn, void *select_pass_user_data)
+ DRW_SelectPassFn select_pass_fn, void *select_pass_user_data,
+ DRW_ObjectFilterFn object_filter_fn, void *object_filter_user_data)
{
Scene *scene = DEG_get_evaluated_scene(depsgraph);
RenderEngineType *engine_type = ED_view3d_engine_type(scene, v3d->drawtype);
@@ -1721,6 +1722,7 @@ void DRW_draw_select_loop(
#endif
}
else {
+ bool filter_exclude = false;
DEG_OBJECT_ITER_BEGIN(
depsgraph, ob,
DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY |
@@ -1728,6 +1730,19 @@ void DRW_draw_select_loop(
DEG_ITER_OBJECT_FLAG_DUPLI)
{
if ((ob->base_flag & BASE_SELECTABLED) != 0) {
+
+ if (object_filter_fn != NULL) {
+ if (ob->base_flag & BASE_FROMDUPLI) {
+ /* pass (use previous filter_exclude value) */
+ }
+ else {
+ filter_exclude = (object_filter_fn(ob, object_filter_user_data) == false);
+ }
+ if (filter_exclude) {
+ continue;
+ }
+ }
+
/* This relies on dupli instances being after their instancing object. */
if ((ob->base_flag & BASE_FROMDUPLI) == 0) {
Object *ob_orig = DEG_get_original_object(ob);
diff --git a/source/blender/editors/armature/armature_select.c b/source/blender/editors/armature/armature_select.c
index cd5a4ced26f..e295e1fd35a 100644
--- a/source/blender/editors/armature/armature_select.c
+++ b/source/blender/editors/armature/armature_select.c
@@ -254,7 +254,9 @@ void *get_nearest_bone(
rect.xmin = rect.xmax = xy[0];
rect.ymin = rect.ymax = xy[1];
- hits = view3d_opengl_select(&vc, buffer, MAXPICKBUF, &rect, VIEW3D_SELECT_PICK_NEAREST);
+ hits = view3d_opengl_select(
+ &vc, buffer, MAXPICKBUF, &rect,
+ VIEW3D_SELECT_PICK_NEAREST, VIEW3D_SELECT_FILTER_NOP);
*r_base = NULL;
@@ -446,9 +448,11 @@ static EditBone *get_nearest_editbonepoint(
{
const int select_mode = (do_nearest ? VIEW3D_SELECT_PICK_NEAREST : VIEW3D_SELECT_PICK_ALL);
+ const eV3DSelectObjectFilter select_filter = VIEW3D_SELECT_FILTER_NOP;
+
rcti rect;
BLI_rcti_init_pt_radius(&rect, vc->mval, 12);
- const int hits12 = view3d_opengl_select(vc, buffer, MAXPICKBUF, &rect, select_mode);
+ const int hits12 = view3d_opengl_select(vc, buffer, MAXPICKBUF, &rect, select_mode, select_filter);
if (hits12 == 1) {
hits = selectbuffer_ret_hits_12(buffer, hits12);
goto cache_end;
@@ -458,7 +462,9 @@ static EditBone *get_nearest_editbonepoint(
offs = 4 * hits12;
BLI_rcti_init_pt_radius(&rect, vc->mval, 5);
- const int hits5 = view3d_opengl_select(vc, buffer + offs, MAXPICKBUF - offs, &rect, select_mode);
+ const int hits5 = view3d_opengl_select(
+ vc, buffer + offs, MAXPICKBUF - offs, &rect,
+ select_mode, select_filter);
if (hits5 == 1) {
hits = selectbuffer_ret_hits_5(buffer, hits12, hits5);
diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h
index 24e5b3e2662..343bffa0082 100644
--- a/source/blender/editors/include/ED_view3d.h
+++ b/source/blender/editors/include/ED_view3d.h
@@ -351,12 +351,19 @@ typedef enum {
VIEW3D_SELECT_PICK_NEAREST = 2,
} eV3DSelectMode;
+typedef enum {
+ /* Don't exclude anything. */
+ VIEW3D_SELECT_FILTER_NOP = 0,
+ /* Don't select objects outside the current mode. */
+ VIEW3D_SELECT_FILTER_OBJECT_MODE_LOCK = 1,
+} eV3DSelectObjectFilter;
+
void view3d_opengl_select_cache_begin(void);
void view3d_opengl_select_cache_end(void);
int view3d_opengl_select(
struct ViewContext *vc, unsigned int *buffer, unsigned int bufsize, const struct rcti *input,
- eV3DSelectMode select_mode);
+ eV3DSelectMode select_mode, eV3DSelectObjectFilter select_filter);
/* view3d_select.c */
float ED_view3d_select_dist_px(void);
diff --git a/source/blender/editors/metaball/mball_edit.c b/source/blender/editors/metaball/mball_edit.c
index aea125ce4b9..1ae122a3801 100644
--- a/source/blender/editors/metaball/mball_edit.c
+++ b/source/blender/editors/metaball/mball_edit.c
@@ -617,7 +617,9 @@ bool ED_mball_select_pick(bContext *C, const int mval[2], bool extend, bool dese
BLI_rcti_init_pt_radius(&rect, mval, 12);
- hits = view3d_opengl_select(&vc, buffer, MAXPICKBUF, &rect, VIEW3D_SELECT_PICK_NEAREST);
+ hits = view3d_opengl_select(
+ &vc, buffer, MAXPICKBUF, &rect,
+ VIEW3D_SELECT_PICK_NEAREST, VIEW3D_SELECT_FILTER_NOP);
/* does startelem exist? */
ml = mb->editelems->first;
@@ -682,5 +684,3 @@ bool ED_mball_select_pick(bContext *C, const int mval[2], bool extend, bool dese
return false;
}
-
-
diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c
index 9b40f03a54a..b4f3be178aa 100644
--- a/source/blender/editors/space_view3d/view3d_select.c
+++ b/source/blender/editors/space_view3d/view3d_select.c
@@ -1172,7 +1172,7 @@ static int selectbuffer_ret_hits_5(unsigned int *buffer, const int hits15, const
/* so check three selection levels and compare */
static int mixed_bones_object_selectbuffer(
ViewContext *vc, unsigned int *buffer, const int mval[2],
- bool use_cycle, bool enumerate,
+ bool use_cycle, bool enumerate, eV3DSelectObjectFilter select_filter,
bool *r_do_nearest)
{
rcti rect;
@@ -1211,7 +1211,7 @@ static int mixed_bones_object_selectbuffer(
view3d_opengl_select_cache_begin();
BLI_rcti_init_pt_radius(&rect, mval, 14);
- hits15 = view3d_opengl_select(vc, buffer, MAXPICKBUF, &rect, select_mode);
+ hits15 = view3d_opengl_select(vc, buffer, MAXPICKBUF, &rect, select_mode, select_filter);
if (hits15 == 1) {
hits = selectbuffer_ret_hits_15(buffer, hits15);
goto finally;
@@ -1222,7 +1222,7 @@ static int mixed_bones_object_selectbuffer(
offs = 4 * hits15;
BLI_rcti_init_pt_radius(&rect, mval, 9);
- hits9 = view3d_opengl_select(vc, buffer + offs, MAXPICKBUF - offs, &rect, select_mode);
+ hits9 = view3d_opengl_select(vc, buffer + offs, MAXPICKBUF - offs, &rect, select_mode, select_filter);
if (hits9 == 1) {
hits = selectbuffer_ret_hits_9(buffer, hits15, hits9);
goto finally;
@@ -1232,7 +1232,7 @@ static int mixed_bones_object_selectbuffer(
offs += 4 * hits9;
BLI_rcti_init_pt_radius(&rect, mval, 5);
- hits5 = view3d_opengl_select(vc, buffer + offs, MAXPICKBUF - offs, &rect, select_mode);
+ hits5 = view3d_opengl_select(vc, buffer + offs, MAXPICKBUF - offs, &rect, select_mode, select_filter);
if (hits5 == 1) {
hits = selectbuffer_ret_hits_5(buffer, hits15, hits9, hits5);
goto finally;
@@ -1373,7 +1373,10 @@ Base *ED_view3d_give_base_under_cursor(bContext *C, const int mval[2])
ED_view3d_viewcontext_init(C, &vc);
- hits = mixed_bones_object_selectbuffer(&vc, buffer, mval, false, false, &do_nearest);
+ hits = mixed_bones_object_selectbuffer(
+ &vc, buffer, mval,
+ false, false, VIEW3D_SELECT_FILTER_NOP,
+ &do_nearest);
if (hits > 0) {
const bool has_bones = selectbuffer_has_bones(buffer, hits);
@@ -1487,7 +1490,13 @@ static bool ed_object_select_pick(
// TIMEIT_START(select_time);
/* if objects have posemode set, the bones are in the same selection buffer */
- hits = mixed_bones_object_selectbuffer(&vc, buffer, mval, true, enumerate, &do_nearest);
+ const eV3DSelectObjectFilter select_filter = (
+ (scene->toolsettings->object_flag & SCE_OBJECT_MODE_LOCK) ?
+ VIEW3D_SELECT_FILTER_OBJECT_MODE_LOCK : VIEW3D_SELECT_FILTER_NOP);
+ hits = mixed_bones_object_selectbuffer(
+ &vc, buffer, mval,
+ true, enumerate, select_filter,
+ &do_nearest);
// TIMEIT_END(select_time);
@@ -1968,7 +1977,9 @@ static int do_meta_box_select(
unsigned int buffer[MAXPICKBUF];
int hits;
- hits = view3d_opengl_select(vc, buffer, MAXPICKBUF, rect, VIEW3D_SELECT_ALL);
+ hits = view3d_opengl_select(
+ vc, buffer, MAXPICKBUF, rect,
+ VIEW3D_SELECT_ALL, VIEW3D_SELECT_FILTER_NOP);
if (extend == false && select)
BKE_mball_deselect_all(mb);
@@ -2002,7 +2013,9 @@ static int do_armature_box_select(
unsigned int buffer[MAXPICKBUF];
int hits;
- hits = view3d_opengl_select(vc, buffer, MAXPICKBUF, rect, VIEW3D_SELECT_ALL);
+ hits = view3d_opengl_select(
+ vc, buffer, MAXPICKBUF, rect,
+ VIEW3D_SELECT_ALL, VIEW3D_SELECT_FILTER_NOP);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(vc->view_layer, &objects_len);
@@ -2150,7 +2163,12 @@ static int do_object_pose_box_select(bContext *C, ViewContext *vc, rcti *rect, b
/* selection buffer now has bones potentially too, so we add MAXPICKBUF */
vbuffer = MEM_mallocN(4 * (totobj + MAXPICKELEMS) * sizeof(unsigned int), "selection buffer");
- hits = view3d_opengl_select(vc, vbuffer, 4 * (totobj + MAXPICKELEMS), rect, VIEW3D_SELECT_ALL);
+ const eV3DSelectObjectFilter select_filter = (
+ (vc->scene->toolsettings->object_flag & SCE_OBJECT_MODE_LOCK) ?
+ VIEW3D_SELECT_FILTER_OBJECT_MODE_LOCK : VIEW3D_SELECT_FILTER_NOP);
+ hits = view3d_opengl_select(
+ vc, vbuffer, 4 * (totobj + MAXPICKELEMS), rect,
+ VIEW3D_SELECT_ALL, select_filter);
/*
* LOGIC NOTES (theeth):
* The buffer and ListBase have the same relative order, which makes the selection
diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c
index 73b9a67ac56..abb8c688e05 100644
--- a/source/blender/editors/space_view3d/view3d_view.c
+++ b/source/blender/editors/space_view3d/view3d_view.c
@@ -896,6 +896,13 @@ static bool drw_select_loop_pass(eDRWSelectStage stage, void *user_data)
}
#endif /* WITH_OPENGL_LEGACY */
+/** Implement #VIEW3D_SELECT_FILTER_OBJECT_MODE_LOCK. */
+static bool drw_select_filter_object_mode_lock(Object *ob, void *user_data)
+{
+ const Object *obact = user_data;
+ return BKE_object_is_mode_compat(ob, obact->mode);
+}
+
/**
* \warning be sure to account for a negative return value
* This is an error, "Too many objects in select buffer"
@@ -905,7 +912,7 @@ static bool drw_select_loop_pass(eDRWSelectStage stage, void *user_data)
*/
int view3d_opengl_select(
ViewContext *vc, unsigned int *buffer, unsigned int bufsize, const rcti *input,
- eV3DSelectMode select_mode)
+ eV3DSelectMode select_mode, eV3DSelectObjectFilter select_filter)
{
struct bThemeState theme_state;
Depsgraph *depsgraph = vc->depsgraph;
@@ -953,6 +960,25 @@ int view3d_opengl_select(
}
}
+ struct {
+ DRW_ObjectFilterFn fn;
+ void *user_data;
+ } object_filter = {NULL, NULL};
+ switch (select_filter) {
+ case VIEW3D_SELECT_FILTER_OBJECT_MODE_LOCK:
+ {
+ Object *obact = OBACT(vc->view_layer);
+ if (obact && obact->mode != OB_MODE_OBJECT) {
+ object_filter.fn = drw_select_filter_object_mode_lock;
+ object_filter.user_data = obact;
+ }
+ break;
+ }
+ case VIEW3D_SELECT_FILTER_NOP:
+ break;
+
+ }
+
/* Tools may request depth outside of regular drawing code. */
UI_Theme_Store(&theme_state);
UI_SetTheme(SPACE_VIEW3D, RGN_TYPE_WINDOW);
@@ -1014,7 +1040,8 @@ int view3d_opengl_select(
DRW_draw_select_loop(
depsgraph, ar, v3d,
use_obedit_skip, use_nearest, &rect,
- drw_select_loop_pass, &drw_select_loop_user_data);
+ drw_select_loop_pass, &drw_select_loop_user_data,
+ object_filter.fn, object_filter.user_data);
hits = drw_select_loop_user_data.hits;
}
#endif /* WITH_OPENGL_LEGACY */