Merge branch 'master' into blender2.8
authorCampbell Barton <ideasman42@gmail.com>
Mon, 16 Apr 2018 05:27:53 +0000 (07:27 +0200)
committerCampbell Barton <ideasman42@gmail.com>
Mon, 16 Apr 2018 05:27:53 +0000 (07:27 +0200)
1  2 
source/blender/editors/armature/armature_edit.c
source/blender/editors/space_view3d/view3d_select.c

index f41aa432b35414d8f715ba456ed85fc89e021cb0,4562329706ff595a8a622eec592dea3ce5b5aeee..75b80627dff96b47b996e73d178bb221f941c7e4
@@@ -50,7 -50,6 +50,7 @@@
  #include "BKE_context.h"
  #include "BKE_global.h"
  #include "BKE_report.h"
 +#include "BKE_object.h"
  
  #include "RNA_access.h"
  #include "RNA_define.h"
@@@ -139,16 -138,17 +139,16 @@@ void ED_armature_transform(struct bArma
  
  /* exported for use in editors/object/ */
  /* 0 == do center, 1 == center new, 2 == center cursor */
 -void ED_armature_origin_set(Scene *scene, Object *ob, float cursor[3], int centermode, int around)
 +void ED_armature_origin_set(Object *ob, float cursor[3], int centermode, int around)
  {
 -      Object *obedit = scene->obedit; // XXX get from context
 +      const bool is_editmode = BKE_object_is_in_editmode(ob);
        EditBone *ebone;
        bArmature *arm = ob->data;
        float cent[3];
  
        /* Put the armature into editmode */
 -      if (ob != obedit) {
 +      if (is_editmode == false) {
                ED_armature_to_edit(arm);
 -              obedit = NULL; /* we cant use this so behave as if there is no obedit */
        }
  
        /* Find the centerpoint */
        }
        
        /* Turn the list into an armature */
 -      if (obedit == NULL) {
 +      if (is_editmode == false) {
                ED_armature_from_edit(arm);
                ED_armature_edit_free(arm);
        }
  
        /* Adjust object location for new centerpoint */
 -      if (centermode && obedit == NULL) {
 +      if (centermode && (is_editmode == false)) {
                mul_mat3_m4_v3(ob->obmat, cent); /* omit translation part */
                add_v3_v3(ob->loc, cent);
        }
@@@ -1303,7 -1303,7 +1303,7 @@@ static int armature_delete_selected_exe
  {
        bArmature *arm;
        EditBone *curBone, *ebone_next;
-       Object *obedit = CTX_data_edit_object(C); // XXX get from context
+       Object *obedit = CTX_data_edit_object(C);
        bool changed = false;
        arm = obedit->data;
  
index 71ec7bf700c1a98e1fe8e17099f3d54fbaf128bc,d184081b03a6b7dd60bd7348eb6a13c59fa606bd..c38bcbcd6458355cce589f8aff473021d381a205
  #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"
@@@ -94,8 -94,6 +94,8 @@@
  #include "UI_interface.h"
  
  #include "GPU_draw.h"
 +#include "GPU_glew.h"
 +#include "GPU_matrix.h"
  
  #include "view3d_intern.h"  /* own include */
  
@@@ -111,10 -109,7 +111,10 @@@ void ED_view3d_viewcontext_init(bContex
  {
        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);
        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 */
@@@ -374,18 -397,18 +374,18 @@@ static void do_lasso_select_pose(ViewCo
                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);
                }
        }
  }
@@@ -397,14 -420,15 +397,14 @@@ static void do_lasso_select_objects
        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)) {
@@@ -462,9 -486,7 +462,9 @@@ static void do_lasso_select_mesh__doSel
        }
  }
  
 -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;
        /* 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);
                }
        }
        
                        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);
                }
        }
        
        EDBM_selectmode_flush(vc->em);
  }
  
 -static void do_lasso_select_curve__doSelect(
 -        void *userData, Nurb *UNUSED(nu), BPoint *bp, BezTriple *bezt, int beztindex, const float screen_co[2])
 +static void do_lasso_select_curve__doSelect(void *userData, Nurb *UNUSED(nu), BPoint *bp, BezTriple *bezt, int beztindex, const float screen_co[2])
  {
        LassoSelectUserData *data = userData;
        Object *obedit = data->vc->obedit;
@@@ -594,7 -617,8 +594,7 @@@ static void do_lasso_select_lattice(Vie
        lattice_foreachScreenVert(vc, do_lasso_select_lattice__doSelect, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
  }
  
 -static void do_lasso_select_armature__doSelectBone(
 -        void *userData, struct EditBone *ebone, const float screen_co_a[2], const float screen_co_b[2])
 +static void do_lasso_select_armature__doSelectBone(void *userData, struct EditBone *ebone, const float screen_co_a[2], const float screen_co_b[2])
  {
        LassoSelectUserData *data = userData;
        bArmature *arm = data->vc->obedit->data;
@@@ -700,7 -724,8 +700,7 @@@ static void do_lasso_select_meta(ViewCo
        mball_foreachScreenElem(vc, do_lasso_select_mball__doSelectElem, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
  }
  
 -static void do_lasso_select_meshobject__doSelectVert(
 -        void *userData, MVert *mv, const float screen_co[2], int UNUSED(index))
 +static void do_lasso_select_meshobject__doSelectVert(void *userData, MVert *mv, const float screen_co[2], int UNUSED(index))
  {
        LassoSelectUserData *data = userData;
  
                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;
        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);
  
  
                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);
  
        }
  
        }
        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;
        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);
  
@@@ -812,22 -837,16 +812,22 @@@ static void view3d_lasso_select
  {
        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);
        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:
@@@ -954,8 -973,8 +954,8 @@@ static int object_select_menu_exec(bCon
        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;
                        }
                }
        {
                /* 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;
                }
        }
@@@ -1011,12 -1030,14 +1011,12 @@@ void VIEW3D_OT_select_menu(wmOperatorTy
        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);
                        }
                }
        }
@@@ -1029,8 -1050,7 +1029,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;
                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;
                                }
@@@ -1138,7 -1158,7 +1138,7 @@@ static int selectbuffer_ret_hits_5(unsi
  /* 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)
  {
        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;
  
                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;
  
                        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;
@@@ -1229,7 -1249,8 +1229,7 @@@ static Base *mouse_select_eval_buffer
          ViewContext *vc, const uint *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;
        
                }
                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)) {
                        }
                }
                
 -              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;
                }
                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;
                                        }
                                }
                        if (basact) break;
                        
                        base = base->next;
 -                      if (base == NULL) base = FIRSTBASE;
 +                      if (base == NULL) base = FIRSTBASE(view_layer);
                        if (base == startbase) break;
                }
        }
  /* 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];
        
        /* setup view context for argument to callbacks */
        view3d_operator_needs_opengl(C);
 +
 +      CTX_data_eval_ctx(C, &eval_ctx);
        ED_view3d_viewcontext_init(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;
@@@ -1359,11 -1375,10 +1359,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;
  
        
        /* setup view context for argument to callbacks */
 +      CTX_data_eval_ctx(C, &eval_ctx);
        ED_view3d_viewcontext_init(C, &vc);
  
        is_obedit = (vc.obedit != NULL);
        }
        
        /* 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 */
                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;
                                }
                                base = base->next;
                                
 -                              if (base == NULL) base = FIRSTBASE;
 +                              if (base == NULL) base = FIRSTBASE(view_layer);
                                if (base == startbase) break;
                        }
                }
                // 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);
  
                        
                        if (has_bones && basact) {
                                if (basact->object->type == OB_CAMERA) {
 -                                      if (BASACT == basact) {
 +                                      if (BASACT(view_layer) == basact) {
                                                int i, hitresult;
                                                bool changed = false;
  
  
                                                        /* 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;
                                                        }
  
                                                                                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;
  
                                                }
                                        }
                                }
 -                              else if (ED_armature_pose_select_pick_with_buffer(
 -                                               scene, basact, buffer, hits, extend, deselect, toggle, do_nearest))
 -                              {
 +                              else if (ED_armature_pose_select_pick_with_buffer(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;
                        }
                }
                
                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 */
                        }
                }
  
@@@ -1619,8 -1635,7 +1619,8 @@@ static void do_paintvert_box_select__do
                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;
  
        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;
  
                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) {
@@@ -1809,8 -1824,7 +1809,8 @@@ static void do_mesh_box_select__doSelec
                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;
        /* 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);
                }
        }
        
                        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);
                }
        }
        
        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;
        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);
        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;
        int a;
  
        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)
+       for (EditBone *ebone = arm->edbo->first; ebone; ebone = ebone->next)
                ebone->flag &= ~BONE_DONE;
        
        if (extend == false && select)
        for (a = 0; a < hits; a++) {
                int index = buffer[(4 * a) + 3];
                if (index != -1) {
-                       ebone = BLI_findlink(arm->edbo, index & ~(BONESEL_ANY));
                        if ((index & 0xFFFF0000) == 0) {
                                continue;
                        }
+                       EditBone *ebone = BLI_findlink(arm->edbo, index & ~(BONESEL_ANY));
                        if ((select == false) || ((ebone->flag & BONE_UNSELECTABLE) == 0)) {
                                if (index & BONESEL_TIP) {
                                        ebone->flag |= BONE_DONE;
                                        if (select) ebone->flag |= BONE_TIPSEL;
                                        else ebone->flag &= ~BONE_TIPSEL;
                                }
-                               
                                if (index & BONESEL_ROOT) {
                                        ebone->flag |= BONE_DONE;
                                        if (select) ebone->flag |= BONE_ROOTSEL;
                        }
                }
        }
-       
        /* now we have to flush tag from parents... */
-       for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
+       for (EditBone *ebone = arm->edbo->first; ebone; ebone = ebone->next) {
                if (ebone->parent && (ebone->flag & BONE_CONNECTED)) {
-                       if (ebone->parent->flag & BONE_DONE)
+                       if (ebone->parent->flag & BONE_DONE) {
                                ebone->flag |= BONE_DONE;
+                       }
                }
        }
-       
        /* only select/deselect entire bones when no points where in the rect */
        for (a = 0; a < hits; a++) {
                int index = buffer[(4 * a) + 3];
                if (index != -1) {
-                       ebone = BLI_findlink(arm->edbo, index & ~(BONESEL_ANY));
                        if (index & BONESEL_BONE) {
+                               EditBone *ebone = BLI_findlink(arm->edbo, index & ~(BONESEL_ANY));
                                if ((select == false) || ((ebone->flag & BONE_UNSELECTABLE) == 0)) {
                                        if (!(ebone->flag & BONE_DONE)) {
-                                               if (select)
+                                               if (select) {
                                                        ebone->flag |= (BONE_ROOTSEL | BONE_TIPSEL | BONE_SELECTED);
-                                               else
+                                               }
+                                               else {
                                                        ebone->flag &= ~(BONE_ROOTSEL | BONE_TIPSEL | BONE_SELECTED);
+                                               }
                                        }
                                }
                        }
        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 */
        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
                        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
         * 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_BEGIN',
 +               * 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 = ED_armature_bone_find_index(base->object, *col & ~(BONESEL_ANY));
                                                if (bone) {
                                                }
                                        }
                                        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 */
                                        
                                        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);
                                        }
                                }
                        }
  
  static int view3d_borderselect_exec(bContext *C, wmOperator *op)
  {
 +      EvaluationContext eval_ctx;
        ViewContext vc;
        rcti rect;
        bool extend;
        view3d_operator_needs_opengl(C);
  
        /* setup view context for argument to callbacks */
 +      CTX_data_eval_ctx(C, &eval_ctx);
        ED_view3d_viewcontext_init(C, &vc);
        
        select = !RNA_boolean_get(op->ptr, "deselect");
                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);
                                }
                                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);
                                }
                        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);
