Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulian Eisel <eiseljulian@gmail.com>2017-12-01 17:47:24 +0300
committerJulian Eisel <eiseljulian@gmail.com>2017-12-01 18:15:30 +0300
commite8c15e0ed15f8369d0d0f706b4953fb64e357902 (patch)
tree0eb072454c535b438caf8eed3033d27b3c17e99b
parent983b1a34783e9600731b973ba52ecc8924bff169 (diff)
Workspaces: Store an active view-layer per scene
Instead of storing a single active view-layer in the workspace, one is stored for each scene the workspace showed before. With this, some things become possible: * Multiple windows in the same workspace but showing different scenes. * Toggling back and forth scene keeps same active view-layer for each scene. * Activating workspace which didn't show current scene before, the current view-layer is kept. A necessary evil for this is that accessing view-layer and object mode from .py can't be done via workspace directly anymore. It has to be done through the window, so RNA can use the correct scene. So instead of `workspace.view_layer`, it's `window.view_layer` now (same with mode) even though it's still workspace data. Fixes T53432.
-rw-r--r--release/scripts/startup/bl_ui/space_info.py7
-rw-r--r--source/blender/blenkernel/BKE_workspace.h28
-rw-r--r--source/blender/blenkernel/intern/layer.c2
-rw-r--r--source/blender/blenkernel/intern/workspace.c64
-rw-r--r--source/blender/blenloader/intern/readfile.c29
-rw-r--r--source/blender/blenloader/intern/versioning_280.c7
-rw-r--r--source/blender/blenloader/intern/writefile.c3
-rw-r--r--source/blender/editors/include/ED_screen.h4
-rw-r--r--source/blender/editors/object/object_edit.c8
-rw-r--r--source/blender/editors/object/object_select.c3
-rw-r--r--source/blender/editors/scene/scene_edit.c17
-rw-r--r--source/blender/editors/screen/screen_context.c2
-rw-r--r--source/blender/editors/screen/workspace_edit.c37
-rw-r--r--source/blender/makesdna/DNA_workspace_types.h1
-rw-r--r--source/blender/makesrna/intern/rna_wm.c61
-rw-r--r--source/blender/makesrna/intern/rna_workspace.c55
16 files changed, 204 insertions, 124 deletions
diff --git a/release/scripts/startup/bl_ui/space_info.py b/release/scripts/startup/bl_ui/space_info.py
index 8c7fcb29ad2..f032f6a899b 100644
--- a/release/scripts/startup/bl_ui/space_info.py
+++ b/release/scripts/startup/bl_ui/space_info.py
@@ -48,15 +48,16 @@ class INFO_HT_header(Header):
layout.template_ID(window, "workspace", new="workspace.workspace_add_menu", unlink="workspace.workspace_delete")
layout.template_search_preview(window, "screen", workspace, "screens", new="screen.new", unlink="screen.delete", rows=2, cols=6)
- if hasattr(workspace, 'object_mode'):
- act_mode_item = bpy.types.Object.bl_rna.properties['mode'].enum_items[workspace.object_mode]
+ if hasattr(window, 'object_mode'):
+ act_mode_item = bpy.types.Object.bl_rna.properties['mode'].enum_items[window.object_mode]
else:
act_mode_item = bpy.types.Object.bl_rna.properties['mode'].enum_items[layer.objects.active.mode]
layout.operator_menu_enum("object.mode_set", "mode", text=act_mode_item.name, icon=act_mode_item.icon)
row = layout.row()
row.active = not workspace.use_scene_settings
- row.template_search(workspace, "view_layer", scene, "view_layers")
+ # Active workspace view-layer is retrieved through window, not through workspace.
+ row.template_search(window, "view_layer", scene, "view_layers")
if view_render.has_multiple_engines:
row.prop(view_render, "engine", text="")
diff --git a/source/blender/blenkernel/BKE_workspace.h b/source/blender/blenkernel/BKE_workspace.h
index f295af3150a..9f989f7ae8f 100644
--- a/source/blender/blenkernel/BKE_workspace.h
+++ b/source/blender/blenkernel/BKE_workspace.h
@@ -32,6 +32,7 @@ struct EvaluationContext;
struct Main;
struct Scene;
struct TransformOrientation;
+struct ViewLayer;
/**
* Plan is to store the object-mode per workspace, not per object anymore.
@@ -62,10 +63,17 @@ void BKE_workspace_layout_remove(
struct Main *bmain,
struct WorkSpace *workspace, struct WorkSpaceLayout *layout) ATTR_NONNULL();
+void BKE_workspace_relations_free(
+ ListBase *relation_list);
+
/* -------------------------------------------------------------------- */
/* General Utils */
+void BKE_workspace_view_layer_remove_references(
+ const struct Main *bmain,
+ const struct ViewLayer *view_layer) ATTR_NONNULL();
+
void BKE_workspace_transform_orientation_remove(
struct WorkSpace *workspace, struct TransformOrientation *orientation) ATTR_NONNULL();
struct TransformOrientation *BKE_workspace_transform_orientation_find(
@@ -98,14 +106,24 @@ void BKE_workspace_active_layout_set(struct WorkSpaceInstanceHook *h
struct bScreen *BKE_workspace_active_screen_get(const struct WorkSpaceInstanceHook *hook) GETTER_ATTRS;
void BKE_workspace_active_screen_set(
struct WorkSpaceInstanceHook *hook, struct WorkSpace *workspace, struct bScreen *screen) SETTER_ATTRS;
-enum eObjectMode BKE_workspace_object_mode_get(const struct WorkSpace *workspace) GETTER_ATTRS;
#ifdef USE_WORKSPACE_MODE
-void BKE_workspace_object_mode_set(struct WorkSpace *workspace, const enum eObjectMode mode) SETTER_ATTRS;
+enum eObjectMode BKE_workspace_object_mode_get(
+ const struct WorkSpace *workspace,
+ const struct Scene *scene) GETTER_ATTRS;
+void BKE_workspace_object_mode_set(
+ struct WorkSpace *workspace,
+ struct Scene *scene,
+ const enum eObjectMode mode) SETTER_ATTRS;
#endif
-struct Base *BKE_workspace_active_base_get(const struct WorkSpace *workspace);
+struct Base *BKE_workspace_active_base_get(const struct WorkSpace *workspace, const struct Scene *scene);
struct ListBase *BKE_workspace_transform_orientations_get(struct WorkSpace *workspace) GETTER_ATTRS;
-struct ViewLayer *BKE_workspace_view_layer_get(const struct WorkSpace *workspace) GETTER_ATTRS;
-void BKE_workspace_view_layer_set(struct WorkSpace *workspace, struct ViewLayer *layer) SETTER_ATTRS;
+struct ViewLayer *BKE_workspace_view_layer_get(
+ const struct WorkSpace *workspace,
+ const struct Scene *scene) GETTER_ATTRS;
+void BKE_workspace_view_layer_set(
+ struct WorkSpace *workspace,
+ struct ViewLayer *layer,
+ struct Scene *scene) SETTER_ATTRS;
struct ListBase *BKE_workspace_layouts_get(struct WorkSpace *workspace) GETTER_ATTRS;
const char *BKE_workspace_layout_name_get(const struct WorkSpaceLayout *layout) GETTER_ATTRS;
diff --git a/source/blender/blenkernel/intern/layer.c b/source/blender/blenkernel/intern/layer.c
index 01d8b180344..f841181f7c4 100644
--- a/source/blender/blenkernel/intern/layer.c
+++ b/source/blender/blenkernel/intern/layer.c
@@ -89,7 +89,7 @@ ViewLayer *BKE_view_layer_from_workspace_get(const struct Scene *scene, const st
return BKE_view_layer_from_scene_get(scene);
}
else {
- return BKE_workspace_view_layer_get(workspace);
+ return BKE_workspace_view_layer_get(workspace, scene);
}
}
diff --git a/source/blender/blenkernel/intern/workspace.c b/source/blender/blenkernel/intern/workspace.c
index 785fd71df69..b6b7d936c76 100644
--- a/source/blender/blenkernel/intern/workspace.c
+++ b/source/blender/blenkernel/intern/workspace.c
@@ -113,6 +113,18 @@ static void *workspace_relation_get_data_matching_parent(
}
}
+static void workspace_relation_remove_from_value(
+ ListBase *relation_list, const void *value)
+{
+ for (WorkSpaceDataRelation *relation = relation_list->first, *relation_next; relation; relation = relation_next) {
+ relation_next = relation->next;
+
+ if (relation->value == value) {
+ workspace_relation_remove(relation_list, relation);
+ }
+ }
+}
+
/**
* Checks if \a screen is already used within any workspace. A screen should never be assigned to multiple
* WorkSpaceLayouts, but that should be ensured outside of the BKE_workspace module and without such checks.
@@ -151,15 +163,12 @@ WorkSpace *BKE_workspace_add(Main *bmain, const char *name)
*/
void BKE_workspace_free(WorkSpace *workspace)
{
- for (WorkSpaceDataRelation *relation = workspace->hook_layout_relations.first, *relation_next;
- relation;
- relation = relation_next)
- {
- relation_next = relation->next;
- workspace_relation_remove(&workspace->hook_layout_relations, relation);
- }
+ BKE_workspace_relations_free(&workspace->hook_layout_relations);
+ BKE_workspace_relations_free(&workspace->scene_viewlayer_relations);
+
BLI_freelistN(&workspace->layouts);
BLI_freelistN(&workspace->transform_orientations);
+
BKE_viewrender_free(&workspace->view_render);
}
@@ -237,9 +246,28 @@ void BKE_workspace_layout_remove(
BLI_freelinkN(&workspace->layouts, layout);
}
+void BKE_workspace_relations_free(
+ ListBase *relation_list)
+{
+ for (WorkSpaceDataRelation *relation = relation_list->first, *relation_next; relation; relation = relation_next) {
+ relation_next = relation->next;
+ workspace_relation_remove(relation_list, relation);
+ }
+}
+
+
/* -------------------------------------------------------------------- */
/* General Utils */
+void BKE_workspace_view_layer_remove_references(
+ const Main *bmain,
+ const ViewLayer *view_layer)
+{
+ for (WorkSpace *workspace = bmain->workspaces.first; workspace; workspace = workspace->id.next) {
+ workspace_relation_remove_from_value(&workspace->scene_viewlayer_relations, view_layer);
+ }
+}
+
void BKE_workspace_transform_orientation_remove(
WorkSpace *workspace, TransformOrientation *orientation)
{
@@ -386,23 +414,24 @@ void BKE_workspace_active_screen_set(WorkSpaceInstanceHook *hook, WorkSpace *wor
}
#ifdef USE_WORKSPACE_MODE
-eObjectMode BKE_workspace_object_mode_get(const WorkSpace *workspace)
+eObjectMode BKE_workspace_object_mode_get(const WorkSpace *workspace, const Scene *scene)
{
- Base *active_base = BKE_workspace_active_base_get(workspace);
+ Base *active_base = BKE_workspace_active_base_get(workspace, scene);
return active_base ? active_base->object->mode : OB_MODE_OBJECT;
}
-void BKE_workspace_object_mode_set(WorkSpace *workspace, const eObjectMode mode)
+void BKE_workspace_object_mode_set(WorkSpace *workspace, Scene *scene, const eObjectMode mode)
{
- Base *active_base = BKE_workspace_active_base_get(workspace);
+ Base *active_base = BKE_workspace_active_base_get(workspace, scene);
if (active_base) {
active_base->object->mode = mode;
}
}
#endif
-Base *BKE_workspace_active_base_get(const WorkSpace *workspace)
+Base *BKE_workspace_active_base_get(const WorkSpace *workspace, const Scene *scene)
{
- return workspace->view_layer->basact;
+ ViewLayer *view_layer = BKE_workspace_view_layer_get(workspace, scene);
+ return view_layer->basact;
}
ListBase *BKE_workspace_transform_orientations_get(WorkSpace *workspace)
@@ -410,13 +439,14 @@ ListBase *BKE_workspace_transform_orientations_get(WorkSpace *workspace)
return &workspace->transform_orientations;
}
-ViewLayer *BKE_workspace_view_layer_get(const WorkSpace *workspace)
+ViewLayer *BKE_workspace_view_layer_get(const WorkSpace *workspace, const Scene *scene)
{
- return workspace->view_layer;
+ return workspace_relation_get_data_matching_parent(&workspace->scene_viewlayer_relations, scene);
}
-void BKE_workspace_view_layer_set(WorkSpace *workspace, ViewLayer *layer)
+void BKE_workspace_view_layer_set(WorkSpace *workspace, ViewLayer *layer, Scene *scene)
{
workspace->view_layer = layer;
+ workspace_relation_ensure_updated(&workspace->scene_viewlayer_relations, scene, layer);
}
ListBase *BKE_workspace_layouts_get(WorkSpace *workspace)
@@ -486,7 +516,7 @@ void BKE_workspace_update_tagged(struct EvaluationContext *eval_ctx,
WorkSpace *workspace,
Scene *scene)
{
- ViewLayer *view_layer = BKE_workspace_view_layer_get(workspace);
+ ViewLayer *view_layer = BKE_workspace_view_layer_get(workspace, scene);
struct Depsgraph *depsgraph = BKE_scene_get_depsgraph(scene,
view_layer,
true);
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 5d170960158..323586b66b2 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -2843,6 +2843,14 @@ static void lib_link_workspaces(FileData *fd, Main *bmain)
IDP_LibLinkProperty(id->properties, fd);
id_us_ensure_real(id);
+ for (WorkSpaceDataRelation *relation = workspace->scene_viewlayer_relations.first;
+ relation != NULL;
+ relation = relation->next)
+ {
+ relation->parent = newlibadr(fd, id->lib, relation->parent);
+ /* relation->value is set in direct_link_workspace_link_scene_data */
+ }
+
for (WorkSpaceLayout *layout = layouts->first, *layout_next; layout; layout = layout_next) {
bScreen *screen = newlibadr(fd, id->lib, BKE_workspace_layout_screen_get(layout));
@@ -2868,6 +2876,7 @@ static void direct_link_workspace(FileData *fd, WorkSpace *workspace, const Main
{
link_list(fd, BKE_workspace_layouts_get(workspace));
link_list(fd, &workspace->hook_layout_relations);
+ link_list(fd, &workspace->scene_viewlayer_relations);
link_list(fd, BKE_workspace_transform_orientations_get(workspace));
for (WorkSpaceDataRelation *relation = workspace->hook_layout_relations.first;
@@ -2881,7 +2890,7 @@ static void direct_link_workspace(FileData *fd, WorkSpace *workspace, const Main
if (ID_IS_LINKED(&workspace->id)) {
/* Appending workspace so render layer is likely from a different scene. Unset
* now, when activating workspace later we set a valid one from current scene. */
- BKE_workspace_view_layer_set(workspace, NULL);
+ BKE_workspace_relations_free(&workspace->scene_viewlayer_relations);
}
/* Same issue/fix as in direct_link_workspace_link_scene_data: Can't read workspace data
@@ -6134,13 +6143,19 @@ static void direct_link_layer_collections(FileData *fd, ListBase *lb)
* Workspaces store a render layer pointer which can only be read after scene is read.
*/
static void direct_link_workspace_link_scene_data(
- FileData *fd, const Scene *scene, const ListBase *workspaces)
+ FileData *fd, Scene *scene, const ListBase *workspaces)
{
for (WorkSpace *workspace = workspaces->first; workspace; workspace = workspace->id.next) {
- ViewLayer *layer = newdataadr(fd, BKE_workspace_view_layer_get(workspace));
- /* only set when layer is from the scene we read */
- if (layer && (BLI_findindex(&scene->view_layers, layer) != -1)) {
- BKE_workspace_view_layer_set(workspace, layer);
+ for (WorkSpaceDataRelation *relation = workspace->scene_viewlayer_relations.first;
+ relation != NULL;
+ relation = relation->next)
+ {
+ ViewLayer *layer = newdataadr(fd, relation->value);
+ if (layer) {
+ BLI_assert(BLI_findindex(&scene->view_layers, layer) != -1);
+ /* relation->parent is set in lib_link_workspaces */
+ relation->value = layer;
+ }
}
}
}
@@ -7175,7 +7190,7 @@ void blo_lib_link_restore(Main *newmain, wmWindowManager *curwm, Scene *curscene
for (WorkSpaceLayout *layout = layouts->first; layout; layout = layout->next) {
lib_link_workspace_layout_restore(id_map, newmain, layout);
}
- BKE_workspace_view_layer_set(workspace, cur_view_layer);
+ BKE_workspace_view_layer_set(workspace, cur_view_layer, curscene);
}
for (wmWindow *win = curwm->windows.first; win; win = win->next) {
diff --git a/source/blender/blenloader/intern/versioning_280.c b/source/blender/blenloader/intern/versioning_280.c
index 8da4fef7b21..3b5e248f58b 100644
--- a/source/blender/blenloader/intern/versioning_280.c
+++ b/source/blender/blenloader/intern/versioning_280.c
@@ -86,8 +86,9 @@ static void do_version_workspaces_create_from_screens(Main *bmain)
{
for (bScreen *screen = bmain->screen.first; screen; screen = screen->id.next) {
const bScreen *screen_parent = screen_parent_find(screen);
+ Scene *scene = screen->scene;
WorkSpace *workspace;
- ViewLayer *layer = BKE_view_layer_from_scene_get(screen->scene);
+ ViewLayer *layer = BKE_view_layer_from_scene_get(scene);
ListBase *transform_orientations;
if (screen_parent) {
@@ -100,7 +101,7 @@ static void do_version_workspaces_create_from_screens(Main *bmain)
workspace = BKE_workspace_add(bmain, screen->id.name + 2);
}
BKE_workspace_layout_add(workspace, screen, screen->id.name + 2);
- BKE_workspace_view_layer_set(workspace, layer);
+ BKE_workspace_view_layer_set(workspace, layer, scene);
#ifdef WITH_CLAY_ENGINE
BLI_strncpy(workspace->view_render.engine_id, RE_engine_id_BLENDER_CLAY,
@@ -111,7 +112,7 @@ static void do_version_workspaces_create_from_screens(Main *bmain)
#endif
transform_orientations = BKE_workspace_transform_orientations_get(workspace);
- BLI_duplicatelist(transform_orientations, &screen->scene->transform_spaces);
+ BLI_duplicatelist(transform_orientations, &scene->transform_spaces);
}
}
diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c
index b20f12e7e70..08ec2231e38 100644
--- a/source/blender/blenloader/intern/writefile.c
+++ b/source/blender/blenloader/intern/writefile.c
@@ -1138,7 +1138,7 @@ static void current_screen_compat(
*r_screen = (window) ? BKE_workspace_active_screen_get(window->workspace_hook) : NULL;
*r_scene = (window) ? window->scene : NULL;
- *r_render_layer = (window) ? BKE_workspace_view_layer_get(workspace) : NULL;
+ *r_render_layer = (window) ? BKE_workspace_view_layer_get(workspace, *r_scene) : NULL;
}
typedef struct RenderInfo {
@@ -3778,6 +3778,7 @@ static void write_workspace(WriteData *wd, WorkSpace *workspace)
writestruct(wd, ID_WS, WorkSpace, 1, workspace);
writelist(wd, DATA, WorkSpaceLayout, layouts);
writelist(wd, DATA, WorkSpaceDataRelation, &workspace->hook_layout_relations);
+ writelist(wd, DATA, WorkSpaceDataRelation, &workspace->scene_viewlayer_relations);
writelist(wd, DATA, TransformOrientation, transform_orientations);
}
diff --git a/source/blender/editors/include/ED_screen.h b/source/blender/editors/include/ED_screen.h
index c1655cbccc2..23e65011387 100644
--- a/source/blender/editors/include/ED_screen.h
+++ b/source/blender/editors/include/ED_screen.h
@@ -136,6 +136,7 @@ void ED_screen_preview_render(const struct bScreen *screen, int size_x, int s
struct WorkSpace *ED_workspace_add(
struct Main *bmain,
const char *name,
+ Scene *scene,
ViewLayer *act_render_layer,
struct ViewRender *view_render) ATTR_NONNULL();
bool ED_workspace_change(
@@ -152,7 +153,8 @@ bool ED_workspace_delete(
void ED_workspace_scene_data_sync(
struct WorkSpaceInstanceHook *hook, Scene *scene) ATTR_NONNULL();
void ED_workspace_view_layer_unset(
- const struct Main *bmain, const ViewLayer *layer_unset, ViewLayer *layer_new) ATTR_NONNULL(1, 2);
+ const struct Main *bmain, struct Scene *scene,
+ const ViewLayer *layer_unset, ViewLayer *layer_new) ATTR_NONNULL(1, 2);
struct WorkSpaceLayout *ED_workspace_layout_add(
struct WorkSpace *workspace,
struct wmWindow *win,
diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c
index 804d0ed1f0d..5697c48d381 100644
--- a/source/blender/editors/object/object_edit.c
+++ b/source/blender/editors/object/object_edit.c
@@ -1516,15 +1516,13 @@ bool ED_object_mode_compat_set(bContext *C, Object *ob, int mode, ReportList *re
{
bool ok;
if (!ELEM(ob->mode, mode, OB_MODE_OBJECT)) {
- WorkSpace *workspace = CTX_wm_workspace(C);
const char *opstring = object_mode_op_string(ob->mode);
WM_operator_name_call(C, opstring, WM_OP_EXEC_REGION_WIN, NULL);
#ifdef USE_WORKSPACE_MODE
- BKE_workspace_object_mode_set(workspace, ob->mode);
-#else
- UNUSED_VARS(workspace);
+ BKE_workspace_object_mode_set(CTX_wm_workspace(C), CTX_data_scene(C), ob->mode);
#endif
+
ok = ELEM(ob->mode, mode, OB_MODE_OBJECT);
if (!ok) {
wmOperatorType *ot = WM_operatortype_find(opstring, false);
@@ -1648,7 +1646,7 @@ void ED_object_toggle_modes(bContext *C, int mode)
#ifdef USE_WORKSPACE_MODE
Object *ob = CTX_data_active_object(C);
if (ob) {
- BKE_workspace_object_mode_set(workspace, ob->mode);
+ BKE_workspace_object_mode_set(workspace, CTX_data_scene(C), ob->mode);
}
#endif
}
diff --git a/source/blender/editors/object/object_select.c b/source/blender/editors/object/object_select.c
index 47e63cb43e5..552380cebdb 100644
--- a/source/blender/editors/object/object_select.c
+++ b/source/blender/editors/object/object_select.c
@@ -123,8 +123,7 @@ void ED_object_base_activate(bContext *C, Base *base)
if (base) {
#ifdef USE_WORKSPACE_MODE
- WorkSpace *workspace = CTX_wm_workspace(C);
- BKE_workspace_object_mode_set(workspace, base->object->mode);
+ BKE_workspace_object_mode_set(CTX_wm_workspace(C), CTX_data_scene(C), base->object->mode);
#endif
WM_event_add_notifier(C, NC_SCENE | ND_OB_ACTIVE, view_layer);
}
diff --git a/source/blender/editors/scene/scene_edit.c b/source/blender/editors/scene/scene_edit.c
index c7f04a0e2f9..812f9a736bf 100644
--- a/source/blender/editors/scene/scene_edit.c
+++ b/source/blender/editors/scene/scene_edit.c
@@ -118,16 +118,20 @@ void ED_scene_exit(bContext *C)
ED_object_editmode_exit(C, EM_FREEDATA | EM_DO_UNDO);
}
+static ViewLayer *scene_change_get_new_view_layer(const WorkSpace *workspace, const Scene *scene_new)
+{
+ ViewLayer *layer_new = BKE_workspace_view_layer_get(workspace, scene_new);
+ return layer_new ? layer_new : BKE_view_layer_from_scene_get(scene_new);
+}
+
void ED_scene_changed_update(Main *bmain, bContext *C, Scene *scene_new, const bScreen *active_screen)
{
- /* XXX Just using active scene render-layer for workspace when switching,
- * but workspace should remember the last one set. Could store render-layer
- * per window-workspace combination (using WorkSpaceDataRelation) */
- ViewLayer *layer_new = BLI_findlink(&scene_new->view_layers, scene_new->active_view_layer);
+ WorkSpace *workspace = CTX_wm_workspace(C);
+ ViewLayer *layer_new = scene_change_get_new_view_layer(workspace, scene_new);
Depsgraph *depsgraph = BKE_scene_get_depsgraph(scene_new, layer_new, true);
CTX_data_scene_set(C, scene_new);
- BKE_workspace_view_layer_set(CTX_wm_workspace(C), layer_new);
+ BKE_workspace_view_layer_set(workspace, layer_new, scene_new);
BKE_scene_set_background(bmain, scene_new);
DEG_graph_relations_update(depsgraph, bmain, scene_new, layer_new);
DEG_on_visible_update(bmain, false);
@@ -186,7 +190,8 @@ bool ED_scene_view_layer_delete(
BLI_assert(BLI_listbase_is_empty(&scene->view_layers) == false);
scene->active_view_layer = 0;
- ED_workspace_view_layer_unset(bmain, layer, scene->view_layers.first);
+ ED_workspace_view_layer_unset(bmain, scene, layer, scene->view_layers.first);
+ BKE_workspace_view_layer_remove_references(bmain, layer);
view_layer_remove_unset_nodetrees(bmain, scene, layer);
BKE_view_layer_free(layer);
diff --git a/source/blender/editors/screen/screen_context.c b/source/blender/editors/screen/screen_context.c
index d84f256bc32..4c62253bef6 100644
--- a/source/blender/editors/screen/screen_context.c
+++ b/source/blender/editors/screen/screen_context.c
@@ -91,7 +91,7 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
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->basact ? view_layer->basact->object : NULL;
+ Object *obact = (view_layer && view_layer->basact) ? view_layer->basact->object : NULL;
if (CTX_data_dir(member)) {
CTX_data_dir_set(result, screen_context_dir);
diff --git a/source/blender/editors/screen/workspace_edit.c b/source/blender/editors/screen/workspace_edit.c
index 84288740df8..00dc1003121 100644
--- a/source/blender/editors/screen/workspace_edit.c
+++ b/source/blender/editors/screen/workspace_edit.c
@@ -71,15 +71,16 @@
* \{ */
WorkSpace *ED_workspace_add(
- Main *bmain, const char *name, ViewLayer *act_view_layer, ViewRender *view_render)
+ Main *bmain, const char *name, Scene *scene,
+ ViewLayer *act_view_layer, ViewRender *view_render)
{
WorkSpace *workspace = BKE_workspace_add(bmain, name);
- BKE_workspace_view_layer_set(workspace, act_view_layer);
+ BKE_workspace_view_layer_set(workspace, act_view_layer, scene);
BKE_viewrender_copy(&workspace->view_render, view_render);
#ifdef USE_WORKSPACE_MODE
- BKE_workspace_object_mode_set(workspace, OB_MODE_OBJECT);
+ BKE_workspace_object_mode_set(workspace, scene, OB_MODE_OBJECT);
#endif
return workspace;
@@ -94,8 +95,9 @@ static void workspace_change_update_mode(
const WorkSpace *workspace_old, const WorkSpace *workspace_new,
bContext *C, Object *ob_act, ReportList *reports)
{
- eObjectMode mode_old = BKE_workspace_object_mode_get(workspace_old);
- eObjectMode mode_new = BKE_workspace_object_mode_get(workspace_new);
+ const Scene *scene = CTX_data_scene(C);
+ eObjectMode mode_old = BKE_workspace_object_mode_get(workspace_old, scene);
+ eObjectMode mode_new = BKE_workspace_object_mode_get(workspace_new, scene);
if (mode_old != mode_new) {
ED_object_mode_compat_set(C, ob_act, mode_new, reports);
@@ -105,10 +107,11 @@ static void workspace_change_update_mode(
#endif
static void workspace_change_update_view_layer(
- WorkSpace *workspace_new, const WorkSpace *workspace_old)
+ WorkSpace *workspace_new, const WorkSpace *workspace_old,
+ Scene *scene)
{
- if (!BKE_workspace_view_layer_get(workspace_new)) {
- BKE_workspace_view_layer_set(workspace_new, BKE_workspace_view_layer_get(workspace_old));
+ if (!BKE_workspace_view_layer_get(workspace_new, scene)) {
+ BKE_workspace_view_layer_set(workspace_new, BKE_workspace_view_layer_get(workspace_old, scene), scene);
}
}
@@ -117,7 +120,7 @@ static void workspace_change_update(
bContext *C, wmWindowManager *wm)
{
/* needs to be done before changing mode! (to ensure right context) */
- workspace_change_update_view_layer(workspace_new, workspace_old);
+ workspace_change_update_view_layer(workspace_new, workspace_old, CTX_data_scene(C));
#ifdef USE_WORKSPACE_MODE
workspace_change_update_mode(workspace_old, workspace_new, C, CTX_data_active_object(C), &wm->reports);
#else
@@ -199,7 +202,7 @@ bool ED_workspace_change(
screen_changed_update(C, win, screen_new);
workspace_change_update(workspace_new, workspace_old, C, wm);
- BLI_assert(BKE_workspace_view_layer_get(workspace_new) != NULL);
+ BLI_assert(BKE_workspace_view_layer_get(workspace_new, CTX_data_scene(C)) != NULL);
BLI_assert(CTX_wm_workspace(C) == workspace_new);
WM_toolsystem_unlink(C, workspace_old);
@@ -220,15 +223,16 @@ WorkSpace *ED_workspace_duplicate(
{
WorkSpaceLayout *layout_active_old = BKE_workspace_active_layout_get(win->workspace_hook);
ListBase *layouts_old = BKE_workspace_layouts_get(workspace_old);
+ Scene *scene = WM_window_get_active_scene(win);
WorkSpace *workspace_new = ED_workspace_add(
- bmain, workspace_old->id.name + 2,
- BKE_workspace_view_layer_get(workspace_old),
+ bmain, workspace_old->id.name + 2, scene,
+ BKE_workspace_view_layer_get(workspace_old, scene),
&workspace_old->view_render);
ListBase *transform_orientations_old = BKE_workspace_transform_orientations_get(workspace_old);
ListBase *transform_orientations_new = BKE_workspace_transform_orientations_get(workspace_new);
#ifdef USE_WORKSPACE_MODE
- BKE_workspace_object_mode_set(workspace_new, BKE_workspace_object_mode_get(workspace_old));
+ BKE_workspace_object_mode_set(workspace_new, scene, BKE_workspace_object_mode_get(workspace_old, scene));
#endif
BLI_duplicatelist(transform_orientations_new, transform_orientations_old);
@@ -279,11 +283,12 @@ void ED_workspace_scene_data_sync(
}
void ED_workspace_view_layer_unset(
- const Main *bmain, const ViewLayer *layer_unset, ViewLayer *layer_new)
+ const Main *bmain, Scene *scene,
+ const ViewLayer *layer_unset, ViewLayer *layer_new)
{
for (WorkSpace *workspace = bmain->workspaces.first; workspace; workspace = workspace->id.next) {
- if (BKE_workspace_view_layer_get(workspace) == layer_unset) {
- BKE_workspace_view_layer_set(workspace, layer_new);
+ if (BKE_workspace_view_layer_get(workspace, scene) == layer_unset) {
+ BKE_workspace_view_layer_set(workspace, layer_new, scene);
}
}
}
diff --git a/source/blender/makesdna/DNA_workspace_types.h b/source/blender/makesdna/DNA_workspace_types.h
index 1fc6acb8c2c..11a67692b8b 100644
--- a/source/blender/makesdna/DNA_workspace_types.h
+++ b/source/blender/makesdna/DNA_workspace_types.h
@@ -84,6 +84,7 @@ typedef struct WorkSpace {
/* Store for each hook (so for each window) which layout has
* been activated the last time this workspace was visible. */
ListBase hook_layout_relations DNA_PRIVATE_WORKSPACE_READ_WRITE; /* WorkSpaceDataRelation */
+ ListBase scene_viewlayer_relations DNA_PRIVATE_WORKSPACE_READ_WRITE; /* WorkSpaceDataRelation */
/* Custom transform orientations */
ListBase transform_orientations DNA_PRIVATE_WORKSPACE;
diff --git a/source/blender/makesrna/intern/rna_wm.c b/source/blender/makesrna/intern/rna_wm.c
index 7d821ee407b..36f07db727b 100644
--- a/source/blender/makesrna/intern/rna_wm.c
+++ b/source/blender/makesrna/intern/rna_wm.c
@@ -36,6 +36,8 @@
#include "BLT_translation.h"
+#include "BKE_workspace.h"
+
#include "RNA_access.h"
#include "RNA_define.h"
#include "RNA_enum_types.h"
@@ -467,6 +469,7 @@ const EnumPropertyItem rna_enum_wm_report_items[] = {
#include "WM_api.h"
+#include "DNA_object_types.h"
#include "DNA_workspace_types.h"
#include "ED_screen.h"
@@ -475,7 +478,6 @@ const EnumPropertyItem rna_enum_wm_report_items[] = {
#include "BKE_global.h"
#include "BKE_idprop.h"
-#include "BKE_workspace.h"
#include "MEM_guardedalloc.h"
@@ -755,6 +757,49 @@ static void rna_workspace_screen_update(bContext *C, PointerRNA *ptr)
}
}
+static PointerRNA rna_Window_view_layer_get(PointerRNA *ptr)
+{
+ wmWindow *win = ptr->data;
+ 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);
+ PointerRNA scene_ptr;
+
+ RNA_id_pointer_create(&scene->id, &scene_ptr);
+ return rna_pointer_inherit_refine(&scene_ptr, &RNA_ViewLayer, view_layer);
+}
+
+static void rna_Window_view_layer_set(PointerRNA *ptr, PointerRNA value)
+{
+ wmWindow *win = ptr->data;
+ Scene *scene = WM_window_get_active_scene(win);
+ WorkSpace *workspace = WM_window_get_active_workspace(win);
+
+ BKE_workspace_view_layer_set(workspace, value.data, scene);
+}
+
+#ifdef USE_WORKSPACE_MODE
+
+static int rna_Window_object_mode_get(PointerRNA *ptr)
+{
+ wmWindow *win = ptr->data;
+ Scene *scene = WM_window_get_active_scene(win);
+ WorkSpace *workspace = WM_window_get_active_workspace(win);
+
+ return (int)BKE_workspace_object_mode_get(workspace, scene);
+}
+
+static void rna_Window_object_mode_set(PointerRNA *ptr, int value)
+{
+ wmWindow *win = ptr->data;
+ Scene *scene = WM_window_get_active_scene(win);
+ WorkSpace *workspace = WM_window_get_active_workspace(win);
+
+ BKE_workspace_object_mode_set(workspace, scene, value);
+}
+
+#endif /* USE_WORKSPACE_MODE */
+
static PointerRNA rna_KeyMapItem_properties_get(PointerRNA *ptr)
{
wmKeyMapItem *kmi = ptr->data;
@@ -2024,6 +2069,20 @@ static void rna_def_window(BlenderRNA *brna)
RNA_def_property_flag(prop, PROP_NEVER_NULL | PROP_EDITABLE | PROP_CONTEXT_UPDATE);
RNA_def_property_update(prop, 0, "rna_workspace_screen_update");
+ prop = RNA_def_property(srna, "view_layer", PROP_POINTER, PROP_NONE);
+ RNA_def_property_struct_type(prop, "ViewLayer");
+ RNA_def_property_pointer_funcs(prop, "rna_Window_view_layer_get", "rna_Window_view_layer_set", NULL, NULL);
+ RNA_def_property_ui_text(prop, "Active View Layer", "The active workspace view layer showing in the window");
+ RNA_def_property_flag(prop, PROP_EDITABLE | PROP_NEVER_NULL);
+ RNA_def_property_update(prop, NC_SCREEN | ND_LAYER, NULL);
+
+#ifdef USE_WORKSPACE_MODE
+ prop = RNA_def_property(srna, "object_mode", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_items(prop, rna_enum_object_mode_items);
+ RNA_def_property_enum_funcs(prop, "rna_Window_object_mode_get", "rna_Window_object_mode_set", NULL);
+ RNA_def_property_ui_text(prop, "Mode", "Object interaction mode used in this window");
+#endif
+
prop = RNA_def_property(srna, "x", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "posx");
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
diff --git a/source/blender/makesrna/intern/rna_workspace.c b/source/blender/makesrna/intern/rna_workspace.c
index 7e7b2eeccd7..0bed91f2807 100644
--- a/source/blender/makesrna/intern/rna_workspace.c
+++ b/source/blender/makesrna/intern/rna_workspace.c
@@ -67,22 +67,6 @@ static PointerRNA rna_workspace_screens_item_get(CollectionPropertyIterator *ite
return rna_pointer_inherit_refine(&iter->parent, &RNA_Screen, screen);
}
-#ifdef USE_WORKSPACE_MODE
-
-static int rna_workspace_object_mode_get(PointerRNA *ptr)
-{
- WorkSpace *workspace = ptr->data;
- return (int)BKE_workspace_object_mode_get(workspace);
-}
-
-static void rna_workspace_object_mode_set(PointerRNA *ptr, int value)
-{
- WorkSpace *workspace = ptr->data;
- BKE_workspace_object_mode_set(workspace, value);
-}
-
-#endif /* USE_WORKSPACE_MODE */
-
void rna_workspace_transform_orientations_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
{
WorkSpace *workspace = ptr->id.data;
@@ -95,30 +79,6 @@ static PointerRNA rna_workspace_transform_orientations_item_get(CollectionProper
return rna_pointer_inherit_refine(&iter->parent, &RNA_TransformOrientation, transform_orientation);
}
-static PointerRNA rna_workspace_view_layer_get(PointerRNA *ptr)
-{
- WorkSpace *workspace = ptr->data;
- ViewLayer *view_layer = BKE_workspace_view_layer_get(workspace);
-
- /* XXX hmrf... lookup in getter... but how could we avoid it? */
- for (Scene *scene = G.main->scene.first; scene; scene = scene->id.next) {
- if (BLI_findindex(&scene->view_layers, view_layer) != -1) {
- PointerRNA scene_ptr;
-
- RNA_id_pointer_create(&scene->id, &scene_ptr);
- return rna_pointer_inherit_refine(&scene_ptr, &RNA_ViewLayer, view_layer);
- }
- }
-
- return PointerRNA_NULL;
-}
-
-static void rna_workspace_view_layer_set(PointerRNA *ptr, PointerRNA value)
-{
- WorkSpace *workspace = ptr->data;
- BKE_workspace_view_layer_set(workspace, value.data);
-}
-
#else /* RNA_RUNTIME */
static void rna_def_workspace(BlenderRNA *brna)
@@ -139,13 +99,6 @@ static void rna_def_workspace(BlenderRNA *brna)
"rna_workspace_screens_item_get", NULL, NULL, NULL, NULL);
RNA_def_property_ui_text(prop, "Screens", "Screen layouts of a workspace");
-#ifdef USE_WORKSPACE_MODE
- prop = RNA_def_property(srna, "object_mode", PROP_ENUM, PROP_NONE);
- RNA_def_property_enum_items(prop, rna_enum_object_mode_items);
- RNA_def_property_enum_funcs(prop, "rna_workspace_object_mode_get", "rna_workspace_object_mode_set", NULL);
- RNA_def_property_ui_text(prop, "Mode", "Object interaction mode");
-#endif
-
prop = RNA_def_property(srna, "tool_keymap", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "tool.keymap");
RNA_def_property_ui_text(prop, "Active Tool", "Currently active tool keymap");
@@ -168,14 +121,6 @@ static void rna_def_workspace(BlenderRNA *brna)
"rna_workspace_transform_orientations_item_get", NULL, NULL, NULL, NULL);
RNA_def_property_ui_text(prop, "Transform Orientations", "");
- prop = RNA_def_property(srna, "view_layer", PROP_POINTER, PROP_NONE);
- RNA_def_property_struct_type(prop, "ViewLayer");
- RNA_def_property_pointer_funcs(prop, "rna_workspace_view_layer_get", "rna_workspace_view_layer_set",
- NULL, NULL);
- RNA_def_property_ui_text(prop, "Active View Layer", "The active view layer used in this workspace");
- RNA_def_property_flag(prop, PROP_EDITABLE | PROP_NEVER_NULL);
- RNA_def_property_update(prop, NC_SCREEN | ND_LAYER, NULL);
-
/* View Render */
prop = RNA_def_property(srna, "view_render", PROP_POINTER, PROP_NONE);
RNA_def_property_flag(prop, PROP_NEVER_NULL);