diff options
Diffstat (limited to 'source/blender/editors/space_view3d/view3d_select.c')
-rw-r--r-- | source/blender/editors/space_view3d/view3d_select.c | 366 |
1 files changed, 197 insertions, 169 deletions
diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c index 05cf552e5cc..28e15b3bfee 100644 --- a/source/blender/editors/space_view3d/view3d_select.c +++ b/source/blender/editors/space_view3d/view3d_select.c @@ -63,16 +63,16 @@ #include "BKE_armature.h" #include "BKE_context.h" #include "BKE_curve.h" -#include "BKE_depsgraph.h" +#include "BKE_layer.h" #include "BKE_mball.h" #include "BKE_mesh.h" #include "BKE_object.h" #include "BKE_paint.h" #include "BKE_editmesh.h" +#include "BKE_scene.h" #include "BKE_tracking.h" -#include "BIF_gl.h" -#include "BIF_glutil.h" +#include "DEG_depsgraph.h" #include "WM_api.h" #include "WM_types.h" @@ -93,6 +93,8 @@ #include "UI_interface.h" #include "GPU_draw.h" +#include "GPU_glew.h" +#include "GPU_matrix.h" #include "view3d_intern.h" /* own include */ @@ -108,7 +110,10 @@ void view3d_set_viewcontext(bContext *C, ViewContext *vc) { memset(vc, 0, sizeof(ViewContext)); vc->ar = CTX_wm_region(C); + vc->depsgraph = CTX_data_depsgraph(C); vc->scene = CTX_data_scene(C); + vc->view_layer = CTX_data_view_layer(C); + vc->engine_type = CTX_data_engine_type(C); vc->v3d = CTX_wm_view3d(C); vc->win = CTX_wm_window(C); vc->rv3d = CTX_wm_region_view3d(C); @@ -116,34 +121,6 @@ void view3d_set_viewcontext(bContext *C, ViewContext *vc) vc->obedit = CTX_data_edit_object(C); } -/* - * ob == NULL if you want global matrices - * */ -void view3d_get_transformation(const ARegion *ar, RegionView3D *rv3d, Object *ob, bglMats *mats) -{ - float cpy[4][4]; - int i, j; - - if (ob) { - mul_m4_m4m4(cpy, rv3d->viewmat, ob->obmat); - } - else { - copy_m4_m4(cpy, rv3d->viewmat); - } - - for (i = 0; i < 4; ++i) { - for (j = 0; j < 4; ++j) { - mats->projection[i * 4 + j] = rv3d->winmat[i][j]; - mats->modelview[i * 4 + j] = cpy[i][j]; - } - } - - mats->viewport[0] = ar->winrct.xmin; - mats->viewport[1] = ar->winrct.ymin; - mats->viewport[2] = ar->winx; - mats->viewport[3] = ar->winy; -} - /* ********************** view3d_select: selection manipulations ********************* */ /* local prototypes */ @@ -394,18 +371,18 @@ static void do_lasso_select_pose(ViewContext *vc, Object *ob, const int mcords[] bArmature *arm = ob->data; if (arm->flag & ARM_HAS_VIZ_DEPS) { /* mask modifier ('armature' mode), etc. */ - DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); } } } -static void object_deselect_all_visible(Scene *scene, View3D *v3d) +static void object_deselect_all_visible(ViewLayer *view_layer) { Base *base; - for (base = scene->base.first; base; base = base->next) { - if (BASE_SELECTABLE(v3d, base)) { - ED_base_object_select(base, BA_DESELECT); + for (base = view_layer->object_bases.first; base; base = base->next) { + if (BASE_SELECTABLE(base)) { + ED_object_base_select(base, BA_DESELECT); } } } @@ -416,15 +393,14 @@ static void do_lasso_select_objects(ViewContext *vc, const int mcords[][2], cons Base *base; if (extend == false && select) - object_deselect_all_visible(vc->scene, vc->v3d); + object_deselect_all_visible(vc->view_layer); - for (base = vc->scene->base.first; base; base = base->next) { - if (BASE_SELECTABLE(vc->v3d, base)) { /* use this to avoid un-needed lasso lookups */ + for (base = vc->view_layer->object_bases.first; base; base = base->next) { + if (BASE_SELECTABLE(base)) { /* use this to avoid un-needed lasso lookups */ if (ED_view3d_project_base(vc->ar, base) == V3D_PROJ_RET_OK) { if (BLI_lasso_is_point_inside(mcords, moves, base->sx, base->sy, IS_CLIPPED)) { - ED_base_object_select(base, select ? BA_SELECT : BA_DESELECT); - base->object->flag = base->flag; + ED_object_base_select(base, select ? BA_SELECT : BA_DESELECT); } } if (vc->obact == base->object && (base->object->mode & OB_MODE_POSE)) { @@ -481,7 +457,9 @@ static void do_lasso_select_mesh__doSelectFace(void *userData, BMFace *efa, cons } } -static void do_lasso_select_mesh(ViewContext *vc, const int mcords[][2], short moves, bool extend, bool select) +static void do_lasso_select_mesh( + const struct EvaluationContext *eval_ctx, ViewContext *vc, + const int mcords[][2], short moves, bool extend, bool select) { LassoSelectUserData data; ToolSettings *ts = vc->scene->toolsettings; @@ -501,25 +479,25 @@ static void do_lasso_select_mesh(ViewContext *vc, const int mcords[][2], short m /* for non zbuf projections, don't change the GL state */ ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); - glLoadMatrixf(vc->rv3d->viewmat); - bbsel = EDBM_backbuf_border_mask_init(vc, mcords, moves, rect.xmin, rect.ymin, rect.xmax, rect.ymax); + gpuLoadMatrix(vc->rv3d->viewmat); + bbsel = EDBM_backbuf_border_mask_init(eval_ctx, vc, mcords, moves, rect.xmin, rect.ymin, rect.xmax, rect.ymax); if (ts->selectmode & SCE_SELECT_VERTEX) { if (bbsel) { edbm_backbuf_check_and_select_verts(vc->em, select); } else { - mesh_foreachScreenVert(vc, do_lasso_select_mesh__doSelectVert, &data, V3D_PROJ_TEST_CLIP_DEFAULT); + mesh_foreachScreenVert(eval_ctx, vc, do_lasso_select_mesh__doSelectVert, &data, V3D_PROJ_TEST_CLIP_DEFAULT); } } if (ts->selectmode & SCE_SELECT_EDGE) { /* Does both bbsel and non-bbsel versions (need screen cos for both) */ data.pass = 0; - mesh_foreachScreenEdge(vc, do_lasso_select_mesh__doSelectEdge, &data, V3D_PROJ_TEST_CLIP_NEAR); + mesh_foreachScreenEdge(eval_ctx, vc, do_lasso_select_mesh__doSelectEdge, &data, V3D_PROJ_TEST_CLIP_NEAR); if (data.is_done == false) { data.pass = 1; - mesh_foreachScreenEdge(vc, do_lasso_select_mesh__doSelectEdge, &data, V3D_PROJ_TEST_CLIP_NEAR); + mesh_foreachScreenEdge(eval_ctx, vc, do_lasso_select_mesh__doSelectEdge, &data, V3D_PROJ_TEST_CLIP_NEAR); } } @@ -528,7 +506,7 @@ static void do_lasso_select_mesh(ViewContext *vc, const int mcords[][2], short m edbm_backbuf_check_and_select_faces(vc->em, select); } else { - mesh_foreachScreenFace(vc, do_lasso_select_mesh__doSelectFace, &data, V3D_PROJ_TEST_CLIP_DEFAULT); + mesh_foreachScreenFace(eval_ctx, vc, do_lasso_select_mesh__doSelectFace, &data, V3D_PROJ_TEST_CLIP_DEFAULT); } } @@ -727,7 +705,7 @@ static void do_lasso_select_meshobject__doSelectVert(void *userData, MVert *mv, SET_FLAG_FROM_TEST(mv->flag, data->select, SELECT); } } -static void do_lasso_select_paintvert(ViewContext *vc, const int mcords[][2], short moves, bool extend, bool select) +static void do_lasso_select_paintvert(const struct EvaluationContext *eval_ctx, ViewContext *vc, const int mcords[][2], short moves, bool extend, bool select) { const bool use_zbuf = (vc->v3d->flag & V3D_ZBUF_SELECT) != 0; Object *ob = vc->obact; @@ -745,7 +723,7 @@ static void do_lasso_select_paintvert(ViewContext *vc, const int mcords[][2], sh if (use_zbuf) { bm_vertoffs = me->totvert + 1; /* max index array */ - EDBM_backbuf_border_mask_init(vc, mcords, moves, rect.xmin, rect.ymin, rect.xmax, rect.ymax); + EDBM_backbuf_border_mask_init(eval_ctx, vc, mcords, moves, rect.xmin, rect.ymin, rect.xmax, rect.ymax); edbm_backbuf_check_and_select_verts_obmode(me, select); @@ -758,7 +736,7 @@ static void do_lasso_select_paintvert(ViewContext *vc, const int mcords[][2], sh ED_view3d_init_mats_rv3d(vc->obact, vc->rv3d); - meshobject_foreachScreenVert(vc, do_lasso_select_meshobject__doSelectVert, &data, V3D_PROJ_TEST_CLIP_DEFAULT); + meshobject_foreachScreenVert(eval_ctx, vc, do_lasso_select_meshobject__doSelectVert, &data, V3D_PROJ_TEST_CLIP_DEFAULT); } @@ -767,7 +745,7 @@ static void do_lasso_select_paintvert(ViewContext *vc, const int mcords[][2], sh } paintvert_flush_flags(ob); } -static void do_lasso_select_paintface(ViewContext *vc, const int mcords[][2], short moves, bool extend, bool select) +static void do_lasso_select_paintface(const struct EvaluationContext *eval_ctx, ViewContext *vc, const int mcords[][2], short moves, bool extend, bool select) { Object *ob = vc->obact; Mesh *me = ob->data; @@ -782,7 +760,7 @@ static void do_lasso_select_paintface(ViewContext *vc, const int mcords[][2], sh bm_vertoffs = me->totpoly + 1; /* max index array */ BLI_lasso_boundbox(&rect, mcords, moves); - EDBM_backbuf_border_mask_init(vc, mcords, moves, rect.xmin, rect.ymin, rect.xmax, rect.ymax); + EDBM_backbuf_border_mask_init(eval_ctx, vc, mcords, moves, rect.xmin, rect.ymin, rect.xmax, rect.ymax); edbm_backbuf_check_and_select_tfaces(me, select); @@ -828,16 +806,22 @@ static void view3d_lasso_select(bContext *C, ViewContext *vc, { Object *ob = CTX_data_active_object(C); + EvaluationContext eval_ctx; + CTX_data_eval_ctx(C, &eval_ctx); + if (vc->obedit == NULL) { /* Object Mode */ - if (BKE_paint_select_face_test(ob)) - do_lasso_select_paintface(vc, mcords, moves, extend, select); - else if (BKE_paint_select_vert_test(ob)) - do_lasso_select_paintvert(vc, mcords, moves, extend, select); + if (BKE_paint_select_face_test(ob)) { + do_lasso_select_paintface(&eval_ctx, vc, mcords, moves, extend, select); + } + else if (BKE_paint_select_vert_test(ob)) { + do_lasso_select_paintvert(&eval_ctx, vc, mcords, moves, extend, select); + } else if (ob && (ob->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT | OB_MODE_TEXTURE_PAINT))) { /* pass */ } - else if (ob && (ob->mode & OB_MODE_PARTICLE_EDIT)) + else if (ob && (ob->mode & OB_MODE_PARTICLE_EDIT)) { PE_lasso_select(C, mcords, moves, extend, select); + } else { do_lasso_select_objects(vc, mcords, moves, extend, select); WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, vc->scene); @@ -846,7 +830,7 @@ static void view3d_lasso_select(bContext *C, ViewContext *vc, else { /* Edit Mode */ switch (vc->obedit->type) { case OB_MESH: - do_lasso_select_mesh(vc, mcords, moves, extend, select); + do_lasso_select_mesh(&eval_ctx, vc, mcords, moves, extend, select); break; case OB_CURVE: case OB_SURF: @@ -930,7 +914,7 @@ static unsigned int samplerect(unsigned int *buf, int size, unsigned int dontdo) base = LASTBASE; if (base == 0) return 0; - maxob = base->selcol; + maxob = base->object->select_color; len = (size - 1) / 2; rc = 0; @@ -1016,8 +1000,8 @@ static int object_select_menu_exec(bContext *C, wmOperator *op) if (!toggle) { CTX_DATA_BEGIN (C, Base *, base, selectable_bases) { - if (base->flag & SELECT) { - ED_base_object_select(base, BA_DESELECT); + if ((base->flag & BASE_SELECTED) != 0) { + ED_object_base_select(base, BA_DESELECT); changed = true; } } @@ -1028,8 +1012,8 @@ static int object_select_menu_exec(bContext *C, wmOperator *op) { /* this is a bit dodjy, there should only be ONE object with this name, but library objects can mess this up */ if (STREQ(name, base->object->id.name + 2)) { - ED_base_object_activate(C, base); - ED_base_object_select(base, BA_SELECT); + ED_object_base_activate(C, base); + ED_object_base_select(base, BA_SELECT); changed = true; } } @@ -1073,14 +1057,12 @@ void VIEW3D_OT_select_menu(wmOperatorType *ot) RNA_def_boolean(ot->srna, "toggle", 0, "Toggle", "Toggle selection instead of deselecting everything first"); } -static void deselectall_except(Scene *scene, Base *b) /* deselect all except b */ +static void deselectall_except(ViewLayer *view_layer, Base *b) /* deselect all except b */ { - Base *base; - - for (base = FIRSTBASE; base; base = base->next) { - if (base->flag & SELECT) { + for (Base *base = view_layer->object_bases.first; base; base = base->next) { + if (base->flag & BASE_SELECTED) { if (b != base) { - ED_base_object_select(base, BA_DESELECT); + ED_object_base_select(base, BA_DESELECT); } } } @@ -1093,7 +1075,8 @@ static Base *object_mouse_select_menu( short baseCount = 0; bool ok; LinkNode *linklist = NULL; - + + /* handle base->object->select_color */ CTX_DATA_BEGIN (C, Base *, base, selectable_bases) { ok = false; @@ -1102,7 +1085,7 @@ static Base *object_mouse_select_menu( if (buffer) { for (int a = 0; a < hits; a++) { /* index was converted */ - if (base->selcol == (buffer[(4 * a) + 3] & ~0xFFFF0000)) { + if (base->object->select_color == (buffer[(4 * a) + 3] & ~0xFFFF0000)) { ok = true; break; } @@ -1201,7 +1184,7 @@ static int selectbuffer_ret_hits_5(unsigned int *buffer, const int hits15, const /* we want a select buffer with bones, if there are... */ /* so check three selection levels and compare */ static int mixed_bones_object_selectbuffer( - ViewContext *vc, unsigned int *buffer, const int mval[2], + const EvaluationContext *eval_ctx, ViewContext *vc, unsigned int *buffer, const int mval[2], bool use_cycle, bool enumerate, bool *r_do_nearest) { @@ -1241,7 +1224,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(eval_ctx, vc, buffer, MAXPICKBUF, &rect, select_mode); if (hits15 == 1) { hits = selectbuffer_ret_hits_15(buffer, hits15); goto finally; @@ -1252,7 +1235,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(eval_ctx, vc, buffer + offs, MAXPICKBUF - offs, &rect, select_mode); if (hits9 == 1) { hits = selectbuffer_ret_hits_9(buffer, hits15, hits9); goto finally; @@ -1262,7 +1245,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(eval_ctx, vc, buffer + offs, MAXPICKBUF - offs, &rect, select_mode); if (hits5 == 1) { hits = selectbuffer_ret_hits_5(buffer, hits15, hits9, hits5); goto finally; @@ -1291,8 +1274,7 @@ finally: static Base *mouse_select_eval_buffer(ViewContext *vc, unsigned int *buffer, int hits, Base *startbase, bool has_bones, bool do_nearest) { - Scene *scene = vc->scene; - View3D *v3d = vc->v3d; + ViewLayer *view_layer = vc->view_layer; Base *base, *basact = NULL; int a; @@ -1312,7 +1294,9 @@ static Base *mouse_select_eval_buffer(ViewContext *vc, unsigned int *buffer, int } else { /* only exclude active object when it is selected... */ - if (BASACT && (BASACT->flag & SELECT) && hits > 1) notcol = BASACT->selcol; + if (BASACT(view_layer) && (BASACT(view_layer)->flag & BASE_SELECTED) && hits > 1) { + notcol = BASACT(view_layer)->object->select_color; + } for (a = 0; a < hits; a++) { if (min > buffer[4 * a + 1] && notcol != (buffer[4 * a + 3] & 0xFFFF)) { @@ -1322,10 +1306,10 @@ static Base *mouse_select_eval_buffer(ViewContext *vc, unsigned int *buffer, int } } - base = FIRSTBASE; + base = FIRSTBASE(view_layer); while (base) { - if (BASE_SELECTABLE(v3d, base)) { - if (base->selcol == selcol) break; + if (BASE_SELECTABLE(base)) { + if (base->object->select_color == selcol) break; } base = base->next; } @@ -1337,23 +1321,23 @@ static Base *mouse_select_eval_buffer(ViewContext *vc, unsigned int *buffer, int while (base) { /* skip objects with select restriction, to prevent prematurely ending this loop * with an un-selectable choice */ - if (base->object->restrictflag & OB_RESTRICT_SELECT) { + if ((base->flag & BASE_SELECTABLED) == 0) { base = base->next; - if (base == NULL) base = FIRSTBASE; + if (base == NULL) base = FIRSTBASE(view_layer); if (base == startbase) break; } - if (BASE_SELECTABLE(v3d, base)) { + if (BASE_SELECTABLE(base)) { for (a = 0; a < hits; a++) { if (has_bones) { /* skip non-bone objects */ if ((buffer[4 * a + 3] & 0xFFFF0000)) { - if (base->selcol == (buffer[(4 * a) + 3] & 0xFFFF)) + if (base->object->select_color == (buffer[(4 * a) + 3] & 0xFFFF)) basact = base; } } else { - if (base->selcol == (buffer[(4 * a) + 3] & 0xFFFF)) + if (base->object->select_color == (buffer[(4 * a) + 3] & 0xFFFF)) basact = base; } } @@ -1362,7 +1346,7 @@ static Base *mouse_select_eval_buffer(ViewContext *vc, unsigned int *buffer, int if (basact) break; base = base->next; - if (base == NULL) base = FIRSTBASE; + if (base == NULL) base = FIRSTBASE(view_layer); if (base == startbase) break; } } @@ -1373,6 +1357,7 @@ static Base *mouse_select_eval_buffer(ViewContext *vc, unsigned int *buffer, int /* mval comes from event->mval, only use within region handlers */ Base *ED_view3d_give_base_under_cursor(bContext *C, const int mval[2]) { + EvaluationContext eval_ctx; ViewContext vc; Base *basact = NULL; unsigned int buffer[MAXPICKBUF]; @@ -1381,13 +1366,15 @@ Base *ED_view3d_give_base_under_cursor(bContext *C, const int mval[2]) /* setup view context for argument to callbacks */ view3d_operator_needs_opengl(C); + + CTX_data_eval_ctx(C, &eval_ctx); view3d_set_viewcontext(C, &vc); - hits = mixed_bones_object_selectbuffer(&vc, buffer, mval, false, false, &do_nearest); + hits = mixed_bones_object_selectbuffer(&eval_ctx, &vc, buffer, mval, false, false, &do_nearest); if (hits > 0) { const bool has_bones = selectbuffer_has_bones(buffer, hits); - basact = mouse_select_eval_buffer(&vc, buffer, hits, vc.scene->base.first, has_bones, do_nearest); + basact = mouse_select_eval_buffer(&vc, buffer, hits, vc.view_layer->object_bases.first, has_bones, do_nearest); } return basact; @@ -1417,10 +1404,11 @@ static bool ed_object_select_pick( bContext *C, const int mval[2], bool extend, bool deselect, bool toggle, bool obcenter, bool enumerate, bool object) { + EvaluationContext eval_ctx; ViewContext vc; ARegion *ar = CTX_wm_region(C); - View3D *v3d = CTX_wm_view3d(C); Scene *scene = CTX_data_scene(C); + ViewLayer *view_layer = CTX_data_view_layer(C); Base *base, *startbase = NULL, *basact = NULL, *oldbasact = NULL; bool is_obedit; float dist = ED_view3d_select_dist_px() * 1.3333f; @@ -1430,6 +1418,7 @@ static bool ed_object_select_pick( /* setup view context for argument to callbacks */ + CTX_data_eval_ctx(C, &eval_ctx); view3d_set_viewcontext(C, &vc); is_obedit = (vc.obedit != NULL); @@ -1439,8 +1428,8 @@ static bool ed_object_select_pick( } /* always start list from basact in wire mode */ - startbase = FIRSTBASE; - if (BASACT && BASACT->next) startbase = BASACT->next; + startbase = FIRSTBASE(view_layer); + if (BASACT(view_layer) && BASACT(view_layer)->next) startbase = BASACT(view_layer)->next; /* This block uses the control key to make the object selected by its center point rather than its contents */ /* in editmode do not activate */ @@ -1453,13 +1442,13 @@ static bool ed_object_select_pick( else { base = startbase; while (base) { - if (BASE_SELECTABLE(v3d, base)) { + if (BASE_SELECTABLE(base)) { float screen_co[2]; if (ED_view3d_project_float_global(ar, base->object->obmat[3], screen_co, V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN | V3D_PROJ_TEST_CLIP_NEAR) == V3D_PROJ_RET_OK) { float dist_temp = len_manhattan_v2v2(mval_fl, screen_co); - if (base == BASACT) dist_temp += 10.0f; + if (base == BASACT(view_layer)) dist_temp += 10.0f; if (dist_temp < dist) { dist = dist_temp; basact = base; @@ -1468,7 +1457,7 @@ static bool ed_object_select_pick( } base = base->next; - if (base == NULL) base = FIRSTBASE; + if (base == NULL) base = FIRSTBASE(view_layer); if (base == startbase) break; } } @@ -1480,7 +1469,7 @@ 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); + hits = mixed_bones_object_selectbuffer(&eval_ctx, &vc, buffer, mval, true, enumerate, &do_nearest); // TIMEIT_END(select_time); @@ -1498,7 +1487,7 @@ static bool ed_object_select_pick( if (has_bones && basact) { if (basact->object->type == OB_CAMERA) { - if (BASACT == basact) { + if (BASACT(view_layer) == basact) { int i, hitresult; bool changed = false; @@ -1507,7 +1496,7 @@ static bool ed_object_select_pick( /* if there's bundles in buffer select bundles first, * so non-camera elements should be ignored in buffer */ - if (basact->selcol != (hitresult & 0xFFFF)) { + if (basact->object->select_color != (hitresult & 0xFFFF)) { continue; } @@ -1536,8 +1525,8 @@ static bool ed_object_select_pick( changed = true; } - basact->flag |= SELECT; - basact->object->flag = basact->flag; + basact->flag |= BASE_SELECTED; + BKE_scene_object_base_flag_sync_from_base(basact); retval = true; @@ -1555,27 +1544,27 @@ static bool ed_object_select_pick( } } } - else if (ED_do_pose_selectbuffer(scene, basact, buffer, hits, extend, deselect, toggle, do_nearest)) { + else if (ED_do_pose_selectbuffer(scene, view_layer, basact, buffer, hits, extend, deselect, toggle, do_nearest)) { /* then bone is found */ /* we make the armature selected: * not-selected active object in posemode won't work well for tools */ - basact->flag |= SELECT; - basact->object->flag = basact->flag; + basact->flag |= BASE_SELECTED; + BKE_scene_object_base_flag_sync_from_base(basact); retval = true; WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, basact->object); WM_event_add_notifier(C, NC_OBJECT | ND_BONE_ACTIVE, basact->object); /* in weightpaint, we use selected bone to select vertexgroup, so no switch to new active object */ - if (BASACT && (BASACT->object->mode & OB_MODE_WEIGHT_PAINT)) { + if (BASACT(view_layer) && (BASACT(view_layer)->object->mode & OB_MODE_WEIGHT_PAINT)) { /* prevent activating */ basact = NULL; } } /* prevent bone selecting to pass on to object selecting */ - if (basact == BASACT) + if (basact == BASACT(view_layer)) basact = NULL; } } @@ -1587,37 +1576,37 @@ static bool ed_object_select_pick( if (vc.obedit) { /* only do select */ - deselectall_except(scene, basact); - ED_base_object_select(basact, BA_SELECT); + deselectall_except(view_layer, basact); + ED_object_base_select(basact, BA_SELECT); } /* also prevent making it active on mouse selection */ - else if (BASE_SELECTABLE(v3d, basact)) { + else if (BASE_SELECTABLE(basact)) { - oldbasact = BASACT; + oldbasact = BASACT(view_layer); if (extend) { - ED_base_object_select(basact, BA_SELECT); + ED_object_base_select(basact, BA_SELECT); } else if (deselect) { - ED_base_object_select(basact, BA_DESELECT); + ED_object_base_select(basact, BA_DESELECT); } else if (toggle) { - if (basact->flag & SELECT) { + if (basact->flag & BASE_SELECTED) { if (basact == oldbasact) { - ED_base_object_select(basact, BA_DESELECT); + ED_object_base_select(basact, BA_DESELECT); } } else { - ED_base_object_select(basact, BA_SELECT); + ED_object_base_select(basact, BA_SELECT); } } else { - deselectall_except(scene, basact); - ED_base_object_select(basact, BA_SELECT); + deselectall_except(view_layer, basact); + ED_object_base_select(basact, BA_SELECT); } if ((oldbasact != basact) && (is_obedit == false)) { - ED_base_object_activate(C, basact); /* adds notifier */ + ED_object_base_activate(C, basact); /* adds notifier */ } } @@ -1673,7 +1662,8 @@ static void do_paintvert_box_select__doSelectVert(void *userData, MVert *mv, con SET_FLAG_FROM_TEST(mv->flag, data->select, SELECT); } } -static int do_paintvert_box_select(ViewContext *vc, rcti *rect, bool select, bool extend) +static int do_paintvert_box_select( + const EvaluationContext *eval_ctx, ViewContext *vc, rcti *rect, bool select, bool extend) { const bool use_zbuf = (vc->v3d->flag & V3D_ZBUF_SELECT) != 0; Mesh *me; @@ -1697,7 +1687,7 @@ static int do_paintvert_box_select(ViewContext *vc, rcti *rect, bool select, boo if (use_zbuf) { selar = MEM_callocN(me->totvert + 1, "selar"); - ED_view3d_backbuf_validate(vc); + ED_view3d_backbuf_validate(eval_ctx, vc); ibuf = IMB_allocImBuf(size[0], size[1], 32, IB_rect); rt = ibuf->rect; @@ -1745,7 +1735,7 @@ static int do_paintvert_box_select(ViewContext *vc, rcti *rect, bool select, boo ED_view3d_init_mats_rv3d(vc->obact, vc->rv3d); - meshobject_foreachScreenVert(vc, do_paintvert_box_select__doSelectVert, &data, V3D_PROJ_TEST_CLIP_DEFAULT); + meshobject_foreachScreenVert(eval_ctx, vc, do_paintvert_box_select__doSelectVert, &data, V3D_PROJ_TEST_CLIP_DEFAULT); } if (select == false) { @@ -1860,7 +1850,8 @@ static void do_mesh_box_select__doSelectFace(void *userData, BMFace *efa, const BM_face_select_set(data->vc->em->bm, efa, data->select); } } -static int do_mesh_box_select(ViewContext *vc, rcti *rect, bool select, bool extend) +static int do_mesh_box_select( + const struct EvaluationContext *eval_ctx, ViewContext *vc, rcti *rect, bool select, bool extend) { BoxSelectUserData data; ToolSettings *ts = vc->scene->toolsettings; @@ -1874,26 +1865,26 @@ static int do_mesh_box_select(ViewContext *vc, rcti *rect, bool select, bool ext /* for non zbuf projections, don't change the GL state */ ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); - glLoadMatrixf(vc->rv3d->viewmat); - bbsel = EDBM_backbuf_border_init(vc, rect->xmin, rect->ymin, rect->xmax, rect->ymax); + gpuLoadMatrix(vc->rv3d->viewmat); + bbsel = EDBM_backbuf_border_init(eval_ctx, vc, rect->xmin, rect->ymin, rect->xmax, rect->ymax); if (ts->selectmode & SCE_SELECT_VERTEX) { if (bbsel) { edbm_backbuf_check_and_select_verts(vc->em, select); } else { - mesh_foreachScreenVert(vc, do_mesh_box_select__doSelectVert, &data, V3D_PROJ_TEST_CLIP_DEFAULT); + mesh_foreachScreenVert(eval_ctx, vc, do_mesh_box_select__doSelectVert, &data, V3D_PROJ_TEST_CLIP_DEFAULT); } } if (ts->selectmode & SCE_SELECT_EDGE) { /* Does both bbsel and non-bbsel versions (need screen cos for both) */ data.pass = 0; - mesh_foreachScreenEdge(vc, do_mesh_box_select__doSelectEdge, &data, V3D_PROJ_TEST_CLIP_NEAR); + mesh_foreachScreenEdge(eval_ctx, vc, do_mesh_box_select__doSelectEdge, &data, V3D_PROJ_TEST_CLIP_NEAR); if (data.is_done == 0) { data.pass = 1; - mesh_foreachScreenEdge(vc, do_mesh_box_select__doSelectEdge, &data, V3D_PROJ_TEST_CLIP_NEAR); + mesh_foreachScreenEdge(eval_ctx, vc, do_mesh_box_select__doSelectEdge, &data, V3D_PROJ_TEST_CLIP_NEAR); } } @@ -1902,7 +1893,7 @@ static int do_mesh_box_select(ViewContext *vc, rcti *rect, bool select, bool ext edbm_backbuf_check_and_select_faces(vc->em, select); } else { - mesh_foreachScreenFace(vc, do_mesh_box_select__doSelectFace, &data, V3D_PROJ_TEST_CLIP_DEFAULT); + mesh_foreachScreenFace(eval_ctx, vc, do_mesh_box_select__doSelectFace, &data, V3D_PROJ_TEST_CLIP_DEFAULT); } } @@ -1913,7 +1904,9 @@ static int do_mesh_box_select(ViewContext *vc, rcti *rect, bool select, bool ext return OPERATOR_FINISHED; } -static int do_meta_box_select(ViewContext *vc, rcti *rect, bool select, bool extend) +static int do_meta_box_select( + const struct EvaluationContext *eval_ctx, ViewContext *vc, + const rcti *rect, bool select, bool extend) { MetaBall *mb = (MetaBall *)vc->obedit->data; MetaElem *ml; @@ -1922,7 +1915,7 @@ static int do_meta_box_select(ViewContext *vc, rcti *rect, bool select, bool ext unsigned int buffer[MAXPICKBUF]; int hits; - hits = view3d_opengl_select(vc, buffer, MAXPICKBUF, rect, VIEW3D_SELECT_ALL); + hits = view3d_opengl_select(eval_ctx, vc, buffer, MAXPICKBUF, rect, VIEW3D_SELECT_ALL); if (extend == false && select) BKE_mball_deselect_all(mb); @@ -1947,7 +1940,9 @@ static int do_meta_box_select(ViewContext *vc, rcti *rect, bool select, bool ext return OPERATOR_FINISHED; } -static int do_armature_box_select(ViewContext *vc, rcti *rect, bool select, bool extend) +static int do_armature_box_select( + const struct EvaluationContext *eval_ctx, ViewContext *vc, + const rcti *rect, bool select, bool extend) { bArmature *arm = vc->obedit->data; EditBone *ebone; @@ -1956,7 +1951,7 @@ static int do_armature_box_select(ViewContext *vc, rcti *rect, bool select, bool unsigned int buffer[MAXPICKBUF]; int hits; - hits = view3d_opengl_select(vc, buffer, MAXPICKBUF, rect, VIEW3D_SELECT_ALL); + hits = view3d_opengl_select(eval_ctx, vc, buffer, MAXPICKBUF, rect, VIEW3D_SELECT_ALL); /* clear flag we use to detect point was affected */ for (ebone = arm->edbo->first; ebone; ebone = ebone->next) @@ -2020,8 +2015,30 @@ static int do_armature_box_select(ViewContext *vc, rcti *rect, bool select, bool return hits > 0 ? OPERATOR_FINISHED : OPERATOR_CANCELLED; } +/** + * Compare result of 'GPU_select': 'uint[4]', + * needed for when we need to align with object draw-order. + */ +static int opengl_select_buffer_cmp(const void *sel_a_p, const void *sel_b_p) +{ + /* 4th element is select id */ + const uint sel_a = ((uint *)sel_a_p)[3]; + const uint sel_b = ((uint *)sel_b_p)[3]; + + if (sel_a < sel_b) { + return -1; + } + else if (sel_a > sel_b) { + return 1; + } + else { + return 0; + } +} + static int do_object_pose_box_select(bContext *C, ViewContext *vc, rcti *rect, bool select, bool extend) { + EvaluationContext eval_ctx; Bone *bone; Object *ob = vc->obact; unsigned int *vbuffer = NULL; /* selection buffer */ @@ -2031,6 +2048,8 @@ static int do_object_pose_box_select(bContext *C, ViewContext *vc, rcti *rect, b int totobj = MAXPICKBUF; /* XXX solve later */ int hits; + CTX_data_eval_ctx(C, &eval_ctx); + if ((ob) && (ob->mode & OB_MODE_POSE)) bone_only = 1; else @@ -2047,13 +2066,13 @@ static int do_object_pose_box_select(bContext *C, ViewContext *vc, rcti *rect, b CTX_DATA_END; } else { - object_deselect_all_visible(vc->scene, vc->v3d); + object_deselect_all_visible(vc->view_layer); } } /* 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); + hits = view3d_opengl_select(&eval_ctx, vc, vbuffer, 4 * (totobj + MAXPICKELEMS), rect, VIEW3D_SELECT_ALL); /* * LOGIC NOTES (theeth): * The buffer and ListBase have the same relative order, which makes the selection @@ -2061,18 +2080,22 @@ static int do_object_pose_box_select(bContext *C, ViewContext *vc, rcti *rect, b * is the same as the object, we have a hit and can move to the next color * and object pair, if not, just move to the next object, * keeping the same color until we have a hit. - * - * The buffer order is defined by OGL standard, hopefully no stupid GFX card - * does it incorrectly. */ if (hits > 0) { /* no need to loop if there's no hit */ Base *base; col = vbuffer + 3; - - for (base = vc->scene->base.first; base && hits; base = base->next) { - if (BASE_SELECTABLE(vc->v3d, base)) { - while (base->selcol == (*col & 0xFFFF)) { /* we got an object */ + + /* The draw order doesn't always match the order we populate the engine, see: T51695. */ + qsort(vbuffer, hits, sizeof(uint[4]), opengl_select_buffer_cmp); + + /* + * Even though 'DRW_draw_select_loop' uses 'DEG_OBJECT_ITER', + * we can be sure the order remains the same between both. + */ + for (base = vc->view_layer->object_bases.first; base && hits; base = base->next) { + if (BASE_SELECTABLE(base)) { + while (base->object->select_color == (*col & 0xFFFF)) { /* we got an object */ if (*col & 0xFFFF0000) { /* we got a bone */ bone = get_indexed_bone(base->object, *col & ~(BONESEL_ANY)); if (bone) { @@ -2091,7 +2114,7 @@ static int do_object_pose_box_select(bContext *C, ViewContext *vc, rcti *rect, b } } else if (!bone_only) { - ED_base_object_select(base, select ? BA_SELECT : BA_DESELECT); + ED_object_base_select(base, select ? BA_SELECT : BA_DESELECT); } col += 4; /* next color */ @@ -2108,7 +2131,7 @@ static int do_object_pose_box_select(bContext *C, ViewContext *vc, rcti *rect, b if (arm && (arm->flag & ARM_HAS_VIZ_DEPS)) { /* mask modifier ('armature' mode), etc. */ - DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); } } } @@ -2123,6 +2146,7 @@ static int do_object_pose_box_select(bContext *C, ViewContext *vc, rcti *rect, b static int view3d_borderselect_exec(bContext *C, wmOperator *op) { + EvaluationContext eval_ctx; ViewContext vc; rcti rect; bool extend; @@ -2133,6 +2157,7 @@ static int view3d_borderselect_exec(bContext *C, wmOperator *op) view3d_operator_needs_opengl(C); /* setup view context for argument to callbacks */ + CTX_data_eval_ctx(C, &eval_ctx); view3d_set_viewcontext(C, &vc); select = !RNA_boolean_get(op->ptr, "deselect"); @@ -2143,7 +2168,7 @@ static int view3d_borderselect_exec(bContext *C, wmOperator *op) switch (vc.obedit->type) { case OB_MESH: vc.em = BKE_editmesh_from_object(vc.obedit); - ret = do_mesh_box_select(&vc, &rect, select, extend); + ret = do_mesh_box_select(&eval_ctx, &vc, &rect, select, extend); // if (EM_texFaceCheck()) if (ret & OPERATOR_FINISHED) { WM_event_add_notifier(C, NC_GEOM | ND_SELECT, vc.obedit->data); @@ -2157,13 +2182,13 @@ static int view3d_borderselect_exec(bContext *C, wmOperator *op) } break; case OB_MBALL: - ret = do_meta_box_select(&vc, &rect, select, extend); + ret = do_meta_box_select(&eval_ctx, &vc, &rect, select, extend); if (ret & OPERATOR_FINISHED) { WM_event_add_notifier(C, NC_GEOM | ND_SELECT, vc.obedit->data); } break; case OB_ARMATURE: - ret = do_armature_box_select(&vc, &rect, select, extend); + ret = do_armature_box_select(&eval_ctx, &vc, &rect, select, extend); if (ret & OPERATOR_FINISHED) { WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, vc.obedit); } @@ -2184,10 +2209,10 @@ static int view3d_borderselect_exec(bContext *C, wmOperator *op) ret = ED_sculpt_mask_box_select(C, &vc, &rect, select, extend); } else if (vc.obact && BKE_paint_select_face_test(vc.obact)) { - ret = do_paintface_box_select(&vc, &rect, select, extend); + ret = do_paintface_box_select(&eval_ctx, &vc, &rect, select, extend); } else if (vc.obact && BKE_paint_select_vert_test(vc.obact)) { - ret = do_paintvert_box_select(&vc, &rect, select, extend); + ret = do_paintvert_box_select(&eval_ctx, &vc, &rect, select, extend); } else if (vc.obact && vc.obact->mode & OB_MODE_PARTICLE_EDIT) { ret = PE_border_select(C, &rect, select, extend); @@ -2431,13 +2456,13 @@ static void mesh_circle_doSelectFace(void *userData, BMFace *efa, const float sc } } -static void mesh_circle_select(ViewContext *vc, const bool select, const int mval[2], float rad) +static void mesh_circle_select(const struct EvaluationContext *eval_ctx, ViewContext *vc, const bool select, const int mval[2], float rad) { ToolSettings *ts = vc->scene->toolsettings; int bbsel; CircleSelectUserData data; - bbsel = EDBM_backbuf_circle_init(vc, mval[0], mval[1], (short)(rad + 1.0f)); + bbsel = EDBM_backbuf_circle_init(eval_ctx, vc, mval[0], mval[1], (short)(rad + 1.0f)); ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* for foreach's screen/vert projection */ vc->em = BKE_editmesh_from_object(vc->obedit); @@ -2449,7 +2474,7 @@ static void mesh_circle_select(ViewContext *vc, const bool select, const int mva edbm_backbuf_check_and_select_verts(vc->em, select); } else { - mesh_foreachScreenVert(vc, mesh_circle_doSelectVert, &data, V3D_PROJ_TEST_CLIP_DEFAULT); + mesh_foreachScreenVert(eval_ctx, vc, mesh_circle_doSelectVert, &data, V3D_PROJ_TEST_CLIP_DEFAULT); } } @@ -2458,7 +2483,7 @@ static void mesh_circle_select(ViewContext *vc, const bool select, const int mva edbm_backbuf_check_and_select_edges(vc->em, select); } else { - mesh_foreachScreenEdge(vc, mesh_circle_doSelectEdge, &data, V3D_PROJ_TEST_CLIP_NEAR); + mesh_foreachScreenEdge(eval_ctx, vc, mesh_circle_doSelectEdge, &data, V3D_PROJ_TEST_CLIP_NEAR); } } @@ -2467,7 +2492,7 @@ static void mesh_circle_select(ViewContext *vc, const bool select, const int mva edbm_backbuf_check_and_select_faces(vc->em, select); } else { - mesh_foreachScreenFace(vc, mesh_circle_doSelectFace, &data, V3D_PROJ_TEST_CLIP_DEFAULT); + mesh_foreachScreenFace(eval_ctx, vc, mesh_circle_doSelectFace, &data, V3D_PROJ_TEST_CLIP_DEFAULT); } } @@ -2475,7 +2500,7 @@ static void mesh_circle_select(ViewContext *vc, const bool select, const int mva EDBM_selectmode_flush(vc->em); } -static void paint_facesel_circle_select(ViewContext *vc, const bool select, const int mval[2], float rad) +static void paint_facesel_circle_select(const struct EvaluationContext *eval_ctx, ViewContext *vc, const bool select, const int mval[2], float rad) { Object *ob = vc->obact; Mesh *me = ob->data; @@ -2483,7 +2508,7 @@ static void paint_facesel_circle_select(ViewContext *vc, const bool select, cons bm_vertoffs = me->totpoly + 1; /* max index array */ - bbsel = EDBM_backbuf_circle_init(vc, mval[0], mval[1], (short)(rad + 1.0f)); + bbsel = EDBM_backbuf_circle_init(eval_ctx, vc, mval[0], mval[1], (short)(rad + 1.0f)); if (bbsel) { edbm_backbuf_check_and_select_tfaces(me, select); EDBM_backbuf_free(); @@ -2499,7 +2524,7 @@ static void paint_vertsel_circle_select_doSelectVert(void *userData, MVert *mv, SET_FLAG_FROM_TEST(mv->flag, data->select, SELECT); } } -static void paint_vertsel_circle_select(ViewContext *vc, const bool select, const int mval[2], float rad) +static void paint_vertsel_circle_select(const struct EvaluationContext *eval_ctx, ViewContext *vc, const bool select, const int mval[2], float rad) { const bool use_zbuf = (vc->v3d->flag & V3D_ZBUF_SELECT) != 0; Object *ob = vc->obact; @@ -2510,7 +2535,7 @@ static void paint_vertsel_circle_select(ViewContext *vc, const bool select, cons if (use_zbuf) { bm_vertoffs = me->totvert + 1; /* max index array */ - bbsel = EDBM_backbuf_circle_init(vc, mval[0], mval[1], (short)(rad + 1.0f)); + bbsel = EDBM_backbuf_circle_init(eval_ctx, vc, mval[0], mval[1], (short)(rad + 1.0f)); if (bbsel) { edbm_backbuf_check_and_select_verts_obmode(me, select); EDBM_backbuf_free(); @@ -2522,7 +2547,7 @@ static void paint_vertsel_circle_select(ViewContext *vc, const bool select, cons ED_view3d_init_mats_rv3d(vc->obact, vc->rv3d); /* for foreach's screen/vert projection */ view3d_userdata_circleselect_init(&data, vc, select, mval, rad); - meshobject_foreachScreenVert(vc, paint_vertsel_circle_select_doSelectVert, &data, V3D_PROJ_TEST_CLIP_DEFAULT); + meshobject_foreachScreenVert(eval_ctx, vc, paint_vertsel_circle_select_doSelectVert, &data, V3D_PROJ_TEST_CLIP_DEFAULT); } if (select != LEFTMOUSE) { @@ -2666,7 +2691,7 @@ static void pose_circle_select(ViewContext *vc, const bool select, const int mva if (arm->flag & ARM_HAS_VIZ_DEPS) { /* mask modifier ('armature' mode), etc. */ - DAG_id_tag_update(&vc->obact->id, OB_RECALC_DATA); + DEG_id_tag_update(&vc->obact->id, OB_RECALC_DATA); } } } @@ -2776,11 +2801,12 @@ static void mball_circle_select(ViewContext *vc, const bool select, const int mv /** Callbacks for circle selection in Editmode */ -static void obedit_circle_select(ViewContext *vc, const bool select, const int mval[2], float rad) +static void obedit_circle_select( + const struct EvaluationContext *eval_ctx, ViewContext *vc, const bool select, const int mval[2], float rad) { switch (vc->obedit->type) { case OB_MESH: - mesh_circle_select(vc, select, mval, rad); + mesh_circle_select(eval_ctx, vc, select, mval, rad); break; case OB_CURVE: case OB_SURF: @@ -2802,22 +2828,22 @@ static void obedit_circle_select(ViewContext *vc, const bool select, const int m static bool object_circle_select(ViewContext *vc, const bool select, const int mval[2], float rad) { - Scene *scene = vc->scene; + ViewLayer *view_layer = vc->view_layer; const float radius_squared = rad * rad; const float mval_fl[2] = {mval[0], mval[1]}; bool changed = false; - const int select_flag = select ? SELECT : 0; + const int select_flag = select ? BASE_SELECTED : 0; Base *base; - for (base = FIRSTBASE; base; base = base->next) { - if (BASE_SELECTABLE(vc->v3d, base) && ((base->flag & SELECT) != select_flag)) { + for (base = FIRSTBASE(view_layer); base; base = base->next) { + if (BASE_SELECTABLE(base) && ((base->flag & BASE_SELECTED) != select_flag)) { float screen_co[2]; if (ED_view3d_project_float_global(vc->ar, base->object->obmat[3], screen_co, V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN | V3D_PROJ_TEST_CLIP_NEAR) == V3D_PROJ_RET_OK) { if (len_squared_v2v2(mval_fl, screen_co) <= radius_squared) { - ED_base_object_select(base, select ? BA_SELECT : BA_DESELECT); + ED_object_base_select(base, select ? BA_SELECT : BA_DESELECT); changed = true; } } @@ -2840,22 +2866,24 @@ static int view3d_circle_select_exec(bContext *C, wmOperator *op) if (CTX_data_edit_object(C) || BKE_paint_select_elem_test(obact) || (obact && (obact->mode & (OB_MODE_PARTICLE_EDIT | OB_MODE_POSE))) ) { + EvaluationContext eval_ctx; ViewContext vc; view3d_operator_needs_opengl(C); + CTX_data_eval_ctx(C, &eval_ctx); view3d_set_viewcontext(C, &vc); if (CTX_data_edit_object(C)) { - obedit_circle_select(&vc, select, mval, (float)radius); + obedit_circle_select(&eval_ctx, &vc, select, mval, (float)radius); WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obact->data); } else if (BKE_paint_select_face_test(obact)) { - paint_facesel_circle_select(&vc, select, mval, (float)radius); + paint_facesel_circle_select(&eval_ctx, &vc, select, mval, (float)radius); WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obact->data); } else if (BKE_paint_select_vert_test(obact)) { - paint_vertsel_circle_select(&vc, select, mval, (float)radius); + paint_vertsel_circle_select(&eval_ctx, &vc, select, mval, (float)radius); WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obact->data); } else if (obact->mode & OB_MODE_POSE) |