@@@ -2417,13 -2399,13 +2419,13 @@@ static void mesh_circle_doSelectFace(vo
        }
  }
  
 -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);
                        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);
                }
        }
  
                        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);
                }
        }
        
                        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);
                }
        }
  
        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;
  
        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();
        }
  }
  
 -static void paint_vertsel_circle_select_doSelectVert(
 -        void *userData, MVert *mv, const float screen_co[2], int UNUSED(index))
 +static void paint_vertsel_circle_select_doSelectVert(void *userData, MVert *mv, const float screen_co[2], int UNUSED(index))
  {
        CircleSelectUserData *data = userData;
  
                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;
        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();
                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) {
@@@ -2654,7 -2637,7 +2656,7 @@@ static void pose_circle_select(ViewCont
  
                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);
                }
        }
  }
@@@ -2765,12 -2748,11 +2767,12 @@@ static void mball_circle_select(ViewCon
  
  /** 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:
  
  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;
                                }
                        }
  /* not a real operator, only for circle test */
  static int view3d_circle_select_exec(bContext *C, wmOperator *op)
  {
 -      ViewContext vc;
 -      ED_view3d_viewcontext_init(C, &vc);
 -      Object *obact = vc.obact;
 -      Object *obedit = vc.obedit;
 +      Scene *scene = CTX_data_scene(C);
 +      Object *obact = CTX_data_active_object(C);
        const int radius = RNA_int_get(op->ptr, "radius");
        const bool select = !RNA_boolean_get(op->ptr, "deselect");
        const int mval[2] = {RNA_int_get(op->ptr, "x"),
                             RNA_int_get(op->ptr, "y")};
  
 -      if (obedit || BKE_paint_select_elem_test(obact) ||
 +      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);
 +              ED_view3d_viewcontext_init(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) {
 +              else if (obact->mode & OB_MODE_POSE)
                        pose_circle_select(&vc, select, mval, (float)radius);
 -              }
 -              else {
 +              else
                        return PE_circle_select(C, select, mval, (float)radius);
 -              }
        }
        else if (obact && obact->mode & OB_MODE_SCULPT) {
                return OPERATOR_CANCELLED;
        }
        else {
 +              ViewContext vc;
 +              ED_view3d_viewcontext_init(C, &vc);
 +
                if (object_circle_select(&vc, select, mval, (float)radius)) {
 -                      WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, vc.scene);
 +                      WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
                }
        }
 -
 +      
        return OPERATOR_FINISHED;
  }