diff --git a/source/blender/blenkernel/BKE_workspace.h b/source/blender/blenkernel/BKE_workspace.h
index f839d4cdf769f08e664fe89cc349610854d9a032..6ed1369c1554d931014dbdcfb2d709e72bb31f5e 100644
--- a/source/blender/blenkernel/BKE_workspace.h
+++ b/source/blender/blenkernel/BKE_workspace.h
@@ -33,6 +33,7 @@ struct Main;
 struct Scene;
 struct TransformOrientation;
 struct ViewLayer;
+struct wmWindow;
 
 /* -------------------------------------------------------------------- */
 /* Create, delete, init */
@@ -133,6 +134,9 @@ void BKE_workspace_update_object_mode(
         struct EvaluationContext *eval_ctx,
         struct WorkSpace *workspace);
 
+struct Object *BKE_workspace_edit_object(
+        struct WorkSpace *workspace, struct Scene *scene);
+
 #undef GETTER_ATTRS
 #undef SETTER_ATTRS
 
diff --git a/source/blender/blenkernel/intern/library_query.c b/source/blender/blenkernel/intern/library_query.c
index 0f83dfe7ecfc9989e5679eb89148fa191e071620..419ed8246db75ec35fa003cd73044fe8de45a079 100644
--- a/source/blender/blenkernel/intern/library_query.c
+++ b/source/blender/blenkernel/intern/library_query.c
@@ -421,10 +421,6 @@ void BKE_library_foreach_ID_link(Main *bmain, ID *id, LibraryIDLinkCallback call
 					/* nodetree **are owned by IDs**, treat them as mere sub-data and not real ID! */
 					library_foreach_ID_as_subdata_link((ID **)&scene->nodetree, callback, user_data, flag, &data);
 				}
