Merge branch 'master' into blender2.8
authorCampbell Barton <ideasman42@gmail.com>
Sun, 28 Jan 2018 04:20:19 +0000 (15:20 +1100)
committerCampbell Barton <ideasman42@gmail.com>
Sun, 28 Jan 2018 04:58:11 +0000 (15:58 +1100)
1  2 
source/blender/editors/include/ED_view3d.h
source/blender/editors/space_view3d/CMakeLists.txt
source/blender/editors/space_view3d/view3d_edit.c
source/blender/editors/space_view3d/view3d_intern.h
source/blender/editors/space_view3d/view3d_project.c
source/blender/editors/space_view3d/view3d_utils.c
source/blender/editors/space_view3d/view3d_view.c

index 68cd3763f932e53adb73693f67e598e683049aed,6e01245e6dcb7fa9123ba571d2fce1ce6c3c3ff4..7eee053061e59443fa72420f59bba314014f7fae
@@@ -40,10 -40,7 +40,10 @@@ struct BPoint
  struct Base;
  struct BezTriple;
  struct BoundBox;
 +struct Camera;
 +struct Depsgraph;
  struct EditBone;
 +struct EvaluationContext;
  struct ImBuf;
  struct MVert;
  struct Main;
@@@ -52,15 -49,14 +52,15 @@@ struct Nurb
  struct Object;
  struct RV3DMatrixStore;
  struct RegionView3D;
 +struct RenderEngineType;
  struct Scene;
 +struct ViewLayer;
  struct ScrArea;
  struct View3D;
  struct ViewContext;
  struct bContext;
  struct bPoseChannel;
  struct bScreen;
 -struct bglMats;
  struct rctf;
  struct rcti;
  struct wmOperator;
