diff options
Diffstat (limited to 'source/blender/blenkernel/intern/layer.c')
-rw-r--r-- | source/blender/blenkernel/intern/layer.c | 162 |
1 files changed, 162 insertions, 0 deletions
diff --git a/source/blender/blenkernel/intern/layer.c b/source/blender/blenkernel/intern/layer.c index 73b330bc0de..6b346d7a337 100644 --- a/source/blender/blenkernel/intern/layer.c +++ b/source/blender/blenkernel/intern/layer.c @@ -57,6 +57,8 @@ #include "DRW_engine.h" +#include "RE_engine.h" + #include "MEM_guardedalloc.h" #include "BLO_read_write.h" @@ -279,6 +281,8 @@ void BKE_view_layer_free_ex(ViewLayer *view_layer, const bool do_id_user) } } BLI_freelistN(&view_layer->drawdata); + BLI_freelistN(&view_layer->aovs); + view_layer->active_aov = NULL; MEM_SAFE_FREE(view_layer->stats); @@ -412,6 +416,28 @@ void BKE_view_layer_base_select_and_set_active(struct ViewLayer *view_layer, Bas } /**************************** Copy View Layer and Layer Collections ***********************/ +static void layer_aov_copy_data(ViewLayer *view_layer_dst, + const ViewLayer *view_layer_src, + ListBase *aovs_dst, + const ListBase *aovs_src) +{ + if (aovs_src != NULL) { + BLI_duplicatelist(aovs_dst, aovs_src); + } + + ViewLayerAOV *aov_dst = aovs_dst->first; + const ViewLayerAOV *aov_src = aovs_src->first; + + while (aov_dst != NULL) { + BLI_assert(aov_src); + if (aov_src == view_layer_src->active_aov) { + view_layer_dst->active_aov = aov_dst; + } + + aov_dst = aov_dst->next; + aov_src = aov_src->next; + } +} static void layer_collections_copy_data(ViewLayer *view_layer_dst, const ViewLayer *view_layer_src, @@ -482,6 +508,10 @@ void BKE_view_layer_copy_data(Scene *scene_dst, LayerCollection *lc_scene_dst = view_layer_dst->layer_collections.first; lc_scene_dst->collection = scene_dst->master_collection; + BLI_listbase_clear(&view_layer_dst->aovs); + layer_aov_copy_data( + view_layer_dst, view_layer_src, &view_layer_dst->aovs, &view_layer_src->aovs); + if ((flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0) { id_us_plus((ID *)view_layer_dst->mat_override); } @@ -1864,6 +1894,9 @@ void BKE_view_layer_blend_write(BlendWriter *writer, ViewLayer *view_layer) LISTBASE_FOREACH (FreestyleLineSet *, fls, &view_layer->freestyle_config.linesets) { BLO_write_struct(writer, FreestyleLineSet, fls); } + LISTBASE_FOREACH (ViewLayerAOV *, aov, &view_layer->aovs) { + BLO_write_struct(writer, ViewLayerAOV, aov); + } write_layer_collections(writer, &view_layer->layer_collections); } @@ -1899,6 +1932,9 @@ void BKE_view_layer_blend_read_data(BlendDataReader *reader, ViewLayer *view_lay BLO_read_list(reader, &(view_layer->freestyle_config.modules)); BLO_read_list(reader, &(view_layer->freestyle_config.linesets)); + BLO_read_list(reader, &view_layer->aovs); + BLO_read_data_address(reader, &view_layer->active_aov); + BLI_listbase_clear(&view_layer->drawdata); view_layer->object_bases_array = NULL; view_layer->object_bases_hash = NULL; @@ -1952,3 +1988,129 @@ void BKE_view_layer_blend_read_lib(BlendLibReader *reader, Library *lib, ViewLay IDP_BlendReadLib(reader, view_layer->id_properties); } + +/* -------------------------------------------------------------------- */ +/** \name Shader AOV + * \{ */ + +static void viewlayer_aov_make_name_unique(ViewLayer *view_layer) +{ + ViewLayerAOV *aov = view_layer->active_aov; + if (aov == NULL) { + return; + } + BLI_uniquename( + &view_layer->aovs, aov, DATA_("AOV"), '.', offsetof(ViewLayerAOV, name), sizeof(aov->name)); +} + +static void viewlayer_aov_active_set(ViewLayer *view_layer, ViewLayerAOV *aov) +{ + if (aov != NULL) { + BLI_assert(BLI_findindex(&view_layer->aovs, aov) != -1); + view_layer->active_aov = aov; + } + else { + view_layer->active_aov = NULL; + } +} + +struct ViewLayerAOV *BKE_view_layer_add_aov(struct ViewLayer *view_layer) +{ + ViewLayerAOV *aov; + aov = MEM_callocN(sizeof(ViewLayerAOV), __func__); + aov->type = AOV_TYPE_COLOR; + BLI_strncpy(aov->name, DATA_("AOV"), sizeof(aov->name)); + BLI_addtail(&view_layer->aovs, aov); + viewlayer_aov_active_set(view_layer, aov); + viewlayer_aov_make_name_unique(view_layer); + return aov; +} + +void BKE_view_layer_remove_aov(ViewLayer *view_layer, ViewLayerAOV *aov) +{ + BLI_assert(BLI_findindex(&view_layer->aovs, aov) != -1); + BLI_assert(aov != NULL); + if (view_layer->active_aov == aov) { + if (aov->next) { + viewlayer_aov_active_set(view_layer, aov->next); + } + else { + viewlayer_aov_active_set(view_layer, aov->prev); + } + } + BLI_freelinkN(&view_layer->aovs, aov); +} + +void BKE_view_layer_set_active_aov(ViewLayer *view_layer, ViewLayerAOV *aov) +{ + viewlayer_aov_active_set(view_layer, aov); +} + +static void bke_view_layer_verify_aov_cb(void *userdata, + Scene *UNUSED(scene), + ViewLayer *UNUSED(view_layer), + const char *name, + int UNUSED(channels), + const char *UNUSED(chanid), + int UNUSED(type)) +{ + GHash *name_count = userdata; + void **value_p; + void *key = BLI_strdup(name); + + if (!BLI_ghash_ensure_p(name_count, key, &value_p)) { + *value_p = POINTER_FROM_INT(1); + } + else { + int value = POINTER_AS_INT(*value_p); + value++; + *value_p = POINTER_FROM_INT(value); + MEM_freeN(key); + } +} + +/* Update the naming and conflicts of the AOVs. + * + * Name must be unique between all AOVs. + * Conflicts with render passes will show a conflict icon. Reason is that switching a render + * engine or activating a render pass could lead to other conflicts that wouldn't be that clear + * for the user. */ +void BKE_view_layer_verify_aov(struct RenderEngine *engine, + struct Scene *scene, + struct ViewLayer *view_layer) +{ + viewlayer_aov_make_name_unique(view_layer); + + GHash *name_count = BLI_ghash_str_new(__func__); + RE_engine_update_render_passes( + engine, scene, view_layer, bke_view_layer_verify_aov_cb, name_count); + LISTBASE_FOREACH (ViewLayerAOV *, aov, &view_layer->aovs) { + void **value_p = BLI_ghash_lookup(name_count, aov->name); + int count = POINTER_AS_INT(value_p); + SET_FLAG_FROM_TEST(aov->flag, count > 1, AOV_CONFLICT); + } + BLI_ghash_free(name_count, MEM_freeN, NULL); +} + +/* Check if the given view layer has at least one valid AOV. */ +bool BKE_view_layer_has_valid_aov(ViewLayer *view_layer) +{ + LISTBASE_FOREACH (ViewLayerAOV *, aov, &view_layer->aovs) { + if ((aov->flag & AOV_CONFLICT) == 0) { + return true; + } + } + return false; +} + +ViewLayer *BKE_view_layer_find_with_aov(struct Scene *scene, struct ViewLayerAOV *aov) +{ + LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) { + if (BLI_findindex(&view_layer->aovs, aov) != -1) { + return view_layer; + } + } + return NULL; +} + +/** \} */ |