diff options
32 files changed, 250 insertions, 393 deletions
diff --git a/source/blender/blenkernel/BKE_layer.h b/source/blender/blenkernel/BKE_layer.h index 9e89033894d..db0e5f21284 100644 --- a/source/blender/blenkernel/BKE_layer.h +++ b/source/blender/blenkernel/BKE_layer.h @@ -58,7 +58,7 @@ struct WorkSpace; struct ViewLayer *BKE_view_layer_default_view(const struct Scene *scene); struct ViewLayer *BKE_view_layer_default_render(const struct Scene *scene); -struct ViewLayer *BKE_view_layer_from_workspace_get(const struct Scene *scene, const struct WorkSpace *workspace); +struct ViewLayer *BKE_view_layer_find(const struct Scene *scene, const char *layer_name); struct ViewLayer *BKE_view_layer_add(struct Scene *scene, const char *name); /* DEPRECATED */ diff --git a/source/blender/blenkernel/BKE_workspace.h b/source/blender/blenkernel/BKE_workspace.h index 03d24ac53d1..4f4ae9f375b 100644 --- a/source/blender/blenkernel/BKE_workspace.h +++ b/source/blender/blenkernel/BKE_workspace.h @@ -54,23 +54,11 @@ void BKE_workspace_layout_remove( void BKE_workspace_relations_free( ListBase *relation_list); -void BKE_workspace_scene_relations_free_invalid( - struct WorkSpace *workspace); /* -------------------------------------------------------------------- */ /* General Utils */ -void BKE_workspace_view_layer_rename( - const struct Main *bmain, - const struct Scene *scene, - const char *old_name, - const char *new_name) ATTR_NONNULL(); - -void BKE_workspace_view_layer_remove( - const struct Main *bmain, - const struct ViewLayer *view_layer) ATTR_NONNULL(); - struct WorkSpaceLayout *BKE_workspace_layout_find( const struct WorkSpace *workspace, const struct bScreen *screen) ATTR_NONNULL() ATTR_WARN_UNUSED_RESULT; struct WorkSpaceLayout *BKE_workspace_layout_find_global( @@ -97,17 +85,6 @@ struct bScreen *BKE_workspace_active_screen_get(const struct WorkSpaceInstanceHo void BKE_workspace_active_screen_set( struct WorkSpaceInstanceHook *hook, struct WorkSpace *workspace, struct bScreen *screen) SETTER_ATTRS; -struct Base *BKE_workspace_active_base_get(const struct WorkSpace *workspace, const struct Scene *scene); -struct ViewLayer *BKE_workspace_view_layer_get( - const struct WorkSpace *workspace, - const struct Scene *scene) GETTER_ATTRS; -struct ViewLayer *BKE_workspace_view_layer_exists( - 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; @@ -121,11 +98,6 @@ struct WorkSpaceLayout *BKE_workspace_hook_layout_for_workspace_get( void BKE_workspace_hook_layout_for_workspace_set( struct WorkSpaceInstanceHook *hook, struct WorkSpace *workspace, struct WorkSpaceLayout *layout) ATTR_NONNULL(); -/* Update / evaluate */ -void BKE_workspace_update_tagged(struct Main *bmain, - struct WorkSpace *workspace, - struct Scene *scene); - bool BKE_workspace_owner_id_check( const struct WorkSpace *workspace, const char *owner_id) ATTR_NONNULL(); diff --git a/source/blender/blenkernel/intern/context.c b/source/blender/blenkernel/intern/context.c index ee907fa496f..1aaf5e4f485 100644 --- a/source/blender/blenkernel/intern/context.c +++ b/source/blender/blenkernel/intern/context.c @@ -926,9 +926,17 @@ ViewLayer *CTX_data_view_layer(const bContext *C) if (ctx_data_pointer_verify(C, "view_layer", (void *)&view_layer)) { return view_layer; } - else { - return BKE_view_layer_from_workspace_get(CTX_data_scene(C), CTX_wm_workspace(C)); + + wmWindow *win = CTX_wm_window(C); + Scene *scene = CTX_data_scene(C); + if (win) { + view_layer = BKE_view_layer_find(scene, win->view_layer_name); + if (view_layer) { + return view_layer; + } } + + return BKE_view_layer_default_view(scene); } RenderEngineType *CTX_data_engine_type(const bContext *C) diff --git a/source/blender/blenkernel/intern/layer.c b/source/blender/blenkernel/intern/layer.c index 22188d25df5..80329a1d328 100644 --- a/source/blender/blenkernel/intern/layer.c +++ b/source/blender/blenkernel/intern/layer.c @@ -42,7 +42,6 @@ #include "BKE_layer.h" #include "BKE_main.h" #include "BKE_node.h" -#include "BKE_workspace.h" #include "BKE_object.h" #include "DNA_group_types.h" @@ -130,17 +129,22 @@ ViewLayer *BKE_view_layer_default_render(const Scene *scene) return scene->view_layers.first; } -/** - * Returns the ViewLayer to be used for drawing, outliner, and other context related areas. - */ -ViewLayer *BKE_view_layer_from_workspace_get(const struct Scene *scene, const struct WorkSpace *workspace) +/* Returns view layer with matching name, or NULL if not found. */ +ViewLayer *BKE_view_layer_find(const Scene *scene, const char *layer_name) { - return BKE_workspace_view_layer_get(workspace, scene); + for (ViewLayer *view_layer = scene->view_layers.first; view_layer; view_layer = view_layer->next) { + if (STREQ(view_layer->name, layer_name)) { + return view_layer; + } + } + + return NULL; } /** - * This is a placeholder to know which areas of the code need to be addressed for the Workspace changes. - * Never use this, you should either use BKE_view_layer_from_workspace_get or get ViewLayer explicitly. + * This is a placeholder to know which areas of the code need to be addressed + * for the Workspace changes. Never use this, you should typically get the + * active layer from the context or window. */ ViewLayer *BKE_view_layer_context_active_PLACEHOLDER(const Scene *scene) { @@ -418,9 +422,15 @@ void BKE_view_layer_rename(Main *bmain, Scene *scene, ViewLayer *view_layer, con } } - /* fix all the animation data and workspace which may link to this */ + /* fix all the animation data and windows which may link to this */ BKE_animdata_fix_paths_rename_all(NULL, "view_layers", oldname, view_layer->name); - BKE_workspace_view_layer_rename(bmain, scene, oldname, view_layer->name); + + wmWindowManager *wm = bmain->wm.first; + for (wmWindow *win = wm->windows.first; win; win = win->next) { + if (win->scene == scene && STREQ(win->view_layer_name, oldname)) { + STRNCPY(win->view_layer_name, view_layer->name); + } + } /* Dependency graph uses view layer name based lookups. */ DEG_id_tag_update(&scene->id, 0); diff --git a/source/blender/blenkernel/intern/library_query.c b/source/blender/blenkernel/intern/library_query.c index 54b73dad982..93fdd3349bf 100644 --- a/source/blender/blenkernel/intern/library_query.c +++ b/source/blender/blenkernel/intern/library_query.c @@ -936,10 +936,6 @@ void BKE_library_foreach_ID_link(Main *bmain, ID *id, LibraryIDLinkCallback call /* allow callback to set a different screen */ BKE_workspace_layout_screen_set(layout, screen); } - - for (WorkSpaceSceneRelation *relation = workspace->scene_layer_relations.first; relation; relation = relation->next) { - CALLBACK_INVOKE(relation->scene, IDWALK_CB_NOP); - } break; } case ID_GD: diff --git a/source/blender/blenkernel/intern/workspace.c b/source/blender/blenkernel/intern/workspace.c index f0f57e8e56c..783baebd525 100644 --- a/source/blender/blenkernel/intern/workspace.c +++ b/source/blender/blenkernel/intern/workspace.c @@ -157,7 +157,6 @@ WorkSpace *BKE_workspace_add(Main *bmain, const char *name) void BKE_workspace_free(WorkSpace *workspace) { BKE_workspace_relations_free(&workspace->hook_layout_relations); - BLI_freelistN(&workspace->scene_layer_relations); BLI_freelistN(&workspace->owner_ids); BLI_freelistN(&workspace->layouts); @@ -267,48 +266,9 @@ void BKE_workspace_relations_free( } } -void BKE_workspace_scene_relations_free_invalid( - WorkSpace *workspace) -{ - for (WorkSpaceSceneRelation *relation = workspace->scene_layer_relations.first, *relation_next; relation; relation = relation_next) { - relation_next = relation->next; - - if (relation->scene == NULL) { - BLI_freelinkN(&workspace->scene_layer_relations, relation); - } - else if (!BLI_findstring(&relation->scene->view_layers, relation->view_layer, offsetof(ViewLayer, name))) { - BLI_freelinkN(&workspace->scene_layer_relations, relation); - } - } -} - /* -------------------------------------------------------------------- */ /* General Utils */ -void BKE_workspace_view_layer_rename( - const Main *bmain, - const Scene *scene, - const char *old_name, - const char *new_name) -{ - for (WorkSpace *workspace = bmain->workspaces.first; workspace; workspace = workspace->id.next) { - for (WorkSpaceSceneRelation *relation = workspace->scene_layer_relations.first; relation; relation = relation->next) { - if (relation->scene == scene && STREQ(relation->view_layer, old_name)) { - STRNCPY(relation->view_layer, new_name); - } - } - } -} - -void BKE_workspace_view_layer_remove( - const Main *bmain, - const ViewLayer *UNUSED(view_layer)) -{ - for (WorkSpace *workspace = bmain->workspaces.first; workspace; workspace = workspace->id.next) { - BKE_workspace_scene_relations_free_invalid(workspace); - } -} - WorkSpaceLayout *BKE_workspace_layout_find( const WorkSpace *workspace, const bScreen *screen) { @@ -429,46 +389,6 @@ void BKE_workspace_active_screen_set(WorkSpaceInstanceHook *hook, WorkSpace *wor BKE_workspace_hook_layout_for_workspace_set(hook, workspace, layout); } -Base *BKE_workspace_active_base_get(const WorkSpace *workspace, const Scene *scene) -{ - ViewLayer *view_layer = BKE_workspace_view_layer_get(workspace, scene); - return view_layer->basact; -} - -ViewLayer *BKE_workspace_view_layer_exists(const WorkSpace *workspace, const Scene *scene) -{ - WorkSpaceSceneRelation *relation = BLI_findptr(&workspace->scene_layer_relations, scene, offsetof(WorkSpaceSceneRelation, scene)); - return (relation) ? BLI_findstring(&scene->view_layers, relation->view_layer, offsetof(ViewLayer, name)) : NULL; -} - -ViewLayer *BKE_workspace_view_layer_get(const WorkSpace *workspace, const Scene *scene) -{ - ViewLayer *layer = BKE_workspace_view_layer_exists(workspace, scene); - - if (layer == NULL) { - BKE_workspace_view_layer_set((WorkSpace *)workspace, scene->view_layers.first, (Scene *)scene); - layer = scene->view_layers.first; - } - - return layer; -} - -void BKE_workspace_view_layer_set(WorkSpace *workspace, ViewLayer *layer, Scene *scene) -{ - WorkSpaceSceneRelation *relation = BLI_findptr(&workspace->scene_layer_relations, scene, offsetof(WorkSpaceSceneRelation, scene)); - if (relation == NULL) { - relation = MEM_callocN(sizeof(*relation), __func__); - } - else { - BLI_remlink(&workspace->scene_layer_relations, relation); - } - - /* (Re)insert at the head of the list, for faster lookups. */ - relation->scene = scene; - STRNCPY(relation->view_layer, layer->name); - BLI_addhead(&workspace->scene_layer_relations, relation); -} - ListBase *BKE_workspace_layouts_get(WorkSpace *workspace) { return &workspace->layouts; @@ -504,27 +424,6 @@ void BKE_workspace_hook_layout_for_workspace_set( workspace_relation_ensure_updated(&workspace->hook_layout_relations, hook, layout); } -/* Update / evaluate */ - -void BKE_workspace_update_tagged(Main *bmain, - WorkSpace *workspace, - Scene *scene) -{ - ViewLayer *view_layer = BKE_workspace_view_layer_get(workspace, scene); - struct Depsgraph *depsgraph = BKE_scene_get_depsgraph(scene, - view_layer, - true); - /* TODO(sergey): For now all dependency graphs which are evaluated from - * workspace are considered active. This will work all fine with "locked" - * view layer and time across windows. This is to be granted separately, - * and for until then we have to accept ambiguities when object is shared - * across visible view layers and has overrides on it. - */ - DEG_make_active(depsgraph); - BKE_scene_graph_update_tagged(depsgraph, bmain); -} - - bool BKE_workspace_owner_id_check( const WorkSpace *workspace, const char *owner_id) { diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 4fa897bb689..b3a2d2f0b0b 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -2866,19 +2866,6 @@ static void direct_link_cachefile(FileData *fd, CacheFile *cache_file) /* ************ READ WORKSPACES *************** */ -static void lib_link_workspace_scene_data(FileData *fd, WorkSpace *workspace) -{ - for (WorkSpaceSceneRelation *relation = workspace->scene_layer_relations.first; - relation != NULL; - relation = relation->next) - { - relation->scene = newlibadr(fd, workspace->id.lib, relation->scene); - } - - /* Free any relations that got lost due to missing datablocks. */ - BKE_workspace_scene_relations_free_invalid(workspace); -} - static void lib_link_workspaces(FileData *fd, Main *bmain) { for (WorkSpace *workspace = bmain->workspaces.first; workspace; workspace = workspace->id.next) { @@ -2891,8 +2878,6 @@ static void lib_link_workspaces(FileData *fd, Main *bmain) IDP_LibLinkProperty(id->properties, fd); id_us_ensure_real(id); - lib_link_workspace_scene_data(fd, workspace); - for (WorkSpaceLayout *layout = layouts->first, *layout_next; layout; layout = layout_next) { bScreen *screen = newlibadr(fd, id->lib, BKE_workspace_layout_screen_get(layout)); @@ -2918,7 +2903,6 @@ 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_layer_relations); link_list(fd, &workspace->owner_ids); link_list(fd, &workspace->tools); @@ -7140,19 +7124,6 @@ static void lib_link_clipboard_restore(struct IDNameLib_Map *id_map) BKE_sequencer_base_recursive_apply(&seqbase_clipboard, lib_link_seq_clipboard_cb, id_map); } -static void lib_link_workspace_scene_data_restore(struct IDNameLib_Map *id_map, WorkSpace *workspace) -{ - for (WorkSpaceSceneRelation *relation = workspace->scene_layer_relations.first; - relation != NULL; - relation = relation->next) - { - relation->scene = restore_pointer_by_name(id_map, &relation->scene->id, USER_IGNORE); - } - - /* Free any relations that got lost due to missing datablocks or view layers. */ - BKE_workspace_scene_relations_free_invalid(workspace); -} - static void lib_link_window_scene_data_restore(wmWindow *win, Scene *scene) { bScreen *screen = BKE_workspace_active_screen_get(win->workspace_hook); @@ -7415,9 +7386,6 @@ void blo_lib_link_restore(Main *newmain, wmWindowManager *curwm, Scene *curscene struct IDNameLib_Map *id_map = BKE_main_idmap_create(newmain); for (WorkSpace *workspace = newmain->workspaces.first; workspace; workspace = workspace->id.next) { - lib_link_workspace_scene_data_restore(id_map, workspace); - BKE_workspace_view_layer_set(workspace, cur_view_layer, curscene); - ListBase *layouts = BKE_workspace_layouts_get(workspace); for (WorkSpaceLayout *layout = layouts->first; layout; layout = layout->next) { @@ -7436,6 +7404,9 @@ void blo_lib_link_restore(Main *newmain, wmWindowManager *curwm, Scene *curscene if (win->scene == NULL) { win->scene = curscene; } + if (BKE_view_layer_find(win->scene, win->view_layer_name) == NULL) { + STRNCPY(win->view_layer_name, cur_view_layer->name); + } BKE_workspace_active_set(win->workspace_hook, workspace); /* keep cursor location through undo */ diff --git a/source/blender/blenloader/intern/versioning_280.c b/source/blender/blenloader/intern/versioning_280.c index 757e17ce82b..3bdd4db3b94 100644 --- a/source/blender/blenloader/intern/versioning_280.c +++ b/source/blender/blenloader/intern/versioning_280.c @@ -97,15 +97,10 @@ 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 = BLI_findlink(&scene->view_layers, scene->r.actlay); if (screen->temp) { continue; } - if (!layer) { - layer = BKE_view_layer_default_view(scene); - } if (screen_parent) { /* fullscreen with "Back to Previous" option, don't create @@ -117,7 +112,6 @@ static void do_version_workspaces_create_from_screens(Main *bmain) workspace = BKE_workspace_add(bmain, screen->id.name + 2); } BKE_workspace_layout_add(bmain, workspace, screen, screen->id.name + 2); - BKE_workspace_view_layer_set(workspace, layer, scene); } } @@ -178,7 +172,16 @@ static void do_version_workspaces_after_lib_link(Main *bmain) BKE_workspace_active_set(win->workspace_hook, workspace); BKE_workspace_active_layout_set(win->workspace_hook, layouts->first); - win->scene = screen->scene; + /* Move scene and view layer to window. */ + Scene *scene = screen->scene; + ViewLayer *layer = BLI_findlink(&scene->view_layers, scene->r.actlay); + if (!layer) { + layer = BKE_view_layer_default_view(scene); + } + + win->scene = scene; + STRNCPY(win->view_layer_name, layer->name); + /* Deprecated from now on! */ win->screen = NULL; } @@ -594,7 +597,7 @@ void do_versions_after_linking_280(Main *bmain) if (!MAIN_VERSION_ATLEAST(bmain, 280, 0)) { for (bScreen *screen = bmain->screen.first; screen; screen = screen->id.next) { /* same render-layer as do_version_workspaces_after_lib_link will activate, - * so same layer as BKE_view_layer_from_workspace_get would return */ + * so same layer as BKE_view_layer_default_view would return */ ViewLayer *layer = screen->scene->view_layers.first; for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) { diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index 146494e6196..0a2d09d0c86 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -166,6 +166,7 @@ #include "BKE_constraint.h" #include "BKE_global.h" // for G #include "BKE_idcode.h" +#include "BKE_layer.h" #include "BKE_library.h" // for set_listbasepointers #include "BKE_library_override.h" #include "BKE_main.h" @@ -1147,7 +1148,6 @@ static void current_screen_compat( { wmWindowManager *wm; wmWindow *window = NULL; - WorkSpace *workspace; /* find a global current screen in the first open window, to have * a reasonable default for reading in older versions */ @@ -1171,11 +1171,10 @@ static void current_screen_compat( window = wm->windows.first; } } - workspace = (window) ? BKE_workspace_active_get(window->workspace_hook) : NULL; *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, *r_scene) : NULL; + *r_render_layer = (window && *r_scene) ? BKE_view_layer_find(*r_scene, window->view_layer_name) : NULL; } typedef struct RenderInfo { @@ -3646,7 +3645,6 @@ 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, WorkSpaceSceneRelation, &workspace->scene_layer_relations); writelist(wd, DATA, wmOwnerID, &workspace->owner_ids); writelist(wd, DATA, bToolRef, &workspace->tools); for (bToolRef *tref = workspace->tools.first; tref; tref = tref->next) { diff --git a/source/blender/editors/include/ED_screen.h b/source/blender/editors/include/ED_screen.h index cc80108e20c..2b0729a8e13 100644 --- a/source/blender/editors/include/ED_screen.h +++ b/source/blender/editors/include/ED_screen.h @@ -204,9 +204,7 @@ void ED_screen_preview_render(const struct bScreen *screen, int size_x, int s /* workspaces */ struct WorkSpace *ED_workspace_add( struct Main *bmain, - const char *name, - Scene *scene, - ViewLayer *act_render_layer) ATTR_NONNULL(); + const char *name) ATTR_NONNULL(); bool ED_workspace_change( struct WorkSpace *workspace_new, struct bContext *C, @@ -220,9 +218,6 @@ bool ED_workspace_delete( struct wmWindowManager *wm) ATTR_NONNULL(); void ED_workspace_scene_data_sync( struct WorkSpaceInstanceHook *hook, Scene *scene) ATTR_NONNULL(); -void ED_workspace_view_layer_unset( - 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 Main *bmain, struct WorkSpace *workspace, diff --git a/source/blender/editors/render/render_internal.c b/source/blender/editors/render/render_internal.c index 1385baa51ad..ae364828119 100644 --- a/source/blender/editors/render/render_internal.c +++ b/source/blender/editors/render/render_internal.c @@ -66,7 +66,6 @@ #include "BKE_screen.h" #include "BKE_scene.h" #include "BKE_undo_system.h" -#include "BKE_workspace.h" #include "DEG_depsgraph.h" @@ -263,7 +262,7 @@ static void image_buffer_rect_update(RenderJob *rj, RenderResult *rr, ImBuf *ibu /* set callbacks, exported to sequence render too. * Only call in foreground (UI) renders. */ -static void screen_render_single_layer_set(wmOperator *op, Main *mainp, WorkSpace *workspace, Scene **scene, ViewLayer **single_layer) +static void screen_render_single_layer_set(wmOperator *op, Main *mainp, ViewLayer *active_layer, Scene **scene, ViewLayer **single_layer) { /* single layer re-render */ if (RNA_struct_property_is_set(op->ptr, "scene")) { @@ -292,8 +291,8 @@ static void screen_render_single_layer_set(wmOperator *op, Main *mainp, WorkSpac if (rl) *single_layer = rl; } - else if (((*scene)->r.scemode & R_SINGLE_LAYER) && workspace) { - *single_layer = BKE_view_layer_from_workspace_get(*scene, workspace); + else if (((*scene)->r.scemode & R_SINGLE_LAYER) && active_layer) { + *single_layer = active_layer; } } @@ -302,12 +301,12 @@ static int screen_render_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); RenderEngineType *re_type = RE_engines_find(scene->r.engine); + ViewLayer *active_layer = CTX_data_view_layer(C); ViewLayer *single_layer = NULL; Render *re; Image *ima; View3D *v3d = CTX_wm_view3d(C); Main *mainp = CTX_data_main(C); - WorkSpace *workspace = CTX_wm_workspace(C); unsigned int lay_override; const bool is_animation = RNA_boolean_get(op->ptr, "animation"); const bool is_write_still = RNA_boolean_get(op->ptr, "write_still"); @@ -319,7 +318,7 @@ static int screen_render_exec(bContext *C, wmOperator *op) } /* custom scene and single layer re-render */ - screen_render_single_layer_set(op, mainp, workspace, &scene, &single_layer); + screen_render_single_layer_set(op, mainp, active_layer, &scene, &single_layer); if (!is_animation && is_write_still && BKE_imtype_is_movie(scene->r.im_format.imtype)) { BKE_report(op->reports, RPT_ERROR, "Cannot write a single file with an animation format selected"); @@ -846,8 +845,7 @@ static void clean_viewport_memory(Main *bmain, Scene *scene) /* Go over all the visible objects. */ for (wmWindowManager *wm = bmain->wm.first; wm; wm = wm->id.next) { for (wmWindow *win = wm->windows.first; win; win = win->next) { - WorkSpace *workspace = BKE_workspace_active_get(win->workspace_hook); - ViewLayer *view_layer = BKE_view_layer_from_workspace_get(scene, workspace); + ViewLayer *view_layer = WM_window_get_active_view_layer(win); for (base = view_layer->object_bases.first; base; base = base->next) { clean_viewport_memory_base(base); @@ -865,8 +863,9 @@ static int screen_render_invoke(bContext *C, wmOperator *op, const wmEvent *even { /* new render clears all callbacks */ Main *bmain = CTX_data_main(C); - ViewLayer *single_layer = NULL; Scene *scene = CTX_data_scene(C); + ViewLayer *active_layer = CTX_data_view_layer(C); + ViewLayer *single_layer = NULL; RenderEngineType *re_type = RE_engines_find(scene->r.engine); Render *re; wmJob *wm_job; @@ -877,7 +876,6 @@ static int screen_render_invoke(bContext *C, wmOperator *op, const wmEvent *even const bool is_write_still = RNA_boolean_get(op->ptr, "write_still"); const bool use_viewport = RNA_boolean_get(op->ptr, "use_viewport"); View3D *v3d = use_viewport ? CTX_wm_view3d(C) : NULL; - WorkSpace *workspace = CTX_wm_workspace(C); struct Object *camera_override = v3d ? V3D_CAMERA_LOCAL(v3d) : NULL; const char *name; ScrArea *sa; @@ -888,7 +886,7 @@ static int screen_render_invoke(bContext *C, wmOperator *op, const wmEvent *even } /* custom scene and single layer re-render */ - screen_render_single_layer_set(op, bmain, workspace, &scene, &single_layer); + screen_render_single_layer_set(op, bmain, active_layer, &scene, &single_layer); /* only one render job at a time */ if (WM_jobs_test(CTX_wm_manager(C), scene, WM_JOB_TYPE_RENDER)) diff --git a/source/blender/editors/render/render_shading.c b/source/blender/editors/render/render_shading.c index 31f25720f8d..07e0c124998 100644 --- a/source/blender/editors/render/render_shading.c +++ b/source/blender/editors/render/render_shading.c @@ -615,12 +615,12 @@ void WORLD_OT_new(wmOperatorType *ot) static int view_layer_add_exec(bContext *C, wmOperator *UNUSED(op)) { - WorkSpace *workspace = CTX_wm_workspace(C); + wmWindow *win = CTX_wm_window(C); Scene *scene = CTX_data_scene(C); ViewLayer *view_layer = BKE_view_layer_add(scene, NULL); - if (workspace) { - BKE_workspace_view_layer_set(workspace, view_layer, scene); + if (win) { + WM_window_set_active_view_layer(win, view_layer); } DEG_id_tag_update(&scene->id, 0); diff --git a/source/blender/editors/scene/scene_edit.c b/source/blender/editors/scene/scene_edit.c index 0ebbd770c9f..62933178266 100644 --- a/source/blender/editors/scene/scene_edit.c +++ b/source/blender/editors/scene/scene_edit.c @@ -23,9 +23,11 @@ */ #include <stdio.h> +#include <string.h> #include "BLI_compiler_attrs.h" #include "BLI_listbase.h" +#include "BLI_string.h" #include "BKE_context.h" #include "BKE_global.h" @@ -175,12 +177,17 @@ bool ED_scene_view_layer_delete( BLI_remlink(&scene->view_layers, layer); BLI_assert(BLI_listbase_is_empty(&scene->view_layers) == false); - ED_workspace_view_layer_unset(bmain, scene, layer, scene->view_layers.first); + /* Remove from windows. */ + wmWindowManager *wm = bmain->wm.first; + for (wmWindow *win = wm->windows.first; win; win = win->next) { + if (win->scene == scene && STREQ(win->view_layer_name, layer->name)) { + ViewLayer *first_layer = BKE_view_layer_default_view(scene); + STRNCPY(win->view_layer_name, first_layer->name); + } + } BKE_view_layer_free(layer); - BKE_workspace_view_layer_remove(bmain, layer); - DEG_id_tag_update(&scene->id, 0); DEG_relations_tag_update(bmain); WM_main_add_notifier(NC_SCENE | ND_LAYER | NA_REMOVED, scene); diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c index 5cb440d315b..77e178bf0b2 100644 --- a/source/blender/editors/screen/area.c +++ b/source/blender/editors/screen/area.c @@ -1482,7 +1482,7 @@ void ED_area_initialize(wmWindowManager *wm, wmWindow *win, ScrArea *sa) { WorkSpace *workspace = WM_window_get_active_workspace(win); const bScreen *screen = BKE_workspace_active_screen_get(win->workspace_hook); - Scene *scene = WM_window_get_active_scene(win); + ViewLayer *view_layer = WM_window_get_active_view_layer(win); ARegion *ar; rcti rect, overlap_rect; rcti window_rect; @@ -1542,7 +1542,7 @@ void ED_area_initialize(wmWindowManager *wm, wmWindow *win, ScrArea *sa) region_azones_add(screen, sa, ar, ar->alignment & ~RGN_SPLIT_PREV); } - WM_toolsystem_refresh_screen_area(workspace, scene, sa); + WM_toolsystem_refresh_screen_area(workspace, view_layer, sa); } static void region_update_rect(ARegion *ar) diff --git a/source/blender/editors/screen/screen_context.c b/source/blender/editors/screen/screen_context.c index fa18826005e..17b1af29010 100644 --- a/source/blender/editors/screen/screen_context.c +++ b/source/blender/editors/screen/screen_context.c @@ -91,8 +91,7 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult bScreen *sc = CTX_wm_screen(C); ScrArea *sa = CTX_wm_area(C); 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); + ViewLayer *view_layer = WM_window_get_active_view_layer(win); Object *obact = (view_layer && view_layer->basact) ? view_layer->basact->object : NULL; Object *obedit = view_layer ? OBEDIT_FROM_VIEW_LAYER(view_layer) : NULL; diff --git a/source/blender/editors/screen/screen_edit.c b/source/blender/editors/screen/screen_edit.c index 50609815168..8fbf74ed800 100644 --- a/source/blender/editors/screen/screen_edit.c +++ b/source/blender/editors/screen/screen_edit.c @@ -944,35 +944,36 @@ static void screen_set_3dview_camera(Scene *scene, ViewLayer *view_layer, ScrAre } } -static ViewLayer *scene_change_get_new_view_layer(const WorkSpace *workspace, const Scene *scene_new) -{ - ViewLayer *layer_new = BKE_workspace_view_layer_exists(workspace, scene_new); - return layer_new ? layer_new : BKE_view_layer_default_view(scene_new); -} - void ED_screen_scene_change(bContext *C, wmWindow *win, Scene *scene) { - const bScreen *screen = WM_window_get_active_screen(win); - WorkSpace *workspace = CTX_wm_workspace(C); - ViewLayer *view_layer = scene_change_get_new_view_layer(workspace, scene); - #if 0 - /* mode syncing */ - Object *obact_new = OBACT(view_layer); - UNUSED_VARS(obact_new); - eObjectMode object_mode_old = workspace->object_mode; - ViewLayer *layer_old = BKE_view_layer_from_workspace_get(scene_old, workspace); - Object *obact_old = OBACT(layer_old); - UNUSED_VARS(obact_old, object_mode_old); + ViewLayer *view_layer_old = WM_window_get_active_view_layer(win); #endif - BKE_workspace_view_layer_set(workspace, view_layer, scene); - + /* Switch scene. */ win->scene = scene; if (CTX_wm_window(C) == win) { CTX_data_scene_set(C, scene); } + /* Ensure the view layer name is updated. */ + WM_window_ensure_active_view_layer(win); + ViewLayer *view_layer = WM_window_get_active_view_layer(win); + +#if 0 + /* Mode Syncing. */ + if (view_layer_old) { + WorkSpace *workspace = CTX_wm_workspace(C); + Object *obact_new = OBACT(view_layer); + UNUSED_VARS(obact_new); + eObjectMode object_mode_old = workspace->object_mode; + Object *obact_old = OBACT(view_layer_old); + UNUSED_VARS(obact_old, object_mode_old); + } +#endif + + /* Update 3D view cameras. */ + const bScreen *screen = WM_window_get_active_screen(win); for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) { for (SpaceLink *sl = sa->spacedata.first; sl; sl = sl->next) { if (sl->spacetype == SPACE_VIEW3D) { diff --git a/source/blender/editors/screen/workspace_edit.c b/source/blender/editors/screen/workspace_edit.c index 9ba9b70a6e8..705d8992900 100644 --- a/source/blender/editors/screen/workspace_edit.c +++ b/source/blender/editors/screen/workspace_edit.c @@ -75,55 +75,33 @@ * \brief API for managing workspaces and their data. * \{ */ -WorkSpace *ED_workspace_add( - Main *bmain, const char *name, Scene *scene, - ViewLayer *act_view_layer) +WorkSpace *ED_workspace_add(Main *bmain, const char *name) { - WorkSpace *workspace = BKE_workspace_add(bmain, name); - - BKE_workspace_view_layer_set(workspace, act_view_layer, scene); - - return workspace; + return BKE_workspace_add(bmain, name); } /** * Changes the object mode (if needed) to the one set in \a workspace_new. * Object mode is still stored on object level. In future it should all be workspace level instead. */ -static void workspace_change_update_mode( - const WorkSpace *workspace_old, const WorkSpace *workspace_new, - bContext *C, Object *ob_act, ReportList *reports) +static void workspace_change_update( + WorkSpace *workspace_new, const WorkSpace *workspace_old, + bContext *C, wmWindowManager *wm) { - UNUSED_VARS(workspace_old, workspace_new, C, ob_act, reports); + /* needs to be done before changing mode! (to ensure right context) */ + UNUSED_VARS(workspace_old, workspace_new, C, wm); #if 0 + Object *ob_act = CTX_data_active_object(C) eObjectMode mode_old = workspace_old->object_mode; eObjectMode mode_new = workspace_new->object_mode; if (mode_old != mode_new) { - ED_object_mode_compat_set(C, ob_act, mode_new, reports); + ED_object_mode_compat_set(C, ob_act, mode_new, &wm->reports); ED_object_mode_toggle(C, mode_new); } #endif } -static void workspace_change_update_view_layer( - WorkSpace *workspace_new, const WorkSpace *workspace_old, - Scene *scene) -{ - if (!BKE_workspace_view_layer_exists(workspace_new, scene)) { - BKE_workspace_view_layer_set(workspace_new, BKE_workspace_view_layer_get(workspace_old, scene), scene); - } -} - -static void workspace_change_update( - WorkSpace *workspace_new, const WorkSpace *workspace_old, - bContext *C, wmWindowManager *wm) -{ - /* needs to be done before changing mode! (to ensure right context) */ - workspace_change_update_view_layer(workspace_new, workspace_old, CTX_data_scene(C)); - workspace_change_update_mode(workspace_old, workspace_new, C, CTX_data_active_object(C), &wm->reports); -} - static bool workspace_change_find_new_layout_cb(const WorkSpaceLayout *layout, void *UNUSED(arg)) { /* return false to stop the iterator if we've found a layout that can be activated */ @@ -199,7 +177,6 @@ bool ED_workspace_change( screen_change_update(C, win, screen_new); workspace_change_update(workspace_new, workspace_old, C, wm); - BLI_assert(BKE_workspace_view_layer_exists(workspace_new, CTX_data_scene(C)) != NULL); BLI_assert(CTX_wm_workspace(C) == workspace_new); WM_toolsystem_unlink_all(C, workspace_old); @@ -220,10 +197,7 @@ 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, scene, - BKE_workspace_view_layer_get(workspace_old, scene)); + WorkSpace *workspace_new = ED_workspace_add(bmain, workspace_old->id.name + 2); /* TODO(campbell): tools */ @@ -271,17 +245,6 @@ void ED_workspace_scene_data_sync( BKE_screen_view3d_scene_sync(screen, scene); } -void ED_workspace_view_layer_unset( - 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, scene) == layer_unset) { - BKE_workspace_view_layer_set(workspace, layer_new, scene); - } - } -} - /** \} Workspace API */ diff --git a/source/blender/editors/space_buttons/buttons_context.c b/source/blender/editors/space_buttons/buttons_context.c index dd943e7988d..4ad62ec705d 100644 --- a/source/blender/editors/space_buttons/buttons_context.c +++ b/source/blender/editors/space_buttons/buttons_context.c @@ -47,6 +47,7 @@ #include "DNA_world_types.h" #include "DNA_brush_types.h" #include "DNA_linestyle_types.h" +#include "DNA_windowmanager_types.h" #include "BKE_context.h" #include "BKE_action.h" @@ -70,6 +71,8 @@ #include "UI_interface.h" #include "UI_resources.h" +#include "WM_api.h" + #include "buttons_intern.h" // own include static int set_pointer_type(ButsContextPath *path, bContextDataResult *result, StructRNA *type) @@ -114,11 +117,13 @@ static int buttons_context_path_scene(ButsContextPath *path) return RNA_struct_is_a(ptr->type, &RNA_Scene); } -static int buttons_context_path_view_layer(ButsContextPath *path, WorkSpace *workspace) +static int buttons_context_path_view_layer(ButsContextPath *path, wmWindow *win) { if (buttons_context_path_scene(path)) { Scene *scene = path->ptr[path->len - 1].data; - ViewLayer *view_layer = BKE_view_layer_from_workspace_get(scene, workspace); + ViewLayer *view_layer = (win->scene == scene) ? + WM_window_get_active_view_layer(win) : + BKE_view_layer_default_view(scene); RNA_pointer_create(&scene->id, &RNA_ViewLayer, view_layer, &path->ptr[path->len]); path->len++; @@ -159,7 +164,7 @@ static int buttons_context_path_world(ButsContextPath *path) return 0; } -static int buttons_context_path_linestyle(ButsContextPath *path, WorkSpace *workspace) +static int buttons_context_path_linestyle(ButsContextPath *path, wmWindow *window) { FreestyleLineStyle *linestyle; PointerRNA *ptr = &path->ptr[path->len - 1]; @@ -169,7 +174,7 @@ static int buttons_context_path_linestyle(ButsContextPath *path, WorkSpace *work return 1; } /* if we have a view layer, use the lineset's linestyle */ - else if (buttons_context_path_view_layer(path, workspace)) { + else if (buttons_context_path_view_layer(path, window)) { ViewLayer *view_layer = path->ptr[path->len - 1].data; linestyle = BKE_linestyle_active_from_view_layer(view_layer); if (linestyle) { @@ -432,7 +437,7 @@ static int buttons_context_path_texture(const bContext *C, ButsContextPath *path else if (GS(id->name) == ID_OB) buttons_context_path_object(path); else if (GS(id->name) == ID_LS) - buttons_context_path_linestyle(path, CTX_wm_workspace(C)); + buttons_context_path_linestyle(path, CTX_wm_window(C)); } if (ct->texture) { @@ -472,8 +477,9 @@ static int buttons_context_path(const bContext *C, ButsContextPath *path, int ma { SpaceButs *sbuts = CTX_wm_space_buts(C); Scene *scene = CTX_data_scene(C); + ViewLayer *view_layer = CTX_data_view_layer(C); + wmWindow *window = CTX_wm_window(C); WorkSpace *workspace = CTX_wm_workspace(C); - ViewLayer *view_layer = BKE_view_layer_from_workspace_get(scene, workspace); ID *id; int found; @@ -514,13 +520,13 @@ static int buttons_context_path(const bContext *C, ButsContextPath *path, int ma case BCONTEXT_VIEW_LAYER: #ifdef WITH_FREESTYLE if (buttons_context_linestyle_pinnable(C, view_layer)) { - found = buttons_context_path_linestyle(path, workspace); + found = buttons_context_path_linestyle(path, window); if (found) { break; } } #endif - found = buttons_context_path_view_layer(path, workspace); + found = buttons_context_path_view_layer(path, window); break; case BCONTEXT_WORLD: found = buttons_context_path_world(path); diff --git a/source/blender/editors/space_buttons/buttons_texture.c b/source/blender/editors/space_buttons/buttons_texture.c index 5feb74edef7..66684de18ac 100644 --- a/source/blender/editors/space_buttons/buttons_texture.c +++ b/source/blender/editors/space_buttons/buttons_texture.c @@ -49,6 +49,7 @@ #include "DNA_screen_types.h" #include "DNA_space_types.h" #include "DNA_linestyle_types.h" +#include "DNA_windowmanager_types.h" #include "BKE_context.h" #include "BKE_layer.h" @@ -72,6 +73,8 @@ #include "ED_node.h" #include "ED_screen.h" +#include "WM_api.h" + #include "../interface/interface_intern.h" #include "buttons_intern.h" // own include @@ -176,8 +179,10 @@ static void buttons_texture_users_from_context(ListBase *users, const bContext * const ID_Type id_type = pinid != NULL ? GS(pinid->name) : -1; if (!pinid || id_type == ID_SCE) { - WorkSpace *workspace = CTX_wm_workspace(C); - ViewLayer *view_layer = BKE_workspace_view_layer_get(workspace, scene); + wmWindow *win = CTX_wm_window(C); + ViewLayer *view_layer = (win->scene == scene) ? + WM_window_get_active_view_layer(win) : + BKE_view_layer_default_view(scene); brush = BKE_paint_brush(BKE_paint_get_active_from_context(C)); linestyle = BKE_linestyle_active_from_view_layer(view_layer); diff --git a/source/blender/editors/space_image/space_image.c b/source/blender/editors/space_image/space_image.c index 5c95d5944d1..9d89e21289d 100644 --- a/source/blender/editors/space_image/space_image.c +++ b/source/blender/editors/space_image/space_image.c @@ -51,6 +51,7 @@ #include "BKE_scene.h" #include "BKE_screen.h" #include "BKE_material.h" +#include "BKE_workspace.h" #include "DEG_depsgraph.h" diff --git a/source/blender/editors/space_outliner/outliner_select.c b/source/blender/editors/space_outliner/outliner_select.c index 8a5df196c7b..bc514914b81 100644 --- a/source/blender/editors/space_outliner/outliner_select.c +++ b/source/blender/editors/space_outliner/outliner_select.c @@ -173,24 +173,25 @@ void outliner_object_mode_toggle( /* Outliner Element Selection/Activation on Click */ static eOLDrawState active_viewlayer( - bContext *C, Scene *UNUSED(scene), ViewLayer *UNUSED(sl), TreeElement *te, TreeStoreElem *tselem, const eOLSetState set) + bContext *C, Scene *UNUSED(scene), ViewLayer *UNUSED(sl), TreeElement *te, const eOLSetState set) { - Scene *sce; - /* paranoia check */ if (te->idcode != ID_SCE) return OL_DRAWSEL_NONE; - sce = (Scene *)tselem->id; - WorkSpace *workspace = CTX_wm_workspace(C); ViewLayer *view_layer = te->directdata; if (set != OL_SETSEL_NONE) { - BKE_workspace_view_layer_set(workspace, view_layer, sce); - WM_event_add_notifier(C, NC_SCREEN | ND_LAYER, NULL); + wmWindow *win = CTX_wm_window(C); + Scene *scene = WM_window_get_active_scene(win); + + if (BLI_findindex(&scene->view_layers, view_layer) != -1) { + WM_window_set_active_view_layer(win, view_layer); + WM_event_add_notifier(C, NC_SCREEN | ND_LAYER, NULL); + } } else { - return BKE_workspace_view_layer_get(workspace, sce) == view_layer; + return CTX_data_view_layer(C) == view_layer; } return OL_DRAWSEL_NONE; } @@ -895,7 +896,7 @@ eOLDrawState tree_element_type_active( case TSE_CONSTRAINT: return tree_element_active_constraint(C, scene, view_layer, te, tselem, set); case TSE_R_LAYER: - return active_viewlayer(C, scene, view_layer, te, tselem, set); + return active_viewlayer(C, scene, view_layer, te, set); case TSE_POSEGRP: return tree_element_active_posegroup(C, scene, view_layer, te, tselem, set); case TSE_SEQUENCE: diff --git a/source/blender/makesdna/DNA_windowmanager_types.h b/source/blender/makesdna/DNA_windowmanager_types.h index 0ef9e9b134a..bd2811d3306 100644 --- a/source/blender/makesdna/DNA_windowmanager_types.h +++ b/source/blender/makesdna/DNA_windowmanager_types.h @@ -188,8 +188,9 @@ typedef struct wmWindow { struct wmWindow *parent; /* Parent window */ - struct Scene *scene; /* The scene displayed in this window. */ + struct Scene *scene; /* Active scene displayed in this window. */ struct Scene *new_scene; /* temporary when switching */ + char view_layer_name[64]; /* Active view layer displayed in this window. */ struct WorkSpaceInstanceHook *workspace_hook; diff --git a/source/blender/makesdna/DNA_workspace_types.h b/source/blender/makesdna/DNA_workspace_types.h index f07dc195455..2b0f74a54ee 100644 --- a/source/blender/makesdna/DNA_workspace_types.h +++ b/source/blender/makesdna/DNA_workspace_types.h @@ -129,7 +129,6 @@ 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_layer_relations; /* WorkSpaceSceneRelation */ /* Feature tagging (use for addons) */ ListBase owner_ids DNA_PRIVATE_WORKSPACE_READ_WRITE; /* wmOwnerID */ @@ -190,13 +189,6 @@ typedef struct WorkSpaceDataRelation { #endif /* DNA_PRIVATE_WORKSPACE_READ_WRITE */ -typedef struct WorkSpaceSceneRelation { - struct WorkSpaceSceneRelation *next, *prev; - - struct Scene *scene; - char view_layer[64]; /* MAX_NAME */ -} WorkSpaceSceneRelation; - /** * Little wrapper to store data that is going to be per window, but comming from the workspace. * It allows us to keep workspace and window data completely separate. diff --git a/source/blender/makesrna/intern/rna_material.c b/source/blender/makesrna/intern/rna_material.c index 26c281ad9e1..0a8ea99b8fb 100644 --- a/source/blender/makesrna/intern/rna_material.c +++ b/source/blender/makesrna/intern/rna_material.c @@ -148,8 +148,7 @@ static void rna_Material_active_paint_texture_index_update(Main *bmain, Scene *s Object *obedit = NULL; { - WorkSpace *workspace = WM_window_get_active_workspace(win); - ViewLayer *view_layer = BKE_workspace_view_layer_get(workspace, scene); + ViewLayer *view_layer = WM_window_get_active_view_layer(win); obedit = OBEDIT_FROM_VIEW_LAYER(view_layer); } diff --git a/source/blender/makesrna/intern/rna_wm.c b/source/blender/makesrna/intern/rna_wm.c index 569bc20d435..7dc8ab54800 100644 --- a/source/blender/makesrna/intern/rna_wm.c +++ b/source/blender/makesrna/intern/rna_wm.c @@ -773,8 +773,8 @@ 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; - ViewLayer *view_layer = WM_window_get_active_view_layer_ex(win, &scene); + Scene *scene = WM_window_get_active_scene(win);; + ViewLayer *view_layer = WM_window_get_active_view_layer(win); PointerRNA scene_ptr; RNA_id_pointer_create(&scene->id, &scene_ptr); @@ -784,10 +784,9 @@ static PointerRNA rna_Window_view_layer_get(PointerRNA *ptr) 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); + ViewLayer *view_layer = value.data; - BKE_workspace_view_layer_set(workspace, value.data, scene); + WM_window_set_active_view_layer(win, view_layer); } static PointerRNA rna_KeyMapItem_properties_get(PointerRNA *ptr) diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h index 0ed23a8fb20..e203a872d24 100644 --- a/source/blender/windowmanager/WM_api.h +++ b/source/blender/windowmanager/WM_api.h @@ -112,7 +112,7 @@ struct WorkSpace *WM_windows_workspace_get_from_screen(const wmWindowManager *wm struct Scene *WM_window_get_active_scene(const struct wmWindow *win) ATTR_NONNULL() ATTR_WARN_UNUSED_RESULT; void WM_window_set_active_scene(struct Main *bmain, struct bContext *C, struct wmWindow *win, - struct Scene *scene_new) ATTR_NONNULL(); + struct Scene *scene_new) ATTR_NONNULL(); struct WorkSpace *WM_window_get_active_workspace(const struct wmWindow *win) ATTR_NONNULL() ATTR_WARN_UNUSED_RESULT; void WM_window_set_active_workspace(struct bContext *C, struct wmWindow *win, struct WorkSpace *workspace) ATTR_NONNULL(1); struct WorkSpaceLayout *WM_window_get_active_layout(const struct wmWindow *win) ATTR_NONNULL() ATTR_WARN_UNUSED_RESULT; @@ -121,8 +121,9 @@ void WM_window_set_active_layout( struct bScreen *WM_window_get_active_screen(const struct wmWindow *win) ATTR_NONNULL() ATTR_WARN_UNUSED_RESULT; void WM_window_set_active_screen(struct wmWindow *win, struct WorkSpace *workspace, struct bScreen *screen) ATTR_NONNULL(1); -struct ViewLayer *WM_window_get_active_view_layer_ex(const struct wmWindow *win, struct Scene **r_scene) ATTR_NONNULL(1) ATTR_WARN_UNUSED_RESULT; struct ViewLayer *WM_window_get_active_view_layer(const struct wmWindow *win) ATTR_NONNULL(1) ATTR_WARN_UNUSED_RESULT; +void WM_window_set_active_view_layer(struct wmWindow *win, struct ViewLayer *view_layer) ATTR_NONNULL(1); +void WM_window_ensure_active_view_layer(struct wmWindow *win) ATTR_NONNULL(1); bool WM_window_is_temp_screen(const struct wmWindow *win) ATTR_WARN_UNUSED_RESULT; diff --git a/source/blender/windowmanager/WM_toolsystem.h b/source/blender/windowmanager/WM_toolsystem.h index 30470e17ed4..f4505bef962 100644 --- a/source/blender/windowmanager/WM_toolsystem.h +++ b/source/blender/windowmanager/WM_toolsystem.h @@ -73,11 +73,9 @@ void WM_toolsystem_ref_set_from_runtime( void WM_toolsystem_init(struct bContext *C); int WM_toolsystem_mode_from_spacetype( - struct WorkSpace *workspace, struct Scene *scene, struct ScrArea *sa, - int space_type); + struct ViewLayer *view_layer, struct ScrArea *sa, int space_type); bool WM_toolsystem_key_from_context( - struct WorkSpace *workspace, struct Scene *scene, struct ScrArea *sa, - bToolKey *tkey); + struct ViewLayer *view_layer, struct ScrArea *sa, bToolKey *tkey); void WM_toolsystem_update_from_context( struct bContext *C, struct WorkSpace *workspace, struct Scene *scene, struct ScrArea *sa); @@ -95,7 +93,7 @@ void WM_toolsystem_ref_properties_ensure(struct bToolRef *tref, struct wmOperato void WM_toolsystem_ref_properties_init_for_keymap( struct bToolRef *tref, struct PointerRNA *dst_ptr, struct PointerRNA *src_ptr, struct wmOperatorType *ot); -void WM_toolsystem_refresh_screen_area(struct WorkSpace *workspace, struct Scene *scene, struct ScrArea *sa); +void WM_toolsystem_refresh_screen_area(struct WorkSpace *workspace, struct ViewLayer *view_layer, struct ScrArea *sa); void WM_toolsystem_refresh_screen_all(struct Main *bmain); #ifdef __cplusplus diff --git a/source/blender/windowmanager/intern/wm.c b/source/blender/windowmanager/intern/wm.c index 9ef0883cbbf..9e7136dc81d 100644 --- a/source/blender/windowmanager/intern/wm.c +++ b/source/blender/windowmanager/intern/wm.c @@ -463,6 +463,7 @@ void wm_add_default(Main *bmain, bContext *C) CTX_wm_manager_set(C, wm); win = wm_window_new(C, NULL); win->scene = CTX_data_scene(C); + STRNCPY(win->view_layer_name, CTX_data_view_layer(C)->name); BKE_workspace_active_set(win->workspace_hook, workspace); BKE_workspace_hook_layout_for_workspace_set(win->workspace_hook, workspace, layout); screen->winid = win->winid; diff --git a/source/blender/windowmanager/intern/wm_draw.c b/source/blender/windowmanager/intern/wm_draw.c index 5b88268f416..5314c434c4c 100644 --- a/source/blender/windowmanager/intern/wm_draw.c +++ b/source/blender/windowmanager/intern/wm_draw.c @@ -729,9 +729,8 @@ static void wm_draw_window(bContext *C, wmWindow *win) /* quick test to prevent changing window drawable */ static bool wm_draw_update_test_window(wmWindow *win) { - struct WorkSpace *workspace = WM_window_get_active_workspace(win); Scene *scene = WM_window_get_active_scene(win); - ViewLayer *view_layer = BKE_workspace_view_layer_get(workspace, scene); + ViewLayer *view_layer = WM_window_get_active_view_layer(win); struct Depsgraph *depsgraph = BKE_scene_get_depsgraph(scene, view_layer, true); bScreen *screen = WM_window_get_active_screen(win); ARegion *ar; diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index 3aee57d5801..91b924c1565 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -317,6 +317,7 @@ void wm_event_do_refresh_wm_and_depsgraph(bContext *C) for (wmWindow *win = wm->windows.first; win; win = win->next) { const bScreen *screen = WM_window_get_active_screen(win); Scene *scene = WM_window_get_active_scene(win); + ViewLayer *view_layer = WM_window_get_active_view_layer(win); ScrArea *sa; CTX_wm_window_set(C, win); @@ -338,9 +339,15 @@ void wm_event_do_refresh_wm_and_depsgraph(bContext *C) /* XXX, hack so operators can enforce datamasks [#26482], gl render */ scene->customdata_mask |= scene->customdata_mask_modal; - WorkSpace *workspace = WM_window_get_active_workspace(win); - - BKE_workspace_update_tagged(bmain, workspace, scene); + /* TODO(sergey): For now all dependency graphs which are evaluated from + * workspace are considered active. This will work all fine with "locked" + * view layer and time across windows. This is to be granted separately, + * and for until then we have to accept ambiguities when object is shared + * across visible view layers and has overrides on it. + */ + Depsgraph *depsgraph = BKE_scene_get_depsgraph(scene, view_layer, true); + DEG_make_active(depsgraph); + BKE_scene_graph_update_tagged(depsgraph, bmain); } } @@ -4380,11 +4387,11 @@ void WM_window_cursor_keymap_status_refresh(bContext *C, struct wmWindow *win) { bToolRef *tref = NULL; if (ar->regiontype == RGN_TYPE_WINDOW) { - Scene *scene = WM_window_get_active_scene(win); + ViewLayer *view_layer = WM_window_get_active_view_layer(win); WorkSpace *workspace = WM_window_get_active_workspace(win); const bToolKey tkey = { .space_type = sa->spacetype, - .mode = WM_toolsystem_mode_from_spacetype(workspace, scene, sa, sa->spacetype), + .mode = WM_toolsystem_mode_from_spacetype(view_layer, sa, sa->spacetype), }; tref = WM_toolsystem_ref_find(workspace, &tkey); } diff --git a/source/blender/windowmanager/intern/wm_toolsystem.c b/source/blender/windowmanager/intern/wm_toolsystem.c index cee5079a02f..d06cc21ec21 100644 --- a/source/blender/windowmanager/intern/wm_toolsystem.c +++ b/source/blender/windowmanager/intern/wm_toolsystem.c @@ -69,11 +69,11 @@ static void toolsystem_refresh_screen_from_active_tool( struct bToolRef *WM_toolsystem_ref_from_context(struct bContext *C) { WorkSpace *workspace = CTX_wm_workspace(C); - Scene *scene = CTX_data_scene(C); + ViewLayer *view_layer = CTX_data_view_layer(C); ScrArea *sa = CTX_wm_area(C); const bToolKey tkey = { .space_type = sa->spacetype, - .mode = WM_toolsystem_mode_from_spacetype(workspace, scene, sa, sa->spacetype), + .mode = WM_toolsystem_mode_from_spacetype(view_layer, sa, sa->spacetype), }; bToolRef *tref = WM_toolsystem_ref_find(workspace, &tkey); /* We could return 'sa->runtime.tool' in this case. */ @@ -192,8 +192,8 @@ static void toolsystem_ref_link(bContext *C, WorkSpace *workspace, bToolRef *tre wmWindowManager *wm = bmain->wm.first; for (wmWindow *win = wm->windows.first; win; win = win->next) { if (workspace == WM_window_get_active_workspace(win)) { - Scene *scene = win->scene; - ViewLayer *view_layer = BKE_workspace_view_layer_get(workspace, scene); + Scene *scene = WM_window_get_active_scene(win); + ViewLayer *view_layer = WM_window_get_active_view_layer(win); Paint *paint = BKE_paint_get_active(scene, view_layer); if (paint) { if (brush) { @@ -261,12 +261,12 @@ void WM_toolsystem_refresh_all(struct bContext *C, struct WorkSpace *workspace) void WM_toolsystem_reinit_all(struct bContext *C, wmWindow *win) { bScreen *screen = WM_window_get_active_screen(win); - Scene *scene = WM_window_get_active_scene(win); + ViewLayer *view_layer = WM_window_get_active_view_layer(win); for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) { WorkSpace *workspace = WM_window_get_active_workspace(win); const bToolKey tkey = { .space_type = sa->spacetype, - .mode = WM_toolsystem_mode_from_spacetype(workspace, scene, sa, sa->spacetype), + .mode = WM_toolsystem_mode_from_spacetype(view_layer, sa, sa->spacetype), }; bToolRef *tref = WM_toolsystem_ref_find(workspace, &tkey); if (tref) { @@ -331,11 +331,11 @@ void WM_toolsystem_init(bContext *C) CTX_wm_window_set(C, win); WorkSpace *workspace = WM_window_get_active_workspace(win); bScreen *screen = WM_window_get_active_screen(win); - Scene *scene = WM_window_get_active_scene(win); + ViewLayer *view_layer = WM_window_get_active_view_layer(win); for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) { const bToolKey tkey = { .space_type = sa->spacetype, - .mode = WM_toolsystem_mode_from_spacetype(workspace, scene, sa, sa->spacetype), + .mode = WM_toolsystem_mode_from_spacetype(view_layer, sa, sa->spacetype), }; bToolRef *tref = WM_toolsystem_ref_find(workspace, &tkey); if (tref) { @@ -351,15 +351,13 @@ void WM_toolsystem_init(bContext *C) } int WM_toolsystem_mode_from_spacetype( - WorkSpace *workspace, Scene *scene, ScrArea *sa, - int spacetype) + ViewLayer *view_layer, ScrArea *sa, int spacetype) { int mode = -1; switch (spacetype) { case SPACE_VIEW3D: { /* 'sa' may be NULL in this case. */ - ViewLayer *view_layer = BKE_workspace_view_layer_get(workspace, scene); Object *obact = OBACT(view_layer); if (obact != NULL) { Object *obedit = OBEDIT_FROM_OBACT(obact); @@ -381,15 +379,14 @@ int WM_toolsystem_mode_from_spacetype( } bool WM_toolsystem_key_from_context( - WorkSpace *workspace, Scene *scene, ScrArea *sa, - bToolKey *tkey) + ViewLayer *view_layer, ScrArea *sa, bToolKey *tkey) { int space_type = SPACE_EMPTY; int mode = -1; if (sa != NULL) { space_type = sa->spacetype; - mode = WM_toolsystem_mode_from_spacetype(workspace, scene, sa, space_type); + mode = WM_toolsystem_mode_from_spacetype(view_layer, sa, space_type); } if (mode != -1) { @@ -400,11 +397,11 @@ bool WM_toolsystem_key_from_context( return false; } -void WM_toolsystem_refresh_screen_area(WorkSpace *workspace, Scene *scene, ScrArea *sa) +void WM_toolsystem_refresh_screen_area(WorkSpace *workspace, ViewLayer *view_layer, ScrArea *sa) { sa->runtime.tool = NULL; sa->runtime.is_tool_set = true; - const int mode = WM_toolsystem_mode_from_spacetype(workspace, scene, sa, sa->spacetype); + const int mode = WM_toolsystem_mode_from_spacetype(view_layer, sa, sa->spacetype); for (bToolRef *tref = workspace->tools.first; tref; tref = tref->next) { if (tref->space_type == sa->spacetype) { if (tref->mode == mode) { @@ -426,12 +423,12 @@ void WM_toolsystem_refresh_screen_all(Main *bmain) space_type_has_tools[tref->space_type] = true; } bScreen *screen = WM_window_get_active_screen(win); - Scene *scene = WM_window_get_active_scene(win); + ViewLayer *view_layer = WM_window_get_active_view_layer(win); for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) { sa->runtime.tool = NULL; sa->runtime.is_tool_set = true; if (space_type_has_tools[sa->spacetype]) { - WM_toolsystem_refresh_screen_area(workspace, scene, sa); + WM_toolsystem_refresh_screen_area(workspace, view_layer, sa); } } } @@ -446,10 +443,10 @@ static void toolsystem_refresh_screen_from_active_tool( for (wmWindow *win = wm->windows.first; win; win = win->next) { if (workspace == WM_window_get_active_workspace(win)) { bScreen *screen = WM_window_get_active_screen(win); - Scene *scene = WM_window_get_active_scene(win); + ViewLayer *view_layer = WM_window_get_active_view_layer(win); for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) { if (sa->spacetype == tref->space_type) { - int mode = WM_toolsystem_mode_from_spacetype(workspace, scene, sa, sa->spacetype); + int mode = WM_toolsystem_mode_from_spacetype(view_layer, sa, sa->spacetype); if (mode == tref->mode) { sa->runtime.tool = tref; sa->runtime.is_tool_set = true; @@ -477,9 +474,9 @@ bToolRef *WM_toolsystem_ref_set_by_name( /* Will get from context if not set. */ bToolKey tkey_from_context; if (tkey == NULL) { - Scene *scene = CTX_data_scene(C); + ViewLayer *view_layer = CTX_data_view_layer(C); ScrArea *sa = CTX_wm_area(C); - WM_toolsystem_key_from_context(workspace, scene, sa, &tkey_from_context); + WM_toolsystem_key_from_context(view_layer, sa, &tkey_from_context); tkey = &tkey_from_context; } @@ -526,11 +523,11 @@ static void toolsystem_reinit_ensure_toolref( void WM_toolsystem_update_from_context_view3d(bContext *C) { WorkSpace *workspace = CTX_wm_workspace(C); - Scene *scene = CTX_data_scene(C); + ViewLayer *view_layer = CTX_data_view_layer(C); int space_type = SPACE_VIEW3D; const bToolKey tkey = { .space_type = space_type, - .mode = WM_toolsystem_mode_from_spacetype(workspace, scene, NULL, space_type), + .mode = WM_toolsystem_mode_from_spacetype(view_layer, NULL, space_type), }; toolsystem_reinit_ensure_toolref(C, workspace, &tkey, "Cursor"); } @@ -549,12 +546,12 @@ void WM_toolsystem_do_msg_notify_tag_refresh( bContext *C, wmMsgSubscribeKey *UNUSED(msg_key), wmMsgSubscribeValue *msg_val) { WorkSpace *workspace = CTX_wm_workspace(C); - Scene *scene = CTX_data_scene(C); + ViewLayer *view_layer = CTX_data_view_layer(C); ScrArea *sa = msg_val->user_data; int space_type = sa->spacetype; const bToolKey tkey = { .space_type = space_type, - .mode = WM_toolsystem_mode_from_spacetype(workspace, scene, sa, sa->spacetype), + .mode = WM_toolsystem_mode_from_spacetype(view_layer, sa, sa->spacetype), }; WM_toolsystem_refresh(C, workspace, &tkey); } diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c index d28d2c6b001..f902c4377cc 100644 --- a/source/blender/windowmanager/intern/wm_window.c +++ b/source/blender/windowmanager/intern/wm_window.c @@ -53,6 +53,7 @@ #include "BKE_blender.h" #include "BKE_context.h" #include "BKE_icons.h" +#include "BKE_layer.h" #include "BKE_library.h" #include "BKE_global.h" #include "BKE_main.h" @@ -280,7 +281,6 @@ wmWindow *wm_window_copy(bContext *C, wmWindow *win_src, const bool duplicate_la wmWindow *win_dst = wm_window_new(C, win_parent); WorkSpace *workspace = WM_window_get_active_workspace(win_src); WorkSpaceLayout *layout_old = WM_window_get_active_layout(win_src); - Scene *scene = WM_window_get_active_scene(win_src); WorkSpaceLayout *layout_new; win_dst->posx = win_src->posx + 10; @@ -288,7 +288,8 @@ wmWindow *wm_window_copy(bContext *C, wmWindow *win_src, const bool duplicate_la win_dst->sizex = win_src->sizex; win_dst->sizey = win_src->sizey; - win_dst->scene = scene; + win_dst->scene = win_src->scene; + STRNCPY(win_dst->view_layer_name, win_src->view_layer_name); BKE_workspace_active_set(win_dst->workspace_hook, workspace); layout_new = duplicate_layout ? ED_workspace_layout_duplicate(bmain, workspace, layout_old, win_dst) : layout_old; BKE_workspace_hook_layout_for_workspace_set(win_dst->workspace_hook, workspace, layout_new); @@ -856,6 +857,7 @@ wmWindow *WM_window_open_temp(bContext *C, int x, int y, int sizex, int sizey, i bScreen *screen; ScrArea *sa; Scene *scene = CTX_data_scene(C); + ViewLayer *view_layer = CTX_data_view_layer(C); const char *title; /* convert to native OS window coordinates */ @@ -912,12 +914,10 @@ wmWindow *WM_window_open_temp(bContext *C, int x, int y, int sizex, int sizey, i WM_window_set_active_layout(win, workspace, layout); } - if (win->scene == NULL) { - win->scene = scene; - } - /* In case we reuse an already existing temp window (see win lookup above). */ - else if (WM_window_get_active_scene(win) != scene) { - WM_window_set_active_scene(bmain, C, win, scene); + /* Set scene and view layer to match original window. */ + STRNCPY(win->view_layer_name, view_layer->name); + if (WM_window_get_active_scene(win) != scene) { + ED_screen_scene_change(C, win, scene); } screen->temp = 1; @@ -2128,22 +2128,72 @@ void WM_window_set_active_scene(Main *bmain, bContext *C, wmWindow *win, Scene * { wmWindowManager *wm = CTX_wm_manager(C); wmWindow *win_parent = (win->parent) ? win->parent : win; + bool changed = false; /* Set scene in parent and its child windows. */ - ED_screen_scene_change(C, win_parent, scene); + if (win_parent->scene != scene) { + ED_screen_scene_change(C, win_parent, scene); + changed = true; + } for (wmWindow *win_child = wm->windows.first; win_child; win_child = win_child->next) { - if (win_child->parent == win_parent) { + if (win_child->parent == win_parent && win_child->scene != scene) { ED_screen_scene_change(C, win_child, scene); + changed = true; } } - /* Update depsgraph and renderers for scene change. */ - ViewLayer *view_layer = WM_window_get_active_view_layer(win_parent); - ED_scene_change_update(bmain, scene, view_layer); + if (changed) { + /* Update depsgraph and renderers for scene change. */ + ViewLayer *view_layer = WM_window_get_active_view_layer(win_parent); + ED_scene_change_update(bmain, scene, view_layer); + + /* Complete redraw. */ + WM_event_add_notifier(C, NC_WINDOW, NULL); + } +} + +ViewLayer *WM_window_get_active_view_layer(const wmWindow *win) +{ + Scene *scene = WM_window_get_active_scene(win); + if (scene == NULL) { + return NULL; + } + + ViewLayer *view_layer = BKE_view_layer_find(scene, win->view_layer_name); + if (view_layer) { + return view_layer; + } - /* Complete redraw. */ - WM_event_add_notifier(C, NC_WINDOW, NULL); + return BKE_view_layer_default_view(scene); +} + +void WM_window_set_active_view_layer(wmWindow *win, ViewLayer *view_layer) +{ + BLI_assert(BKE_view_layer_find(WM_window_get_active_scene(win), view_layer->name) != NULL); + + wmWindowManager *wm = G_MAIN->wm.first; + wmWindow *win_parent = (win->parent) ? win->parent : win; + + /* Set view layer in parent and child windows. */ + STRNCPY(win->view_layer_name, view_layer->name); + + for (wmWindow *win_child = wm->windows.first; win_child; win_child = win_child->next) { + if (win_child->parent == win_parent) { + STRNCPY(win_child->view_layer_name, view_layer->name); + } + } +} + +void WM_window_ensure_active_view_layer(wmWindow *win) +{ + /* Update layer name is correct after scene changes, load without UI, etc. */ + Scene *scene = WM_window_get_active_scene(win); + + if (scene && BKE_view_layer_find(scene, win->view_layer_name) == NULL) { + ViewLayer *view_layer = BKE_view_layer_default_view(scene); + STRNCPY(win->view_layer_name, view_layer->name); + } } WorkSpace *WM_window_get_active_workspace(const wmWindow *win) @@ -2189,26 +2239,6 @@ void WM_window_set_active_screen(wmWindow *win, WorkSpace *workspace, bScreen *s BKE_workspace_active_screen_set(win->workspace_hook, workspace, screen); } -struct ViewLayer *WM_window_get_active_view_layer_ex(const wmWindow *win, Scene **r_scene) -{ - const WorkSpace *workspace = WM_window_get_active_workspace(win); - Scene *scene = WM_window_get_active_scene(win); - /* May be NULL in rare cases like closing Blender */ - bScreen *screen = (LIKELY(workspace != NULL) ? BKE_workspace_active_screen_get(win->workspace_hook) : NULL); - if (screen != NULL) { - if (r_scene) { - *r_scene = scene; - } - return BKE_workspace_view_layer_get(workspace, scene); - } - return NULL; -} - -struct ViewLayer *WM_window_get_active_view_layer(const wmWindow *win) -{ - return WM_window_get_active_view_layer_ex(win, NULL); -} - bool WM_window_is_temp_screen(const wmWindow *win) { const bScreen *screen = WM_window_get_active_screen(win); |