-				/* DO NOT handle scene->basact here, it's doubling with the loop over whole scene->base later,
-				 * since basact is just a pointer to one of those items. */
-				CALLBACK_INVOKE(scene->obedit, IDWALK_CB_NOP);
-
 				if (scene->ed) {
 					Sequence *seq;
 					SEQP_BEGIN(scene->ed, seq)
diff --git a/source/blender/blenkernel/intern/object_dupli.c b/source/blender/blenkernel/intern/object_dupli.c
index f9f6b0aab40599fc724b109c7d3d667091982ac2..2d82d5a1e0a79b79d1d457f0af1ae90dd31f4426 100644
--- a/source/blender/blenkernel/intern/object_dupli.c
+++ b/source/blender/blenkernel/intern/object_dupli.c
@@ -74,6 +74,7 @@ typedef struct DupliContext {
 	bool do_update;
 	bool animated;
 	Group *group; /* XXX child objects are selected from this group if set, could be nicer */
+	Object *obedit; /* Only to check if the object is in edit-mode. */
 
 	Scene *scene;
 	ViewLayer *view_layer;
@@ -107,6 +108,7 @@ static void init_context(DupliContext *r_ctx, const EvaluationContext *eval_ctx,
 	r_ctx->animated = false;
 	r_ctx->group = NULL;
 
+	r_ctx->obedit = OBEDIT_FROM_EVAL_CTX(eval_ctx);
 	r_ctx->object = ob;
 	if (space_mat)
 		copy_m4_m4(r_ctx->space_mat, space_mat);
@@ -241,14 +243,13 @@ static bool is_child(const Object *ob, const Object *parent)
 static void make_child_duplis(const DupliContext *ctx, void *userdata, MakeChildDuplisFunc make_child_duplis_cb)
 {
 	Object *parent = ctx->object;
-	Object *obedit = ctx->scene->obedit;
 
 	if (ctx->group) {
 		int groupid = 0;
 		FOREACH_GROUP_BASE(ctx->group, base)
 		{
 			Object *ob = base->object;
-			if ((base->flag & BASE_VISIBLED) && ob != obedit && is_child(ob, parent)) {
+			if ((base->flag & BASE_VISIBLED) && ob != ctx->obedit && is_child(ob, parent)) {
 				DupliContext pctx;
 				copy_dupli_context(&pctx, ctx, ctx->object, NULL, groupid, false);
 
@@ -267,7 +268,7 @@ static void make_child_duplis(const DupliContext *ctx, void *userdata, MakeChild
 		ViewLayer *view_layer = ctx->view_layer;
 		for (Base *base = view_layer->object_bases.first; base; base = base->next, baseid++) {
 			Object *ob = base->object;
-			if (ob != obedit && is_child(ob, parent)) {
+			if (ob != ctx->obedit && is_child(ob, parent)) {
 				DupliContext pctx;
 				copy_dupli_context(&pctx, ctx, ctx->object, NULL, baseid, false);
 
diff --git a/source/blender/blenkernel/intern/object_update.c b/source/blender/blenkernel/intern/object_update.c
index bc183ba95a64424e2acd52539c4a8719858ccc46..845afb8af3c1874836f5a715baaefe7bf27d58ad 100644
--- a/source/blender/blenkernel/intern/object_update.c
+++ b/source/blender/blenkernel/intern/object_update.c
@@ -173,7 +173,7 @@ void BKE_object_handle_data_update(
 	switch (ob->type) {
 		case OB_MESH:
 		{
-			BMEditMesh *em = (ob == scene->obedit) ? BKE_editmesh_from_object(ob) : NULL;
+			BMEditMesh *em = (eval_ctx->object_mode & OB_MODE_EDIT) ? BKE_editmesh_from_object(ob) : NULL;
 			uint64_t data_mask = scene->customdata_mask | CD_MASK_BAREMESH;
 #ifdef WITH_FREESTYLE
 			/* make sure Freestyle edge/face marks appear in DM for render (see T40315) */
@@ -223,7 +223,7 @@ void BKE_object_handle_data_update(
 	}
 
 	/* particles */
-	if (ob != scene->obedit && ob->particlesystem.first) {
+	if (ob != OBEDIT_FROM_EVAL_CTX(eval_ctx) && ob->particlesystem.first) {
 		ParticleSystem *tpsys, *psys;
 		DerivedMesh *dm;
 		ob->transflag &= ~OB_DUPLIPARTS;
diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c
index a4ccf3b9bba4ffc2c888241eae20bd14761f4b7d..932f80c35d523c1858461cb32693626fb24f589f 100644
--- a/source/blender/blenkernel/intern/scene.c
+++ b/source/blender/blenkernel/intern/scene.c
@@ -166,7 +166,6 @@ void BKE_scene_copy_data(Main *bmain, Scene *sce_dst, const Scene *sce_src, cons
 
 	sce_dst->ed = NULL;
 	sce_dst->depsgraph_hash = NULL;
-	sce_dst->obedit = NULL;
 	sce_dst->fps_info = NULL;
 
 	/* layers and collections */
@@ -982,9 +981,6 @@ void BKE_scene_set_background(Main *bmain, Scene *scene)
 	/* check for cyclic sets, for reading old files but also for definite security (py?) */
 	BKE_scene_validate_setscene(bmain, scene);
 	
-	/* can happen when switching modes in other scenes */
-	scene->obedit = NULL;
-
 	/* deselect objects (for dataselect) */
 	for (ob = bmain->object.first; ob; ob = ob->id.next)
 		ob->flag &= ~(SELECT | OB_FROMGROUP);
@@ -1380,7 +1376,7 @@ static bool check_rendered_viewport_visible(Main *bmain)
 	return false;
 }
 
-static void prepare_mesh_for_viewport_render(Main *bmain, Scene *scene)
+static void prepare_mesh_for_viewport_render(Main *bmain, const EvaluationContext *eval_ctx)
 {
 	/* This is needed to prepare mesh to be used by the render
 	 * engine from the viewport rendering. We do loading here
@@ -1391,7 +1387,7 @@ static void prepare_mesh_for_viewport_render(Main *bmain, Scene *scene)
 	 * call loading of the edit data for the mesh objects.
 	 */
 
-	Object *obedit = scene->obedit;
+	Object *obedit = OBEDIT_FROM_EVAL_CTX(eval_ctx);
 	if (obedit) {
 		Mesh *mesh = obedit->data;
 		if ((obedit->type == OB_MESH) &&
@@ -1429,7 +1425,7 @@ void BKE_scene_graph_update_tagged(EvaluationContext *eval_ctx,
 	/* Uncomment this to check if graph was properly tagged for update. */
 	// DEG_debug_graph_relations_validate(depsgraph, bmain, scene);
 	/* Flush editing data if needed. */
-	prepare_mesh_for_viewport_render(bmain, scene);
+	prepare_mesh_for_viewport_render(bmain, eval_ctx);
 	/* Flush recalc flags to dependencies. */
 	DEG_graph_flush_update(bmain, depsgraph);
 	/* Update all objects: drivers, matrices, displists, etc. flags set
diff --git a/source/blender/blenkernel/intern/workspace.c b/source/blender/blenkernel/intern/workspace.c
index dcd4183210d58cb58e1dcac7aee589d3c9fbb877..bc5731b957425c85978e4961f900f811f85c30f7 100644
--- a/source/blender/blenkernel/intern/workspace.c
+++ b/source/blender/blenkernel/intern/workspace.c
@@ -38,6 +38,7 @@
 #include "BKE_main.h"
 #include "BKE_scene.h"
 #include "BKE_screen.h"
+#include "BKE_object.h"
 #include "BKE_workspace.h"
 
 #include "DNA_object_types.h"
@@ -517,4 +518,20 @@ void BKE_workspace_update_object_mode(
 	 * for now without this 'bmain->eval_ctx' is never set. */
 
 	eval_ctx->object_mode = workspace->object_mode;
-}
\ No newline at end of file
+}
+
+Object *BKE_workspace_edit_object(WorkSpace *workspace, Scene *scene)
+{
+	if (workspace->object_mode & OB_MODE_EDIT) {
+		ViewLayer *view_layer = BKE_workspace_view_layer_get(workspace, scene);
+		if (view_layer) {
+			Object *obedit = OBACT(view_layer);
+			if (obedit) {
+				BLI_assert(BKE_object_is_in_editmode(obedit));
+				return obedit;
+			}
+		}
+	}
+	return NULL;
+}
+
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index a91aeee52dfbb35b5b31b0ca76fb50fe12d5820b..a5370313a93558264efcd47cf2487731980de7ea 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -6216,7 +6216,6 @@ static void direct_link_scene(FileData *fd, Scene *sce, Main *bmain)
 	SceneRenderLayer *srl;
 	
 	sce->depsgraph_hash = NULL;
-	sce->obedit = NULL;
 	sce->fps_info = NULL;
 	sce->customdata_mask_modal = 0;
 	sce->lay_updated = 0;
diff --git a/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc b/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc
index 5daf462970854c7582f41d45bc1eb2e3994e134b..8bdc68d935191bbc78388eb9342a0996aebc3a68 100644
--- a/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc
+++ b/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc
@@ -461,18 +461,6 @@ void update_special_pointers(const Depsgraph *depsgraph,
 			}
 			break;
 		}
-		case ID_SCE:
-		{
-			const Scene *scene_orig = (const Scene *)id_orig;
-			Scene *scene_cow = (Scene *)id_cow;
-			if (scene_orig->obedit != NULL) {
-				scene_cow->obedit = (Object *)depsgraph->get_cow_id(&scene_orig->obedit->id);
-			}
-			else {
-				scene_cow->obedit = NULL;
-			}
-			break;
-		}
 		default:
 			break;
 	}
@@ -622,13 +610,6 @@ void update_copy_on_write_scene(const Depsgraph *depsgraph,
 	update_copy_on_write_view_layers(depsgraph, scene_cow, scene_orig);
 	update_copy_on_write_scene_collection(scene_cow->collection,
 	                                      scene_orig->collection);
-	// Update edit object pointer.
-	if (scene_orig->obedit != NULL) {
-		scene_cow->obedit = (Object *)depsgraph->get_cow_id(&scene_orig->obedit->id);
-	}
-	else {
-		scene_cow->obedit = NULL;
-	}
 	/* Synchronize active render engine. */
 	BLI_strncpy(scene_cow->view_render.engine_id,
 	            scene_orig->view_render.engine_id,
diff --git a/source/blender/draw/engines/clay/clay_engine.c b/source/blender/draw/engines/clay/clay_engine.c
index 50c6790f817e9a743a6596457c64c15b4f40c754..4b554f776a626b717e238de28068bb64ecd83e54 100644
--- a/source/blender/draw/engines/clay/clay_engine.c
+++ b/source/blender/draw/engines/clay/clay_engine.c
@@ -770,11 +770,7 @@ static void clay_cache_populate_particles(void *vedata, Object *ob)
 	CLAY_StorageList *stl = ((CLAY_Data *)vedata)->stl;
 	const DRWContextState *draw_ctx = DRW_context_state_get();
 
-
-	Scene *scene = draw_ctx->scene;
-	Object *obedit = scene->obedit;
-
-	if (ob != obedit) {
+	if (ob != draw_ctx->object_edit) {
 		for (ParticleSystem *psys = ob->particlesystem.first; psys; psys = psys->next) {
 			if (psys_check_enabled(ob, psys, false)) {
 				ParticleSettings *part = psys->part;
diff --git a/source/blender/draw/engines/eevee/eevee_materials.c b/source/blender/draw/engines/eevee/eevee_materials.c
index 9754bfbd78bf691388e8037623a3098cc85f3bda..71564be496aa90176d678900428384e57da66890 100644
--- a/source/blender/draw/engines/eevee/eevee_materials.c
+++ b/source/blender/draw/engines/eevee/eevee_materials.c
@@ -1377,7 +1377,7 @@ void EEVEE_materials_cache_populate(EEVEE_Data *vedata, EEVEE_ViewLayerData *sld
 	}
 
 	if (ob->type == OB_MESH) {
-		if (ob != draw_ctx->scene->obedit) {
+		if (ob != draw_ctx->object_edit) {
 			material_hash = stl->g_data->hair_material_hash;
 
 			for (ModifierData *md = ob->modifiers.first; md; md = md->next) {
diff --git a/source/blender/draw/intern/DRW_render.h b/source/blender/draw/intern/DRW_render.h
index 8eb10ed5a1471fc479a4bb91cae215fcc4bc7c28..6343fbf4b807c39dcbb5e167bcdf784474fce0c0 100644
--- a/source/blender/draw/intern/DRW_render.h
+++ b/source/blender/draw/intern/DRW_render.h
@@ -477,6 +477,7 @@ typedef struct DRWContextState {
 	const struct bContext *evil_C;
 
 	struct Object *object_pose;
+	struct Object *object_edit;
 
 } DRWContextState;
 
diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c
index 45ad9853d20838fb7314e0be1b4c0a43a263e3ce..115b387905943ae1364e36e83147e8c424c6527c 100644
--- a/source/blender/draw/intern/draw_manager.c
+++ b/source/blender/draw/intern/draw_manager.c
@@ -2210,13 +2210,10 @@ struct DRWTextStore *DRW_text_cache_ensure(void)
 
 bool DRW_object_is_renderable(Object *ob)
 {
-	Scene *scene = DST.draw_ctx.scene;
-	Object *obedit = scene->obedit;
-
 	BLI_assert(BKE_object_is_visible(ob, OB_VISIBILITY_CHECK_UNKNOWN_RENDER_MODE));
 
 	if (ob->type == OB_MESH) {
-		if (ob == obedit) {
+		if (ob == DST.draw_ctx.object_edit) {
 			IDProperty *props = BKE_layer_collection_engine_evaluated_get(ob, COLLECTION_MODE_EDIT, "");
 			bool do_show_occlude_wire = BKE_collection_engine_property_value_get_bool(props, "show_occlude_wire");
 			if (do_show_occlude_wire) {
@@ -2609,6 +2606,28 @@ static void drw_viewport_var_init(void)
 {
 	RegionView3D *rv3d = DST.draw_ctx.rv3d;
 
+	/* Not a viewport variable, we could split this out. */
+	{
+		/* Edit object. */
+		if (DST.draw_ctx.object_mode & OB_MODE_EDIT) {
+			DST.draw_ctx.object_edit = DST.draw_ctx.obact;
+		}
+		else {
+			DST.draw_ctx.object_edit = NULL;
+		}
+
+		/* Pose object. */
+		if (DST.draw_ctx.object_mode & OB_MODE_POSE) {
+			DST.draw_ctx.object_pose = DST.draw_ctx.obact;
+		}
+		else if (DST.draw_ctx.object_mode & OB_MODE_WEIGHT_PAINT) {
+			DST.draw_ctx.object_pose = BKE_object_pose_armature_get(DST.draw_ctx.obact);
+		}
+		else {
+			DST.draw_ctx.object_pose = NULL;
+		}
+	}
+
 	/* Refresh DST.size */
 	if (DST.viewport) {
 		int size[2];
@@ -2664,8 +2683,8 @@ static void drw_viewport_var_init(void)
 	DST.backface = GL_CW;
 	glFrontFace(DST.frontface);
 
-	if (DST.draw_ctx.scene->obedit) {
-		ED_view3d_init_mats_rv3d(DST.draw_ctx.scene->obedit, rv3d);
+	if (DST.draw_ctx.object_edit) {
+		ED_view3d_init_mats_rv3d(DST.draw_ctx.object_edit, rv3d);
 	}
 
 	/* Alloc array of texture reference. */
@@ -2678,19 +2697,6 @@ static void drw_viewport_var_init(void)
 
 	memset(viewport_matrix_override.override, 0x0, sizeof(viewport_matrix_override.override));
 	memset(DST.common_instance_data, 0x0, sizeof(DST.common_instance_data));
-
-	/* Not a viewport variable, we could split this out. */
-	{
-		if (DST.draw_ctx.object_mode & OB_MODE_POSE) {
-			DST.draw_ctx.object_pose = DST.draw_ctx.obact;
-		}
-		else if (DST.draw_ctx.object_mode & OB_MODE_WEIGHT_PAINT) {
-			DST.draw_ctx.object_pose = BKE_object_pose_armature_get(DST.draw_ctx.obact);
-		}
-		else {
-			DST.draw_ctx.object_pose = NULL;
-		}
-	}
 }
 
 void DRW_viewport_matrix_get(float mat[4][4], DRWViewportMatrixType type)
@@ -3185,10 +3191,10 @@ static void drw_engines_enable_external(void)
 	use_drw_engine(DRW_engine_viewport_external_type.draw_engine);
 }
 
-static void drw_engines_enable(const Scene *scene, ViewLayer *view_layer, RenderEngineType *engine_type)
+static void drw_engines_enable(ViewLayer *view_layer, RenderEngineType *engine_type)
 {
 	Object *obact = OBACT(view_layer);
-	const int mode = CTX_data_mode_enum_ex(scene->obedit, obact, DST.draw_ctx.object_mode);
+	const int mode = CTX_data_mode_enum_ex(DST.draw_ctx.object_edit, obact, DST.draw_ctx.object_mode);
 
 	drw_engines_enable_from_engine(engine_type);
 
@@ -3366,7 +3372,7 @@ void DRW_notify_view_update(const DRWUpdateContext *update_ctx)
 		NULL,
 	};
 
-	drw_engines_enable(scene, view_layer, engine_type);
+	drw_engines_enable(view_layer, engine_type);
 
 	for (LinkData *link = DST.enabled_engines.first; link; link = link->next) {
 		DrawEngineType *draw_engine = link->data;
@@ -3411,7 +3417,7 @@ void DRW_notify_id_update(const DRWUpdateContext *update_ctx, ID *id)
 	DST.draw_ctx = (DRWContextState){
 		ar, rv3d, v3d, scene, view_layer, OBACT(view_layer), engine_type, depsgraph, OB_MODE_OBJECT, NULL,
 	};
-	drw_engines_enable(scene, view_layer, engine_type);
+	drw_engines_enable(view_layer, engine_type);
 	for (LinkData *link = DST.enabled_engines.first; link; link = link->next) {
 		DrawEngineType *draw_engine = link->data;
 		ViewportEngineData *data = DRW_viewport_engine_data_ensure(draw_engine);
@@ -3478,7 +3484,7 @@ void DRW_draw_render_loop_ex(
 	drw_viewport_var_init();
 
 	/* Get list of enabled engines */
-	drw_engines_enable(scene, view_layer, engine_type);
+	drw_engines_enable(view_layer, engine_type);
 
 	/* Update ubos */
 	DRW_globals_update();
@@ -3723,6 +3729,7 @@ void DRW_draw_select_loop(
 	Scene *scene = DEG_get_evaluated_scene(depsgraph);
 	RenderEngineType *engine_type = RE_engines_find(scene->view_render.engine_id);
 	ViewLayer *view_layer = DEG_get_evaluated_view_layer(depsgraph);
+	Object *obact = OBACT(view_layer);
 #ifndef USE_GPU_SELECT
 	UNUSED_VARS(vc, scene, view_layer, v3d, ar, rect);
 #else
@@ -3737,14 +3744,12 @@ void DRW_draw_select_loop(
 
 	bool use_obedit = false;
 	int obedit_mode = 0;
-	if (scene->obedit && scene->obedit->type == OB_MBALL) {
-		use_obedit = true;
-		obedit_mode = CTX_MODE_EDIT_METABALL;
-	}
-	else if ((scene->obedit && scene->obedit->type == OB_ARMATURE)) {
-		/* if not drawing sketch, draw bones */
-		// if (!BDR_drawSketchNames(vc))
-		{
+	if (object_mode & OB_MODE_EDIT) {
+		if (obact->type == OB_MBALL) {
+			use_obedit = true;
+			obedit_mode = CTX_MODE_EDIT_METABALL;
+		}
+		else if (obact->type == OB_ARMATURE) {
 			use_obedit = true;
 			obedit_mode = CTX_MODE_EDIT_ARMATURE;
 		}
@@ -3773,7 +3778,7 @@ void DRW_draw_select_loop(
 
 	/* Instead of 'DRW_context_state_init(C, &DST.draw_ctx)', assign from args */
 	DST.draw_ctx = (DRWContextState){
-		ar, rv3d, v3d, scene, view_layer, OBACT(view_layer), engine_type, depsgraph, object_mode,
+		ar, rv3d, v3d, scene, view_layer, obact, engine_type, depsgraph, object_mode,
 		(bContext *)NULL,
 	};
 
@@ -3792,7 +3797,7 @@ void DRW_draw_select_loop(
 		drw_engines_cache_init();
 
 		if (use_obedit) {
-			drw_engines_cache_populate(scene->obedit);
+			drw_engines_cache_populate(obact);
 		}
 		else {
 			DEG_OBJECT_ITER(depsgraph, ob, DRW_iterator_mode_get(),
diff --git a/source/blender/draw/modes/edit_curve_mode.c b/source/blender/draw/modes/edit_curve_mode.c
index 54a1bd79572c4a19cb0d79f142720c426e82051c..73a4fb1e9e6d14595f1e8eba6b60216ba23ca7cc 100644
--- a/source/blender/draw/modes/edit_curve_mode.c
+++ b/source/blender/draw/modes/edit_curve_mode.c
@@ -229,12 +229,11 @@ static void EDIT_CURVE_cache_populate(void *vedata, Object *ob)
 	EDIT_CURVE_StorageList *stl = ((EDIT_CURVE_Data *)vedata)->stl;
 	const DRWContextState *draw_ctx = DRW_context_state_get();
 	const Scene *scene = draw_ctx->scene;
-	const Object *obedit = scene->obedit;
 
 	UNUSED_VARS(psl, stl);
 
 	if (ob->type == OB_CURVE) {
-		if (ob == obedit) {
+		if (ob == draw_ctx->object_edit) {
 			Curve *cu = ob->data;
 			/* Get geometry cache */
 			struct Gwn_Batch *geom;
diff --git a/source/blender/draw/modes/edit_lattice_mode.c b/source/blender/draw/modes/edit_lattice_mode.c
index e676677ff97917d0328a431c9e0d4222048bd7fd..0268f4eb45363480a03039111cce9f884adcfd21 100644
--- a/source/blender/draw/modes/edit_lattice_mode.c
+++ b/source/blender/draw/modes/edit_lattice_mode.c
@@ -188,13 +188,11 @@ static void EDIT_LATTICE_cache_populate(void *vedata, Object *ob)
 	EDIT_LATTICE_PassList *psl = ((EDIT_LATTICE_Data *)vedata)->psl;
 	EDIT_LATTICE_StorageList *stl = ((EDIT_LATTICE_Data *)vedata)->stl;
 	const DRWContextState *draw_ctx = DRW_context_state_get();
-	Scene *scene = draw_ctx->scene;
-	Object *obedit = scene->obedit;
 
 	UNUSED_VARS(psl);
 
 	if (ob->type == OB_LATTICE) {
-		if (ob == obedit) {
+		if (ob == draw_ctx->object_edit) {
 			/* Get geometry cache */
 			struct Gwn_Batch *geom;
 
diff --git a/source/blender/draw/modes/edit_mesh_mode.c b/source/blender/draw/modes/edit_mesh_mode.c
index 29ba658f79d3caa0204cf4446f77bfc77448cfb3..cc1373dc29fcf925b9865dbf5f47403002d19775 100644
--- a/source/blender/draw/modes/edit_mesh_mode.c
+++ b/source/blender/draw/modes/edit_mesh_mode.c
@@ -443,11 +443,10 @@ static void EDIT_MESH_cache_populate(void *vedata, Object *ob)
 	const DRWContextState *draw_ctx = DRW_context_state_get();
 	View3D *v3d = draw_ctx->v3d;
 	Scene *scene = draw_ctx->scene;
-	Object *obedit = scene->obedit;
 	struct Gwn_Batch *geom;
 
 	if (ob->type == OB_MESH) {
-		if (ob == obedit) {
+		if (ob == draw_ctx->object_edit) {
 			const Mesh *me = ob->data;
 			IDProperty *ces_mode_ed = BKE_layer_collection_engine_evaluated_get(ob, COLLECTION_MODE_EDIT, "");
 			bool do_occlude_wire = BKE_collection_engine_property_value_get_bool(ces_mode_ed, "show_occlude_wire");
diff --git a/source/blender/draw/modes/edit_metaball_mode.c b/source/blender/draw/modes/edit_metaball_mode.c
index 78ceaf8b6f1079059bc9426a856cb94045d915c8..b759dce5931fdb8065c267baf2b5d8e4bec0e17c 100644
--- a/source/blender/draw/modes/edit_metaball_mode.c
+++ b/source/blender/draw/modes/edit_metaball_mode.c
@@ -169,11 +169,9 @@ static void EDIT_METABALL_cache_populate(void *vedata, Object *ob)
 
 	if (ob->type == OB_MBALL) {
 		const DRWContextState *draw_ctx = DRW_context_state_get();
-		Scene *scene = draw_ctx->scene;
-		Object *obedit = scene->obedit;
 		DRWShadingGroup *group = stl->g_data->group;
 
-		if (ob == obedit) {
+		if (ob == draw_ctx->object_edit) {
 			MetaBall *mb = ob->data;
 
 			const bool is_select = DRW_state_is_select();
diff --git a/source/blender/draw/modes/edit_text_mode.c b/source/blender/draw/modes/edit_text_mode.c
index 60f28d89f4bfc0a51c8ae2af948eda47a171bd5a..43c4a356279975d60c28d91de7ee0a270efa5b57 100644
--- a/source/blender/draw/modes/edit_text_mode.c
+++ b/source/blender/draw/modes/edit_text_mode.c
@@ -190,13 +190,11 @@ static void EDIT_TEXT_cache_populate(void *vedata, Object *ob)
 	EDIT_TEXT_PassList *psl = ((EDIT_TEXT_Data *)vedata)->psl;
 	EDIT_TEXT_StorageList *stl = ((EDIT_TEXT_Data *)vedata)->stl;
 	const DRWContextState *draw_ctx = DRW_context_state_get();
-	Scene *scene = draw_ctx->scene;
-	Object *obedit = scene->obedit;
 
 	UNUSED_VARS(psl, stl);
 
 	if (ob->type == OB_FONT) {
-		if (ob == obedit) {
+		if (ob == draw_ctx->object_edit) {
 			const Curve *cu = ob->data;
 			/* Get geometry cache */
 			struct Gwn_Batch *geom;
diff --git a/source/blender/draw/modes/object_mode.c b/source/blender/draw/modes/object_mode.c
index e807be34633789531bfd36d26ffbb5fe187c2726..7ed81366341c15b93b1dc99d8f94c4ce95df90e2 100644
--- a/source/blender/draw/modes/object_mode.c
+++ b/source/blender/draw/modes/object_mode.c
@@ -1790,7 +1790,6 @@ static void OBJECT_cache_populate(void *vedata, Object *ob)
 	OBJECT_PassList *psl = ((OBJECT_Data *)vedata)->psl;
 	OBJECT_StorageList *stl = ((OBJECT_Data *)vedata)->stl;
 	const DRWContextState *draw_ctx = DRW_context_state_get();
-	Scene *scene = draw_ctx->scene;
 	ViewLayer *view_layer = draw_ctx->view_layer;
 	View3D *v3d = draw_ctx->v3d;
 	int theme_id = TH_UNDEFINED;
@@ -1810,8 +1809,7 @@ static void OBJECT_cache_populate(void *vedata, Object *ob)
 	bool do_outlines = ((ob->base_flag & BASE_SELECTED) != 0);
 
 	if (do_outlines) {
-		Object *obedit = scene->obedit;
-		if (ob != obedit && !((ob == draw_ctx->obact) && (draw_ctx->object_mode & OB_MODE_ALL_PAINT))) {
+		if ((ob != draw_ctx->object_edit) && !((ob == draw_ctx->obact) && (draw_ctx->object_mode & OB_MODE_ALL_PAINT))) {
 			struct Gwn_Batch *geom = DRW_cache_object_surface_get(ob);
 			if (geom) {
 				theme_id = DRW_object_wire_theme_get(ob, view_layer, NULL);
@@ -1828,8 +1826,7 @@ static void OBJECT_cache_populate(void *vedata, Object *ob)
 		{
 			Mesh *me = ob->data;
 			if (me->totpoly == 0) {
-				Object *obedit = scene->obedit;
-				if (ob != obedit) {
+				if (ob != draw_ctx->object_edit) {
 					struct Gwn_Batch *geom = DRW_cache_mesh_edges_get(ob);
 					if (geom) {
 						if (theme_id == TH_UNDEFINED) {
@@ -1847,8 +1844,7 @@ static void OBJECT_cache_populate(void *vedata, Object *ob)
 			break;
 		case OB_LATTICE:
 		{
-			Object *obedit = scene->obedit;
-			if (ob != obedit) {
+			if (ob != draw_ctx->object_edit) {
 				struct Gwn_Batch *geom = DRW_cache_lattice_wire_get(ob, false);
 				if (theme_id == TH_UNDEFINED) {
 					theme_id = DRW_object_wire_theme_get(ob, view_layer, NULL);
@@ -1862,8 +1858,7 @@ static void OBJECT_cache_populate(void *vedata, Object *ob)
 
 		case OB_CURVE:
 		{
-			Object *obedit = scene->obedit;
-			if (ob != obedit) {
+			if (ob != draw_ctx->object_edit) {
 				struct Gwn_Batch *geom = DRW_cache_curve_edge_wire_get(ob);
 				if (theme_id == TH_UNDEFINED) {
 					theme_id = DRW_object_wire_theme_get(ob, view_layer, NULL);
@@ -1875,8 +1870,7 @@ static void OBJECT_cache_populate(void *vedata, Object *ob)
 		}
 		case OB_MBALL:
 		{
-			Object *obedit = scene->obedit;
-			if (ob != obedit) {
+			if (ob != draw_ctx->object_edit) {
 				DRW_shgroup_mball_helpers(stl, ob, view_layer);
 			}
 			break;
diff --git a/source/blender/editors/animation/anim_channels_edit.c b/source/blender/editors/animation/anim_channels_edit.c
index 5d5990b9a0a2b39dc1461855bb5240c0e8be4970..d137e5f1c74c4b5496aab4b68921bbf5ce4512fe 100644
--- a/source/blender/editors/animation/anim_channels_edit.c
+++ b/source/blender/editors/animation/anim_channels_edit.c
@@ -2683,8 +2683,10 @@ static int mouse_anim_channels(bContext *C, bAnimContext *ac, int channel_index,
 		}
 		case ANIMTYPE_OBJECT:
 		{
+#if 0
 			bDopeSheet *ads = (bDopeSheet *)ac->data;
 			Scene *sce = (Scene *)ads->source;
+#endif
 			ViewLayer *view_layer = ac->view_layer;
 			Base *base = (Base *)ale->data;
 			Object *ob = base->object;
@@ -2723,7 +2725,7 @@ static int mouse_anim_channels(bContext *C, bAnimContext *ac, int channel_index,
 					adt->flag |= ADT_UI_ACTIVE;
 
 				/* ensure we exit editmode on whatever object was active before to avoid getting stuck there - T48747 */
-				if (ob != sce->obedit)
+				if (ob != CTX_data_edit_object(C))
 					ED_object_editmode_exit(C, EM_FREEDATA | EM_FREEUNDO | EM_WAITCURSOR | EM_DO_UNDO);
 
 				notifierFlags |= (ND_ANIMCHAN | NA_SELECTED);
diff --git a/source/blender/editors/armature/armature_edit.c b/source/blender/editors/armature/armature_edit.c
index a2fbfe645f7de651be000fb2ac2b3e994a989cf5..35fec98fee7aa18eece56c97b6682bd770ee3c95 100644
--- a/source/blender/editors/armature/armature_edit.c
+++ b/source/blender/editors/armature/armature_edit.c
@@ -50,6 +50,7 @@
 #include "BKE_context.h"
 #include "BKE_global.h"
 #include "BKE_report.h"
+#include "BKE_object.h"
 
 #include "RNA_access.h"
 #include "RNA_define.h"
@@ -138,17 +139,16 @@ void ED_armature_transform(struct bArmature *arm, float mat[4][4], const bool do
 
 /* exported for use in editors/object/ */
 /* 0 == do center, 1 == center new, 2 == center cursor */
-void ED_armature_origin_set(Scene *scene, Object *ob, float cursor[3], int centermode, int around)
+void ED_armature_origin_set(Object *ob, float cursor[3], int centermode, int around)
 {
-	Object *obedit = scene->obedit; // XXX get from context
+	const bool is_editmode = BKE_object_is_in_editmode(ob);
 	EditBone *ebone;
 	bArmature *arm = ob->data;
 	float cent[3];
 
 	/* Put the armature into editmode */
-	if (ob != obedit) {
+	if (is_editmode == false) {
 		ED_armature_to_edit(arm);
-		obedit = NULL; /* we cant use this so behave as if there is no obedit */
 	}
 
 	/* Find the centerpoint */
@@ -188,13 +188,13 @@ void ED_armature_origin_set(Scene *scene, Object *ob, float cursor[3], int cente
 	}
 	
 	/* Turn the list into an armature */
-	if (obedit == NULL) {
+	if (is_editmode == false) {
 		ED_armature_from_edit(arm);
 		ED_armature_edit_free(arm);
 	}
 
 	/* Adjust object location for new centerpoint */
-	if (centermode && obedit == NULL) {
+	if (centermode && is_editmode) {
 		mul_mat3_m4_v3(ob->obmat, cent); /* omit translation part */
 		add_v3_v3(ob->loc, cent);
 	}
diff --git a/source/blender/editors/armature/armature_intern.h b/source/blender/editors/armature/armature_intern.h
index 192bb8eea61a0ce8b59ac7331ff7398dcc875531..0ba720a17d002f27c65d7f4794ec4b13e044689d 100644
--- a/source/blender/editors/armature/armature_intern.h
+++ b/source/blender/editors/armature/armature_intern.h
@@ -250,7 +250,7 @@ void armature_tag_unselect(struct bArmature *arm);
 
 void *get_nearest_bone(struct bContext *C, const int xy[2], bool findunsel);
 void *get_bone_from_selectbuffer(
-        struct Scene *scene, struct Base *base, const unsigned int *buffer, short hits,
+        struct Base *base, struct Object *obedit, const unsigned int *buffer, short hits,
         bool findunsel, bool do_nearest);
 
 int bone_looper(struct Object *ob, struct Bone *bone, void *data,
diff --git a/source/blender/editors/armature/armature_select.c b/source/blender/editors/armature/armature_select.c
index b87942fed8471d03917d6beb1c1821a5ea4afb52..f178ad640b63fb8c5b00b43eb9778a1b8a84d7e1 100644
--- a/source/blender/editors/armature/armature_select.c
+++ b/source/blender/editors/armature/armature_select.c
@@ -77,10 +77,9 @@ Bone *get_indexed_bone(Object *ob, int index)
 /* See if there are any selected bones in this buffer */
 /* only bones from base are checked on */
 void *get_bone_from_selectbuffer(
-        Scene *scene, Base *base, const unsigned int *buffer, short hits,
+        Base *base, Object *obedit, const unsigned int *buffer, short hits,
         bool findunsel, bool do_nearest)
 {
-	Object *obedit = scene->obedit; // XXX get from context
 	Bone *bone;
 	EditBone *ebone;
 	void *firstunSel = NULL, *firstSel = NULL, *data;
@@ -183,9 +182,9 @@ void *get_nearest_bone(bContext *C, const int xy[2], bool findunsel)
 	
 	hits = view3d_opengl_select(&eval_ctx, &vc, buffer, MAXPICKBUF, &rect, VIEW3D_SELECT_PICK_NEAREST);
 
-	if (hits > 0)
-		return get_bone_from_selectbuffer(vc.scene, vc.view_layer->basact, buffer, hits, findunsel, true);
-	
+	if (hits > 0) {
+		return get_bone_from_selectbuffer(vc.view_layer->basact, vc.obedit, buffer, hits, findunsel, true);
+	}
 	return NULL;
 }
 
diff --git a/source/blender/editors/armature/pose_select.c b/source/blender/editors/armature/pose_select.c
index a43f3ff4acc96360a744d37829de4650d5c02bee..d0a4cbde1a0445cb8d96af11c369ae9a37136171 100644
--- a/source/blender/editors/armature/pose_select.c
+++ b/source/blender/editors/armature/pose_select.c
@@ -135,7 +135,7 @@ void ED_pose_bone_select(Object *ob, bPoseChannel *pchan, bool select)
 /* assumes scene obact and basact is still on old situation */
 bool ED_do_pose_selectbuffer(
         const EvaluationContext *eval_ctx,
-        Scene *scene, ViewLayer *view_layer, Base *base, const unsigned int *buffer, short hits,
+        ViewLayer *view_layer, Base *base, const unsigned int *buffer, short hits,
         bool extend, bool deselect, bool toggle, bool do_nearest)
 {
 	Object *ob = base->object;
@@ -143,11 +143,13 @@ bool ED_do_pose_selectbuffer(
 	
 	if (!ob || !ob->pose) return 0;
 
-	nearBone = get_bone_from_selectbuffer(scene, base, buffer, hits, 1, do_nearest);
+	Object *ob_act = OBACT(view_layer);
+	Object *obedit = (eval_ctx->object_mode & OB_MODE_EDIT) ? ob_act : NULL;
+
+	nearBone = get_bone_from_selectbuffer(base, obedit, buffer, hits, 1, do_nearest);
 	
 	/* if the bone cannot be affected, don't do anything */
 	if ((nearBone) && !(nearBone->flag & BONE_UNSELECTABLE)) {
-		Object *ob_act = OBACT(view_layer);
 		bArmature *arm = ob->data;
 		
 		/* since we do unified select, we don't shift+select a bone if the
diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c
index 4b578ba389ebc1f1f387cd5fc06f94ed368e2d59..c3e92589791c0dadeb1ea8e767f169823f43a405 100644
--- a/source/blender/editors/curve/editcurve.c
+++ b/source/blender/editors/curve/editcurve.c
@@ -5027,7 +5027,7 @@ static int add_vertex_invoke(bContext *C, wmOperator *op, const wmEvent *event)
 			        snap_context,
 			        SCE_SELECT_FACE,
 			        &(const struct SnapObjectParams){
-			            .snap_select = (vc.scene->obedit != NULL) ? SNAP_NOT_ACTIVE : SNAP_ALL,
+			            .snap_select = (vc.obedit != NULL) ? SNAP_NOT_ACTIVE : SNAP_ALL,
 			            .use_object_edit_cage = false,
 			        },
 			        mval, NULL, true,
diff --git a/source/blender/editors/curve/editcurve_paint.c b/source/blender/editors/curve/editcurve_paint.c
index 062b9c94a1bb866a1efd5f4ba535e4accb15e5a5..0d2514ec27e6abf8813f28fb37ca8b2c32a4ed74 100644
--- a/source/blender/editors/curve/editcurve_paint.c
+++ b/source/blender/editors/curve/editcurve_paint.c
@@ -788,7 +788,7 @@ static int curve_draw_exec(bContext *C, wmOperator *op)
 	struct CurveDrawData *cdd = op->customdata;
 
 	const CurvePaintSettings *cps = &cdd->vc.scene->toolsettings->curve_paint_settings;
-	Object *obedit = cdd->vc.scene->obedit;
+	Object *obedit = cdd->vc.obedit;
 	Curve *cu = obedit->data;
 	ListBase *nurblist = object_editcurve_get(obedit);
 
diff --git a/source/blender/editors/gpencil/gpencil_convert.c b/source/blender/editors/gpencil/gpencil_convert.c
index d2ae8bc3ce7011d13d67e087a6938a75c49d2a03..8d45c6af686425e6ab51f417a784ee373ebd3c64 100644
--- a/source/blender/editors/gpencil/gpencil_convert.c
+++ b/source/blender/editors/gpencil/gpencil_convert.c
@@ -55,6 +55,7 @@
 #include "DNA_space_types.h"
 #include "DNA_view3d_types.h"
 #include "DNA_gpencil_types.h"
+#include "DNA_workspace_types.h"
 
 #include "BKE_collection.h"
 #include "BKE_context.h"
@@ -1293,6 +1294,7 @@ static int gp_convert_poll(bContext *C)
 	bGPDframe *gpf = NULL;
 	ScrArea *sa = CTX_wm_area(C);
 	Scene *scene = CTX_data_scene(C);
+	const WorkSpace *workspace = CTX_wm_workspace(C);
 	
 	/* only if the current view is 3D View, if there's valid data (i.e. at least one stroke!),
 	 * and if we are not in edit mode!
@@ -1301,7 +1303,7 @@ static int gp_convert_poll(bContext *C)
 	        (gpl = BKE_gpencil_layer_getactive(gpd)) &&
 	        (gpf = BKE_gpencil_layer_getframe(gpl, CFRA, 0)) &&
 	        (gpf->strokes.first) &&
-	        (scene->obedit == NULL));
+	        ((workspace->object_mode & OB_MODE_EDIT) == 0));
 }
 
 static int gp_convert_layer_exec(bContext *C, wmOperator *op)
diff --git a/source/blender/editors/include/ED_armature.h b/source/blender/editors/include/ED_armature.h
index 5ad242003e39c142a5d110d8b58cf499059a1ade..18eb442766b5181bdd81904475177d1a6ee2d782 100644
--- a/source/blender/editors/include/ED_armature.h
+++ b/source/blender/editors/include/ED_armature.h
@@ -144,7 +144,7 @@ void ED_armature_deselect_all_visible(struct Object *obedit);
 
 bool ED_do_pose_selectbuffer(
         const struct EvaluationContext *eval_ctx,
-        struct Scene *scene, struct ViewLayer *view_layer, struct Base *base, const unsigned int *buffer, short hits,
+        struct ViewLayer *view_layer, struct Base *base, const unsigned int *buffer, short hits,
         bool extend, bool deselect, bool toggle, bool do_nearest);
 bool ED_armature_select_pick(struct bContext *C, const int mval[2], bool extend, bool deselect, bool toggle);
 int join_armature_exec(struct bContext *C, struct wmOperator *op);
@@ -169,7 +169,7 @@ void ED_armature_ebone_from_mat3(EditBone *ebone, float mat[3][3]);
 void ED_armature_ebone_from_mat4(EditBone *ebone, float mat[4][4]);
 
 void transform_armature_mirror_update(struct Object *obedit);
-void ED_armature_origin_set(struct Scene *scene, struct Object *ob, float cursor[3], int centermode, int around);
+void ED_armature_origin_set(struct Object *ob, float cursor[3], int centermode, int around);
 
 void ED_armature_transform_bones(struct bArmature *arm, float mat[4][4], const bool do_props);
 void ED_armature_apply_transform(struct Object *ob, float mat[4][4], const bool do_props);
diff --git a/source/blender/editors/include/ED_screen.h b/source/blender/editors/include/ED_screen.h
index 18480d01ed7d93d8d43fe443f5e8f2703cf0d6dd..7c234a01e86a7c98444f29d1004ba4257af284ce 100644
--- a/source/blender/editors/include/ED_screen.h
+++ b/source/blender/editors/include/ED_screen.h
@@ -147,7 +147,9 @@ struct ScrArea *ED_screen_state_toggle(struct bContext *C, struct wmWindow *win,
 void    ED_screens_header_tools_menu_create(struct bContext *C, struct uiLayout *layout, void *arg);
 bool    ED_screen_stereo3d_required(const struct bScreen *screen, const struct Scene *scene);
 Scene   *ED_screen_scene_find(const struct bScreen *screen, const struct wmWindowManager *wm);
+
 Scene   *ED_screen_scene_find_with_window(const struct bScreen *screen, const struct wmWindowManager *wm, struct wmWindow **r_window);
+struct wmWindow *ED_screen_window_find(const struct bScreen *screen, const struct wmWindowManager *wm);
 void    ED_screen_preview_render(const struct bScreen *screen, int size_x, int size_y, unsigned int *r_rect) ATTR_NONNULL();
 
 /* workspaces */
diff --git a/source/blender/editors/include/ED_uvedit.h b/source/blender/editors/include/ED_uvedit.h
index d4c386883356ba766cd8176db2c0b6c198cfb71c..e25c34ddb78270f66ce3cfd8ee2046d10493e429 100644
--- a/source/blender/editors/include/ED_uvedit.h
+++ b/source/blender/editors/include/ED_uvedit.h
@@ -62,7 +62,7 @@ void ED_object_assign_active_image(struct Main *bmain, struct Object *ob, int ma
 bool ED_uvedit_test(struct Object *obedit);
 
 /* visibility and selection */
-bool uvedit_face_visible_test(struct Scene *scene, struct Image *ima, struct BMFace *efa);
+bool uvedit_face_visible_test(struct Scene *scene, struct Object *obedit, struct Image *ima, struct BMFace *efa);
 bool uvedit_face_select_test(struct Scene *scene, struct BMFace *efa,
                              const int cd_loop_uv_offset);
 bool uvedit_edge_select_test(struct Scene *scene, struct BMLoop *l,
diff --git a/source/blender/editors/mesh/editmesh_path.c b/source/blender/editors/mesh/editmesh_path.c
index b71dd029bf23d2effcdaeeffa1cc32a5ed9fc9fa..795c7b6aa530b1bae943364c5393d3e121dbd5f7 100644
--- a/source/blender/editors/mesh/editmesh_path.c
+++ b/source/blender/editors/mesh/editmesh_path.c
@@ -121,10 +121,9 @@ static void verttag_set_cb(BMVert *v, bool val, void *user_data_v)
 }
 
 static void mouse_mesh_shortest_path_vert(
-        Scene *scene, const struct PathSelectParams *op_params,
+        Scene *UNUSED(scene), Object *obedit, const struct PathSelectParams *op_params,
         BMVert *v_act, BMVert *v_dst)
 {
-	Object *obedit = scene->obedit;
 	BMEditMesh *em = BKE_editmesh_from_object(obedit);
 	BMesh *bm = em->bm;
 
@@ -280,11 +279,11 @@ static void edgetag_set_cb(BMEdge *e, bool val, void *user_data_v)
 	}
 }
 
-static void edgetag_ensure_cd_flag(Scene *scene, Mesh *me)
+static void edgetag_ensure_cd_flag(Mesh *me, const char edge_mode)
 {
 	BMesh *bm = me->edit_btmesh->bm;
 
-	switch (scene->toolsettings->edge_mode) {
+	switch (edge_mode) {
 		case EDGE_MODE_TAG_CREASE:
 			BM_mesh_cd_flag_ensure(bm, me, ME_CDFLAG_EDGE_CREASE);
 			break;
@@ -307,10 +306,9 @@ static void edgetag_ensure_cd_flag(Scene *scene, Mesh *me)
 
 /* since you want to create paths with multiple selects, it doesn't have extend option */
 static void mouse_mesh_shortest_path_edge(
-        Scene *scene, const struct PathSelectParams *op_params,
+        Scene *scene, Object *obedit, const struct PathSelectParams *op_params,
         BMEdge *e_act, BMEdge *e_dst)
 {
-	Object *obedit = scene->obedit;
 	BMEditMesh *em = BKE_editmesh_from_object(obedit);
 	BMesh *bm = em->bm;
 
@@ -319,7 +317,7 @@ static void mouse_mesh_shortest_path_edge(
 	Mesh *me = obedit->data;
 	bool is_path_ordered = false;
 
-	edgetag_ensure_cd_flag(scene, obedit->data);
+	edgetag_ensure_cd_flag(obedit->data, op_params->edge_mode);
 
 	if (e_act && (e_act != e_dst)) {
 		if (op_params->use_fill) {
@@ -377,7 +375,7 @@ static void mouse_mesh_shortest_path_edge(
 	}
 	else {
 		const bool is_act = !edgetag_test_cb(e_dst, &user_data);
-		edgetag_ensure_cd_flag(scene, obedit->data);
+		edgetag_ensure_cd_flag(obedit->data, op_params->edge_mode);
 		edgetag_set_cb(e_dst, is_act, &user_data); /* switch the edge option */
 	}
 
@@ -452,10 +450,9 @@ static void facetag_set_cb(BMFace *f, bool val, void *user_data_v)
 }
 
 static void mouse_mesh_shortest_path_face(
-        Scene *scene, const struct PathSelectParams *op_params,
+        Scene *UNUSED(scene), Object *obedit, const struct PathSelectParams *op_params,
         BMFace *f_act, BMFace *f_dst)
 {
-	Object *obedit = scene->obedit;
 	BMEditMesh *em = BKE_editmesh_from_object(obedit);
 	BMesh *bm = em->bm;
 
@@ -547,7 +544,7 @@ static void mouse_mesh_shortest_path_face(
 /* Main Operator for vert/edge/face tag */
 
 static bool edbm_shortest_path_pick_ex(
-        Scene *scene, const struct PathSelectParams *op_params,
+        Scene *scene, Object *obedit, const struct PathSelectParams *op_params,
         BMElem *ele_src, BMElem *ele_dst)
 {
 
@@ -555,15 +552,15 @@ static bool edbm_shortest_path_pick_ex(
 		/* pass */
 	}
 	else if (ele_src->head.htype == BM_VERT) {
-		mouse_mesh_shortest_path_vert(scene, op_params, (BMVert *)ele_src, (BMVert *)ele_dst);
+		mouse_mesh_shortest_path_vert(scene, obedit, op_params, (BMVert *)ele_src, (BMVert *)ele_dst);
 		return true;
 	}
 	else if (ele_src->head.htype == BM_EDGE) {
-		mouse_mesh_shortest_path_edge(scene, op_params, (BMEdge *)ele_src, (BMEdge *)ele_dst);
+		mouse_mesh_shortest_path_edge(scene, obedit, op_params, (BMEdge *)ele_src, (BMEdge *)ele_dst);
 		return true;
 	}
 	else if (ele_src->head.htype == BM_FACE) {
-		mouse_mesh_shortest_path_face(scene, op_params, (BMFace *)ele_src, (BMFace *)ele_dst);
+		mouse_mesh_shortest_path_face(scene, obedit, op_params, (BMFace *)ele_src, (BMFace *)ele_dst);
 		return true;
 	}
 
@@ -644,7 +641,7 @@ static int edbm_shortest_path_pick_invoke(bContext *C, wmOperator *op, const wmE
 	op_params.track_active = track_active;
 	op_params.edge_mode = vc.scene->toolsettings->edge_mode;
 
-	if (!edbm_shortest_path_pick_ex(vc.scene, &op_params, ele_src, ele_dst)) {
+	if (!edbm_shortest_path_pick_ex(vc.scene, vc.obedit, &op_params, ele_src, ele_dst)) {
 		return OPERATOR_PASS_THROUGH;
 	}
 
@@ -681,7 +678,7 @@ static int edbm_shortest_path_pick_exec(bContext *C, wmOperator *op)
 	op_params.track_active = true;
 	op_params.edge_mode = scene->toolsettings->edge_mode;
 
-	if (!edbm_shortest_path_pick_ex(scene, &op_params, ele_src, ele_dst)) {
+	if (!edbm_shortest_path_pick_ex(scene, obedit, &op_params, ele_src, ele_dst)) {
 		return OPERATOR_CANCELLED;
 	}
 
@@ -720,8 +717,8 @@ void MESH_OT_shortest_path_pick(wmOperatorType *ot)
 static int edbm_shortest_path_select_exec(bContext *C, wmOperator *op)
 {
 	Scene *scene = CTX_data_scene(C);
-	Object *ob = CTX_data_edit_object(C);
-	BMEditMesh *em = BKE_editmesh_from_object(ob);
+	Object *obedit = CTX_data_edit_object(C);
+	BMEditMesh *em = BKE_editmesh_from_object(obedit);
 	BMesh *bm = em->bm;
 	BMIter iter;
 	BMEditSelection *ese_src, *ese_dst;
@@ -773,7 +770,7 @@ static int edbm_shortest_path_select_exec(bContext *C, wmOperator *op)
 		struct PathSelectParams op_params;
 		path_select_params_from_op(op, &op_params);
 
-		edbm_shortest_path_pick_ex(scene, &op_params, ele_src, ele_dst);
+		edbm_shortest_path_pick_ex(scene, obedit, &op_params, ele_src, ele_dst);
 
 		return OPERATOR_FINISHED;
 	}
diff --git a/source/blender/editors/mesh/meshtools.c b/source/blender/editors/mesh/meshtools.c
index 85b1c70fde3ae65306f9acbd960e1223e7d5356b..64b6f5b80100ef112a6257233a9141a31765d552 100644
--- a/source/blender/editors/mesh/meshtools.c
+++ b/source/blender/editors/mesh/meshtools.c
@@ -42,6 +42,7 @@
 #include "DNA_scene_types.h"
 #include "DNA_screen_types.h"
 #include "DNA_view3d_types.h"
+#include "DNA_workspace_types.h"
 
 #include "BLI_math.h"
 #include "BLI_blenlib.h"
@@ -275,6 +276,7 @@ static void join_mesh_single(
 
 int join_mesh_exec(bContext *C, wmOperator *op)
 {
+	const WorkSpace *workspace = CTX_wm_workspace(C);
 	Main *bmain = CTX_data_main(C);
 	Scene *scene = CTX_data_scene(C);
 	Object *ob = CTX_data_active_object(C);
@@ -294,7 +296,7 @@ int join_mesh_exec(bContext *C, wmOperator *op)
 	bDeformGroup *dg, *odg;
 	CustomData vdata, edata, fdata, ldata, pdata;
 
-	if (scene->obedit) {
+	if (workspace->object_mode & OB_MODE_EDIT) {
 		BKE_report(op->reports, RPT_WARNING, "Cannot join while in edit mode");
 		return OPERATOR_CANCELLED;
 	}
diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c
index 18c18f10c136f4860d7ba14d0530014dc6fafc54..b77cb6525eab7beedd9d25635090574717f3c28e 100644
--- a/source/blender/editors/object/object_add.c
+++ b/source/blender/editors/object/object_add.c
@@ -1673,7 +1673,7 @@ static int convert_poll(bContext *C)
 	Base *base_act = CTX_data_active_base(C);
 	Object *obact = base_act ? base_act->object : NULL;
 
-	return (!ID_IS_LINKED(scene) && obact && scene->obedit != obact &&
+	return (!ID_IS_LINKED(scene) && obact && BKE_object_is_in_editmode(obact) &&
 	        (base_act->flag & BASE_SELECTED) && !ID_IS_LINKED(obact));
 }
 
@@ -2529,10 +2529,10 @@ static int join_poll(bContext *C)
 
 static int join_exec(bContext *C, wmOperator *op)
 {
-	Scene *scene = CTX_data_scene(C);
+	const WorkSpace *workspace = CTX_wm_workspace(C);
 	Object *ob = CTX_data_active_object(C);
 
-	if (scene->obedit) {
+	if (workspace->object_mode & OB_MODE_EDIT) {
 		BKE_report(op->reports, RPT_ERROR, "This data does not support joining in edit mode");
 		return OPERATOR_CANCELLED;
 	}
@@ -2583,10 +2583,10 @@ static int join_shapes_poll(bContext *C)
 
 static int join_shapes_exec(bContext *C, wmOperator *op)
 {
-	Scene *scene = CTX_data_scene(C);
+	const WorkSpace *workspace = CTX_wm_workspace(C);
 	Object *ob = CTX_data_active_object(C);
 
-	if (scene->obedit) {
+	if (workspace->object_mode & OB_MODE_EDIT) {
 		BKE_report(op->reports, RPT_ERROR, "This data does not support joining in edit mode");
 		return OPERATOR_CANCELLED;
 	}
diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c
index ca96e1c67988ca047f4878a6515c56f403cff439..986f10b0797e81d2cc0b979d2abd36d5b0e69ba7 100644
--- a/source/blender/editors/object/object_edit.c
+++ b/source/blender/editors/object/object_edit.c
@@ -84,6 +84,7 @@
 #include "BKE_modifier.h"
 #include "BKE_editmesh.h"
 #include "BKE_report.h"
+#include "BKE_object.h"
 #include "BKE_workspace.h"
 
 #include "DEG_depsgraph.h"
@@ -283,9 +284,6 @@ void ED_object_editmode_exit(bContext *C, int flag)
 		ListBase pidlist;
 		PTCacheID *pid;
 
-		/* for example; displist make is different in editmode */
-		scene->obedit = NULL; // XXX for context
-
 		/* flag object caches as outdated */
 		BKE_ptcache_ids_from_object(&pidlist, obedit, scene, 0);
 		for (pid = pidlist.first; pid; pid = pid->next) {
@@ -358,8 +356,6 @@ void ED_object_editmode_enter(bContext *C, int flag)
 	if (ob->type == OB_MESH) {
 		BMEditMesh *em;
 		ok = 1;
-		scene->obedit = ob;  /* context sees this */
-
 		const bool use_key_index = mesh_needs_keyindex(ob->data);
 
 		EDBM_mesh_make(scene->toolsettings, ob, use_key_index);
@@ -389,7 +385,6 @@ void ED_object_editmode_enter(bContext *C, int flag)
 			return;
 		}
 		ok = 1;
-		scene->obedit = ob;
 		ED_armature_to_edit(arm);
 		/* to ensure all goes in restposition and without striding */
 		DEG_id_tag_update(&ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME); /* XXX: should this be OB_RECALC_DATA? */
@@ -397,21 +392,18 @@ void ED_object_editmode_enter(bContext *C, int flag)
 		WM_event_add_notifier(C, NC_SCENE | ND_MODE | NS_EDITMODE_ARMATURE, scene);
 	}
 	else if (ob->type == OB_FONT) {
-		scene->obedit = ob; /* XXX for context */
 		ok = 1;
 		ED_curve_editfont_make(ob);
 
 		WM_event_add_notifier(C, NC_SCENE | ND_MODE | NS_EDITMODE_TEXT, scene);
 	}
 	else if (ob->type == OB_MBALL) {
-		scene->obedit = ob; /* XXX for context */
 		ok = 1;
 		ED_mball_editmball_make(ob);
 
 		WM_event_add_notifier(C, NC_SCENE | ND_MODE | NS_EDITMODE_MBALL, scene);
 	}
 	else if (ob->type == OB_LATTICE) {
-		scene->obedit = ob; /* XXX for context */
 		ok = 1;
 		ED_lattice_editlatt_make(ob);
 
@@ -419,7 +411,6 @@ void ED_object_editmode_enter(bContext *C, int flag)
 	}
 	else if (ob->type == OB_SURF || ob->type == OB_CURVE) {
 		ok = 1;
-		scene->obedit = ob; /* XXX for context */
 		ED_curve_editnurb_make(ob);
 
 		WM_event_add_notifier(C, NC_SCENE | ND_MODE | NS_EDITMODE_CURVE, scene);
@@ -431,7 +422,6 @@ void ED_object_editmode_enter(bContext *C, int flag)
 		DEG_id_tag_update(&scene->id, 0);
 	}
 	else {
-		scene->obedit = NULL; /* XXX for context */
 		workspace->object_mode &= ~OB_MODE_EDIT;
 		WM_event_add_notifier(C, NC_SCENE | ND_MODE | NS_MODE_OBJECT, scene);
 	}
@@ -703,7 +693,7 @@ static void copy_attr(Main *bmain, Scene *scene, ViewLayer *view_layer, short ev
 
 	if (!(ob = OBACT(view_layer))) return;
 	
-	if (scene->obedit) { // XXX get from context
+	if (BKE_object_is_in_editmode(ob)) { // XXX get from context
 		/* obedit_copymenu(); */
 		return;
 	}
@@ -942,7 +932,7 @@ static void copy_attr(Main *bmain, Scene *scene, ViewLayer *view_layer, short ev
 		DEG_relations_tag_update(bmain);
 }
 
-static void UNUSED_FUNCTION(copy_attr_menu) (Main *bmain, Scene *scene, ViewLayer *view_layer)
+static void UNUSED_FUNCTION(copy_attr_menu) (Main *bmain, Scene *scene, ViewLayer *view_layer, Object *obedit)
 {
 	Object *ob;
 	short event;
@@ -950,7 +940,7 @@ static void UNUSED_FUNCTION(copy_attr_menu) (Main *bmain, Scene *scene, ViewLaye
 	
 	if (!(ob = OBACT(view_layer))) return;
 	
-	if (scene->obedit) { /* XXX get from context */
+	if (obedit) { /* XXX get from context */
 /*		if (ob->type == OB_MESH) */
 /* XXX			mesh_copy_menu(); */
 		return;
@@ -1367,7 +1357,7 @@ void OBJECT_OT_shade_smooth(wmOperatorType *ot)
 
 /* ********************** */
 
-static void UNUSED_FUNCTION(image_aspect) (Scene *scene, ViewLayer *view_layer)
+static void UNUSED_FUNCTION(image_aspect) (Scene *scene, ViewLayer *view_layer, Object *obedit)
 {
 	/* all selected objects with an image map: scale in image aspect */
 	Base *base;
@@ -1377,7 +1367,7 @@ static void UNUSED_FUNCTION(image_aspect) (Scene *scene, ViewLayer *view_layer)
 	float x, y, space;
 	int a, b, done;
 	
-	if (scene->obedit) return;  // XXX get from context
+	if (obedit) return;
 	if (ID_IS_LINKED(scene)) return;
 	
 	for (base = FIRSTBASE(view_layer); base; base = base->next) {
diff --git a/source/blender/editors/object/object_modifier.c b/source/blender/editors/object/object_modifier.c
index 78554713f4d1894bad99eb21aa847a9957659330..9d1792e9f16f07a529565258e331b1331b098265 100644
--- a/source/blender/editors/object/object_modifier.c
+++ b/source/blender/editors/object/object_modifier.c
@@ -693,7 +693,7 @@ int ED_object_modifier_apply(ReportList *reports, const bContext *C, Scene *scen
 	const WorkSpace *workspace = CTX_wm_workspace(C);
 	int prev_mode;
 
-	if (scene->obedit) {
+	if (BKE_object_is_in_editmode(ob)) {
 		BKE_report(reports, RPT_ERROR, "Modifiers cannot be applied in edit mode");
 		return 0;
 	}
diff --git a/source/blender/editors/object/object_transform.c b/source/blender/editors/object/object_transform.c
index d69d8f8b26ef69743dc1e3a967afd80dc0bcb815..b336b560ef276eeecbc152736dfdf12c00f51925 100644
--- a/source/blender/editors/object/object_transform.c
+++ b/source/blender/editors/object/object_transform.c
@@ -983,7 +983,7 @@ static int object_origin_set_exec(bContext *C, wmOperator *op)
 					/* Function to recenter armatures in editarmature.c
 					 * Bone + object locations are handled there.
 					 */
-					ED_armature_origin_set(scene, ob, cursor, centermode, around);
+					ED_armature_origin_set(ob, cursor, centermode, around);
 
 					tot_change++;
 					arm->id.tag |= LIB_TAG_DOIT;
diff --git a/source/blender/editors/render/render_internal.c b/source/blender/editors/render/render_internal.c
index 8e410a3abbb7528c72657818a147be4dba597472..07efa046e1a95f1d037ccee20bf72f9690851857 100644
--- a/source/blender/editors/render/render_internal.c
+++ b/source/blender/editors/render/render_internal.c
@@ -1444,8 +1444,11 @@ static bool render_view3d_flag_changed(RenderEngine *engine, const bContext *C)
 		job_update_flag |= PR_UPDATE_DATABASE;
 
 		/* load editmesh */
-		if (scene->obedit)
-			ED_object_editmode_load(scene->obedit);
+		const EvaluationContext *eval_ctx = RE_GetEvalCtx(re);
+		Object *obedit = OBEDIT_FROM_EVAL_CTX(eval_ctx);
+		if (obedit) {
+			ED_object_editmode_load(obedit);
+		}
 	}
 	
 	engine->update_flag = 0;
diff --git a/source/blender/editors/screen/screen_context.c b/source/blender/editors/screen/screen_context.c
index bb92ea35ad07a448a4fbc2bf506ee7aa36e9c23b..2a48ae46b1222cfbdc8ec715e3dadbceca8013b7 100644
--- a/source/blender/editors/screen/screen_context.c
+++ b/source/blender/editors/screen/screen_context.c
@@ -92,8 +92,8 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
 	Scene *scene = WM_window_get_active_scene(win);
 	WorkSpace *workspace = BKE_workspace_active_get(win->workspace_hook);
 	ViewLayer *view_layer = BKE_view_layer_from_workspace_get(scene, workspace);
-	Object *obedit = scene->obedit;
 	Object *obact = (view_layer && view_layer->basact) ? view_layer->basact->object : NULL;
+	Object *obedit = BKE_workspace_edit_object(workspace, scene);
 
 	if (CTX_data_dir(member)) {
 		CTX_data_dir_set(result, screen_context_dir);
diff --git a/source/blender/editors/screen/screen_edit.c b/source/blender/editors/screen/screen_edit.c
index 604a86a151909224d3dcf5e515723122082ace93..0d9fc7c60e324b21788e6005bf20916b1716f6c9 100644
--- a/source/blender/editors/screen/screen_edit.c
+++ b/source/blender/editors/screen/screen_edit.c
@@ -1871,3 +1871,14 @@ Scene *ED_screen_scene_find(const bScreen *screen, const wmWindowManager *wm)
 {
 	return ED_screen_scene_find_with_window(screen, wm, NULL);
 }
+
+
+wmWindow *ED_screen_window_find(const bScreen *screen, const wmWindowManager *wm)
+{
+	for (wmWindow *win = wm->windows.first; win; win = win->next) {
+		if (WM_window_get_active_screen(win) == screen) {
+			return win;
+		}
+	}
+	return NULL;
+}
diff --git a/source/blender/editors/sculpt_paint/paint_image.c b/source/blender/editors/sculpt_paint/paint_image.c
index d42bbfdc43aa2ff5ab1aa26d4bb2844a293a91c2..1cb37fc10cd316eb5855fe607a7eae47d59172bf 100644
--- a/source/blender/editors/sculpt_paint/paint_image.c
+++ b/source/blender/editors/sculpt_paint/paint_image.c
@@ -1429,8 +1429,10 @@ static int texture_paint_toggle_exec(bContext *C, wmOperator *op)
 						if (sl->spacetype == SPACE_IMAGE) {
 							SpaceImage *sima = (SpaceImage *)sl;
 							
-							if (!sima->pin)
-								ED_space_image_set(sima, scene, scene->obedit, ima);
+							if (!sima->pin) {
+								Object *obedit = CTX_data_edit_object(C);
+								ED_space_image_set(sima, scene, obedit, ima);
+							}
 						}
 					}
 				}
diff --git a/source/blender/editors/sculpt_paint/paint_vertex_weight_utils.c b/source/blender/editors/sculpt_paint/paint_vertex_weight_utils.c
index 4d70d82d5c6e49234d686362bdbc7c361849d800..51cd759b260458170634a468b0c4eea973412916 100644
--- a/source/blender/editors/sculpt_paint/paint_vertex_weight_utils.c
+++ b/source/blender/editors/sculpt_paint/paint_vertex_weight_utils.c
@@ -43,6 +43,7 @@
 #include "BKE_modifier.h"
 #include "BKE_object_deform.h"
 #include "BKE_report.h"
+#include "BKE_object.h"
 
 #include "WM_api.h"
 #include "WM_types.h"
@@ -58,7 +59,6 @@ bool ED_wpaint_ensure_data(
         bContext *C, struct ReportList *reports,
         enum eWPaintFlag flag, struct WPaintVGroupIndex *vgroup_index)
 {
-	Scene *scene = CTX_data_scene(C);
 	Object *ob = CTX_data_active_object(C);
 	Mesh *me = BKE_mesh_from_object(ob);
 
@@ -67,7 +67,7 @@ bool ED_wpaint_ensure_data(
 		vgroup_index->mirror = -1;
 	}
 
-	if (scene->obedit) {
+	if (BKE_object_is_in_editmode(ob)) {
 		return false;
 	}
 
@@ -308,4 +308,4 @@ float ED_wpaint_blend_tool(
 	}
 }
 
-/** \} */
\ No newline at end of file
+/** \} */
diff --git a/source/blender/editors/sculpt_paint/sculpt_uv.c b/source/blender/editors/sculpt_paint/sculpt_uv.c
index c9453f94e612505effc54e400a0e4aecc05d14ff..c736f70f9fa6c0a809557abde4eea4b0b2377cce 100644
--- a/source/blender/editors/sculpt_paint/sculpt_uv.c
+++ b/source/blender/editors/sculpt_paint/sculpt_uv.c
@@ -652,7 +652,7 @@ static UvSculptData *uv_sculpt_stroke_init(bContext *C, wmOperator *op, const wm
 			UvElement *element;
 			NearestHit hit;
 			Image *ima = CTX_data_edit_image(C);
-			uv_find_nearest_vert(scene, ima, em, co, NULL, &hit);
+			uv_find_nearest_vert(scene, ima, obedit, em, co, NULL, &hit);
 
 			element = BM_uv_element_get(data->elementMap, hit.efa, hit.l);
 			island_index = element->island;
diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c
index 0ff30c228b475bf5441d3c968b9523b30f1009c1..6ee9d547ac3633ef99e704d0017f3bf3200f8cc1 100644
--- a/source/blender/editors/space_image/image_ops.c
+++ b/source/blender/editors/space_image/image_ops.c
@@ -275,12 +275,14 @@ int space_image_main_region_poll(bContext *C)
 /* For IMAGE_OT_curves_point_set to avoid sampling when in uv smooth mode or editmode */
 static int space_image_main_area_not_uv_brush_poll(bContext *C)
 {
+	const WorkSpace *workspace = CTX_wm_workspace(C);
 	SpaceImage *sima = CTX_wm_space_image(C);
 	Scene *scene = CTX_data_scene(C);
 	ToolSettings *toolsettings = scene->toolsettings;
 
-	if (sima && !toolsettings->uvsculpt && !scene->obedit)
+	if (sima && !toolsettings->uvsculpt && ((workspace->object_mode & OB_MODE_EDIT) == 0)) {
 		return 1;
+	}
 
 	return 0;
 }
@@ -2459,7 +2461,7 @@ static int image_new_exec(bContext *C, wmOperator *op)
 						SpaceImage *sima_other = (SpaceImage *)sl;
 						
 						if (!sima_other->pin) {
-							ED_space_image_set(sima_other, scene, scene->obedit, ima);
+							ED_space_image_set(sima_other, scene, obedit, ima);
 						}
 					}
 				}
diff --git a/source/blender/editors/space_info/info_stats.c b/source/blender/editors/space_info/info_stats.c
index 118be88216e1d8c7761f07aea9f056f243cb51fb..800560c380c67b07dff99bc3745d91b8a2746bb0 100644
--- a/source/blender/editors/space_info/info_stats.c
+++ b/source/blender/editors/space_info/info_stats.c
@@ -54,6 +54,7 @@
 #include "BKE_paint.h"
 #include "BKE_particle.h"
 #include "BKE_editmesh.h"
+#include "BKE_object.h"
 
 #include "ED_info.h"
 #include "ED_armature.h"
@@ -374,15 +375,15 @@ static bool stats_is_object_dynamic_topology_sculpt(Object *ob, const eObjectMod
 }
 
 /* Statistics displayed in info header. Called regularly on scene changes. */
-static void stats_update(Scene *scene, ViewLayer *view_layer, const eObjectMode object_mode)
+static void stats_update(ViewLayer *view_layer, Object *obedit, const eObjectMode object_mode)
 {
 	SceneStats stats = {0};
 	Object *ob = (view_layer->basact) ? view_layer->basact->object : NULL;
 	Base *base;
-	
-	if (scene->obedit) {
+
+	if (obedit) {
 		/* Edit Mode */
-		stats_object_edit(scene->obedit, &stats);
+		stats_object_edit(ob, &stats);
 	}
 	else if (ob && (object_mode & OB_MODE_POSE)) {
 		/* Pose Mode */
@@ -407,7 +408,7 @@ static void stats_update(Scene *scene, ViewLayer *view_layer, const eObjectMode
 	*(view_layer->stats) = stats;
 }
 
-static void stats_string(Scene *scene, ViewLayer *view_layer, const eObjectMode object_mode)
+static void stats_string(ViewLayer *view_layer, Object *obedit, const eObjectMode object_mode)
 {
 #define MAX_INFO_MEM_LEN  64
 	SceneStats *stats = view_layer->stats;
@@ -473,17 +474,17 @@ static void stats_string(Scene *scene, ViewLayer *view_layer, const eObjectMode
 
 	ofs += BLI_snprintf(s + ofs, MAX_INFO_LEN - ofs, "%s | ", versionstr);
 
-	if (scene->obedit) {
-		if (BKE_keyblock_from_object(scene->obedit))
+	if (obedit) {
+		if (BKE_keyblock_from_object(obedit))
 			ofs += BLI_strncpy_rlen(s + ofs, IFACE_("(Key) "), MAX_INFO_LEN - ofs);
 
-		if (scene->obedit->type == OB_MESH) {
+		if (obedit->type == OB_MESH) {
 			ofs += BLI_snprintf(s + ofs, MAX_INFO_LEN - ofs,
 			                    IFACE_("Verts:%s/%s | Edges:%s/%s | Faces:%s/%s | Tris:%s"),
 			                    stats_fmt.totvertsel, stats_fmt.totvert, stats_fmt.totedgesel, stats_fmt.totedge,
 			                    stats_fmt.totfacesel, stats_fmt.totface, stats_fmt.tottri);
 		}
-		else if (scene->obedit->type == OB_ARMATURE) {
+		else if (obedit->type == OB_ARMATURE) {
 			ofs += BLI_snprintf(s + ofs, MAX_INFO_LEN - ofs, IFACE_("Verts:%s/%s | Bones:%s/%s"), stats_fmt.totvertsel,
 			                    stats_fmt.totvert, stats_fmt.totbonesel, stats_fmt.totbone);
 		}
@@ -527,12 +528,16 @@ void ED_info_stats_clear(ViewLayer *view_layer)
 	}
 }
 
-const char *ED_info_stats_string(Scene *scene, WorkSpace *workspace, ViewLayer *view_layer)
+const char *ED_info_stats_string(Scene *UNUSED(scene), WorkSpace *workspace, ViewLayer *view_layer)
 {
+	Object *obact = (view_layer->basact) ? view_layer->basact->object : NULL;
+	Object *obedit = (obact && (workspace->object_mode & OB_MODE_EDIT) &&
+	                  BKE_object_is_in_editmode(obact)) ? obact : NULL;
+
 	if (!view_layer->stats) {
-		stats_update(scene, view_layer, workspace->object_mode);
+		stats_update(view_layer, obedit, workspace->object_mode);
 	}
-	stats_string(scene, view_layer, workspace->object_mode);
+	stats_string(view_layer, obedit, workspace->object_mode);
 
 	return view_layer->stats->infostr;
 }
diff --git a/source/blender/editors/space_outliner/outliner_draw.c b/source/blender/editors/space_outliner/outliner_draw.c
index 4308a795a9c412c9ac38686ab9d70bf8b18a5801..c3d0713ca6d0c0678f49b9d70caf2fc83b1ea278 100644
--- a/source/blender/editors/space_outliner/outliner_draw.c
+++ b/source/blender/editors/space_outliner/outliner_draw.c
@@ -1234,8 +1234,9 @@ static void tselem_draw_icon(uiBlock *block, int xmax, float x, float y, TreeSto
 #undef ICON_DRAW
 }
 
-static void outliner_draw_iconrow(bContext *C, uiBlock *block, Scene *scene, ViewLayer *view_layer, SpaceOops *soops,
-                                  ListBase *lb, int level, int xmax, int *offsx, int ys, float alpha_fac)
+static void outliner_draw_iconrow(
+        bContext *C, uiBlock *block, Scene *scene, ViewLayer *view_layer, Object *obedit, SpaceOops *soops,
+        ListBase *lb, int level, int xmax, int *offsx, int ys, float alpha_fac)
 {
 	TreeElement *te;
 	TreeStoreElem *tselem;
@@ -1256,7 +1257,7 @@ static void outliner_draw_iconrow(bContext *C, uiBlock *block, Scene *scene, Vie
 				if (te->idcode == ID_OB) {
 					active = (OBACT(view_layer) == (Object *)tselem->id) ? OL_DRAWSEL_NORMAL : OL_DRAWSEL_NONE;
 				}
-				else if (scene->obedit && scene->obedit->data == tselem->id) {
+				else if (obedit && obedit->data == tselem->id) {
 					active = OL_DRAWSEL_NORMAL;
 				}
 				else {
@@ -1296,7 +1297,9 @@ static void outliner_draw_iconrow(bContext *C, uiBlock *block, Scene *scene, Vie
 		
 		/* this tree element always has same amount of branches, so don't draw */
 		if (tselem->type != TSE_R_LAYER)
-			outliner_draw_iconrow(C, block, scene, view_layer, soops, &te->subtree, level + 1, xmax, offsx, ys, alpha_fac);
+			outliner_draw_iconrow(
+			        C, block, scene, view_layer, obedit, soops,
+			        &te->subtree, level + 1, xmax, offsx, ys, alpha_fac);
 	}
 	
 }
@@ -1320,7 +1323,7 @@ static void outliner_set_coord_tree_element(TreeElement *te, int startx, int sta
 
 
 static void outliner_draw_tree_element(
-        bContext *C, uiBlock *block, const uiFontStyle *fstyle, Scene *scene, ViewLayer *view_layer,
+        bContext *C, uiBlock *block, const uiFontStyle *fstyle, Scene *scene, ViewLayer *view_layer, Object *obedit,
         ARegion *ar, SpaceOops *soops, TreeElement *te, bool draw_grayed_out,
         int startx, int *starty, TreeElement **te_edit, TreeElement **te_floating)
 {
@@ -1384,7 +1387,7 @@ static void outliner_draw_tree_element(
 				}
 			
 			}
-			else if (scene->obedit && scene->obedit->data == tselem->id) {
+			else if (obedit && obedit->data == tselem->id) {
 				rgba_float_args_set(color, 1.0f, 1.0f, 1.0f, alpha);
 				active = OL_DRAWSEL_ACTIVE;
 			}
@@ -1514,8 +1517,9 @@ static void outliner_draw_tree_element(
 						immUnbindProgram();
 					}
 
-					outliner_draw_iconrow(C, block, scene, view_layer, soops, &te->subtree, 0, xmax, &tempx,
-					                      *starty, alpha_fac);
+					outliner_draw_iconrow(
+					        C, block, scene, view_layer, obedit, soops, &te->subtree, 0, xmax, &tempx,
+					        *starty, alpha_fac);
 
 					glDisable(GL_BLEND);
 				}
@@ -1534,8 +1538,10 @@ static void outliner_draw_tree_element(
 			/* check if element needs to be drawn grayed out, but also gray out
 			 * childs of a grayed out parent (pass on draw_grayed_out to childs) */
 			bool draw_childs_grayed_out = draw_grayed_out || (ten->drag_data != NULL);
-			outliner_draw_tree_element(C, block, fstyle, scene, view_layer, ar, soops, ten, draw_childs_grayed_out,
-			                           startx + UI_UNIT_X, starty, te_edit, te_floating);
+			outliner_draw_tree_element(
+			        C, block, fstyle, scene, view_layer, obedit,
+			        ar, soops, ten, draw_childs_grayed_out,
+			        startx + UI_UNIT_X, starty, te_edit, te_floating);
 		}
 	}
 	else {
@@ -1774,8 +1780,8 @@ static void outliner_draw_highlights(ARegion *ar, SpaceOops *soops, int startx,
 }
 
 static void outliner_draw_tree(
-        bContext *C, uiBlock *block, Scene *scene, ViewLayer *view_layer, ARegion *ar,
-        SpaceOops *soops, const bool has_restrict_icons,
+        bContext *C, uiBlock *block, Scene *scene, ViewLayer *view_layer, Object *obedit,
+        ARegion *ar, SpaceOops *soops, const bool has_restrict_icons,
         TreeElement **te_edit)
 {
 	const uiFontStyle *fstyle = UI_FSTYLE_WIDGET;
@@ -1815,8 +1821,10 @@ static void outliner_draw_tree(
 	starty = (int)ar->v2d.tot.ymax - UI_UNIT_Y - OL_Y_OFFSET;
 	startx = 0;
 	for (TreeElement *te = soops->tree.first; te; te = te->next) {
-		outliner_draw_tree_element(C, block, fstyle, scene, view_layer, ar, soops, te, te->drag_data != NULL,
-		                           startx, &starty, te_edit, &te_floating);
+		outliner_draw_tree_element(
+		        C, block, fstyle, scene, view_layer, obedit,
+		        ar, soops, te, te->drag_data != NULL,
+		        startx, &starty, te_edit, &te_floating);
 	}
 	if (te_floating && te_floating->drag_data->insert_handle) {
 		outliner_draw_tree_element_floating(ar, te_floating);
@@ -1893,6 +1901,7 @@ void draw_outliner(const bContext *C)
 {
 	EvaluationContext eval_ctx;
 	CTX_data_eval_ctx(C, &eval_ctx);
+	Object *obedit = OBEDIT_FROM_EVAL_CTX(&eval_ctx);
 	Main *mainvar = CTX_data_main(C); 
 	Scene *scene = CTX_data_scene(C);
 	ViewLayer *view_layer = CTX_data_view_layer(C);
@@ -1955,7 +1964,9 @@ void draw_outliner(const bContext *C)
 	/* draw outliner stuff (background, hierarchy lines and names) */
 	outliner_back(ar);
 	block = UI_block_begin(C, ar, __func__, UI_EMBOSS);
-	outliner_draw_tree((bContext *)C, block, scene, view_layer, ar, soops, has_restrict_icons, &te_edit);
+	outliner_draw_tree(
+	        (bContext *)C, block, scene, view_layer, obedit,
+	        ar, soops, has_restrict_icons, &te_edit);
 
 	if (soops->outlinevis == SO_DATABLOCKS) {
 		/* draw rna buttons */
diff --git a/source/blender/editors/space_outliner/outliner_select.c b/source/blender/editors/space_outliner/outliner_select.c
index df5f43978e613a68038b56162ab81ebd298738a6..9e4e024bf648a90bd2782bfa7a38c52219cb3912 100644
--- a/source/blender/editors/space_outliner/outliner_select.c
+++ b/source/blender/editors/space_outliner/outliner_select.c
@@ -50,6 +50,7 @@
 #include "BKE_scene.h"
 #include "BKE_sequencer.h"
 #include "BKE_armature.h"
+#include "BKE_workspace.h"
 
 #include "DEG_depsgraph.h"
 
@@ -193,10 +194,10 @@ static eOLDrawState tree_element_set_active_object(
 			WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
 		}
 	}
-	
-	if (ob != scene->obedit)
+
+	if (!BKE_object_is_in_editmode(ob)) {
 		ED_object_editmode_exit(C, EM_FREEDATA | EM_FREEUNDO | EM_WAITCURSOR | EM_DO_UNDO);
-		
+	}
 	return OL_DRAWSEL_NORMAL;
 }
 
@@ -547,7 +548,7 @@ static eOLDrawState tree_element_active_bone(
 
 
 /* ebones only draw in editmode armature */
-static void tree_element_active_ebone__sel(bContext *C, Scene *scene, bArmature *arm, EditBone *ebone, short sel)
+static void tree_element_active_ebone__sel(bContext *C, Object *obedit, bArmature *arm, EditBone *ebone, short sel)
 {
 	if (sel) {
 		ebone->flag |= BONE_SELECTED | BONE_ROOTSEL | BONE_TIPSEL;
@@ -561,34 +562,34 @@ static void tree_element_active_ebone__sel(bContext *C, Scene *scene, bArmature
 		if (ebone->parent && (ebone->flag & BONE_CONNECTED)) ebone->parent->flag &= ~BONE_TIPSEL;
 	}
 
-	WM_event_add_notifier(C, NC_OBJECT | ND_BONE_ACTIVE, scene->obedit);
+	WM_event_add_notifier(C, NC_OBJECT | ND_BONE_ACTIVE, obedit);
 }
 static eOLDrawState tree_element_active_ebone(
         bContext *C, Scene *scene, TreeElement *te, TreeStoreElem *UNUSED(tselem), const eOLSetState set, bool recursive)
 {
-	BLI_assert(scene->obedit != NULL);
-
-	bArmature *arm = scene->obedit->data;
+	Object *obedit = BKE_workspace_edit_object(CTX_wm_workspace(C), scene);
+	BLI_assert(obedit != NULL);
+	bArmature *arm = obedit->data;
 	EditBone *ebone = te->directdata;
 	eOLDrawState status = OL_DRAWSEL_NONE;
 
 	if (set != OL_SETSEL_NONE) {
 		if (set == OL_SETSEL_NORMAL) {
 			if (!(ebone->flag & BONE_HIDDEN_A)) {
-				ED_armature_deselect_all(scene->obedit);
-				tree_element_active_ebone__sel(C, scene, arm, ebone, true);
+				ED_armature_deselect_all(obedit);
+				tree_element_active_ebone__sel(C, obedit, arm, ebone, true);
 				status = OL_DRAWSEL_NORMAL;
 			}
 		}
 		else if (set == OL_SETSEL_EXTEND) {
 			if (!(ebone->flag & BONE_HIDDEN_A)) {
 				if (!(ebone->flag & BONE_SELECTED)) {
-					tree_element_active_ebone__sel(C, scene, arm, ebone, true);
+					tree_element_active_ebone__sel(C, obedit, arm, ebone, true);
 					status = OL_DRAWSEL_NORMAL;
 				}
 				else {
 					/* entirely selected, so de-select */
-					tree_element_active_ebone__sel(C, scene, arm, ebone, false);
+					tree_element_active_ebone__sel(C, obedit, arm, ebone, false);
 					status = OL_DRAWSEL_NONE;
 				}
 			}
@@ -656,7 +657,7 @@ static eOLDrawState tree_element_active_text(
 }
 
 static eOLDrawState tree_element_active_pose(
-        bContext *C, Scene *scene, ViewLayer *view_layer, TreeElement *UNUSED(te), TreeStoreElem *tselem, const eOLSetState set)
+        bContext *C, ViewLayer *view_layer, TreeElement *UNUSED(te), TreeStoreElem *tselem, const eOLSetState set)
 {
 	const WorkSpace *workspace = CTX_wm_workspace(C);
 	Object *ob = (Object *)tselem->id;
@@ -668,7 +669,7 @@ static eOLDrawState tree_element_active_pose(
 	}
 
 	if (set != OL_SETSEL_NONE) {
-		if (scene->obedit) {
+		if (workspace->object_mode & OB_MODE_EDIT) {
 			ED_object_editmode_exit(C, EM_FREEDATA | EM_FREEUNDO | EM_WAITCURSOR | EM_DO_UNDO);
 		}
 		if (workspace->object_mode & OB_MODE_POSE) {
@@ -864,7 +865,7 @@ eOLDrawState tree_element_type_active(
 		case TSE_LINKED_PSYS:
 			return tree_element_active_psys(C, scene, te, tselem, set);
 		case TSE_POSE_BASE:
-			return tree_element_active_pose(C, scene, view_layer, te, tselem, set);
+			return tree_element_active_pose(C, view_layer, te, tselem, set);
 		case TSE_POSE_CHANNEL:
 			return tree_element_active_posechannel(C, scene, view_layer, te, tselem, set, recursive);
 		case TSE_CONSTRAINT:
diff --git a/source/blender/editors/space_outliner/outliner_tools.c b/source/blender/editors/space_outliner/outliner_tools.c
index 3ee0d011bbb5e8688cac7a9d3b428952273457b1..b97046d147000944a974ddd3b241a7caf7d6c3ee 100644
--- a/source/blender/editors/space_outliner/outliner_tools.c
+++ b/source/blender/editors/space_outliner/outliner_tools.c
@@ -419,9 +419,9 @@ static void object_delete_cb(
 		}
 
 		// check also library later
-		if (scene->obedit == ob)
+		if (ob == CTX_data_edit_object(C)) {
 			ED_object_editmode_exit(C, EM_FREEDATA | EM_FREEUNDO | EM_WAITCURSOR | EM_DO_UNDO);
-		
+		}
 		ED_object_base_free_and_unlink(CTX_data_main(C), scene, ob);
 		/* leave for ED_outliner_id_unref to handle */
 #if 0
@@ -980,7 +980,7 @@ static void object_delete_hierarchy_cb(
 {
 	ViewLayer *view_layer = CTX_data_view_layer(C);
 	Base *base = (Base *)te->directdata;
-	Object *obedit = scene->obedit;
+	Object *obedit = CTX_data_edit_object(C);
 
 	if (!base) {
 		base = BKE_view_layer_base_find(view_layer, (Object *)tselem->id);
diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c
index 7ad5f733f028510cb6a1da5d71638633dfd945bc..b12756c8299c27dbe015e975d5556363177b2845 100644
--- a/source/blender/editors/space_view3d/drawobject.c
+++ b/source/blender/editors/space_view3d/drawobject.c
@@ -4579,7 +4579,7 @@ static bool draw_mesh_object(
         const char dt, const unsigned char ob_wire_col[4], const short dflag)
 {
 	Object *ob = base->object;
-	Object *obedit = scene->obedit;
+	Object *obedit = OBEDIT_FROM_EVAL_CTX(eval_ctx);
 	Mesh *me = ob->data;
 	BMEditMesh *em = me->edit_btmesh;
 	bool do_alpha_after = false, drawlinked = false, retval = false;
@@ -4720,8 +4720,10 @@ static void make_color_variations(const unsigned char base_ubyte[4], float low[4
 	high[3] = base[3];
 }
 
-static void draw_mesh_fancy_new(EvaluationContext *eval_ctx, Scene *scene, ViewLayer *view_layer, ARegion *ar, View3D *v3d, RegionView3D *rv3d, Base *base,
-                                const char dt, const unsigned char ob_wire_col[4], const short dflag, const bool other_obedit)
+static void draw_mesh_fancy_new(
+        const EvaluationContext *eval_ctx, Scene *scene, ViewLayer *view_layer,
+        ARegion *ar, View3D *v3d, RegionView3D *rv3d, Base *base,
+        const char dt, const unsigned char ob_wire_col[4], const short dflag, const bool other_obedit)
 {
 	if (dflag & (DRAW_PICKING | DRAW_CONSTCOLOR)) {
 		/* too complicated! use existing methods */
@@ -5042,22 +5044,20 @@ static void draw_mesh_fancy_new(EvaluationContext *eval_ctx, Scene *scene, ViewL
 	dm->release(dm);
 }
 
-static bool UNUSED_FUNCTION(draw_mesh_object_new)(const bContext *C, Scene *scene, ViewLayer *view_layer, ARegion *ar, View3D *v3d, RegionView3D *rv3d, Base *base,
-                                 const char dt, const unsigned char ob_wire_col[4], const short dflag)
+static bool UNUSED_FUNCTION(draw_mesh_object_new)(
+        const EvaluationContext *eval_ctx, Scene *scene, ARegion *ar, View3D *v3d, RegionView3D *rv3d, Base *base,
+        const char dt, const unsigned char ob_wire_col[4], const short dflag)
 {
-	EvaluationContext eval_ctx;
 	Object *ob = base->object;
-	Object *obedit = scene->obedit;
 	Mesh *me = ob->data;
 	BMEditMesh *em = me->edit_btmesh;
 	bool do_alpha_after = false, drawlinked = false, retval = false;
 
-	CTX_data_eval_ctx(C, &eval_ctx);
-
 	if (v3d->flag2 & V3D_RENDER_SHADOW) {
 		/* TODO: handle shadow pass separately */
 		return true;
 	}
+	Object *obedit = OBEDIT_FROM_EVAL_CTX(eval_ctx);
 	
 	if (obedit && ob != obedit && ob->data == obedit->data) {
 		if (BKE_key_from_object(ob) || BKE_key_from_object(obedit)) {}
@@ -5083,7 +5083,7 @@ static bool UNUSED_FUNCTION(draw_mesh_object_new)(const bContext *C, Scene *scen
 		}
 		else {
 			cageDM = editbmesh_get_derived_cage_and_final(
-			        &eval_ctx, scene, ob, em, scene->customdata_mask,
+			        eval_ctx, scene, ob, em, scene->customdata_mask,
 			        &finalDM);
 		}
 
@@ -5102,9 +5102,9 @@ static bool UNUSED_FUNCTION(draw_mesh_object_new)(const bContext *C, Scene *scen
 				DM_update_materials(cageDM, ob);
 			}
 
-			const bool glsl = draw_glsl_material(&eval_ctx, scene, view_layer, ob, v3d, dt);
+			const bool glsl = draw_glsl_material(eval_ctx, scene, eval_ctx->view_layer, ob, v3d, dt);
 
-			GPU_begin_object_materials(v3d, rv3d, scene, view_layer, ob, glsl, eval_ctx.object_mode, NULL);
+			GPU_begin_object_materials(v3d, rv3d, scene, eval_ctx->view_layer, ob, glsl, eval_ctx->object_mode, NULL);
 		}
 
 		draw_em_fancy_new(scene, ar, v3d, ob, me, em, cageDM, finalDM, dt);
@@ -5120,19 +5120,19 @@ static bool UNUSED_FUNCTION(draw_mesh_object_new)(const bContext *C, Scene *scen
 		/* ob->bb was set by derived mesh system, do NULL check just to be sure */
 		if (me->totpoly <= 4 || (!ob->bb || ED_view3d_boundbox_clip(rv3d, ob->bb))) {
 			if (solid) {
-				const bool glsl = draw_glsl_material(&eval_ctx, scene, view_layer, ob, v3d, dt);
+				const bool glsl = draw_glsl_material(eval_ctx, scene, eval_ctx->view_layer, ob, v3d, dt);
 
 				if (dt == OB_SOLID || glsl) {
-					const bool check_alpha = check_alpha_pass(&eval_ctx, base);
+					const bool check_alpha = check_alpha_pass(eval_ctx, base);
 					GPU_begin_object_materials(
-					        v3d, rv3d, scene, view_layer, ob,
-					        eval_ctx.object_mode, glsl, (check_alpha) ? &do_alpha_after : NULL);
+					        v3d, rv3d, scene, eval_ctx->view_layer, ob,
+					        eval_ctx->object_mode, glsl, (check_alpha) ? &do_alpha_after : NULL);
 				}
 			}
 
 			const bool other_obedit = obedit && (obedit != ob);
 
-			draw_mesh_fancy_new(&eval_ctx, scene, view_layer, ar, v3d, rv3d, base, dt, ob_wire_col, dflag, other_obedit);
+			draw_mesh_fancy_new(eval_ctx, scene, eval_ctx->view_layer, ar, v3d, rv3d, base, dt, ob_wire_col, dflag, other_obedit);
 
 			GPU_end_object_materials();
 
@@ -8345,7 +8345,8 @@ static void draw_object_selected_outline(
 	glDepthMask(GL_TRUE);
 }
 
-static void draw_wire_extra(Scene *scene, RegionView3D *rv3d, Object *ob, const unsigned char ob_wire_col[4])
+static void draw_wire_extra(
+        RegionView3D *rv3d, Object *ob, const bool is_obedit, const unsigned char ob_wire_col[4])
 {
 	if (ELEM(ob->type, OB_FONT, OB_CURVE, OB_SURF, OB_MBALL)) {
 		unsigned char wire_edit_col[4];
@@ -8362,13 +8363,13 @@ static void draw_wire_extra(Scene *scene, RegionView3D *rv3d, Object *ob, const
 					drawCurveDMWired(ob);
 				}
 				else {
-					drawDispListwire(&ob->curve_cache->disp, ob->type, (scene->obedit == ob) ? wire_edit_col : ob_wire_col);
+					drawDispListwire(&ob->curve_cache->disp, ob->type, is_obedit ? wire_edit_col : ob_wire_col);
 				}
 			}
 		}
 		else if (ob->type == OB_MBALL) {
 			if (BKE_mball_is_basis(ob)) {
-				drawDispListwire(&ob->curve_cache->disp, ob->type, (scene->obedit == ob) ? wire_edit_col : ob_wire_col);
+				drawDispListwire(&ob->curve_cache->disp, ob->type, is_obedit ? wire_edit_col : ob_wire_col);
 			}
 		}
 
@@ -8447,7 +8448,7 @@ static void draw_rigid_body_pivot(bRigidBodyJointConstraint *data,
 }
 
 void draw_object_wire_color(
-        const EvaluationContext *eval_ctx, Scene *scene, ViewLayer *view_layer,
+        const EvaluationContext *eval_ctx, ViewLayer *view_layer,
         Base *base, unsigned char r_ob_wire_col[4])
 {
 	Object *ob = base->object;
@@ -8460,7 +8461,7 @@ void draw_object_wire_color(
 	int theme_id = is_edit ? TH_WIRE_EDIT : TH_WIRE;
 	int theme_shade = 0;
 
-	if ((scene->obedit == NULL) &&
+	if (((eval_ctx->object_mode & OB_MODE_EDIT) == 0) &&
 	    (G.moving & G_TRANSFORM_OBJ) &&
 	    ((base->flag & BASE_SELECTED) || (base->flag_legacy & BA_WAS_SEL)))
 	{
@@ -8606,13 +8607,15 @@ void draw_object(
 	const unsigned char *ob_wire_col = NULL;  /* dont initialize this, use NULL crashes as a way to find invalid use */
 	bool zbufoff = false, is_paint = false, empty_object = false;
 	const bool is_obact = (ob == OBACT(view_layer));
+	/* this could be moved to a 'dflag'. */
+	const bool is_obedit = (is_obact && (ob == OBEDIT_FROM_EVAL_CTX(eval_ctx)));
 	const bool render_override = (v3d->flag2 & V3D_RENDER_OVERRIDE) != 0;
 	const bool is_picking = (G.f & G_PICKSEL) != 0;
 	const bool has_particles = (ob->particlesystem.first != NULL);
 	bool skip_object = false;  /* Draw particles but not their emitter object. */
 	SmokeModifierData *smd = NULL;
 
-	if (ob != scene->obedit) {
+	if (is_obedit == false) {
 		if (ob->restrictflag & OB_RESTRICT_VIEW)
 			return;
 		
@@ -8722,7 +8725,7 @@ void draw_object(
 
 		ED_view3d_project_base(ar, base);
 
-		draw_object_wire_color(eval_ctx, scene, view_layer, base, _ob_wire_col);
+		draw_object_wire_color(eval_ctx, view_layer, base, _ob_wire_col);
 		ob_wire_col = _ob_wire_col;
 
 		//glColor3ubv(ob_wire_col);
@@ -8956,7 +8959,7 @@ afterdraw:
 
 	/* code for new particle system */
 	if ((ob->particlesystem.first) &&
-	    (ob != scene->obedit))
+	    (is_obedit == false))
 	{
 		ParticleSystem *psys;
 
@@ -8986,7 +8989,7 @@ afterdraw:
 
 	/* draw edit particles last so that they can draw over child particles */
 	if ((dflag & DRAW_PICKING) == 0 &&
-	    (!scene->obedit))
+	    (is_obedit == false))
 	{
 
 		if (eval_ctx->object_mode & OB_MODE_PARTICLE_EDIT && is_obact) {
@@ -9135,7 +9138,7 @@ afterdraw:
 			}
 			if ((dtx & OB_DRAWWIRE) && dt >= OB_SOLID) {
 				if ((dflag & DRAW_CONSTCOLOR) == 0) {
-					draw_wire_extra(scene, rv3d, ob, ob_wire_col);
+					draw_wire_extra(rv3d, ob, is_obedit, ob_wire_col);
 				}
 			}
 		}
@@ -9239,11 +9242,11 @@ afterdraw:
 		immUniformColor3ubv(ob_wire_col);
 
 		/* draw hook center and offset line */
-		if (ob != scene->obedit)
+		if (is_obedit == false)
 			draw_hooks(ob, pos);
 
 		/* help lines and so */
-		if (ob != scene->obedit && ob->parent) {
+		if ((is_obedit == false) && ob->parent) {
 			const eObjectVisibilityCheck mode = eval_ctx->mode != DAG_EVAL_VIEWPORT ?
 			                                                 OB_VISIBILITY_CHECK_FOR_RENDER :
 			                                                 OB_VISIBILITY_CHECK_FOR_VIEWPORT;
diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c
index 2f2e0db8c7a25d00cac36f704ae072550f3d103b..b1a37211eab1d03481e752ddb957b641f5f40438 100644
--- a/source/blender/editors/space_view3d/space_view3d.c
+++ b/source/blender/editors/space_view3d/space_view3d.c
@@ -915,10 +915,10 @@ static void view3d_main_region_listener(
 				case ND_SELECT:
 				{
 					WM_manipulatormap_tag_refresh(mmap);
-					if (scene->obedit) {
-						Object *ob = scene->obedit;
+					Object *obedit = OBEDIT_FROM_WINDOW(wmn->window);
+					if (obedit) {
 						/* TODO(sergey): Notifiers shouldn't really be doing DEG tags. */
-						DEG_id_tag_update((ID *)ob->data, DEG_TAG_SELECT_UPDATE);
+						DEG_id_tag_update((ID *)obedit->data, DEG_TAG_SELECT_UPDATE);
 					}
 					ATTR_FALLTHROUGH;
 				}
@@ -1132,9 +1132,8 @@ static void view3d_main_region_message_subscribe(
 /* concept is to retrieve cursor type context-less */
 static void view3d_main_region_cursor(wmWindow *win, ScrArea *UNUSED(sa), ARegion *UNUSED(ar))
 {
-	const Scene *scene = WM_window_get_active_scene(win);
-
-	if (scene->obedit) {
+	WorkSpace *workspace = WM_window_get_active_workspace(win);
+	if (workspace->object_mode) {
 		WM_cursor_set(win, CURSOR_EDIT);
 	}
 	else {
diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c
index 7ce1978dca2c4eca57d6d2ab1596b7030a4708eb..f96dead513c9d55cd6842cfe5980ba455592e307 100644
--- a/source/blender/editors/space_view3d/view3d_draw.c
+++ b/source/blender/editors/space_view3d/view3d_draw.c
@@ -99,15 +99,15 @@
 
 /* ******************** general functions ***************** */
 
-static bool use_depth_doit(Scene *scene, View3D *v3d)
+static bool use_depth_doit(View3D *v3d, Object *obedit)
 {
 	if (v3d->drawtype > OB_WIRE)
 		return true;
 
 	/* special case (depth for wire color) */
 	if (v3d->drawtype <= OB_WIRE) {
-		if (scene->obedit && scene->obedit->type == OB_MESH) {
-			Mesh *me = scene->obedit->data;
+		if (obedit && obedit->type == OB_MESH) {
+			Mesh *me = obedit->data;
 			if (me->drawflag & ME_DRAWEIGHT) {
 				return true;
 			}
@@ -2406,9 +2406,9 @@ void VP_legacy_view3d_stereo3d_setup(const EvaluationContext *eval_ctx, Scene *s
 	view3d_stereo3d_setup(eval_ctx, scene, v3d, ar, NULL);
 }
 
-bool VP_legacy_use_depth(Scene *scene, View3D *v3d)
+bool VP_legacy_use_depth(View3D *v3d, Object *obedit)
 {
-	return use_depth_doit(scene, v3d);
+	return use_depth_doit(v3d, obedit);
 }
 
 void VP_drawviewborder(Scene *scene, const struct Depsgraph *depsgraph, ARegion *ar, View3D *v3d)
diff --git a/source/blender/editors/space_view3d/view3d_draw_legacy.c b/source/blender/editors/space_view3d/view3d_draw_legacy.c
index 0b85ac477812f15a2846af2900891e4586725a8d..0c87250600a34d2173215fce2ca849ba8d8b7892 100644
--- a/source/blender/editors/space_view3d/view3d_draw_legacy.c
+++ b/source/blender/editors/space_view3d/view3d_draw_legacy.c
@@ -237,7 +237,7 @@ static void backdrawview3d(
 	{
 		/* do nothing */
 	}
-	else if (scene->obedit &&
+	else if ((eval_ctx->object_mode & OB_MODE_POSE) &&
 	         V3D_IS_ZBUF(v3d))
 	{
 		/* do nothing */
@@ -1304,7 +1304,7 @@ void ED_view3d_draw_select_loop(
 		for (base = view_layer->object_bases.first; base; base = base->next) {
 			if ((base->flag & BASE_VISIBLED) != 0) {
 				if (((base->flag & BASE_SELECTABLED) == 0) ||
-				    (use_obedit_skip && (scene->obedit->data == base->object->data)))
+				    (use_obedit_skip && (vc->obedit->data == base->object->data)))
 				{
 					base->object->select_color = 0;
 				}
@@ -1508,6 +1508,7 @@ static void view3d_draw_objects(
 	Depsgraph *depsgraph = CTX_data_depsgraph(C);
 	RegionView3D *rv3d = ar->regiondata;
 	Base *base;
+	Object *obedit = OBEDIT_FROM_EVAL_CTX(eval_ctx);
 	const bool do_camera_frame = !draw_offscreen;
 	const bool draw_grids = !draw_offscreen && (v3d->flag2 & V3D_RENDER_OVERRIDE) == 0;
 	const bool draw_floor = (rv3d->view == RV3D_VIEW_USER) || (rv3d->persp != RV3D_ORTHO);
@@ -1524,7 +1525,7 @@ static void view3d_draw_objects(
 		view3d_draw_clipping(rv3d);
 
 	/* set zbuffer after we draw clipping region */
-	v3d->zbuf = VP_legacy_use_depth(scene, v3d);
+	v3d->zbuf = VP_legacy_use_depth(v3d, obedit);
 
 	if (v3d->zbuf) {
 		glEnable(GL_DEPTH_TEST);
@@ -1601,7 +1602,7 @@ static void view3d_draw_objects(
 					draw_dupli_objects(eval_ctx, scene, view_layer, ar, v3d, base);
 				}
 				if ((base->flag & BASE_SELECTED) == 0) {
-					if (base->object != scene->obedit)
+					if (base->object != obedit)
 						draw_object(eval_ctx, scene, view_layer, ar, v3d, base, 0);
 				}
 			}
@@ -1613,7 +1614,7 @@ static void view3d_draw_objects(
 		/* draw selected and editmode */
 		for (base = view_layer->object_bases.first; base; base = base->next) {
 			if ((base->flag & BASE_VISIBLED) != 0) {
-				if (base->object == scene->obedit || (base->flag & BASE_SELECTED)) {
+				if (base->object == obedit || (base->flag & BASE_SELECTED)) {
 					draw_object(eval_ctx, scene, view_layer, ar, v3d, base, 0);
 				}
 			}
diff --git a/source/blender/editors/space_view3d/view3d_header.c b/source/blender/editors/space_view3d/view3d_header.c
index 5f38cbddce061ea49bf0cb0da7b870b21f44d52a..bf4abf1852ddd9a7eb340fa469488ce195e57e19 100644
--- a/source/blender/editors/space_view3d/view3d_header.c
+++ b/source/blender/editors/space_view3d/view3d_header.c
@@ -95,14 +95,14 @@ static void handle_view3d_lock(bContext *C)
  * - uiTemplateLayers in interface/ code for buttons
  * - ED_view3d_view_layer_set for RNA
  */
-static void view3d_layers_editmode_ensure(Scene *scene, View3D *v3d)
+static void view3d_layers_editmode_ensure(View3D *v3d, Object *obedit)
 {
 	/* sanity check - when in editmode disallow switching the editmode layer off since its confusing
 	 * an alternative would be to always draw the editmode object. */
-	if (scene->obedit && (scene->obedit->lay & v3d->lay) == 0) {
+	if (obedit && (obedit->lay & v3d->lay) == 0) {
 		int bit;
 		for (bit = 0; bit < 32; bit++) {
-			if (scene->obedit->lay & (1u << bit)) {
+			if (obedit->lay & (1u << bit)) {
 				v3d->lay |= (1u << bit);
 				break;
 			}
@@ -112,9 +112,9 @@ static void view3d_layers_editmode_ensure(Scene *scene, View3D *v3d)
 
 static int view3d_layers_exec(bContext *C, wmOperator *op)
 {
-	Scene *scene = CTX_data_scene(C);
 	ScrArea *sa = CTX_wm_area(C);
 	View3D *v3d = sa->spacedata.first;
+	Object *obedit = CTX_data_edit_object(C);
 	int nr = RNA_int_get(op->ptr, "nr");
 	const bool toggle = RNA_boolean_get(op->ptr, "toggle");
 	
@@ -130,7 +130,7 @@ static int view3d_layers_exec(bContext *C, wmOperator *op)
 			/* return to active layer only */
 			v3d->lay = v3d->lay_prev;
 
-			view3d_layers_editmode_ensure(scene, v3d);
+			view3d_layers_editmode_ensure(v3d, obedit);
 		}
 		else {
 			v3d->lay_prev = v3d->lay;
@@ -151,7 +151,7 @@ static int view3d_layers_exec(bContext *C, wmOperator *op)
 			v3d->lay = (1 << nr);
 		}
 
-		view3d_layers_editmode_ensure(scene, v3d);
+		view3d_layers_editmode_ensure(v3d, obedit);
 
 		/* set active layer, ensure to always have one */
 		if (v3d->lay & (1 << nr))
diff --git a/source/blender/editors/space_view3d/view3d_intern.h b/source/blender/editors/space_view3d/view3d_intern.h
index 0b913ad179d177fdc72e0e01b4729ab4e3ea6ee7..0eb7a964fdf44589d8fbbb18947fff9eb8247000 100644
--- a/source/blender/editors/space_view3d/view3d_intern.h
+++ b/source/blender/editors/space_view3d/view3d_intern.h
@@ -166,7 +166,7 @@ void draw_object_instance(const struct EvaluationContext *eval_ctx, Scene *scene
 void draw_object_backbufsel(const struct EvaluationContext *eval_ctx, Scene *scene, View3D *v3d, RegionView3D *rv3d, struct Object *ob);
 
 void draw_object_wire_color(
-        const struct EvaluationContext *eval_ctx, Scene *scene, struct ViewLayer *,
+        const struct EvaluationContext *eval_ctx, 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,
@@ -388,7 +388,7 @@ void VP_legacy_view3d_main_region_setup_view(const struct EvaluationContext *eva
 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);
+bool VP_legacy_use_depth(View3D *v3d, struct Object *obedit);
 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);
diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c
index 89a033236f190184605bfa9e6186ca5c1a21686f..27625a02daa435b2eeb3135dcb305548585c1b9b 100644
--- a/source/blender/editors/space_view3d/view3d_select.c
+++ b/source/blender/editors/space_view3d/view3d_select.c
@@ -1549,7 +1549,7 @@ static bool ed_object_select_pick(
 					}
 				}
 				else if (ED_do_pose_selectbuffer(
-				                 &eval_ctx, scene, view_layer,
+				                 &eval_ctx, view_layer,
 				                 basact, buffer, hits, extend, deselect, toggle, do_nearest))
 				{
 					/* then bone is found */
diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c
index a0918066887f78fa1a150e464b30c0e59b78004e..89b65944ba6e4ec647a3b6d00d659a2cb32eca96 100644
--- a/source/blender/editors/space_view3d/view3d_view.c
+++ b/source/blender/editors/space_view3d/view3d_view.c
@@ -879,7 +879,7 @@ int view3d_opengl_select(
 	ARegion *ar = vc->ar;
 	rcti rect;
 	int hits;
-	const bool use_obedit_skip = (scene->obedit != NULL) && (vc->obedit == NULL);
+	const bool use_obedit_skip = (OBEDIT_FROM_EVAL_CTX(eval_ctx)) && (vc->obedit == NULL);
 	const bool is_pick_select = (U.gpu_select_pick_deph != 0);
 	const bool do_passes = (
 	        (is_pick_select == false) &&
diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c
index 63df39c7d6e1418990915d10b4705e24998a4279..96970fa8a0ffabc423c1e59d3b2a6d0848dfd520 100644
--- a/source/blender/editors/transform/transform_conversions.c
+++ b/source/blender/editors/transform/transform_conversions.c
@@ -2969,7 +2969,7 @@ static void createTransUVs(bContext *C, TransInfo *t)
 	BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
 		BMLoop *l;
 
-		if (!uvedit_face_visible_test(scene, ima, efa)) {
+		if (!uvedit_face_visible_test(scene, t->obedit, ima, efa)) {
 			BM_elem_flag_disable(efa, BM_ELEM_TAG);
 			continue;
 		}
diff --git a/source/blender/editors/transform/transform_manipulator.c b/source/blender/editors/transform/transform_manipulator.c
index 459727ad531b1322742ac65b4d5fbba88916dad5..44a7bb92c3e1fb658c36cfb014ecdd787534561b 100644
--- a/source/blender/editors/transform/transform_manipulator.c
+++ b/source/blender/editors/transform/transform_manipulator.c
@@ -1069,7 +1069,7 @@ static void manipulator_prepare_mat(
 			bGPdata *gpd = CTX_data_gpencil_data(C);
 			Object *ob = OBACT(view_layer);
 
-			if (((v3d->around == V3D_AROUND_ACTIVE) && (scene->obedit == NULL)) &&
+			if (((v3d->around == V3D_AROUND_ACTIVE) && (workspace->object_mode & OB_MODE_EDIT)) &&
 			    ((gpd == NULL) || !(gpd->flag & GP_DATA_STROKE_EDITMODE)) &&
 			    (!(workspace->object_mode & OB_MODE_POSE)))
 			{
diff --git a/source/blender/editors/transform/transform_manipulator2d.c b/source/blender/editors/transform/transform_manipulator2d.c
index 6e2d0d8c5c0077fa188f1cbaa291926956da8b85..9b6dd187c157451c16ed92daab58ef02089dd35a 100644
--- a/source/blender/editors/transform/transform_manipulator2d.c
+++ b/source/blender/editors/transform/transform_manipulator2d.c
@@ -368,7 +368,7 @@ bool ED_widgetgroup_manipulator2d_poll(const bContext *C, wmManipulatorGroupType
 
 		/* check if there's a selected poly */
 		BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
-			if (!uvedit_face_visible_test(scene, ima, efa))
+			if (!uvedit_face_visible_test(scene, obedit, ima, efa))
 				continue;
 
 			BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
diff --git a/source/blender/editors/transform/transform_ops.c b/source/blender/editors/transform/transform_ops.c
index ab0e24671ebc895c833faa0cd235751514009855..d5d25888ec8b1c6a842ccdb24436c525adf3740a 100644
--- a/source/blender/editors/transform/transform_ops.c
+++ b/source/blender/editors/transform/transform_ops.c
@@ -316,7 +316,8 @@ static void transformops_loopsel_hack(bContext *C, wmOperator *op)
 
 				/* still switch if we were originally in face select mode */
 				if ((ts->selectmode != selectmode_orig) && (selectmode_orig != SCE_SELECT_FACE)) {
-					BMEditMesh *em = BKE_editmesh_from_object(scene->obedit);
+					Object *obedit = CTX_data_edit_object(C);
+					BMEditMesh *em = BKE_editmesh_from_object(obedit);
 					em->selectmode = ts->selectmode = selectmode_orig;
 					EDBM_selectmode_set(em);
 				}
diff --git a/source/blender/editors/transform/transform_snap_object.c b/source/blender/editors/transform/transform_snap_object.c
index 82da9991dda81df8e6feea6e9d6f1d86cf85784f..14cd4bcc7ac34cb9853f7e3102691ae3f595f1da 100644
--- a/source/blender/editors/transform/transform_snap_object.c
+++ b/source/blender/editors/transform/transform_snap_object.c
@@ -822,7 +822,7 @@ static bool raycastObjects(
         Object **r_ob, float r_obmat[4][4],
         ListBase *r_hit_list)
 {
-	Object *obedit = use_object_edit_cage ? sctx->scene->obedit : NULL;
+	Object *obedit = use_object_edit_cage ? OBEDIT_FROM_EVAL_CTX(&sctx->eval_ctx) : NULL;
 
 	struct RaycastObjUserData data = {
 		.ray_start = ray_start,
@@ -2060,7 +2060,7 @@ static bool snapObjectsRay(
         float r_loc[3], float r_no[3],
         Object **r_ob, float r_obmat[4][4])
 {
-	Object *obedit = use_object_edit_cage ? sctx->scene->obedit : NULL;
+	Object *obedit = use_object_edit_cage ? OBEDIT_FROM_EVAL_CTX(&sctx->eval_ctx) : NULL;
 
 	struct SnapObjUserData data = {
 		.snapdata = snapdata,
diff --git a/source/blender/editors/util/ed_util.c b/source/blender/editors/util/ed_util.c
index 02443af0bfcc11d8dd6f5db9e4073ce5e5a6d583..a5a26cf4d57abdd21173f1f5075dc50d8b75f3b5 100644
--- a/source/blender/editors/util/ed_util.c
+++ b/source/blender/editors/util/ed_util.c
@@ -35,6 +35,7 @@
 
 #include "MEM_guardedalloc.h"
 
+#include "DNA_armature_types.h"
 #include "DNA_mesh_types.h"
 #include "DNA_object_types.h"
 #include "DNA_screen_types.h"
@@ -109,7 +110,6 @@ void ED_editors_init(bContext *C)
 void ED_editors_exit(bContext *C)
 {
 	Main *bmain = CTX_data_main(C);
-	Scene *sce;
 
 	if (!bmain)
 		return;
@@ -117,23 +117,20 @@ void ED_editors_exit(bContext *C)
 	/* frees all editmode undos */
 	undo_editmode_clear();
 	ED_undo_paint_free();
-	
-	for (sce = bmain->scene.first; sce; sce = sce->id.next) {
-		if (sce->obedit) {
-			Object *ob = sce->obedit;
-		
-			if (ob) {
-				if (ob->type == OB_MESH) {
-					Mesh *me = ob->data;
-					if (me->edit_btmesh) {
-						EDBM_mesh_free(me->edit_btmesh);
-						MEM_freeN(me->edit_btmesh);
-						me->edit_btmesh = NULL;
-					}
-				}
-				else if (ob->type == OB_ARMATURE) {
-					ED_armature_edit_free(ob->data);
-				}
+
+	for (Object *ob = bmain->object.first; ob; ob = ob->id.next) {
+		if (ob->type == OB_MESH) {
+			Mesh *me = ob->data;
+			if (me->edit_btmesh) {
+				EDBM_mesh_free(me->edit_btmesh);
+				MEM_freeN(me->edit_btmesh);
+				me->edit_btmesh = NULL;
+			}
+		}
+		else if (ob->type == OB_ARMATURE) {
+			bArmature *arm = ob->data;
+			if (arm->edbo) {
+				ED_armature_edit_free(ob->data);
 			}
 		}
 	}
diff --git a/source/blender/editors/uvedit/uvedit_buttons.c b/source/blender/editors/uvedit/uvedit_buttons.c
index 6b4dd0f0210baef0eef257cfb76a70bf7b22bad8..f037783bd5e1f75abcb24c9d0309b1d24c7fb891 100644
--- a/source/blender/editors/uvedit/uvedit_buttons.c
+++ b/source/blender/editors/uvedit/uvedit_buttons.c
@@ -61,7 +61,7 @@
 
 /* UV Utilities */
 
-static int uvedit_center(Scene *scene, BMEditMesh *em, Image *ima, float center[2])
+static int uvedit_center(Scene *scene, Object *obedit, BMEditMesh *em, Image *ima, float center[2])
 {
 	BMFace *f;
 	BMLoop *l;
@@ -73,7 +73,7 @@ static int uvedit_center(Scene *scene, BMEditMesh *em, Image *ima, float center[
 	
 	zero_v2(center);
 	BM_ITER_MESH (f, &iter, em->bm, BM_FACES_OF_MESH) {
-		if (!uvedit_face_visible_test(scene, ima, f))
+		if (!uvedit_face_visible_test(scene, obedit, ima, f))
 			continue;
 
 		BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
@@ -93,7 +93,7 @@ static int uvedit_center(Scene *scene, BMEditMesh *em, Image *ima, float center[
 	return tot;
 }
 
-static void uvedit_translate(Scene *scene, BMEditMesh *em, Image *ima, float delta[2])
+static void uvedit_translate(Scene *scene, Object *obedit, BMEditMesh *em, Image *ima, float delta[2])
 {
 	BMFace *f;
 	BMLoop *l;
@@ -103,7 +103,7 @@ static void uvedit_translate(Scene *scene, BMEditMesh *em, Image *ima, float del
 	const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
 	
 	BM_ITER_MESH (f, &iter, em->bm, BM_FACES_OF_MESH) {
-		if (!uvedit_face_visible_test(scene, ima, f))
+		if (!uvedit_face_visible_test(scene, obedit, ima, f))
 			continue;
 
 		BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
@@ -134,7 +134,7 @@ static void uvedit_vertex_buttons(const bContext *C, uiBlock *block)
 	
 	em = BKE_editmesh_from_object(obedit);
 
-	if (uvedit_center(scene, em, ima, center)) {
+	if (uvedit_center(scene, obedit, em, ima, center)) {
 		float range_xy[2][2] = {
 		    {-10.0f, 10.0f},
 		    {-10.0f, 10.0f},
@@ -190,7 +190,7 @@ static void do_uvedit_vertex(bContext *C, void *UNUSED(arg), int event)
 	em = BKE_editmesh_from_object(obedit);
 
 	ED_space_image_get_size(sima, &imx, &imy);
-	uvedit_center(scene, em, ima, center);
+	uvedit_center(scene, obedit, em, ima, center);
 
 	if (sima->flag & SI_COORDFLOATS) {
 		delta[0] = uvedit_old_center[0] - center[0];
@@ -201,7 +201,7 @@ static void do_uvedit_vertex(bContext *C, void *UNUSED(arg), int event)
 		delta[1] = uvedit_old_center[1] / imy - center[1];
 	}
 
-	uvedit_translate(scene, em, ima, delta);
+	uvedit_translate(scene, obedit, em, ima, delta);
 
 	WM_event_add_notifier(C, NC_IMAGE, sima->image);
 }
diff --git a/source/blender/editors/uvedit/uvedit_draw.c b/source/blender/editors/uvedit/uvedit_draw.c
index 6a8d13574f3d36868d09828bc854055b58541c9a..c375cd2e62222e9de6c97d04c978d586036d4691 100644
--- a/source/blender/editors/uvedit/uvedit_draw.c
+++ b/source/blender/editors/uvedit/uvedit_draw.c
@@ -179,7 +179,7 @@ static void draw_uvs_shadow(Object *obedit)
 	immUnbindProgram();
 }
 
-static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, BMEditMesh *em, const BMFace *efa_act)
+static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, Object *obedit, BMEditMesh *em, const BMFace *efa_act)
 {
 	BMesh *bm = em->bm;
 	BMFace *efa;
@@ -217,7 +217,7 @@ static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, BMEditMesh *em, con
 				totarea += BM_face_calc_area(efa);
 				totuvarea += area_poly_v2(tf_uv, efa->len);
 				
-				if (uvedit_face_visible_test(scene, ima, efa)) {
+				if (uvedit_face_visible_test(scene, obedit, ima, efa)) {
 					BM_elem_flag_enable(efa, BM_ELEM_TAG);
 				}
 				else {
@@ -314,7 +314,7 @@ static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, BMEditMesh *em, con
 			immBindBuiltinProgram(GPU_SHADER_2D_SMOOTH_COLOR);
 
 			BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
-				if (uvedit_face_visible_test(scene, ima, efa)) {
+				if (uvedit_face_visible_test(scene, obedit, ima, efa)) {
 					const int efa_len = efa->len;
 					float (*tf_uv)[2]     = (float (*)[2])BLI_buffer_reinit_data(&tf_uv_buf,     vec2f, efa_len);
 					float (*tf_uvorig)[2] = (float (*)[2])BLI_buffer_reinit_data(&tf_uvorig_buf, vec2f, efa_len);
@@ -669,12 +669,12 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, ViewLayer *view_layer, Obje
 	/* 2. draw colored faces */
 	
 	if (sima->flag & SI_DRAW_STRETCH) {
-		draw_uvs_stretch(sima, scene, em, efa_act);
+		draw_uvs_stretch(sima, scene, obedit, em, efa_act);
 	}
 	else {
 		unsigned int tri_count = 0;
 		BM_ITER_MESH(efa, &iter, bm, BM_FACES_OF_MESH) {
-			if (uvedit_face_visible_test(scene, ima, efa)) {
+			if (uvedit_face_visible_test(scene, obedit, ima, efa)) {
 				BM_elem_flag_enable(efa, BM_ELEM_TAG);
 				tri_count += efa->len - 2;
 			}
@@ -722,7 +722,7 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, ViewLayer *view_layer, Obje
 			glDisable(GL_BLEND);
 		}
 		else {
-			if (efa_act && !uvedit_face_visible_test(scene, ima, efa_act)) {
+			if (efa_act && !uvedit_face_visible_test(scene, obedit, ima, efa_act)) {
 				efa_act = NULL;
 			}
 		}
diff --git a/source/blender/editors/uvedit/uvedit_intern.h b/source/blender/editors/uvedit/uvedit_intern.h
index 6ca469414044ce31bdeefe15a73876c53c6f2320..eb92f17544f985ac57d97035181a3c3fac7cbd48 100644
--- a/source/blender/editors/uvedit/uvedit_intern.h
+++ b/source/blender/editors/uvedit/uvedit_intern.h
@@ -57,10 +57,12 @@ typedef struct NearestHit {
 	int lindex;  /* index of loop within face */
 } NearestHit;
 
-void uv_find_nearest_vert(struct Scene *scene, struct Image *ima, struct BMEditMesh *em,
-                          const float co[2], const float penalty[2], struct NearestHit *hit);
-void uv_find_nearest_edge(struct Scene *scene, struct Image *ima, struct BMEditMesh *em,
-                          const float co[2], struct NearestHit *hit);
+void uv_find_nearest_vert(
+        struct Scene *scene, struct Image *ima, struct Object *obedit, struct BMEditMesh *em,
+        const float co[2], const float penalty[2], struct NearestHit *hit);
+void uv_find_nearest_edge(
+        struct Scene *scene, struct Image *ima, struct Object *obedit, struct BMEditMesh *em,
+        const float co[2], struct NearestHit *hit);
 
 /* utility tool functions */
 
diff --git a/source/blender/editors/uvedit/uvedit_ops.c b/source/blender/editors/uvedit/uvedit_ops.c
index 479b43d50f0f247ca8268a64ae49c02926bff88a..63f82c2b422664751dbde0a6762b8c350bdbdf89 100644
--- a/source/blender/editors/uvedit/uvedit_ops.c
+++ b/source/blender/editors/uvedit/uvedit_ops.c
@@ -89,7 +89,7 @@
 
 #include "uvedit_intern.h"
 
-static void uv_select_all_perform(Scene *scene, Image *ima, BMEditMesh *em, int action);
+static void uv_select_all_perform(Scene *scene, Image *ima, Object *obedit, BMEditMesh *em, int action);
 static void uv_select_flush_from_tag_face(SpaceImage *sima, Scene *scene, Object *obedit, const bool select);
 static void uv_select_flush_from_tag_loop(SpaceImage *sima, Scene *scene, Object *obedit, const bool select);
 
@@ -230,7 +230,7 @@ void ED_uvedit_assign_image(Main *UNUSED(bmain), Scene *scene, Object *obedit, I
 
 		/* now assign to all visible faces */
 		BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
-			if (uvedit_face_visible_test(scene, previma, efa) &&
+			if (uvedit_face_visible_test(scene, obedit, previma, efa) &&
 			    (selected == true || uvedit_face_select_test(scene, efa, cd_loop_uv_offset)))
 			{
 #ifdef USE_SWITCH_ASPECT
@@ -296,12 +296,12 @@ bool uvedit_face_visible_nolocal(Scene *scene, BMFace *efa)
 		return (BM_elem_flag_test(efa, BM_ELEM_HIDDEN) == 0 && BM_elem_flag_test(efa, BM_ELEM_SELECT));
 }
 
-bool uvedit_face_visible_test(Scene *scene, Image *ima, BMFace *efa)
+bool uvedit_face_visible_test(Scene *scene, Object *obedit, Image *ima, BMFace *efa)
 {
 	ToolSettings *ts = scene->toolsettings;
 
 	if (ts->uv_flag & UV_SHOW_SAME_IMAGE) {
-		const Image *face_image = BKE_object_material_edit_image_get(scene->obedit, efa->mat_nr);
+		const Image *face_image = BKE_object_material_edit_image_get(obedit, efa->mat_nr);
 		return (face_image == ima) ? uvedit_face_visible_nolocal(scene, efa) : false;
 	}
 	else {
@@ -607,7 +607,7 @@ bool ED_uvedit_minmax(Scene *scene, Image *ima, Object *obedit, float r_min[2],
 	INIT_MINMAX2(r_min, r_max);
 
 	BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
-		if (!uvedit_face_visible_test(scene, ima, efa))
+		if (!uvedit_face_visible_test(scene, obedit, ima, efa))
 			continue;
 		
 		BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
@@ -653,7 +653,7 @@ static bool ED_uvedit_median(Scene *scene, Image *ima, Object *obedit, float co[
 
 	zero_v2(co);
 	BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
-		if (!uvedit_face_visible_test(scene, ima, efa))
+		if (!uvedit_face_visible_test(scene, obedit, ima, efa))
 			continue;
 		
 		BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
@@ -692,7 +692,7 @@ bool ED_uvedit_center(Scene *scene, Image *ima, Object *obedit, float cent[2], c
 
 /************************** find nearest ****************************/
 
-void uv_find_nearest_edge(Scene *scene, Image *ima, BMEditMesh *em, const float co[2], NearestHit *hit)
+void uv_find_nearest_edge(Scene *scene, Image *ima, Object *obedit, BMEditMesh *em, const float co[2], NearestHit *hit)
 {
 	BMFace *efa;
 	BMLoop *l;
@@ -709,7 +709,7 @@ void uv_find_nearest_edge(Scene *scene, Image *ima, BMEditMesh *em, const float
 	BM_mesh_elem_index_ensure(em->bm, BM_VERT);
 	
 	BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
-		if (!uvedit_face_visible_test(scene, ima, efa))
+		if (!uvedit_face_visible_test(scene, obedit, ima, efa))
 			continue;
 		
 		BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) {
@@ -732,7 +732,8 @@ void uv_find_nearest_edge(Scene *scene, Image *ima, BMEditMesh *em, const float
 	}
 }
 
-static void uv_find_nearest_face(Scene *scene, Image *ima, BMEditMesh *em, const float co[2], NearestHit *hit)
+static void uv_find_nearest_face(
+        Scene *scene, Image *ima, Object *obedit, BMEditMesh *em, const float co[2], NearestHit *hit)
 {
 	BMFace *efa;
 	BMIter iter;
@@ -744,12 +745,12 @@ static void uv_find_nearest_face(Scene *scene, Image *ima, BMEditMesh *em, const
 	memset(hit, 0, sizeof(*hit));
 
 	/*this will fill in hit.vert1 and hit.vert2*/
-	uv_find_nearest_edge(scene, ima, em, co, hit);
+	uv_find_nearest_edge(scene, ima, obedit, em, co, hit);
 	hit->l = NULL;
 	hit->luv = hit->luv_next = NULL;
 
 	BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
-		if (!uvedit_face_visible_test(scene, ima, efa))
+		if (!uvedit_face_visible_test(scene, obedit, ima, efa))
 			continue;
 
 		uv_poly_center(efa, cent, cd_loop_uv_offset);
@@ -774,8 +775,9 @@ static bool uv_nearest_between(const BMLoop *l, const float co[2],
 	        (line_point_side_v2(uv_next, uv_curr, co) <= 0.0f));
 }
 
-void uv_find_nearest_vert(Scene *scene, Image *ima, BMEditMesh *em,
-                          float const co[2], const float penalty[2], NearestHit *hit)
+void uv_find_nearest_vert(
+        Scene *scene, Image *ima, Object *obedit, BMEditMesh *em,
+        float const co[2], const float penalty[2], NearestHit *hit)
 {
 	BMFace *efa;
 	BMLoop *l;
@@ -787,7 +789,7 @@ void uv_find_nearest_vert(Scene *scene, Image *ima, BMEditMesh *em,
 	const int cd_loop_uv_offset  = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
 
 	/*this will fill in hit.vert1 and hit.vert2*/
-	uv_find_nearest_edge(scene, ima, em, co, hit);
+	uv_find_nearest_edge(scene, ima, obedit, em, co, hit);
 	hit->l = NULL;
 	hit->luv = hit->luv_next = NULL;
 
@@ -797,7 +799,7 @@ void uv_find_nearest_vert(Scene *scene, Image *ima, BMEditMesh *em,
 	BM_mesh_elem_index_ensure(em->bm, BM_VERT);
 
 	BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
-		if (!uvedit_face_visible_test(scene, ima, efa))
+		if (!uvedit_face_visible_test(scene, obedit, ima, efa))
 			continue;
 
 		BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) {
@@ -842,7 +844,7 @@ bool ED_uvedit_nearest_uv(Scene *scene, Object *obedit, Image *ima, const float
 	copy_v2_v2(r_uv, co);
 	
 	BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
-		if (!uvedit_face_visible_test(scene, ima, efa))
+		if (!uvedit_face_visible_test(scene, obedit, ima, efa))
 			continue;
 		
 		BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
@@ -946,8 +948,9 @@ static bool uv_select_edgeloop_edge_tag_faces(BMEditMesh *em, UvMapVert *first1,
 	return true;
 }
 
-static int uv_select_edgeloop(Scene *scene, Image *ima, BMEditMesh *em, NearestHit *hit,
-                              const float limit[2], const bool extend)
+static int uv_select_edgeloop(
+        Scene *scene, Image *ima, Object *obedit, BMEditMesh *em, NearestHit *hit,
+        const float limit[2], const bool extend)
 {
 	BMFace *efa;
 	BMIter iter, liter;
@@ -967,7 +970,7 @@ static int uv_select_edgeloop(Scene *scene, Image *ima, BMEditMesh *em, NearestH
 	BM_mesh_elem_index_ensure(em->bm, BM_VERT | BM_FACE);
 
 	if (!extend) {
-		uv_select_all_perform(scene, ima, em, SEL_DESELECT);
+		uv_select_all_perform(scene, ima, obedit, em, SEL_DESELECT);
 	}
 
 	BM_mesh_elem_hflag_disable_all(em->bm, BM_FACE, BM_ELEM_TAG, false);
@@ -991,7 +994,7 @@ static int uv_select_edgeloop(Scene *scene, Image *ima, BMEditMesh *em, NearestH
 		/* find correct valence edges which are not tagged yet, but connect to tagged one */
 
 		BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
-			if (!BM_elem_flag_test(efa, BM_ELEM_TAG) && uvedit_face_visible_test(scene, ima, efa)) {
+			if (!BM_elem_flag_test(efa, BM_ELEM_TAG) && uvedit_face_visible_test(scene, obedit, ima, efa)) {
 				BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
 					/* check face not hidden and not tagged */
 					if (!(iterv_curr = uv_select_edgeloop_vertex_map_get(vmap, efa, l)))
@@ -1046,7 +1049,9 @@ static int uv_select_edgeloop(Scene *scene, Image *ima, BMEditMesh *em, NearestH
 
 /*********************** linked select ***********************/
 
-static void uv_select_linked(Scene *scene, Image *ima, BMEditMesh *em, const float limit[2], NearestHit *hit, bool extend, bool select_faces)
+static void uv_select_linked(
+        Scene *scene, Image *ima, Object *obedit, BMEditMesh *em,
+        const float limit[2], NearestHit *hit, bool extend, bool select_faces)
 {
 	BMFace *efa;
 	BMLoop *l;
@@ -1078,7 +1083,7 @@ static void uv_select_linked(Scene *scene, Image *ima, BMEditMesh *em, const flo
 
 	if (!hit) {
 		BM_ITER_MESH_INDEX (efa, &iter, em->bm, BM_FACES_OF_MESH, a) {
-			if (uvedit_face_visible_test(scene, ima, efa)) {
+			if (uvedit_face_visible_test(scene, obedit, ima, efa)) {
 				if (select_faces) {
 					if (BM_elem_flag_test(efa, BM_ELEM_SELECT)) {
 						stack[stacksize] = a;
@@ -1236,7 +1241,7 @@ static void uv_select_linked(Scene *scene, Image *ima, BMEditMesh *em, const flo
 
 /* WATCH IT: this returns first selected UV,
  * not ideal in many cases since there could be multiple */
-static float *uv_sel_co_from_eve(Scene *scene, Image *ima, BMEditMesh *em, BMVert *eve)
+static float *uv_sel_co_from_eve(Scene *scene, Object *obedit, Image *ima, BMEditMesh *em, BMVert *eve)
 {
 	BMIter liter;
 	BMLoop *l;
@@ -1244,7 +1249,7 @@ static float *uv_sel_co_from_eve(Scene *scene, Image *ima, BMEditMesh *em, BMVer
 	const int cd_loop_uv_offset  = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
 
 	BM_ITER_ELEM (l, &liter, eve, BM_LOOPS_OF_VERT) {
-		if (!uvedit_face_visible_test(scene, ima, l->f))
+		if (!uvedit_face_visible_test(scene, obedit, ima, l->f))
 			continue;
 
 		if (uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) {
@@ -1292,7 +1297,7 @@ static int uv_select_more_less(bContext *C, const bool select)
 
 		/* mark loops to be selected */
 		BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
-			if (uvedit_face_visible_test(scene, ima, efa)) {
+			if (uvedit_face_visible_test(scene, obedit, ima, efa)) {
 
 #define IS_SEL   1
 #define IS_UNSEL 2
@@ -1335,7 +1340,7 @@ static int uv_select_more_less(bContext *C, const bool select)
 
 		/* mark loops to be selected */
 		BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
-			if (uvedit_face_visible_test(scene, ima, efa)) {
+			if (uvedit_face_visible_test(scene, obedit, ima, efa)) {
 				BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
 
 					MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
@@ -1418,7 +1423,7 @@ static void uv_weld_align(bContext *C, int tool)
 		BMLoop *l;
 
 		BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
-			if (!uvedit_face_visible_test(scene, ima, efa))
+			if (!uvedit_face_visible_test(scene, obedit, ima, efa))
 				continue;
 
 			BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
@@ -1440,7 +1445,7 @@ static void uv_weld_align(bContext *C, int tool)
 		BMLoop *l;
 
 		BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
-			if (!uvedit_face_visible_test(scene, ima, efa))
+			if (!uvedit_face_visible_test(scene, obedit, ima, efa))
 				continue;
 
 			BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
@@ -1459,7 +1464,7 @@ static void uv_weld_align(bContext *C, int tool)
 		BMLoop *l;
 
 		BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
-			if (!uvedit_face_visible_test(scene, ima, efa))
+			if (!uvedit_face_visible_test(scene, obedit, ima, efa))
 				continue;
 
 			BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
@@ -1487,7 +1492,7 @@ static void uv_weld_align(bContext *C, int tool)
 		/* tag verts with a selected UV */
 		BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) {
 			BM_ITER_ELEM (l, &liter, eve, BM_LOOPS_OF_VERT) {
-				if (!uvedit_face_visible_test(scene, ima, l->f))
+				if (!uvedit_face_visible_test(scene, obedit, ima, l->f))
 					continue;
 
 				if (uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) {
@@ -1554,8 +1559,10 @@ static void uv_weld_align(bContext *C, int tool)
 			if (BLI_array_count(eve_line) > 2) {
 
 				/* we know the returns from these must be valid */
-				const float *uv_start = uv_sel_co_from_eve(scene, ima, em, eve_line[0]);
-				const float *uv_end   = uv_sel_co_from_eve(scene, ima, em, eve_line[BLI_array_count(eve_line) - 1]);
+				const float *uv_start = uv_sel_co_from_eve(
+				        scene, obedit, ima, em, eve_line[0]);
+				const float *uv_end   = uv_sel_co_from_eve(
+				        scene, obedit, ima, em, eve_line[BLI_array_count(eve_line) - 1]);
 				/* For t & u modes */
 				float a = 0.0f;
 
@@ -1575,7 +1582,7 @@ static void uv_weld_align(bContext *C, int tool)
 				/* go over all verts except for endpoints */
 				for (i = 0; i < BLI_array_count(eve_line); i++) {
 					BM_ITER_ELEM (l, &liter, eve_line[i], BM_LOOPS_OF_VERT) {
-						if (!uvedit_face_visible_test(scene, ima, l->f))
+						if (!uvedit_face_visible_test(scene, obedit, ima, l->f))
 							continue;
 
 						if (uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) {
@@ -1684,7 +1691,7 @@ static int uv_remove_doubles_exec(bContext *C, wmOperator *op)
 
 		/* TODO, use qsort as with MESH_OT_remove_doubles, this isn't optimal */
 		BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
-			if (!uvedit_face_visible_test(scene, ima, efa))
+			if (!uvedit_face_visible_test(scene, obedit, ima, efa))
 				continue;
 
 			BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
@@ -1746,7 +1753,7 @@ static int uv_remove_doubles_exec(bContext *C, wmOperator *op)
 		BLI_array_declare(loop_arr_unselected);
 
 		BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
-			if (!uvedit_face_visible_test(scene, ima, efa))
+			if (!uvedit_face_visible_test(scene, obedit, ima, efa))
 				continue;
 
 			BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
@@ -1830,7 +1837,7 @@ static void UV_OT_weld(wmOperatorType *ot)
 
 /* ******************** (de)select all operator **************** */
 
-static void uv_select_all_perform(Scene *scene, Image *ima, BMEditMesh *em, int action)
+static void uv_select_all_perform(Scene *scene, Image *ima, Object *obedit, BMEditMesh *em, int action)
 {
 	ToolSettings *ts = scene->toolsettings;
 	BMFace *efa;
@@ -1862,7 +1869,7 @@ static void uv_select_all_perform(Scene *scene, Image *ima, BMEditMesh *em, int
 		if (action == SEL_TOGGLE) {
 			action = SEL_SELECT;
 			BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
-				if (!uvedit_face_visible_test(scene, ima, efa))
+				if (!uvedit_face_visible_test(scene, obedit, ima, efa))
 					continue;
 
 				BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
@@ -1878,7 +1885,7 @@ static void uv_select_all_perform(Scene *scene, Image *ima, BMEditMesh *em, int
 	
 		
 		BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
-			if (!uvedit_face_visible_test(scene, ima, efa))
+			if (!uvedit_face_visible_test(scene, obedit, ima, efa))
 				continue;
 
 			BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
@@ -1909,7 +1916,7 @@ static int uv_select_all_exec(bContext *C, wmOperator *op)
 
 	int action = RNA_enum_get(op->ptr, "action");
 
-	uv_select_all_perform(scene, ima, em, action);
+	uv_select_all_perform(scene, ima, obedit, em, action);
 
 	WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
 
@@ -2008,7 +2015,7 @@ static int uv_mouse_select(bContext *C, const float co[2], bool extend, bool loo
 	/* find nearest element */
 	if (loop) {
 		/* find edge */
-		uv_find_nearest_edge(scene, ima, em, co, &hit);
+		uv_find_nearest_edge(scene, ima, obedit, em, co, &hit);
 		if (hit.efa == NULL) {
 			return OPERATOR_CANCELLED;
 		}
@@ -2017,7 +2024,7 @@ static int uv_mouse_select(bContext *C, const float co[2], bool extend, bool loo
 	}
 	else if (selectmode == UV_SELECT_VERTEX) {
 		/* find vertex */
-		uv_find_nearest_vert(scene, ima, em, co, penalty, &hit);
+		uv_find_nearest_vert(scene, ima, obedit, em, co, penalty, &hit);
 		if (hit.efa == NULL) {
 			return OPERATOR_CANCELLED;
 		}
@@ -2034,7 +2041,7 @@ static int uv_mouse_select(bContext *C, const float co[2], bool extend, bool loo
 	}
 	else if (selectmode == UV_SELECT_EDGE) {
 		/* find edge */
-		uv_find_nearest_edge(scene, ima, em, co, &hit);
+		uv_find_nearest_edge(scene, ima, obedit, em, co, &hit);
 		if (hit.efa == NULL) {
 			return OPERATOR_CANCELLED;
 		}
@@ -2053,7 +2060,7 @@ static int uv_mouse_select(bContext *C, const float co[2], bool extend, bool loo
 	}
 	else if (selectmode == UV_SELECT_FACE) {
 		/* find face */
-		uv_find_nearest_face(scene, ima, em, co, &hit);
+		uv_find_nearest_face(scene, ima, obedit, em, co, &hit);
 		if (hit.efa == NULL) {
 			return OPERATOR_CANCELLED;
 		}
@@ -2074,7 +2081,7 @@ static int uv_mouse_select(bContext *C, const float co[2], bool extend, bool loo
 		hitlen = hit.efa->len;
 	}
 	else if (selectmode == UV_SELECT_ISLAND) {
-		uv_find_nearest_edge(scene, ima, em, co, &hit);
+		uv_find_nearest_edge(scene, ima, obedit, em, co, &hit);
 
 		if (hit.efa == NULL) {
 			return OPERATOR_CANCELLED;
@@ -2089,10 +2096,10 @@ static int uv_mouse_select(bContext *C, const float co[2], bool extend, bool loo
 
 	/* do selection */
 	if (loop) {
-		flush = uv_select_edgeloop(scene, ima, em, &hit, limit, extend);
+		flush = uv_select_edgeloop(scene, ima, obedit, em, &hit, limit, extend);
 	}
 	else if (selectmode == UV_SELECT_ISLAND) {
-		uv_select_linked(scene, ima, em, limit, &hit, extend, false);
+		uv_select_linked(scene, ima, obedit, em, limit, &hit, extend, false);
 	}
 	else if (extend) {
 		if (selectmode == UV_SELECT_VERTEX) {
@@ -2127,7 +2134,7 @@ static int uv_mouse_select(bContext *C, const float co[2], bool extend, bool loo
 			BM_mesh_elem_index_ensure(em->bm, BM_VERT);
 
 			BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
-				if (!uvedit_face_visible_test(scene, ima, efa))
+				if (!uvedit_face_visible_test(scene, obedit, ima, efa))
 					continue;
 
 				BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
@@ -2142,7 +2149,7 @@ static int uv_mouse_select(bContext *C, const float co[2], bool extend, bool loo
 	}
 	else {
 		/* deselect all */
-		uv_select_all_perform(scene, ima, em, SEL_DESELECT);
+		uv_select_all_perform(scene, ima, obedit, em, SEL_DESELECT);
 
 		if (selectmode == UV_SELECT_VERTEX) {
 			/* select vertex */
@@ -2162,7 +2169,7 @@ static int uv_mouse_select(bContext *C, const float co[2], bool extend, bool loo
 		/* select sticky uvs */
 		if (sticky != SI_STICKY_DISABLE) {
 			BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
-				if (!uvedit_face_visible_test(scene, ima, efa))
+				if (!uvedit_face_visible_test(scene, obedit, ima, efa))
 					continue;
 				
 				BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
@@ -2338,11 +2345,11 @@ static int uv_select_linked_internal(bContext *C, wmOperator *op, const wmEvent
 			RNA_float_get_array(op->ptr, "location", co);
 		}
 
-		uv_find_nearest_edge(scene, ima, em, co, &hit);
+		uv_find_nearest_edge(scene, ima, obedit, em, co, &hit);
 		hit_p = &hit;
 	}
 
-	uv_select_linked(scene, ima, em, limit, hit_p, extend, select_faces);
+	uv_select_linked(scene, ima, obedit, em, limit, hit_p, extend, select_faces);
 
 	DEG_id_tag_update(obedit->data, 0);
 	WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
@@ -2434,7 +2441,7 @@ static int uv_select_split_exec(bContext *C, wmOperator *op)
 		bool is_sel = false;
 		bool is_unsel = false;
 
-		if (!uvedit_face_visible_test(scene, ima, efa))
+		if (!uvedit_face_visible_test(scene, obedit, ima, efa))
 			continue;
 
 		/* are we all selected? */
@@ -2765,7 +2772,7 @@ static int uv_border_select_exec(bContext *C, wmOperator *op)
 	pinned = RNA_boolean_get(op->ptr, "pinned");
 
 	if (!extend)
-		uv_select_all_perform(scene, ima, em, SEL_DESELECT);
+		uv_select_all_perform(scene, ima, obedit, em, SEL_DESELECT);
 
 	/* do actual selection */
 	if (use_face_center && !pinned) {
@@ -2778,7 +2785,7 @@ static int uv_border_select_exec(bContext *C, wmOperator *op)
 			/* assume not touched */
 			BM_elem_flag_disable(efa, BM_ELEM_TAG);
 
-			if (uvedit_face_visible_test(scene, ima, efa)) {
+			if (uvedit_face_visible_test(scene, obedit, ima, efa)) {
 				uv_poly_center(efa, cent, cd_loop_uv_offset);
 				if (BLI_rctf_isect_pt_v(&rectf, cent)) {
 					BM_elem_flag_enable(efa, BM_ELEM_TAG);
@@ -2797,7 +2804,7 @@ static int uv_border_select_exec(bContext *C, wmOperator *op)
 		changed = true;
 		
 		BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
-			if (!uvedit_face_visible_test(scene, ima, efa))
+			if (!uvedit_face_visible_test(scene, obedit, ima, efa))
 				continue;
 			BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
 				luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
@@ -3006,7 +3013,7 @@ static bool do_lasso_select_mesh_uv(bContext *C, const int mcords[][2], short mo
 	BLI_lasso_boundbox(&rect, mcords, moves);
 
 	if (!extend && select) {
-		uv_select_all_perform(scene, ima, em, SEL_DESELECT);
+		uv_select_all_perform(scene, ima, obedit, em, SEL_DESELECT);
 	}
 
 	if (use_face_center) { /* Face Center Sel */
@@ -3034,7 +3041,7 @@ static bool do_lasso_select_mesh_uv(bContext *C, const int mcords[][2], short mo
 	}
 	else { /* Vert Sel */
 		BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
-			if (uvedit_face_visible_test(scene, ima, efa)) {
+			if (uvedit_face_visible_test(scene, obedit, ima, efa)) {
 				BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
 					if ((select) != (uvedit_uv_select_test(scene, l, cd_loop_uv_offset))) {
 						MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
@@ -3188,7 +3195,7 @@ static bool uv_snap_uvs_to_cursor(Scene *scene, Image *ima, Object *obedit, cons
 	const int cd_loop_uv_offset  = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
 
 	BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
-		if (!uvedit_face_visible_test(scene, ima, efa))
+		if (!uvedit_face_visible_test(scene, obedit, ima, efa))
 			continue;
 
 		BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
@@ -3215,7 +3222,7 @@ static bool uv_snap_uvs_offset(Scene *scene, Image *ima, Object *obedit, const f
 	const int cd_loop_uv_offset  = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
 
 	BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
-		if (!uvedit_face_visible_test(scene, ima, efa))
+		if (!uvedit_face_visible_test(scene, obedit, ima, efa))
 			continue;
 
 		BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
@@ -3244,7 +3251,7 @@ static bool uv_snap_uvs_to_adjacent_unselected(Scene *scene, Image *ima, Object
 	/* index every vert that has a selected UV using it, but only once so as to
 	 * get unique indices and to count how much to malloc */
 	BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
-		if (uvedit_face_visible_test(scene, ima, f)) {
+		if (uvedit_face_visible_test(scene, obedit, ima, f)) {
 			BM_elem_flag_enable(f, BM_ELEM_TAG);
 			BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
 				BM_elem_flag_set(l, BM_ELEM_TAG, uvedit_uv_select_test(scene, l, cd_loop_uv_offset));
@@ -3304,7 +3311,7 @@ static bool uv_snap_uvs_to_pixels(SpaceImage *sima, Scene *scene, Object *obedit
 	h = (float)height;
 	
 	BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
-		if (!uvedit_face_visible_test(scene, ima, efa))
+		if (!uvedit_face_visible_test(scene, obedit, ima, efa))
 			continue;
 
 		BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
@@ -3400,7 +3407,7 @@ static int uv_pin_exec(bContext *C, wmOperator *op)
 	const int cd_loop_uv_offset  = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
 
 	BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
-		if (!uvedit_face_visible_test(scene, ima, efa))
+		if (!uvedit_face_visible_test(scene, obedit, ima, efa))
 			continue;
 
 		BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
@@ -3454,7 +3461,7 @@ static int uv_select_pinned_exec(bContext *C, wmOperator *UNUSED(op))
 	const int cd_loop_uv_offset  = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
 
 	BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
-		if (!uvedit_face_visible_test(scene, ima, efa))
+		if (!uvedit_face_visible_test(scene, obedit, ima, efa))
 			continue;
 
 		BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
@@ -3534,7 +3541,7 @@ static int uv_hide_exec(bContext *C, wmOperator *op)
 	BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
 		int hide = 0;
 
-		if (!uvedit_face_visible_test(scene, ima, efa)) {
+		if (!uvedit_face_visible_test(scene, obedit, ima, efa)) {
 			continue;
 		}
 
diff --git a/source/blender/editors/uvedit/uvedit_smart_stitch.c b/source/blender/editors/uvedit/uvedit_smart_stitch.c
index fa936e998fae1c9e8b5b5fcb23151f88fcf30dd4..e19fa41b5006c3db0806ec89f0dd832f25f4ed40 100644
--- a/source/blender/editors/uvedit/uvedit_smart_stitch.c
+++ b/source/blender/editors/uvedit/uvedit_smart_stitch.c
@@ -157,6 +157,8 @@ typedef struct StitchState {
 	bool snap_islands;
 	/* stitch at midpoints or at islands */
 	bool midpoints;
+	/* object for editmesh */
+	Object *obedit;
 	/* editmesh, cached for use in modal handler */
 	BMEditMesh *em;
 	/* clear seams of stitched edges after stitch */
@@ -1719,6 +1721,7 @@ static int stitch_init(bContext *C, wmOperator *op)
 	/* initialize state */
 	state->use_limit = RNA_boolean_get(op->ptr, "use_limit");
 	state->limit_dist = RNA_float_get(op->ptr, "limit");
+	state->obedit = obedit;
 	state->em = em;
 	state->snap_islands = RNA_boolean_get(op->ptr, "snap_islands");
 	state->static_island = RNA_int_get(op->ptr, "static_island");
@@ -2131,7 +2134,7 @@ static void stitch_select(bContext *C, Scene *scene, const wmEvent *event, Stitc
 	UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &co[0], &co[1]);
 
 	if (state->mode == STITCH_VERT) {
-		uv_find_nearest_vert(scene, ima, state->em, co, NULL, &hit);
+		uv_find_nearest_vert(scene, ima, state->obedit, state->em, co, NULL, &hit);
 
 		if (hit.efa) {
 			/* Add vertex to selection, deselect all common uv's of vert other
@@ -2145,7 +2148,7 @@ static void stitch_select(bContext *C, Scene *scene, const wmEvent *event, Stitc
 		}
 	}
 	else {
-		uv_find_nearest_edge(scene, ima, state->em, co, &hit);
+		uv_find_nearest_edge(scene, ima, state->obedit, state->em, co, &hit);
 
 		if (hit.efa) {
 			UvEdge *edge = uv_edge_get(hit.l, state);
diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h
index 671ad1bc95490c1da9d6f4519b6df6a258b9f895..e7f0ad9d3db37d97af6a198b70715e1f957e2ccc 100644
--- a/source/blender/makesdna/DNA_scene_types.h
+++ b/source/blender/makesdna/DNA_scene_types.h
@@ -1623,7 +1623,8 @@ typedef struct Scene {
 	
 	ListBase base DNA_DEPRECATED;
 	struct Base  *basact DNA_DEPRECATED; /* active base */
-	struct Object *obedit;		/* name replaces old G.obedit */
+
+	struct Editing *ed;								/* sequence editor data is allocated here */
 	
 	float cursor[3];			/* 3d cursor location */
 	char _pad[4];
@@ -1639,10 +1640,7 @@ typedef struct Scene {
 	
 	struct bNodeTree *nodetree;
 	
-	struct Editing *ed;								/* sequence editor data is allocated here */
-	
 	struct ToolSettings *toolsettings;		/* default allocated now */
-	void *pad2;
 	struct DisplaySafeAreas safe_areas;
 
 	/* migrate or replace? depends on some internal things... */
@@ -1944,6 +1942,14 @@ extern const char *RE_engine_id_CYCLES;
 #define BASACT(_view_layer)     ((_view_layer)->basact)
 #define OBACT(_view_layer)      (BASACT(_view_layer) ? BASACT(_view_layer)->object: NULL)
 
+#define OBEDIT_FROM_WORKSPACE(workspace, _view_layer) \
+	(((workspace)->object_mode & OD_MODE_EDIT) ? OBACT(_view_layer) : NULL)
+#define OBEDIT_FROM_EVAL_CTX(eval_ctx) \
+	(((eval_ctx)->object_mode & OB_MODE_EDIT) ? OBACT((eval_ctx)->view_layer) : NULL)
+
+#define OBEDIT_FROM_WINDOW(window) \
+	BKE_workspace_edit_object(WM_window_get_active_workspace(window), WM_window_get_active_scene(window))
+
 #define V3D_CAMERA_LOCAL(v3d) ((!(v3d)->scenelock && (v3d)->camera) ? (v3d)->camera : NULL)
 #define V3D_CAMERA_SCENE(scene, v3d) ((!(v3d)->scenelock && (v3d)->camera) ? (v3d)->camera : (scene)->camera)
 
diff --git a/source/blender/makesrna/intern/rna_layer.c b/source/blender/makesrna/intern/rna_layer.c
index efa05ed5b92b63dcb43ef51500356980d78b4d11..1e7e8de0ca7d8bb3378c3c6e35d7c2c598ad40c2 100644
--- a/source/blender/makesrna/intern/rna_layer.c
+++ b/source/blender/makesrna/intern/rna_layer.c
@@ -847,7 +847,10 @@ static void rna_LayerObjects_active_object_update(struct bContext *C, PointerRNA
 	}
 
 	ViewLayer *view_layer = (ViewLayer *)ptr->data;
-	if (scene->obedit) {
+
+	/* OBMODE/TODO edit_object from _previous_ state needs to be freed! */
+	Object *obedit = CTX_data_edit_object(C);
+	if (obedit) {
 		ED_object_editmode_exit(C, EM_FREEDATA);
 	}
 	ED_object_base_activate(C, view_layer->basact);
diff --git a/source/blender/makesrna/intern/rna_material.c b/source/blender/makesrna/intern/rna_material.c
index 440af0d0e8e96d3da4366034418e2c2848af5fbf..6f23b0fd281eb2e369b7edf48e9d2933a4ca07ae 100644
--- a/source/blender/makesrna/intern/rna_material.c
+++ b/source/blender/makesrna/intern/rna_material.c
@@ -92,13 +92,15 @@ const EnumPropertyItem rna_enum_ramp_blend_items[] = {
 #include "BKE_texture.h"
 #include "BKE_node.h"
 #include "BKE_paint.h"
+#include "BKE_scene.h"
+#include "BKE_workspace.h"
 
 #include "DEG_depsgraph.h"
 #include "DEG_depsgraph_build.h"
 
 #include "ED_node.h"
 #include "ED_image.h"
-#include "BKE_scene.h"
+#include "ED_screen.h"
 
 static void rna_Material_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
 {
@@ -201,6 +203,11 @@ static void rna_Material_active_paint_texture_index_update(Main *bmain, Scene *s
 	if (ma->texpaintslot) {
 		Image *image = ma->texpaintslot[ma->paint_active_slot].ima;
 		for (sc = bmain->screen.first; sc; sc = sc->id.next) {
+			wmWindow *win = ED_screen_window_find(sc, bmain->wm.first);
+			if (win == NULL) {
+				continue;
+			}
+			Object *obedit = OBEDIT_FROM_WINDOW(win);
 			ScrArea *sa;
 			for (sa = sc->areabase.first; sa; sa = sa->next) {
 				SpaceLink *sl;
@@ -209,7 +216,7 @@ static void rna_Material_active_paint_texture_index_update(Main *bmain, Scene *s
 						SpaceImage *sima = (SpaceImage *)sl;
 						
 						if (!sima->pin)
-							ED_space_image_set(sima, scene, scene->obedit, image);
+							ED_space_image_set(sima, scene, obedit, image);
 					}
 				}
 			}
diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c
index 270d9fe14ca3f15701add0b8459adef93abd0ba1..d3096bbb6bb1c81a6d5b8da57b6f8fa0854337d7 100644
--- a/source/blender/makesrna/intern/rna_object.c
+++ b/source/blender/makesrna/intern/rna_object.c
@@ -295,11 +295,11 @@ void rna_Object_internal_update_data(Main *UNUSED(bmain), Scene *UNUSED(scene),
 	WM_main_add_notifier(NC_OBJECT | ND_DRAW, ptr->id.data);
 }
 
-static void rna_Object_active_shape_update(Main *bmain, Scene *scene, PointerRNA *ptr)
+static void rna_Object_active_shape_update(bContext *C, Main *bmain, Scene *scene, PointerRNA *ptr)
 {
 	Object *ob = ptr->id.data;
 
-	if (scene->obedit == ob) {
+	if (CTX_data_edit_object(C) == ob) {
 		/* exit/enter editmode to get new shape */
 		switch (ob->type) {
 			case OB_MESH:
@@ -3018,6 +3018,7 @@ static void rna_def_object(BlenderRNA *brna)
 
 	prop = RNA_def_property(srna, "active_shape_key_index", PROP_INT, PROP_NONE);
 	RNA_def_property_int_sdna(prop, NULL, "shapenr");
+	RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
 	RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); /* XXX this is really unpredictable... */
 	RNA_def_property_int_funcs(prop, "rna_Object_active_shape_key_index_get", "rna_Object_active_shape_key_index_set",
 	                           "rna_Object_active_shape_key_index_range");
diff --git a/source/blender/makesrna/intern/rna_sculpt_paint.c b/source/blender/makesrna/intern/rna_sculpt_paint.c
index cc447f2a0282e2dfdfa08ad449c9b8a69d9e5e7b..06c0260d08f41c582a0aab241b77bf79b5d3a1e3 100644
--- a/source/blender/makesrna/intern/rna_sculpt_paint.c
+++ b/source/blender/makesrna/intern/rna_sculpt_paint.c
@@ -39,6 +39,7 @@
 #include "DNA_brush_types.h"
 #include "DNA_screen_types.h"
 #include "DNA_space_types.h"
+#include "DNA_workspace_types.h"
 
 #include "BKE_paint.h"
 #include "BKE_material.h"
@@ -107,6 +108,7 @@ const EnumPropertyItem rna_enum_symmetrize_direction_items[] = {
 #include "BKE_pointcache.h"
 #include "BKE_particle.h"
 #include "BKE_pbvh.h"
+#include "BKE_object.h"
 
 #include "DEG_depsgraph.h"
 
@@ -391,10 +393,12 @@ static void rna_ImaPaint_stencil_update(bContext *C, PointerRNA *UNUSED(ptr))
 
 static void rna_ImaPaint_canvas_update(bContext *C, PointerRNA *UNUSED(ptr))
 {
+	const WorkSpace *workspace = CTX_wm_workspace(C);
 	Main *bmain = CTX_data_main(C);
 	Scene *scene = CTX_data_scene(C);
 	ViewLayer *view_layer = CTX_data_view_layer(C);
 	Object *ob = OBACT(view_layer);
+	Object *obedit = ((workspace->object_mode & OB_MODE_EDIT) && BKE_object_is_in_editmode(ob)) ? ob : NULL;
 	bScreen *sc;
 	Image *ima = scene->toolsettings->imapaint.canvas;
 	
@@ -407,7 +411,7 @@ static void rna_ImaPaint_canvas_update(bContext *C, PointerRNA *UNUSED(ptr))
 					SpaceImage *sima = (SpaceImage *)slink;
 					
 					if (!sima->pin)
-						ED_space_image_set(sima, scene, scene->obedit, ima);
+						ED_space_image_set(sima, scene, obedit, ima);
 				}
 			}
 		}
diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c
index b4a42b3a90911c0d88b343d3acb36c531a1dab7b..c95b33d90ad8daae81c811c0b51b21c96302ec01 100644
--- a/source/blender/makesrna/intern/rna_space.c
+++ b/source/blender/makesrna/intern/rna_space.c
@@ -857,9 +857,10 @@ static int rna_SpaceImageEditor_show_uvedit_get(PointerRNA *ptr)
 {
 	SpaceImage *sima = (SpaceImage *)(ptr->data);
 	bScreen *sc = (bScreen *)ptr->id.data;
-	Scene *scene = ED_screen_scene_find(sc, G.main->wm.first);
+	wmWindow *win = ED_screen_window_find(sc, G.main->wm.first);
+	Object *obedit = OBEDIT_FROM_WINDOW(win);
 
-	return ED_space_image_show_uvedit(sima, scene->obedit);
+	return ED_space_image_show_uvedit(sima, obedit);
 }
 
 static int rna_SpaceImageEditor_show_maskedit_get(PointerRNA *ptr)
@@ -877,9 +878,10 @@ static void rna_SpaceImageEditor_image_set(PointerRNA *ptr, PointerRNA value)
 {
 	SpaceImage *sima = (SpaceImage *)(ptr->data);
 	bScreen *sc = (bScreen *)ptr->id.data;
-	Scene *scene = ED_screen_scene_find(sc, G.main->wm.first);
-
-	ED_space_image_set(sima, scene, scene->obedit, (Image *)value.data);
+	wmWindow *win;
+	Scene *scene = ED_screen_scene_find_with_window(sc, G.main->wm.first, &win);
+	Object *obedit = OBEDIT_FROM_WINDOW(win);
+	ED_space_image_set(sima, scene, obedit, (Image *)value.data);
 }
 
 static void rna_SpaceImageEditor_mask_set(PointerRNA *ptr, PointerRNA value)
diff --git a/source/blender/makesrna/intern/rna_wm.c b/source/blender/makesrna/intern/rna_wm.c
index f3cf2bb0d6420f31c281eab745ea6a31f911f773..dca4fa3822def4ec7f3e6eb6814b3979bb70418e 100644
--- a/source/blender/makesrna/intern/rna_wm.c
+++ b/source/blender/makesrna/intern/rna_wm.c
@@ -785,9 +785,10 @@ static void rna_Window_view_layer_update(struct bContext *C, PointerRNA *ptr)
 	Scene *scene = WM_window_get_active_scene(win);
 	WorkSpace *workspace = WM_window_get_active_workspace(win);
 	ViewLayer *view_layer = BKE_workspace_view_layer_get(workspace, scene);
+	Object *obedit = CTX_data_edit_object(C);
 
 	eObjectMode object_mode = workspace->object_mode;
-	if (scene->obedit) {
+	if (obedit) {
 		ED_object_editmode_exit(C, EM_FREEDATA);
 	}
 	workspace->object_mode = object_mode;
diff --git a/source/blender/modifiers/intern/MOD_meshdeform.c b/source/blender/modifiers/intern/MOD_meshdeform.c
index da233a18d0af1a544fd9526d5ee8f875c83f43dc..e8fc832b597e378def475a38b487b59d3eabbbfe 100644
--- a/source/blender/modifiers/intern/MOD_meshdeform.c
+++ b/source/blender/modifiers/intern/MOD_meshdeform.c
@@ -49,6 +49,8 @@
 
 #include "MEM_guardedalloc.h"
 
+#include "DEG_depsgraph.h"
+
 #include "MOD_util.h"
 
 #ifdef __SSE2__
@@ -300,7 +302,7 @@ static void meshdeformModifier_do(
 	 *
 	 * We'll support this case once granular dependency graph is landed.
 	 */
-	if (mmd->object == md->scene->obedit) {
+	if (mmd->object == OBEDIT_FROM_EVAL_CTX(eval_ctx)) {
 		BMEditMesh *em = BKE_editmesh_from_object(mmd->object);
 		tmpdm = editbmesh_get_derived_cage_and_final(eval_ctx, md->scene, mmd->object, em, 0, &cagedm);
 		if (tmpdm)
diff --git a/source/blender/modifiers/intern/MOD_surfacedeform.c b/source/blender/modifiers/intern/MOD_surfacedeform.c
index 046a0ab27bf1a91abdbd4288d0bd9459b2585cfd..85347288872b504b0a61f0e4efb2b938beb3e585 100644
--- a/source/blender/modifiers/intern/MOD_surfacedeform.c
+++ b/source/blender/modifiers/intern/MOD_surfacedeform.c
@@ -11,6 +11,8 @@
 #include "BKE_library_query.h"
 #include "BKE_modifier.h"
 
+#include "DEG_depsgraph.h"
+
 #include "MEM_guardedalloc.h"
 
 #include "MOD_util.h"
@@ -1097,7 +1099,9 @@ static void deformVert(
 	}
 }
 
-static void surfacedeformModifier_do(ModifierData *md, float (*vertexCos)[3], unsigned int numverts, Object *ob)
+static void surfacedeformModifier_do(
+        ModifierData *md, const EvaluationContext *eval_ctx,
+        float (*vertexCos)[3], unsigned int numverts, Object *ob)
 {
 	SurfaceDeformModifierData *smd = (SurfaceDeformModifierData *)md;
 	DerivedMesh *tdm;
@@ -1110,7 +1114,7 @@ static void surfacedeformModifier_do(ModifierData *md, float (*vertexCos)[3], un
 	}
 
 	/* Handle target mesh both in and out of edit mode */
-	if (smd->target == md->scene->obedit) {
+	if (smd->target == OBEDIT_FROM_EVAL_CTX(eval_ctx)) {
 		BMEditMesh *em = BKE_editmesh_from_object(smd->target);
 		tdm = em->derivedFinal;
 	}
@@ -1180,20 +1184,22 @@ static void surfacedeformModifier_do(ModifierData *md, float (*vertexCos)[3], un
 	}
 }
 
-static void deformVerts(ModifierData *md, const struct EvaluationContext *UNUSED(eval_ctx),
-                        Object *ob, DerivedMesh *UNUSED(derivedData),
-                        float (*vertexCos)[3], int numVerts,
-                        ModifierApplyFlag UNUSED(flag))
+static void deformVerts(
+        ModifierData *md, const struct EvaluationContext *eval_ctx,
+        Object *ob, DerivedMesh *UNUSED(derivedData),
+        float (*vertexCos)[3], int numVerts,
+        ModifierApplyFlag UNUSED(flag))
 {
-	surfacedeformModifier_do(md, vertexCos, numVerts, ob);
+	surfacedeformModifier_do(md, eval_ctx, vertexCos, numVerts, ob);
 }
 
-static void deformVertsEM(ModifierData *md, const struct EvaluationContext *UNUSED(eval_ctx),
-                          Object *ob, struct BMEditMesh *UNUSED(editData),
-                          DerivedMesh *UNUSED(derivedData),
-                          float (*vertexCos)[3], int numVerts)
+static void deformVertsEM(
+        ModifierData *md, const struct EvaluationContext *eval_ctx,
+        Object *ob, struct BMEditMesh *UNUSED(editData),
+        DerivedMesh *UNUSED(derivedData),
+        float (*vertexCos)[3], int numVerts)
 {
-	surfacedeformModifier_do(md, vertexCos, numVerts, ob);
+	surfacedeformModifier_do(md, eval_ctx, vertexCos, numVerts, ob);
 }
 
 static bool isDisabled(ModifierData *md, int UNUSED(useRenderParams))
diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp
index 3b0fb335d21d561850974bc1e004f1cd6a13d6a0..dda1864f07c86ded4f046bd97d5171d11ce9aa8d 100644
--- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp
+++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp
@@ -1688,6 +1688,7 @@ struct parentChildLink {
 	SG_Node* m_gamechildnode;
 };
 
+#if 0
 static bPoseChannel *get_active_posechannel2(Object *ob)
 {
 	bArmature *arm= (bArmature*)ob->data;
@@ -1701,6 +1702,7 @@ static bPoseChannel *get_active_posechannel2(Object *ob)
 	
 	return NULL;
 }
+#endif
 
 static ListBase *get_active_constraints2(Object *ob)
 {