@@@ -70,16 -66,11 +70,16 @@@ struct wmWindowManager
  struct GPUFX;
  struct GPUOffScreen;
  struct GPUFXSettings;
 +struct GPUViewport;
 +struct WorkSpace;
  enum eGPUFXFlags;
  
  /* for derivedmesh drawing callbacks, for view3d_select, .... */
  typedef struct ViewContext {
 +      struct Depsgraph *depsgraph;
        struct Scene *scene;
 +      struct ViewLayer *view_layer;
 +      struct RenderEngineType *engine_type;
        struct Object *obact;
        struct Object *obedit;
        struct ARegion *ar;
@@@ -117,10 -108,10 +117,10 @@@ void ED_view3d_lastview_store(struct Re
  void  ED_view3d_depth_update(struct ARegion *ar);
  float ED_view3d_depth_read_cached(const struct ViewContext *vc, const int mval[2]);
  bool  ED_view3d_depth_read_cached_normal(
 -        const ViewContext *vc, const struct bglMats *mats, const int mval[2],
 +        const ViewContext *vc, const int mval[2],
          float r_normal[3]);
  bool ED_view3d_depth_unproject(
 -        const struct ARegion *ar, const struct bglMats *mats,
 +        const struct ARegion *ar,
          const int mval[2], const double depth,
          float r_location_world[3]);
  void  ED_view3d_depth_tag_update(struct RegionView3D *rv3d);
@@@ -157,20 -148,20 +157,20 @@@ typedef enum 
  
  /* foreach iterators */
  void meshobject_foreachScreenVert(
 -        struct ViewContext *vc,
 +        const struct EvaluationContext *eval_ctx, struct ViewContext *vc,
          void (*func)(void *userData, struct MVert *eve, const float screen_co[2], int index),
          void *userData, const eV3DProjTest clip_flag);
  void mesh_foreachScreenVert(
 -        struct ViewContext *vc,
 +        const struct EvaluationContext *eval_ctx, struct ViewContext *vc,
          void (*func)(void *userData, struct BMVert *eve, const float screen_co[2], int index),
          void *userData, const eV3DProjTest clip_flag);
  void mesh_foreachScreenEdge(
 -        struct ViewContext *vc,
 +        const struct EvaluationContext *eval_ctx, struct ViewContext *vc,
          void (*func)(void *userData, struct BMEdge *eed, const float screen_co_a[2], const float screen_co_b[2],
                       int index),
          void *userData, const eV3DProjTest clip_flag);
  void mesh_foreachScreenFace(
 -        struct ViewContext *vc,
 +        const struct EvaluationContext *eval_ctx, struct ViewContext *vc,
          void (*func)(void *userData, struct BMFace *efa, const float screen_co[2], int index),
          void *userData, const eV3DProjTest clip_flag);
  void nurbs_foreachScreenVert(
@@@ -224,14 -215,14 +224,16 @@@ eV3DProjStatus ED_view3d_project_float_
  eV3DProjStatus ED_view3d_project_float_global(const struct ARegion *ar, const float co[3], float r_co[2], const eV3DProjTest flag);
  eV3DProjStatus ED_view3d_project_float_object(const struct ARegion *ar, const float co[3], float r_co[2], const eV3DProjTest flag);
  
+ float ED_view3d_pixel_size(const struct RegionView3D *rv3d, const float co[3]);
  float ED_view3d_calc_zfac(const struct RegionView3D *rv3d, const float co[3], bool *r_flip);
  bool ED_view3d_clip_segment(const struct RegionView3D *rv3d, float ray_start[3], float ray_end[3]);
  bool ED_view3d_win_to_ray(
 +        const struct Depsgraph *depsgraph,
          const struct ARegion *ar, const struct View3D *v3d, const float mval[2],
          float ray_start[3], float ray_normal[3], const bool do_clip);
  bool ED_view3d_win_to_ray_ex(
 +        const struct Depsgraph *depsgraph,
          const struct ARegion *ar, const struct View3D *v3d, const float mval[2],
          float r_ray_co[3], float r_ray_normal[3], float r_ray_start[3], bool do_clip);
  void ED_view3d_global_to_vector(const struct RegionView3D *rv3d, const float coord[3], float vec[3]);
@@@ -246,14 -237,11 +248,14 @@@ void ED_view3d_win_to_3d_int
  void ED_view3d_win_to_delta(const struct ARegion *ar, const float mval[2], float out[3], const float zfac);
  void ED_view3d_win_to_origin(const struct ARegion *ar, const float mval[2], float out[3]);
  void ED_view3d_win_to_vector(const struct ARegion *ar, const float mval[2], float out[3]);
 -bool ED_view3d_win_to_segment(const struct ARegion *ar, struct View3D *v3d, const float mval[2],
 +bool ED_view3d_win_to_segment(const struct Depsgraph *depsgraph,
 +                              const struct ARegion *ar, struct View3D *v3d, const float mval[2],
                                float r_ray_start[3], float r_ray_end[3], const bool do_clip);
  void ED_view3d_ob_project_mat_get(const struct RegionView3D *v3d, struct Object *ob, float pmat[4][4]);
  void ED_view3d_ob_project_mat_get_from_obmat(const struct RegionView3D *rv3d, float obmat[4][4], float pmat[4][4]);
 -void ED_view3d_unproject(struct bglMats *mats, float out[3], const float x, const float y, const float z);
 +
 +void ED_view3d_project(const struct ARegion *ar, const float world[3], float region[3]);
 +bool ED_view3d_unproject(const struct ARegion *ar, float regionx, float regiony, float regionz, float world[3]);
  
  /* end */
  
@@@ -262,42 -250,34 +264,40 @@@ void ED_view3d_dist_range_get
          const struct View3D *v3d,
          float r_dist_range[2]);
  bool ED_view3d_clip_range_get(
 +        const struct Depsgraph *depsgraph,
          const struct View3D *v3d, const struct RegionView3D *rv3d,
          float *r_clipsta, float *r_clipend, const bool use_ortho_factor);
  bool ED_view3d_viewplane_get(
 +        const struct Depsgraph *depsgraph,
          const struct View3D *v3d, const struct RegionView3D *rv3d, int winxi, int winyi,
          struct rctf *r_viewplane, float *r_clipsta, float *r_clipend, float *r_pixsize);
  
  void ED_view3d_polygon_offset(const struct RegionView3D *rv3d, const float dist);
  
  void ED_view3d_calc_camera_border(
 -        const struct Scene *scene, const struct ARegion *ar,
 +        const struct Scene *scene, const struct Depsgraph *depsgraph,
 +        const struct ARegion *ar,
          const struct View3D *v3d, const struct RegionView3D *rv3d,
          struct rctf *r_viewborder, const bool no_shift);
  void ED_view3d_calc_camera_border_size(
 -        const struct Scene *scene, const struct ARegion *ar,
 +        const struct Scene *scene, const struct Depsgraph *depsgraph,
 +        const struct ARegion *ar,
          const struct View3D *v3d, const struct RegionView3D *rv3d,
          float r_size[2]);
  bool ED_view3d_calc_render_border(
 -        const struct Scene *scene, const struct View3D *v3d,
 -        const struct ARegion *ar, struct rcti *rect);
 +        const struct Scene *scene, const struct Depsgraph *depsgraph,
 +        struct View3D *v3d,
 +        struct ARegion *ar, struct rcti *rect);
  
  void ED_view3d_clipping_calc_from_boundbox(float clip[6][4], const struct BoundBox *clipbb, const bool is_flip);
 -void ED_view3d_clipping_calc(struct BoundBox *bb, float planes[4][4], struct bglMats *mats, const struct rcti *rect);
 +void ED_view3d_clipping_calc(struct BoundBox *bb, float planes[4][4],
 +        const struct ARegion *ar, const struct Object *ob, const struct rcti *rect);
  void ED_view3d_clipping_local(struct RegionView3D *rv3d, float mat[4][4]);
  bool ED_view3d_clipping_test(const struct RegionView3D *rv3d, const float co[3], const bool is_local);
  void ED_view3d_clipping_set(struct RegionView3D *rv3d);
  void ED_view3d_clipping_enable(void);
  void ED_view3d_clipping_disable(void);
  
- float ED_view3d_pixel_size(const struct RegionView3D *rv3d, const float co[3]);
  float ED_view3d_radius_to_dist_persp(const float angle, const float radius);
  float ED_view3d_radius_to_dist_ortho(const float lens, const float radius);
  float ED_view3d_radius_to_dist(
          const char persp, const bool use_aspect,
          const float radius);
  
 -void drawcircball(int mode, const float cent[3], float rad, const float tmat[4][4]);
 +void imm_drawcircball(const float cent[3], float rad, const float tmat[4][4], unsigned pos);
  
  /* backbuffer select and draw support */
 -void          ED_view3d_backbuf_validate(struct ViewContext *vc);
 -struct ImBuf *ED_view3d_backbuf_read(struct ViewContext *vc, int xmin, int ymin, int xmax, int ymax);
 +void          ED_view3d_backbuf_validate(const struct EvaluationContext *eval_ctx, struct ViewContext *vc);
 +struct ImBuf *ED_view3d_backbuf_read(
 +        const struct EvaluationContext *eval_ctx, struct ViewContext *vc, int xmin, int ymin, int xmax, int ymax);
  unsigned int  ED_view3d_backbuf_sample_rect(
 -        struct ViewContext *vc, const int mval[2], int size,
 +        const struct EvaluationContext *eval_ctx, struct ViewContext *vc, const int mval[2], int size,
          unsigned int min, unsigned int max, float *r_dist);
  int          ED_view3d_backbuf_sample_size_clamp(struct ARegion *ar, const float dist);
 -unsigned int ED_view3d_backbuf_sample(struct ViewContext *vc, int x, int y);
 +unsigned int ED_view3d_backbuf_sample(
 +        const struct EvaluationContext *eval_ctx, struct ViewContext *vc, int x, int y);
  
  bool ED_view3d_autodist(
 -        struct Scene *scene, struct ARegion *ar, struct View3D *v3d,
 +        const struct EvaluationContext *eval_ctx, struct Depsgraph *graph, struct ARegion *ar, struct View3D *v3d,
          const int mval[2], float mouse_worldloc[3],
          const bool alphaoverride, const float fallback_depth_pt[3]);
  
  /* only draw so ED_view3d_autodist_simple can be called many times after */
 -void ED_view3d_autodist_init(struct Scene *scene, struct ARegion *ar, struct View3D *v3d, int mode);
 +void ED_view3d_autodist_init(const struct EvaluationContext *eval_ctx, struct Depsgraph *graph, struct ARegion *ar, struct View3D *v3d, int mode);
  bool ED_view3d_autodist_simple(struct ARegion *ar, const int mval[2], float mouse_worldloc[3], int margin, float *force_depth);
  bool ED_view3d_autodist_depth(struct ARegion *ar, const int mval[2], int margin, float *depth);
  bool ED_view3d_autodist_depth_seg(struct ARegion *ar, const int mval_sta[2], const int mval_end[2], int margin, float *depth);
@@@ -346,7 -324,7 +346,7 @@@ void view3d_opengl_select_cache_begin(v
  void view3d_opengl_select_cache_end(void);
  
  int view3d_opengl_select(
 -        struct ViewContext *vc, unsigned int *buffer, unsigned int bufsize, const struct rcti *input,
 +        const struct EvaluationContext *eval_ctx, struct ViewContext *vc, unsigned int *buffer, unsigned int bufsize, const struct rcti *input,
          eV3DSelectMode select_mode);
  
  /* view3d_select.c */
@@@ -355,6 -333,7 +355,6 @@@ void view3d_set_viewcontext(struct bCon
  void view3d_operator_needs_opengl(const struct bContext *C);
  void view3d_region_operator_needs_opengl(struct wmWindow *win, struct ARegion *ar);
  void view3d_opengl_read_pixels(struct ARegion *ar, int x, int y, int w, int h, int format, int type, void *data);
 -void view3d_get_transformation(const struct ARegion *ar, struct RegionView3D *rv3d, struct Object *ob, struct bglMats *mats);
  
  /* XXX should move to BLI_math */
  bool edge_inside_circle(const float cent[2], float radius, const float screen_co_a[2], const float screen_co_b[2]);
@@@ -373,25 -352,20 +373,25 @@@ void ED_view3d_check_mats_rv3d(struct R
  #  define ED_view3d_clear_mats_rv3d(rv3d) (void)(rv3d)
  #  define ED_view3d_check_mats_rv3d(rv3d) (void)(rv3d)
  #endif
 -int ED_view3d_scene_layer_set(int lay, const int *values, int *active);
 +int ED_view3d_view_layer_set(int lay, const int *values, int *active);
  
  struct RV3DMatrixStore *ED_view3d_mats_rv3d_backup(struct RegionView3D *rv3d);
  void                    ED_view3d_mats_rv3d_restore(struct RegionView3D *rv3d, struct RV3DMatrixStore *rv3dmat);
  
 +void  ED_draw_object_facemap(const struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob, const float col[4], const int facemap);
 +
  bool ED_view3d_context_activate(struct bContext *C);
 -void ED_view3d_draw_offscreen_init(struct Scene *scene, struct View3D *v3d);
 +void ED_view3d_draw_offscreen_init(
 +        const struct EvaluationContext *eval_ctx, struct Scene *scene,
 +        struct ViewLayer *view_layer, struct View3D *v3d);
  void ED_view3d_draw_offscreen(
 -        struct Scene *scene, struct View3D *v3d, struct ARegion *ar, int winx, int winy, float viewmat[4][4],
 +        const struct EvaluationContext *eval_ctx, struct Scene *scene,
 +        struct ViewLayer *view_layer, struct View3D *v3d, struct ARegion *ar, int winx, int winy, float viewmat[4][4],
          float winmat[4][4], bool do_bgpic, bool do_sky, bool is_persp, const char *viewname,
          struct GPUFX *fx, struct GPUFXSettings *fx_settings,
 -        struct GPUOffScreen *ofs);
 +        struct GPUOffScreen *ofs, struct GPUViewport *viewport);
  void ED_view3d_draw_setup_view(
 -        struct wmWindow *win, struct Scene *scene, struct ARegion *ar, struct View3D *v3d,
 +        struct wmWindow *win, const struct EvaluationContext *eval_ctx, struct Scene *scene, struct ARegion *ar, struct View3D *v3d,
          float viewmat[4][4], float winmat[4][4], const struct rcti *rect);
  
  enum {
  };
  
  struct ImBuf *ED_view3d_draw_offscreen_imbuf(
 -        struct Scene *scene, struct View3D *v3d, struct ARegion *ar, int sizex, int sizey,
 -        unsigned int flag, unsigned int draw_flags,
 +        const struct EvaluationContext *eval_ctx, struct Scene *scene,
 +        struct ViewLayer *view_layer, struct View3D *v3d, struct ARegion *ar,
 +        int sizex, int sizey, unsigned int flag, unsigned int draw_flags,
          int alpha_mode, int samples, const char *viewname,
          struct GPUFX *fx, struct GPUOffScreen *ofs, char err_out[256]);
  struct ImBuf *ED_view3d_draw_offscreen_imbuf_simple(
 -        struct Scene *scene, struct Object *camera, int width, int height,
 +        const struct EvaluationContext *eval_ctx, struct Scene *scene,
 +        struct ViewLayer *view_layer, struct Object *camera, int width, int height,
          unsigned int flag, unsigned int draw_flags, int drawtype, int alpha_mode,
          int samples, const char *viewname,
          struct GPUFX *fx, struct GPUOffScreen *ofs, char err_out[256]);
  struct Base *ED_view3d_give_base_under_cursor(struct bContext *C, const int mval[2]);
  void ED_view3d_quadview_update(struct ScrArea *sa, struct ARegion *ar, bool do_clip);
  void ED_view3d_update_viewmat(
 -        struct Scene *scene, struct View3D *v3d, struct ARegion *ar,
 +        const struct EvaluationContext *eval_ctx, struct Scene *scene, struct View3D *v3d, struct ARegion *ar,
          float viewmat[4][4], float winmat[4][4], const struct rcti *rect);
  bool ED_view3d_quat_from_axis_view(const char view, float quat[4]);
  char ED_view3d_quat_to_axis_view(const float quat[4], const float epsilon);
@@@ -431,9 -403,12 +431,12 @@@ char ED_view3d_axis_view_opposite(char 
  bool ED_view3d_lock(struct RegionView3D *rv3d);
  
  uint64_t ED_view3d_datamask(const struct Scene *scene, const struct View3D *v3d);
 -uint64_t ED_view3d_screen_datamask(const struct bScreen *screen);
 +uint64_t ED_view3d_screen_datamask(const struct Scene *scene, const struct bScreen *screen);
  
  bool ED_view3d_offset_lock_check(const struct View3D *v3d, const struct RegionView3D *rv3d);
+ void ED_view3d_persp_switch_from_camera(struct View3D *v3d, struct RegionView3D *rv3d, const char persp);
+ bool ED_view3d_persp_ensure(struct View3D *v3d, struct ARegion *ar);
  
  /* camera lock functions */
  bool ED_view3d_camera_lock_check(const struct View3D *v3d, const struct RegionView3D *rv3d);
@@@ -452,6 -427,10 +455,6 @@@ bool ED_view3d_camera_lock_autokey
  
  void ED_view3d_lock_clear(struct View3D *v3d);
  
 -struct BGpic *ED_view3d_background_image_new(struct View3D *v3d);
 -void ED_view3d_background_image_remove(struct View3D *v3d, struct BGpic *bgpic);
 -void ED_view3d_background_image_clear(struct View3D *v3d);
 -
  #define VIEW3D_MARGIN 1.4f
  #define VIEW3D_DIST_FALLBACK 1.0f
  
@@@ -480,11 -459,4 +483,11 @@@ void ED_view3d_shade_update(struct Mai
  
  void ED_view3d_id_remap(struct View3D *v3d, const struct ID *old_id, struct ID *new_id);
  
 +/* view3d_draw_legacy.c */
 +/* Try avoid using these more move out of legacy. */
 +void ED_view3d_draw_bgpic_test(
 +        struct Scene *scene, const struct Depsgraph *depsgraph,
 +        struct ARegion *ar, struct View3D *v3d,
 +        const bool do_foreground, const bool do_camera_frame);
 +
  #endif /* __ED_VIEW3D_H__ */
index 11ef781b229da7799edb9f9de35ef080a4245108,e25a9c04f15b3648bb45d24189b84ed2431b1bc3..d148ef3c6fee7824685abe49579f88faa204100d
@@@ -25,7 -25,6 +25,7 @@@ set(IN
        ../../blenlib
        ../../blentranslation
        ../../bmesh
 +      ../../draw
        ../../gpu
        ../../imbuf
        ../../makesdna
@@@ -53,26 -52,18 +53,27 @@@ set(SR
        view3d_buttons.c
        view3d_camera_control.c
        view3d_draw.c
 +      view3d_draw_legacy.c
        view3d_edit.c
        view3d_fly.c
        view3d_walk.c
        view3d_header.c
        view3d_iterators.c
 +      view3d_manipulator_armature.c
 +      view3d_manipulator_camera.c
 +      view3d_manipulator_empty.c
 +      view3d_manipulator_forcefield.c
 +      view3d_manipulator_lamp.c
 +      view3d_manipulator_navigate.c
 +      view3d_manipulator_navigate_type.c
 +      view3d_manipulator_ruler.c
        view3d_ops.c
        view3d_project.c
        view3d_ruler.c
        view3d_select.c
        view3d_snap.c
        view3d_toolbar.c
+       view3d_utils.c
        view3d_view.c
  
        view3d_intern.h
@@@ -104,4 -95,8 +105,4 @@@ if(WITH_MOD_SMOKE
        add_definitions(-DWITH_SMOKE)
  endif()
  
 -if(WITH_LEGACY_DEPSGRAPH)
 -      add_definitions(-DWITH_LEGACY_DEPSGRAPH)
 -endif()
 -
  blender_add_lib(bf_editor_space_view3d "${SRC}" "${INC}" "${INC_SYS}")
index 647a8b9de3a93e2edc94ff4db072008494ab8f38,861808118cd19b241ecc78a643c8d9a6b1f1e11e..1e368e2d171627ad13b34fe3e01ecaca2978e24a
@@@ -36,7 -36,6 +36,7 @@@
  #include <float.h>
  
  #include "DNA_armature_types.h"
 +#include "DNA_camera_types.h"
  #include "DNA_curve_types.h"
  #include "DNA_object_types.h"
  #include "DNA_scene_types.h"
  
  #include "MEM_guardedalloc.h"
  
- #include "BLI_bitmap_draw_2d.h"
  #include "BLI_blenlib.h"
- #include "BLI_kdopbvh.h"
  #include "BLI_math.h"
  #include "BLI_utildefines.h"
  
  #include "BKE_armature.h"
 +#include "BKE_camera.h"
  #include "BKE_context.h"
  #include "BKE_font.h"
 +#include "BKE_layer.h"
  #include "BKE_library.h"
  #include "BKE_object.h"
  #include "BKE_paint.h"
  #include "BKE_report.h"
--#include "BKE_scene.h"
  #include "BKE_screen.h"
  #include "BKE_action.h"
  
 +#include "DEG_depsgraph.h"
  
--#include "BIF_gl.h"
 -#include "BIF_glutil.h"
  
  #include "WM_api.h"
  #include "WM_types.h"
  
  #include "ED_armature.h"
  #include "ED_particle.h"
- #include "ED_keyframing.h"
  #include "ED_screen.h"
  #include "ED_transform.h"
  #include "ED_mesh.h"
  #include "ED_gpencil.h"
  #include "ED_view3d.h"
  
- #include "DEG_depsgraph_query.h"
 +
  #include "UI_resources.h"
  
  #include "PIL_time.h" /* smoothview */
  
  #include "view3d_intern.h"  /* own include */
  
- static bool view3d_ensure_persp(struct View3D *v3d, ARegion *ar);
- /* -------------------------------------------------------------------- */
- /** \name View Utilities
-  *
-  * Lock the camera to the view-port, allowing view manipulation to transform the camera.
-  * \{ */
- /**
-  * Use to store the last view, before entering camera view.
-  */
- void ED_view3d_lastview_store(RegionView3D *rv3d)
- {
-       copy_qt_qt(rv3d->lviewquat, rv3d->viewquat);
-       rv3d->lview = rv3d->view;
-       if (rv3d->persp != RV3D_CAMOB) {
-               rv3d->lpersp = rv3d->persp;
-       }
- }
- void ED_view3d_lock_clear(View3D *v3d)
- {
-       v3d->ob_centre = NULL;
-       v3d->ob_centre_bone[0] = '\0';
-       v3d->ob_centre_cursor = false;
-       v3d->flag2 &= ~V3D_LOCK_CAMERA;
- }
- bool ED_view3d_offset_lock_check(const  View3D *v3d, const  RegionView3D *rv3d)
- {
-       return (rv3d->persp != RV3D_CAMOB) && (v3d->ob_centre_cursor || v3d->ob_centre);
- }
- /**
-  * For viewport operators that exit camera persp.
-  *
-  * \note This differs from simply setting ``rv3d->persp = persp`` because it
-  * sets the ``ofs`` and ``dist`` values of the viewport so it matches the camera,
-  * otherwise switching out of camera view may jump to a different part of the scene.
-  */
- static void view3d_persp_switch_from_camera(View3D *v3d, RegionView3D *rv3d, const char persp)
- {
-       BLI_assert(rv3d->persp == RV3D_CAMOB);
-       BLI_assert(persp != RV3D_CAMOB);
-       if (v3d->camera) {
-               rv3d->dist = ED_view3d_offset_distance(v3d->camera->obmat, rv3d->ofs, VIEW3D_DIST_FALLBACK);
-               ED_view3d_from_object(v3d->camera, rv3d->ofs, rv3d->viewquat, &rv3d->dist, NULL);
-       }
-       if (!ED_view3d_camera_lock_check(v3d, rv3d)) {
-               rv3d->persp = persp;
-       }
- }
- /** \} */
- /* -------------------------------------------------------------------- */
- /** \name Camera Lock API
-  *
-  * Lock the camera to the view-port, allowing view manipulation to transform the camera.
-  * \{ */
- /**
-  * \return true when the view-port is locked to its camera.
-  */
- bool ED_view3d_camera_lock_check(const View3D *v3d, const RegionView3D *rv3d)
- {
-       return ((v3d->camera) &&
-               (!ID_IS_LINKED(v3d->camera)) &&
-               (v3d->flag2 & V3D_LOCK_CAMERA) &&
-               (rv3d->persp == RV3D_CAMOB));
- }
- /**
-  * Apply the camera object transformation to the view-port.
-  * (needed so we can use regular view-port manipulation operators, that sync back to the camera).
-  */
- void ED_view3d_camera_lock_init_ex(View3D *v3d, RegionView3D *rv3d, const bool calc_dist)
- {
-       if (ED_view3d_camera_lock_check(v3d, rv3d)) {
-               if (calc_dist) {
-                       /* using a fallback dist is OK here since ED_view3d_from_object() compensates for it */
-                       rv3d->dist = ED_view3d_offset_distance(v3d->camera->obmat, rv3d->ofs, VIEW3D_DIST_FALLBACK);
-               }
-               ED_view3d_from_object(v3d->camera, rv3d->ofs, rv3d->viewquat, &rv3d->dist, NULL);
-       }
- }
- void ED_view3d_camera_lock_init(View3D *v3d, RegionView3D *rv3d)
- {
-       ED_view3d_camera_lock_init_ex(v3d, rv3d, true);
- }
- /**
-  * Apply the view-port transformation back to the camera object.
-  *
-  * \return true if the camera is moved.
-  */
- bool ED_view3d_camera_lock_sync(View3D *v3d, RegionView3D *rv3d)
- {
-       if (ED_view3d_camera_lock_check(v3d, rv3d)) {
-               ObjectTfmProtectedChannels obtfm;
-               Object *root_parent;
-               if ((U.uiflag & USER_CAM_LOCK_NO_PARENT) == 0 && (root_parent = v3d->camera->parent)) {
-                       Object *ob_update;
-                       float tmat[4][4];
-                       float imat[4][4];
-                       float view_mat[4][4];
-                       float diff_mat[4][4];
-                       float parent_mat[4][4];
-                       while (root_parent->parent) {
-                               root_parent = root_parent->parent;
-                       }
-                       ED_view3d_to_m4(view_mat, rv3d->ofs, rv3d->viewquat, rv3d->dist);
-                       normalize_m4_m4(tmat, v3d->camera->obmat);
-                       invert_m4_m4(imat, tmat);
-                       mul_m4_m4m4(diff_mat, view_mat, imat);
-                       mul_m4_m4m4(parent_mat, diff_mat, root_parent->obmat);
-                       BKE_object_tfm_protected_backup(root_parent, &obtfm);
-                       BKE_object_apply_mat4(root_parent, parent_mat, true, false);
-                       BKE_object_tfm_protected_restore(root_parent, &obtfm, root_parent->protectflag);
-                       ob_update = v3d->camera;
-                       while (ob_update) {
-                               DEG_id_tag_update(&ob_update->id, OB_RECALC_OB);
-                               WM_main_add_notifier(NC_OBJECT | ND_TRANSFORM, ob_update);
-                               ob_update = ob_update->parent;
-                       }
-               }
-               else {
-                       /* always maintain the same scale */
-                       const short protect_scale_all = (OB_LOCK_SCALEX | OB_LOCK_SCALEY | OB_LOCK_SCALEZ);
-                       BKE_object_tfm_protected_backup(v3d->camera, &obtfm);
-                       ED_view3d_to_object(v3d->camera, rv3d->ofs, rv3d->viewquat, rv3d->dist);
-                       BKE_object_tfm_protected_restore(v3d->camera, &obtfm, v3d->camera->protectflag | protect_scale_all);
-                       DEG_id_tag_update(&v3d->camera->id, OB_RECALC_OB);
-                       WM_main_add_notifier(NC_OBJECT | ND_TRANSFORM, v3d->camera);
-               }
-               return true;
-       }
-       else {
-               return false;
-       }
- }
- bool ED_view3d_camera_autokey(
-         Scene *scene, ID *id_key,
-         struct bContext *C, const bool do_rotate, const bool do_translate)
- {
-       if (autokeyframe_cfra_can_key(scene, id_key)) {
-               const float cfra = (float)CFRA;
-               ListBase dsources = {NULL, NULL};
-               /* add data-source override for the camera object */
-               ANIM_relative_keyingset_add_source(&dsources, id_key, NULL, NULL);
-               /* insert keyframes
-                * 1) on the first frame
-                * 2) on each subsequent frame
-                *    TODO: need to check in future that frame changed before doing this
-                */
-               if (do_rotate) {
-                       struct KeyingSet *ks = ANIM_get_keyingset_for_autokeying(scene, ANIM_KS_ROTATION_ID);
-                       ANIM_apply_keyingset(C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, cfra);
-               }
-               if (do_translate) {
-                       struct KeyingSet *ks = ANIM_get_keyingset_for_autokeying(scene, ANIM_KS_LOCATION_ID);
-                       ANIM_apply_keyingset(C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, cfra);
-               }
-               /* free temp data */
-               BLI_freelistN(&dsources);
-               return true;
-       }
-       else {
-               return false;
-       }
- }
- /**
-  * Call after modifying a locked view.
-  *
-  * \note Not every view edit currently auto-keys (numpad for eg),
-  * this is complicated because of smoothview.
-  */
- bool ED_view3d_camera_lock_autokey(
-         View3D *v3d, RegionView3D *rv3d,
-         struct bContext *C, const bool do_rotate, const bool do_translate)
- {
-       /* similar to ED_view3d_cameracontrol_update */
-       if (ED_view3d_camera_lock_check(v3d, rv3d)) {
-               Scene *scene = CTX_data_scene(C);
-               ID *id_key;
-               Object *root_parent;
-               if ((U.uiflag & USER_CAM_LOCK_NO_PARENT) == 0 && (root_parent = v3d->camera->parent)) {
-                       while (root_parent->parent) {
-                               root_parent = root_parent->parent;
-                       }
-                       id_key = &root_parent->id;
-               }
-               else {
-                       id_key = &v3d->camera->id;
-               }
-               return ED_view3d_camera_autokey(scene, id_key, C, do_rotate, do_translate);
-       }
-       else {
-               return false;
-       }
- }
- /** \} */
- /* -------------------------------------------------------------------- */
- /** \name Box View Support
-  *
-  * Use with quad-split so each view is clipped by the bounds of each view axis.
-  * \{ */
- static void view3d_boxview_clip(ScrArea *sa)
- {
-       ARegion *ar;
-       BoundBox *bb = MEM_callocN(sizeof(BoundBox), "clipbb");
-       float clip[6][4];
-       float x1 = 0.0f, y1 = 0.0f, z1 = 0.0f, ofs[3] = {0.0f, 0.0f, 0.0f};
-       int val;
-       /* create bounding box */
-       for (ar = sa->regionbase.first; ar; ar = ar->next) {
-               if (ar->regiontype == RGN_TYPE_WINDOW) {
-                       RegionView3D *rv3d = ar->regiondata;
-                       if (rv3d->viewlock & RV3D_BOXCLIP) {
-                               if (ELEM(rv3d->view, RV3D_VIEW_TOP, RV3D_VIEW_BOTTOM)) {
-                                       if (ar->winx > ar->winy) x1 = rv3d->dist;
-                                       else x1 = ar->winx * rv3d->dist / ar->winy;
-                                       if (ar->winx > ar->winy) y1 = ar->winy * rv3d->dist / ar->winx;
-                                       else y1 = rv3d->dist;
-                                       copy_v2_v2(ofs, rv3d->ofs);
-                               }
-                               else if (ELEM(rv3d->view, RV3D_VIEW_FRONT, RV3D_VIEW_BACK)) {
-                                       ofs[2] = rv3d->ofs[2];
-                                       if (ar->winx > ar->winy) z1 = ar->winy * rv3d->dist / ar->winx;
-                                       else z1 = rv3d->dist;
-                               }
-                       }
-               }
-       }
-       for (val = 0; val < 8; val++) {
-               if (ELEM(val, 0, 3, 4, 7))
-                       bb->vec[val][0] = -x1 - ofs[0];
-               else
-                       bb->vec[val][0] =  x1 - ofs[0];
-               if (ELEM(val, 0, 1, 4, 5))
-                       bb->vec[val][1] = -y1 - ofs[1];
-               else
-                       bb->vec[val][1] =  y1 - ofs[1];
-               if (val > 3)
-                       bb->vec[val][2] = -z1 - ofs[2];
-               else
-                       bb->vec[val][2] =  z1 - ofs[2];
-       }
-       /* normals for plane equations */
-       normal_tri_v3(clip[0], bb->vec[0], bb->vec[1], bb->vec[4]);
-       normal_tri_v3(clip[1], bb->vec[1], bb->vec[2], bb->vec[5]);
-       normal_tri_v3(clip[2], bb->vec[2], bb->vec[3], bb->vec[6]);
-       normal_tri_v3(clip[3], bb->vec[3], bb->vec[0], bb->vec[7]);
-       normal_tri_v3(clip[4], bb->vec[4], bb->vec[5], bb->vec[6]);
-       normal_tri_v3(clip[5], bb->vec[0], bb->vec[2], bb->vec[1]);
-       /* then plane equations */
-       for (val = 0; val < 6; val++) {
-               clip[val][3] = -dot_v3v3(clip[val], bb->vec[val % 5]);
-       }
-       /* create bounding box */
-       for (ar = sa->regionbase.first; ar; ar = ar->next) {
-               if (ar->regiontype == RGN_TYPE_WINDOW) {
-                       RegionView3D *rv3d = ar->regiondata;
-                       if (rv3d->viewlock & RV3D_BOXCLIP) {
-                               rv3d->rflag |= RV3D_CLIPPING;
-                               memcpy(rv3d->clip, clip, sizeof(clip));
-                               if (rv3d->clipbb) MEM_freeN(rv3d->clipbb);
-                               rv3d->clipbb = MEM_dupallocN(bb);
-                       }
-               }
-       }
-       MEM_freeN(bb);
- }
- /**
-  * Find which axis values are shared between both views and copy to \a rv3d_dst
-  * taking axis flipping into account.
-  */
- static void view3d_boxview_sync_axis(RegionView3D *rv3d_dst, RegionView3D *rv3d_src)
- {
-       /* absolute axis values above this are considered to be set (will be ~1.0f) */
-       const float axis_eps = 0.5f;
-       float viewinv[4];
-       /* use the view rotation to identify which axis to sync on */
-       float view_axis_all[4][3] = {
-           {1.0f, 0.0f, 0.0f},
-           {0.0f, 1.0f, 0.0f},
-           {1.0f, 0.0f, 0.0f},
-           {0.0f, 1.0f, 0.0f}};
-       float *view_src_x = &view_axis_all[0][0];
-       float *view_src_y = &view_axis_all[1][0];
-       float *view_dst_x = &view_axis_all[2][0];
-       float *view_dst_y = &view_axis_all[3][0];
-       int i;
-       /* we could use rv3d->viewinv, but better not depend on view matrix being updated */
-       if (UNLIKELY(ED_view3d_quat_from_axis_view(rv3d_src->view, viewinv) == false)) {
-               return;
-       }
-       invert_qt_normalized(viewinv);
-       mul_qt_v3(viewinv, view_src_x);
-       mul_qt_v3(viewinv, view_src_y);
-       if (UNLIKELY(ED_view3d_quat_from_axis_view(rv3d_dst->view, viewinv) == false)) {
-               return;
-       }
-       invert_qt_normalized(viewinv);
-       mul_qt_v3(viewinv, view_dst_x);
-       mul_qt_v3(viewinv, view_dst_y);
-       /* check source and dest have a matching axis */
-       for (i = 0; i < 3; i++) {
-               if (((fabsf(view_src_x[i]) > axis_eps) || (fabsf(view_src_y[i]) > axis_eps)) &&
-                   ((fabsf(view_dst_x[i]) > axis_eps) || (fabsf(view_dst_y[i]) > axis_eps)))
-               {
-                       rv3d_dst->ofs[i] = rv3d_src->ofs[i];
-               }
-       }
- }
- /* sync center/zoom view of region to others, for view transforms */
- static void view3d_boxview_sync(ScrArea *sa, ARegion *ar)
- {
-       ARegion *artest;
-       RegionView3D *rv3d = ar->regiondata;
-       short clip = 0;
-       for (artest = sa->regionbase.first; artest; artest = artest->next) {
-               if (artest != ar && artest->regiontype == RGN_TYPE_WINDOW) {
-                       RegionView3D *rv3dtest = artest->regiondata;
-                       if (rv3dtest->viewlock & RV3D_LOCKED) {
-                               rv3dtest->dist = rv3d->dist;
-                               view3d_boxview_sync_axis(rv3dtest, rv3d);
-                               clip |= rv3dtest->viewlock & RV3D_BOXCLIP;
-                               ED_region_tag_redraw(artest);
-                       }
-               }
-       }
-       if (clip) {
-               view3d_boxview_clip(sa);
-       }
- }
- /* for home, center etc */
- void view3d_boxview_copy(ScrArea *sa, ARegion *ar)
- {
-       ARegion *artest;
-       RegionView3D *rv3d = ar->regiondata;
-       bool clip = false;
-       for (artest = sa->regionbase.first; artest; artest = artest->next) {
-               if (artest != ar && artest->regiontype == RGN_TYPE_WINDOW) {
-                       RegionView3D *rv3dtest = artest->regiondata;
-                       if (rv3dtest->viewlock) {
-                               rv3dtest->dist = rv3d->dist;
-                               copy_v3_v3(rv3dtest->ofs, rv3d->ofs);
-                               ED_region_tag_redraw(artest);
-                               clip |= ((rv3dtest->viewlock & RV3D_BOXCLIP) != 0);
-                       }
-               }
-       }
-       if (clip) {
-               view3d_boxview_clip(sa);
-       }
- }
- /* 'clip' is used to know if our clip setting has changed */
- void ED_view3d_quadview_update(ScrArea *sa, ARegion *ar, bool do_clip)
- {
-       ARegion *ar_sync = NULL;
-       RegionView3D *rv3d = ar->regiondata;
-       short viewlock;
-       /* this function copies flags from the first of the 3 other quadview
-        * regions to the 2 other, so it assumes this is the region whose
-        * properties are always being edited, weak */
-       viewlock = rv3d->viewlock;
-       if ((viewlock & RV3D_LOCKED) == 0) {
-               do_clip = (viewlock & RV3D_BOXCLIP) != 0;
-               viewlock = 0;
-       }
-       else if ((viewlock & RV3D_BOXVIEW) == 0 && (viewlock & RV3D_BOXCLIP) != 0) {
-               do_clip = true;
-               viewlock &= ~RV3D_BOXCLIP;
-       }
-       for (; ar; ar = ar->prev) {
-               if (ar->alignment == RGN_ALIGN_QSPLIT) {
-                       rv3d = ar->regiondata;
-                       rv3d->viewlock = viewlock;
-                       if (do_clip && (viewlock & RV3D_BOXCLIP) == 0) {
-                               rv3d->rflag &= ~RV3D_BOXCLIP;
-                       }
-                       /* use ar_sync so we sync with one of the aligned views below
-                        * else the view jumps on changing view settings like 'clip'
-                        * since it copies from the perspective view */
-                       ar_sync = ar;
-               }
-       }
-       if (rv3d->viewlock & RV3D_BOXVIEW) {
-               view3d_boxview_sync(sa, ar_sync ? ar_sync : sa->regionbase.last);
-       }
-       /* ensure locked regions have an axis, locked user views don't make much sense */
-       if (viewlock & RV3D_LOCKED) {
-               int index_qsplit = 0;
-               for (ar = sa->regionbase.first; ar; ar = ar->next) {
-                       if (ar->alignment == RGN_ALIGN_QSPLIT) {
-                               rv3d = ar->regiondata;
-                               if (rv3d->viewlock) {
-                                       if (!RV3D_VIEW_IS_AXIS(rv3d->view)) {
-                                               rv3d->view = ED_view3d_lock_view_from_index(index_qsplit);
-                                               rv3d->persp = RV3D_ORTHO;
-                                               ED_view3d_lock(rv3d);
-                                       }
-                               }
-                               index_qsplit++;
-                       }
-               }
-       }
-       ED_area_tag_redraw(sa);
- }
- /** \} */
  /* -------------------------------------------------------------------- */
  /** \name Generic View Operator Custom-Data
   * \{ */
  
  typedef struct ViewOpsData {
        /* context pointers (assigned by viewops_data_alloc) */
 +      const Depsgraph *depsgraph;
        Scene *scene;
        ScrArea *sa;
        ARegion *ar;
@@@ -634,7 -152,6 +155,7 @@@ static void viewops_data_alloc(bContex
  
        /* store data */
        op->customdata = vod;
 +      vod->depsgraph = CTX_data_depsgraph(C);
        vod->scene = CTX_data_scene(C);
        vod->sa = CTX_wm_area(C);
        vod->ar = CTX_wm_region(C);
@@@ -663,8 -180,7 +184,8 @@@ static bool view3d_orbit_calc_center(bC
        bool is_set = false;
  
        Scene *scene = CTX_data_scene(C);
 -      Object *ob_act = OBACT;
 +      ViewLayer *view_layer = CTX_data_view_layer(C);
 +      Object *ob_act = OBACT(view_layer);
  
        if (ob_act && (ob_act->mode & OB_MODE_ALL_PAINT) &&
            /* with weight-paint + pose-mode, fall through to using calculateTransformCenter */
        }
        else if (ob_act == NULL || ob_act->mode == OB_MODE_OBJECT) {
                /* object mode use boundbox centers */
 -              View3D *v3d = CTX_wm_view3d(C);
                Base *base;
                unsigned int tot = 0;
                float select_center[3];
  
                zero_v3(select_center);
 -              for (base = FIRSTBASE; base; base = base->next) {
 -                      if (TESTBASE(v3d, base)) {
 +              for (base = FIRSTBASE(view_layer); base; base = base->next) {
 +                      if (TESTBASE(base)) {
                                /* use the boundbox if we can */
                                Object *ob = base->object;
  
@@@ -769,7 -286,7 +290,7 @@@ static enum eViewOpsOrbit viewops_orbit
  /**
   * Calculate the values for #ViewOpsData
   *
-  * \param use_ensure_persp: When enabled run #view3d_ensure_persp this may switch out of
+  * \param use_ensure_persp: When enabled run #ED_view3d_persp_ensure this may switch out of
   * camera view when orbiting or switch from ortho to perspective when auto-persp is enabled.
   * Some operations don't require this (view zoom/pan or ndof where subtle rotation is common
   * so we don't want it to trigger auto-perspective).
@@@ -783,18 -300,14 +304,18 @@@ static void viewops_data_create_ex
  
        /* we need the depth info before changing any viewport options */
        if (orbit_mode & VIEWOPS_ORBIT_DEPTH) {
 +              EvaluationContext eval_ctx;
 +              struct Depsgraph *graph = CTX_data_depsgraph(C);
                float fallback_depth_pt[3];
  
 +              CTX_data_eval_ctx(C, &eval_ctx);
 +
                view3d_operator_needs_opengl(C); /* needed for zbuf drawing */
  
                negate_v3_v3(fallback_depth_pt, rv3d->ofs);
  
                vod->use_dyn_ofs = ED_view3d_autodist(
 -                      vod->scene, vod->ar, vod->v3d,
 +                      &eval_ctx, graph, vod->ar, vod->v3d,
                        event->mval, vod->dyn_ofs, true, fallback_depth_pt);
        }
        else {
        }
  
        if (use_ensure_persp) {
-               if (view3d_ensure_persp(vod->v3d, vod->ar)) {
+               if (ED_view3d_persp_ensure(vod->v3d, vod->ar)) {
                        /* If we're switching from camera view to the perspective one,
                         * need to tag viewport update, so camera vuew and borders
                         * are properly updated.
@@@ -912,9 -425,8 +433,9 @@@ static void viewops_data_create(bContex
  static void viewops_data_free(bContext *C, wmOperator *op)
  {
        ARegion *ar;
 +#if 0
        Paint *p = BKE_paint_get_active_from_context(C);
 -
 +#endif
        if (op->customdata) {
                ViewOpsData *vod = op->customdata;
                ar = vod->ar;
                ar = CTX_wm_region(C);
        }
  
 +#if 0
        if (p && (p->flags & PAINT_FAST_NAVIGATE))
 +#endif
                ED_region_tag_redraw(ar);
  }
  
  /** \} */
  
  /* -------------------------------------------------------------------- */
- /** \name View Rotate
+ /** \name View Rotate Operator
   * \{ */
  
  enum {
@@@ -1272,37 -782,6 +793,6 @@@ static int viewrotate_modal(bContext *C
        return ret;
  }
  
- /**
-  * Action to take when rotating the view,
-  * handle auto-persp and logic for switching out of views.
-  *
-  * shared with NDOF.
-  */
- static bool view3d_ensure_persp(struct View3D *v3d, ARegion *ar)
- {
-       RegionView3D *rv3d = ar->regiondata;
-       const bool autopersp = (U.uiflag & USER_AUTOPERSP) != 0;
-       BLI_assert((rv3d->viewlock & RV3D_LOCKED) == 0);
-       if (ED_view3d_camera_lock_check(v3d, rv3d))
-               return false;
-       if (rv3d->persp != RV3D_PERSP) {
-               if (rv3d->persp == RV3D_CAMOB) {
-                       /* If autopersp and previous view was an axis one, switch back to PERSP mode, else reuse previous mode. */
-                       char persp = (autopersp && RV3D_VIEW_IS_AXIS(rv3d->lview)) ? RV3D_PERSP : rv3d->lpersp;
-                       view3d_persp_switch_from_camera(v3d, rv3d, persp);
-               }
-               else if (autopersp && RV3D_VIEW_IS_AXIS(rv3d->view)) {
-                       rv3d->persp = RV3D_PERSP;
-               }
-               return true;
-       }
-       return false;
- }
  static int viewrotate_invoke(bContext *C, wmOperator *op, const wmEvent *event)
  {
        ViewOpsData *vod;
@@@ -1537,7 -1016,7 +1027,7 @@@ static void view3d_ndof_orbit
  
        BLI_assert((rv3d->viewlock & RV3D_LOCKED) == 0);
  
-       view3d_ensure_persp(v3d, ar);
+       ED_view3d_persp_ensure(v3d, ar);
  
        rv3d->view = RV3D_VIEW_USER;
  
@@@ -2050,8 -1529,9 +1540,9 @@@ static void viewmove_apply(ViewOpsData 
  
                add_v3_v3(vod->rv3d->ofs, dvec);
  
-               if (vod->rv3d->viewlock & RV3D_BOXVIEW)
+               if (vod->rv3d->viewlock & RV3D_BOXVIEW) {
                        view3d_boxview_sync(vod->sa, vod->ar);
+               }
        }
  
        vod->oldx = x;
@@@ -2210,7 -1690,7 +1701,7 @@@ void viewzoom_modal_keymap(wmKeyConfig 
  }
  
  static void view_zoom_mouseloc_camera(
 -        Scene *scene, View3D *v3d,
 +        Scene *scene, const Depsgraph *depsgraph, View3D *v3d,
          ARegion *ar, float dfac, int mx, int my)
  {
        RegionView3D *rv3d = ar->regiondata;
                float pt_dst[2];
                float delta_px[2];
  
 -              ED_view3d_calc_camera_border(scene, ar, v3d, rv3d, &camera_frame_old, false);
 +              ED_view3d_calc_camera_border(scene, depsgraph, ar, v3d, rv3d, &camera_frame_old, false);
                BLI_rctf_translate(&camera_frame_old, ar->winrct.xmin, ar->winrct.ymin);
  
                rv3d->camzoom = camzoom_new;
                CLAMP(rv3d->camzoom, RV3D_CAMZOOM_MIN, RV3D_CAMZOOM_MAX);
  
 -              ED_view3d_calc_camera_border(scene, ar, v3d, rv3d, &camera_frame_new, false);
 +              ED_view3d_calc_camera_border(scene, depsgraph, ar, v3d, rv3d, &camera_frame_new, false);
                BLI_rctf_translate(&camera_frame_new, ar->winrct.xmin, ar->winrct.ymin);
  
                BLI_rctf_transform_pt_v(&camera_frame_new, &camera_frame_old, pt_dst, pt_src);
@@@ -2381,7 -1861,7 +1872,7 @@@ static void viewzoom_apply_camera
                /* calculate inverted, then invert again (needed because of camera zoom scaling) */
                zfac = 1.0f / zfac;
                view_zoom_mouseloc_camera(
 -                      vod->scene, vod->v3d,
 +                      vod->scene, vod->depsgraph, vod->v3d,
                        vod->ar, zfac, vod->oldx, vod->oldy);
        }
  
@@@ -2414,8 -1894,9 +1905,9 @@@ static void viewzoom_apply_3d
        /* these limits were in old code too */
        CLAMP(vod->rv3d->dist, dist_range[0], dist_range[1]);
  
-       if (vod->rv3d->viewlock & RV3D_BOXVIEW)
+       if (vod->rv3d->viewlock & RV3D_BOXVIEW) {
                view3d_boxview_sync(vod->sa, vod->ar);
+       }
  
        ED_view3d_camera_lock_sync(vod->v3d, vod->rv3d);
  
@@@ -2495,7 -1976,6 +1987,7 @@@ static int viewzoom_modal(bContext *C, 
  
  static int viewzoom_exec(bContext *C, wmOperator *op)
  {
 +      const Depsgraph *depsgraph = CTX_data_depsgraph(C);
        Scene *scene = CTX_data_scene(C);
        View3D *v3d;
        RegionView3D *rv3d;
                const float step = 1.2f;
                /* this min and max is also in viewmove() */
                if (use_cam_zoom) {
 -                      view_zoom_mouseloc_camera(scene, v3d, ar, step, mx, my);
 +                      view_zoom_mouseloc_camera(scene, depsgraph, v3d, ar, step, mx, my);
                }
                else {
                        if (rv3d->dist < dist_range[1]) {
        else {
                const float step = 1.0f / 1.2f;
                if (use_cam_zoom) {
 -                      view_zoom_mouseloc_camera(scene, v3d, ar, step, mx, my);
 +                      view_zoom_mouseloc_camera(scene, depsgraph, v3d, ar, step, mx, my);
                }
                else {
                        if (rv3d->dist > dist_range[0]) {
                }
        }
  
-       if (rv3d->viewlock & RV3D_BOXVIEW)
+       if (rv3d->viewlock & RV3D_BOXVIEW) {
                view3d_boxview_sync(sa, ar);
+       }
  
        ED_view3d_depth_tag_update(rv3d);
  
@@@ -2741,8 -2222,9 +2234,9 @@@ static void viewdolly_apply(ViewOpsDat
        if (zfac != 1.0f)
                view_dolly_mouseloc(vod->ar, vod->ofs, vod->mousevec, zfac);
  
-       if (vod->rv3d->viewlock & RV3D_BOXVIEW)
+       if (vod->rv3d->viewlock & RV3D_BOXVIEW) {
                view3d_boxview_sync(vod->sa, vod->ar);
+       }
  
        ED_view3d_camera_lock_sync(vod->v3d, vod->rv3d);
  
@@@ -2842,8 -2324,9 +2336,9 @@@ static int viewdolly_exec(bContext *C, 
                view_dolly_mouseloc(ar, rv3d->ofs, mousevec, 1.8f);
        }
  
-       if (rv3d->viewlock & RV3D_BOXVIEW)
+       if (rv3d->viewlock & RV3D_BOXVIEW) {
                view3d_boxview_sync(sa, ar);
+       }
  
        ED_view3d_depth_tag_update(rv3d);
  
@@@ -2881,7 -2364,7 +2376,7 @@@ static int viewdolly_invoke(bContext *C
        if (vod->rv3d->persp != RV3D_PERSP) {
                if (vod->rv3d->persp == RV3D_CAMOB) {
                        /* ignore rv3d->lpersp because dolly only makes sense in perspective mode */
-                       view3d_persp_switch_from_camera(vod->v3d, vod->rv3d, RV3D_PERSP);
+                       ED_view3d_persp_switch_from_camera(vod->v3d, vod->rv3d, RV3D_PERSP);
                }
                else {
                        vod->rv3d->persp = RV3D_PERSP;
@@@ -2963,9 -2446,18 +2458,16 @@@ void VIEW3D_OT_dolly(wmOperatorType *ot
        RNA_def_int(ot->srna, "my", 0, 0, INT_MAX, "Zoom Position Y", "", 0, INT_MAX);
  }
  
 -
 -static void view3d_from_minmax(
 -        bContext *C, View3D *v3d, ARegion *ar,
 -        const float min[3], const float max[3],
 -        bool ok_dist, const int smooth_viewtx)
+ /** \} */
+ /* -------------------------------------------------------------------- */
+ /** \name View All Operator
+  *
+  * Move & Zoom the view to fit all of it's contents.
+  * \{ */
 +static void view3d_from_minmax(bContext *C, View3D *v3d, ARegion *ar,
 +                               const float min[3], const float max[3],
 +                               bool ok_dist, const int smooth_viewtx)
  {
        RegionView3D *rv3d = ar->regiondata;
        float afm[3];
@@@ -3056,7 -2548,6 +2558,7 @@@ static int view3d_all_exec(bContext *C
        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;
        float *curs;
        const bool use_all_regions = RNA_boolean_get(op->ptr, "use_all_regions");
                INIT_MINMAX(min, max);
        }
  
 -      for (base = scene->base.first; base; base = base->next) {
 -              if (BASE_VISIBLE(v3d, base)) {
 +      for (base = view_layer->object_bases.first; base; base = base->next) {
 +              if (BASE_VISIBLE(base)) {
                        changed = true;
  
                        if (skip_camera && base->object == v3d->camera) {
@@@ -3149,12 -2640,9 +2651,12 @@@ static int viewselected_exec(bContext *
        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);
        bGPdata *gpd = CTX_data_gpencil_data(C);
        const bool is_gp_edit = ((gpd) && (gpd->flag & GP_DATA_STROKE_EDITMODE));
 -      Object *ob = OBACT;
 +      const bool is_face_map = ((is_gp_edit == false) && ar->manipulator_map &&
 +                                WM_manipulatormap_is_any_selected(ar->manipulator_map));
 +      Object *ob = OBACT(view_layer);
        Object *obedit = CTX_data_edit_object(C);
        float min[3], max[3];
        bool ok = false, ok_dist = true;
        const int smooth_viewtx = WM_operator_smooth_viewtx_get(op);
  
        INIT_MINMAX(min, max);
 -
 -      if (is_gp_edit) {
 +      if (is_gp_edit || is_face_map) {
                ob = NULL;
        }
  
                /* hard-coded exception, we look for the one selected armature */
                /* this is weak code this way, we should make a generic active/selection callback interface once... */
                Base *base;
 -              for (base = scene->base.first; base; base = base->next) {
 -                      if (TESTBASELIB(v3d, base)) {
 +              for (base = view_layer->object_bases.first; base; base = base->next) {
 +                      if (TESTBASELIB(base)) {
                                if (base->object->type == OB_ARMATURE)
                                        if (base->object->mode & OB_MODE_POSE)
                                                break;
                }
                CTX_DATA_END;
        }
 +      else if (is_face_map) {
 +              ok = WM_manipulatormap_minmax(ar->manipulator_map, true, true, min, max);
 +      }
        else if (obedit) {
                ok = ED_view3d_minmax_verts(obedit, min, max);    /* only selected */
        }
                ok = paintface_minmax(ob, min, max);
        }
        else if (ob && (ob->mode & OB_MODE_PARTICLE_EDIT)) {
 -              ok = PE_minmax(scene, min, max);
 +              ok = PE_minmax(scene, view_layer, min, max);
        }
        else if (ob &&
                 (ob->mode & (OB_MODE_SCULPT | OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT | OB_MODE_TEXTURE_PAINT)))
        }
        else {
                Base *base;
 -              for (base = FIRSTBASE; base; base = base->next) {
 -                      if (TESTBASE(v3d, base)) {
 +              for (base = FIRSTBASE(view_layer); base; base = base->next) {
 +                      if (TESTBASE(base)) {
  
                                if (skip_camera && base->object == v3d->camera) {
                                        continue;
@@@ -3424,21 -2910,18 +2926,21 @@@ static int viewcenter_pick_invoke(bCont
  {
        View3D *v3d = CTX_wm_view3d(C);
        RegionView3D *rv3d = CTX_wm_region_view3d(C);
 -      Scene *scene = CTX_data_scene(C);
        ARegion *ar = CTX_wm_region(C);
  
        if (rv3d) {
 +              EvaluationContext eval_ctx;
 +              struct Depsgraph *graph = CTX_data_depsgraph(C);
                float new_ofs[3];
                const int smooth_viewtx = WM_operator_smooth_viewtx_get(op);
  
 +              CTX_data_eval_ctx(C, &eval_ctx);
 +
                ED_view3d_smooth_view_force_finish(C, v3d, ar);
  
                view3d_operator_needs_opengl(C);
  
 -              if (ED_view3d_autodist(scene, ar, v3d, event->mval, new_ofs, false, NULL)) {
 +              if (ED_view3d_autodist(&eval_ctx, graph, ar, v3d, event->mval, new_ofs, false, NULL)) {
                        /* pass */
                }
                else {
@@@ -3478,7 -2961,6 +2980,7 @@@ void VIEW3D_OT_view_center_pick(wmOpera
  
  static int view3d_center_camera_exec(bContext *C, wmOperator *UNUSED(op)) /* was view3d_home() in 2.4x */
  {
 +      const Depsgraph *depsgraph = CTX_data_depsgraph(C);
        Scene *scene = CTX_data_scene(C);
        float xfac, yfac;
        float size[2];
  
        rv3d->camdx = rv3d->camdy = 0.0f;
  
 -      ED_view3d_calc_camera_border_size(scene, ar, v3d, rv3d, size);
 +      ED_view3d_calc_camera_border_size(scene, depsgraph, ar, v3d, rv3d, size);
  
        /* 4px is just a little room from the edge of the area */
        xfac = (float)ar->winx / (float)(size[0] + 4);
@@@ -3562,7 -3044,6 +3064,7 @@@ void VIEW3D_OT_view_center_lock(wmOpera
  
  static int render_border_exec(bContext *C, wmOperator *op)
  {
 +      const Depsgraph *depsgraph = CTX_data_depsgraph(C);
        View3D *v3d = CTX_wm_view3d(C);
        ARegion *ar = CTX_wm_region(C);
        RegionView3D *rv3d = ED_view3d_context_rv3d(C);
        /* calculate range */
  
        if (rv3d->persp == RV3D_CAMOB) {
 -              ED_view3d_calc_camera_border(scene, ar, v3d, rv3d, &vb, false);
 +              ED_view3d_calc_camera_border(scene, depsgraph, ar, v3d, rv3d, &vb, false);
        }
        else {
                vb.xmin = 0;
@@@ -3719,10 -3200,10 +3221,10 @@@ void VIEW3D_OT_clear_render_border(wmOp
  
  static int view3d_zoom_border_exec(bContext *C, wmOperator *op)
  {
 +      EvaluationContext eval_ctx;
        ARegion *ar = CTX_wm_region(C);
        View3D *v3d = CTX_wm_view3d(C);
        RegionView3D *rv3d = CTX_wm_region_view3d(C);
 -      Scene *scene = CTX_data_scene(C);
        const int smooth_viewtx = WM_operator_smooth_viewtx_get(op);
  
        /* Zooms in on a border drawn by the user */
        float new_ofs[3];
  
        /* ZBuffer depth vars */
 -      bglMats mats;
        float depth_close = FLT_MAX;
 -      double cent[2],  p[3];
 +      float p[3];
  
        /* note; otherwise opengl won't work */
        view3d_operator_needs_opengl(C);
  
 +      CTX_data_eval_ctx(C, &eval_ctx);
 +
        /* get border select values using rna */
        WM_operator_properties_border_to_rcti(op, &rect);
  
        ED_view3d_dist_range_get(v3d, dist_range);
  
        /* Get Z Depths, needed for perspective, nice for ortho */
 -      bgl_get_mats(&mats);
 -      ED_view3d_draw_depth(scene, ar, v3d, true);
 +      ED_view3d_draw_depth(&eval_ctx, CTX_data_depsgraph(C), ar, v3d, true);
        
        {
                /* avoid allocating the whole depth buffer */
                MEM_SAFE_FREE(depth_temp.depths);
        }
  
 -      cent[0] = (((double)rect.xmin) + ((double)rect.xmax)) / 2;
 -      cent[1] = (((double)rect.ymin) + ((double)rect.ymax)) / 2;
 +      float centx = (((float)rect.xmin) + ((float)rect.xmax)) / 2;
 +      float centy = (((float)rect.ymin) + ((float)rect.ymax)) / 2;
  
        if (rv3d->is_persp) {
 -              double p_corner[3];
 +              float p_corner[3];
  
                /* no depths to use, we cant do anything! */
                if (depth_close == FLT_MAX) {
                        return OPERATOR_CANCELLED;
                }
                /* convert border to 3d coordinates */
 -              if ((!gluUnProject(cent[0], cent[1], depth_close,
 -                                 mats.modelview, mats.projection, (GLint *)mats.viewport,
 -                                 &p[0], &p[1], &p[2])) ||
 -                  (!gluUnProject((double)rect.xmin, (double)rect.ymin, depth_close,
 -                                 mats.modelview, mats.projection, (GLint *)mats.viewport,
 -                                 &p_corner[0], &p_corner[1], &p_corner[2])))
 +              if ((!ED_view3d_unproject(ar, centx, centy, depth_close, p)) ||
 +                  (!ED_view3d_unproject(ar, rect.xmin, rect.ymin, depth_close, p_corner)))
                {
                        return OPERATOR_CANCELLED;
                }
  
 -              dvec[0] = p[0] - p_corner[0];
 -              dvec[1] = p[1] - p_corner[1];
 -              dvec[2] = p[2] - p_corner[2];
 -
 -              new_ofs[0] = -p[0];
 -              new_ofs[1] = -p[1];
 -              new_ofs[2] = -p[2];
 +              sub_v3_v3v3(dvec, p, p_corner);
 +              negate_v3_v3(new_ofs, p);
  
                new_dist = len_v3(dvec);
  
                new_dist = rv3d->dist;
  
                /* convert the drawn rectangle into 3d space */
 -              if (depth_close != FLT_MAX && gluUnProject(cent[0], cent[1], depth_close,
 -                                                         mats.modelview, mats.projection, (GLint *)mats.viewport,
 -                                                         &p[0], &p[1], &p[2]))
 -              {
 -                      new_ofs[0] = -p[0];
 -                      new_ofs[1] = -p[1];
 -                      new_ofs[2] = -p[2];
 +              if (depth_close != FLT_MAX && ED_view3d_unproject(ar, centx, centy, depth_close, p)) {
 +                      negate_v3_v3(new_ofs, p);
                }
                else {
                        float mval_f[2];
                C, v3d, ar, smooth_viewtx,
                &(const V3D_SmoothParams) {.ofs = new_ofs, .dist = &new_dist});
  
-       if (rv3d->viewlock & RV3D_BOXVIEW)
+       if (rv3d->viewlock & RV3D_BOXVIEW) {
                view3d_boxview_sync(CTX_wm_area(C), ar);
+       }
  
        return OPERATOR_FINISHED;
  }
@@@ -3891,13 -3387,13 +3394,13 @@@ void VIEW3D_OT_zoom_border(wmOperatorTy
   * Sets the view to 1:1 camera/render-pixel.
   * \{ */
  
 -static void view3d_set_1_to_1_viewborder(Scene *scene, ARegion *ar, View3D *v3d)
 +static void view3d_set_1_to_1_viewborder(Scene *scene, const Depsgraph *depsgraph, ARegion *ar, View3D *v3d)
  {
        RegionView3D *rv3d = ar->regiondata;
        float size[2];
        int im_width = (scene->r.size * scene->r.xsch) / 100;
        
 -      ED_view3d_calc_camera_border_size(scene, ar, v3d, rv3d, size);
 +      ED_view3d_calc_camera_border_size(scene, depsgraph, ar, v3d, rv3d, size);
  
        rv3d->camzoom = BKE_screen_view3d_zoom_from_fac((float)im_width / size[0]);
        CLAMP(rv3d->camzoom, RV3D_CAMZOOM_MIN, RV3D_CAMZOOM_MAX);
  
  static int view3d_zoom_1_to_1_camera_exec(bContext *C, wmOperator *UNUSED(op))
  {
 +      const Depsgraph *depsgraph = CTX_data_depsgraph(C);
        Scene *scene = CTX_data_scene(C);
  
        View3D *v3d;
        /* no NULL check is needed, poll checks */
        ED_view3d_context_user_region(C, &v3d, &ar);
  
 -      view3d_set_1_to_1_viewborder(scene, ar, v3d);
 +      view3d_set_1_to_1_viewborder(scene, depsgraph, ar, v3d);
  
        WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, v3d);
  
@@@ -4052,7 -3547,6 +3555,7 @@@ static int viewnumpad_exec(bContext *C
        ARegion *ar;
        RegionView3D *rv3d;
        Scene *scene = CTX_data_scene(C);
 +      ViewLayer *view_layer = CTX_data_view_layer(C);
        static int perspo = RV3D_PERSP;
        int viewnum, nextperspo;
        bool align_active;
                        /* lastview -  */
  
                        if (rv3d->persp != RV3D_CAMOB) {
 -                              Object *ob = OBACT;
 +                              Object *ob = OBACT(view_layer);
  
                                if (!rv3d->smooth_timer) {
                                        /* store settings of current view before allowing overwriting with camera view
                                        v3d->camera = ob;
  
                                if (v3d->camera == NULL)
 -                                      v3d->camera = BKE_scene_camera_find(scene);
 +                                      v3d->camera = BKE_view_layer_camera_find(view_layer);
  
                                /* couldnt find any useful camera, bail out */
                                if (v3d->camera == NULL)
@@@ -4229,7 -3723,7 +3732,7 @@@ static int vieworbit_exec(bContext *C, 
                        float quat_new[4];
  
                        if (view_opposite == RV3D_VIEW_USER) {
-                               view3d_ensure_persp(v3d, ar);
+                               ED_view3d_persp_ensure(v3d, ar);
                        }
  
                        if (ELEM(orbitdir, V3D_VIEW_STEPLEFT, V3D_VIEW_STEPRIGHT)) {
@@@ -4350,8 -3844,9 +3853,9 @@@ static void viewroll_apply(ViewOpsData 
                view3d_orbit_apply_dyn_ofs(vod->rv3d->ofs, vod->ofs, vod->oldquat, vod->rv3d->viewquat, vod->dyn_ofs);
        }
  
-       if (vod->rv3d->viewlock & RV3D_BOXVIEW)
+       if (vod->rv3d->viewlock & RV3D_BOXVIEW) {
                view3d_boxview_sync(vod->sa, vod->ar);
+       }
  
        ED_view3d_camera_lock_sync(vod->v3d, vod->rv3d);
  
@@@ -4687,11 -4182,11 +4191,11 @@@ void VIEW3D_OT_navigate(wmOperatorType 
  /** \name Background Image Add Operator
   * \{ */
  
 -static BGpic *background_image_add(bContext *C)
 +static CameraBGImage *background_image_add(bContext *C)
  {
 -      View3D *v3d = CTX_wm_view3d(C);
 +      Camera *cam = CTX_data_pointer_get_type(C, "camera", &RNA_Camera).data;
  
 -      return ED_view3d_background_image_new(v3d);
 +      return BKE_camera_background_image_new(cam);
  }
  
  static int background_image_add_exec(bContext *C, wmOperator *UNUSED(op))
  
  static int background_image_add_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
  {
 -      View3D *v3d = CTX_wm_view3d(C);
 +      Camera *cam = CTX_data_pointer_get_type(C, "camera", &RNA_Camera).data;
        Image *ima;
 -      BGpic *bgpic;
 +      CameraBGImage *bgpic;
        
        ima = (Image *)WM_operator_drop_load_path(C, op, ID_IM);
        /* may be NULL, continue anyway */
        bgpic = background_image_add(C);
        bgpic->ima = ima;
  
 -      v3d->flag |= V3D_DISPBGPICS;
 -      
 -      WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, v3d);
 -      
 +      cam->flag |= CAM_SHOW_BG_IMAGE;
 +
 +      WM_event_add_notifier(C, NC_CAMERA | ND_DRAW_RENDER_VIEWPORT, cam);
 +
        return OPERATOR_FINISHED;
  }
  
@@@ -4732,7 -4227,7 +4236,7 @@@ void VIEW3D_OT_background_image_add(wmO
        /* api callbacks */
        ot->invoke = background_image_add_invoke;
        ot->exec   = background_image_add_exec;
 -      ot->poll   = ED_operator_view3d_active;
 +      ot->poll   = ED_operator_camera;
  
        /* flags */
        ot->flag   = OPTYPE_UNDO;
  
  static int background_image_remove_exec(bContext *C, wmOperator *op)
  {
 -      View3D *v3d = CTX_wm_view3d(C);
 +      Camera *cam = CTX_data_pointer_get_type(C, "camera", &RNA_Camera).data;
        const int index = RNA_int_get(op->ptr, "index");
 -      BGpic *bgpic_rem = BLI_findlink(&v3d->bgpicbase, index);
 +      CameraBGImage *bgpic_rem = BLI_findlink(&cam->bg_images, index);
  
        if (bgpic_rem) {
 -              if (bgpic_rem->source == V3D_BGPIC_IMAGE) {
 +              if (bgpic_rem->source == CAM_BGIMG_SOURCE_IMAGE) {
                        id_us_min((ID *)bgpic_rem->ima);
                }
 -              else if (bgpic_rem->source == V3D_BGPIC_MOVIE) {
 +              else if (bgpic_rem->source == CAM_BGIMG_SOURCE_MOVIE) {
                        id_us_min((ID *)bgpic_rem->clip);
                }
  
 -              ED_view3d_background_image_remove(v3d, bgpic_rem);
 +              BKE_camera_background_image_remove(cam, bgpic_rem);
 +
 +              WM_event_add_notifier(C, NC_CAMERA | ND_DRAW_RENDER_VIEWPORT, cam);
  
 -              WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, v3d);
                return OPERATOR_FINISHED;
        }
        else {
@@@ -4785,7 -4279,7 +4289,7 @@@ void VIEW3D_OT_background_image_remove(
  
        /* api callbacks */
        ot->exec   = background_image_remove_exec;
 -      ot->poll   = ED_operator_view3d_active;
 +      ot->poll   = ED_operator_camera;
  
        /* flags */
        ot->flag   = 0;
@@@ -4825,8 -4319,9 +4329,8 @@@ void ED_view3d_clipping_local(RegionVie
  
  static int view3d_clipping_exec(bContext *C, wmOperator *op)
  {
 +      ARegion *ar = CTX_wm_region(C);
        RegionView3D *rv3d = CTX_wm_region_view3d(C);
 -      ViewContext vc;
 -      bglMats mats;
        rcti rect;
  
        WM_operator_properties_border_to_rcti(op, &rect);
        rv3d->rflag |= RV3D_CLIPPING;
        rv3d->clipbb = MEM_callocN(sizeof(BoundBox), "clipbb");
  
 -      /* note; otherwise opengl won't work */
 -      view3d_operator_needs_opengl(C);
 -
 -      view3d_set_viewcontext(C, &vc);
 -      view3d_get_transformation(vc.ar, vc.rv3d, NULL, &mats); /* NULL because we don't want it in object space */
 -      ED_view3d_clipping_calc(rv3d->clipbb, rv3d->clip, &mats, &rect);
 +      /* NULL object because we don't want it in object space */
 +      ED_view3d_clipping_calc(rv3d->clipbb, rv3d->clip, ar, NULL, &rect);
  
        return OPERATOR_FINISHED;
  }
@@@ -4857,7 -4356,6 +4361,7 @@@ static int view3d_clipping_invoke(bCont
        }
  }
  
 +/* toggles */
  void VIEW3D_OT_clip_border(wmOperatorType *ot)
  {
  
  /* note: cannot use event->mval here (called by object_add() */
  void ED_view3d_cursor3d_position(bContext *C, float fp[3], const int mval[2])
  {
 -      Scene *scene = CTX_data_scene(C);
        ARegion *ar = CTX_wm_region(C);
        View3D *v3d = CTX_wm_view3d(C);
        RegionView3D *rv3d = ar->regiondata;
        }
  
        if (U.uiflag & USER_ZBUF_CURSOR) {  /* maybe this should be accessed some other way */
 +              EvaluationContext eval_ctx;
 +              struct Depsgraph *graph = CTX_data_depsgraph(C);
 +
 +              CTX_data_eval_ctx(C, &eval_ctx);
 +
                view3d_operator_needs_opengl(C);
 -              if (ED_view3d_autodist(scene, ar, v3d, mval, fp, true, NULL))
 +              if (ED_view3d_autodist(&eval_ctx, graph, ar, v3d, mval, fp, true, NULL)) {
                        depth_used = true;
 +              }
        }
  
        if (depth_used == false) {
@@@ -4999,6 -4492,50 +4503,6 @@@ void VIEW3D_OT_cursor3d(wmOperatorType 
  
  /** \} */
  
 -/* -------------------------------------------------------------------- */
 -/** \name Transform Manipulator Operator
 - * \{ */
 -
 -static int manipulator_invoke(bContext *C, wmOperator *op, const wmEvent *event)
 -{
 -      View3D *v3d = CTX_wm_view3d(C);
 -
 -      if (!(v3d->twflag & V3D_USE_MANIPULATOR)) return OPERATOR_PASS_THROUGH;
 -      if (!(v3d->twflag & V3D_DRAW_MANIPULATOR)) return OPERATOR_PASS_THROUGH;
 -
 -      /* note; otherwise opengl won't work */
 -      view3d_operator_needs_opengl(C);
 -
 -      if (BIF_do_manipulator(C, event, op) == 0)
 -              return OPERATOR_PASS_THROUGH;
 -
 -      return OPERATOR_FINISHED;
 -}
 -
 -void VIEW3D_OT_manipulator(wmOperatorType *ot)
 -{
 -      PropertyRNA *prop;
 -
 -      /* identifiers */
 -      ot->name = "3D Manipulator";
 -      ot->description = "Manipulate selected item by axis";
 -      ot->idname = "VIEW3D_OT_manipulator";
 -
 -      /* api callbacks */
 -      ot->invoke = manipulator_invoke;
 -
 -      ot->poll = ED_operator_view3d_active;
 -
 -      /* properties to pass to transform */
 -      Transform_Properties(ot, P_CONSTRAINT);
 -
 -      prop = RNA_def_boolean(ot->srna, "use_planar_constraint", false, "Planar Constraint", "Limit the transformation to the "
 -                             "two axes that have not been clicked (translate/scale only)");
 -      RNA_def_property_flag(prop, PROP_SKIP_SAVE | PROP_HIDDEN);
 -}
 -
 -/** \} */
 -
  /* -------------------------------------------------------------------- */
  /** \name Enable Transform Manipulator Operator
   * \{ */
@@@ -5077,307 -4614,3 +4581,3 @@@ void VIEW3D_OT_toggle_render(wmOperator
  }
  
  /** \} */
- /* -------------------------------------------------------------------- */
- /** \name View Distance Utilities
-  * \{ */
- static float view_autodist_depth_margin(ARegion *ar, const int mval[2], int margin)
- {
-       ViewDepths depth_temp = {0};
-       rcti rect;
-       float depth_close;
-       if (margin == 0) {
-               /* Get Z Depths, needed for perspective, nice for ortho */
-               rect.xmin = mval[0];
-               rect.ymin = mval[1];
-               rect.xmax = mval[0] + 1;
-               rect.ymax = mval[1] + 1;
-       }
-       else {
-               BLI_rcti_init_pt_radius(&rect, mval, margin);
-       }
-       view3d_update_depths_rect(ar, &depth_temp, &rect);
-       depth_close = view3d_depth_near(&depth_temp);
-       MEM_SAFE_FREE(depth_temp.depths);
-       return depth_close;
- }
- /**
-  * Get the world-space 3d location from a screen-space 2d point.
-  *
-  * \param mval: Input screen-space pixel location.
-  * \param mouse_worldloc: Output world-space location.
-  * \param fallback_depth_pt: Use this points depth when no depth can be found.
-  */
- bool ED_view3d_autodist(
-         const EvaluationContext *eval_ctx, struct Depsgraph *graph, ARegion *ar, View3D *v3d,
-         const int mval[2], float mouse_worldloc[3],
-         const bool alphaoverride, const float fallback_depth_pt[3])
- {
-       float depth_close;
-       int margin_arr[] = {0, 2, 4};
-       int i;
-       bool depth_ok = false;
-       /* Get Z Depths, needed for perspective, nice for ortho */
-       ED_view3d_draw_depth(eval_ctx, graph, ar, v3d, alphaoverride);
-       /* Attempt with low margin's first */
-       i = 0;
-       do {
-               depth_close = view_autodist_depth_margin(ar, mval, margin_arr[i++] * U.pixelsize);
-               depth_ok = (depth_close != FLT_MAX);
-       } while ((depth_ok == false) && (i < ARRAY_SIZE(margin_arr)));
-       if (depth_ok) {
-               float centx = (float)mval[0] + 0.5f;
-               float centy = (float)mval[1] + 0.5f;
-               if (ED_view3d_unproject(ar, centx, centy, depth_close, mouse_worldloc)) {
-                       return true;
-               }
-       }
-       if (fallback_depth_pt) {
-               ED_view3d_win_to_3d_int(v3d, ar, fallback_depth_pt, mval, mouse_worldloc);
-               return true;
-       }
-       else {
-               return false;
-       }
- }
- void ED_view3d_autodist_init(
-         const EvaluationContext *eval_ctx, struct Depsgraph *graph,
-         ARegion *ar, View3D *v3d, int mode)
- {
-       /* Get Z Depths, needed for perspective, nice for ortho */
-       switch (mode) {
-               case 0:
-                       ED_view3d_draw_depth(eval_ctx, graph, ar, v3d, true);
-                       break;
-               case 1:
-               {
-                       Scene *scene = DEG_get_evaluated_scene(graph);
-                       ED_view3d_draw_depth_gpencil(eval_ctx, scene, ar, v3d);
-                       break;
-               }
-       }
- }
- /* no 4x4 sampling, run #ED_view3d_autodist_init first */
- bool ED_view3d_autodist_simple(ARegion *ar, const int mval[2], float mouse_worldloc[3],
-                                int margin, float *force_depth)
- {
-       float depth;
-       /* Get Z Depths, needed for perspective, nice for ortho */
-       if (force_depth)
-               depth = *force_depth;
-       else
-               depth = view_autodist_depth_margin(ar, mval, margin);
-       if (depth == FLT_MAX)
-               return false;
-       float centx = (float)mval[0] + 0.5f;
-       float centy = (float)mval[1] + 0.5f;
-       return ED_view3d_unproject(ar, centx, centy, depth, mouse_worldloc);
- }
- bool ED_view3d_autodist_depth(ARegion *ar, const int mval[2], int margin, float *depth)
- {
-       *depth = view_autodist_depth_margin(ar, mval, margin);
-       return (*depth != FLT_MAX);
- }
- static bool depth_segment_cb(int x, int y, void *userData)
- {
-       struct { ARegion *ar; int margin; float depth; } *data = userData;
-       int mval[2];
-       float depth;
-       mval[0] = x;
-       mval[1] = y;
-       depth = view_autodist_depth_margin(data->ar, mval, data->margin);
-       if (depth != FLT_MAX) {
-               data->depth = depth;
-               return 0;
-       }
-       else {
-               return 1;
-       }
- }
- bool ED_view3d_autodist_depth_seg(
-         ARegion *ar, const int mval_sta[2], const int mval_end[2],
-         int margin, float *depth)
- {
-       struct { ARegion *ar; int margin; float depth; } data = {NULL};
-       int p1[2];
-       int p2[2];
-       data.ar = ar;
-       data.margin = margin;
-       data.depth = FLT_MAX;
-       copy_v2_v2_int(p1, mval_sta);
-       copy_v2_v2_int(p2, mval_end);
-       BLI_bitmap_draw_2d_line_v2v2i(p1, p2, depth_segment_cb, &data);
-       *depth = data.depth;
-       return (*depth != FLT_MAX);
- }
- /* problem - ofs[3] can be on same location as camera itself.
-  * Blender needs proper dist value for zoom.
-  * use fallback_dist to override small values
-  */
- float ED_view3d_offset_distance(float mat[4][4], const float ofs[3], const float fallback_dist)
- {
-       float pos[4] = {0.0f, 0.0f, 0.0f, 1.0f};
-       float dir[4] = {0.0f, 0.0f, 1.0f, 0.0f};
-       float dist;
-       
-       mul_m4_v4(mat, pos);
-       add_v3_v3(pos, ofs);
-       mul_m4_v4(mat, dir);
-       normalize_v3(dir);
-       dist = dot_v3v3(pos, dir);
-       if ((dist < FLT_EPSILON) && (fallback_dist != 0.0f)) {
-               dist = fallback_dist;
-       }
-       return dist;
- }
- /**
-  * Set the dist without moving the view (compensate with #RegionView3D.ofs)
-  *
-  * \note take care that viewinv is up to date, #ED_view3d_update_viewmat first.
-  */
- void ED_view3d_distance_set(RegionView3D *rv3d, const float dist)
- {
-       float viewinv[4];
-       float tvec[3];
-       BLI_assert(dist >= 0.0f);
-       copy_v3_fl3(tvec, 0.0f, 0.0f, rv3d->dist - dist);
-       /* rv3d->viewinv isn't always valid */
- #if 0
-       mul_mat3_m4_v3(rv3d->viewinv, tvec);
- #else
-       invert_qt_qt_normalized(viewinv, rv3d->viewquat);
-       mul_qt_v3(viewinv, tvec);
- #endif
-       sub_v3_v3(rv3d->ofs, tvec);
-       rv3d->dist = dist;
- }
- /** \} */
- /* -------------------------------------------------------------------- */
- /** \name View Transform Utilities
-  * \{ */
- /**
-  * Set the view transformation from a 4x4 matrix.
-  *
-  * \param mat The view 4x4 transformation matrix to assign.
-  * \param ofs The view offset, normally from RegionView3D.ofs.
-  * \param quat The view rotation, quaternion normally from RegionView3D.viewquat.
-  * \param dist The view distance from ofs, normally from RegionView3D.dist.
-  */
- void ED_view3d_from_m4(float mat[4][4], float ofs[3], float quat[4], float *dist)
- {
-       float nmat[3][3];
-       /* dist depends on offset */
-       BLI_assert(dist == NULL || ofs != NULL);
-       copy_m3_m4(nmat, mat);
-       normalize_m3(nmat);
-       /* Offset */
-       if (ofs)
-               negate_v3_v3(ofs, mat[3]);
-       /* Quat */
-       if (quat) {
-               mat3_normalized_to_quat(quat, nmat);
-               invert_qt_normalized(quat);
-       }
-       if (ofs && dist) {
-               madd_v3_v3fl(ofs, nmat[2], *dist);
-       }
- }
- /**
-  * Calculate the view transformation matrix from RegionView3D input.
-  * The resulting matrix is equivalent to RegionView3D.viewinv
-  * \param mat The view 4x4 transformation matrix to calculate.
-  * \param ofs The view offset, normally from RegionView3D.ofs.
-  * \param quat The view rotation, quaternion normally from RegionView3D.viewquat.
-  * \param dist The view distance from ofs, normally from RegionView3D.dist.
-  */
- void ED_view3d_to_m4(float mat[4][4], const float ofs[3], const float quat[4], const float dist)
- {
-       float iviewquat[4] = {-quat[0], quat[1], quat[2], quat[3]};
-       float dvec[3] = {0.0f, 0.0f, dist};
-       quat_to_mat4(mat, iviewquat);
-       mul_mat3_m4_v3(mat, dvec);
-       sub_v3_v3v3(mat[3], dvec, ofs);
- }
- /**
-  * Set the RegionView3D members from an objects transformation and optionally lens.
-  * \param ob The object to set the view to.
-  * \param ofs The view offset to be set, normally from RegionView3D.ofs.
-  * \param quat The view rotation to be set, quaternion normally from RegionView3D.viewquat.
-  * \param dist The view distance from ofs to be set, normally from RegionView3D.dist.
-  * \param lens The view lens angle set for cameras and lamps, normally from View3D.lens.
-  */
- void ED_view3d_from_object(Object *ob, float ofs[3], float quat[4], float *dist, float *lens)
- {
-       ED_view3d_from_m4(ob->obmat, ofs, quat, dist);
-       if (lens) {
-               CameraParams params;
-               BKE_camera_params_init(&params);
-               BKE_camera_params_from_object(&params, ob);
-               *lens = params.lens;
-       }
- }
- /**
-  * Set the object transformation from RegionView3D members.
-  * \param ob The object which has the transformation assigned.
-  * \param ofs The view offset, normally from RegionView3D.ofs.
-  * \param quat The view rotation, quaternion normally from RegionView3D.viewquat.
-  * \param dist The view distance from ofs, normally from RegionView3D.dist.
-  */
- void ED_view3d_to_object(Object *ob, const float ofs[3], const float quat[4], const float dist)
- {
-       float mat[4][4];
-       ED_view3d_to_m4(mat, ofs, quat, dist);
-       BKE_object_apply_mat4(ob, mat, true, true);
- }
- /** \} */
index 6724c04658f5329ffb0c16370dd0b53bacdeb31a,6237bfe669332b92235276fd27925ffc4a787fdb..5e34bc188f0e79a57e4da62ec5fa1dd1072527af
@@@ -37,9 -37,7 +37,9 @@@
  
  struct ARegion;
  struct ARegionType;
 +struct Base;
  struct BoundBox;
 +struct Gwn_Batch;
  struct DerivedMesh;
  struct Object;
  struct SmokeDomainSettings;
@@@ -48,12 -46,9 +48,12 @@@ struct bContext
  struct bMotionPath;
  struct bPoseChannel;
  struct Mesh;
 +struct ViewLayer;
  struct wmOperatorType;
 -struct wmWindowManager;
  struct wmKeyConfig;
 +struct wmManipulatorGroupType;
 +struct wmManipulatorType;
 +struct wmWindowManager;
  
  /* drawing flags: */
  enum {
@@@ -104,6 -99,7 +104,6 @@@ void VIEW3D_OT_view_orbit(struct wmOper
  void VIEW3D_OT_view_roll(struct wmOperatorType *ot);
  void VIEW3D_OT_clip_border(struct wmOperatorType *ot);
  void VIEW3D_OT_cursor3d(struct wmOperatorType *ot);
 -void VIEW3D_OT_manipulator(struct wmOperatorType *ot);
  void VIEW3D_OT_enable_manipulator(struct wmOperatorType *ot);
  void VIEW3D_OT_render_border(struct wmOperatorType *ot);
  void VIEW3D_OT_clear_render_border(struct wmOperatorType *ot);
@@@ -111,6 -107,7 +111,7 @@@ void VIEW3D_OT_zoom_border(struct wmOpe
  void VIEW3D_OT_toggle_render(struct wmOperatorType *ot);
  
  void view3d_boxview_copy(ScrArea *sa, ARegion *ar);
+ void view3d_boxview_sync(ScrArea *sa, ARegion *ar);
  
  void view3d_orbit_apply_dyn_ofs(
          float r_ofs[3], const float ofs_old[3], const float viewquat_old[4],
@@@ -147,28 -144,16 +148,28 @@@ void draw_motion_paths_cleanup(View3D *
  
  /* drawobject.c */
  void draw_object(
 -        Scene *scene, struct ARegion *ar, View3D *v3d,
 -        Base *base, const short dflag);
 +        const struct EvaluationContext *eval_ctx, Scene *scene, struct ViewLayer *view_layer, struct ARegion *ar, View3D *v3d,
 +        struct Base *base, const short dflag);
  void draw_object_select(
 -        Scene *scene, ARegion *ar, View3D *v3d,
 +        const struct EvaluationContext *eval_ctx, Scene *scene, struct ViewLayer *view_layer, struct ARegion *ar, View3D *v3d,
          Base *base, const short dflag);
  
 -bool draw_glsl_material(Scene *scene, struct Object *ob, View3D *v3d, const char dt);
 -void draw_object_instance(Scene *scene, View3D *v3d, RegionView3D *rv3d, struct Object *ob, const char dt, int outline);
 -void draw_object_backbufsel(Scene *scene, View3D *v3d, RegionView3D *rv3d, struct Object *ob);
 -void drawaxes(const float viewmat_local[4][4], float size, char drawtype);
 +void draw_mesh_object_outline(View3D *v3d, struct Object *ob, struct DerivedMesh *dm, const unsigned char ob_wire_col[4]);
 +
 +bool draw_glsl_material(Scene *scene, struct ViewLayer *view_layer, struct Object *ob, View3D *v3d, const char dt);
 +void draw_object_instance(const struct EvaluationContext *eval_ctx, Scene *scene, struct ViewLayer *view_layer, View3D *v3d, RegionView3D *rv3d, struct Object *ob, const char dt, int outline, const float wire_col[4]);
 +void draw_object_backbufsel(const struct EvaluationContext *eval_ctx, Scene *scene, View3D *v3d, RegionView3D *rv3d, struct Object *ob);
 +
 +void draw_object_wire_color(Scene *scene, struct ViewLayer *, Base *base, unsigned char r_ob_wire_col[4]);
 +void drawaxes(const float viewmat_local[4][4], float size, char drawtype, const unsigned char color[4]);
 +void drawlamp(View3D *v3d, RegionView3D *rv3d, Base *base,
 +              const char dt, const short dflag, const unsigned char ob_wire_col[4],
 +              const bool is_obact);
 +void drawcamera(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base,
 +                const short dflag, const unsigned char ob_wire_col[4]);
 +void drawspeaker(const unsigned char ob_wire_col[3]);
 +void draw_bounding_volume(struct Object *ob, char type, const unsigned char ob_wire_col[4]);
 +void draw_rigidbody_shape(struct Object *ob, const unsigned char ob_wire_col[4]);
  
  void view3d_cached_text_draw_begin(void);
  void view3d_cached_text_draw_add(const float co[3],
@@@ -190,12 -175,12 +191,12 @@@ int view3d_effective_drawtype(const str
  
  /* drawarmature.c */
  bool draw_armature(
 -        Scene *scene, View3D *v3d, ARegion *ar, Base *base,
 +        const struct EvaluationContext *eval_ctx, Scene *scene, struct ViewLayer *view_layer, View3D *v3d, ARegion *ar, Base *base,
          const short dt, const short dflag, const unsigned char ob_wire_col[4],
          const bool is_outline);
  
  /* drawmesh.c */
 -void draw_mesh_textured(Scene *scene, View3D *v3d, RegionView3D *rv3d,
 +void draw_mesh_textured(Scene *scene, struct ViewLayer *view_layer, View3D *v3d, RegionView3D *rv3d,
                          struct Object *ob, struct DerivedMesh *dm, const int draw_flags);
  void draw_mesh_face_select(
          struct RegionView3D *rv3d, struct Mesh *me, struct DerivedMesh *dm,
@@@ -216,25 -201,19 +217,25 @@@ void draw_sim_debug_data(Scene *scene, 
  
  /* view3d_draw.c */
  void view3d_main_region_draw(const struct bContext *C, struct ARegion *ar);
 +void view3d_draw_region_info(const struct bContext *C, struct ARegion *ar, const int offset);
  
  void ED_view3d_draw_depth(
 -        Scene *scene,
 +        const struct EvaluationContext *eval_ctx, struct Depsgraph *graph,
          struct ARegion *ar, View3D *v3d, bool alphaoverride);
 -void ED_view3d_draw_depth_gpencil(Scene *scene, ARegion *ar, View3D *v3d);
 +
 +/* view3d_draw_legacy.c */
 +void view3d_main_region_draw_legacy(const struct bContext *C, struct ARegion *ar);
 +void ED_view3d_draw_depth_gpencil(const struct EvaluationContext *eval_ctx, Scene *scene, ARegion *ar, View3D *v3d);
 +
  void ED_view3d_draw_select_loop(
 -        ViewContext *vc, Scene *scene, View3D *v3d, ARegion *ar,
 +        const struct EvaluationContext *eval_ctx, ViewContext *vc, Scene *scene, struct ViewLayer *view_layer, View3D *v3d, ARegion *ar,
          bool use_obedit_skip, bool use_nearest);
  
 -void ED_view3d_after_add(ListBase *lb, Base *base, const short dflag);\
 +void ED_view3d_draw_depth_loop(
 +        const struct EvaluationContext *eval_ctx, Scene *scene, ARegion *ar, View3D *v3d);
 +
 +void ED_view3d_after_add(ListBase *lb, Base *base, const short dflag);
  
 -void circf(float x, float y, float rad);
 -void circ(float x, float y, float rad);
  void view3d_update_depths_rect(struct ARegion *ar, struct ViewDepths *d, struct rcti *rect);
  float view3d_depth_near(struct ViewDepths *d);
  
@@@ -249,6 -228,7 +250,6 @@@ void VIEW3D_OT_smoothview(struct wmOper
  void VIEW3D_OT_camera_to_view(struct wmOperatorType *ot);
  void VIEW3D_OT_camera_to_view_selected(struct wmOperatorType *ot);
  void VIEW3D_OT_object_as_camera(struct wmOperatorType *ot);
 -void VIEW3D_OT_localview(struct wmOperatorType *ot);
  void VIEW3D_OT_game_start(struct wmOperatorType *ot);
  
  
@@@ -277,10 -257,9 +278,10 @@@ void ED_view3d_smooth_view_force_finish
          struct View3D *v3d, struct ARegion *ar);
  
  void view3d_winmatrix_set(
 +        const struct Depsgraph *depsgraph,
          ARegion *ar, const View3D *v3d, const rcti *rect);
  void view3d_viewmatrix_set(
 -        Scene *scene,
 +        const struct EvaluationContext *eval_ctx, Scene *scene,
          const View3D *v3d, RegionView3D *rv3d, const float rect_scale[2]);
  
  void fly_modal_keymap(struct wmKeyConfig *keyconf);
@@@ -296,7 -275,7 +297,7 @@@ void view3d_buttons_register(struct ARe
  
  /* view3d_camera_control.c */
  struct View3DCameraControl *ED_view3d_cameracontrol_acquire(
 -        Scene *scene, View3D *v3d, RegionView3D *rv3d,
 +        const struct EvaluationContext *eval_ctx, Scene *scene, View3D *v3d, RegionView3D *rv3d,
          const bool use_parent_root);
  void ED_view3d_cameracontrol_update(
          struct View3DCameraControl *vctrl,
  void ED_view3d_cameracontrol_release(
          struct View3DCameraControl *vctrl,
          const bool restore);
 -Object *ED_view3d_cameracontrol_object_get(
 +struct Object *ED_view3d_cameracontrol_object_get(
          struct View3DCameraControl *vctrl);
  
  /* view3d_toolbar.c */
@@@ -330,23 -309,6 +331,23 @@@ ARegion *view3d_has_tools_region(ScrAre
  
  extern const char *view3d_context_dir[]; /* doc access */
  
 +/* view3d_widgets.c */
 +void VIEW3D_WGT_lamp_spot(struct wmManipulatorGroupType *wgt);
 +void VIEW3D_WGT_lamp_area(struct wmManipulatorGroupType *wgt);
 +void VIEW3D_WGT_lamp_target(struct wmManipulatorGroupType *wgt);
 +void VIEW3D_WGT_camera(struct wmManipulatorGroupType *wgt);
 +void VIEW3D_WGT_camera_view(struct wmManipulatorGroupType *wgt);
 +void VIEW3D_WGT_force_field(struct wmManipulatorGroupType *wgt);
 +void VIEW3D_WGT_empty_image(struct wmManipulatorGroupType *wgt);
 +void VIEW3D_WGT_armature_spline(struct wmManipulatorGroupType *wgt);
 +void VIEW3D_WGT_navigate(struct wmManipulatorGroupType *wgt);
 +
 +void VIEW3D_WGT_ruler(struct wmManipulatorGroupType *wgt);
 +void VIEW3D_WT_ruler_item(struct wmManipulatorType *wt);
 +void VIEW3D_OT_ruler_add(struct wmOperatorType *ot);
 +
 +void VIEW3D_WT_navigate_rotate(struct wmManipulatorType *wt);
 +
  /* draw_volume.c */
  void draw_smoke_volume(struct SmokeDomainSettings *sds, struct Object *ob,
                         const float min[3], const float max[3],
@@@ -365,31 -327,5 +366,31 @@@ extern unsigned char view3d_camera_bord
  extern bool view3d_camera_border_hack_test;
  #endif
  
 -#endif /* __VIEW3D_INTERN_H__ */
 +/* temporary for legacy viewport to work */
 +void VP_legacy_drawcursor(Scene *scene, struct ViewLayer *view_layer, ARegion *ar, View3D *v3d);
 +void VP_legacy_draw_view_axis(RegionView3D *rv3d, rcti *rect);
 +void VP_legacy_draw_viewport_name(ARegion *ar, View3D *v3d, rcti *rect);
 +void VP_legacy_draw_selected_name(Scene *scene, struct Object *ob, rcti *rect);
 +void VP_legacy_drawgrid(UnitSettings *unit, ARegion *ar, View3D *v3d, const char **grid_unit);
 +void VP_legacy_drawfloor(Scene *scene, View3D *v3d, const char **grid_unit, bool write_depth);
 +void VP_legacy_view3d_main_region_setup_view(const struct EvaluationContext *eval_ctx, Scene *scene, View3D *v3d, ARegion *ar, float viewmat[4][4], float winmat[4][4]);
 +bool VP_legacy_view3d_stereo3d_active(struct wmWindow *win, Scene *scene, View3D *v3d, RegionView3D *rv3d);
 +void VP_legacy_view3d_stereo3d_setup(const struct EvaluationContext *eval_ctx, Scene *scene, View3D *v3d, ARegion *ar);
 +void draw_dupli_objects(const struct EvaluationContext *eval_ctx, Scene *scene, ViewLayer *view_layer, ARegion *ar, View3D *v3d, Base *base);
 +bool VP_legacy_use_depth(Scene *scene, View3D *v3d);
 +void VP_drawviewborder(Scene *scene, const struct Depsgraph *depsgraph, ARegion *ar, View3D *v3d);
 +void VP_drawrenderborder(ARegion *ar, View3D *v3d);
 +void VP_view3d_draw_background_none(void);
 +void VP_view3d_draw_background_world(Scene *scene, RegionView3D *rv3d);
 +void VP_view3d_main_region_clear(Scene *scene, View3D *v3d, ARegion *ar);
 +
 +/* temporary legacy calls, only when there is a switch between new/old draw calls */
 +void VP_deprecated_gpu_update_lamps_shadows_world(const struct EvaluationContext *eval_ctx, Scene *scene, View3D *v3d);
 +void VP_deprecated_view3d_draw_objects(
 +        const struct bContext *C,
 +        const struct EvaluationContext *eval_ctx,
 +        Scene *scene, View3D *v3d, ARegion *ar,
 +        const char **grid_unit,
 +        const bool do_bgpic, const bool draw_offscreen, struct GPUFX *fx);
  
 +#endif /* __VIEW3D_INTERN_H__ */
index af44629a18e2fa965a3d375763172c59f88e77d0,2e876bc48b3ae787dc0396a66f25a441d3e0c937..ba3e78b25b99a137230c47e5f2c6e40a94b3adb2
  
  #include "BLI_sys_types.h"  /* int64_t */
  
 -#include "BIF_gl.h"  /* bglMats */
 -#include "BIF_glutil.h"  /* bglMats */
 -
  #include "BLI_math_vector.h"
  
  #include "BKE_camera.h"
  #include "BKE_screen.h"
  
 +#include "GPU_matrix.h"
 +
  #include "ED_view3d.h"  /* own include */
  
  #define BL_NEAR_CLIP 0.001
@@@ -277,6 -278,11 +277,11 @@@ eV3DProjStatus ED_view3d_project_float_
  /* More Generic Window/Ray/Vector projection functions
   * *************************************************** */
  
+ float ED_view3d_pixel_size(const RegionView3D *rv3d, const float co[3])
+ {
+       return mul_project_m4_v3_zfac((float(*)[4])rv3d->persmat, co) * rv3d->pixsize * U.pixelsize;
+ }
  /**
   * Calculate a depth value from \a co, use with #ED_view3d_win_to_delta
   */
@@@ -304,7 -310,6 +309,7 @@@ float ED_view3d_calc_zfac(const RegionV
  }
  
  static void view3d_win_to_ray_segment(
 +        const struct Depsgraph *depsgraph,
          const ARegion *ar, const View3D *v3d, const float mval[2],
          float r_ray_co[3], float r_ray_dir[3], float r_ray_start[3], float r_ray_end[3])
  {
                start_offset = -end_offset;
        }
        else {
 -              ED_view3d_clip_range_get(v3d, rv3d, &start_offset, &end_offset, false);
 +              ED_view3d_clip_range_get(depsgraph, v3d, rv3d, &start_offset, &end_offset, false);
        }
  
        if (r_ray_start) {
@@@ -361,13 -366,12 +366,13 @@@ bool ED_view3d_clip_segment(const Regio
   * \return success, false if the ray is totally clipped.
   */
  bool ED_view3d_win_to_ray_ex(
 +        const struct Depsgraph *depsgraph,
          const ARegion *ar, const View3D *v3d, const float mval[2],
          float r_ray_co[3], float r_ray_normal[3], float r_ray_start[3], bool do_clip)
  {
        float ray_end[3];
  
 -      view3d_win_to_ray_segment(ar, v3d, mval, r_ray_co, r_ray_normal, r_ray_start, ray_end);
 +      view3d_win_to_ray_segment(depsgraph, ar, v3d, mval, r_ray_co, r_ray_normal, r_ray_start, ray_end);
  
        /* bounds clipping */
        if (do_clip) {
   * \return success, false if the ray is totally clipped.
   */
  bool ED_view3d_win_to_ray(
 +        const struct Depsgraph *depsgraph,
          const ARegion *ar, const View3D *v3d, const float mval[2],
          float r_ray_start[3], float r_ray_normal[3], const bool do_clip)
  {
 -      return ED_view3d_win_to_ray_ex(ar, v3d, mval, NULL, r_ray_normal, r_ray_start, do_clip);
 +      return ED_view3d_win_to_ray_ex(depsgraph,ar, v3d, mval, NULL, r_ray_normal, r_ray_start, do_clip);
  }
  
  /**
@@@ -625,11 -628,10 +630,11 @@@ void ED_view3d_win_to_vector(const AReg
   * \param do_clip Optionally clip the ray by the view clipping planes.
   * \return success, false if the segment is totally clipped.
   */
 -bool ED_view3d_win_to_segment(const ARegion *ar, View3D *v3d, const float mval[2],
 +bool ED_view3d_win_to_segment(const struct Depsgraph *depsgraph,
 +                              const ARegion *ar, View3D *v3d, const float mval[2],
                                float r_ray_start[3], float r_ray_end[3], const bool do_clip)
  {
 -      view3d_win_to_ray_segment(ar, v3d, mval, NULL, NULL, r_ray_start, r_ray_end);
 +      view3d_win_to_ray_segment(depsgraph, ar, v3d, mval, NULL, NULL, r_ray_start, r_ray_end);
  
        /* bounds clipping */
        if (do_clip) {
@@@ -659,22 -661,16 +664,22 @@@ void ED_view3d_ob_project_mat_get_from_
  }
  
  /**
 - * Uses window coordinates (x,y) and depth component z to find a point in
 - * modelspace */
 -void ED_view3d_unproject(bglMats *mats, float out[3], const float x, const float y, const float z)
 + * Convert between region relative coordinates (x,y) and depth component z and
 + * a point in world space. */
 +void ED_view3d_project(const struct ARegion *ar, const float world[3], float region[3])
  {
 -      double ux, uy, uz;
 +      // viewport is set up to make coordinates relative to the region, not window
 +      RegionView3D *rv3d = ar->regiondata;
 +      int viewport[4] = {0, 0, ar->winx, ar->winy};
  
 -      gluUnProject(x, y, z, mats->modelview, mats->projection,
 -                   (GLint *)mats->viewport, &ux, &uy, &uz);
 +      gpuProject(world, rv3d->viewmat, rv3d->winmat, viewport, region);
 +}
 +
 +bool ED_view3d_unproject(const struct ARegion *ar, float regionx, float regiony, float regionz, float world[3])
 +{
 +      RegionView3D *rv3d = ar->regiondata;
 +      int viewport[4] = {0, 0, ar->winx, ar->winy};
 +      float region[3] = {regionx, regiony, regionz};
  
 -      out[0] = ux;
 -      out[1] = uy;
 -      out[2] = uz;
 +      return gpuUnProject(region, rv3d->viewmat, rv3d->winmat, viewport, world);
  }
index 0000000000000000000000000000000000000000,e40a4b3f9f65401011f9bd16bbff8b46caf23d15..cb9c7f02db9dad2bd19e29df46ccc014ca155c03
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,1477 +1,1407 @@@
 -#include "BKE_depsgraph.h" /* for ED_view3d_camera_lock_sync */
+ /*
+  * ***** BEGIN GPL LICENSE BLOCK *****
+  *
+  * This program is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU General Public License
+  * as published by the Free Software Foundation; either version 2
+  * of the License, or (at your option) any later version.
+  *
+  * This program is distributed in the hope that it will be useful,
+  * but WITHOUT ANY WARRANTY; without even the implied warranty of
+  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  * GNU General Public License for more details.
+  *
+  * You should have received a copy of the GNU General Public License
+  * along with this program; if not, write to the Free Software Foundation,
+  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+  *
+  * The Original Code is Copyright (C) 2008 Blender Foundation.
+  * All rights reserved.
+  *
+  * ***** END GPL LICENSE BLOCK *****
+  */
+ /** \file blender/editors/space_view3d/view3d_utils.c
+  *  \ingroup spview3d
+  *
+  * 3D View checks and manipulation (no operators).
+  */
+ #include <string.h>
+ #include <stdio.h>
+ #include <math.h>
+ #include <float.h>
+ #include "DNA_camera_types.h"
+ #include "DNA_curve_types.h"
+ #include "DNA_object_types.h"
+ #include "DNA_scene_types.h"
+ #include "MEM_guardedalloc.h"
+ #include "BLI_bitmap_draw_2d.h"
+ #include "BLI_blenlib.h"
+ #include "BLI_math.h"
+ #include "BLI_utildefines.h"
+ #include "BKE_camera.h"
+ #include "BKE_context.h"
+ #include "BKE_object.h"
+ #include "BKE_screen.h"
 -      BKE_camera_params_from_view3d(&params, v3d, rv3d);
++
++#include "DEG_depsgraph.h"
++#include "DEG_depsgraph_query.h"
+ #include "BIF_gl.h"
+ #include "BIF_glutil.h"
+ #include "WM_api.h"
+ #include "WM_types.h"
+ #include "ED_keyframing.h"
+ #include "ED_screen.h"
+ #include "ED_view3d.h"
+ #include "view3d_intern.h"  /* own include */
+ /* -------------------------------------------------------------------- */
+ /** \name View Data Access Utilities
+  *
+  * \{ */
+ float *ED_view3d_cursor3d_get(Scene *scene, View3D *v3d)
+ {
+       if (v3d && v3d->localvd) return v3d->cursor;
+       else return scene->cursor;
+ }
+ Camera *ED_view3d_camera_data_get(View3D *v3d, RegionView3D *rv3d)
+ {
+       /* establish the camera object, so we can default to view mapping if anything is wrong with it */
+       if ((rv3d->persp == RV3D_CAMOB) && v3d->camera && (v3d->camera->type == OB_CAMERA)) {
+               return v3d->camera->data;
+       }
+       else {
+               return NULL;
+       }
+ }
+ void ED_view3d_dist_range_get(
+         const View3D *v3d,
+         float r_dist_range[2])
+ {
+       r_dist_range[0] = v3d->grid * 0.001f;
+       r_dist_range[1] = v3d->far * 10.0f;
+ }
+ /**
+  * \note copies logic of #ED_view3d_viewplane_get(), keep in sync.
+  */
+ bool ED_view3d_clip_range_get(
++        const Depsgraph *depsgraph,
+         const View3D *v3d, const RegionView3D *rv3d,
+         float *r_clipsta, float *r_clipend,
+         const bool use_ortho_factor)
+ {
+       CameraParams params;
+       BKE_camera_params_init(&params);
 -      BKE_camera_params_from_view3d(&params, v3d, rv3d);
++      BKE_camera_params_from_view3d(&params, depsgraph, v3d, rv3d);
+       if (use_ortho_factor && params.is_ortho) {
+               const float fac = 2.0f / (params.clipend - params.clipsta);
+               params.clipsta *= fac;
+               params.clipend *= fac;
+       }
+       if (r_clipsta) *r_clipsta = params.clipsta;
+       if (r_clipend) *r_clipend = params.clipend;
+       return params.is_ortho;
+ }
+ bool ED_view3d_viewplane_get(
++        const Depsgraph *depsgraph,
+         const View3D *v3d, const RegionView3D *rv3d, int winx, int winy,
+         rctf *r_viewplane, float *r_clipsta, float *r_clipend, float *r_pixsize)
+ {
+       CameraParams params;
+       BKE_camera_params_init(&params);
 -void ED_view3d_clipping_calc(BoundBox *bb, float planes[4][4], bglMats *mats, const rcti *rect)
++      BKE_camera_params_from_view3d(&params, depsgraph, v3d, rv3d);
+       BKE_camera_params_compute_viewplane(&params, winx, winy, 1.0f, 1.0f);
+       if (r_viewplane) *r_viewplane = params.viewplane;
+       if (r_clipsta) *r_clipsta = params.clipsta;
+       if (r_clipend) *r_clipend = params.clipend;
+       if (r_pixsize) *r_pixsize = params.viewdx;
+       return params.is_ortho;
+ }
+ /** \} */
+ /* -------------------------------------------------------------------- */
+ /** \name View State/Context Utilities
+  *
+  * \{ */
+ /**
+  * Use instead of: ``bglPolygonOffset(rv3d->dist, ...)`` see bug [#37727]
+  */
+ void ED_view3d_polygon_offset(const RegionView3D *rv3d, const float dist)
+ {
+       float viewdist;
+       if (rv3d->rflag & RV3D_ZOFFSET_DISABLED) {
+               return;
+       }
+       viewdist = rv3d->dist;
+       /* special exception for ortho camera (viewdist isnt used for perspective cameras) */
+       if (dist != 0.0f) {
+               if (rv3d->persp == RV3D_CAMOB) {
+                       if (rv3d->is_persp == false) {
+                               viewdist = 1.0f / max_ff(fabsf(rv3d->winmat[0][0]), fabsf(rv3d->winmat[1][1]));
+                       }
+               }
+       }
+       bglPolygonOffset(viewdist, dist);
+ }
+ bool ED_view3d_context_activate(bContext *C)
+ {
+       bScreen *sc = CTX_wm_screen(C);
+       ScrArea *sa = CTX_wm_area(C);
+       ARegion *ar;
+       /* sa can be NULL when called from python */
+       if (sa == NULL || sa->spacetype != SPACE_VIEW3D) {
+               sa = BKE_screen_find_big_area(sc, SPACE_VIEW3D, 0);
+       }
+       if (sa == NULL) {
+               return false;
+       }
+       ar = BKE_area_find_region_active_win(sa);
+       if (ar == NULL) {
+               return false;
+       }
+       /* bad context switch .. */
+       CTX_wm_area_set(C, sa);
+       CTX_wm_region_set(C, ar);
+       return true;
+ }
+ /** \} */
+ /* -------------------------------------------------------------------- */
+ /** \name View Clipping Utilities
+  *
+  * \{ */
++
+ void ED_view3d_clipping_calc_from_boundbox(float clip[4][4], const BoundBox *bb, const bool is_flip)
+ {
+       int val;
+       for (val = 0; val < 4; val++) {
+               normal_tri_v3(clip[val], bb->vec[val], bb->vec[val == 3 ? 0 : val + 1], bb->vec[val + 4]);
+               if (UNLIKELY(is_flip)) {
+                       negate_v3(clip[val]);
+               }
+               clip[val][3] = -dot_v3v3(clip[val], bb->vec[val]);
+       }
+ }
 -      float modelview[4][4];
 -      double xs, ys, p[3];
 -      int val, flip_sign, a;
 -
 -      /* near zero floating point values can give issues with gluUnProject
 -       * in side view on some implementations */
 -      if (fabs(mats->modelview[0]) < 1e-6) mats->modelview[0] = 0.0;
 -      if (fabs(mats->modelview[5]) < 1e-6) mats->modelview[5] = 0.0;
 -
 -      /* Set up viewport so that gluUnProject will give correct values */
 -      mats->viewport[0] = 0;
 -      mats->viewport[1] = 0;
++void ED_view3d_clipping_calc(BoundBox *bb, float planes[4][4], const ARegion *ar, const Object *ob, const rcti *rect)
+ {
 -      for (val = 0; val < 4; val++) {
 -              xs = (val == 0 || val == 3) ? rect->xmin : rect->xmax;
 -              ys = (val == 0 || val == 1) ? rect->ymin : rect->ymax;
++      /* init in case unproject fails */
++      memset(bb->vec, 0, sizeof(bb->vec));
+       /* four clipping planes and bounding volume */
+       /* first do the bounding volume */
 -              gluUnProject(xs, ys, 0.0, mats->modelview, mats->projection, mats->viewport, &p[0], &p[1], &p[2]);
 -              copy_v3fl_v3db(bb->vec[val], p);
++      for (int val = 0; val < 4; val++) {
++              float xs = (val == 0 || val == 3) ? rect->xmin : rect->xmax;
++              float ys = (val == 0 || val == 1) ? rect->ymin : rect->ymax;
 -              gluUnProject(xs, ys, 1.0, mats->modelview, mats->projection, mats->viewport, &p[0], &p[1], &p[2]);
 -              copy_v3fl_v3db(bb->vec[4 + val], p);
++              ED_view3d_unproject(ar, xs, ys, 0.0, bb->vec[val]);
++              ED_view3d_unproject(ar, xs, ys, 1.0, bb->vec[4 + val]);
++      }
 -      for (a = 0; a < 16; a++)
 -              ((float *)modelview)[a] = mats->modelview[a];
 -      flip_sign = is_negative_m4(modelview);
++      /* optionally transform to object space */
++      if (ob) {
++              float imat[4][4];
++              invert_m4_m4(imat, ob->obmat);
++
++              for (int val = 0; val < 8; val++) {
++                      mul_m4_v3(imat, bb->vec[val]);
++              }
+       }
+       /* verify if we have negative scale. doing the transform before cross
+        * product flips the sign of the vector compared to doing cross product
+        * before transform then, so we correct for that. */
 -                              DAG_id_tag_update(&ob_update->id, OB_RECALC_OB);
++      int flip_sign = (ob) ? is_negative_m4(ob->obmat) : false;
+       ED_view3d_clipping_calc_from_boundbox(planes, bb, flip_sign);
+ }
+ /** \} */
+ /* -------------------------------------------------------------------- */
+ /** \name View Bound-Box Utilities
+  *
+  * \{ */
+ static bool view3d_boundbox_clip_m4(const BoundBox *bb, float persmatob[4][4])
+ {
+       int a, flag = -1, fl;
+       for (a = 0; a < 8; a++) {
+               float vec[4], min, max;
+               copy_v3_v3(vec, bb->vec[a]);
+               vec[3] = 1.0;
+               mul_m4_v4(persmatob, vec);
+               max = vec[3];
+               min = -vec[3];
+               fl = 0;
+               if (vec[0] < min) fl += 1;
+               if (vec[0] > max) fl += 2;
+               if (vec[1] < min) fl += 4;
+               if (vec[1] > max) fl += 8;
+               if (vec[2] < min) fl += 16;
+               if (vec[2] > max) fl += 32;
+               flag &= fl;
+               if (flag == 0) return true;
+       }
+       return false;
+ }
+ bool ED_view3d_boundbox_clip_ex(const RegionView3D *rv3d, const BoundBox *bb, float obmat[4][4])
+ {
+       /* return 1: draw */
+       float persmatob[4][4];
+       if (bb == NULL) return true;
+       if (bb->flag & BOUNDBOX_DISABLED) return true;
+       mul_m4_m4m4(persmatob, (float(*)[4])rv3d->persmat, obmat);
+       return view3d_boundbox_clip_m4(bb, persmatob);
+ }
+ bool ED_view3d_boundbox_clip(RegionView3D *rv3d, const BoundBox *bb)
+ {
+       if (bb == NULL) return true;
+       if (bb->flag & BOUNDBOX_DISABLED) return true;
+       return view3d_boundbox_clip_m4(bb, rv3d->persmatob);
+ }
+ /** \} */
+ /* -------------------------------------------------------------------- */
+ /** \name View Perspective & Mode Switching
+  *
+  * Misc view utility functions.
+  * \{ */
+ bool ED_view3d_offset_lock_check(const  View3D *v3d, const  RegionView3D *rv3d)
+ {
+       return (rv3d->persp != RV3D_CAMOB) && (v3d->ob_centre_cursor || v3d->ob_centre);
+ }
+ /**
+  * Use to store the last view, before entering camera view.
+  */
+ void ED_view3d_lastview_store(RegionView3D *rv3d)
+ {
+       copy_qt_qt(rv3d->lviewquat, rv3d->viewquat);
+       rv3d->lview = rv3d->view;
+       if (rv3d->persp != RV3D_CAMOB) {
+               rv3d->lpersp = rv3d->persp;
+       }
+ }
+ void ED_view3d_lock_clear(View3D *v3d)
+ {
+       v3d->ob_centre = NULL;
+       v3d->ob_centre_bone[0] = '\0';
+       v3d->ob_centre_cursor = false;
+       v3d->flag2 &= ~V3D_LOCK_CAMERA;
+ }
+ /**
+  * For viewport operators that exit camera perspective.
+  *
+  * \note This differs from simply setting ``rv3d->persp = persp`` because it
+  * sets the ``ofs`` and ``dist`` values of the viewport so it matches the camera,
+  * otherwise switching out of camera view may jump to a different part of the scene.
+  */
+ void ED_view3d_persp_switch_from_camera(View3D *v3d, RegionView3D *rv3d, const char persp)
+ {
+       BLI_assert(rv3d->persp == RV3D_CAMOB);
+       BLI_assert(persp != RV3D_CAMOB);
+       if (v3d->camera) {
+               rv3d->dist = ED_view3d_offset_distance(v3d->camera->obmat, rv3d->ofs, VIEW3D_DIST_FALLBACK);
+               ED_view3d_from_object(v3d->camera, rv3d->ofs, rv3d->viewquat, &rv3d->dist, NULL);
+       }
+       if (!ED_view3d_camera_lock_check(v3d, rv3d)) {
+               rv3d->persp = persp;
+       }
+ }
+ /**
+  * Action to take when rotating the view,
+  * handle auto-persp and logic for switching out of views.
+  *
+  * shared with NDOF.
+  */
+ bool ED_view3d_persp_ensure(struct View3D *v3d, ARegion *ar)
+ {
+       RegionView3D *rv3d = ar->regiondata;
+       const bool autopersp = (U.uiflag & USER_AUTOPERSP) != 0;
+       BLI_assert((rv3d->viewlock & RV3D_LOCKED) == 0);
+       if (ED_view3d_camera_lock_check(v3d, rv3d))
+               return false;
+       if (rv3d->persp != RV3D_PERSP) {
+               if (rv3d->persp == RV3D_CAMOB) {
+                       /* If autopersp and previous view was an axis one, switch back to PERSP mode, else reuse previous mode. */
+                       char persp = (autopersp && RV3D_VIEW_IS_AXIS(rv3d->lview)) ? RV3D_PERSP : rv3d->lpersp;
+                       ED_view3d_persp_switch_from_camera(v3d, rv3d, persp);
+               }
+               else if (autopersp && RV3D_VIEW_IS_AXIS(rv3d->view)) {
+                       rv3d->persp = RV3D_PERSP;
+               }
+               return true;
+       }
+       return false;
+ }
+ /** \} */
+ /* -------------------------------------------------------------------- */
+ /** \name Camera Lock API
+  *
+  * Lock the camera to the view-port, allowing view manipulation to transform the camera.
+  * \{ */
+ /**
+  * \return true when the view-port is locked to its camera.
+  */
+ bool ED_view3d_camera_lock_check(const View3D *v3d, const RegionView3D *rv3d)
+ {
+       return ((v3d->camera) &&
+               (!ID_IS_LINKED(v3d->camera)) &&
+               (v3d->flag2 & V3D_LOCK_CAMERA) &&
+               (rv3d->persp == RV3D_CAMOB));
+ }
+ /**
+  * Apply the camera object transformation to the view-port.
+  * (needed so we can use regular view-port manipulation operators, that sync back to the camera).
+  */
+ void ED_view3d_camera_lock_init_ex(View3D *v3d, RegionView3D *rv3d, const bool calc_dist)
+ {
+       if (ED_view3d_camera_lock_check(v3d, rv3d)) {
+               if (calc_dist) {
+                       /* using a fallback dist is OK here since ED_view3d_from_object() compensates for it */
+                       rv3d->dist = ED_view3d_offset_distance(v3d->camera->obmat, rv3d->ofs, VIEW3D_DIST_FALLBACK);
+               }
+               ED_view3d_from_object(v3d->camera, rv3d->ofs, rv3d->viewquat, &rv3d->dist, NULL);
+       }
+ }
+ void ED_view3d_camera_lock_init(View3D *v3d, RegionView3D *rv3d)
+ {
+       ED_view3d_camera_lock_init_ex(v3d, rv3d, true);
+ }
+ /**
+  * Apply the view-port transformation back to the camera object.
+  *
+  * \return true if the camera is moved.
+  */
+ bool ED_view3d_camera_lock_sync(View3D *v3d, RegionView3D *rv3d)
+ {
+       if (ED_view3d_camera_lock_check(v3d, rv3d)) {
+               ObjectTfmProtectedChannels obtfm;
+               Object *root_parent;
+               if ((U.uiflag & USER_CAM_LOCK_NO_PARENT) == 0 && (root_parent = v3d->camera->parent)) {
+                       Object *ob_update;
+                       float tmat[4][4];
+                       float imat[4][4];
+                       float view_mat[4][4];
+                       float diff_mat[4][4];
+                       float parent_mat[4][4];
+                       while (root_parent->parent) {
+                               root_parent = root_parent->parent;
+                       }
+                       ED_view3d_to_m4(view_mat, rv3d->ofs, rv3d->viewquat, rv3d->dist);
+                       normalize_m4_m4(tmat, v3d->camera->obmat);
+                       invert_m4_m4(imat, tmat);
+                       mul_m4_m4m4(diff_mat, view_mat, imat);
+                       mul_m4_m4m4(parent_mat, diff_mat, root_parent->obmat);
+                       BKE_object_tfm_protected_backup(root_parent, &obtfm);
+                       BKE_object_apply_mat4(root_parent, parent_mat, true, false);
+                       BKE_object_tfm_protected_restore(root_parent, &obtfm, root_parent->protectflag);
+                       ob_update = v3d->camera;
+                       while (ob_update) {
 -                      DAG_id_tag_update(&v3d->camera->id, OB_RECALC_OB);
++                              DEG_id_tag_update(&ob_update->id, OB_RECALC_OB);
+                               WM_main_add_notifier(NC_OBJECT | ND_TRANSFORM, ob_update);
+                               ob_update = ob_update->parent;
+                       }
+               }
+               else {
+                       /* always maintain the same scale */
+                       const short protect_scale_all = (OB_LOCK_SCALEX | OB_LOCK_SCALEY | OB_LOCK_SCALEZ);
+                       BKE_object_tfm_protected_backup(v3d->camera, &obtfm);
+                       ED_view3d_to_object(v3d->camera, rv3d->ofs, rv3d->viewquat, rv3d->dist);
+                       BKE_object_tfm_protected_restore(v3d->camera, &obtfm, v3d->camera->protectflag | protect_scale_all);
 -        Scene *scene, ARegion *ar, View3D *v3d,
++                      DEG_id_tag_update(&v3d->camera->id, OB_RECALC_OB);
+                       WM_main_add_notifier(NC_OBJECT | ND_TRANSFORM, v3d->camera);
+               }
+               return true;
+       }
+       else {
+               return false;
+       }
+ }
+ bool ED_view3d_camera_autokey(
+         Scene *scene, ID *id_key,
+         struct bContext *C, const bool do_rotate, const bool do_translate)
+ {
+       if (autokeyframe_cfra_can_key(scene, id_key)) {
+               const float cfra = (float)CFRA;
+               ListBase dsources = {NULL, NULL};
+               /* add data-source override for the camera object */
+               ANIM_relative_keyingset_add_source(&dsources, id_key, NULL, NULL);
+               /* insert keyframes
+                * 1) on the first frame
+                * 2) on each subsequent frame
+                *    TODO: need to check in future that frame changed before doing this
+                */
+               if (do_rotate) {
+                       struct KeyingSet *ks = ANIM_get_keyingset_for_autokeying(scene, ANIM_KS_ROTATION_ID);
+                       ANIM_apply_keyingset(C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, cfra);
+               }
+               if (do_translate) {
+                       struct KeyingSet *ks = ANIM_get_keyingset_for_autokeying(scene, ANIM_KS_LOCATION_ID);
+                       ANIM_apply_keyingset(C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, cfra);
+               }
+               /* free temp data */
+               BLI_freelistN(&dsources);
+               return true;
+       }
+       else {
+               return false;
+       }
+ }
+ /**
+  * Call after modifying a locked view.
+  *
+  * \note Not every view edit currently auto-keys (numpad for eg),
+  * this is complicated because of smoothview.
+  */
+ bool ED_view3d_camera_lock_autokey(
+         View3D *v3d, RegionView3D *rv3d,
+         struct bContext *C, const bool do_rotate, const bool do_translate)
+ {
+       /* similar to ED_view3d_cameracontrol_update */
+       if (ED_view3d_camera_lock_check(v3d, rv3d)) {
+               Scene *scene = CTX_data_scene(C);
+               ID *id_key;
+               Object *root_parent;
+               if ((U.uiflag & USER_CAM_LOCK_NO_PARENT) == 0 && (root_parent = v3d->camera->parent)) {
+                       while (root_parent->parent) {
+                               root_parent = root_parent->parent;
+                       }
+                       id_key = &root_parent->id;
+               }
+               else {
+                       id_key = &v3d->camera->id;
+               }
+               return ED_view3d_camera_autokey(scene, id_key, C, do_rotate, do_translate);
+       }
+       else {
+               return false;
+       }
+ }
+ /** \} */
++
+ /* -------------------------------------------------------------------- */
+ /** \name Box View Support
+  *
+  * Use with quad-split so each view is clipped by the bounds of each view axis.
+  * \{ */
+ static void view3d_boxview_clip(ScrArea *sa)
+ {
+       ARegion *ar;
+       BoundBox *bb = MEM_callocN(sizeof(BoundBox), "clipbb");
+       float clip[6][4];
+       float x1 = 0.0f, y1 = 0.0f, z1 = 0.0f, ofs[3] = {0.0f, 0.0f, 0.0f};
+       int val;
+       /* create bounding box */
+       for (ar = sa->regionbase.first; ar; ar = ar->next) {
+               if (ar->regiontype == RGN_TYPE_WINDOW) {
+                       RegionView3D *rv3d = ar->regiondata;
+                       if (rv3d->viewlock & RV3D_BOXCLIP) {
+                               if (ELEM(rv3d->view, RV3D_VIEW_TOP, RV3D_VIEW_BOTTOM)) {
+                                       if (ar->winx > ar->winy) x1 = rv3d->dist;
+                                       else x1 = ar->winx * rv3d->dist / ar->winy;
+                                       if (ar->winx > ar->winy) y1 = ar->winy * rv3d->dist / ar->winx;
+                                       else y1 = rv3d->dist;
+                                       copy_v2_v2(ofs, rv3d->ofs);
+                               }
+                               else if (ELEM(rv3d->view, RV3D_VIEW_FRONT, RV3D_VIEW_BACK)) {
+                                       ofs[2] = rv3d->ofs[2];
+                                       if (ar->winx > ar->winy) z1 = ar->winy * rv3d->dist / ar->winx;
+                                       else z1 = rv3d->dist;
+                               }
+                       }
+               }
+       }
+       for (val = 0; val < 8; val++) {
+               if (ELEM(val, 0, 3, 4, 7))
+                       bb->vec[val][0] = -x1 - ofs[0];
+               else
+                       bb->vec[val][0] =  x1 - ofs[0];
+               if (ELEM(val, 0, 1, 4, 5))
+                       bb->vec[val][1] = -y1 - ofs[1];
+               else
+                       bb->vec[val][1] =  y1 - ofs[1];
+               if (val > 3)
+                       bb->vec[val][2] = -z1 - ofs[2];
+               else
+                       bb->vec[val][2] =  z1 - ofs[2];
+       }
+       /* normals for plane equations */
+       normal_tri_v3(clip[0], bb->vec[0], bb->vec[1], bb->vec[4]);
+       normal_tri_v3(clip[1], bb->vec[1], bb->vec[2], bb->vec[5]);
+       normal_tri_v3(clip[2], bb->vec[2], bb->vec[3], bb->vec[6]);
+       normal_tri_v3(clip[3], bb->vec[3], bb->vec[0], bb->vec[7]);
+       normal_tri_v3(clip[4], bb->vec[4], bb->vec[5], bb->vec[6]);
+       normal_tri_v3(clip[5], bb->vec[0], bb->vec[2], bb->vec[1]);
+       /* then plane equations */
+       for (val = 0; val < 6; val++) {
+               clip[val][3] = -dot_v3v3(clip[val], bb->vec[val % 5]);
+       }
+       /* create bounding box */
+       for (ar = sa->regionbase.first; ar; ar = ar->next) {
+               if (ar->regiontype == RGN_TYPE_WINDOW) {
+                       RegionView3D *rv3d = ar->regiondata;
+                       if (rv3d->viewlock & RV3D_BOXCLIP) {
+                               rv3d->rflag |= RV3D_CLIPPING;
+                               memcpy(rv3d->clip, clip, sizeof(clip));
+                               if (rv3d->clipbb) MEM_freeN(rv3d->clipbb);
+                               rv3d->clipbb = MEM_dupallocN(bb);
+                       }
+               }
+       }
+       MEM_freeN(bb);
+ }
+ /**
+  * Find which axis values are shared between both views and copy to \a rv3d_dst
+  * taking axis flipping into account.
+  */
+ static void view3d_boxview_sync_axis(RegionView3D *rv3d_dst, RegionView3D *rv3d_src)
+ {
+       /* absolute axis values above this are considered to be set (will be ~1.0f) */
+       const float axis_eps = 0.5f;
+       float viewinv[4];
+       /* use the view rotation to identify which axis to sync on */
+       float view_axis_all[4][3] = {
+           {1.0f, 0.0f, 0.0f},
+           {0.0f, 1.0f, 0.0f},
+           {1.0f, 0.0f, 0.0f},
+           {0.0f, 1.0f, 0.0f}};
+       float *view_src_x = &view_axis_all[0][0];
+       float *view_src_y = &view_axis_all[1][0];
+       float *view_dst_x = &view_axis_all[2][0];
+       float *view_dst_y = &view_axis_all[3][0];
+       int i;
+       /* we could use rv3d->viewinv, but better not depend on view matrix being updated */
+       if (UNLIKELY(ED_view3d_quat_from_axis_view(rv3d_src->view, viewinv) == false)) {
+               return;
+       }
+       invert_qt_normalized(viewinv);
+       mul_qt_v3(viewinv, view_src_x);
+       mul_qt_v3(viewinv, view_src_y);
+       if (UNLIKELY(ED_view3d_quat_from_axis_view(rv3d_dst->view, viewinv) == false)) {
+               return;
+       }
+       invert_qt_normalized(viewinv);
+       mul_qt_v3(viewinv, view_dst_x);
+       mul_qt_v3(viewinv, view_dst_y);
+       /* check source and dest have a matching axis */
+       for (i = 0; i < 3; i++) {
+               if (((fabsf(view_src_x[i]) > axis_eps) || (fabsf(view_src_y[i]) > axis_eps)) &&
+                   ((fabsf(view_dst_x[i]) > axis_eps) || (fabsf(view_dst_y[i]) > axis_eps)))
+               {
+                       rv3d_dst->ofs[i] = rv3d_src->ofs[i];
+               }
+       }
+ }
+ /* sync center/zoom view of region to others, for view transforms */
+ void view3d_boxview_sync(ScrArea *sa, ARegion *ar)
+ {
+       ARegion *artest;
+       RegionView3D *rv3d = ar->regiondata;
+       short clip = 0;
+       for (artest = sa->regionbase.first; artest; artest = artest->next) {
+               if (artest != ar && artest->regiontype == RGN_TYPE_WINDOW) {
+                       RegionView3D *rv3dtest = artest->regiondata;
+                       if (rv3dtest->viewlock & RV3D_LOCKED) {
+                               rv3dtest->dist = rv3d->dist;
+                               view3d_boxview_sync_axis(rv3dtest, rv3d);
+                               clip |= rv3dtest->viewlock & RV3D_BOXCLIP;
+                               ED_region_tag_redraw(artest);
+                       }
+               }
+       }
+       if (clip) {
+               view3d_boxview_clip(sa);
+       }
+ }
+ /* for home, center etc */
+ void view3d_boxview_copy(ScrArea *sa, ARegion *ar)
+ {
+       ARegion *artest;
+       RegionView3D *rv3d = ar->regiondata;
+       bool clip = false;
+       for (artest = sa->regionbase.first; artest; artest = artest->next) {
+               if (artest != ar && artest->regiontype == RGN_TYPE_WINDOW) {
+                       RegionView3D *rv3dtest = artest->regiondata;
+                       if (rv3dtest->viewlock) {
+                               rv3dtest->dist = rv3d->dist;
+                               copy_v3_v3(rv3dtest->ofs, rv3d->ofs);
+                               ED_region_tag_redraw(artest);
+                               clip |= ((rv3dtest->viewlock & RV3D_BOXCLIP) != 0);
+                       }
+               }
+       }
+       if (clip) {
+               view3d_boxview_clip(sa);
+       }
+ }
+ /* 'clip' is used to know if our clip setting has changed */
+ void ED_view3d_quadview_update(ScrArea *sa, ARegion *ar, bool do_clip)
+ {
+       ARegion *ar_sync = NULL;
+       RegionView3D *rv3d = ar->regiondata;
+       short viewlock;
+       /* this function copies flags from the first of the 3 other quadview
+        * regions to the 2 other, so it assumes this is the region whose
+        * properties are always being edited, weak */
+       viewlock = rv3d->viewlock;
+       if ((viewlock & RV3D_LOCKED) == 0) {
+               do_clip = (viewlock & RV3D_BOXCLIP) != 0;
+               viewlock = 0;
+       }
+       else if ((viewlock & RV3D_BOXVIEW) == 0 && (viewlock & RV3D_BOXCLIP) != 0) {
+               do_clip = true;
+               viewlock &= ~RV3D_BOXCLIP;
+       }
+       for (; ar; ar = ar->prev) {
+               if (ar->alignment == RGN_ALIGN_QSPLIT) {
+                       rv3d = ar->regiondata;
+                       rv3d->viewlock = viewlock;
+                       if (do_clip && (viewlock & RV3D_BOXCLIP) == 0) {
+                               rv3d->rflag &= ~RV3D_BOXCLIP;
+                       }
+                       /* use ar_sync so we sync with one of the aligned views below
+                        * else the view jumps on changing view settings like 'clip'
+                        * since it copies from the perspective view */
+                       ar_sync = ar;
+               }
+       }
+       if (rv3d->viewlock & RV3D_BOXVIEW) {
+               view3d_boxview_sync(sa, ar_sync ? ar_sync : sa->regionbase.last);
+       }
+       /* ensure locked regions have an axis, locked user views don't make much sense */
+       if (viewlock & RV3D_LOCKED) {
+               int index_qsplit = 0;
+               for (ar = sa->regionbase.first; ar; ar = ar->next) {
+                       if (ar->alignment == RGN_ALIGN_QSPLIT) {
+                               rv3d = ar->regiondata;
+                               if (rv3d->viewlock) {
+                                       if (!RV3D_VIEW_IS_AXIS(rv3d->view)) {
+                                               rv3d->view = ED_view3d_lock_view_from_index(index_qsplit);
+                                               rv3d->persp = RV3D_ORTHO;
+                                               ED_view3d_lock(rv3d);
+                                       }
+                               }
+                               index_qsplit++;
+                       }
+               }
+       }
+       ED_area_tag_redraw(sa);
+ }
+ /** \} */
+ /* -------------------------------------------------------------------- */
+ /** \name View Auto-Depth Utilities
+  * \{ */
+ static float view_autodist_depth_margin(ARegion *ar, const int mval[2], int margin)
+ {
+       ViewDepths depth_temp = {0};
+       rcti rect;
+       float depth_close;
+       if (margin == 0) {
+               /* Get Z Depths, needed for perspective, nice for ortho */
+               rect.xmin = mval[0];
+               rect.ymin = mval[1];
+               rect.xmax = mval[0] + 1;
+               rect.ymax = mval[1] + 1;
+       }
+       else {
+               BLI_rcti_init_pt_radius(&rect, mval, margin);
+       }
+       view3d_update_depths_rect(ar, &depth_temp, &rect);
+       depth_close = view3d_depth_near(&depth_temp);
+       MEM_SAFE_FREE(depth_temp.depths);
+       return depth_close;
+ }
+ /**
+  * Get the world-space 3d location from a screen-space 2d point.
+  *
+  * \param mval: Input screen-space pixel location.
+  * \param mouse_worldloc: Output world-space location.
+  * \param fallback_depth_pt: Use this points depth when no depth can be found.
+  */
+ bool ED_view3d_autodist(
 -      bglMats mats; /* ZBuffer depth vars */
++        const EvaluationContext *eval_ctx, struct Depsgraph *graph, ARegion *ar, View3D *v3d,
+         const int mval[2], float mouse_worldloc[3],
+         const bool alphaoverride, const float fallback_depth_pt[3])
+ {
 -      double cent[2],  p[3];
+       float depth_close;
 -      ED_view3d_draw_depth(scene, ar, v3d, alphaoverride);
 -
 -      /* call after in case settings have been modified since last drawing, see: T47089 */
 -      bgl_get_mats(&mats);
+       int margin_arr[] = {0, 2, 4};
+       int i;
+       bool depth_ok = false;
+       /* Get Z Depths, needed for perspective, nice for ortho */
 -              cent[0] = (double)mval[0] + 0.5;
 -              cent[1] = (double)mval[1] + 0.5;
++      ED_view3d_draw_depth(eval_ctx, graph, ar, v3d, alphaoverride);
+       /* Attempt with low margin's first */
+       i = 0;
+       do {
+               depth_close = view_autodist_depth_margin(ar, mval, margin_arr[i++] * U.pixelsize);
+               depth_ok = (depth_close != FLT_MAX);
+       } while ((depth_ok == false) && (i < ARRAY_SIZE(margin_arr)));
+       if (depth_ok) {
 -              if (gluUnProject(cent[0], cent[1], depth_close,
 -                               mats.modelview, mats.projection, (GLint *)mats.viewport, &p[0], &p[1], &p[2]))
 -              {
 -                      mouse_worldloc[0] = (float)p[0];
 -                      mouse_worldloc[1] = (float)p[1];
 -                      mouse_worldloc[2] = (float)p[2];
++              float centx = (float)mval[0] + 0.5f;
++              float centy = (float)mval[1] + 0.5f;
 -void ED_view3d_autodist_init(Scene *scene, ARegion *ar, View3D *v3d, int mode)
++              if (ED_view3d_unproject(ar, centx, centy, depth_close, mouse_worldloc)) {
+                       return true;
+               }
+       }
+       if (fallback_depth_pt) {
+               ED_view3d_win_to_3d_int(v3d, ar, fallback_depth_pt, mval, mouse_worldloc);
+               return true;
+       }
+       else {
+               return false;
+       }
+ }
 -                      ED_view3d_draw_depth(scene, ar, v3d, true);
++void ED_view3d_autodist_init(
++        const EvaluationContext *eval_ctx, struct Depsgraph *graph,
++        ARegion *ar, View3D *v3d, int mode)
+ {
+       /* Get Z Depths, needed for perspective, nice for ortho */
+       switch (mode) {
+               case 0:
 -                      ED_view3d_draw_depth_gpencil(scene, ar, v3d);
++                      ED_view3d_draw_depth(eval_ctx, graph, ar, v3d, true);
+                       break;
+               case 1:
 -bool ED_view3d_autodist_simple(
 -        ARegion *ar, const int mval[2], float mouse_worldloc[3],
 -        int margin, float *force_depth)
++              {
++                      Scene *scene = DEG_get_evaluated_scene(graph);
++                      ED_view3d_draw_depth_gpencil(eval_ctx, scene, ar, v3d);
+                       break;
++              }
+       }
+ }
+ /* no 4x4 sampling, run #ED_view3d_autodist_init first */
 -      bglMats mats; /* ZBuffer depth vars, could cache? */
++bool ED_view3d_autodist_simple(ARegion *ar, const int mval[2], float mouse_worldloc[3],
++                               int margin, float *force_depth)
+ {
 -      double cent[2],  p[3];
+       float depth;
 -      cent[0] = (double)mval[0] + 0.5;
 -      cent[1] = (double)mval[1] + 0.5;
 -
 -      bgl_get_mats(&mats);
 -
 -      if (!gluUnProject(cent[0], cent[1], depth,
 -                        mats.modelview, mats.projection, (GLint *)mats.viewport, &p[0], &p[1], &p[2]))
 -      {
 -              return false;
 -      }
 -
 -      mouse_worldloc[0] = (float)p[0];
 -      mouse_worldloc[1] = (float)p[1];
 -      mouse_worldloc[2] = (float)p[2];
 -      return true;
+       /* Get Z Depths, needed for perspective, nice for ortho */
+       if (force_depth)
+               depth = *force_depth;
+       else
+               depth = view_autodist_depth_margin(ar, mval, margin);
+       if (depth == FLT_MAX)
+               return false;
 -        const ViewContext *vc, const bglMats *mats, const int mval[2],
++      float centx = (float)mval[0] + 0.5f;
++      float centy = (float)mval[1] + 0.5f;
++      return ED_view3d_unproject(ar, centx, centy, depth, mouse_worldloc);
+ }
+ bool ED_view3d_autodist_depth(ARegion *ar, const int mval[2], int margin, float *depth)
+ {
+       *depth = view_autodist_depth_margin(ar, mval, margin);
+       return (*depth != FLT_MAX);
+ }
+ static bool depth_segment_cb(int x, int y, void *userData)
+ {
+       struct { ARegion *ar; int margin; float depth; } *data = userData;
+       int mval[2];
+       float depth;
+       mval[0] = x;
+       mval[1] = y;
+       depth = view_autodist_depth_margin(data->ar, mval, data->margin);
+       if (depth != FLT_MAX) {
+               data->depth = depth;
+               return 0;
+       }
+       else {
+               return 1;
+       }
+ }
+ bool ED_view3d_autodist_depth_seg(
+         ARegion *ar, const int mval_sta[2], const int mval_end[2],
+         int margin, float *depth)
+ {
+       struct { ARegion *ar; int margin; float depth; } data = {NULL};
+       int p1[2];
+       int p2[2];
+       data.ar = ar;
+       data.margin = margin;
+       data.depth = FLT_MAX;
+       copy_v2_v2_int(p1, mval_sta);
+       copy_v2_v2_int(p2, mval_end);
+       BLI_bitmap_draw_2d_line_v2v2i(p1, p2, depth_segment_cb, &data);
+       *depth = data.depth;
+       return (*depth != FLT_MAX);
+ }
+ /** \} */
+ /* -------------------------------------------------------------------- */
+ /** \name View Radius/Distance Utilities
+  *
+  * Use to calculate a distance to a point based on it's radius.
+  * \{ */
+ float ED_view3d_radius_to_dist_persp(const float angle, const float radius)
+ {
+       return radius * (1.0f / tanf(angle / 2.0f));
+ }
+ float ED_view3d_radius_to_dist_ortho(const float lens, const float radius)
+ {
+       return radius / (DEFAULT_SENSOR_WIDTH / lens);
+ }
+ /**
+  * Return a new RegionView3D.dist value to fit the \a radius.
+  *
+  * \note Depth isn't taken into account, this will fit a flat plane exactly,
+  * but points towards the view (with a perspective projection),
+  * may be within the radius but outside the view. eg:
+  *
+  * <pre>
+  *           +
+  * pt --> + /^ radius
+  *         / |
+  *        /  |
+  * view  +   +
+  *        \  |
+  *         \ |
+  *          \|
+  *           +
+  * </pre>
+  *
+  * \param ar  Can be NULL if \a use_aspect is false.
+  * \param persp  Allow the caller to tell what kind of perspective to use (ortho/view/camera)
+  * \param use_aspect  Increase the distance to account for non 1:1 view aspect.
+  * \param radius  The radius will be fitted exactly, typically pre-scaled by a margin (#VIEW3D_MARGIN).
+  */
+ float ED_view3d_radius_to_dist(
+         const View3D *v3d, const ARegion *ar,
+         const char persp, const bool use_aspect,
+         const float radius)
+ {
+       float dist;
+       BLI_assert(ELEM(persp, RV3D_ORTHO, RV3D_PERSP, RV3D_CAMOB));
+       BLI_assert((persp != RV3D_CAMOB) || v3d->camera);
+       if (persp == RV3D_ORTHO) {
+               dist = ED_view3d_radius_to_dist_ortho(v3d->lens, radius);
+       }
+       else {
+               float lens, sensor_size, zoom;
+               float angle;
+               if (persp == RV3D_CAMOB) {
+                       CameraParams params;
+                       BKE_camera_params_init(&params);
+                       params.clipsta = v3d->near;
+                       params.clipend = v3d->far;
+                       BKE_camera_params_from_object(&params, v3d->camera);
+                       lens = params.lens;
+                       sensor_size = BKE_camera_sensor_size(params.sensor_fit, params.sensor_x, params.sensor_y);
+                       /* ignore 'rv3d->camzoom' because we want to fit to the cameras frame */
+                       zoom = CAMERA_PARAM_ZOOM_INIT_CAMOB;
+               }
+               else {
+                       lens = v3d->lens;
+                       sensor_size = DEFAULT_SENSOR_WIDTH;
+                       zoom = CAMERA_PARAM_ZOOM_INIT_PERSP;
+               }
+               angle = focallength_to_fov(lens, sensor_size);
+               /* zoom influences lens, correct this by scaling the angle as a distance (by the zoom-level) */
+               angle = atanf(tanf(angle / 2.0f) * zoom) * 2.0f;
+               dist = ED_view3d_radius_to_dist_persp(angle, radius);
+       }
+       if (use_aspect) {
+               const RegionView3D *rv3d = ar->regiondata;
+               float winx, winy;
+               if (persp == RV3D_CAMOB) {
+                       /* camera frame x/y in pixels */
+                       winx = ar->winx / rv3d->viewcamtexcofac[0];
+                       winy = ar->winy / rv3d->viewcamtexcofac[1];
+               }
+               else {
+                       winx = ar->winx;
+                       winy = ar->winy;
+               }
+               if (winx && winy) {
+                       float aspect = winx / winy;
+                       if (aspect < 1.0f) {
+                               aspect = 1.0f / aspect;
+                       }
+                       dist *= aspect;
+               }
+       }
+       return dist;
+ }
+ /** \} */
+ /* -------------------------------------------------------------------- */
+ /** \name View Distance Utilities
+  * \{ */
+ /* problem - ofs[3] can be on same location as camera itself.
+  * Blender needs proper dist value for zoom.
+  * use fallback_dist to override small values
+  */
+ float ED_view3d_offset_distance(float mat[4][4], const float ofs[3], const float fallback_dist)
+ {
+       float pos[4] = {0.0f, 0.0f, 0.0f, 1.0f};
+       float dir[4] = {0.0f, 0.0f, 1.0f, 0.0f};
+       float dist;
+       mul_m4_v4(mat, pos);
+       add_v3_v3(pos, ofs);
+       mul_m4_v4(mat, dir);
+       normalize_v3(dir);
+       dist = dot_v3v3(pos, dir);
+       if ((dist < FLT_EPSILON) && (fallback_dist != 0.0f)) {
+               dist = fallback_dist;
+       }
+       return dist;
+ }
+ /**
+  * Set the dist without moving the view (compensate with #RegionView3D.ofs)
+  *
+  * \note take care that viewinv is up to date, #ED_view3d_update_viewmat first.
+  */
+ void ED_view3d_distance_set(RegionView3D *rv3d, const float dist)
+ {
+       float viewinv[4];
+       float tvec[3];
+       BLI_assert(dist >= 0.0f);
+       copy_v3_fl3(tvec, 0.0f, 0.0f, rv3d->dist - dist);
+       /* rv3d->viewinv isn't always valid */
+ #if 0
+       mul_mat3_m4_v3(rv3d->viewinv, tvec);
+ #else
+       invert_qt_qt_normalized(viewinv, rv3d->viewquat);
+       mul_qt_v3(viewinv, tvec);
+ #endif
+       sub_v3_v3(rv3d->ofs, tvec);
+       rv3d->dist = dist;
+ }
+ /** \} */
+ /* -------------------------------------------------------------------- */
+ /** \name View Axis Utilities
+  * \{ */
+ static float view3d_quat_axis[6][4] = {
+       {M_SQRT1_2, -M_SQRT1_2, 0.0f, 0.0f},    /* RV3D_VIEW_FRONT */
+       {0.0f, 0.0f, -M_SQRT1_2, -M_SQRT1_2},   /* RV3D_VIEW_BACK */
+       {0.5f, -0.5f, 0.5f, 0.5f},              /* RV3D_VIEW_LEFT */
+       {0.5f, -0.5f, -0.5f, -0.5f},            /* RV3D_VIEW_RIGHT */
+       {1.0f, 0.0f, 0.0f, 0.0f},               /* RV3D_VIEW_TOP */
+       {0.0f, -1.0f, 0.0f, 0.0f},              /* RV3D_VIEW_BOTTOM */
+ };
+ bool ED_view3d_quat_from_axis_view(const char view, float quat[4])
+ {
+       if (RV3D_VIEW_IS_AXIS(view)) {
+               copy_qt_qt(quat, view3d_quat_axis[view - RV3D_VIEW_FRONT]);
+               return true;
+       }
+       else {
+               return false;
+       }
+ }
+ char ED_view3d_quat_to_axis_view(const float quat[4], const float epsilon)
+ {
+       /* quat values are all unit length */
+       char view;
+       for (view = RV3D_VIEW_FRONT; view <= RV3D_VIEW_BOTTOM; view++) {
+               if (fabsf(angle_signed_qtqt(quat, view3d_quat_axis[view - RV3D_VIEW_FRONT])) < epsilon) {
+                       return view;
+               }
+       }
+       return RV3D_VIEW_USER;
+ }
+ char ED_view3d_lock_view_from_index(int index)
+ {
+       switch (index) {
+               case 0:  return RV3D_VIEW_FRONT;
+               case 1:  return RV3D_VIEW_TOP;
+               case 2:  return RV3D_VIEW_RIGHT;
+               default: return RV3D_VIEW_USER;
+       }
+ }
+ char ED_view3d_axis_view_opposite(char view)
+ {
+       switch (view) {
+               case RV3D_VIEW_FRONT:   return RV3D_VIEW_BACK;
+               case RV3D_VIEW_BACK:    return RV3D_VIEW_FRONT;
+               case RV3D_VIEW_LEFT:    return RV3D_VIEW_RIGHT;
+               case RV3D_VIEW_RIGHT:   return RV3D_VIEW_LEFT;
+               case RV3D_VIEW_TOP:     return RV3D_VIEW_BOTTOM;
+               case RV3D_VIEW_BOTTOM:  return RV3D_VIEW_TOP;
+       }
+       return RV3D_VIEW_USER;
+ }
+ bool ED_view3d_lock(RegionView3D *rv3d)
+ {
+       return ED_view3d_quat_from_axis_view(rv3d->view, rv3d->viewquat);
+ }
+ /** \} */
+ /* -------------------------------------------------------------------- */
+ /** \name View Transform Utilities
+  * \{ */
+ /**
+  * Set the view transformation from a 4x4 matrix.
+  *
+  * \param mat The view 4x4 transformation matrix to assign.
+  * \param ofs The view offset, normally from RegionView3D.ofs.
+  * \param quat The view rotation, quaternion normally from RegionView3D.viewquat.
+  * \param dist The view distance from ofs, normally from RegionView3D.dist.
+  */
+ void ED_view3d_from_m4(float mat[4][4], float ofs[3], float quat[4], float *dist)
+ {
+       float nmat[3][3];
+       /* dist depends on offset */
+       BLI_assert(dist == NULL || ofs != NULL);
+       copy_m3_m4(nmat, mat);
+       normalize_m3(nmat);
+       /* Offset */
+       if (ofs)
+               negate_v3_v3(ofs, mat[3]);
+       /* Quat */
+       if (quat) {
+               mat3_normalized_to_quat(quat, nmat);
+               invert_qt_normalized(quat);
+       }
+       if (ofs && dist) {
+               madd_v3_v3fl(ofs, nmat[2], *dist);
+       }
+ }
+ /**
+  * Calculate the view transformation matrix from RegionView3D input.
+  * The resulting matrix is equivalent to RegionView3D.viewinv
+  * \param mat The view 4x4 transformation matrix to calculate.
+  * \param ofs The view offset, normally from RegionView3D.ofs.
+  * \param quat The view rotation, quaternion normally from RegionView3D.viewquat.
+  * \param dist The view distance from ofs, normally from RegionView3D.dist.
+  */
+ void ED_view3d_to_m4(float mat[4][4], const float ofs[3], const float quat[4], const float dist)
+ {
+       float iviewquat[4] = {-quat[0], quat[1], quat[2], quat[3]};
+       float dvec[3] = {0.0f, 0.0f, dist};
+       quat_to_mat4(mat, iviewquat);
+       mul_mat3_m4_v3(mat, dvec);
+       sub_v3_v3v3(mat[3], dvec, ofs);
+ }
+ /**
+  * Set the RegionView3D members from an objects transformation and optionally lens.
+  * \param ob The object to set the view to.
+  * \param ofs The view offset to be set, normally from RegionView3D.ofs.
+  * \param quat The view rotation to be set, quaternion normally from RegionView3D.viewquat.
+  * \param dist The view distance from ofs to be set, normally from RegionView3D.dist.
+  * \param lens The view lens angle set for cameras and lamps, normally from View3D.lens.
+  */
+ void ED_view3d_from_object(Object *ob, float ofs[3], float quat[4], float *dist, float *lens)
+ {
+       ED_view3d_from_m4(ob->obmat, ofs, quat, dist);
+       if (lens) {
+               CameraParams params;
+               BKE_camera_params_init(&params);
+               BKE_camera_params_from_object(&params, ob);
+               *lens = params.lens;
+       }
+ }
+ /**
+  * Set the object transformation from RegionView3D members.
+  * \param ob The object which has the transformation assigned.
+  * \param ofs The view offset, normally from RegionView3D.ofs.
+  * \param quat The view rotation, quaternion normally from RegionView3D.viewquat.
+  * \param dist The view distance from ofs, normally from RegionView3D.dist.
+  */
+ void ED_view3d_to_object(Object *ob, const float ofs[3], const float quat[4], const float dist)
+ {
+       float mat[4][4];
+       ED_view3d_to_m4(mat, ofs, quat, dist);
+       BKE_object_apply_mat4(ob, mat, true, true);
+ }
+ /** \} */
+ /* -------------------------------------------------------------------- */
+ /** \name Depth Buffer Utilities
+  * \{ */
+ float ED_view3d_depth_read_cached(const ViewContext *vc, const int mval[2])
+ {
+       ViewDepths *vd = vc->rv3d->depths;
+       int x = mval[0];
+       int y = mval[1];
+       if (vd && vd->depths && x > 0 && y > 0 && x < vd->w && y < vd->h) {
+               return vd->depths[y * vd->w + x];
+       }
+       else {
+               BLI_assert(1.0 <= vd->depth_range[1]);
+               return 1.0f;
+       }
+ }
+ bool ED_view3d_depth_read_cached_normal(
 -                              if (ED_view3d_depth_unproject(ar, mats, mval_ofs, depth, coords[i])) {
++        const ViewContext *vc, const int mval[2],
+         float r_normal[3])
+ {
+       /* Note: we could support passing in a radius.
+        * For now just read 9 pixels. */
+       /* pixels surrounding */
+       bool  depths_valid[9] = {false};
+       float coords[9][3] = {{0}};
+       ARegion *ar = vc->ar;
+       const ViewDepths *depths = vc->rv3d->depths;
+       for (int x = 0, i = 0; x < 2; x++) {
+               for (int y = 0; y < 2; y++) {
+                       const int mval_ofs[2] = {mval[0] + (x - 1), mval[1] + (y - 1)};
+                       const double depth = (double)ED_view3d_depth_read_cached(vc, mval_ofs);
+                       if ((depth > depths->depth_range[0]) && (depth < depths->depth_range[1])) {
 -        const ARegion *ar, const bglMats *mats,
++                              if (ED_view3d_depth_unproject(ar, mval_ofs, depth, coords[i])) {
+                                       depths_valid[i] = true;
+                               }
+                       }
+                       i++;
+               }
+       }
+       const int edges[2][6][2] = {
+           /* x edges */
+           {{0, 1}, {1, 2},
+            {3, 4}, {4, 5},
+            {6, 7}, {7, 8}},
+           /* y edges */
+           {{0, 3}, {3, 6},
+            {1, 4}, {4, 7},
+            {2, 5}, {5, 8}},
+       };
+       float cross[2][3] = {{0.0f}};
+       for (int i = 0; i < 6; i++) {
+               for (int axis = 0; axis < 2; axis++) {
+                       if (depths_valid[edges[axis][i][0]] && depths_valid[edges[axis][i][1]]) {
+                               float delta[3];
+                               sub_v3_v3v3(delta, coords[edges[axis][i][0]], coords[edges[axis][i][1]]);
+                               add_v3_v3(cross[axis], delta);
+                       }
+               }
+       }
+       cross_v3_v3v3(r_normal, cross[0], cross[1]);
+       if (normalize_v3(r_normal) != 0.0f) {
+               return true;
+       }
+       else {
+               return false;
+       }
+ }
+ bool ED_view3d_depth_unproject(
 -      double p[3];
 -      if (gluUnProject(
 -              (double)ar->winrct.xmin + mval[0] + 0.5,
 -              (double)ar->winrct.ymin + mval[1] + 0.5,
 -              depth, mats->modelview, mats->projection, (const GLint *)mats->viewport,
 -              &p[0], &p[1], &p[2]))
 -      {
 -              copy_v3fl_v3db(r_location_world, p);
 -              return true;
 -      }
 -      return false;
++        const ARegion *ar,
+         const int mval[2], const double depth,
+         float r_location_world[3])
+ {
 -
 -/* -------------------------------------------------------------------- */
 -/** \name Background Image Utilities
 - * \{ */
 -
 -BGpic *ED_view3d_background_image_new(View3D *v3d)
 -{
 -      BGpic *bgpic = MEM_callocN(sizeof(BGpic), "Background Image");
 -
 -      bgpic->rotation = 0.0f;
 -      bgpic->size = 5.0f;
 -      bgpic->blend = 0.5f;
 -      bgpic->iuser.fie_ima = 2;
 -      bgpic->iuser.ok = 1;
 -      bgpic->view = 0; /* 0 for all */
 -      bgpic->flag |= V3D_BGPIC_EXPANDED;
 -
 -      BLI_addtail(&v3d->bgpicbase, bgpic);
 -
 -      return bgpic;
 -}
 -
 -void ED_view3d_background_image_remove(View3D *v3d, BGpic *bgpic)
 -{
 -      BLI_remlink(&v3d->bgpicbase, bgpic);
 -
 -      MEM_freeN(bgpic);
 -}
 -
 -void ED_view3d_background_image_clear(View3D *v3d)
 -{
 -      BGpic *bgpic = v3d->bgpicbase.first;
 -
 -      while (bgpic) {
 -              BGpic *next_bgpic = bgpic->next;
 -
 -              ED_view3d_background_image_remove(v3d, bgpic);
 -
 -              bgpic = next_bgpic;
 -      }
 -}
 -
 -/** \} */
++      float centx = (float)mval[0] + 0.5f;
++      float centy = (float)mval[1] + 0.5f;
++      return ED_view3d_unproject(ar, centx, centy, depth, r_location_world);
+ }
+ void ED_view3d_depth_tag_update(RegionView3D *rv3d)
+ {
+       if (rv3d->depths)
+               rv3d->depths->damaged = true;
+ }
+ /** \} */
index 3af7f5c8ae8b2723ef15c74abc4a2e8a1d645258,7dfc465286df89b6e72c12871b7804c7221c7764..acc6d7184ff71156360bf6dfdb62ed580050b8f3
@@@ -28,7 -28,6 +28,6 @@@
   *  \ingroup spview3d
   */
  
  #include "DNA_camera_types.h"
  #include "DNA_scene_types.h"
  #include "DNA_object_types.h"
  #include "BLI_rect.h"
  #include "BLI_utildefines.h"
  
- #include "BKE_anim.h"
  #include "BKE_action.h"
  #include "BKE_camera.h"
  #include "BKE_context.h"
 -#include "BKE_depsgraph.h"
  #include "BKE_object.h"
  #include "BKE_global.h"
  #include "BKE_main.h"
  #include "BKE_report.h"
  #include "BKE_scene.h"
- #include "BKE_screen.h"
  
 -#include "BIF_gl.h"
 +#include "DEG_depsgraph.h"
 +
- #include "BIF_glutil.h"
  
  #include "UI_resources.h"
  
 +#include "GPU_glew.h"
  #include "GPU_select.h"
 +#include "GPU_matrix.h"
  
  #include "WM_api.h"
  #include "WM_types.h"
  
  #include "ED_screen.h"
- #include "ED_armature.h"
  
 +#include "DRW_engine.h"
 +
 +#include "DEG_depsgraph_query.h"
 +
  #ifdef WITH_GAMEENGINE
  #  include "BLI_listbase.h"
  #  include "BLI_callbacks.h"
@@@ -79,7 -68,6 +74,7 @@@
  #  include "BL_System.h"
  #endif
  
 +
  #include "view3d_intern.h"  /* own include */
  
  /* use this call when executing an operator,
@@@ -103,28 -91,13 +98,11 @@@ void view3d_region_operator_needs_openg
                RegionView3D *rv3d = ar->regiondata;
                
                wmSubWindowSet(win, ar->swinid);
 -              glMatrixMode(GL_PROJECTION);
 -              glLoadMatrixf(rv3d->winmat);
 -              glMatrixMode(GL_MODELVIEW);
 -              glLoadMatrixf(rv3d->viewmat);
 +              gpuLoadProjectionMatrix(rv3d->winmat);
 +              gpuLoadMatrix(rv3d->viewmat);
        }
  }
  
- float *ED_view3d_cursor3d_get(Scene *scene, View3D *v3d)
- {
-       if (v3d && v3d->localvd) return v3d->cursor;
-       else return scene->cursor;
- }
- Camera *ED_view3d_camera_data_get(View3D *v3d, RegionView3D *rv3d)
- {
-       /* establish the camera object, so we can default to view mapping if anything is wrong with it */
-       if ((rv3d->persp == RV3D_CAMOB) && v3d->camera && (v3d->camera->type == OB_CAMERA)) {
-               return v3d->camera->data;
-       }
-       else {
-               return NULL;
-       }
- }
  /* ****************** smooth view operator ****************** */
  /* This operator is one of the 'timer refresh' ones like animation playback */
  
@@@ -448,9 -421,6 +426,9 @@@ void ED_view3d_smooth_view_force_finish
          View3D *v3d, ARegion *ar)
  {
        RegionView3D *rv3d = ar->regiondata;
 +      EvaluationContext eval_ctx;
 +
 +      CTX_data_eval_ctx(C, &eval_ctx);
  
        if (rv3d && rv3d->sms) {
                rv3d->sms->time_allowed = 0.0;  /* force finishing */
                /* force update of view matrix so tools that run immediately after
                 * can use them without redrawing first */
                Scene *scene = CTX_data_scene(C);
 -              ED_view3d_update_viewmat(scene, v3d, ar, NULL, NULL, NULL);
 +              ED_view3d_update_viewmat(&eval_ctx, scene, v3d, ar, NULL, NULL, NULL);
        }
  }
  
@@@ -501,7 -471,7 +479,7 @@@ static int view3d_camera_to_view_exec(b
  
        BKE_object_tfm_protected_restore(v3d->camera, &obtfm, v3d->camera->protectflag);
  
 -      DAG_id_tag_update(&v3d->camera->id, OB_RECALC_OB);
 +      DEG_id_tag_update(&v3d->camera->id, OB_RECALC_OB);
        rv3d->persp = RV3D_CAMOB;
        
        WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, v3d->camera);
@@@ -549,7 -519,6 +527,7 @@@ void VIEW3D_OT_camera_to_view(wmOperato
  static int view3d_camera_to_view_selected_exec(bContext *C, wmOperator *op)
  {
        Scene *scene = CTX_data_scene(C);
 +      ViewLayer *view_layer = CTX_data_view_layer(C);
        View3D *v3d = CTX_wm_view3d(C);  /* can be NULL */
        Object *camera_ob = v3d ? v3d->camera : scene->camera;
  
        }
  
        /* this function does all the important stuff */
 -      if (BKE_camera_view_frame_fit_to_scene(scene, v3d, camera_ob, r_co, &r_scale)) {
 +      if (BKE_camera_view_frame_fit_to_scene(scene, view_layer, camera_ob, r_co, &r_scale)) {
                ObjectTfmProtectedChannels obtfm;
                float obmat_new[4][4];
  
                BKE_object_tfm_protected_restore(camera_ob, &obtfm, OB_LOCK_SCALE | OB_LOCK_ROT4D);
  
                /* notifiers */
 -              DAG_id_tag_update(&camera_ob->id, OB_RECALC_OB);
 +              DEG_id_tag_update(&camera_ob->id, OB_RECALC_OB);
                WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, camera_ob);
                return OPERATOR_FINISHED;
        }
@@@ -722,289 -691,17 +700,17 @@@ void VIEW3D_OT_object_as_camera(wmOpera
  
  /* ********************************** */
  
- void ED_view3d_clipping_calc_from_boundbox(float clip[4][4], const BoundBox *bb, const bool is_flip)
- {
-       int val;
-       for (val = 0; val < 4; val++) {
-               normal_tri_v3(clip[val], bb->vec[val], bb->vec[val == 3 ? 0 : val + 1], bb->vec[val + 4]);
-               if (UNLIKELY(is_flip)) {
-                       negate_v3(clip[val]);
-               }
-               clip[val][3] = -dot_v3v3(clip[val], bb->vec[val]);
-       }
- }
- void ED_view3d_clipping_calc(BoundBox *bb, float planes[4][4], const ARegion *ar, const Object *ob, const rcti *rect)
- {
-       /* init in case unproject fails */
-       memset(bb->vec, 0, sizeof(bb->vec));
-       /* four clipping planes and bounding volume */
-       /* first do the bounding volume */
-       for (int val = 0; val < 4; val++) {
-               float xs = (val == 0 || val == 3) ? rect->xmin : rect->xmax;
-               float ys = (val == 0 || val == 1) ? rect->ymin : rect->ymax;
-               ED_view3d_unproject(ar, xs, ys, 0.0, bb->vec[val]);
-               ED_view3d_unproject(ar, xs, ys, 1.0, bb->vec[4 + val]);
-       }
-       /* optionally transform to object space */
-       if (ob) {
-               float imat[4][4];
-               invert_m4_m4(imat, ob->obmat);
-               for (int val = 0; val < 8; val++) {
-                       mul_m4_v3(imat, bb->vec[val]);
-               }
-       }
-       /* verify if we have negative scale. doing the transform before cross
-        * product flips the sign of the vector compared to doing cross product
-        * before transform then, so we correct for that. */
-       int flip_sign = (ob) ? is_negative_m4(ob->obmat) : false;
-       ED_view3d_clipping_calc_from_boundbox(planes, bb, flip_sign);
- }
- static bool view3d_boundbox_clip_m4(const BoundBox *bb, float persmatob[4][4])
- {
-       int a, flag = -1, fl;
-       for (a = 0; a < 8; a++) {
-               float vec[4], min, max;
-               copy_v3_v3(vec, bb->vec[a]);
-               vec[3] = 1.0;
-               mul_m4_v4(persmatob, vec);
-               max = vec[3];
-               min = -vec[3];
-               fl = 0;
-               if (vec[0] < min) fl += 1;
-               if (vec[0] > max) fl += 2;
-               if (vec[1] < min) fl += 4;
-               if (vec[1] > max) fl += 8;
-               if (vec[2] < min) fl += 16;
-               if (vec[2] > max) fl += 32;
-               flag &= fl;
-               if (flag == 0) return true;
-       }
-       return false;
- }
- bool ED_view3d_boundbox_clip_ex(const RegionView3D *rv3d, const BoundBox *bb, float obmat[4][4])
- {
-       /* return 1: draw */
-       float persmatob[4][4];
-       if (bb == NULL) return true;
-       if (bb->flag & BOUNDBOX_DISABLED) return true;
-       mul_m4_m4m4(persmatob, (float(*)[4])rv3d->persmat, obmat);
-       return view3d_boundbox_clip_m4(bb, persmatob);
- }
- bool ED_view3d_boundbox_clip(RegionView3D *rv3d, const BoundBox *bb)
- {
-       if (bb == NULL) return true;
-       if (bb->flag & BOUNDBOX_DISABLED) return true;
-       return view3d_boundbox_clip_m4(bb, rv3d->persmatob);
- }
- /* -------------------------------------------------------------------- */
- /** \name Depth Utilities
-  * \{ */
- float ED_view3d_depth_read_cached(const ViewContext *vc, const int mval[2])
- {
-       ViewDepths *vd = vc->rv3d->depths;
-               
-       int x = mval[0];
-       int y = mval[1];
-       if (vd && vd->depths && x > 0 && y > 0 && x < vd->w && y < vd->h) {
-               return vd->depths[y * vd->w + x];
-       }
-       else {
-               BLI_assert(1.0 <= vd->depth_range[1]);
-               return 1.0f;
-       }
- }
- bool ED_view3d_depth_read_cached_normal(
-         const ViewContext *vc, const int mval[2],
-         float r_normal[3])
- {
-       /* Note: we could support passing in a radius.
-        * For now just read 9 pixels. */
-       /* pixels surrounding */
-       bool  depths_valid[9] = {false};
-       float coords[9][3] = {{0}};
-       ARegion *ar = vc->ar;
-       const ViewDepths *depths = vc->rv3d->depths;
-       for (int x = 0, i = 0; x < 2; x++) {
-               for (int y = 0; y < 2; y++) {
-                       const int mval_ofs[2] = {mval[0] + (x - 1), mval[1] + (y - 1)};
-                       const double depth = (double)ED_view3d_depth_read_cached(vc, mval_ofs);
-                       if ((depth > depths->depth_range[0]) && (depth < depths->depth_range[1])) {
-                               if (ED_view3d_depth_unproject(ar, mval_ofs, depth, coords[i])) {
-                                       depths_valid[i] = true;
-                               }
-                       }
-                       i++;
-               }
-       }
-       const int edges[2][6][2] = {
-           /* x edges */
-           {{0, 1}, {1, 2},
-            {3, 4}, {4, 5},
-            {6, 7}, {7, 8}},
-           /* y edges */
-           {{0, 3}, {3, 6},
-            {1, 4}, {4, 7},
-            {2, 5}, {5, 8}},
-       };
-       float cross[2][3] = {{0.0f}};
-       for (int i = 0; i < 6; i++) {
-               for (int axis = 0; axis < 2; axis++) {
-                       if (depths_valid[edges[axis][i][0]] && depths_valid[edges[axis][i][1]]) {
-                               float delta[3];
-                               sub_v3_v3v3(delta, coords[edges[axis][i][0]], coords[edges[axis][i][1]]);
-                               add_v3_v3(cross[axis], delta);
-                       }
-               }
-       }
-       cross_v3_v3v3(r_normal, cross[0], cross[1]);
-       if (normalize_v3(r_normal) != 0.0f) {
-               return true;
-       }
-       else {
-               return false;
-       }
- }
- bool ED_view3d_depth_unproject(
-         const ARegion *ar,
-         const int mval[2], const double depth,
-         float r_location_world[3])
- {
-       float centx = (float)mval[0] + 0.5f;
-       float centy = (float)mval[1] + 0.5f;
-       return ED_view3d_unproject(ar, centx, centy, depth, r_location_world);
- }
- /** \} */
- void ED_view3d_depth_tag_update(RegionView3D *rv3d)
- {
-       if (rv3d->depths)
-               rv3d->depths->damaged = true;
- }
- void ED_view3d_dist_range_get(
-         const View3D *v3d,
-         float r_dist_range[2])
- {
-       r_dist_range[0] = v3d->grid * 0.001f;
-       r_dist_range[1] = v3d->far * 10.0f;
- }
- /* copies logic of get_view3d_viewplane(), keep in sync */
- bool ED_view3d_clip_range_get(
-         const Depsgraph *depsgraph,
-         const View3D *v3d, const RegionView3D *rv3d,
-         float *r_clipsta, float *r_clipend,
-         const bool use_ortho_factor)
- {
-       CameraParams params;
-       BKE_camera_params_init(&params);
-       BKE_camera_params_from_view3d(&params, depsgraph, v3d, rv3d);
-       if (use_ortho_factor && params.is_ortho) {
-               const float fac = 2.0f / (params.clipend - params.clipsta);
-               params.clipsta *= fac;
-               params.clipend *= fac;
-       }
-       if (r_clipsta) *r_clipsta = params.clipsta;
-       if (r_clipend) *r_clipend = params.clipend;
-       return params.is_ortho;
- }
- bool ED_view3d_viewplane_get(
-         const Depsgraph *depsgraph,
-         const View3D *v3d, const RegionView3D *rv3d, int winx, int winy,
-         rctf *r_viewplane, float *r_clipsta, float *r_clipend, float *r_pixsize)
- {
-       CameraParams params;
-       BKE_camera_params_init(&params);
-       BKE_camera_params_from_view3d(&params, depsgraph, v3d, rv3d);
-       BKE_camera_params_compute_viewplane(&params, winx, winy, 1.0f, 1.0f);
-       if (r_viewplane) *r_viewplane = params.viewplane;
-       if (r_clipsta) *r_clipsta = params.clipsta;
-       if (r_clipend) *r_clipend = params.clipend;
-       if (r_pixsize) *r_pixsize = params.viewdx;
-       
-       return params.is_ortho;
- }
- /**
-  * Use instead of: ``bglPolygonOffset(rv3d->dist, ...)`` see bug [#37727]
-  */
- void ED_view3d_polygon_offset(const RegionView3D *rv3d, const float dist)
- {
-       float viewdist;
-       if (rv3d->rflag & RV3D_ZOFFSET_DISABLED) {
-               return;
-       }
-       viewdist = rv3d->dist;
-       /* special exception for ortho camera (viewdist isnt used for perspective cameras) */
-       if (dist != 0.0f) {
-               if (rv3d->persp == RV3D_CAMOB) {
-                       if (rv3d->is_persp == false) {
-                               viewdist = 1.0f / max_ff(fabsf(rv3d->winmat[0][0]), fabsf(rv3d->winmat[1][1]));
-                       }
-               }
-       }
-       bglPolygonOffset(viewdist, dist);
- }
  /**
   * \param rect optional for picking (can be NULL).
   */
 -void view3d_winmatrix_set(ARegion *ar, const View3D *v3d, const rcti *rect)
 +void view3d_winmatrix_set(const Depsgraph *depsgraph, ARegion *ar, const View3D *v3d, const rcti *rect)
  {
        RegionView3D *rv3d = ar->regiondata;
        rctf viewplane;
        float clipsta, clipend;
        bool is_ortho;
        
 -      is_ortho = ED_view3d_viewplane_get(v3d, rv3d, ar->winx, ar->winy, &viewplane, &clipsta, &clipend, NULL);
 +      is_ortho = ED_view3d_viewplane_get(depsgraph, v3d, rv3d, ar->winx, ar->winy, &viewplane, &clipsta, &clipend, NULL);
        rv3d->is_persp = !is_ortho;
  
  #if 0
        }
  
        if (is_ortho) {
 -              wmOrtho(viewplane.xmin, viewplane.xmax, viewplane.ymin, viewplane.ymax, clipsta, clipend);
 +              gpuOrtho(viewplane.xmin, viewplane.xmax, viewplane.ymin, viewplane.ymax, clipsta, clipend);
        }
        else {
 -              wmFrustum(viewplane.xmin, viewplane.xmax, viewplane.ymin, viewplane.ymax, clipsta, clipend);
 +              gpuFrustum(viewplane.xmin, viewplane.xmax, viewplane.ymin, viewplane.ymax, clipsta, clipend);
        }
  
        /* update matrix in 3d view region */
 -      glGetFloatv(GL_PROJECTION_MATRIX, (float *)rv3d->winmat);
 +      gpuGetProjectionMatrix(rv3d->winmat);
  }
  
  static void obmat_to_viewmat(RegionView3D *rv3d, Object *ob)
        mat4_normalized_to_quat(rv3d->viewquat, rv3d->viewmat);
  }
  
- static float view3d_quat_axis[6][4] = {
-       {M_SQRT1_2, -M_SQRT1_2, 0.0f, 0.0f},    /* RV3D_VIEW_FRONT */
-       {0.0f, 0.0f, -M_SQRT1_2, -M_SQRT1_2},   /* RV3D_VIEW_BACK */
-       {0.5f, -0.5f, 0.5f, 0.5f},              /* RV3D_VIEW_LEFT */
-       {0.5f, -0.5f, -0.5f, -0.5f},            /* RV3D_VIEW_RIGHT */
-       {1.0f, 0.0f, 0.0f, 0.0f},               /* RV3D_VIEW_TOP */
-       {0.0f, -1.0f, 0.0f, 0.0f},              /* RV3D_VIEW_BOTTOM */
- };
- bool ED_view3d_quat_from_axis_view(const char view, float quat[4])
- {
-       if (RV3D_VIEW_IS_AXIS(view)) {
-               copy_qt_qt(quat, view3d_quat_axis[view - RV3D_VIEW_FRONT]);
-               return true;
-       }
-       else {
-               return false;
-       }
- }
- char ED_view3d_quat_to_axis_view(const float quat[4], const float epsilon)
- {
-       /* quat values are all unit length */
-       char view;
-       for (view = RV3D_VIEW_FRONT; view <= RV3D_VIEW_BOTTOM; view++) {
-               if (fabsf(angle_signed_qtqt(quat, view3d_quat_axis[view - RV3D_VIEW_FRONT])) < epsilon) {
-                       return view;
-               }
-       }
-       return RV3D_VIEW_USER;
- }
- char ED_view3d_lock_view_from_index(int index)
- {
-       switch (index) {
-               case 0:  return RV3D_VIEW_FRONT;
-               case 1:  return RV3D_VIEW_TOP;
-               case 2:  return RV3D_VIEW_RIGHT;
-               default: return RV3D_VIEW_USER;
-       }
- }
- char ED_view3d_axis_view_opposite(char view)
- {
-       switch (view) {
-               case RV3D_VIEW_FRONT:   return RV3D_VIEW_BACK;
-               case RV3D_VIEW_BACK:    return RV3D_VIEW_FRONT;
-               case RV3D_VIEW_LEFT:    return RV3D_VIEW_RIGHT;
-               case RV3D_VIEW_RIGHT:   return RV3D_VIEW_LEFT;
-               case RV3D_VIEW_TOP:     return RV3D_VIEW_BOTTOM;
-               case RV3D_VIEW_BOTTOM:  return RV3D_VIEW_TOP;
-       }
-       return RV3D_VIEW_USER;
- }
- bool ED_view3d_lock(RegionView3D *rv3d)
- {
-       return ED_view3d_quat_from_axis_view(rv3d->view, rv3d->viewquat);
- }
  /**
   * Sets #RegionView3D.viewmat
   *
 + * \param eval_ctx: Context.
   * \param scene: Scene for camera and cursor location.
   * \param v3d: View 3D space data.
   * \param rv3d: 3D region which stores the final matrices.
   * \note don't set windows active in here, is used by renderwin too.
   */
  void view3d_viewmatrix_set(
 -        Scene *scene,
 +        const EvaluationContext *eval_ctx, Scene *scene,
          const View3D *v3d, RegionView3D *rv3d, const float rect_scale[2])
  {
        if (rv3d->persp == RV3D_CAMOB) {      /* obs/camera */
                if (v3d->camera) {
 -                      BKE_object_where_is_calc(scene, v3d->camera);
 -                      obmat_to_viewmat(rv3d, v3d->camera);
 +                      const Depsgraph *depsgraph = eval_ctx->depsgraph;
 +                      Object *camera_object = DEG_get_evaluated_object(depsgraph, v3d->camera);
 +                      BKE_object_where_is_calc(eval_ctx, scene, camera_object);
 +                      obmat_to_viewmat(rv3d, camera_object);
                }
                else {
                        quat_to_mat4(rv3d->viewmat, rv3d->viewquat);
@@@ -1229,11 -856,10 +868,11 @@@ void view3d_opengl_select_cache_end(voi
   * \note (vc->obedit == NULL) can be set to explicitly skip edit-object selection.
   */
  int view3d_opengl_select(
 -        ViewContext *vc, unsigned int *buffer, unsigned int bufsize, const rcti *input,
 +        const EvaluationContext *eval_ctx, ViewContext *vc, unsigned int *buffer, unsigned int bufsize, const rcti *input,
          eV3DSelectMode select_mode)
  {
        struct bThemeState theme_state;
 +      Depsgraph *graph = vc->depsgraph;
        Scene *scene = vc->scene;
        View3D *v3d = vc->v3d;
        ARegion *ar = vc->ar;
  
        /* Important we use the 'viewmat' and don't re-calculate since
         * the object & bone view locking takes 'rect' into account, see: T51629. */
 -      ED_view3d_draw_setup_view(vc->win, scene, ar, v3d, vc->rv3d->viewmat, NULL, &rect);
 +      ED_view3d_draw_setup_view(vc->win, eval_ctx, scene, ar, v3d, vc->rv3d->viewmat, NULL, &rect);
  
        if (v3d->drawtype > OB_WIRE) {
                v3d->zbuf = true;
        
        GPU_select_begin(buffer, bufsize, &rect, gpu_select_mode, 0);
  
 -      ED_view3d_draw_select_loop(vc, scene, v3d, ar, use_obedit_skip, use_nearest);
 +#ifdef WITH_OPENGL_LEGACY
 +      if (IS_VIEWPORT_LEGACY(vc->v3d)) {
 +              ED_view3d_draw_select_loop(vc, scene, sl, v3d, ar, use_obedit_skip, use_nearest);
 +      }
 +      else
 +#else
 +      {
 +              DRW_draw_select_loop(graph, ar, v3d, use_obedit_skip, use_nearest, &rect);
 +      }
 +#endif /* WITH_OPENGL_LEGACY */
  
        hits = GPU_select_end();
        
        if (do_passes && (hits > 0)) {
                GPU_select_begin(buffer, bufsize, &rect, GPU_SELECT_NEAREST_SECOND_PASS, hits);
  
 -              ED_view3d_draw_select_loop(vc, scene, v3d, ar, use_obedit_skip, use_nearest);
 +#ifdef WITH_OPENGL_LEGACY
 +              if (IS_VIEWPORT_LEGACY(vc->v3d)) {
 +                      ED_view3d_draw_select_loop(vc, scene, sl, v3d, ar, use_obedit_skip, use_nearest);
 +              }
 +              else
 +#else
 +              {
 +                      DRW_draw_select_loop(graph, ar, v3d, use_obedit_skip, use_nearest, &rect);
 +              }
 +#endif /* WITH_OPENGL_LEGACY */
  
                GPU_select_end();
        }
  
        G.f &= ~G_PICKSEL;
 -      ED_view3d_draw_setup_view(vc->win, scene, ar, v3d, vc->rv3d->viewmat, NULL, NULL);
 +      ED_view3d_draw_setup_view(vc->win, eval_ctx, scene, ar, v3d, vc->rv3d->viewmat, NULL, NULL);
        
        if (v3d->drawtype > OB_WIRE) {
                v3d->zbuf = 0;
@@@ -1357,7 -965,43 +996,7 @@@ finally
        return hits;
  }
  
 -/* ********************** local view operator ******************** */
 -
 -static unsigned int free_localbit(Main *bmain)
 -{
 -      unsigned int lay;
 -      ScrArea *sa;
 -      bScreen *sc;
 -      
 -      lay = 0;
 -      
 -      /* sometimes we loose a localview: when an area is closed */
 -      /* check all areas: which localviews are in use? */
 -      for (sc = bmain->screen.first; sc; sc = sc->id.next) {
 -              for (sa = sc->areabase.first; sa; sa = sa->next) {
 -                      SpaceLink *sl = sa->spacedata.first;
 -                      for (; sl; sl = sl->next) {
 -                              if (sl->spacetype == SPACE_VIEW3D) {
 -                                      View3D *v3d = (View3D *) sl;
 -                                      lay |= v3d->lay;
 -                              }
 -                      }
 -              }
 -      }
 -      
 -      if ((lay & 0x01000000) == 0) return 0x01000000;
 -      if ((lay & 0x02000000) == 0) return 0x02000000;
 -      if ((lay & 0x04000000) == 0) return 0x04000000;
 -      if ((lay & 0x08000000) == 0) return 0x08000000;
 -      if ((lay & 0x10000000) == 0) return 0x10000000;
 -      if ((lay & 0x20000000) == 0) return 0x20000000;
 -      if ((lay & 0x40000000) == 0) return 0x40000000;
 -      if ((lay & 0x80000000) == 0) return 0x80000000;
 -      
 -      return 0;
 -}
 -
 -int ED_view3d_scene_layer_set(int lay, const int *values, int *active)
 +int ED_view3d_view_layer_set(int lay, const int *values, int *active)
  {
        int i, tot = 0;
        
        return lay;
  }
  
 -static bool view3d_localview_init(
 -        wmWindowManager *wm, wmWindow *win,
 -        Main *bmain, Scene *scene, ScrArea *sa, const int smooth_viewtx,
 -        ReportList *reports)
 -{
 -      View3D *v3d = sa->spacedata.first;
 -      Base *base;
 -      float min[3], max[3], box[3], mid[3];
 -      float size = 0.0f;
 -      unsigned int locallay;
 -      bool ok = false;
 -
 -      if (v3d->localvd) {
 -              return ok;
 -      }
 -
 -      INIT_MINMAX(min, max);
 -
 -      locallay = free_localbit(bmain);
 -
 -      if (locallay == 0) {
 -              BKE_report(reports, RPT_ERROR, "No more than 8 local views");
 -              ok = false;
 -      }
 -      else {
 -              if (scene->obedit) {
 -                      BKE_object_minmax(scene->obedit, min, max, false);
 -                      
 -                      ok = true;
 -              
 -                      BASACT->lay |= locallay;
 -                      scene->obedit->lay = BASACT->lay;
 -              }
 -              else {
 -                      for (base = FIRSTBASE; base; base = base->next) {
 -                              if (TESTBASE(v3d, base)) {
 -                                      BKE_object_minmax(base->object, min, max, false);
 -                                      base->lay |= locallay;
 -                                      base->object->lay = base->lay;
 -                                      ok = true;
 -                              }
 -                      }
 -              }
 -
 -              sub_v3_v3v3(box, max, min);
 -              size = max_fff(box[0], box[1], box[2]);
 -      }
 -      
 -      if (ok == true) {
 -              ARegion *ar;
 -              
 -              v3d->localvd = MEM_mallocN(sizeof(View3D), "localview");
 -              
 -              memcpy(v3d->localvd, v3d, sizeof(View3D));
 -
 -              mid_v3_v3v3(mid, min, max);
 -
 -              copy_v3_v3(v3d->cursor, mid);
 -
 -              for (ar = sa->regionbase.first; ar; ar = ar->next) {
 -                      if (ar->regiontype == RGN_TYPE_WINDOW) {
 -                              RegionView3D *rv3d = ar->regiondata;
 -                              bool ok_dist = true;
 -
 -                              /* new view values */
 -                              Object *camera_old = NULL;
 -                              float dist_new, ofs_new[3];
 -
 -                              rv3d->localvd = MEM_mallocN(sizeof(RegionView3D), "localview region");
 -                              memcpy(rv3d->localvd, rv3d, sizeof(RegionView3D));
 -
 -                              negate_v3_v3(ofs_new, mid);
 -
 -                              if (rv3d->persp == RV3D_CAMOB) {
 -                                      rv3d->persp = RV3D_PERSP;
 -                                      camera_old = v3d->camera;
 -                              }
 -
 -                              if (rv3d->persp == RV3D_ORTHO) {
 -                                      if (size < 0.0001f) {
 -                                              ok_dist = false;
 -                                      }
 -                              }
 -
 -                              if (ok_dist) {
 -                                      dist_new = ED_view3d_radius_to_dist(v3d, ar, rv3d->persp, true, (size / 2) * VIEW3D_MARGIN);
 -                                      if (rv3d->persp == RV3D_PERSP) {
 -                                              /* don't zoom closer than the near clipping plane */
 -                                              dist_new = max_ff(dist_new, v3d->near * 1.5f);
 -                                      }
 -                              }
 -
 -                              ED_view3d_smooth_view_ex(
 -                                      wm, win, sa, v3d, ar, smooth_viewtx,
 -                                          &(const V3D_SmoothParams) {
 -                                              .camera_old = camera_old,
 -                                              .ofs = ofs_new, .quat = rv3d->viewquat,
 -                                              .dist = ok_dist ? &dist_new : NULL, .lens = &v3d->lens});
 -                      }
 -              }
 -              
 -              v3d->lay = locallay;
 -      }
 -      else {
 -              /* clear flags */ 
 -              for (base = FIRSTBASE; base; base = base->next) {
 -                      if (base->lay & locallay) {
 -                              base->lay -= locallay;
 -                              if (base->lay == 0) base->lay = v3d->layact;
 -                              if (base->object != scene->obedit) base->flag |= SELECT;
 -                              base->object->lay = base->lay;
 -                      }
 -              }
 -      }
 -
 -      DAG_on_visible_update(bmain, false);
 -
 -      return ok;
 -}
 -
 -static void restore_localviewdata(wmWindowManager *wm, wmWindow *win, Main *bmain, Scene *scene, ScrArea *sa, const int smooth_viewtx)
 -{
 -      const bool free = true;
 -      ARegion *ar;
 -      View3D *v3d = sa->spacedata.first;
 -      Object *camera_old, *camera_new;
 -      
 -      if (v3d->localvd == NULL) return;
 -      
 -      camera_old = v3d->camera;
 -      camera_new = v3d->localvd->camera;
 -
 -      v3d->lay = v3d->localvd->lay;
 -      v3d->layact = v3d->localvd->layact;
 -      v3d->drawtype = v3d->localvd->drawtype;
 -      v3d->camera = v3d->localvd->camera;
 -      
 -      if (free) {
 -              MEM_freeN(v3d->localvd);
 -              v3d->localvd = NULL;
 -      }
 -      
 -      for (ar = sa->regionbase.first; ar; ar = ar->next) {
 -              if (ar->regiontype == RGN_TYPE_WINDOW) {
 -                      RegionView3D *rv3d = ar->regiondata;
 -                      
 -                      if (rv3d->localvd) {
 -                              Object *camera_old_rv3d, *camera_new_rv3d;
 -
 -                              camera_old_rv3d = (rv3d->persp          == RV3D_CAMOB) ? camera_old : NULL;
 -                              camera_new_rv3d = (rv3d->localvd->persp == RV3D_CAMOB) ? camera_new : NULL;
 -
 -                              rv3d->view = rv3d->localvd->view;
 -                              rv3d->persp = rv3d->localvd->persp;
 -                              rv3d->camzoom = rv3d->localvd->camzoom;
 -
 -                              ED_view3d_smooth_view_ex(
 -                                      wm, win, sa,
 -                                      v3d, ar, smooth_viewtx,
 -                                      &(const V3D_SmoothParams) {
 -                                          .camera_old = camera_old_rv3d, .camera = camera_new_rv3d,
 -                                          .ofs = rv3d->localvd->ofs, .quat = rv3d->localvd->viewquat,
 -                                          .dist = &rv3d->localvd->dist});
 -
 -                              if (free) {
 -                                      MEM_freeN(rv3d->localvd);
 -                                      rv3d->localvd = NULL;
 -                              }
 -                      }
 -
 -                      ED_view3d_shade_update(bmain, scene, v3d, sa);
 -              }
 -      }
 -}
 -
 -static bool view3d_localview_exit(
 -        wmWindowManager *wm, wmWindow *win,
 -        Main *bmain, Scene *scene, ScrArea *sa, const int smooth_viewtx)
 -{
 -      View3D *v3d = sa->spacedata.first;
 -      struct Base *base;
 -      unsigned int locallay;
 -      
 -      if (v3d->localvd) {
 -              
 -              locallay = v3d->lay & 0xFF000000;
 -
 -              restore_localviewdata(wm, win, bmain, scene, sa, smooth_viewtx);
 -
 -              /* for when in other window the layers have changed */
 -              if (v3d->scenelock) v3d->lay = scene->lay;
 -              
 -              for (base = FIRSTBASE; base; base = base->next) {
 -                      if (base->lay & locallay) {
 -                              base->lay -= locallay;
 -                              if (base->lay == 0) base->lay = v3d->layact;
 -                              if (base->object != scene->obedit) {
 -                                      base->flag |= SELECT;
 -                                      base->object->flag |= SELECT;
 -                              }
 -                              base->object->lay = base->lay;
 -                      }
 -              }
 -              
 -              DAG_on_visible_update(bmain, false);
 -
 -              return true;
 -      }
 -      else {
 -              return false;
 -      }
 -}
 -
 -static int localview_exec(bContext *C, wmOperator *op)
 -{
 -      const int smooth_viewtx = WM_operator_smooth_viewtx_get(op);
 -      wmWindowManager *wm = CTX_wm_manager(C);
 -      wmWindow *win = CTX_wm_window(C);
 -      Main *bmain = CTX_data_main(C);
 -      Scene *scene = CTX_data_scene(C);
 -      ScrArea *sa = CTX_wm_area(C);
 -      View3D *v3d = CTX_wm_view3d(C);
 -      bool changed;
 -      
 -      if (v3d->localvd) {
 -              changed = view3d_localview_exit(wm, win, bmain, scene, sa, smooth_viewtx);
 -      }
 -      else {
 -              changed = view3d_localview_init(wm, win, bmain, scene, sa, smooth_viewtx, op->reports);
 -      }
 -
 -      if (changed) {
 -              DAG_id_type_tag(bmain, ID_OB);
 -              ED_area_tag_redraw(sa);
 -
 -              /* unselected objects become selected when exiting */
 -              if (v3d->localvd == NULL) {
 -                      WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
 -              }
 -
 -              return OPERATOR_FINISHED;
 -      }
 -      else {
 -              return OPERATOR_CANCELLED;
 -      }
 -}
 -
 -void VIEW3D_OT_localview(wmOperatorType *ot)
 -{
 -      /* identifiers */
 -      ot->name = "Local View";
 -      ot->description = "Toggle display of selected object(s) separately and centered in view";
 -      ot->idname = "VIEW3D_OT_localview";
 -      
 -      /* api callbacks */
 -      ot->exec = localview_exec;
 -      ot->flag = OPTYPE_UNDO; /* localview changes object layer bitflags */
 -      
 -      ot->poll = ED_operator_view3d_active;
 -}
 -
  #ifdef WITH_GAMEENGINE
  
  static ListBase queue_back;
@@@ -1433,6 -1338,7 +1072,6 @@@ static void RestoreState(bContext *C, w
                win->queue = queue_back;
        
        GPU_state_init();
 -      GPU_set_tpage(NULL, 0, 0);
  
        glPopAttrib();
  }
@@@ -1475,6 -1381,10 +1114,6 @@@ static void game_set_commmandline_optio
                SYS_WriteCommandLineInt(syshandle, "blender_material", test);
                test = (gm->matmode == GAME_MAT_GLSL);
                SYS_WriteCommandLineInt(syshandle, "blender_glsl_material", test);
 -              test = (gm->flag & GAME_DISPLAY_LISTS);
 -              SYS_WriteCommandLineInt(syshandle, "displaylists", test);
 -
 -
        }
  }
  
  
  static int game_engine_poll(bContext *C)
  {
 -      bScreen *screen;
 +      const wmWindow *win = CTX_wm_window(C);
 +      const Scene *scene = WM_window_get_active_scene(win);
 +
        /* we need a context and area to launch BGE
         * it's a temporary solution to avoid crash at load time
         * if we try to auto run the BGE. Ideally we want the
         * context to be set as soon as we load the file. */
  
 -      if (CTX_wm_window(C) == NULL) return 0;
 -      if ((screen = CTX_wm_screen(C)) == NULL) return 0;
 +      if (win == NULL) return 0;
 +      if (CTX_wm_screen(C) == NULL) return 0;
  
        if (CTX_data_mode_enum(C) != CTX_MODE_OBJECT)
                return 0;
  
 -      if (!BKE_scene_uses_blender_game(screen->scene))
 +      if (!BKE_scene_uses_blender_game(scene))
                return 0;
  
        return 1;
  }
  
- bool ED_view3d_context_activate(bContext *C)
- {
-       bScreen *sc = CTX_wm_screen(C);
-       ScrArea *sa = CTX_wm_area(C);
-       ARegion *ar;
-       /* sa can be NULL when called from python */
-       if (sa == NULL || sa->spacetype != SPACE_VIEW3D) {
-               sa = BKE_screen_find_big_area(sc, SPACE_VIEW3D, 0);
-       }
-       if (sa == NULL) {
-               return false;
-       }
-       
-       ar = BKE_area_find_region_active_win(sa);
-       if (ar == NULL) {
-               return false;
-       }
-       
-       /* bad context switch .. */
-       CTX_wm_area_set(C, sa);
-       CTX_wm_region_set(C, ar);
-       return true;
- }
  static int game_engine_exec(bContext *C, wmOperator *op)
  {
  #ifdef WITH_GAMEENGINE
            (startscene->gm.framing.type == SCE_GAMEFRAMING_BARS) &&
            (startscene->gm.stereoflag != STEREO_DOME))
        {
 +              const Depsgraph *depsgraph = CTX_data_depsgraph(C);
                /* Letterbox */
                rctf cam_framef;
 -              ED_view3d_calc_camera_border(startscene, ar, CTX_wm_view3d(C), rv3d, &cam_framef, false);
 +              ED_view3d_calc_camera_border(startscene, depsgraph, ar, CTX_wm_view3d(C), rv3d, &cam_framef, false);
                cam_frame.xmin = cam_framef.xmin + ar->winrct.xmin;
                cam_frame.xmax = cam_framef.xmax + ar->winrct.xmin;
                cam_frame.ymin = cam_framef.ymin + ar->winrct.ymin;
  
        //XXX restore_all_scene_cfra(scene_cfra_store);
        BKE_scene_set_background(CTX_data_main(C), startscene);
 -      //XXX BKE_scene_update_for_newframe(bmain->eval_ctx, bmain, scene, scene->lay);
 +      //XXX BKE_scene_graph_update_for_newframe(bmain->eval_ctx, bmain, scene, depsgraph);
  
        BLI_callback_exec(bmain, &startscene->id, BLI_CB_EVT_GAME_POST);
  
@@@ -1631,157 -1511,3 +1243,3 @@@ void VIEW3D_OT_game_start(wmOperatorTyp
        
        ot->poll = game_engine_poll;
  }
- /* ************************************** */
- float ED_view3d_pixel_size(const RegionView3D *rv3d, const float co[3])
- {
-       return mul_project_m4_v3_zfac((float(*)[4])rv3d->persmat, co) * rv3d->pixsize * U.pixelsize;
- }
- float ED_view3d_radius_to_dist_persp(const float angle, const float radius)
- {
-       return radius * (1.0f / tanf(angle / 2.0f));
- }
- float ED_view3d_radius_to_dist_ortho(const float lens, const float radius)
- {
-       return radius / (DEFAULT_SENSOR_WIDTH / lens);
- }
- /**
-  * Return a new RegionView3D.dist value to fit the \a radius.
-  *
-  * \note Depth isn't taken into account, this will fit a flat plane exactly,
-  * but points towards the view (with a perspective projection),
-  * may be within the radius but outside the view. eg:
-  *
-  * <pre>
-  *           +
-  * pt --> + /^ radius
-  *         / |
-  *        /  |
-  * view  +   +
-  *        \  |
-  *         \ |
-  *          \|
-  *           +
-  * </pre>
-  *
-  * \param ar  Can be NULL if \a use_aspect is false.
-  * \param persp  Allow the caller to tell what kind of perspective to use (ortho/view/camera)
-  * \param use_aspect  Increase the distance to account for non 1:1 view aspect.
-  * \param radius  The radius will be fitted exactly, typically pre-scaled by a margin (#VIEW3D_MARGIN).
-  */
- float ED_view3d_radius_to_dist(
-         const View3D *v3d, const ARegion *ar,
-         const char persp, const bool use_aspect,
-         const float radius)
- {
-       float dist;
-       BLI_assert(ELEM(persp, RV3D_ORTHO, RV3D_PERSP, RV3D_CAMOB));
-       BLI_assert((persp != RV3D_CAMOB) || v3d->camera);
-       if (persp == RV3D_ORTHO) {
-               dist = ED_view3d_radius_to_dist_ortho(v3d->lens, radius);
-       }
-       else {
-               float lens, sensor_size, zoom;
-               float angle;
-               if (persp == RV3D_CAMOB) {
-                       CameraParams params;
-                       BKE_camera_params_init(&params);
-                       params.clipsta = v3d->near;
-                       params.clipend = v3d->far;
-                       BKE_camera_params_from_object(&params, v3d->camera);
-                       lens = params.lens;
-                       sensor_size = BKE_camera_sensor_size(params.sensor_fit, params.sensor_x, params.sensor_y);
-                       /* ignore 'rv3d->camzoom' because we want to fit to the cameras frame */
-                       zoom = CAMERA_PARAM_ZOOM_INIT_CAMOB;
-               }
-               else {
-                       lens = v3d->lens;
-                       sensor_size = DEFAULT_SENSOR_WIDTH;
-                       zoom = CAMERA_PARAM_ZOOM_INIT_PERSP;
-               }
-               angle = focallength_to_fov(lens, sensor_size);
-               /* zoom influences lens, correct this by scaling the angle as a distance (by the zoom-level) */
-               angle = atanf(tanf(angle / 2.0f) * zoom) * 2.0f;
-               dist = ED_view3d_radius_to_dist_persp(angle, radius);
-       }
-       if (use_aspect) {
-               const RegionView3D *rv3d = ar->regiondata;
-               float winx, winy;
-               if (persp == RV3D_CAMOB) {
-                       /* camera frame x/y in pixels */
-                       winx = ar->winx / rv3d->viewcamtexcofac[0];
-                       winy = ar->winy / rv3d->viewcamtexcofac[1];
-               }
-               else {
-                       winx = ar->winx;
-                       winy = ar->winy;
-               }
-               if (winx && winy) {
-                       float aspect = winx / winy;
-                       if (aspect < 1.0f) {
-                               aspect = 1.0f / aspect;
-                       }
-                       dist *= aspect;
-               }
-       }
-       return dist;
- }
- /* view matrix properties utilities */
- /* unused */
- #if 0
- void ED_view3d_operator_properties_viewmat(wmOperatorType *ot)
- {
-       PropertyRNA *prop;
-       prop = RNA_def_int(ot->srna, "region_width", 0, 0, INT_MAX, "Region Width", "", 0, INT_MAX);
-       RNA_def_property_flag(prop, PROP_HIDDEN);
-       prop = RNA_def_int(ot->srna, "region_height", 0, 0, INT_MAX, "Region height", "", 0, INT_MAX);
-       RNA_def_property_flag(prop, PROP_HIDDEN);
-       prop = RNA_def_float_matrix(ot->srna, "perspective_matrix", 4, 4, NULL, 0.0f, 0.0f, "", "Perspective Matrix", 0.0f, 0.0f);
-       RNA_def_property_flag(prop, PROP_HIDDEN);
- }
- void ED_view3d_operator_properties_viewmat_set(bContext *C, wmOperator *op)
- {
-       ARegion *ar = CTX_wm_region(C);
-       RegionView3D *rv3d = ED_view3d_context_rv3d(C);
-       if (!RNA_struct_property_is_set(op->ptr, "region_width"))
-               RNA_int_set(op->ptr, "region_width", ar->winx);
-       if (!RNA_struct_property_is_set(op->ptr, "region_height"))
-               RNA_int_set(op->ptr, "region_height", ar->winy);
-       if (!RNA_struct_property_is_set(op->ptr, "perspective_matrix"))
-               RNA_float_set_array(op->ptr, "perspective_matrix", (float *)rv3d->persmat);
- }
- void ED_view3d_operator_properties_viewmat_get(wmOperator *op, int *winx, int *winy, float persmat[4][4])
- {
-       *winx = RNA_int_get(op->ptr, "region_width");
-       *winy = RNA_int_get(op->ptr, "region_height");
-       RNA_float_get_array(op->ptr, "perspective_matrix", (float *)persmat);
- }
- #endif