diff options
Diffstat (limited to 'source/blender')
95 files changed, 1049 insertions, 524 deletions
diff --git a/source/blender/blenkernel/BKE_context.h b/source/blender/blenkernel/BKE_context.h index 350d7a40875..7b071dc01a5 100644 --- a/source/blender/blenkernel/BKE_context.h +++ b/source/blender/blenkernel/BKE_context.h @@ -54,6 +54,7 @@ struct SceneLayer; struct ScrArea; struct SpaceLink; struct View3D; +struct ViewRender; struct RegionView3D; struct StructRNA; struct ToolSettings; @@ -69,6 +70,7 @@ struct bGPDpalettecolor; struct bGPDbrush; struct wmWindow; struct wmWindowManager; +struct RenderEngineType; struct SpaceText; struct SpaceImage; struct SpaceClip; @@ -251,6 +253,8 @@ struct Scene *CTX_data_scene(const bContext *C); struct LayerCollection *CTX_data_layer_collection(const bContext *C); struct SceneCollection *CTX_data_scene_collection(const bContext *C); struct SceneLayer *CTX_data_scene_layer(const bContext *C); +struct ViewRender *CTX_data_view_render(const bContext *C); +struct RenderEngineType *CTX_data_engine(const bContext *C); struct ToolSettings *CTX_data_tool_settings(const bContext *C); const char *CTX_data_mode_string(const bContext *C); diff --git a/source/blender/blenkernel/BKE_layer.h b/source/blender/blenkernel/BKE_layer.h index 52d5405ec0a..1585742729c 100644 --- a/source/blender/blenkernel/BKE_layer.h +++ b/source/blender/blenkernel/BKE_layer.h @@ -57,7 +57,7 @@ struct WorkSpace; void BKE_layer_exit(void); struct SceneLayer *BKE_scene_layer_from_scene_get(const struct Scene *scene); -struct SceneLayer *BKE_scene_layer_from_workspace_get(const struct WorkSpace *workspace); +struct SceneLayer *BKE_scene_layer_from_workspace_get(const struct Scene *scene, const struct WorkSpace *workspace); struct SceneLayer *BKE_scene_layer_add(struct Scene *scene, const char *name); /* DEPRECATED */ @@ -65,8 +65,6 @@ struct SceneLayer *BKE_scene_layer_context_active_PLACEHOLDER(const struct Scene void BKE_scene_layer_free(struct SceneLayer *sl); -void BKE_scene_layer_engine_set(struct SceneLayer *sl, const char *engine); - void BKE_scene_layer_selected_objects_tag(struct SceneLayer *sl, const int tag); struct SceneLayer *BKE_scene_layer_find_from_collection(const struct Scene *scene, struct LayerCollection *lc); @@ -167,6 +165,10 @@ void BKE_visible_objects_iterator_begin(BLI_Iterator *iter, void *data_in); void BKE_visible_objects_iterator_next(BLI_Iterator *iter); void BKE_visible_objects_iterator_end(BLI_Iterator *iter); +void BKE_renderable_objects_iterator_begin(BLI_Iterator *iter, void *data_in); +void BKE_renderable_objects_iterator_next(BLI_Iterator *iter); +void BKE_renderable_objects_iterator_end(BLI_Iterator *iter); + void BKE_selected_bases_iterator_begin(BLI_Iterator *iter, void *data_in); void BKE_selected_bases_iterator_next(BLI_Iterator *iter); void BKE_selected_bases_iterator_end(BLI_Iterator *iter); @@ -248,6 +250,29 @@ void BKE_visible_bases_iterator_end(BLI_Iterator *iter); ITER_END \ } +typedef struct ObjectsRenderableIteratorData { + struct Scene *scene; + + struct { + struct SceneLayer *scene_layer; + struct Base *base; + struct Scene *set; + } iter; +} ObjectsRenderableIteratorData; + +#define FOREACH_OBJECT_RENDERABLE(scene_, _instance) \ + ObjectsRenderableIteratorData data_ = { \ + .scene = (scene_), \ + }; \ + ITER_BEGIN(BKE_renderable_objects_iterator_begin, \ + BKE_renderable_objects_iterator_next, \ + BKE_renderable_objects_iterator_end, \ + &data_, Object *, _instance) + + +#define FOREACH_OBJECT_RENDERABLE_END \ + ITER_END + #ifdef __cplusplus } #endif diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h index 3bb8f6c9ed3..fe9fb2598d0 100644 --- a/source/blender/blenkernel/BKE_node.h +++ b/source/blender/blenkernel/BKE_node.h @@ -74,6 +74,7 @@ struct PointerRNA; struct RenderData; struct Scene; struct Tex; +struct ViewRender; struct SpaceNode; struct ARegion; struct ColorManagedViewSettings; @@ -282,7 +283,7 @@ typedef struct bNodeTreeType { /* callbacks */ void (*free_cache)(struct bNodeTree *ntree); void (*free_node_cache)(struct bNodeTree *ntree, struct bNode *node); - void (*foreach_nodeclass)(struct Scene *scene, void *calldata, bNodeClassCallback func); /* iteration over all node classes */ + void (*foreach_nodeclass)(struct ViewRender *view_render, void *calldata, bNodeClassCallback func); /* iteration over all node classes */ /* Check visibility in the node editor */ int (*poll)(const struct bContext *C, struct bNodeTreeType *ntreetype); /* Select a node tree from the context */ diff --git a/source/blender/blenkernel/BKE_pointcache.h b/source/blender/blenkernel/BKE_pointcache.h index f0819c8d79d..48fe8423233 100644 --- a/source/blender/blenkernel/BKE_pointcache.h +++ b/source/blender/blenkernel/BKE_pointcache.h @@ -90,6 +90,7 @@ struct ParticleKey; struct ParticleSystem; struct PointCache; struct Scene; +struct SceneLayer; struct SmokeModifierData; struct SoftBody; struct RigidBodyWorld; @@ -186,6 +187,7 @@ typedef struct PTCacheID { typedef struct PTCacheBaker { struct Main *main; struct Scene *scene; + struct SceneLayer *scene_layer; int bake; int render; int anim_init; @@ -319,7 +321,7 @@ struct PointCache *BKE_ptcache_copy_list(struct ListBase *ptcaches_new, const st /********************** Baking *********************/ /* Bakes cache with cache_step sized jumps in time, not accurate but very fast. */ -void BKE_ptcache_quick_cache_all(struct Main *bmain, struct Scene *scene); +void BKE_ptcache_quick_cache_all(struct Main *bmain, struct Scene *scene, struct SceneLayer *scene_layer); /* Bake cache or simulate to current frame with settings defined in the baker. */ void BKE_ptcache_bake(struct PTCacheBaker *baker); diff --git a/source/blender/blenkernel/BKE_scene.h b/source/blender/blenkernel/BKE_scene.h index e517b65cf3e..b31cd1742a2 100644 --- a/source/blender/blenkernel/BKE_scene.h +++ b/source/blender/blenkernel/BKE_scene.h @@ -50,7 +50,8 @@ struct Scene; struct SceneCollection; struct SceneLayer; struct UnitSettings; -struct Main; +struct ViewRender; +struct WorkSpace; typedef enum eSceneCopyMethod { SCE_COPY_NEW = 0, @@ -62,11 +63,21 @@ typedef enum eSceneCopyMethod { /* Use as the contents of a 'for' loop: for (SETLOOPER(...)) { ... */ #define SETLOOPER(_sce_basis, _sce_iter, _base) \ - _sce_iter = _sce_basis, _base = _setlooper_base_step(&_sce_iter, NULL); \ + _sce_iter = _sce_basis, _base = _setlooper_base_step(&_sce_iter, BKE_scene_layer_from_scene_get(_sce_basis), NULL); \ + _base; \ + _base = _setlooper_base_step(&_sce_iter, NULL, _base) + +#define SETLOOPER_SCENE_LAYER(_sce_basis, _scene_layer, _sce_iter, _base) \ + _sce_iter = _sce_basis, _base = _setlooper_base_step(&_sce_iter, _scene_layer, NULL); \ _base; \ - _base = _setlooper_base_step(&_sce_iter, _base) + _base = _setlooper_base_step(&_sce_iter, NULL, _base) -struct Base *_setlooper_base_step(struct Scene **sce_iter, struct Base *base); +#define SETLOOPER_SET_ONLY(_sce_basis, _sce_iter, _base) \ + _sce_iter = _sce_basis, _base = _setlooper_base_step(&_sce_iter, NULL, NULL); \ + _base; \ + _base = _setlooper_base_step(&_sce_iter, NULL, _base) + +struct Base *_setlooper_base_step(struct Scene **sce_iter, struct SceneLayer *scene_layer, struct Base *base); void free_avicodecdata(struct AviCodecData *acd); @@ -168,6 +179,22 @@ int BKE_render_num_threads(const struct RenderData *r); int BKE_render_preview_pixel_size(const struct RenderData *r); +/**********************************/ + +struct ViewRender *BKE_viewrender_get(struct Scene *scene, struct WorkSpace *workspace); +void BKE_viewrender_init(struct ViewRender *view_render); +void BKE_viewrender_free(struct ViewRender *view_render); +void BKE_viewrender_copy(struct ViewRender *view_render_dst, const struct ViewRender *view_render_src); +bool BKE_viewrender_use_new_shading_nodes(const struct ViewRender *view_render); +bool BKE_viewrender_use_shading_nodes_custom(const struct ViewRender *view_render); +bool BKE_viewrender_use_world_space_shading(const struct ViewRender *view_render); +bool BKE_viewrender_use_spherical_stereo(const struct ViewRender *view_render); +bool BKE_viewrender_uses_blender_internal(const struct ViewRender *view_render); +bool BKE_viewrender_uses_blender_game(const struct ViewRender *view_render); +bool BKE_viewrender_uses_blender_eevee(const struct ViewRender *view_render); + +/**********************************/ + double BKE_scene_unit_scale(const struct UnitSettings *unit, const int unit_type, double value); /* multiview */ diff --git a/source/blender/blenkernel/BKE_screen.h b/source/blender/blenkernel/BKE_screen.h index 3cb78a427ab..2bbe5b0587e 100644 --- a/source/blender/blenkernel/BKE_screen.h +++ b/source/blender/blenkernel/BKE_screen.h @@ -85,7 +85,7 @@ typedef struct SpaceType { void (*exit)(struct wmWindowManager *, struct ScrArea *); /* Listeners can react to bContext changes */ void (*listener)(struct bScreen *sc, struct ScrArea *, - struct wmNotifier *, const struct Scene *scene); + struct wmNotifier *, struct Scene *scene, struct WorkSpace *workspace); /* refresh context, called after filereads, ED_area_tag_refresh() */ void (*refresh)(const struct bContext *, struct ScrArea *); diff --git a/source/blender/blenkernel/BKE_sequencer.h b/source/blender/blenkernel/BKE_sequencer.h index bcc06a4ab25..dfb6b47a4e4 100644 --- a/source/blender/blenkernel/BKE_sequencer.h +++ b/source/blender/blenkernel/BKE_sequencer.h @@ -422,7 +422,8 @@ struct Sequence *BKE_sequencer_add_movie_strip(struct bContext *C, ListBase *seq /* view3d draw callback, run when not in background view */ typedef struct ImBuf *(*SequencerDrawView)( - const struct EvaluationContext *eval_ctx, struct Scene *, struct SceneLayer *sl, struct Object *, int, int, + const struct EvaluationContext *eval_ctx, struct Scene *, + struct SceneLayer *sl, struct Object *, int, int, unsigned int, int, bool, bool, bool, int, int, bool, const char *, struct GPUFX *, struct GPUOffScreen *, char[256]); diff --git a/source/blender/blenkernel/BKE_workspace.h b/source/blender/blenkernel/BKE_workspace.h index 43962c2eb35..67868ee961a 100644 --- a/source/blender/blenkernel/BKE_workspace.h +++ b/source/blender/blenkernel/BKE_workspace.h @@ -115,6 +115,12 @@ 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(); +struct ViewRender *BKE_workspace_view_render_get(struct WorkSpace *workspace) GETTER_ATTRS; + +/* flags */ +bool BKE_workspace_use_scene_settings_get(const struct WorkSpace *workspace) GETTER_ATTRS; +void BKE_workspace_use_scene_settings_set(struct WorkSpace *workspace, bool value) SETTER_ATTRS; + #undef GETTER_ATTRS #undef SETTER_ATTRS diff --git a/source/blender/blenkernel/intern/collision.c b/source/blender/blenkernel/intern/collision.c index acb48a9646f..bc50fdd5a11 100644 --- a/source/blender/blenkernel/intern/collision.c +++ b/source/blender/blenkernel/intern/collision.c @@ -47,6 +47,7 @@ #include "BKE_cloth.h" #include "BKE_effect.h" +#include "BKE_layer.h" #include "BKE_modifier.h" #include "BKE_scene.h" diff --git a/source/blender/blenkernel/intern/context.c b/source/blender/blenkernel/intern/context.c index 4f1dd18b39c..bc75958ba33 100644 --- a/source/blender/blenkernel/intern/context.c +++ b/source/blender/blenkernel/intern/context.c @@ -57,6 +57,8 @@ #include "BKE_sound.h" #include "BKE_workspace.h" +#include "RE_engine.h" + #include "RNA_access.h" #ifdef WITH_PYTHON @@ -927,10 +929,36 @@ SceneLayer *CTX_data_scene_layer(const bContext *C) return sl; } else { - return BKE_scene_layer_from_workspace_get(CTX_wm_workspace(C)); + return BKE_scene_layer_from_workspace_get(CTX_data_scene(C), CTX_wm_workspace(C)); + } +} + +ViewRender *CTX_data_view_render(const bContext *C) +{ + ViewRender *view_render; + + if (ctx_data_pointer_verify(C, "view_render", (void *)&view_render)) { + return view_render; + } + else { + Scene *scene = CTX_data_scene(C); + WorkSpace *workspace = CTX_wm_workspace(C); + return BKE_viewrender_get(scene, workspace); } } +RenderEngineType *CTX_data_engine(const bContext *C) +{ + const char *engine_id; + + if (!ctx_data_pointer_verify(C, "engine", (void *)&engine_id)) { + ViewRender *view_render = CTX_data_view_render(C); + engine_id = view_render->engine_id; + } + + return RE_engines_find(engine_id); +} + /** * This is tricky. Sometimes the user overrides the render_layer * but not the scene_collection. In this case what to do? @@ -1247,7 +1275,8 @@ void CTX_data_eval_ctx(const bContext *C, EvaluationContext *eval_ctx) Scene *scene = CTX_data_scene(C); SceneLayer *scene_layer = CTX_data_scene_layer(C); + RenderEngineType *engine = CTX_data_engine(C); DEG_evaluation_context_init_from_scene(eval_ctx, - scene, scene_layer, + scene, scene_layer, engine, DAG_EVAL_VIEWPORT); } diff --git a/source/blender/blenkernel/intern/layer.c b/source/blender/blenkernel/intern/layer.c index f20b96b8bc7..0e0290414a4 100644 --- a/source/blender/blenkernel/intern/layer.c +++ b/source/blender/blenkernel/intern/layer.c @@ -82,9 +82,14 @@ SceneLayer *BKE_scene_layer_from_scene_get(const Scene *scene) /** * Returns the SceneLayer to be used for drawing, outliner, and other context related areas. */ -SceneLayer *BKE_scene_layer_from_workspace_get(const struct WorkSpace *workspace) +SceneLayer *BKE_scene_layer_from_workspace_get(const struct Scene *scene, const struct WorkSpace *workspace) { - return BKE_workspace_render_layer_get(workspace); + if (BKE_workspace_use_scene_settings_get(workspace)) { + return BKE_scene_layer_from_scene_get(scene); + } + else { + return BKE_workspace_render_layer_get(workspace); + } } /** @@ -171,14 +176,6 @@ void BKE_scene_layer_free(SceneLayer *sl) } /** - * Set the render engine of a renderlayer - */ -void BKE_scene_layer_engine_set(SceneLayer *sl, const char *engine) -{ - BLI_strncpy_utf8(sl->engine, engine, sizeof(sl->engine)); -} - -/** * Tag all the selected objects of a renderlayer */ void BKE_scene_layer_selected_objects_tag(SceneLayer *sl, const int tag) @@ -1781,6 +1778,89 @@ void BKE_visible_bases_iterator_end(BLI_Iterator *UNUSED(iter)) /* do nothing */ } +void BKE_renderable_objects_iterator_begin(BLI_Iterator *iter, void *data_in) +{ + ObjectsRenderableIteratorData *data = data_in; + + for (Scene *scene = data->scene; scene; scene = scene->set) { + for (SceneLayer *sl = scene->render_layers.first; sl; sl = sl->next) { + for (Base *base = sl->object_bases.first; base; base = base->next) { + base->object->id.flag |= LIB_TAG_DOIT; + } + } + } + + SceneLayer *scene_layer = data->scene->render_layers.first; + data->iter.scene_layer = scene_layer; + + Base base = {(Base *)scene_layer->object_bases.first, NULL}; + data->iter.base = &base; + + data->iter.set = NULL; + + iter->data = data_in; + BKE_renderable_objects_iterator_next(iter); +} + +void BKE_renderable_objects_iterator_next(BLI_Iterator *iter) +{ + ObjectsRenderableIteratorData *data = iter->data; + Base *base = data->iter.base->next; + + /* There is still a base in the current scene layer. */ + if (base != NULL) { + Object *ob = base->object; + + iter->current = ob; + data->iter.base = base; + + if ((base->flag & BASE_VISIBLED) == 0) { + BKE_renderable_objects_iterator_next(iter); + } + return; + } + + /* Time to go to the next scene layer. */ + if (data->iter.set == NULL) { + while ((data->iter.scene_layer = data->iter.scene_layer->next)) { + SceneLayer *scene_layer = data->iter.scene_layer; + if (scene_layer->flag & SCENE_LAYER_RENDER) { + + Base base_iter = {(Base *)scene_layer->object_bases.first, NULL}; + data->iter.base = &base_iter; + + BKE_renderable_objects_iterator_next(iter); + return; + } + } + + /* Setup the "set" for the next iteration. */ + Scene scene = {.set = data->scene}; + data->iter.set = &scene; + BKE_renderable_objects_iterator_next(iter); + return; + } + + /* Look for an object in the next set. */ + while ((data->iter.set = data->iter.set->set)) { + SceneLayer *scene_layer = BKE_scene_layer_from_scene_get(data->iter.set); + + Base base_iter = {(Base *)scene_layer->object_bases.first, NULL}; + data->iter.base = &base_iter; + + BKE_renderable_objects_iterator_next(iter); + return; + } + + iter->current = NULL; + iter->valid = false; +} + +void BKE_renderable_objects_iterator_end(BLI_Iterator *UNUSED(iter)) +{ + /* Do nothing - iter->data was static allocated, we can't free it. */ +} + /* Evaluation */ /** diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c index 5ec3156f4df..35d65551483 100644 --- a/source/blender/blenkernel/intern/pointcache.c +++ b/source/blender/blenkernel/intern/pointcache.c @@ -3509,13 +3509,14 @@ PointCache *BKE_ptcache_copy_list(ListBase *ptcaches_new, const ListBase *ptcach * every user action changing stuff, and then it runs a complete bake??? (ton) */ /* Baking */ -void BKE_ptcache_quick_cache_all(Main *bmain, Scene *scene) +void BKE_ptcache_quick_cache_all(Main *bmain, Scene *scene, SceneLayer *scene_layer) { PTCacheBaker baker; memset(&baker, 0, sizeof(baker)); baker.main = bmain; baker.scene = scene; + baker.scene_layer = scene_layer; baker.bake = 0; baker.render = 0; baker.anim_init = 0; @@ -3541,6 +3542,7 @@ void BKE_ptcache_bake(PTCacheBaker *baker) { Main *bmain = baker->main; Scene *scene = baker->scene; + SceneLayer *scene_layer = baker->scene_layer; Scene *sce_iter; /* SETLOOPER macro only */ Base *base; ListBase pidlist; @@ -3603,7 +3605,7 @@ void BKE_ptcache_bake(PTCacheBaker *baker) } } else { - for (SETLOOPER(scene, sce_iter, base)) { + for (SETLOOPER_SCENE_LAYER(scene, scene_layer, sce_iter, base)) { /* cache/bake everything in the scene */ BKE_ptcache_ids_from_object(&pidlist, base->object, scene, MAX_DUPLI_RECUR); @@ -3714,7 +3716,7 @@ void BKE_ptcache_bake(PTCacheBaker *baker) } } else { - for (SETLOOPER(scene, sce_iter, base)) { + for (SETLOOPER_SCENE_LAYER(scene, scene_layer, sce_iter, base)) { BKE_ptcache_ids_from_object(&pidlist, base->object, scene, MAX_DUPLI_RECUR); for (pid=pidlist.first; pid; pid=pid->next) { diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index 6b2d809c31a..f49ba37faaa 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -49,6 +49,7 @@ #include "DNA_space_types.h" #include "DNA_view3d_types.h" #include "DNA_windowmanager_types.h" +#include "DNA_workspace_types.h" #include "DNA_gpencil_types.h" #include "BLI_math.h" @@ -905,7 +906,7 @@ void BKE_scene_init(Scene *sce) sce->r.ffcodecdata.audio_bitrate = 192; sce->r.ffcodecdata.audio_channels = 2; - BLI_strncpy(sce->r.engine, RE_engine_id_BLENDER_EEVEE, sizeof(sce->r.engine)); + BKE_viewrender_init(&sce->view_render); sce->audio.distance_model = 2.0f; sce->audio.doppler_factor = 1.0f; @@ -1541,9 +1542,11 @@ static bool check_rendered_viewport_visible(Main *bmain) wmWindow *window; for (window = wm->windows.first; window != NULL; window = window->next) { const bScreen *screen = BKE_workspace_active_screen_get(window->workspace_hook); + WorkSpace *workspace = BKE_workspace_active_get(window->workspace_hook); Scene *scene = window->scene; + ViewRender *view_render = BKE_viewrender_get(scene, workspace); ScrArea *area; - RenderEngineType *type = RE_engines_find(scene->r.engine); + RenderEngineType *type = RE_engines_find(view_render->engine_id); if ((type->draw_engine != NULL) || (type->render_to_view == NULL)) { continue; } @@ -1833,38 +1836,32 @@ float get_render_aosss_error(const RenderData *r, float error) } /** - * Helper function for the SETLOOPER macro + * Helper function for the SETLOOPER and SETLOOPER_SCENE_LAYER macros * * It iterates over the bases of the active layer and then the bases * of the active layer of the background (set) scenes recursively. */ -Base *_setlooper_base_step(Scene **sce_iter, Base *base) +Base *_setlooper_base_step(Scene **sce_iter, SceneLayer *scene_layer, Base *base) { if (base && base->next) { - /* common case, step to the next */ + /* Common case, step to the next. */ return base->next; } - else if (base == NULL) { - /* first time looping, return the scenes first base */ - - /* for the first loop we should get the layer from context */ - SceneLayer *sl = BKE_scene_layer_context_active_PLACEHOLDER((*sce_iter)); - /* TODO For first scene (non-background set), we should pass the render layer as argument. - * In some cases we want it to be the workspace one, in other the scene one. */ - TODO_LAYER; - - if (sl->object_bases.first) { - return (Base *)sl->object_bases.first; + else if ((base == NULL) && (scene_layer != NULL)) { + /* First time looping, return the scenes first base. */ + /* For the first loop we should get the layer from workspace when available. */ + if (scene_layer->object_bases.first) { + return (Base *)scene_layer->object_bases.first; } - /* no base on this scene layer */ + /* No base on this scene layer. */ goto next_set; } else { next_set: - /* reached the end, get the next base in the set */ + /* Reached the end, get the next base in the set. */ while ((*sce_iter = (*sce_iter)->set)) { - SceneLayer *sl = BKE_scene_layer_from_scene_get((*sce_iter)); - base = (Base *)sl->object_bases.first; + SceneLayer *scene_layer_set = BKE_scene_layer_from_scene_get((*sce_iter)); + base = (Base *)scene_layer_set->object_bases.first; if (base) { return base; @@ -1877,42 +1874,39 @@ next_set: bool BKE_scene_use_new_shading_nodes(const Scene *scene) { - const RenderEngineType *type = RE_engines_find(scene->r.engine); - return (type && type->flag & RE_USE_SHADING_NODES); + return BKE_viewrender_use_new_shading_nodes(&scene->view_render); } bool BKE_scene_use_shading_nodes_custom(Scene *scene) { - RenderEngineType *type = RE_engines_find(scene->r.engine); - return (type && type->flag & RE_USE_SHADING_NODES_CUSTOM); + return BKE_viewrender_use_shading_nodes_custom(&scene->view_render); } bool BKE_scene_use_world_space_shading(Scene *scene) { - const RenderEngineType *type = RE_engines_find(scene->r.engine); + RenderEngineType *type = RE_engines_find(scene->view_render.engine_id); return ((scene->r.mode & R_USE_WS_SHADING) || (type && (type->flag & RE_USE_SHADING_NODES))); } bool BKE_scene_use_spherical_stereo(Scene *scene) { - RenderEngineType *type = RE_engines_find(scene->r.engine); - return (type && type->flag & RE_USE_SPHERICAL_STEREO); + return BKE_viewrender_use_spherical_stereo(&scene->view_render); } -bool BKE_scene_uses_blender_internal(const Scene *scene) +bool BKE_scene_uses_blender_internal(const Scene *scene) { - return STREQ(scene->r.engine, RE_engine_id_BLENDER_RENDER); + return BKE_viewrender_uses_blender_internal(&scene->view_render); } bool BKE_scene_uses_blender_game(const Scene *scene) { - return STREQ(scene->r.engine, RE_engine_id_BLENDER_GAME); + return BKE_viewrender_uses_blender_game(&scene->view_render); } bool BKE_scene_uses_blender_eevee(const Scene *scene) { - return STREQ(scene->r.engine, RE_engine_id_BLENDER_EEVEE); + return BKE_viewrender_uses_blender_eevee(&scene->view_render); } void BKE_scene_base_flag_to_objects(SceneLayer *sl) @@ -2027,6 +2021,81 @@ int BKE_render_preview_pixel_size(const RenderData *r) return r->preview_pixel_size; } +/* ***************************************************** */ +/* render engine settings */ + +ViewRender *BKE_viewrender_get(Scene *scene, WorkSpace *workspace) +{ + if (workspace == NULL || BKE_workspace_use_scene_settings_get(workspace)) { + return &scene->view_render; + } + return BKE_workspace_view_render_get(workspace); +} + +/** + * Initialize a static created struct for WorkSpace and Scene to store the viewport + * related drawing data. + */ +void BKE_viewrender_init(ViewRender *view_render) +{ + BLI_strncpy(view_render->engine_id, RE_engine_id_BLENDER_EEVEE, sizeof(view_render->engine_id)); +} + +/** + * Do not free ViewRender itself since it's not even allocated. + */ +void BKE_viewrender_free(ViewRender *UNUSED(view_render)) +{ + /* Do nothing. */ +} + +/** + * Copy used by libblock copying. + */ +void BKE_viewrender_copy(ViewRender *to, const ViewRender *from) +{ + *to = *from; +} + +bool BKE_viewrender_use_new_shading_nodes(const ViewRender *view_render) +{ + RenderEngineType *type = RE_engines_find(view_render->engine_id); + return (type && type->flag & RE_USE_SHADING_NODES); +} + +bool BKE_viewrender_use_shading_nodes_custom(const ViewRender *view_render) +{ + RenderEngineType *type = RE_engines_find(view_render->engine_id); + return (type && type->flag & RE_USE_SHADING_NODES_CUSTOM); +} + +bool BKE_viewrender_use_spherical_stereo(const ViewRender *view_render) +{ + const char *engine_id = view_render->engine_id; + RenderEngineType *type = RE_engines_find(engine_id); + return (type && type->flag & RE_USE_SPHERICAL_STEREO); +} + +bool BKE_viewrender_uses_blender_internal(const ViewRender *view_render) +{ + const char *engine_id = view_render->engine_id; + return STREQ(engine_id, RE_engine_id_BLENDER_RENDER); +} + +bool BKE_viewrender_uses_blender_game(const ViewRender *view_render) +{ + const char *engine_id = view_render->engine_id; + return STREQ(engine_id, RE_engine_id_BLENDER_GAME); +} + +bool BKE_viewrender_uses_blender_eevee(const ViewRender *view_render) +{ + const char *engine_id = view_render->engine_id; + return STREQ(engine_id, RE_engine_id_BLENDER_EEVEE); +} + +/* ***************************************************** */ + /* Apply the needed correction factor to value, based on unit_type (only length-related are affected currently) * and unit->scale_length. */ diff --git a/source/blender/blenkernel/intern/sound.c b/source/blender/blenkernel/intern/sound.c index a2568707b0a..6cf310461c1 100644 --- a/source/blender/blenkernel/intern/sound.c +++ b/source/blender/blenkernel/intern/sound.c @@ -806,13 +806,76 @@ void BKE_sound_read_waveform(bSound *sound, short *stop) BLI_spin_unlock(sound->spinlock); } -void BKE_sound_update_scene(Main *bmain, struct Scene *scene) +static void sound_update_base(Scene *scene, Base *base, void *new_set) { - Object *ob; - Base *base; + Object *ob = base->object; NlaTrack *track; NlaStrip *strip; Speaker *speaker; + float quat[4]; + + if ((ob->id.tag & LIB_TAG_DOIT) == 0) { + return; + } + + ob->id.tag &= ~LIB_TAG_DOIT; + + if ((ob->type != OB_SPEAKER) || !ob->adt) { + return; + } + + for (track = ob->adt->nla_tracks.first; track; track = track->next) { + for (strip = track->strips.first; strip; strip = strip->next) { + if (strip->type != NLASTRIP_TYPE_SOUND) { + continue; + } + speaker = (Speaker *)ob->data; + + if (AUD_removeSet(scene->speaker_handles, strip->speaker_handle)) { + if (speaker->sound) { + AUD_SequenceEntry_move(strip->speaker_handle, (double)strip->start / FPS, FLT_MAX, 0); + } + else { + AUD_Sequence_remove(scene->sound_scene, strip->speaker_handle); + strip->speaker_handle = NULL; + } + } + else { + if (speaker->sound) { + strip->speaker_handle = AUD_Sequence_add(scene->sound_scene, + speaker->sound->playback_handle, + (double)strip->start / FPS, FLT_MAX, 0); + AUD_SequenceEntry_setRelative(strip->speaker_handle, 0); + } + } + + if (strip->speaker_handle) { + const bool mute = ((strip->flag & NLASTRIP_FLAG_MUTED) || (speaker->flag & SPK_MUTED)); + AUD_addSet(new_set, strip->speaker_handle); + AUD_SequenceEntry_setVolumeMaximum(strip->speaker_handle, speaker->volume_max); + AUD_SequenceEntry_setVolumeMinimum(strip->speaker_handle, speaker->volume_min); + AUD_SequenceEntry_setDistanceMaximum(strip->speaker_handle, speaker->distance_max); + AUD_SequenceEntry_setDistanceReference(strip->speaker_handle, speaker->distance_reference); + AUD_SequenceEntry_setAttenuation(strip->speaker_handle, speaker->attenuation); + AUD_SequenceEntry_setConeAngleOuter(strip->speaker_handle, speaker->cone_angle_outer); + AUD_SequenceEntry_setConeAngleInner(strip->speaker_handle, speaker->cone_angle_inner); + AUD_SequenceEntry_setConeVolumeOuter(strip->speaker_handle, speaker->cone_volume_outer); + + mat4_to_quat(quat, ob->obmat); + AUD_SequenceEntry_setAnimationData(strip->speaker_handle, AUD_AP_LOCATION, CFRA, ob->obmat[3], 1); + AUD_SequenceEntry_setAnimationData(strip->speaker_handle, AUD_AP_ORIENTATION, CFRA, quat, 1); + AUD_SequenceEntry_setAnimationData(strip->speaker_handle, AUD_AP_VOLUME, CFRA, &speaker->volume, 1); + AUD_SequenceEntry_setAnimationData(strip->speaker_handle, AUD_AP_PITCH, CFRA, &speaker->pitch, 1); + AUD_SequenceEntry_setSound(strip->speaker_handle, speaker->sound->playback_handle); + AUD_SequenceEntry_setMuted(strip->speaker_handle, mute); + } + } + } +} + +void BKE_sound_update_scene(Main *bmain, Scene *scene) +{ + Base *base; Scene *sce_it; void *new_set = AUD_createSet(); @@ -821,59 +884,18 @@ void BKE_sound_update_scene(Main *bmain, struct Scene *scene) /* cheap test to skip looping over all objects (no speakers is a common case) */ if (!BLI_listbase_is_empty(&bmain->speaker)) { - for (SETLOOPER(scene, sce_it, base)) { - ob = base->object; - if ((ob->type != OB_SPEAKER) || !ob->adt) { - continue; - } - for (track = ob->adt->nla_tracks.first; track; track = track->next) { - for (strip = track->strips.first; strip; strip = strip->next) { - if (strip->type != NLASTRIP_TYPE_SOUND) { - continue; - } - speaker = (Speaker *)ob->data; - - if (AUD_removeSet(scene->speaker_handles, strip->speaker_handle)) { - if (speaker->sound) { - AUD_SequenceEntry_move(strip->speaker_handle, (double)strip->start / FPS, FLT_MAX, 0); - } - else { - AUD_Sequence_remove(scene->sound_scene, strip->speaker_handle); - strip->speaker_handle = NULL; - } - } - else { - if (speaker->sound) { - strip->speaker_handle = AUD_Sequence_add(scene->sound_scene, - speaker->sound->playback_handle, - (double)strip->start / FPS, FLT_MAX, 0); - AUD_SequenceEntry_setRelative(strip->speaker_handle, 0); - } - } - - if (strip->speaker_handle) { - const bool mute = ((strip->flag & NLASTRIP_FLAG_MUTED) || (speaker->flag & SPK_MUTED)); - AUD_addSet(new_set, strip->speaker_handle); - AUD_SequenceEntry_setVolumeMaximum(strip->speaker_handle, speaker->volume_max); - AUD_SequenceEntry_setVolumeMinimum(strip->speaker_handle, speaker->volume_min); - AUD_SequenceEntry_setDistanceMaximum(strip->speaker_handle, speaker->distance_max); - AUD_SequenceEntry_setDistanceReference(strip->speaker_handle, speaker->distance_reference); - AUD_SequenceEntry_setAttenuation(strip->speaker_handle, speaker->attenuation); - AUD_SequenceEntry_setConeAngleOuter(strip->speaker_handle, speaker->cone_angle_outer); - AUD_SequenceEntry_setConeAngleInner(strip->speaker_handle, speaker->cone_angle_inner); - AUD_SequenceEntry_setConeVolumeOuter(strip->speaker_handle, speaker->cone_volume_outer); - - mat4_to_quat(quat, ob->obmat); - AUD_SequenceEntry_setAnimationData(strip->speaker_handle, AUD_AP_LOCATION, CFRA, ob->obmat[3], 1); - AUD_SequenceEntry_setAnimationData(strip->speaker_handle, AUD_AP_ORIENTATION, CFRA, quat, 1); - AUD_SequenceEntry_setAnimationData(strip->speaker_handle, AUD_AP_VOLUME, CFRA, &speaker->volume, 1); - AUD_SequenceEntry_setAnimationData(strip->speaker_handle, AUD_AP_PITCH, CFRA, &speaker->pitch, 1); - AUD_SequenceEntry_setSound(strip->speaker_handle, speaker->sound->playback_handle); - AUD_SequenceEntry_setMuted(strip->speaker_handle, mute); - } - } + BKE_main_id_tag_listbase(&bmain->object, LIB_TAG_DOIT, true); + + for (SceneLayer *scene_layer = scene->render_layers.first; scene_layer; scene_layer = scene_layer->next) { + for (base = scene_layer->object_bases.first; base; base = base->next) { + sound_update_base(scene, base, new_set); } } + + for (SETLOOPER_SET_ONLY(scene, sce_it, base)) { + sound_update_base(scene, base, new_set); + } + } while ((handle = AUD_getSet(scene->speaker_handles))) { diff --git a/source/blender/blenkernel/intern/workspace.c b/source/blender/blenkernel/intern/workspace.c index 05dab9208e5..0747bde16d3 100644 --- a/source/blender/blenkernel/intern/workspace.c +++ b/source/blender/blenkernel/intern/workspace.c @@ -29,12 +29,14 @@ #include "BLI_utildefines.h" #include "BLI_string.h" +#include "BLI_string_utf8.h" #include "BLI_string_utils.h" #include "BLI_listbase.h" #include "BKE_global.h" #include "BKE_library.h" #include "BKE_main.h" +#include "BKE_scene.h" #include "BKE_screen.h" #include "BKE_workspace.h" @@ -161,6 +163,7 @@ void BKE_workspace_remove(Main *bmain, WorkSpace *workspace) BKE_workspace_layout_remove(bmain, workspace, layout); } + BKE_viewrender_free(&workspace->view_render); BKE_libblock_free(bmain, workspace); } @@ -430,3 +433,27 @@ void BKE_workspace_hook_layout_for_workspace_set( hook->act_layout = layout; workspace_relation_ensure_updated(&workspace->hook_layout_relations, hook, layout); } + +/** + * Get the render engine of a workspace, to be used in the viewport. + */ +ViewRender *BKE_workspace_view_render_get(WorkSpace *workspace) +{ + return &workspace->view_render; +} + +/* Flags */ +bool BKE_workspace_use_scene_settings_get(const WorkSpace *workspace) +{ + return (workspace->flags & WORKSPACE_USE_SCENE_SETTINGS) != 0; +} + +void BKE_workspace_use_scene_settings_set(WorkSpace *workspace, bool value) +{ + if (value) { + workspace->flags |= WORKSPACE_USE_SCENE_SETTINGS; + } + else { + workspace->flags &= ~WORKSPACE_USE_SCENE_SETTINGS; + } +} diff --git a/source/blender/blenloader/intern/versioning_280.c b/source/blender/blenloader/intern/versioning_280.c index ba46c8f81b8..55245cec56c 100644 --- a/source/blender/blenloader/intern/versioning_280.c +++ b/source/blender/blenloader/intern/versioning_280.c @@ -192,7 +192,6 @@ void do_versions_after_linking_280(Main *main) for (SceneRenderLayer *srl = scene->r.layers.first; srl; srl = srl->next) { SceneLayer *sl = BKE_scene_layer_add(scene, srl->name); - BKE_scene_layer_engine_set(sl, scene->r.engine); if (srl->mat_override) { BKE_collection_override_datablock_add((LayerCollection *)sl->layer_collections.first, "material", (ID *)srl->mat_override); @@ -510,4 +509,17 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *main) printf("You need to combine transparency and emission shaders to the converted Principled shader nodes.\n"); } } + + { + if (!DNA_struct_elem_find(fd->filesdna, "Scene", "ViewRender", "view_render")) { + for (Scene *scene = main->scene.first; scene; scene = scene->id.next) { + BLI_strncpy_utf8(scene->view_render.engine_id, scene->r.engine, + sizeof(scene->view_render.engine_id)); + } + + for (WorkSpace *workspace = main->workspaces.first; workspace; workspace = workspace->id.next) { + BKE_viewrender_init(&workspace->view_render); + } + } + } } diff --git a/source/blender/blenloader/intern/versioning_defaults.c b/source/blender/blenloader/intern/versioning_defaults.c index 54ed29ab6fa..925a87cb653 100644 --- a/source/blender/blenloader/intern/versioning_defaults.c +++ b/source/blender/blenloader/intern/versioning_defaults.c @@ -45,6 +45,7 @@ #include "BKE_brush.h" #include "BKE_library.h" #include "BKE_main.h" +#include "BKE_scene.h" #include "BKE_workspace.h" #include "BLO_readfile.h" @@ -103,6 +104,7 @@ static void update_defaults_startup_workspaces(Main *bmain) if (STREQ(workspace->id.name + 2, "Default")) { /* don't rename within iterator, renaming causes listbase to be re-sorted */ workspace_default = workspace; + BKE_viewrender_init(&workspace->view_render); } else { BKE_workspace_remove(bmain, workspace); @@ -120,7 +122,7 @@ static void update_defaults_startup_workspaces(Main *bmain) void BLO_update_defaults_startup_blend(Main *bmain) { for (Scene *scene = bmain->scene.first; scene; scene = scene->id.next) { - BLI_strncpy(scene->r.engine, RE_engine_id_BLENDER_EEVEE, sizeof(scene->r.engine)); + BLI_strncpy(scene->view_render.engine_id, RE_engine_id_BLENDER_EEVEE, sizeof(scene->view_render.engine_id)); scene->r.im_format.planes = R_IMF_PLANES_RGBA; scene->r.im_format.compress = 15; diff --git a/source/blender/depsgraph/DEG_depsgraph.h b/source/blender/depsgraph/DEG_depsgraph.h index 932a7c51286..e05b417f245 100644 --- a/source/blender/depsgraph/DEG_depsgraph.h +++ b/source/blender/depsgraph/DEG_depsgraph.h @@ -65,6 +65,7 @@ struct Main; struct PointerRNA; struct PropertyRNA; +struct RenderEngineType; struct Scene; struct SceneLayer; @@ -84,6 +85,7 @@ typedef struct EvaluationContext { float ctime; struct SceneLayer *scene_layer; + struct RenderEngineType *engine; } EvaluationContext; /* DagNode->eval_flags */ @@ -213,6 +215,7 @@ void DEG_evaluation_context_init(struct EvaluationContext *eval_ctx, void DEG_evaluation_context_init_from_scene(struct EvaluationContext *eval_ctx, struct Scene *scene, struct SceneLayer *scene_layer, + struct RenderEngineType *engine, eEvaluationMode mode); /* Free evaluation context. */ diff --git a/source/blender/depsgraph/intern/depsgraph_eval.cc b/source/blender/depsgraph/intern/depsgraph_eval.cc index 77a32740524..9235069f531 100644 --- a/source/blender/depsgraph/intern/depsgraph_eval.cc +++ b/source/blender/depsgraph/intern/depsgraph_eval.cc @@ -79,10 +79,12 @@ void DEG_evaluation_context_init(EvaluationContext *eval_ctx, void DEG_evaluation_context_init_from_scene(EvaluationContext *eval_ctx, Scene *scene, SceneLayer *scene_layer, + RenderEngineType *engine, eEvaluationMode mode) { DEG_evaluation_context_init(eval_ctx, mode); eval_ctx->scene_layer = scene_layer; + eval_ctx->engine = engine; eval_ctx->ctime = BKE_scene_frame_get(scene); } diff --git a/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc b/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc index 03be601ce2c..e4f1e8b9cf6 100644 --- a/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc +++ b/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc @@ -527,9 +527,9 @@ void update_copy_on_write_scene(const Depsgraph *depsgraph, scene_cow->obedit = NULL; } /* Synchronize active render engine. */ - BLI_strncpy_utf8(scene_cow->r.engine, - scene_orig->r.engine, - sizeof(scene_cow->r.engine)); + BLI_strncpy_utf8(scene_cow->view_render.engine_id, + scene_orig->view_render.engine_id, + sizeof(scene_cow->view_render.engine_id)); /* TODO(sergey): What else do we need here? */ } diff --git a/source/blender/draw/DRW_engine.h b/source/blender/draw/DRW_engine.h index 646d8716094..e96aec0766f 100644 --- a/source/blender/draw/DRW_engine.h +++ b/source/blender/draw/DRW_engine.h @@ -42,6 +42,8 @@ struct ViewportEngineData; struct View3D; struct rcti; struct GPUOffScreen; +struct RenderEngineType; +struct WorkSpace; #include "BLI_sys_types.h" /* for bool */ @@ -72,6 +74,7 @@ void DRW_draw_view(const struct bContext *C); void DRW_draw_render_loop_ex( struct Depsgraph *graph, + struct RenderEngineType *engine, struct ARegion *ar, struct View3D *v3d, const struct bContext *evil_C); void DRW_draw_render_loop( @@ -79,6 +82,7 @@ void DRW_draw_render_loop( struct ARegion *ar, struct View3D *v3d); void DRW_draw_render_loop_offscreen( struct Depsgraph *graph, + struct RenderEngineType *engine, struct ARegion *ar, struct View3D *v3d, struct GPUOffScreen *ofs); void DRW_draw_select_loop( diff --git a/source/blender/draw/engines/external/external_engine.c b/source/blender/draw/engines/external/external_engine.c index f4b38b7ebbf..76f5b4d9840 100644 --- a/source/blender/draw/engines/external/external_engine.c +++ b/source/blender/draw/engines/external/external_engine.c @@ -151,17 +151,16 @@ static void external_draw_scene(void *vedata) /* Create render engine. */ if (!rv3d->render_engine) { - RenderEngine *engine; - type = RE_engines_find(scene->r.engine); + RenderEngineType *engine_type = draw_ctx->engine; - if (!(type->view_update && type->render_to_view)) { + if (!(engine_type->view_update && engine_type->render_to_view)) { return; } - engine = RE_engine_create_ex(type, true); + RenderEngine *engine = RE_engine_create_ex(engine_type, true); engine->tile_x = scene->r.tilex; engine->tile_y = scene->r.tiley; - type->view_update(engine, draw_ctx->evil_C); + engine_type->view_update(engine, draw_ctx->evil_C); rv3d->render_engine = engine; } diff --git a/source/blender/draw/intern/DRW_render.h b/source/blender/draw/intern/DRW_render.h index 428bea17f7c..e8eedac7048 100644 --- a/source/blender/draw/intern/DRW_render.h +++ b/source/blender/draw/intern/DRW_render.h @@ -438,6 +438,8 @@ typedef struct DRWContextState { /* Use 'scene->obedit' for edit-mode */ struct Object *obact; /* 'OBACT_NEW' */ + struct RenderEngineType *engine; + /* Last resort (some functions take this as an arg so we can't easily avoid). * May be NULL when used for selection or depth buffer. */ const struct bContext *evil_C; diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c index 38a767b7e34..2a3d9fafd2a 100644 --- a/source/blender/draw/intern/draw_manager.c +++ b/source/blender/draw/intern/draw_manager.c @@ -37,6 +37,7 @@ #include "BKE_object.h" #include "BKE_pbvh.h" #include "BKE_paint.h" +#include "BKE_workspace.h" #include "BLT_translation.h" #include "BLF_api.h" @@ -2905,15 +2906,14 @@ static void use_drw_engine(DrawEngineType *engine) /* TODO revisit this when proper layering is implemented */ /* Gather all draw engines needed and store them in DST.enabled_engines * That also define the rendering order of engines */ -static void DRW_engines_enable_from_engine(const Scene *scene) +static void DRW_engines_enable_from_engine(RenderEngineType *engine) { /* TODO layers */ - RenderEngineType *type = RE_engines_find(scene->r.engine); - if (type->draw_engine != NULL) { - use_drw_engine(type->draw_engine); + if (engine->draw_engine != NULL) { + use_drw_engine(engine->draw_engine); } - if ((type->flag & RE_INTERNAL) == 0) { + if ((engine->flag & RE_INTERNAL) == 0) { DRW_engines_enable_external(); } } @@ -2990,11 +2990,12 @@ static void DRW_engines_enable_external(void) use_drw_engine(DRW_engine_viewport_external_type.draw_engine); } -static void DRW_engines_enable(const Scene *scene, SceneLayer *sl) +static void DRW_engines_enable(const Scene *scene, SceneLayer *sl, RenderEngineType *engine) { Object *obact = OBACT_NEW(sl); const int mode = CTX_data_mode_enum_ex(scene->obedit, obact); - DRW_engines_enable_from_engine(scene); + + DRW_engines_enable_from_engine(engine); if (DRW_state_draw_support()) { DRW_engines_enable_from_object_mode(); @@ -3153,7 +3154,8 @@ void DRW_notify_view_update(const bContext *C) View3D *v3d = CTX_wm_view3d(C); RegionView3D *rv3d = ar->regiondata; Scene *scene = DEG_get_evaluated_scene(graph); - SceneLayer *sl = DEG_get_evaluated_scene_layer(graph); + RenderEngineType *engine = CTX_data_engine(C); + SceneLayer *scene_layer = CTX_data_scene_layer(C); if (rv3d->viewport == NULL) { return; @@ -3165,17 +3167,17 @@ void DRW_notify_view_update(const bContext *C) DST.viewport = rv3d->viewport; DST.draw_ctx = (DRWContextState){ - ar, rv3d, v3d, scene, sl, OBACT_NEW(sl), C, + ar, rv3d, v3d, scene, scene_layer, OBACT_NEW(scene_layer), engine, C, }; - DRW_engines_enable(scene, sl); + DRW_engines_enable(scene, scene_layer, engine); for (LinkData *link = DST.enabled_engines.first; link; link = link->next) { - DrawEngineType *engine = link->data; - ViewportEngineData *data = DRW_viewport_engine_data_get(engine); + DrawEngineType *draw_engine = link->data; + ViewportEngineData *data = DRW_viewport_engine_data_get(draw_engine); - if (engine->view_update) { - engine->view_update(data); + if (draw_engine->view_update) { + draw_engine->view_update(data); } } @@ -3197,12 +3199,13 @@ void DRW_notify_view_update(const bContext *C) void DRW_draw_view(const bContext *C) { struct Depsgraph *graph = CTX_data_depsgraph(C); + RenderEngineType *engine = CTX_data_engine(C); ARegion *ar = CTX_wm_region(C); View3D *v3d = CTX_wm_view3d(C); /* Reset before using it. */ memset(&DST, 0x0, sizeof(DST)); - DRW_draw_render_loop_ex(graph, ar, v3d, C); + DRW_draw_render_loop_ex(graph, engine, ar, v3d, C); } /** @@ -3211,11 +3214,12 @@ void DRW_draw_view(const bContext *C) */ void DRW_draw_render_loop_ex( struct Depsgraph *graph, + RenderEngineType *engine, ARegion *ar, View3D *v3d, const bContext *evil_C) { Scene *scene = DEG_get_evaluated_scene(graph); - SceneLayer *sl = DEG_get_evaluated_scene_layer(graph); + SceneLayer *scene_layer = DEG_get_evaluated_scene_layer(graph); RegionView3D *rv3d = ar->regiondata; DST.draw_ctx.evil_C = evil_C; @@ -3228,15 +3232,16 @@ void DRW_draw_render_loop_ex( cache_is_dirty = GPU_viewport_cache_validate(DST.viewport, DRW_engines_get_hash()); DST.draw_ctx = (DRWContextState){ - ar, rv3d, v3d, scene, sl, OBACT_NEW(sl), - /* reuse if caller sets */ - DST.draw_ctx.evil_C, + ar, rv3d, v3d, scene, scene_layer, OBACT_NEW(scene_layer), engine, + + /* reuse if caller sets */ + DST.draw_ctx.evil_C, }; DRW_viewport_var_init(); /* Get list of enabled engines */ - DRW_engines_enable(scene, sl); + DRW_engines_enable(scene, scene_layer, engine); /* Update ubos */ DRW_globals_update(); @@ -3316,11 +3321,15 @@ void DRW_draw_render_loop( { /* Reset before using it. */ memset(&DST, 0x0, sizeof(DST)); - DRW_draw_render_loop_ex(graph, ar, v3d, NULL); + + Scene *scene = DEG_get_evaluated_scene(graph); + RenderEngineType *engine = RE_engines_find(scene->view_render.engine_id); + + DRW_draw_render_loop_ex(graph, engine, ar, v3d, NULL); } void DRW_draw_render_loop_offscreen( - struct Depsgraph *graph, + struct Depsgraph *graph, RenderEngineType *engine, ARegion *ar, View3D *v3d, GPUOffScreen *ofs) { RegionView3D *rv3d = ar->regiondata; @@ -3335,7 +3344,7 @@ void DRW_draw_render_loop_offscreen( /* Reset before using it. */ memset(&DST, 0x0, sizeof(DST)); DST.options.is_image_render = true; - DRW_draw_render_loop_ex(graph, ar, v3d, NULL); + DRW_draw_render_loop_ex(graph, engine, ar, v3d, NULL); /* restore */ { @@ -3360,6 +3369,7 @@ void DRW_draw_select_loop( bool UNUSED(use_obedit_skip), bool UNUSED(use_nearest), const rcti *rect) { Scene *scene = DEG_get_evaluated_scene(graph); + RenderEngineType *engine = RE_engines_find(scene->view_render.engine_id); SceneLayer *sl = DEG_get_evaluated_scene_layer(graph); #ifndef USE_GPU_SELECT UNUSED_VARS(vc, scene, sl, v3d, ar, rect); @@ -3412,7 +3422,7 @@ void DRW_draw_select_loop( /* Instead of 'DRW_context_state_init(C, &DST.draw_ctx)', assign from args */ DST.draw_ctx = (DRWContextState){ - ar, rv3d, v3d, scene, sl, OBACT_NEW(sl), (bContext *)NULL, + ar, rv3d, v3d, scene, sl, OBACT_NEW(sl), engine, (bContext *)NULL, }; DRW_viewport_var_init(); @@ -3478,6 +3488,7 @@ void DRW_draw_depth_loop( ARegion *ar, View3D *v3d) { Scene *scene = DEG_get_evaluated_scene(graph); + RenderEngineType *engine = RE_engines_find(scene->view_render.engine_id); SceneLayer *sl = DEG_get_evaluated_scene_layer(graph); RegionView3D *rv3d = ar->regiondata; @@ -3508,7 +3519,7 @@ void DRW_draw_depth_loop( /* Instead of 'DRW_context_state_init(C, &DST.draw_ctx)', assign from args */ DST.draw_ctx = (DRWContextState){ - ar, rv3d, v3d, scene, sl, OBACT_NEW(sl), (bContext *)NULL, + ar, rv3d, v3d, scene, sl, OBACT_NEW(sl), engine, (bContext *)NULL, }; DRW_viewport_var_init(); diff --git a/source/blender/editors/armature/editarmature_sketch.c b/source/blender/editors/armature/editarmature_sketch.c index 41c1c73e49c..1de7b99c6d2 100644 --- a/source/blender/editors/armature/editarmature_sketch.c +++ b/source/blender/editors/armature/editarmature_sketch.c @@ -998,7 +998,7 @@ static int sk_getStrokeSnapPoint(bContext *C, SK_Point *pt, SK_Sketch *sketch, S * the ideal would be to call this function only at the beginning of the snap operation, * or at the beginning of the operator itself */ struct SnapObjectContext *snap_context = ED_transform_snap_object_context_create_view3d( - CTX_data_main(C), CTX_data_scene(C), CTX_data_scene_layer(C), 0, + CTX_data_main(C), CTX_data_scene(C), CTX_data_scene_layer(C), CTX_data_engine(C), 0, CTX_wm_region(C), CTX_wm_view3d(C)); float mvalf[2] = {UNPACK2(dd->mval)}; diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c index bce6afa2434..f8863a3e00f 100644 --- a/source/blender/editors/curve/editcurve.c +++ b/source/blender/editors/curve/editcurve.c @@ -5017,7 +5017,7 @@ static int add_vertex_invoke(bContext *C, wmOperator *op, const wmEvent *event) const float mval[2] = {UNPACK2(event->mval)}; struct SnapObjectContext *snap_context = ED_transform_snap_object_context_create_view3d( - CTX_data_main(C), vc.scene, vc.scene_layer, 0, + CTX_data_main(C), vc.scene, vc.scene_layer, vc.engine, 0, vc.ar, vc.v3d); ED_transform_snap_object_project_view3d_mixed( diff --git a/source/blender/editors/include/ED_screen.h b/source/blender/editors/include/ED_screen.h index f650ae879a5..e7a8583c50a 100644 --- a/source/blender/editors/include/ED_screen.h +++ b/source/blender/editors/include/ED_screen.h @@ -35,6 +35,7 @@ #include "DNA_space_types.h" #include "DNA_view2d_types.h" #include "DNA_view3d_types.h" +#include "DNA_workspace_types.h" #include "BLI_compiler_attrs.h" @@ -92,7 +93,8 @@ int ED_area_header_switchbutton(const struct bContext *C, struct uiBlock *bl void ED_area_initialize(struct wmWindowManager *wm, struct wmWindow *win, struct ScrArea *sa); void ED_area_exit(struct bContext *C, struct ScrArea *sa); int ED_screen_area_active(const struct bContext *C); -void ED_area_do_listen(struct bScreen *sc, ScrArea *sa, struct wmNotifier *note, const Scene *scene); +void ED_area_do_listen(struct bScreen *sc, ScrArea *sa, struct wmNotifier *note, const Scene *scene, + const struct WorkSpace *workspace); void ED_area_tag_redraw(ScrArea *sa); void ED_area_tag_redraw_regiontype(ScrArea *sa, int type); void ED_area_tag_refresh(ScrArea *sa); @@ -129,7 +131,8 @@ 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, - SceneLayer *act_render_layer) ATTR_NONNULL(); + SceneLayer *act_render_layer, + struct ViewRender *view_render) ATTR_NONNULL(); bool ED_workspace_change( struct WorkSpace *workspace_new, struct bContext *C, diff --git a/source/blender/editors/include/ED_transform_snap_object_context.h b/source/blender/editors/include/ED_transform_snap_object_context.h index b802694444b..babed92230c 100644 --- a/source/blender/editors/include/ED_transform_snap_object_context.h +++ b/source/blender/editors/include/ED_transform_snap_object_context.h @@ -30,6 +30,7 @@ struct BMEdge; struct BMFace; struct ListBase; +struct RenderEngineType; struct Scene; struct SceneLayer; struct Main; @@ -75,9 +76,9 @@ struct SnapObjectParams { typedef struct SnapObjectContext SnapObjectContext; SnapObjectContext *ED_transform_snap_object_context_create( - struct Main *bmain, struct Scene *scene, struct SceneLayer *sl, int flag); + struct Main *bmain, struct Scene *scene, struct SceneLayer *sl, struct RenderEngineType *engine, int flag); SnapObjectContext *ED_transform_snap_object_context_create_view3d( - struct Main *bmain, struct Scene *scene, struct SceneLayer *sl, int flag, + struct Main *bmain, struct Scene *scene, struct SceneLayer *sl, struct RenderEngineType *engine, int flag, /* extra args for view3d */ const struct ARegion *ar, const struct View3D *v3d); void ED_transform_snap_object_context_destroy(SnapObjectContext *sctx); diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h index 0dcfd68c0f1..b55703bff0e 100644 --- a/source/blender/editors/include/ED_view3d.h +++ b/source/blender/editors/include/ED_view3d.h @@ -51,6 +51,7 @@ struct Nurb; struct Object; struct RV3DMatrixStore; struct RegionView3D; +struct RenderEngineType; struct Scene; struct SceneLayer; struct ScrArea; @@ -68,6 +69,7 @@ struct wmWindowManager; struct GPUFX; struct GPUOffScreen; struct GPUFXSettings; +struct WorkSpace; enum eGPUFXFlags; /* for derivedmesh drawing callbacks, for view3d_select, .... */ @@ -75,6 +77,7 @@ typedef struct ViewContext { struct Depsgraph *depsgraph; struct Scene *scene; struct SceneLayer *scene_layer; + struct RenderEngineType *engine; struct Object *obact; struct Object *obedit; struct ARegion *ar; @@ -369,9 +372,11 @@ void ED_draw_object_facemap(const struct EvaluationContext *eval_ctx, struct Sc bool ED_view3d_context_activate(struct bContext *C); void ED_view3d_draw_offscreen_init( - const struct EvaluationContext *eval_ctx, struct Scene *scene, struct SceneLayer *sl, struct View3D *v3d); + const struct EvaluationContext *eval_ctx, struct Scene *scene, + struct SceneLayer *sl, struct View3D *v3d); void ED_view3d_draw_offscreen( - const struct EvaluationContext *eval_ctx, struct Scene *scene, struct SceneLayer *sl, struct View3D *v3d, struct ARegion *ar, int winx, int winy, float viewmat[4][4], + const struct EvaluationContext *eval_ctx, struct Scene *scene, + struct SceneLayer *scene_layer, struct View3D *v3d, struct ARegion *ar, int winx, int winy, float viewmat[4][4], float winmat[4][4], bool do_bgpic, bool do_sky, bool is_persp, const char *viewname, struct GPUFX *fx, struct GPUFXSettings *fx_settings, struct GPUOffScreen *ofs); @@ -380,12 +385,14 @@ void ED_view3d_draw_setup_view( float viewmat[4][4], float winmat[4][4], const struct rcti *rect); struct ImBuf *ED_view3d_draw_offscreen_imbuf( - const struct EvaluationContext *eval_ctx, struct Scene *scene, struct SceneLayer *sl, struct View3D *v3d, struct ARegion *ar, + const struct EvaluationContext *eval_ctx, struct Scene *scene, + struct SceneLayer *scene_layer, struct View3D *v3d, struct ARegion *ar, int sizex, int sizey, unsigned int flag, bool draw_background, int alpha_mode, int samples, bool full_samples, const char *viewname, struct GPUFX *fx, struct GPUOffScreen *ofs, char err_out[256]); struct ImBuf *ED_view3d_draw_offscreen_imbuf_simple( - const struct EvaluationContext *eval_ctx, struct Scene *scene, struct SceneLayer *sl, struct Object *camera, int width, int height, + const struct EvaluationContext *eval_ctx, struct Scene *scene, + struct SceneLayer *scene_layer, struct Object *camera, int width, int height, unsigned int flag, int drawtype, bool use_solid_tex, bool use_gpencil, bool draw_background, int alpha_mode, int samples, bool full_samples, const char *viewname, struct GPUFX *fx, struct GPUOffScreen *ofs, char err_out[256]); diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c index ebd4ce36bbe..f2ee8a11706 100644 --- a/source/blender/editors/interface/interface_templates.c +++ b/source/blender/editors/interface/interface_templates.c @@ -1193,7 +1193,7 @@ static uiLayout *draw_modifier( /* When Modifier is a simulation, show button to switch to context rather than the delete button. */ if (modifier_can_delete(md) && (!modifier_is_simulation(md) || - STREQ(scene->r.engine, RE_engine_id_BLENDER_GAME))) + STREQ(scene->view_render.engine_id, RE_engine_id_BLENDER_GAME))) { uiItemO(row, "", ICON_X, "OBJECT_OT_modifier_remove"); } diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index 5749bedc463..b44b78c450b 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -309,7 +309,7 @@ void EMBM_project_snap_verts(bContext *C, ARegion *ar, BMEditMesh *em) ED_view3d_init_mats_rv3d(obedit, ar->regiondata); struct SnapObjectContext *snap_context = ED_transform_snap_object_context_create_view3d( - CTX_data_main(C), CTX_data_scene(C), CTX_data_scene_layer(C), 0, + CTX_data_main(C), CTX_data_scene(C), CTX_data_scene_layer(C), CTX_data_engine(C), 0, ar, CTX_wm_view3d(C)); BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) { diff --git a/source/blender/editors/physics/physics_pointcache.c b/source/blender/editors/physics/physics_pointcache.c index d4f949880ee..74946e3f44d 100644 --- a/source/blender/editors/physics/physics_pointcache.c +++ b/source/blender/editors/physics/physics_pointcache.c @@ -166,6 +166,7 @@ static PTCacheBaker *ptcache_baker_create(bContext *C, wmOperator *op, bool all) baker->main = CTX_data_main(C); baker->scene = CTX_data_scene(C); + baker->scene_layer = CTX_data_scene_layer(C); baker->bake = RNA_boolean_get(op->ptr, "bake"); baker->render = 0; baker->anim_init = 0; diff --git a/source/blender/editors/render/render_internal.c b/source/blender/editors/render/render_internal.c index ababd637e00..8a51d42c598 100644 --- a/source/blender/editors/render/render_internal.c +++ b/source/blender/editors/render/render_internal.c @@ -56,6 +56,7 @@ #include "BKE_colortools.h" #include "BKE_global.h" #include "BKE_image.h" +#include "BKE_layer.h" #include "BKE_library.h" #include "BKE_main.h" #include "BKE_node.h" @@ -64,6 +65,7 @@ #include "BKE_sequencer.h" #include "BKE_screen.h" #include "BKE_scene.h" +#include "BKE_workspace.h" #include "DEG_depsgraph.h" @@ -787,33 +789,46 @@ static void screen_render_cancel(bContext *C, wmOperator *op) WM_jobs_kill_type(wm, scene, WM_JOB_TYPE_RENDER); } +static void clean_viewport_memory_base(Base *base) +{ + if ((base->flag & BASE_VISIBLED) == 0) { + return; + } + + Object *object = base->object; + + if (object->id.tag & LIB_TAG_DOIT) { + return; + } + + object->id.tag &= ~LIB_TAG_DOIT; + if (RE_allow_render_generic_object(object)) { + BKE_object_free_derived_caches(object); + } +} + static void clean_viewport_memory(Main *bmain, Scene *scene) { - Object *object; Scene *sce_iter; Base *base; - for (object = bmain->object.first; object; object = object->id.next) { - object->id.tag |= LIB_TAG_DOIT; - } + /* Tag all the available objects. */ + BKE_main_id_tag_listbase(&bmain->object, LIB_TAG_DOIT, true); - for (SETLOOPER(scene, sce_iter, base)) { - if ((base->flag & BASE_VISIBLED) == 0) { - continue; - } - if (RE_allow_render_generic_object(base->object)) { - base->object->id.tag &= ~LIB_TAG_DOIT; - } - } + /* 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); + SceneLayer *scene_layer = BKE_scene_layer_from_workspace_get(scene, workspace); - for (SETLOOPER(scene, sce_iter, base)) { - object = base->object; - if ((object->id.tag & LIB_TAG_DOIT) == 0) { - continue; + for (base = scene_layer->object_bases.first; base; base = base->next) { + clean_viewport_memory_base(base); + } } - object->id.tag &= ~LIB_TAG_DOIT; + } - BKE_object_free_derived_caches(object); + for (SETLOOPER_SET_ONLY(scene, sce_iter, base)) { + clean_viewport_memory_base(base); } } @@ -1256,10 +1271,10 @@ static void render_view3d_startjob(void *customdata, short *stop, short *do_upda /* initalize always */ if (use_border) { rdata.mode |= R_BORDER; - RE_InitState(re, NULL, &rdata, NULL, rp->ar->winx, rp->ar->winy, &cliprct); + RE_InitState(re, NULL, &rdata, &rp->scene->view_render, NULL, rp->ar->winx, rp->ar->winy, &cliprct); } else - RE_InitState(re, NULL, &rdata, NULL, rp->ar->winx, rp->ar->winy, NULL); + RE_InitState(re, NULL, &rdata, &rp->scene->view_render, NULL, rp->ar->winx, rp->ar->winy, NULL); } if (orth) diff --git a/source/blender/editors/render/render_opengl.c b/source/blender/editors/render/render_opengl.c index af932c27c5e..c17beded91e 100644 --- a/source/blender/editors/render/render_opengl.c +++ b/source/blender/editors/render/render_opengl.c @@ -94,6 +94,7 @@ typedef struct OGLRender { Main *bmain; Render *re; Scene *scene; + WorkSpace *workspace; SceneLayer *scene_layer; View3D *v3d; @@ -267,7 +268,7 @@ static void screen_opengl_views_setup(OGLRender *oglrender) static void screen_opengl_render_doit(const bContext *C, OGLRender *oglrender, RenderResult *rr) { Scene *scene = oglrender->scene; - SceneLayer *sl = oglrender->scene_layer; + SceneLayer *scene_layer = oglrender->scene_layer; ARegion *ar = oglrender->ar; View3D *v3d = oglrender->v3d; RegionView3D *rv3d = oglrender->rv3d; @@ -352,7 +353,7 @@ static void screen_opengl_render_doit(const bContext *C, OGLRender *oglrender, R if (view_context) { ibuf_view = ED_view3d_draw_offscreen_imbuf( - &eval_ctx, scene, sl, v3d, ar, sizex, sizey, + &eval_ctx, scene, scene_layer, v3d, ar, sizex, sizey, IB_rect, draw_bgpic, alpha_mode, oglrender->ofs_samples, oglrender->ofs_full_samples, viewname, oglrender->fx, oglrender->ofs, err_out); @@ -364,7 +365,7 @@ static void screen_opengl_render_doit(const bContext *C, OGLRender *oglrender, R } else { ibuf_view = ED_view3d_draw_offscreen_imbuf_simple( - &eval_ctx, scene, sl, scene->camera, oglrender->sizex, oglrender->sizey, + &eval_ctx, scene, scene_layer, scene->camera, oglrender->sizex, oglrender->sizey, IB_rect, OB_SOLID, false, true, true, alpha_mode, oglrender->ofs_samples, oglrender->ofs_full_samples, viewname, oglrender->fx, oglrender->ofs, err_out); @@ -591,6 +592,7 @@ static bool screen_opengl_render_init(bContext *C, wmOperator *op) /* new render clears all callbacks */ wmWindowManager *wm = CTX_wm_manager(C); wmWindow *win = CTX_wm_window(C); + WorkSpace *workspace = CTX_wm_workspace(C); Scene *scene = CTX_data_scene(C); ScrArea *prevsa = CTX_wm_area(C); @@ -662,6 +664,7 @@ static bool screen_opengl_render_init(bContext *C, wmOperator *op) oglrender->sizey = sizey; oglrender->bmain = CTX_data_main(C); oglrender->scene = scene; + oglrender->workspace = workspace; oglrender->scene_layer = CTX_data_scene_layer(C); oglrender->cfrao = scene->r.cfra; @@ -698,6 +701,8 @@ static bool screen_opengl_render_init(bContext *C, wmOperator *op) /* create render */ oglrender->re = RE_NewSceneRender(scene); + ViewRender *view_render = BKE_viewrender_get(scene, workspace); + RE_SetEngineByID(oglrender->re, view_render->engine_id); /* create image and image user */ oglrender->ima = BKE_image_verify_viewer(IMA_TYPE_R_RESULT, "Render Result"); @@ -708,7 +713,7 @@ static bool screen_opengl_render_init(bContext *C, wmOperator *op) oglrender->iuser.ok = 1; /* create render result */ - RE_InitState(oglrender->re, NULL, &scene->r, NULL, sizex, sizey, NULL); + RE_InitState(oglrender->re, NULL, &scene->r, view_render, NULL, sizex, sizey, NULL); /* create render views */ screen_opengl_views_setup(oglrender); diff --git a/source/blender/editors/render/render_preview.c b/source/blender/editors/render/render_preview.c index 3f817672c00..958f1585e84 100644 --- a/source/blender/editors/render/render_preview.c +++ b/source/blender/editors/render/render_preview.c @@ -173,6 +173,7 @@ typedef struct ShaderPreview { Main *bmain; Main *pr_main; + ViewRender *view_render; } ShaderPreview; typedef struct IconPreviewSize { @@ -187,6 +188,7 @@ typedef struct IconPreview { void *owner; ID *id; ListBase sizes; + ViewRender *view_render; } IconPreview; /* *************************** Preview for buttons *********************** */ @@ -229,7 +231,7 @@ void ED_preview_ensure_dbase(void) static bool check_engine_supports_textures(Scene *scene) { - RenderEngineType *type = RE_engines_find(scene->r.engine); + RenderEngineType *type = RE_engines_find(scene->view_render.engine_id); return type->flag & RE_USE_TEXTURE_PREVIEW; } @@ -383,10 +385,10 @@ static Scene *preview_prepare_scene(Main *bmain, Scene *scene, ID *id, int id_ty * seems commonly used render engines does not support * such kind of rendering. */ - BLI_strncpy(sce->r.engine, RE_engine_id_BLENDER_RENDER, sizeof(sce->r.engine)); + BLI_strncpy(sce->view_render.engine_id, RE_engine_id_BLENDER_RENDER, sizeof(sce->view_render.engine_id)); } else { - BLI_strncpy(sce->r.engine, scene->r.engine, sizeof(sce->r.engine)); + BLI_strncpy(sce->view_render.engine_id, scene->view_render.engine_id, sizeof(sce->view_render.engine_id)); } if (id_type == ID_MA) { @@ -857,7 +859,7 @@ static void shader_preview_render(ShaderPreview *sp, ID *id, int split, int firs ((Camera *)sce->camera->data)->lens *= (float)sp->sizey / (float)sizex; /* entire cycle for render engine */ - RE_PreviewRender(re, pr_main, sce); + RE_PreviewRender(re, pr_main, sce, sp->view_render); ((Camera *)sce->camera->data)->lens = oldlens; @@ -1184,6 +1186,7 @@ static void icon_preview_startjob_all_sizes(void *customdata, short *stop, short /* construct shader preview from image size and previewcustomdata */ sp->scene = ip->scene; + sp->view_render = ip->view_render; sp->owner = ip->owner; sp->sizex = cur_size->sizex; sp->sizey = cur_size->sizey; @@ -1268,6 +1271,7 @@ void ED_preview_icon_render(Main *bmain, Scene *scene, ID *id, unsigned int *rec ip.bmain = bmain; ip.scene = scene; + ip.view_render = &scene->view_render; ip.owner = BKE_previewimg_id_ensure(id); ip.id = id; @@ -1301,6 +1305,7 @@ void ED_preview_icon_job(const bContext *C, void *owner, ID *id, unsigned int *r /* customdata for preview thread */ ip->bmain = CTX_data_main(C); ip->scene = CTX_data_scene(C); + ip->view_render = &ip->scene->view_render; ip->owner = owner; ip->id = id; @@ -1328,8 +1333,12 @@ void ED_preview_shader_job(const bContext *C, void *owner, ID *id, ID *parent, M wmJob *wm_job; ShaderPreview *sp; Scene *scene = CTX_data_scene(C); + WorkSpace *workspace = CTX_wm_workspace(C); short id_type = GS(id->name); - bool use_new_shading = BKE_scene_use_new_shading_nodes(scene); + + /* Use workspace render only for buttons Window, since the other previews are related to the datablock. */ + ViewRender *view_render = (method == PR_BUTS_RENDER) ? BKE_viewrender_get(scene, workspace) : &scene->view_render; + bool use_new_shading = BKE_viewrender_use_new_shading_nodes(view_render); /* Only texture node preview is supported with Cycles. */ if (use_new_shading && method == PR_NODE_RENDER && id_type != ID_TE) { @@ -1352,6 +1361,7 @@ void ED_preview_shader_job(const bContext *C, void *owner, ID *id, ID *parent, M sp->parent = parent; sp->slot = slot; sp->bmain = CTX_data_main(C); + sp->view_render = view_render; /* hardcoded preview .blend for cycles/internal, this should be solved * once with custom preview .blend path for external engines */ diff --git a/source/blender/editors/render/render_update.c b/source/blender/editors/render/render_update.c index ccea1e5930c..f160b71f633 100644 --- a/source/blender/editors/render/render_update.c +++ b/source/blender/editors/render/render_update.c @@ -141,7 +141,7 @@ void ED_render_scene_update(Main *bmain, Scene *scene, int updated) engine->type->view_update(engine, C); } - else if ((RE_engines_find(scene->r.engine)->flag & RE_USE_LEGACY_PIPELINE) == 0) { + else if ((RE_engines_find(scene->view_render.engine_id)->flag & RE_USE_LEGACY_PIPELINE) == 0) { if (updated) { CTX_wm_screen_set(C, sc); CTX_wm_area_set(C, sa); diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c index 0c8ca2a5b87..852632ceddd 100644 --- a/source/blender/editors/screen/area.c +++ b/source/blender/editors/screen/area.c @@ -145,11 +145,11 @@ void ED_region_do_listen(bScreen *sc, ScrArea *sa, ARegion *ar, wmNotifier *note } /* only exported for WM */ -void ED_area_do_listen(bScreen *sc, ScrArea *sa, wmNotifier *note, const Scene *scene) +void ED_area_do_listen(bScreen *sc, ScrArea *sa, wmNotifier *note, const Scene *scene, const WorkSpace *workspace) { /* no generic notes? */ if (sa->type && sa->type->listener) { - sa->type->listener(sc, sa, note, scene); + sa->type->listener(sc, sa, note, scene, workspace); } } diff --git a/source/blender/editors/screen/screen_context.c b/source/blender/editors/screen/screen_context.c index 5813f317295..b8575b2da2a 100644 --- a/source/blender/editors/screen/screen_context.c +++ b/source/blender/editors/screen/screen_context.c @@ -89,7 +89,7 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult ScrArea *sa = CTX_wm_area(C); Scene *scene = WM_window_get_active_scene(win); WorkSpace *workspace = BKE_workspace_active_get(win->workspace_hook); - SceneLayer *sl = BKE_scene_layer_from_workspace_get(workspace); + SceneLayer *sl = BKE_scene_layer_from_workspace_get(scene, workspace); Object *obedit = scene->obedit; Object *obact = sl->basact ? sl->basact->object : NULL; diff --git a/source/blender/editors/screen/workspace_edit.c b/source/blender/editors/screen/workspace_edit.c index 00a965beae7..1c5b11c7177 100644 --- a/source/blender/editors/screen/workspace_edit.c +++ b/source/blender/editors/screen/workspace_edit.c @@ -38,6 +38,7 @@ #include "BKE_main.h" #include "BKE_library.h" #include "BKE_report.h" +#include "BKE_scene.h" #include "BKE_screen.h" #include "BKE_workspace.h" @@ -51,6 +52,8 @@ #include "ED_object.h" #include "ED_screen.h" +#include "MEM_guardedalloc.h" + #include "RNA_access.h" #include "UI_interface.h" @@ -68,7 +71,7 @@ * \{ */ WorkSpace *ED_workspace_add( - Main *bmain, const char *name, SceneLayer *act_render_layer) + Main *bmain, const char *name, SceneLayer *act_render_layer, ViewRender *view_render) { WorkSpace *workspace = BKE_workspace_add(bmain, name); @@ -77,6 +80,7 @@ WorkSpace *ED_workspace_add( #endif BKE_workspace_render_layer_set(workspace, act_render_layer); + BKE_viewrender_copy(&workspace->view_render, view_render); return workspace; } @@ -215,7 +219,8 @@ WorkSpace *ED_workspace_duplicate( ListBase *layouts_old = BKE_workspace_layouts_get(workspace_old); WorkSpace *workspace_new = ED_workspace_add( bmain, workspace_old->id.name + 2, - BKE_workspace_render_layer_get(workspace_old)); + BKE_workspace_render_layer_get(workspace_old), + &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); @@ -231,7 +236,6 @@ WorkSpace *ED_workspace_duplicate( win->workspace_hook->temp_layout_store = layout_new; } } - return workspace_new; } diff --git a/source/blender/editors/sculpt_paint/paint_image_proj.c b/source/blender/editors/sculpt_paint/paint_image_proj.c index 2ffd9757f92..a8271287e10 100644 --- a/source/blender/editors/sculpt_paint/paint_image_proj.c +++ b/source/blender/editors/sculpt_paint/paint_image_proj.c @@ -5455,7 +5455,7 @@ static int texture_paint_image_from_view_exec(bContext *C, wmOperator *op) char filename[FILE_MAX]; Scene *scene = CTX_data_scene(C); - SceneLayer *sl = CTX_data_scene_layer(C); + SceneLayer *scene_layer = CTX_data_scene_layer(C); EvaluationContext eval_ctx; ToolSettings *settings = scene->toolsettings; int w = settings->imapaint.screen_grab_size[0]; @@ -5473,7 +5473,7 @@ static int texture_paint_image_from_view_exec(bContext *C, wmOperator *op) if (h > maxsize) h = maxsize; ibuf = ED_view3d_draw_offscreen_imbuf( - &eval_ctx, scene, sl, CTX_wm_view3d(C), CTX_wm_region(C), + &eval_ctx, scene, scene_layer, CTX_wm_view3d(C), CTX_wm_region(C), w, h, IB_rect, false, R_ALPHAPREMUL, 0, false, NULL, NULL, NULL, err_out); if (!ibuf) { diff --git a/source/blender/editors/space_action/space_action.c b/source/blender/editors/space_action/space_action.c index f4affb90cc3..50882571dad 100644 --- a/source/blender/editors/space_action/space_action.c +++ b/source/blender/editors/space_action/space_action.c @@ -409,7 +409,8 @@ static void action_main_region_listener( /* editor level listener */ static void action_listener( - bScreen *UNUSED(sc), ScrArea *sa, wmNotifier *wmn, const Scene *UNUSED(scene)) + bScreen *UNUSED(sc), ScrArea *sa, wmNotifier *wmn, Scene *UNUSED(scene), + WorkSpace *UNUSED(workspace)) { SpaceAction *saction = (SpaceAction *)sa->spacedata.first; diff --git a/source/blender/editors/space_buttons/buttons_context.c b/source/blender/editors/space_buttons/buttons_context.c index f6c15f4d030..8aa4e674d11 100644 --- a/source/blender/editors/space_buttons/buttons_context.c +++ b/source/blender/editors/space_buttons/buttons_context.c @@ -57,6 +57,7 @@ #include "BKE_screen.h" #include "BKE_texture.h" #include "BKE_linestyle.h" +#include "BKE_workspace.h" #include "RNA_access.h" @@ -168,29 +169,53 @@ static int buttons_context_path_linestyle(ButsContextPath *path) return 0; } +static int buttons_context_path_workspace(ButsContextPath *path) +{ + PointerRNA *ptr = &path->ptr[path->len - 1]; + + /* This one just verifies. */ + return RNA_struct_is_a(ptr->type, &RNA_WorkSpace); +} + +static int buttons_context_path_collection(ButsContextPath *path) +{ + PointerRNA *ptr = &path->ptr[path->len - 1]; + + /* if we already have a (pinned) Collection, we're done */ + if (RNA_struct_is_a(ptr->type, &RNA_LayerCollection)) { + return 1; + } + + SceneLayer *sl = ptr->data; + LayerCollection *sc = BKE_layer_collection_get_active(sl); + + if (sc) { + RNA_pointer_create(NULL, &RNA_LayerCollection, sc, &path->ptr[path->len]); + path->len++; + return 1; + } + + /* no path to a collection possible */ + return 0; +} + static int buttons_context_path_object(ButsContextPath *path) { - Scene *scene; - Object *ob; PointerRNA *ptr = &path->ptr[path->len - 1]; /* if we already have a (pinned) object, we're done */ if (RNA_struct_is_a(ptr->type, &RNA_Object)) { return 1; } - /* if we have a scene, use the scene's active object */ - else if (buttons_context_path_scene(path)) { - scene = path->ptr[path->len - 1].data; - SceneLayer *sl = BKE_scene_layer_context_active_PLACEHOLDER(scene); - ob = (sl->basact) ? sl->basact->object : NULL; + SceneLayer *sl = ptr->data; + Object *ob = (sl->basact) ? sl->basact->object : NULL; - if (ob) { - RNA_id_pointer_create(&ob->id, &path->ptr[path->len]); - path->len++; + if (ob) { + RNA_id_pointer_create(&ob->id, &path->ptr[path->len]); + path->len++; - return 1; - } + return 1; } /* no path to a object possible */ @@ -559,39 +584,11 @@ static bool buttons_context_linestyle_pinnable(const bContext *C) } #endif -static int buttons_context_path_collection(const bContext *C, ButsContextPath *path) -{ - PointerRNA *ptr = &path->ptr[path->len - 1]; - - /* if we already have a (pinned) Collection, we're done */ - if (RNA_struct_is_a(ptr->type, &RNA_LayerCollection)) { - return 1; - } - - SceneLayer *sl = CTX_data_scene_layer(C); - LayerCollection *sc = BKE_layer_collection_get_active(sl); - - if (sc) { - RNA_pointer_create(NULL, &RNA_LayerCollection, sc, &path->ptr[path->len]); - path->len++; - - /* temporary object in context path to get edit mode */ - Object *ob = CTX_data_active_object(C); - if (ob) { - RNA_id_pointer_create(&ob->id, &path->ptr[path->len]); - path->len++; - } - - return 1; - } - - /* no path to a collection possible */ - return 0; -} - static int buttons_context_path(const bContext *C, ButsContextPath *path, int mainb, int flag) { SpaceButs *sbuts = CTX_wm_space_buts(C); + Scene *scene = CTX_data_scene(C); + WorkSpace *workspace = CTX_wm_workspace(C); ID *id; int found; @@ -599,18 +596,32 @@ static int buttons_context_path(const bContext *C, ButsContextPath *path, int ma path->flag = flag; path->tex_ctx = sbuts->texture_context; - /* if some ID datablock is pinned, set the root pointer */ + const bool use_scene_settings = BKE_workspace_use_scene_settings_get(workspace); + + /* If some ID datablock is pinned, set the root pointer. */ if (sbuts->pinid) { id = sbuts->pinid; RNA_id_pointer_create(id, &path->ptr[0]); path->len++; } + /* No pinned root, use scene or workspace as initial root. */ + else { + if ((mainb != BCONTEXT_WORKSPACE) && (use_scene_settings || + ELEM(mainb, BCONTEXT_SCENE, BCONTEXT_RENDER, BCONTEXT_RENDER_LAYER, BCONTEXT_WORLD))) + { + RNA_id_pointer_create(&scene->id, &path->ptr[0]); + path->len++; + } + else { + RNA_id_pointer_create(&workspace->id, &path->ptr[0]); + path->len++; + } + } - /* no pinned root, use scene as root */ - if (path->len == 0) { - id = (ID *)CTX_data_scene(C); - RNA_id_pointer_create(id, &path->ptr[0]); + if (!ELEM(mainb, BCONTEXT_WORKSPACE, BCONTEXT_SCENE, BCONTEXT_RENDER, BCONTEXT_RENDER_LAYER, BCONTEXT_WORLD)) { + SceneLayer *scene_layer = BKE_scene_layer_from_workspace_get(scene, workspace); + RNA_pointer_create(NULL, &RNA_SceneLayer, scene_layer, &path->ptr[path->len]); path->len++; } @@ -635,6 +646,12 @@ static int buttons_context_path(const bContext *C, ButsContextPath *path, int ma case BCONTEXT_WORLD: found = buttons_context_path_world(path); break; + case BCONTEXT_WORKSPACE: + found = buttons_context_path_workspace(path); + break; + case BCONTEXT_COLLECTION: + found = buttons_context_path_collection(path); + break; case BCONTEXT_OBJECT: case BCONTEXT_PHYSICS: case BCONTEXT_CONSTRAINT: @@ -663,9 +680,6 @@ static int buttons_context_path(const bContext *C, ButsContextPath *path, int ma case BCONTEXT_BONE_CONSTRAINT: found = buttons_context_path_pose_bone(path); break; - case BCONTEXT_COLLECTION: - found = buttons_context_path_collection(C, path); - break; default: found = 0; break; @@ -783,7 +797,7 @@ const char *buttons_context_dir[] = { "texture", "texture_user", "texture_user_property", "bone", "edit_bone", "pose_bone", "particle_system", "particle_system_editable", "particle_settings", "cloth", "soft_body", "fluid", "smoke", "collision", "brush", "dynamic_paint", - "line_style", "collection", NULL + "line_style", "collection", "workspace", NULL }; int buttons_context(const bContext *C, const char *member, bContextDataResult *result) @@ -812,6 +826,10 @@ int buttons_context(const bContext *C, const char *member, bContextDataResult *r set_pointer_type(path, result, &RNA_World); return 1; } + else if (CTX_data_equals(member, "workspace")) { + /* Do not return one here if scene not found in path, in this case we want to get default context scene! */ + return set_pointer_type(path, result, &RNA_WorkSpace); + } else if (CTX_data_equals(member, "object")) { set_pointer_type(path, result, &RNA_Object); return 1; @@ -1168,10 +1186,14 @@ void buttons_context_draw(const bContext *C, uiLayout *layout) name = RNA_struct_name_get_alloc(ptr, namebuf, sizeof(namebuf), NULL); if (name) { - if (!ELEM(sbuts->mainb, BCONTEXT_RENDER, BCONTEXT_SCENE, BCONTEXT_RENDER_LAYER) && ptr->type == &RNA_Scene) + if ((!ELEM(sbuts->mainb, BCONTEXT_RENDER, BCONTEXT_SCENE, BCONTEXT_RENDER_LAYER) && ptr->type == &RNA_Scene) || + (!ELEM(sbuts->mainb, BCONTEXT_WORKSPACE) && ptr->type == &RNA_WorkSpace)) + { uiItemLDrag(row, ptr, "", icon); /* save some space */ - else + } + else { uiItemLDrag(row, ptr, name, icon); + } if (name != namebuf) MEM_freeN(name); diff --git a/source/blender/editors/space_buttons/space_buttons.c b/source/blender/editors/space_buttons/space_buttons.c index 299ab7171d6..c2b0b3cdcc0 100644 --- a/source/blender/editors/space_buttons/space_buttons.c +++ b/source/blender/editors/space_buttons/space_buttons.c @@ -151,6 +151,10 @@ static void buttons_main_region_draw(const bContext *C, ARegion *ar) ED_region_panels(C, ar, "render_layer", sbuts->mainb, vertical); else if (sbuts->mainb == BCONTEXT_WORLD) ED_region_panels(C, ar, "world", sbuts->mainb, vertical); + else if (sbuts->mainb == BCONTEXT_WORKSPACE) + ED_region_panels(C, ar, "workspace", sbuts->mainb, vertical); + else if (sbuts->mainb == BCONTEXT_COLLECTION) + ED_region_panels(C, ar, "collection", sbuts->mainb, vertical); else if (sbuts->mainb == BCONTEXT_OBJECT) ED_region_panels(C, ar, "object", sbuts->mainb, vertical); else if (sbuts->mainb == BCONTEXT_DATA) @@ -171,8 +175,6 @@ static void buttons_main_region_draw(const bContext *C, ARegion *ar) ED_region_panels(C, ar, "constraint", sbuts->mainb, vertical); else if (sbuts->mainb == BCONTEXT_BONE_CONSTRAINT) ED_region_panels(C, ar, "bone_constraint", sbuts->mainb, vertical); - else if (sbuts->mainb == BCONTEXT_COLLECTION) - ED_region_panels(C, ar, "collection", sbuts->mainb, vertical); sbuts->re_align = 0; sbuts->mainbo = sbuts->mainb; @@ -235,7 +237,8 @@ static void buttons_area_redraw(ScrArea *sa, short buttons) /* reused! */ static void buttons_area_listener( - bScreen *UNUSED(sc), ScrArea *sa, wmNotifier *wmn, const Scene *UNUSED(scene)) + bScreen *UNUSED(sc), ScrArea *sa, wmNotifier *wmn, const Scene *UNUSED(scene), + const WorkSpace *UNUSED(workspace)) { SpaceButs *sbuts = sa->spacedata.first; diff --git a/source/blender/editors/space_clip/space_clip.c b/source/blender/editors/space_clip/space_clip.c index f185eea6d32..478254fb165 100644 --- a/source/blender/editors/space_clip/space_clip.c +++ b/source/blender/editors/space_clip/space_clip.c @@ -330,7 +330,8 @@ static SpaceLink *clip_duplicate(SpaceLink *sl) return (SpaceLink *)scn; } -static void clip_listener(bScreen *UNUSED(sc), ScrArea *sa, wmNotifier *wmn, const Scene *UNUSED(scene)) +static void clip_listener(bScreen *UNUSED(sc), ScrArea *sa, wmNotifier *wmn, Scene *UNUSED(scene), + WorkSpace *UNUSED(workspace)) { /* context changes */ switch (wmn->category) { diff --git a/source/blender/editors/space_file/space_file.c b/source/blender/editors/space_file/space_file.c index 6e4815af032..780c2ec5a47 100644 --- a/source/blender/editors/space_file/space_file.c +++ b/source/blender/editors/space_file/space_file.c @@ -292,7 +292,8 @@ static void file_refresh(const bContext *C, ScrArea *sa) } } -static void file_listener(bScreen *UNUSED(sc), ScrArea *sa, wmNotifier *wmn, const Scene *UNUSED(scene)) +static void file_listener(bScreen *UNUSED(sc), ScrArea *sa, wmNotifier *wmn, Scene *UNUSED(scene), + WorkSpace *UNUSED(workspace)) { SpaceFile *sfile = (SpaceFile *)sa->spacedata.first; diff --git a/source/blender/editors/space_graph/space_graph.c b/source/blender/editors/space_graph/space_graph.c index d2358a494d5..4b89c8db9e6 100644 --- a/source/blender/editors/space_graph/space_graph.c +++ b/source/blender/editors/space_graph/space_graph.c @@ -475,7 +475,8 @@ static void graph_region_listener( } /* editor level listener */ -static void graph_listener(bScreen *UNUSED(sc), ScrArea *sa, wmNotifier *wmn, const Scene *UNUSED(scene)) +static void graph_listener(bScreen *UNUSED(sc), ScrArea *sa, wmNotifier *wmn, Scene *UNUSED(scene), + WorkSpace *UNUSED(workspace)) { SpaceIpo *sipo = (SpaceIpo *)sa->spacedata.first; diff --git a/source/blender/editors/space_image/space_image.c b/source/blender/editors/space_image/space_image.c index 514cb1ab97e..cd4bfb918b3 100644 --- a/source/blender/editors/space_image/space_image.c +++ b/source/blender/editors/space_image/space_image.c @@ -442,7 +442,8 @@ static void image_refresh(const bContext *C, ScrArea *sa) } } -static void image_listener(bScreen *UNUSED(sc), ScrArea *sa, wmNotifier *wmn, const Scene *scene) +static void image_listener(bScreen *UNUSED(sc), ScrArea *sa, wmNotifier *wmn, Scene *scene, + WorkSpace *workspace) { SpaceImage *sima = (SpaceImage *)sa->spacedata.first; @@ -536,7 +537,7 @@ static void image_listener(bScreen *UNUSED(sc), ScrArea *sa, wmNotifier *wmn, co case ND_TRANSFORM: case ND_MODIFIER: { - SceneLayer *sl = BKE_scene_layer_context_active_PLACEHOLDER(scene); + SceneLayer *sl = BKE_scene_layer_from_workspace_get(scene, workspace); Object *ob = OBACT_NEW(sl); if (ob && (ob == wmn->reference) && (ob->mode & OB_MODE_EDIT)) { if (sima->lock && (sima->flag & SI_DRAWSHADOW)) { diff --git a/source/blender/editors/space_nla/space_nla.c b/source/blender/editors/space_nla/space_nla.c index ab7a913ce62..f6068087f02 100644 --- a/source/blender/editors/space_nla/space_nla.c +++ b/source/blender/editors/space_nla/space_nla.c @@ -477,7 +477,8 @@ static void nla_channel_region_listener( } /* editor level listener */ -static void nla_listener(bScreen *UNUSED(sc), ScrArea *sa, wmNotifier *wmn, const Scene *UNUSED(scene)) +static void nla_listener(bScreen *UNUSED(sc), ScrArea *sa, wmNotifier *wmn, Scene *UNUSED(scene), + WorkSpace *UNUSED(workspace)) { /* context changes */ switch (wmn->category) { diff --git a/source/blender/editors/space_node/node_edit.c b/source/blender/editors/space_node/node_edit.c index 75955ea3ab1..2f269470b82 100644 --- a/source/blender/editors/space_node/node_edit.c +++ b/source/blender/editors/space_node/node_edit.c @@ -383,7 +383,7 @@ bool ED_node_is_texture(struct SpaceNode *snode) /* called from shading buttons or header */ void ED_node_shader_default(const bContext *C, ID *id) { - Scene *scene = CTX_data_scene(C); + ViewRender *view_render = CTX_data_view_render(C); bNode *in, *out; bNodeSocket *fromsock, *tosock, *sock; bNodeTree *ntree; @@ -398,11 +398,11 @@ void ED_node_shader_default(const bContext *C, ID *id) Material *ma = (Material *)id; ma->nodetree = ntree; - if (BKE_scene_uses_blender_eevee(scene)) { + if (BKE_viewrender_uses_blender_eevee(view_render)) { output_type = SH_NODE_OUTPUT_MATERIAL; shader_type = SH_NODE_BSDF_PRINCIPLED; } - else if (BKE_scene_use_new_shading_nodes(scene)) { + else if (BKE_viewrender_use_new_shading_nodes(view_render)) { output_type = SH_NODE_OUTPUT_MATERIAL; shader_type = SH_NODE_BSDF_DIFFUSE; } @@ -460,7 +460,7 @@ void ED_node_shader_default(const bContext *C, ID *id) nodeAddLink(ntree, in, fromsock, out, tosock); /* default values */ - if (BKE_scene_use_new_shading_nodes(scene)) { + if (BKE_viewrender_use_new_shading_nodes(view_render)) { PointerRNA sockptr; sock = in->inputs.first; RNA_pointer_create((ID *)ntree, &RNA_NodeSocket, sock, &sockptr); @@ -2353,7 +2353,7 @@ void NODE_OT_tree_socket_move(wmOperatorType *ot) static int node_shader_script_update_poll(bContext *C) { Scene *scene = CTX_data_scene(C); - RenderEngineType *type = RE_engines_find(scene->r.engine); + RenderEngineType *type = RE_engines_find(scene->view_render.engine_id); SpaceNode *snode = CTX_wm_space_node(C); bNode *node; Text *text; @@ -2423,7 +2423,7 @@ static int node_shader_script_update_exec(bContext *C, wmOperator *op) bool found = false; /* setup render engine */ - type = RE_engines_find(scene->r.engine); + type = RE_engines_find(scene->view_render.engine_id); engine = RE_engine_create(type); engine->reports = op->reports; diff --git a/source/blender/editors/space_node/node_templates.c b/source/blender/editors/space_node/node_templates.c index 5d0877a1eff..c791b9f6eae 100644 --- a/source/blender/editors/space_node/node_templates.c +++ b/source/blender/editors/space_node/node_templates.c @@ -559,6 +559,7 @@ static void ui_template_node_link_menu(bContext *C, uiLayout *layout, void *but_ { Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); + ViewRender *view_render = CTX_data_view_render(C); uiBlock *block = uiLayoutGetBlock(layout); uiBut *but = (uiBut *)but_p; uiLayout *split, *column; @@ -575,7 +576,7 @@ static void ui_template_node_link_menu(bContext *C, uiLayout *layout, void *but_ arg->layout = split; if (ntreetype && ntreetype->foreach_nodeclass) - ntreetype->foreach_nodeclass(scene, arg, node_menu_column_foreach_cb); + ntreetype->foreach_nodeclass(view_render, arg, node_menu_column_foreach_cb); column = uiLayoutColumn(split, false); UI_block_layout_set_current(block, column); diff --git a/source/blender/editors/space_node/space_node.c b/source/blender/editors/space_node/space_node.c index 7cb22dcc570..e1765e39f7a 100644 --- a/source/blender/editors/space_node/space_node.c +++ b/source/blender/editors/space_node/space_node.c @@ -382,12 +382,14 @@ static void node_init(struct wmWindowManager *UNUSED(wm), ScrArea *UNUSED(sa)) } -static void node_area_listener(bScreen *UNUSED(sc), ScrArea *sa, wmNotifier *wmn, const Scene *scene) +static void node_area_listener(bScreen *UNUSED(sc), ScrArea *sa, wmNotifier *wmn, Scene *scene, + WorkSpace *workspace) { /* note, ED_area_tag_refresh will re-execute compositor */ SpaceNode *snode = sa->spacedata.first; + ViewRender *view_render = BKE_viewrender_get(scene, workspace); /* shaderfrom is only used for new shading nodes, otherwise all shaders are from objects */ - short shader_type = BKE_scene_use_new_shading_nodes(scene) ? snode->shaderfrom : SNODE_SHADER_OBJECT; + short shader_type = BKE_viewrender_use_new_shading_nodes(view_render) ? snode->shaderfrom : SNODE_SHADER_OBJECT; /* preview renders */ switch (wmn->category) { diff --git a/source/blender/editors/space_outliner/outliner_tree.c b/source/blender/editors/space_outliner/outliner_tree.c index f3a5af4b164..5331c76a0dc 100644 --- a/source/blender/editors/space_outliner/outliner_tree.c +++ b/source/blender/editors/space_outliner/outliner_tree.c @@ -386,7 +386,7 @@ static void outliner_add_scene_contents(SpaceOops *soops, ListBase *lb, Scene *s outliner_add_element(soops, lb, sce->world, te, 0, 0); #ifdef WITH_FREESTYLE - if (STREQ(sce->r.engine, RE_engine_id_BLENDER_RENDER) && (sce->r.mode & R_EDGE_FRS)) + if (STREQ(sce->view_render->engine_id, RE_engine_id_BLENDER_RENDER) && (sce->r.mode & R_EDGE_FRS)) outliner_add_line_styles(soops, lb, sce, te); #endif } diff --git a/source/blender/editors/space_sequencer/space_sequencer.c b/source/blender/editors/space_sequencer/space_sequencer.c index 3b04e6c80cd..da16ac5acaa 100644 --- a/source/blender/editors/space_sequencer/space_sequencer.c +++ b/source/blender/editors/space_sequencer/space_sequencer.c @@ -338,7 +338,8 @@ static SpaceLink *sequencer_duplicate(SpaceLink *sl) } static void sequencer_listener( - bScreen *UNUSED(sc), ScrArea *sa, wmNotifier *wmn, const Scene *UNUSED(scene)) + bScreen *UNUSED(sc), ScrArea *sa, wmNotifier *wmn, Scene *UNUSED(scene), + WorkSpace *UNUSED(workspace)) { /* context changes */ switch (wmn->category) { diff --git a/source/blender/editors/space_text/space_text.c b/source/blender/editors/space_text/space_text.c index ed1ef080e0c..539fe1c53bd 100644 --- a/source/blender/editors/space_text/space_text.c +++ b/source/blender/editors/space_text/space_text.c @@ -125,7 +125,8 @@ static SpaceLink *text_duplicate(SpaceLink *sl) return (SpaceLink *)stextn; } -static void text_listener(bScreen *UNUSED(sc), ScrArea *sa, wmNotifier *wmn, const Scene *UNUSED(scene)) +static void text_listener(bScreen *UNUSED(sc), ScrArea *sa, wmNotifier *wmn, Scene *UNUSED(scene), + WorkSpace *UNUSED(workspace)) { SpaceText *st = sa->spacedata.first; diff --git a/source/blender/editors/space_time/space_time.c b/source/blender/editors/space_time/space_time.c index 7ecb5cb072d..8a5277d31da 100644 --- a/source/blender/editors/space_time/space_time.c +++ b/source/blender/editors/space_time/space_time.c @@ -468,7 +468,8 @@ static void time_draw_keyframes(const bContext *C, ARegion *ar) /* ---------------- */ /* editor level listener */ -static void time_listener(bScreen *UNUSED(sc), ScrArea *sa, wmNotifier *wmn, const Scene *UNUSED(scene)) +static void time_listener(bScreen *UNUSED(sc), ScrArea *sa, wmNotifier *wmn, const Scene *UNUSED(scene), + const WorkSpace *UNUSED(workspace)) { /* mainly for updating cache display */ diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c index 9654ff74f54..2267c12f100 100644 --- a/source/blender/editors/space_view3d/space_view3d.c +++ b/source/blender/editors/space_view3d/space_view3d.c @@ -1301,7 +1301,8 @@ static void view3d_props_region_listener( /* area (not region) level listener */ static void space_view3d_listener( - bScreen *UNUSED(sc), ScrArea *sa, struct wmNotifier *wmn, const Scene *UNUSED(scene)) + bScreen *UNUSED(sc), ScrArea *sa, struct wmNotifier *wmn, Scene *UNUSED(scene), + WorkSpace *UNUSED(workspace)) { View3D *v3d = sa->spacedata.first; diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index ed4d7861d6d..ec2dcc75bc0 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -1880,10 +1880,11 @@ static void view3d_draw_view(const bContext *C, ARegion *ar) void view3d_main_region_draw(const bContext *C, ARegion *ar) { Scene *scene = CTX_data_scene(C); + WorkSpace *workspace = CTX_wm_workspace(C); View3D *v3d = CTX_wm_view3d(C); RegionView3D *rv3d = ar->regiondata; - /* XXX: In the future we should get RE from Layers/Depsgraph */ - RenderEngineType *type = RE_engines_find(scene->r.engine); + ViewRender *view_render = BKE_viewrender_get(scene, workspace); + RenderEngineType *type = RE_engines_find(view_render->engine_id); /* Provisory Blender Internal drawing */ if (type->flag & RE_USE_LEGACY_PIPELINE) { @@ -1931,7 +1932,7 @@ static void view3d_stereo3d_setup_offscreen( void ED_view3d_draw_offscreen_init(const EvaluationContext *eval_ctx, Scene *scene, SceneLayer *sl, View3D *v3d) { - RenderEngineType *type = RE_engines_find(scene->r.engine); + RenderEngineType *type = eval_ctx->engine; if (type->flag & RE_USE_LEGACY_PIPELINE) { /* shadow buffers, before we setup matrices */ if (draw_glsl_material(scene, sl, NULL, v3d, v3d->drawtype)) { @@ -1959,7 +1960,8 @@ static void view3d_main_region_clear(Scene *scene, View3D *v3d, ARegion *ar) * stuff like shadow buffers */ void ED_view3d_draw_offscreen( - const EvaluationContext *eval_ctx, Scene *scene, SceneLayer *sl, View3D *v3d, ARegion *ar, int winx, int winy, + const EvaluationContext *eval_ctx, Scene *scene, SceneLayer *scene_layer, + View3D *v3d, ARegion *ar, int winx, int winy, float viewmat[4][4], float winmat[4][4], bool do_bgpic, bool do_sky, bool is_persp, const char *viewname, GPUFX *fx, GPUFXSettings *fx_settings, @@ -2013,7 +2015,7 @@ void ED_view3d_draw_offscreen( view3d_main_region_setup_view(eval_ctx, scene, v3d, ar, viewmat, winmat, NULL); /* main drawing call */ - RenderEngineType *type = RE_engines_find(scene->r.engine); + RenderEngineType *type = eval_ctx->engine; if (type->flag & RE_USE_LEGACY_PIPELINE) { /* framebuffer fx needed, we need to draw offscreen first */ @@ -2055,8 +2057,8 @@ void ED_view3d_draw_offscreen( } else { /* XXX, should take depsgraph as arg */ - Depsgraph *depsgraph = BKE_scene_get_depsgraph(scene, sl); - DRW_draw_render_loop_offscreen(depsgraph, ar, v3d, ofs); + Depsgraph *depsgraph = BKE_scene_get_depsgraph(scene, scene_layer); + DRW_draw_render_loop_offscreen(depsgraph, eval_ctx->engine, ar, v3d, ofs); } /* restore size */ @@ -2079,7 +2081,8 @@ void ED_view3d_draw_offscreen( * (avoids re-creating when doing multiple GL renders). */ ImBuf *ED_view3d_draw_offscreen_imbuf( - const EvaluationContext *eval_ctx, Scene *scene, SceneLayer *sl, View3D *v3d, ARegion *ar, int sizex, int sizey, + const EvaluationContext *eval_ctx, Scene *scene, SceneLayer *scene_layer, + View3D *v3d, ARegion *ar, int sizex, int sizey, unsigned int flag, bool draw_background, int alpha_mode, int samples, bool full_samples, const char *viewname, /* output vars */ @@ -2108,7 +2111,7 @@ ImBuf *ED_view3d_draw_offscreen_imbuf( } } - ED_view3d_draw_offscreen_init(eval_ctx, scene, sl, v3d); + ED_view3d_draw_offscreen_init(eval_ctx, scene, scene_layer, v3d); GPU_offscreen_bind(ofs, true); @@ -2150,7 +2153,7 @@ ImBuf *ED_view3d_draw_offscreen_imbuf( if ((samples && full_samples) == 0) { /* Single-pass render, common case */ ED_view3d_draw_offscreen( - eval_ctx, scene, sl, v3d, ar, sizex, sizey, NULL, winmat, + eval_ctx, scene, scene_layer, v3d, ar, sizex, sizey, NULL, winmat, draw_background, draw_sky, !is_ortho, viewname, fx, &fx_settings, ofs); @@ -2174,7 +2177,7 @@ ImBuf *ED_view3d_draw_offscreen_imbuf( /* first sample buffer, also initializes 'rv3d->persmat' */ ED_view3d_draw_offscreen( - eval_ctx, scene, sl, v3d, ar, sizex, sizey, NULL, winmat, + eval_ctx, scene, scene_layer, v3d, ar, sizex, sizey, NULL, winmat, draw_background, draw_sky, !is_ortho, viewname, fx, &fx_settings, ofs); GPU_offscreen_read_pixels(ofs, GL_UNSIGNED_BYTE, rect_temp); @@ -2193,7 +2196,7 @@ ImBuf *ED_view3d_draw_offscreen_imbuf( (jit_ofs[j][1] * 2.0f) / sizey); ED_view3d_draw_offscreen( - eval_ctx, scene, sl, v3d, ar, sizex, sizey, NULL, winmat_jitter, + eval_ctx, scene, scene_layer, v3d, ar, sizex, sizey, NULL, winmat_jitter, draw_background, draw_sky, !is_ortho, viewname, fx, &fx_settings, ofs); GPU_offscreen_read_pixels(ofs, GL_UNSIGNED_BYTE, rect_temp); @@ -2244,7 +2247,8 @@ ImBuf *ED_view3d_draw_offscreen_imbuf( * \note used by the sequencer */ ImBuf *ED_view3d_draw_offscreen_imbuf_simple( - const EvaluationContext *eval_ctx, Scene *scene, SceneLayer *sl, Object *camera, int width, int height, + const EvaluationContext *eval_ctx, Scene *scene, SceneLayer *scene_layer, + Object *camera, int width, int height, unsigned int flag, int drawtype, bool use_solid_tex, bool use_gpencil, bool draw_background, int alpha_mode, int samples, bool full_samples, const char *viewname, GPUFX *fx, GPUOffScreen *ofs, char err_out[256]) @@ -2298,7 +2302,7 @@ ImBuf *ED_view3d_draw_offscreen_imbuf_simple( invert_m4_m4(rv3d.persinv, rv3d.viewinv); return ED_view3d_draw_offscreen_imbuf( - eval_ctx, scene, sl, &v3d, &ar, width, height, flag, + eval_ctx, scene, scene_layer, &v3d, &ar, width, height, flag, draw_background, alpha_mode, samples, full_samples, viewname, fx, ofs, err_out); } diff --git a/source/blender/editors/space_view3d/view3d_draw_legacy.c b/source/blender/editors/space_view3d/view3d_draw_legacy.c index d24c8241855..3680470c734 100644 --- a/source/blender/editors/space_view3d/view3d_draw_legacy.c +++ b/source/blender/editors/space_view3d/view3d_draw_legacy.c @@ -1786,8 +1786,7 @@ void ED_scene_draw_fps(Scene *scene, const rcti *rect) static bool view3d_main_region_do_render_draw(const Scene *scene) { - RenderEngineType *type = RE_engines_find(scene->r.engine); - + RenderEngineType *type = RE_engines_find(scene->view_render.engine_id); return (type && type->view_update && type->render_to_view); } @@ -1849,8 +1848,7 @@ static bool view3d_main_region_draw_engine( /* create render engine */ if (!rv3d->render_engine) { RenderEngine *engine; - - type = RE_engines_find(scene->r.engine); + type = RE_engines_find(scene->view_render.engine_id); if (!(type->view_update && type->render_to_view)) return false; @@ -1979,7 +1977,7 @@ static void view3d_main_region_draw_objects(const bContext *C, Scene *scene, Sce rv3d->rflag &= ~RV3D_IS_GAME_ENGINE; #ifdef WITH_GAMEENGINE - if (STREQ(scene->r.engine, RE_engine_id_BLENDER_GAME)) { + if (STREQ(scene->view_render.engine_id, RE_engine_id_BLENDER_GAME)) { rv3d->rflag |= RV3D_IS_GAME_ENGINE; /* Make sure LoDs are up to date */ diff --git a/source/blender/editors/space_view3d/view3d_ruler.c b/source/blender/editors/space_view3d/view3d_ruler.c index 60e90121ad1..03f4f506c13 100644 --- a/source/blender/editors/space_view3d/view3d_ruler.c +++ b/source/blender/editors/space_view3d/view3d_ruler.c @@ -282,7 +282,7 @@ static void ruler_state_set(bContext *C, RulerInfo *ruler_info, int state) } else if (state == RULER_STATE_DRAG) { ruler_info->snap_context = ED_transform_snap_object_context_create_view3d( - CTX_data_main(C), CTX_data_scene(C), CTX_data_scene_layer(C), 0, + CTX_data_main(C), CTX_data_scene(C), CTX_data_scene_layer(C), CTX_data_engine(C), 0, ruler_info->ar, CTX_wm_view3d(C)); } else { diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c index f5d5ae3726f..9014a2c74e6 100644 --- a/source/blender/editors/space_view3d/view3d_select.c +++ b/source/blender/editors/space_view3d/view3d_select.c @@ -114,6 +114,7 @@ void view3d_set_viewcontext(bContext *C, ViewContext *vc) vc->depsgraph = CTX_data_depsgraph(C); vc->scene = CTX_data_scene(C); vc->scene_layer = CTX_data_scene_layer(C); + vc->engine = CTX_data_engine(C); vc->v3d = CTX_wm_view3d(C); vc->win = CTX_wm_window(C); vc->rv3d = CTX_wm_region_view3d(C); diff --git a/source/blender/editors/space_view3d/view3d_walk.c b/source/blender/editors/space_view3d/view3d_walk.c index 44b7fadd29f..2f7893b9b83 100644 --- a/source/blender/editors/space_view3d/view3d_walk.c +++ b/source/blender/editors/space_view3d/view3d_walk.c @@ -58,6 +58,8 @@ #include "GPU_immediate.h" +#include "RE_engine.h" + #include "view3d_intern.h" /* own include */ #ifdef WITH_INPUT_NDOF @@ -249,6 +251,7 @@ typedef struct WalkInfo { ARegion *ar; Scene *scene; SceneLayer *scene_layer; + RenderEngineType *engine; wmTimer *timer; /* needed for redraws */ @@ -512,6 +515,7 @@ static bool initWalkInfo(bContext *C, WalkInfo *walk, wmOperator *op) walk->ar = CTX_wm_region(C); walk->scene = CTX_data_scene(C); walk->scene_layer = CTX_data_scene_layer(C); + walk->engine = CTX_data_engine(C); #ifdef NDOF_WALK_DEBUG puts("\n-- walk begin --"); @@ -600,7 +604,7 @@ static bool initWalkInfo(bContext *C, WalkInfo *walk, wmOperator *op) walk->rv3d->rflag |= RV3D_NAVIGATING; walk->snap_context = ED_transform_snap_object_context_create_view3d( - CTX_data_main(C), walk->scene, walk->scene_layer, 0, + CTX_data_main(C), walk->scene, walk->scene_layer, walk->engine, 0, walk->ar, walk->v3d); walk->v3d_camera_control = ED_view3d_cameracontrol_acquire( diff --git a/source/blender/editors/transform/CMakeLists.txt b/source/blender/editors/transform/CMakeLists.txt index fda15545ead..f38f6c064b8 100644 --- a/source/blender/editors/transform/CMakeLists.txt +++ b/source/blender/editors/transform/CMakeLists.txt @@ -29,6 +29,7 @@ set(INC ../../ikplugin ../../makesdna ../../makesrna + ../../render/extern/include ../../windowmanager ../../depsgraph ../../../../intern/guardedalloc diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h index 92eb31aabe6..60ad61e3475 100644 --- a/source/blender/editors/transform/transform.h +++ b/source/blender/editors/transform/transform.h @@ -37,6 +37,8 @@ #include "ED_numinput.h" #include "ED_view3d.h" +#include "RE_engine.h" + #include "DNA_listBase.h" /* ************************** Types ***************************** */ @@ -60,6 +62,7 @@ struct wmTimer; struct ARegion; struct ReportList; struct EditBone; +struct RenderEngineType; struct SnapObjectContext; /* transinfo->redraw */ @@ -467,6 +470,7 @@ typedef struct TransInfo { struct ARegion *ar; struct Scene *scene; struct SceneLayer *scene_layer; + struct RenderEngineType *engine; struct ToolSettings *settings; struct wmTimer *animtimer; struct wmKeyMap *keymap; /* so we can do lookups for header text */ diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index 166a5805fa1..b04767724ea 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -2485,7 +2485,7 @@ static void createTransEditVerts(TransInfo *t) int *island_vert_map = NULL; DEG_evaluation_context_init_from_scene(&eval_ctx, - t->scene, t->scene_layer, + t->scene, t->scene_layer, t->engine, DAG_EVAL_VIEWPORT); /* Even for translation this is needed because of island-orientation, see: T51651. */ @@ -5557,7 +5557,7 @@ static void set_trans_object_base_flags(TransInfo *t) /* handle pending update events, otherwise they got copied below */ EvaluationContext eval_ctx; DEG_evaluation_context_init_from_scene(&eval_ctx, - t->scene, t->scene_layer, + t->scene, t->scene_layer, t->engine, DAG_EVAL_VIEWPORT); for (base = sl->object_bases.first; base; base = base->next) { if (base->object->recalc & OB_RECALC_ALL) { diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c index 2bed1dd28f2..5081b65c215 100644 --- a/source/blender/editors/transform/transform_generics.c +++ b/source/blender/editors/transform/transform_generics.c @@ -105,6 +105,8 @@ #include "WM_types.h" #include "WM_api.h" +#include "RE_engine.h" + #include "UI_resources.h" #include "UI_view2d.h" @@ -1122,10 +1124,12 @@ void initTransInfo(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve Object *obedit = CTX_data_edit_object(C); Object *ob = CTX_data_active_object(C); bGPdata *gpd = CTX_data_gpencil_data(C); + RenderEngineType *engine = CTX_data_engine(C); PropertyRNA *prop; t->scene = sce; t->scene_layer = sl; + t->engine = engine; t->sa = sa; t->ar = ar; t->obedit = obedit; diff --git a/source/blender/editors/transform/transform_snap.c b/source/blender/editors/transform/transform_snap.c index e3ea8a51c6d..2654887d45c 100644 --- a/source/blender/editors/transform/transform_snap.c +++ b/source/blender/editors/transform/transform_snap.c @@ -585,7 +585,7 @@ static void initSnappingMode(TransInfo *t) if (t->spacetype == SPACE_VIEW3D) { if (t->tsnap.object_context == NULL) { t->tsnap.object_context = ED_transform_snap_object_context_create_view3d( - G.main, t->scene, t->scene_layer, 0, + G.main, t->scene, t->scene_layer, t->engine, 0, t->ar, t->view); ED_transform_snap_object_context_set_editmesh_callbacks( diff --git a/source/blender/editors/transform/transform_snap_object.c b/source/blender/editors/transform/transform_snap_object.c index e72bfa40480..9d60cac48f0 100644 --- a/source/blender/editors/transform/transform_snap_object.c +++ b/source/blender/editors/transform/transform_snap_object.c @@ -2096,7 +2096,7 @@ static bool snapObjectsRay( * \{ */ SnapObjectContext *ED_transform_snap_object_context_create( - Main *bmain, Scene *scene, SceneLayer *sl, int flag) + Main *bmain, Scene *scene, SceneLayer *sl, RenderEngineType *engine, int flag) { SnapObjectContext *sctx = MEM_callocN(sizeof(*sctx), __func__); @@ -2105,7 +2105,7 @@ SnapObjectContext *ED_transform_snap_object_context_create( sctx->bmain = bmain; sctx->scene = scene; - DEG_evaluation_context_init_from_scene(&sctx->eval_ctx, scene, sl, DAG_EVAL_VIEWPORT); + DEG_evaluation_context_init_from_scene(&sctx->eval_ctx, scene, sl, engine, DAG_EVAL_VIEWPORT); sctx->cache.object_map = BLI_ghash_ptr_new(__func__); sctx->cache.mem_arena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, __func__); @@ -2114,11 +2114,11 @@ SnapObjectContext *ED_transform_snap_object_context_create( } SnapObjectContext *ED_transform_snap_object_context_create_view3d( - Main *bmain, Scene *scene, SceneLayer *sl, int flag, + Main *bmain, Scene *scene, SceneLayer *sl, RenderEngineType *engine, int flag, /* extra args for view3d */ const ARegion *ar, const View3D *v3d) { - SnapObjectContext *sctx = ED_transform_snap_object_context_create(bmain, scene, sl, flag); + SnapObjectContext *sctx = ED_transform_snap_object_context_create(bmain, scene, sl, engine, flag); sctx->use_v3d = true; sctx->v3d_data.ar = ar; diff --git a/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp b/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp index 322acd9966c..6ab855ac6af 100644 --- a/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp +++ b/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp @@ -115,8 +115,8 @@ BlenderStrokeRenderer::BlenderStrokeRenderer(Render *re, int render_count) : Str freestyle_scene->r.filtertype = old_scene->r.filtertype; freestyle_scene->r.gauss = old_scene->r.gauss; freestyle_scene->r.dither_intensity = old_scene->r.dither_intensity; - BLI_strncpy(freestyle_scene->r.engine, old_scene->r.engine, sizeof(freestyle_scene->r.engine)); - freestyle_scene->r.im_format.planes = R_IMF_PLANES_RGBA; + BKE_viewrender_copy(&freestyle_scene->view_render, &old_scene->view_render); + freestyle_scene->r.im_format.planes = R_IMF_PLANES_RGBA; freestyle_scene->r.im_format.imtype = R_IMF_IMTYPE_PNG; if (G.debug & G_DEBUG_FREESTYLE) { @@ -463,7 +463,7 @@ void BlenderStrokeRenderer::RenderStrokeRepBasic(StrokeRep *iStrokeRep) const BLI_ghash_insert(_nodetree_hash, nt, ma); } - if (STREQ(freestyle_scene->r.engine, RE_engine_id_CYCLES)) { + if (STREQ(freestyle_scene->view_render.engine_id, RE_engine_id_CYCLES)) { PointerRNA scene_ptr, freestyle_scene_ptr; RNA_pointer_create(NULL, &RNA_Scene, old_scene, &scene_ptr); RNA_pointer_create(NULL, &RNA_Scene, freestyle_scene, &freestyle_scene_ptr); diff --git a/source/blender/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c index ef37d6bd02a..55157246c19 100644 --- a/source/blender/gpu/intern/gpu_material.c +++ b/source/blender/gpu/intern/gpu_material.c @@ -50,6 +50,7 @@ #include "BKE_colortools.h" #include "BKE_global.h" #include "BKE_image.h" +#include "BKE_layer.h" #include "BKE_main.h" #include "BKE_node.h" #include "BKE_scene.h" diff --git a/source/blender/makesdna/DNA_layer_types.h b/source/blender/makesdna/DNA_layer_types.h index 7ef6e8c34dd..86931401aae 100644 --- a/source/blender/makesdna/DNA_layer_types.h +++ b/source/blender/makesdna/DNA_layer_types.h @@ -74,7 +74,6 @@ typedef struct LayerCollection { typedef struct SceneLayer { struct SceneLayer *next, *prev; char name[64]; /* MAX_NAME */ - char engine[32]; /* render engine */ short active_collection; short flag; short pad[2]; diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index d81a4625144..35d3f4470da 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -749,7 +749,7 @@ typedef struct RenderData { float unit_line_thickness; /* in pixels */ /* render engine */ - char engine[32]; + char engine[32] DNA_DEPRECATED; // XXX deprecated since 2.8 /* Cycles baking */ struct BakeData bake; @@ -773,6 +773,12 @@ typedef struct RenderData { } RenderData; /* *************************************************************** */ +/* Settings related to viewport drawing/render, only settings used by WorkSpace and Scene. */ +typedef struct ViewRender { + char engine_id[32]; +} ViewRender; + +/* *************************************************************** */ /* Render Conversion/Simplfication Settings */ /* control render convert and shading engine */ @@ -883,7 +889,6 @@ typedef struct GameData { /* Scene LoD */ short lodflag, pad2; int scehysteresis, pad5; - } GameData; #define STEREO_NOSTEREO 1 @@ -1699,6 +1704,8 @@ typedef struct Scene { IDProperty *layer_properties; /* settings to be override by workspaces */ int pad5[2]; + + ViewRender view_render; } Scene; /* **************** RENDERDATA ********************* */ diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h index 68cc5c2d79e..f172737e3bd 100644 --- a/source/blender/makesdna/DNA_space_types.h +++ b/source/blender/makesdna/DNA_space_types.h @@ -182,6 +182,7 @@ typedef enum eSpaceButtons_Context { BCONTEXT_BONE_CONSTRAINT = 12, BCONTEXT_RENDER_LAYER = 13, BCONTEXT_COLLECTION = 14, + BCONTEXT_WORKSPACE = 15, /* always as last... */ BCONTEXT_TOT diff --git a/source/blender/makesdna/DNA_workspace_types.h b/source/blender/makesdna/DNA_workspace_types.h index 3805e1c0a8a..f6d5f8805a8 100644 --- a/source/blender/makesdna/DNA_workspace_types.h +++ b/source/blender/makesdna/DNA_workspace_types.h @@ -29,6 +29,7 @@ #ifndef __DNA_WORKSPACE_TYPES_H__ #define __DNA_WORKSPACE_TYPES_H__ +#include "DNA_scene_types.h" /* Same logic as DNA_DEPRECATED_ALLOW, but throws 'deprecated' * warnings if DNA_PRIVATE_WORKSPACE_ALLOW is not defined */ @@ -77,9 +78,12 @@ typedef struct WorkSpace { ListBase transform_orientations DNA_PRIVATE_WORKSPACE; int object_mode DNA_PRIVATE_WORKSPACE; /* enum ObjectMode */ - int pad; + int flags DNA_PRIVATE_WORKSPACE; /* enum eWorkSpaceFlags */ struct SceneLayer *render_layer DNA_PRIVATE_WORKSPACE; + + char engine_id[32]; /* Render Engine. */ + struct ViewRender view_render; } WorkSpace; /* internal struct, but exported for read/write */ @@ -132,4 +136,8 @@ typedef struct WorkSpaceInstanceHook { struct WorkSpaceLayout *temp_layout_store; } WorkSpaceInstanceHook; +typedef enum eWorkSpaceFlags { + WORKSPACE_USE_SCENE_SETTINGS = (1 << 0), +} eWorkSpaceFlags; + #endif /* __DNA_WORKSPACE_TYPES_H__ */ diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h index 114b0c32c15..501a1cccca6 100644 --- a/source/blender/makesrna/RNA_access.h +++ b/source/blender/makesrna/RNA_access.h @@ -708,6 +708,7 @@ extern StructRNA RNA_WaveModifier; extern StructRNA RNA_VertexWeightEditModifier; extern StructRNA RNA_VertexWeightMixModifier; extern StructRNA RNA_VertexWeightProximityModifier; +extern StructRNA RNA_ViewRenderSettings; extern StructRNA RNA_Window; extern StructRNA RNA_WindowManager; extern StructRNA RNA_WipeSequence; diff --git a/source/blender/makesrna/intern/rna_context.c b/source/blender/makesrna/intern/rna_context.c index 5701150b1bf..7be3dd60d52 100644 --- a/source/blender/makesrna/intern/rna_context.c +++ b/source/blender/makesrna/intern/rna_context.c @@ -39,6 +39,8 @@ #ifdef RNA_RUNTIME +#include "RE_engine.h" + static PointerRNA rna_Context_manager_get(PointerRNA *ptr) { bContext *C = (bContext *)ptr->data; @@ -133,6 +135,26 @@ static PointerRNA rna_Context_scene_layer_get(PointerRNA *ptr) return rna_pointer_inherit_refine(ptr, &RNA_SceneLayer, CTX_data_scene_layer(C)); } +static PointerRNA rna_Context_view_render_get(PointerRNA *ptr) +{ + bContext *C = (bContext *)ptr->data; + return rna_pointer_inherit_refine(ptr, &RNA_ViewRenderSettings, CTX_data_view_render(C)); +} + +static void rna_Context_engine_get(PointerRNA *ptr, char *value) + { + bContext *C = (bContext *)ptr->data; + RenderEngineType *engine = CTX_data_engine(C); + strcpy(value, engine->idname); +} + +static int rna_Context_engine_length(PointerRNA *ptr) +{ + bContext *C = (bContext *)ptr->data; + RenderEngineType *engine = CTX_data_engine(C); + return strlen(engine->idname); +} + static PointerRNA rna_Context_scene_collection_get(PointerRNA *ptr) { bContext *C = (bContext *)ptr->data; @@ -263,6 +285,15 @@ void RNA_def_context(BlenderRNA *brna) RNA_def_property_struct_type(prop, "SceneLayer"); RNA_def_property_pointer_funcs(prop, "rna_Context_scene_layer_get", NULL, NULL, NULL); + prop = RNA_def_property(srna, "view_render", PROP_POINTER, PROP_NONE); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_struct_type(prop, "ViewRenderSettings"); + RNA_def_property_pointer_funcs(prop, "rna_Context_view_render_get", NULL, NULL, NULL); + + prop = RNA_def_property(srna, "engine", PROP_STRING, PROP_NONE); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_string_funcs(prop, "rna_Context_engine_get", "rna_Context_engine_length", NULL); + prop = RNA_def_property(srna, "scene_collection", PROP_POINTER, PROP_NONE); RNA_def_property_clear_flag(prop, PROP_EDITABLE); RNA_def_property_struct_type(prop, "SceneCollection"); diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index 29d68111bac..0f59451e17c 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -3027,7 +3027,7 @@ static void rna_ShaderNodeScript_update(Main *bmain, Scene *scene, PointerRNA *p { bNodeTree *ntree = (bNodeTree *)ptr->id.data; bNode *node = (bNode *)ptr->data; - RenderEngineType *engine_type = RE_engines_find(scene->r.engine); + RenderEngineType *engine_type = RE_engines_find(scene->view_render.engine_id); if (engine_type && engine_type->update_script_node) { /* auto update node */ diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index 685844149e1..3e1f8f06d92 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -454,6 +454,7 @@ EnumPropertyItem rna_enum_layer_collection_mode_settings_type_items[] = { #include "DNA_object_types.h" #include "DNA_mesh_types.h" #include "DNA_text_types.h" +#include "DNA_workspace_types.h" #include "RNA_access.h" @@ -1007,6 +1008,11 @@ static void rna_RenderSettings_stereoViews_begin(CollectionPropertyIterator *ite rna_iterator_listbase_begin(iter, &rd->views, rna_RenderSettings_stereoViews_skip); } +static char *rna_ViewRenderSettings_path(PointerRNA *UNUSED(ptr)) +{ + return BLI_sprintfN("viewport_render"); +} + static char *rna_RenderSettings_path(PointerRNA *UNUSED(ptr)) { return BLI_sprintfN("render"); @@ -1482,19 +1488,32 @@ static void rna_RenderView_remove( WM_main_add_notifier(NC_SCENE | ND_RENDER_OPTIONS, NULL); } -static void rna_RenderSettings_engine_set(PointerRNA *ptr, int value) +static void rna_RenderSettings_views_format_set(PointerRNA *ptr, int value) { RenderData *rd = (RenderData *)ptr->data; - RenderEngineType *type = BLI_findlink(&R_engines, value); - Scene *scene = (Scene *)ptr->id.data; - if (type) - BLI_strncpy_utf8(rd->engine, type->idname, sizeof(rd->engine)); + if (rd->views_format == SCE_VIEWS_FORMAT_MULTIVIEW && + value == SCE_VIEWS_FORMAT_STEREO_3D) + { + /* make sure the actview is visible */ + if (rd->actview > 1) rd->actview = 1; + } + + rd->views_format = value; +} + +static void rna_ViewRenderSettings_engine_set(PointerRNA *ptr, int value) +{ + ViewRender *view_render = (ViewRender *)ptr->data; + RenderEngineType *type = BLI_findlink(&R_engines, value); - DEG_id_tag_update(&scene->id, DEG_TAG_COPY_ON_WRITE); + if (type) { + BLI_strncpy_utf8(view_render->engine_id, type->idname, sizeof(view_render->engine_id)); + DEG_id_tag_update(ptr->id.data, DEG_TAG_COPY_ON_WRITE); + } } -static EnumPropertyItem *rna_RenderSettings_engine_itemf( +static EnumPropertyItem *rna_ViewRenderSettings_engine_itemf( bContext *UNUSED(C), PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), bool *r_free) { RenderEngineType *type; @@ -1515,20 +1534,20 @@ static EnumPropertyItem *rna_RenderSettings_engine_itemf( return item; } -static int rna_RenderSettings_engine_get(PointerRNA *ptr) +static int rna_ViewRenderSettings_engine_get(PointerRNA *ptr) { - RenderData *rd = (RenderData *)ptr->data; + ViewRender *view_render = (ViewRender *)ptr->data; RenderEngineType *type; int a = 0; for (type = R_engines.first; type; type = type->next, a++) - if (STREQ(type->idname, rd->engine)) + if (STREQ(type->idname, view_render->engine_id)) return a; return 0; } -static void rna_RenderSettings_engine_update(Main *bmain, Scene *UNUSED(unused), PointerRNA *UNUSED(ptr)) +static void rna_ViewRenderSettings_engine_update(Main *bmain, Scene *UNUSED(unused), PointerRNA *UNUSED(ptr)) { ED_render_engine_changed(bmain); } @@ -1624,44 +1643,30 @@ static char *rna_SceneRenderView_path(PointerRNA *ptr) return BLI_sprintfN("render.views[\"%s\"]", srv->name); } -static void rna_RenderSettings_views_format_set(PointerRNA *ptr, int value) -{ - RenderData *rd = (RenderData *)ptr->data; - - if (rd->views_format == SCE_VIEWS_FORMAT_MULTIVIEW && - value == SCE_VIEWS_FORMAT_STEREO_3D) - { - /* make sure the actview is visible */ - if (rd->actview > 1) rd->actview = 1; - } - - rd->views_format = value; -} - -static int rna_RenderSettings_multiple_engines_get(PointerRNA *UNUSED(ptr)) +static int rna_ViewRenderSettings_multiple_engines_get(PointerRNA *UNUSED(ptr)) { return (BLI_listbase_count(&R_engines) > 1); } -static int rna_RenderSettings_use_shading_nodes_get(PointerRNA *ptr) +static int rna_ViewRenderSettings_use_shading_nodes_get(PointerRNA *ptr) { - Scene *scene = (Scene *)ptr->id.data; - return BKE_scene_use_new_shading_nodes(scene); + ViewRender *view_render = (ViewRender *)ptr->data; + return BKE_viewrender_use_new_shading_nodes(view_render); } -static int rna_RenderSettings_use_spherical_stereo_get(PointerRNA *ptr) +static int rna_ViewRenderSettings_use_spherical_stereo_get(PointerRNA *ptr) { - Scene *scene = (Scene *)ptr->id.data; - return BKE_scene_use_spherical_stereo(scene); + ViewRender *view_render = (ViewRender *)ptr->data; + return BKE_viewrender_use_spherical_stereo(view_render); } -static int rna_RenderSettings_use_game_engine_get(PointerRNA *ptr) +static int rna_ViewRenderSettings_use_game_engine_get(PointerRNA *ptr) { - RenderData *rd = (RenderData *)ptr->data; + ViewRender *view_render = (ViewRender *)ptr->data; RenderEngineType *type; for (type = R_engines.first; type; type = type->next) - if (STREQ(type->idname, rd->engine)) + if (STREQ(type->idname, view_render->engine_id)) return (type->flag & RE_GAME) != 0; return 0; @@ -1771,26 +1776,32 @@ static void object_simplify_update(Object *ob) } } -static void rna_Scene_use_simplify_update(Main *bmain, Scene *scene, PointerRNA *ptr) +static void rna_Scene_use_simplify_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr) { Scene *sce = ptr->id.data; Scene *sce_iter; Base *base; - BKE_main_id_tag_listbase(&bmain->object, LIB_TAG_DOIT, true); - for (SETLOOPER(sce, sce_iter, base)) + FOREACH_SCENE_OBJECT(sce, ob) + { + object_simplify_update(ob); + } + FOREACH_SCENE_OBJECT_END + + for (SETLOOPER_SET_ONLY(sce, sce_iter, base)) { object_simplify_update(base->object); + } WM_main_add_notifier(NC_GEOM | ND_DATA, NULL); - DEG_id_tag_update(&scene->id, 0); + DEG_id_tag_update(&sce->id, 0); } -static void rna_Scene_simplify_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr) +static void rna_Scene_simplify_update(Main *bmain, Scene *scene, PointerRNA *ptr) { Scene *sce = ptr->id.data; if (sce->r.mode & R_SIMPLIFY) - rna_Scene_use_simplify_update(bmain, sce, ptr); + rna_Scene_use_simplify_update(bmain, scene, ptr); } static void rna_SceneRenderData_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr) @@ -2977,59 +2988,6 @@ static void rna_LayerObjects_selected_begin(CollectionPropertyIterator *iter, Po rna_iterator_listbase_begin(iter, &sl->object_bases, rna_SceneLayer_objects_selected_skip); } -static void rna_SceneLayer_engine_set(PointerRNA *ptr, int value) -{ - SceneLayer *sl = (SceneLayer *)ptr->data; - RenderEngineType *type = BLI_findlink(&R_engines, value); - - if (type) - BKE_scene_layer_engine_set(sl, type->idname); -} - -static EnumPropertyItem *rna_SceneLayer_engine_itemf( - bContext *UNUSED(C), PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), bool *r_free) -{ - RenderEngineType *type; - EnumPropertyItem *item = NULL; - EnumPropertyItem tmp = {0, "", 0, "", ""}; - int a = 0, totitem = 0; - - for (type = R_engines.first; type; type = type->next, a++) { - tmp.value = a; - tmp.identifier = type->idname; - tmp.name = type->name; - RNA_enum_item_add(&item, &totitem, &tmp); - } - - RNA_enum_item_end(&item, &totitem); - *r_free = true; - - return item; -} - -static int rna_SceneLayer_engine_get(PointerRNA *ptr) -{ - SceneLayer *sl = (SceneLayer *)ptr->data; - RenderEngineType *type; - int a = 0; - - for (type = R_engines.first; type; type = type->next, a++) - if (STREQ(type->idname, sl->engine)) - return a; - - return 0; -} - -static void rna_SceneLayer_engine_update(Main *bmain, Scene *UNUSED(unused), PointerRNA *UNUSED(ptr)) -{ - ED_render_engine_changed(bmain); -} - -static int rna_SceneLayer_multiple_engines_get(PointerRNA *UNUSED(ptr)) -{ - return (BLI_listbase_count(&R_engines) > 1); -} - static void rna_SceneLayer_update_tagged(SceneLayer *UNUSED(sl), bContext *C) { Depsgraph *graph = CTX_data_depsgraph(C); @@ -7067,11 +7025,6 @@ static void rna_def_scene_layer(BlenderRNA *brna) StructRNA *srna; PropertyRNA *prop; - static EnumPropertyItem engine_items[] = { - {0, "BLENDER_RENDER", 0, "Blender Render", "Use the Blender internal rendering engine for rendering"}, - {0, NULL, 0, NULL, NULL} - }; - srna = RNA_def_struct(brna, "SceneLayer", NULL); RNA_def_struct_ui_text(srna, "Render Layer", "Render layer"); RNA_def_struct_ui_icon(srna, ICON_RENDERLAYERS); @@ -7107,20 +7060,6 @@ static void rna_def_scene_layer(BlenderRNA *brna) RNA_def_property_struct_type(prop, "SceneLayerSettings"); RNA_def_property_ui_text(prop, "Layer Settings", "Override of engine specific render settings"); - /* engine */ - prop = RNA_def_property(srna, "engine", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_items(prop, engine_items); - RNA_def_property_enum_funcs(prop, "rna_SceneLayer_engine_get", "rna_SceneLayer_engine_set", - "rna_SceneLayer_engine_itemf"); - RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_ui_text(prop, "Engine", "Engine to use for rendering"); - RNA_def_property_update(prop, NC_WINDOW, "rna_SceneLayer_engine_update"); - - prop = RNA_def_property(srna, "has_multiple_engines", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_funcs(prop, "rna_SceneLayer_multiple_engines_get", NULL); - RNA_def_property_clear_flag(prop, PROP_EDITABLE); - RNA_def_property_ui_text(prop, "Multiple Engines", "More than one rendering engine is available"); - /* debug update routine */ func = RNA_def_function(srna, "update", "rna_SceneLayer_update_tagged"); RNA_def_function_flag(func, FUNC_USE_CONTEXT); @@ -7937,11 +7876,6 @@ static void rna_def_scene_render_data(BlenderRNA *brna) {0, NULL, 0, NULL, NULL} }; - static EnumPropertyItem engine_items[] = { - {0, "BLENDER_RENDER", 0, "Blender Render", "Use the Blender internal rendering engine for rendering"}, - {0, NULL, 0, NULL, NULL} - }; - static EnumPropertyItem freestyle_thickness_items[] = { {R_LINE_THICKNESS_ABSOLUTE, "ABSOLUTE", 0, "Absolute", "Specify unit line thickness in pixels"}, {R_LINE_THICKNESS_RELATIVE, "RELATIVE", 0, "Relative", @@ -8678,35 +8612,6 @@ static void rna_def_scene_render_data(BlenderRNA *brna) RNA_def_property_enum_funcs(prop, NULL, "rna_RenderSettings_views_format_set", NULL); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); - /* engine */ - prop = RNA_def_property(srna, "engine", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_items(prop, engine_items); - RNA_def_property_enum_funcs(prop, "rna_RenderSettings_engine_get", "rna_RenderSettings_engine_set", - "rna_RenderSettings_engine_itemf"); - RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_ui_text(prop, "Engine", "Engine to use for rendering"); - RNA_def_property_update(prop, NC_WINDOW, "rna_RenderSettings_engine_update"); - - prop = RNA_def_property(srna, "has_multiple_engines", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_funcs(prop, "rna_RenderSettings_multiple_engines_get", NULL); - RNA_def_property_clear_flag(prop, PROP_EDITABLE); - RNA_def_property_ui_text(prop, "Multiple Engines", "More than one rendering engine is available"); - - prop = RNA_def_property(srna, "use_shading_nodes", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_funcs(prop, "rna_RenderSettings_use_shading_nodes_get", NULL); - RNA_def_property_clear_flag(prop, PROP_EDITABLE); - RNA_def_property_ui_text(prop, "Use Shading Nodes", "Active render engine uses new shading nodes system"); - - prop = RNA_def_property(srna, "use_spherical_stereo", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_funcs(prop, "rna_RenderSettings_use_spherical_stereo_get", NULL); - RNA_def_property_clear_flag(prop, PROP_EDITABLE); - RNA_def_property_ui_text(prop, "Use Spherical Stereo", "Active render engine supports spherical stereo rendering"); - - prop = RNA_def_property(srna, "use_game_engine", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_funcs(prop, "rna_RenderSettings_use_game_engine_get", NULL); - RNA_def_property_clear_flag(prop, PROP_EDITABLE); - RNA_def_property_ui_text(prop, "Use Game Engine", "Current rendering engine is a game engine"); - /* simplify */ prop = RNA_def_property(srna, "use_simplify", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "mode", R_SIMPLIFY); @@ -8788,6 +8693,52 @@ static void rna_def_scene_render_data(BlenderRNA *brna) RNA_api_scene_render(srna); } +static void rna_def_scene_view_render(BlenderRNA *brna) +{ + StructRNA *srna; + PropertyRNA *prop; + + static EnumPropertyItem engine_items[] = { + {0, "BLENDER_RENDER", 0, "Blender Render", "Use the Blender internal rendering engine for rendering"}, + {0, NULL, 0, NULL, NULL} + }; + + srna = RNA_def_struct(brna, "ViewRenderSettings", NULL); + RNA_def_struct_sdna(srna, "ViewRender"); + RNA_def_struct_nested(brna, srna, "Scene"); + RNA_def_struct_path_func(srna, "rna_ViewRenderSettings_path"); + RNA_def_struct_ui_text(srna, "View Render", "Rendering settings related to viewport drawing/rendering"); + + /* engine */ + prop = RNA_def_property(srna, "engine", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_items(prop, engine_items); + RNA_def_property_enum_funcs(prop, "rna_ViewRenderSettings_engine_get", "rna_ViewRenderSettings_engine_set", + "rna_ViewRenderSettings_engine_itemf"); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_ui_text(prop, "Engine", "Engine to use for rendering"); + RNA_def_property_update(prop, NC_WINDOW, "rna_ViewRenderSettings_engine_update"); + + prop = RNA_def_property(srna, "has_multiple_engines", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_funcs(prop, "rna_ViewRenderSettings_multiple_engines_get", NULL); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_ui_text(prop, "Multiple Engines", "More than one rendering engine is available"); + + prop = RNA_def_property(srna, "use_shading_nodes", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_funcs(prop, "rna_ViewRenderSettings_use_shading_nodes_get", NULL); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_ui_text(prop, "Use Shading Nodes", "Active render engine uses new shading nodes system"); + + prop = RNA_def_property(srna, "use_spherical_stereo", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_funcs(prop, "rna_ViewRenderSettings_use_spherical_stereo_get", NULL); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_ui_text(prop, "Use Spherical Stereo", "Active render engine supports spherical stereo rendering"); + + prop = RNA_def_property(srna, "use_game_engine", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_funcs(prop, "rna_ViewRenderSettings_use_game_engine_get", NULL); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_ui_text(prop, "Use Game Engine", "Current rendering engine is a game engine"); +} + /* scene.objects */ static void rna_def_scene_objects(BlenderRNA *brna, PropertyRNA *cprop) { @@ -9335,6 +9286,12 @@ void RNA_def_scene(BlenderRNA *brna) RNA_def_property_struct_type(prop, "RenderSettings"); RNA_def_property_ui_text(prop, "Render Data", ""); + /* View Render */ + prop = RNA_def_property(srna, "view_render", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, PROP_NEVER_NULL); + RNA_def_property_struct_type(prop, "ViewRenderSettings"); + RNA_def_property_ui_text(prop, "View Render", ""); + /* Render Engine Data */ prop = RNA_def_property(srna, "layer_properties", PROP_COLLECTION, PROP_NONE); RNA_def_property_collection_sdna(prop, NULL, "layer_properties->data.group", NULL); @@ -9497,6 +9454,7 @@ void RNA_def_scene(BlenderRNA *brna) rna_def_scene_layer_settings(brna); rna_def_layer_collection_settings(brna); rna_def_scene_render_data(brna); + rna_def_scene_view_render(brna); rna_def_scene_render_layer(brna); rna_def_gpu_fx(brna); rna_def_scene_render_view(brna); diff --git a/source/blender/makesrna/intern/rna_scene_api.c b/source/blender/makesrna/intern/rna_scene_api.c index a1ef3f17bd6..baa29df3fc3 100644 --- a/source/blender/makesrna/intern/rna_scene_api.c +++ b/source/blender/makesrna/intern/rna_scene_api.c @@ -151,14 +151,24 @@ static void rna_SceneRender_get_frame_path(RenderData *rd, int frame, int previe } static void rna_Scene_ray_cast( - Scene *scene, SceneLayer *sl, float origin[3], float direction[3], float ray_dist, + Scene *scene, SceneLayer *scene_layer, const char *engine_id, + float origin[3], float direction[3], float ray_dist, int *r_success, float r_location[3], float r_normal[3], int *r_index, Object **r_ob, float r_obmat[16]) { + RenderEngineType *engine; + + if (engine_id == NULL || engine_id[0] == '\0') { + engine = RE_engines_find(scene->view_render.engine_id); + } + else { + engine = RE_engines_find(engine_id); + } + normalize_v3(direction); SnapObjectContext *sctx = ED_transform_snap_object_context_create( - G.main, scene, sl, 0); + G.main, scene, scene_layer, engine, 0); bool ret = ED_transform_snap_object_project_ray_ex( sctx, @@ -354,6 +364,7 @@ void RNA_api_scene(StructRNA *srna) RNA_def_function_ui_description(func, "Cast a ray onto in object space"); parm = RNA_def_pointer(func, "scene_layer", "SceneLayer", "", "Scene Layer"); RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED); + parm = RNA_def_string(func, "engine", NULL, MAX_NAME, "Engine", "Render engine, use scene one by default"); /* ray start and end */ parm = RNA_def_float_vector(func, "origin", 3, NULL, -FLT_MAX, FLT_MAX, "", "", -1e4, 1e4); RNA_def_parameter_flags(parm, 0, PARM_REQUIRED); diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index bf583654fc6..016392754d1 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -210,6 +210,7 @@ static EnumPropertyItem buttons_context_items[] = { {BCONTEXT_PARTICLE, "PARTICLES", ICON_PARTICLES, "Particles", "Particle"}, {BCONTEXT_PHYSICS, "PHYSICS", ICON_PHYSICS, "Physics", "Physics"}, {BCONTEXT_COLLECTION, "COLLECTION", ICON_COLLAPSEMENU, "Collection", "Collection"}, + {BCONTEXT_WORKSPACE, "WORKSPACE", ICON_RENDER_RESULT, "Workspace", "Workspace"}, {0, NULL, 0, NULL, NULL} }; @@ -726,8 +727,14 @@ static void rna_RegionView3D_view_matrix_set(PointerRNA *ptr, const float *value static int rna_SpaceView3D_viewport_shade_get(PointerRNA *ptr) { - Scene *scene = WM_windows_scene_get_from_screen(G.main->wm.first, ptr->id.data); - RenderEngineType *type = RE_engines_find(scene->r.engine); + bScreen *screen = ptr->id.data; + + Scene *scene = WM_windows_scene_get_from_screen(G.main->wm.first, screen); + WorkSpace *workspace = WM_windows_workspace_get_from_screen(G.main->wm.first, screen); + + ViewRender *view_render = BKE_viewrender_get(scene, workspace); + RenderEngineType *type = RE_engines_find(view_render->engine_id); + View3D *v3d = (View3D *)ptr->data; int drawtype = v3d->drawtype; @@ -751,7 +758,9 @@ static EnumPropertyItem *rna_SpaceView3D_viewport_shade_itemf(bContext *C, Point { wmWindow *win = CTX_wm_window(C); Scene *scene = WM_window_get_active_scene(win); - RenderEngineType *type = RE_engines_find(scene->r.engine); + WorkSpace *workspace = WM_window_get_active_workspace(win); + ViewRender *view_render = BKE_viewrender_get(scene, workspace); + RenderEngineType *type = RE_engines_find(view_render->engine_id); EnumPropertyItem *item = NULL; int totitem = 0; @@ -1117,14 +1126,18 @@ static EnumPropertyItem *rna_SpaceProperties_context_itemf(bContext *UNUSED(C), RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_SCENE); } - if (sbuts->pathflag & (1 << BCONTEXT_COLLECTION)) { - RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_COLLECTION); - } - if (sbuts->pathflag & (1 << BCONTEXT_WORLD)) { RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_WORLD); } + if (sbuts->pathflag & (1 << BCONTEXT_WORKSPACE)) { + RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_WORKSPACE); + } + + if (sbuts->pathflag & (1 << BCONTEXT_COLLECTION)) { + RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_COLLECTION); + } + if (sbuts->pathflag & (1 << BCONTEXT_OBJECT)) { RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_OBJECT); } diff --git a/source/blender/makesrna/intern/rna_workspace.c b/source/blender/makesrna/intern/rna_workspace.c index c09cc204bbc..4e04581a0a8 100644 --- a/source/blender/makesrna/intern/rna_workspace.c +++ b/source/blender/makesrna/intern/rna_workspace.c @@ -28,11 +28,18 @@ #include "BKE_workspace.h" +#include "ED_render.h" + +#include "RE_engine.h" + #include "WM_api.h" #include "WM_types.h" #include "rna_internal.h" +/* Allow accessing private members of DNA_workspace_types.h */ +#define DNA_PRIVATE_WORKSPACE_ALLOW +#include "DNA_workspace_types.h" #ifdef RNA_RUNTIME @@ -42,7 +49,6 @@ #include "DNA_object_types.h" #include "DNA_screen_types.h" -#include "DNA_workspace_types.h" #include "RNA_access.h" @@ -154,6 +160,20 @@ static void rna_def_workspace(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Active Render Layer", "The active render 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); + RNA_def_property_struct_type(prop, "ViewRenderSettings"); + RNA_def_property_ui_text(prop, "View Render", ""); + + /* Flags */ + prop = RNA_def_property(srna, "use_scene_settings", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_boolean_sdna(prop, NULL, "flags", WORKSPACE_USE_SCENE_SETTINGS); + RNA_def_property_ui_text(prop, "Scene Settings", + "Use scene settings instead of workspace settings"); + RNA_def_property_update(prop, NC_SCREEN | ND_LAYER, NULL); } static void rna_def_transform_orientation(BlenderRNA *brna) diff --git a/source/blender/nodes/composite/nodes/node_composite_image.c b/source/blender/nodes/composite/nodes/node_composite_image.c index a95c3233132..0ca36ef548e 100644 --- a/source/blender/nodes/composite/nodes/node_composite_image.c +++ b/source/blender/nodes/composite/nodes/node_composite_image.c @@ -41,6 +41,7 @@ #include "BKE_context.h" #include "BKE_global.h" #include "BKE_main.h" +#include "BKE_scene.h" /* **************** IMAGE (and RenderResult, multilayer image) ******************** */ @@ -218,7 +219,7 @@ static void cmp_node_rlayer_create_outputs(bNodeTree *ntree, bNode *node, LinkNo Scene *scene = (Scene *)node->id; if (scene) { - RenderEngineType *engine_type = RE_engines_find(scene->r.engine); + RenderEngineType *engine_type = RE_engines_find(scene->view_render.engine_id); if (engine_type && engine_type->update_render_passes) { SceneRenderLayer *srl = BLI_findlink(&scene->r.layers, node->custom1); if (srl) { diff --git a/source/blender/nodes/shader/node_shader_tree.c b/source/blender/nodes/shader/node_shader_tree.c index 08205d589bf..b014da90145 100644 --- a/source/blender/nodes/shader/node_shader_tree.c +++ b/source/blender/nodes/shader/node_shader_tree.c @@ -39,6 +39,7 @@ #include "DNA_space_types.h" #include "DNA_world_types.h" #include "DNA_linestyle_types.h" +#include "DNA_workspace_types.h" #include "BLI_listbase.h" #include "BLI_threads.h" @@ -67,23 +68,29 @@ static int shader_tree_poll(const bContext *C, bNodeTreeType *UNUSED(treetype)) { Scene *scene = CTX_data_scene(C); + WorkSpace *workspace = CTX_wm_workspace(C); + ViewRender *view_render = BKE_viewrender_get(scene, workspace); + const char *engine_id = view_render->engine_id; + /* allow empty engine string too, this is from older versions that didn't have registerable engines yet */ - return (scene->r.engine[0] == '\0' || - STREQ(scene->r.engine, RE_engine_id_BLENDER_RENDER) || - STREQ(scene->r.engine, RE_engine_id_BLENDER_GAME) || - STREQ(scene->r.engine, RE_engine_id_CYCLES) || - !BKE_scene_use_shading_nodes_custom(scene)); + return (engine_id[0] == '\0' || + STREQ(engine_id, RE_engine_id_BLENDER_RENDER) || + STREQ(engine_id, RE_engine_id_BLENDER_GAME) || + STREQ(engine_id, RE_engine_id_CYCLES) || + !BKE_viewrender_use_shading_nodes_custom(view_render)); } static void shader_get_from_context(const bContext *C, bNodeTreeType *UNUSED(treetype), bNodeTree **r_ntree, ID **r_id, ID **r_from) { SpaceNode *snode = CTX_wm_space_node(C); Scene *scene = CTX_data_scene(C); + WorkSpace *workspace = CTX_wm_workspace(C); SceneLayer *sl = CTX_data_scene_layer(C); Object *ob = OBACT_NEW(sl); + ViewRender *view_render = BKE_viewrender_get(scene, workspace); if ((snode->shaderfrom == SNODE_SHADER_OBJECT) || - (BKE_scene_use_new_shading_nodes(scene) == false)) + (BKE_viewrender_use_new_shading_nodes(view_render) == false)) { if (ob) { *r_from = &ob->id; @@ -119,12 +126,12 @@ static void shader_get_from_context(const bContext *C, bNodeTreeType *UNUSED(tre } } -static void foreach_nodeclass(Scene *scene, void *calldata, bNodeClassCallback func) +static void foreach_nodeclass(ViewRender *view_render, void *calldata, bNodeClassCallback func) { func(calldata, NODE_CLASS_INPUT, N_("Input")); func(calldata, NODE_CLASS_OUTPUT, N_("Output")); - if (BKE_scene_use_new_shading_nodes(scene)) { + if (BKE_viewrender_use_new_shading_nodes(view_render)) { func(calldata, NODE_CLASS_SHADER, N_("Shader")); func(calldata, NODE_CLASS_TEXTURE, N_("Texture")); } diff --git a/source/blender/nodes/texture/node_texture_tree.c b/source/blender/nodes/texture/node_texture_tree.c index 2ac4ce2f48c..6db5e106ed7 100644 --- a/source/blender/nodes/texture/node_texture_tree.c +++ b/source/blender/nodes/texture/node_texture_tree.c @@ -121,7 +121,7 @@ static void texture_get_from_context(const bContext *C, bNodeTreeType *UNUSED(tr } } -static void foreach_nodeclass(Scene *UNUSED(scene), void *calldata, bNodeClassCallback func) +static void foreach_nodeclass(ViewRender *UNUSED(view_render), void *calldata, bNodeClassCallback func) { func(calldata, NODE_CLASS_INPUT, N_("Input")); func(calldata, NODE_CLASS_OUTPUT, N_("Output")); diff --git a/source/blender/render/extern/include/RE_pipeline.h b/source/blender/render/extern/include/RE_pipeline.h index 09f308da10a..c19c332c677 100644 --- a/source/blender/render/extern/include/RE_pipeline.h +++ b/source/blender/render/extern/include/RE_pipeline.h @@ -51,6 +51,7 @@ struct Scene; struct SceneRenderLayer; struct EnvMap; struct StampData; +struct ViewRender; /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ /* this include is what is exposed of render to outside world */ @@ -243,7 +244,7 @@ struct RenderPass *RE_create_gp_pass(struct RenderResult *rr, const char *layern /* obligatory initialize call, disprect is optional */ void RE_InitState(struct Render *re, struct Render *source, struct RenderData *rd, - struct SceneRenderLayer *srl, + struct ViewRender *view_render, struct SceneRenderLayer *srl, int winx, int winy, rcti *disprect); void RE_ChangeResolution(struct Render *re, int winx, int winy, rcti *disprect); void RE_ChangeModeFlag(struct Render *re, int flag, bool clear); @@ -304,11 +305,13 @@ void RE_RenderFreestyleExternal(struct Render *re); void RE_SetActiveRenderView(struct Render *re, const char *viewname); const char *RE_GetActiveRenderView(struct Render *re); +void RE_SetEngineByID(struct Render *re, const char *engine_id); + /* error reporting */ void RE_SetReports(struct Render *re, struct ReportList *reports); /* main preview render call */ -void RE_PreviewRender(struct Render *re, struct Main *bmain, struct Scene *scene); +void RE_PreviewRender(struct Render *re, struct Main *bmain, struct Scene *scene, struct ViewRender *render_view); bool RE_ReadRenderResult(struct Scene *scene, struct Scene *scenode); bool RE_WriteRenderResult( diff --git a/source/blender/render/intern/include/render_types.h b/source/blender/render/intern/include/render_types.h index 1de1f23f351..c97832f32c5 100644 --- a/source/blender/render/intern/include/render_types.h +++ b/source/blender/render/intern/include/render_types.h @@ -192,6 +192,7 @@ struct Render { Scene *scene; RenderData r; World wrld; + ViewRender view_render; struct Object *camera_override; unsigned int lay, layer_override; diff --git a/source/blender/render/intern/include/renderpipeline.h b/source/blender/render/intern/include/renderpipeline.h index c5d6e3b44b1..44df2726847 100644 --- a/source/blender/render/intern/include/renderpipeline.h +++ b/source/blender/render/intern/include/renderpipeline.h @@ -37,11 +37,13 @@ struct Render; struct RenderData; struct RenderLayer; struct RenderResult; +struct ViewRender; struct RenderLayer *render_get_active_layer(struct Render *re, struct RenderResult *rr); float panorama_pixel_rot(struct Render *re); void render_update_anim_renderdata(struct Render *re, struct RenderData *rd); void render_copy_renderdata(struct RenderData *to, struct RenderData *from); +void render_copy_viewrender(struct ViewRender *to, struct ViewRender *from); #endif /* __RENDERPIPELINE_H__ */ diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c index 1329ad484ea..76daa635df2 100644 --- a/source/blender/render/intern/source/convertblender.c +++ b/source/blender/render/intern/source/convertblender.c @@ -71,6 +71,7 @@ #include "BKE_key.h" #include "BKE_image.h" #include "BKE_lattice.h" +#include "BKE_layer.h" #include "BKE_material.h" #include "BKE_main.h" #include "BKE_mball.h" @@ -4848,6 +4849,8 @@ void RE_Database_Free(Render *re) BLI_memarena_free(re->memArena); re->memArena = NULL; } + + BKE_viewrender_free(&re->view_render); } static int allow_render_object(Render *re, Object *ob, int nolamps, int onlyselected, Object *actob) @@ -5200,6 +5203,7 @@ void RE_Database_FromScene(Render *re, Main *bmain, Scene *scene, unsigned int l re->i.infostr= "Preparing Scene data"; re->i.cfra= scene->r.cfra; BLI_strncpy(re->i.scene_name, scene->id.name + 2, sizeof(re->i.scene_name)); + re->view_render = scene->view_render; /* XXX add test if dbase was filled already? */ @@ -5909,6 +5913,7 @@ void RE_Database_Baking(Render *re, Main *bmain, Scene *scene, unsigned int lay, /* renderdata setup and exceptions */ render_copy_renderdata(&re->r, &scene->r); + render_copy_viewrender(&re->view_render, &scene->view_render); RE_init_threadcount(re); diff --git a/source/blender/render/intern/source/envmap.c b/source/blender/render/intern/source/envmap.c index 7bd8c6decf0..1aab70c0fb9 100644 --- a/source/blender/render/intern/source/envmap.c +++ b/source/blender/render/intern/source/envmap.c @@ -142,7 +142,6 @@ static Render *envmap_render_copy(Render *re, EnvMap *env) envre->flag = re->flag; /* set up renderdata */ - render_copy_renderdata(&envre->r, &re->r); envre->r.mode &= ~(R_BORDER | R_PANORAMA | R_ORTHO | R_MBLUR); BLI_freelistN(&envre->r.layers); BLI_freelistN(&envre->r.views); @@ -152,7 +151,7 @@ static Render *envmap_render_copy(Render *re, EnvMap *env) envre->r.size = 100; envre->r.yasp = envre->r.xasp = 1; - RE_InitState(envre, NULL, &envre->r, NULL, cuberes, cuberes, NULL); + RE_InitState(envre, NULL, &envre->r, &envre->view_render, NULL, cuberes, cuberes, NULL); envre->main = re->main; envre->scene = re->scene; /* unsure about this... */ envre->scene_color_manage = re->scene_color_manage; diff --git a/source/blender/render/intern/source/external_engine.c b/source/blender/render/intern/source/external_engine.c index c2e6d540ad8..9ea6a21c566 100644 --- a/source/blender/render/intern/source/external_engine.c +++ b/source/blender/render/intern/source/external_engine.c @@ -152,8 +152,7 @@ RenderEngineType *RE_engines_find(const char *idname) bool RE_engine_is_external(Render *re) { - RenderEngineType *type = RE_engines_find(re->r.engine); - return (type && type->render_to_image); + return (re->engine && re->engine->type && re->engine->type->render_to_image); } /* Create, Free */ @@ -521,11 +520,12 @@ void RE_bake_engine_set_engine_parameters(Render *re, Main *bmain, Depsgraph *gr re->scene = scene; re->main = bmain; render_copy_renderdata(&re->r, &scene->r); + render_copy_viewrender(&re->view_render, &scene->view_render); } bool RE_bake_has_engine(Render *re) { - RenderEngineType *type = RE_engines_find(re->r.engine); + RenderEngineType *type = RE_engines_find(re->view_render.engine_id); return (type->bake != NULL); } @@ -536,7 +536,7 @@ bool RE_bake_engine( const ScenePassType pass_type, const int pass_filter, float result[]) { - RenderEngineType *type = RE_engines_find(re->r.engine); + RenderEngineType *type = RE_engines_find(re->view_render.engine_id); RenderEngine *engine; bool persistent_data = (re->r.mode & R_PERSISTENT_DATA) != 0; @@ -630,7 +630,7 @@ void RE_engine_frame_set(RenderEngine *engine, int frame, float subframe) int RE_engine_render(Render *re, int do_all) { - RenderEngineType *type = RE_engines_find(re->r.engine); + RenderEngineType *type = RE_engines_find(re->view_render.engine_id); RenderEngine *engine; bool persistent_data = (re->r.mode & R_PERSISTENT_DATA) != 0; diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c index 2a390c5fb97..019773a91db 100644 --- a/source/blender/render/intern/source/pipeline.c +++ b/source/blender/render/intern/source/pipeline.c @@ -660,12 +660,13 @@ void RE_FreePersistentData(void) /* ********* initialize state ******** */ /* clear full sample and tile flags if needed */ -static int check_mode_full_sample(RenderData *rd) +static int check_mode_full_sample(RenderData *rd, ViewRender *view_render) { + const char *engine_id = view_render->engine_id; int scemode = rd->scemode; - if (!STREQ(rd->engine, RE_engine_id_BLENDER_RENDER) && - !STREQ(rd->engine, RE_engine_id_BLENDER_GAME)) + if (!STREQ(engine_id, RE_engine_id_BLENDER_RENDER) && + !STREQ(engine_id, RE_engine_id_BLENDER_GAME)) { scemode &= ~R_FULL_SAMPLE; } @@ -738,10 +739,15 @@ void render_copy_renderdata(RenderData *to, RenderData *from) curvemapping_copy_data(&to->mblur_shutter_curve, &from->mblur_shutter_curve); } +void render_copy_viewrender(ViewRender *to, ViewRender *from) +{ + BKE_viewrender_copy(to, from); +} + /* what doesn't change during entire render sequence */ /* disprect is optional, if NULL it assumes full window render */ void RE_InitState(Render *re, Render *source, RenderData *rd, - SceneRenderLayer *srl, + ViewRender *view_render, SceneRenderLayer *srl, int winx, int winy, rcti *disprect) { bool had_freestyle = (re->r.mode & R_EDGE_FRS) != 0; @@ -752,6 +758,7 @@ void RE_InitState(Render *re, Render *source, RenderData *rd, /* copy render data and render layers for thread safety */ render_copy_renderdata(&re->r, rd); + render_copy_viewrender(&re->view_render, view_render); if (source) { /* reuse border flags from source renderer */ @@ -781,7 +788,7 @@ void RE_InitState(Render *re, Render *source, RenderData *rd, return; } - re->r.scemode = check_mode_full_sample(&re->r); + re->r.scemode = check_mode_full_sample(&re->r, &re->view_render); /* fullsample wants uniform osa levels */ if (source && (re->r.scemode & R_FULL_SAMPLE)) { @@ -1968,7 +1975,7 @@ static void render_scene(Render *re, Scene *sce, int cfra) } /* initial setup */ - RE_InitState(resc, re, &sce->r, NULL, winx, winy, &re->disprect); + RE_InitState(resc, re, &sce->r, &sce->view_render, NULL, winx, winy, &re->disprect); /* We still want to use 'rendercache' setting from org (main) scene... */ resc->r.scemode = (resc->r.scemode & ~R_EXR_CACHE_FILE) | (re->r.scemode & R_EXR_CACHE_FILE); @@ -2058,15 +2065,8 @@ bool RE_allow_render_generic_object(Object *ob) #ifdef DEPSGRAPH_WORKAROUND_HACK static void tag_dependend_objects_for_render(Scene *scene, int UNUSED(renderlay)) { - Scene *sce_iter; - Base *base; - for (SETLOOPER(scene, sce_iter, base)) { - Object *object = base->object; - - if ((base->flag & BASE_VISIBLED) == 0) { - continue; - } - + FOREACH_OBJECT_RENDERABLE(scene, object) + { if (object->type == OB_MESH) { if (RE_allow_render_generic_object(object)) { ModifierData *md; @@ -2105,6 +2105,7 @@ static void tag_dependend_objects_for_render(Scene *scene, int UNUSED(renderlay) } } } + FOREACH_OBJECT_RENDERABLE_END } #endif @@ -2875,7 +2876,7 @@ static void do_render_all_options(Render *re) bool RE_force_single_renderlayer(Scene *scene) { - int scemode = check_mode_full_sample(&scene->r); + int scemode = check_mode_full_sample(&scene->r, &scene->view_render); if (scemode & R_SINGLE_LAYER) { SceneRenderLayer *srl = BLI_findlink(&scene->r.layers, scene->r.actlay); /* force layer to be enabled */ @@ -3022,7 +3023,7 @@ static int check_composite_output(Scene *scene) bool RE_is_rendering_allowed(Scene *scene, Object *camera_override, ReportList *reports) { - int scemode = check_mode_full_sample(&scene->r); + int scemode = check_mode_full_sample(&scene->r, &scene->view_render); if (scene->r.mode & R_BORDER) { if (scene->r.border.xmax <= scene->r.border.xmin || @@ -3135,13 +3136,14 @@ static void validate_render_settings(Render *re) } } -static void update_physics_cache(Render *re, Scene *scene, int UNUSED(anim_init)) +static void update_physics_cache(Render *re, Scene *scene, SceneLayer *scene_layer, int UNUSED(anim_init)) { PTCacheBaker baker; memset(&baker, 0, sizeof(baker)); baker.main = re->main; baker.scene = scene; + baker.scene_layer = scene_layer; baker.bake = 0; baker.render = 1; baker.anim_init = 1; @@ -3160,9 +3162,15 @@ const char *RE_GetActiveRenderView(Render *re) return re->viewname; } +void RE_SetEngineByID(Render *re, const char *engine_id) +{ + BLI_strncpy(re->view_render.engine_id, engine_id, sizeof(re->view_render.engine_id)); +} + /* evaluating scene options for general Blender render */ -static int render_initialize_from_main(Render *re, RenderData *rd, Main *bmain, Scene *scene, SceneRenderLayer *srl, - Object *camera_override, unsigned int lay_override, int anim, int anim_init) +static int render_initialize_from_main(Render *re, RenderData *rd, Main *bmain, Scene *scene, ViewRender *view_render, + SceneRenderLayer *srl, Object *camera_override, unsigned int lay_override, + int anim, int anim_init) { int winx, winy; rcti disprect; @@ -3196,6 +3204,7 @@ static int render_initialize_from_main(Render *re, RenderData *rd, Main *bmain, re->layer_override = lay_override; re->i.localview = (re->lay & 0xFF000000) != 0; re->viewname[0] = '\0'; + RE_SetEngineByID(re, view_render->engine_id); /* not too nice, but it survives anim-border render */ if (anim) { @@ -3214,7 +3223,8 @@ static int render_initialize_from_main(Render *re, RenderData *rd, Main *bmain, */ if (0) { /* make sure dynamics are up to date */ - update_physics_cache(re, scene, anim_init); + SceneLayer *scene_layer = BKE_scene_layer_from_scene_get(scene); + update_physics_cache(re, scene, scene_layer, anim_init); } if (srl || scene->r.scemode & R_SINGLE_LAYER) { @@ -3223,7 +3233,7 @@ static int render_initialize_from_main(Render *re, RenderData *rd, Main *bmain, BLI_rw_mutex_unlock(&re->resultmutex); } - RE_InitState(re, NULL, &scene->r, srl, winx, winy, &disprect); + RE_InitState(re, NULL, &scene->r, &scene->view_render, srl, winx, winy, &disprect); if (!re->ok) /* if an error was printed, abort */ return 0; @@ -3254,7 +3264,9 @@ void RE_BlenderFrame(Render *re, Main *bmain, Scene *scene, SceneRenderLayer *sr scene->r.cfra = frame; - if (render_initialize_from_main(re, &scene->r, bmain, scene, srl, camera_override, lay_override, 0, 0)) { + if (render_initialize_from_main(re, &scene->r, bmain, scene, &scene->view_render, srl, + camera_override, lay_override, 0, 0)) + { MEM_reset_peak_memory(); BLI_callback_exec(re->main, (ID *)scene, BLI_CB_EVT_RENDER_PRE); @@ -3293,7 +3305,7 @@ void RE_BlenderFrame(Render *re, Main *bmain, Scene *scene, SceneRenderLayer *sr void RE_RenderFreestyleStrokes(Render *re, Main *bmain, Scene *scene, int render) { re->result_ok= 0; - if (render_initialize_from_main(re, &scene->r, bmain, scene, NULL, NULL, scene->lay, 0, 0)) { + if (render_initialize_from_main(re, &scene->r, bmain, scene, &scene->view_render, NULL, NULL, scene->lay, 0, 0)) { if (render) do_render_fields_blur_3d(re); } @@ -3591,7 +3603,7 @@ void RE_BlenderAnim(Render *re, Main *bmain, Scene *scene, Object *camera_overri BLI_callback_exec(re->main, (ID *)scene, BLI_CB_EVT_RENDER_INIT); /* do not fully call for each frame, it initializes & pops output window */ - if (!render_initialize_from_main(re, &rd, bmain, scene, NULL, camera_override, lay_override, 0, 1)) + if (!render_initialize_from_main(re, &rd, bmain, scene, &scene->view_render, NULL, camera_override, lay_override, 0, 1)) return; /* MULTIVIEW_TODO: @@ -3681,7 +3693,8 @@ void RE_BlenderAnim(Render *re, Main *bmain, Scene *scene, Object *camera_overri } /* only border now, todo: camera lens. (ton) */ - render_initialize_from_main(re, &rd, bmain, scene, NULL, camera_override, lay_override, 1, 0); + render_initialize_from_main(re, &rd, bmain, scene, &scene->view_render, + NULL, camera_override, lay_override, 1, 0); if (nfra != scene->r.cfra) { /* Skip this frame, but update for physics and particles system. */ @@ -3831,7 +3844,7 @@ void RE_BlenderAnim(Render *re, Main *bmain, Scene *scene, Object *camera_overri G.is_rendering = false; } -void RE_PreviewRender(Render *re, Main *bmain, Scene *sce) +void RE_PreviewRender(Render *re, Main *bmain, Scene *sce, ViewRender *view_render) { Object *camera; SceneLayer *scene_layer = BKE_scene_layer_from_scene_get(sce); @@ -3840,7 +3853,7 @@ void RE_PreviewRender(Render *re, Main *bmain, Scene *sce) winx = (sce->r.size * sce->r.xsch) / 100; winy = (sce->r.size * sce->r.ysch) / 100; - RE_InitState(re, NULL, &sce->r, NULL, winx, winy, NULL); + RE_InitState(re, NULL, &sce->r, view_render, NULL, winx, winy, NULL); re->pool = BKE_image_pool_new(); @@ -3895,7 +3908,7 @@ bool RE_ReadRenderResult(Scene *scene, Scene *scenode) re = RE_GetSceneRender(scene); if (re == NULL) re = RE_NewSceneRender(scene); - RE_InitState(re, NULL, &scene->r, NULL, winx, winy, &disprect); + RE_InitState(re, NULL, &scene->r, &scene->view_render, NULL, winx, winy, &disprect); re->scene = scene; re->scene_color_manage = BKE_scene_check_color_management_enabled(scene); diff --git a/source/blender/render/intern/source/pointdensity.c b/source/blender/render/intern/source/pointdensity.c index 63fe7e4471a..4ba6e914c68 100644 --- a/source/blender/render/intern/source/pointdensity.c +++ b/source/blender/render/intern/source/pointdensity.c @@ -945,7 +945,7 @@ static void particle_system_minmax(EvaluationContext *eval_ctx, void RE_point_density_cache( Scene *scene, - SceneLayer *sl, + SceneLayer *scene_layer, PointDensity *pd, const bool use_render_params) { @@ -955,7 +955,7 @@ void RE_point_density_cache( DEG_evaluation_context_init(&eval_ctx, use_render_params ? DAG_EVAL_RENDER : DAG_EVAL_VIEWPORT); - eval_ctx.scene_layer = sl; + eval_ctx.scene_layer = scene_layer; /* Same matricies/resolution as dupli_render_particle_set(). */ unit_m4(mat); diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h index 6f7bedffda4..8eab8662ea9 100644 --- a/source/blender/windowmanager/WM_api.h +++ b/source/blender/windowmanager/WM_api.h @@ -101,6 +101,7 @@ bool WM_window_is_fullscreen (struct wmWindow *win); void WM_windows_scene_data_sync(const ListBase *win_lb, struct Scene *scene) ATTR_NONNULL(); struct Scene *WM_windows_scene_get_from_screen(const struct wmWindowManager *wm, const struct bScreen *screen) ATTR_NONNULL() ATTR_WARN_UNUSED_RESULT; +struct WorkSpace *WM_windows_workspace_get_from_screen(const wmWindowManager *wm, const struct bScreen *screen) ATTR_NONNULL() ATTR_WARN_UNUSED_RESULT; struct Scene *WM_window_get_active_scene(const struct wmWindow *win) ATTR_NONNULL() ATTR_WARN_UNUSED_RESULT; void WM_window_change_active_scene(struct Main *bmain, struct bContext *C, struct wmWindow *win, diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index e842db64015..2852b1b4d24 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -409,12 +409,13 @@ void wm_event_do_notifiers(bContext *C) for (win = wm->windows.first; win; win = win->next) { Scene *scene = WM_window_get_active_scene(win); bScreen *screen = WM_window_get_active_screen(win); + WorkSpace *workspace = WM_window_get_active_workspace(win); /* filter out notifiers */ if (note->category == NC_SCREEN && note->reference && note->reference != screen && - note->reference != WM_window_get_active_workspace(win) && + note->reference != workspace && note->reference != WM_window_get_active_layout(win)) { /* pass */ @@ -437,7 +438,7 @@ void wm_event_do_notifiers(bContext *C) } for (sa = screen->areabase.first; sa; sa = sa->next) { - ED_area_do_listen(screen, sa, note, scene); + ED_area_do_listen(screen, sa, note, scene, workspace); for (ar = sa->regionbase.first; ar; ar = ar->next) { ED_region_do_listen(screen, sa, ar, note, scene); } diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c index 3de6824c23d..33f7a2ecb4d 100644 --- a/source/blender/windowmanager/intern/wm_files.c +++ b/source/blender/windowmanager/intern/wm_files.c @@ -433,8 +433,9 @@ void wm_file_read_report(bContext *C) Scene *sce; for (sce = G.main->scene.first; sce; sce = sce->id.next) { - if (sce->r.engine[0] && - BLI_findstring(&R_engines, sce->r.engine, offsetof(RenderEngineType, idname)) == NULL) + ViewRender *view_render = &sce->view_render; + if (view_render->engine_id[0] && + BLI_findstring(&R_engines, view_render->engine_id, offsetof(RenderEngineType, idname)) == NULL) { if (reports == NULL) { reports = CTX_wm_reports(C); @@ -442,7 +443,7 @@ void wm_file_read_report(bContext *C) BKE_reportf(reports, RPT_ERROR, "Engine '%s' not available for scene '%s' (an add-on may need to be installed or enabled)", - sce->r.engine, sce->id.name + 2); + view_render->engine_id, sce->id.name + 2); } } @@ -1000,7 +1001,7 @@ static void wm_history_file_update(void) /* screen can be NULL */ -static ImBuf *blend_file_thumb(const bContext *C, Scene *scene, SceneLayer *sl, bScreen *screen, BlendThumbnail **thumb_pt) +static ImBuf *blend_file_thumb(const bContext *C, Scene *scene, SceneLayer *scene_layer, bScreen *screen, BlendThumbnail **thumb_pt) { /* will be scaled down, but gives some nice oversampling */ ImBuf *ibuf; @@ -1041,14 +1042,14 @@ static ImBuf *blend_file_thumb(const bContext *C, Scene *scene, SceneLayer *sl, /* gets scaled to BLEN_THUMB_SIZE */ if (scene->camera) { ibuf = ED_view3d_draw_offscreen_imbuf_simple( - &eval_ctx, scene, sl, scene->camera, + &eval_ctx, scene, scene_layer, scene->camera, BLEN_THUMB_SIZE * 2, BLEN_THUMB_SIZE * 2, IB_rect, OB_SOLID, false, false, false, R_ALPHAPREMUL, 0, false, NULL, NULL, NULL, err_out); } else { ibuf = ED_view3d_draw_offscreen_imbuf( - &eval_ctx, scene, sl, v3d, ar, + &eval_ctx, scene, scene_layer, v3d, ar, BLEN_THUMB_SIZE * 2, BLEN_THUMB_SIZE * 2, IB_rect, false, R_ALPHAPREMUL, 0, false, NULL, NULL, NULL, err_out); diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c index 09b2b50687a..0d2f68ca4ac 100644 --- a/source/blender/windowmanager/intern/wm_window.c +++ b/source/blender/windowmanager/intern/wm_window.c @@ -1938,6 +1938,16 @@ Scene *WM_windows_scene_get_from_screen(const wmWindowManager *wm, const bScreen return NULL; } +WorkSpace *WM_windows_workspace_get_from_screen(const wmWindowManager *wm, const bScreen *screen) +{ + for (wmWindow *win = wm->windows.first; win; win = win->next) { + if (WM_window_get_active_screen(win) == screen) { + return WM_window_get_active_workspace(win); + } + } + return NULL; +} + Scene *WM_window_get_active_scene(const wmWindow *win) { return win->scene; |