diff --git a/source/blender/blenkernel/BKE_layer.h b/source/blender/blenkernel/BKE_layer.h index de8a577d272..a1eec8653ad 100644 --- a/source/blender/blenkernel/BKE_layer.h +++ b/source/blender/blenkernel/BKE_layer.h @@ -71,7 +71,9 @@ void BKE_scene_layer_base_select(struct SceneLayer *sl, struct Base *selbase); void BKE_scene_layer_base_flag_recalculate(struct SceneLayer *sl); void BKE_scene_layer_engine_settings_recalculate(struct SceneLayer *sl); -void BKE_scene_layer_engine_settings_update(struct SceneLayer *sl); +void BKE_scene_layer_engine_settings_object_recalculate(struct SceneLayer *sl, struct Object *ob); +void BKE_scene_layer_engine_settings_collection_recalculate(struct SceneLayer *sl, struct LayerCollection *lc); +void BKE_scene_layer_engine_settings_update(struct SceneLayer *sl, const char *engine_name); void BKE_layer_collection_free(struct SceneLayer *sl, struct LayerCollection *lc); @@ -103,8 +105,9 @@ typedef void (*CollectionEngineSettingsCB)(struct RenderEngine *engine, struct C struct CollectionEngineSettings *BKE_layer_collection_engine_get(struct LayerCollection *lc, const char *engine_name); void BKE_layer_collection_engine_settings_callback_register(struct Main *bmain, const char *engine_name, CollectionEngineSettingsCB func); void BKE_layer_collection_engine_settings_callback_free(void); -void BKE_layer_collection_engine_settings_create(struct ListBase *lb, const char *engine_name); -void BKE_layer_collection_engine_settings_free(struct ListBase *lb); + +struct CollectionEngineSettings *BKE_layer_collection_engine_settings_create(const char *engine_name); +void BKE_layer_collection_engine_settings_free(struct CollectionEngineSettings *ces); void BKE_collection_engine_property_add_float(struct CollectionEngineSettings *ces, const char *name, float value); void BKE_collection_engine_property_add_int(struct CollectionEngineSettings *ces, const char *name, int value); @@ -195,10 +198,10 @@ void BKE_visible_bases_Iterator_end(Iterator *iter); } /* temporary hacky solution waiting for final depsgraph evaluation */ -#define DEG_OBJECT_ITER(sl_, ob_) \ +#define DEG_OBJECT_ITER(sl_, engine_name_, ob_) \ { \ /* temporary solution, waiting for depsgraph update */ \ - BKE_scene_layer_engine_settings_update(sl); \ + BKE_scene_layer_engine_settings_update(sl, engine_name_); \ \ /* flush all the data to objects*/ \ Base *base_; \ diff --git a/source/blender/blenkernel/intern/collection.c b/source/blender/blenkernel/intern/collection.c index f374ebd1e53..2798edfc47f 100644 --- a/source/blender/blenkernel/intern/collection.c +++ b/source/blender/blenkernel/intern/collection.c @@ -119,6 +119,7 @@ static void layer_collection_remove(SceneLayer *sl, ListBase *lb, const SceneCol LayerCollection *lc = lb->first; while(lc) { if (lc->scene_collection == sc) { + BKE_scene_layer_engine_settings_collection_recalculate(sl, lc); BKE_layer_collection_free(sl, lc); BLI_remlink(lb, lc); diff --git a/source/blender/blenkernel/intern/layer.c b/source/blender/blenkernel/intern/layer.c index 28c5e9aff5d..c36a67c27b3 100644 --- a/source/blender/blenkernel/intern/layer.c +++ b/source/blender/blenkernel/intern/layer.c @@ -49,8 +49,10 @@ struct CollectionEngineSettingsCB_Type; static void layer_collection_free(SceneLayer *sl, LayerCollection *lc); static LayerCollection *layer_collection_add(SceneLayer *sl, ListBase *lb, SceneCollection *sc); static LayerCollection *find_layer_collection_by_scene_collection(LayerCollection *lc, const SceneCollection *sc); -static void collection_engine_settings_create(ListBase *lb, struct CollectionEngineSettingsCB_Type *ces_type); +static CollectionEngineSettings *collection_engine_settings_create(struct CollectionEngineSettingsCB_Type *ces_type); +static void layer_collection_engine_settings_free(LayerCollection *lc); static void layer_collection_create_engine_settings(LayerCollection *lc); +static void scene_layer_engine_settings_update(SceneLayer *sl, Object *ob, const char *engine_name); static void object_bases_Iterator_next(Iterator *iter, const int flag); /* RenderLayer */ @@ -257,8 +259,6 @@ void BKE_scene_layer_base_flag_recalculate(SceneLayer *sl) base->flag &= ~BASE_SELECTED; } } - - BKE_scene_layer_engine_settings_recalculate(sl); } /** @@ -266,9 +266,45 @@ void BKE_scene_layer_base_flag_recalculate(SceneLayer *sl) * * Temporary function, waiting for real depsgraph */ -void BKE_scene_layer_engine_settings_recalculate(struct SceneLayer *sl) +void BKE_scene_layer_engine_settings_recalculate(SceneLayer *sl) { sl->flag |= SCENE_LAYER_ENGINE_DIRTY; + for (Base *base = sl->object_bases.first; base; base = base->next) { + base->flag |= BASE_DIRTY_ENGINE_SETTINGS; + } +} + +/** + * Tag Object in SceneLayer to recalculation + * + * Temporary function, waiting for real depsgraph + */ +void BKE_scene_layer_engine_settings_object_recalculate(SceneLayer *sl, Object *ob) +{ + Base *base = BLI_findptr(&sl->object_bases, ob, offsetof(Base, object)); + if (base) { + sl->flag |= SCENE_LAYER_ENGINE_DIRTY; + base->flag |= BASE_DIRTY_ENGINE_SETTINGS; + } +} + +/** + * Tag all Objects in LayerCollection to recalculation + * + * Temporary function, waiting for real depsgraph + */ +void BKE_scene_layer_engine_settings_collection_recalculate(SceneLayer *sl, LayerCollection *lc) +{ + sl->flag |= SCENE_LAYER_ENGINE_DIRTY; + + for (LinkData *link = lc->object_bases.first; link; link = link->next) { + Base *base = (Base *)link->data; + base->flag |= BASE_DIRTY_ENGINE_SETTINGS; + } + + for (LayerCollection *lcn = lc->layer_collections.first; lcn; lcn = lcn->next) { + BKE_scene_layer_engine_settings_collection_recalculate(sl, lcn); + } } /** @@ -276,14 +312,21 @@ void BKE_scene_layer_engine_settings_recalculate(struct SceneLayer *sl) * * Temporary function, waiting for real depsgraph */ -void BKE_scene_layer_engine_settings_update(struct SceneLayer *sl) +void BKE_scene_layer_engine_settings_update(struct SceneLayer *sl, const char *engine_name) { if ((sl->flag & SCENE_LAYER_ENGINE_DIRTY) == 0) { return; } /* do the complete settings update */ - TODO_LAYER_DEPSGRAPH; + for (Base *base = sl->object_bases.first; base; base = base->next) { + if (((base->flag & BASE_DIRTY_ENGINE_SETTINGS) != 0) && \ + (base->flag & BASE_VISIBLED) != 0) + { + scene_layer_engine_settings_update(sl, base->object, engine_name); + base->flag &= ~BASE_DIRTY_ENGINE_SETTINGS; + } + } sl->flag &= ~SCENE_LAYER_ENGINE_DIRTY; } @@ -324,7 +367,7 @@ static void layer_collection_free(SceneLayer *sl, LayerCollection *lc) BLI_freelistN(&lc->object_bases); BLI_freelistN(&lc->overrides); - BKE_layer_collection_engine_settings_free(&lc->engine_settings); + layer_collection_engine_settings_free(lc); for (LayerCollection *nlc = lc->layer_collections.first; nlc; nlc = nlc->next) { layer_collection_free(sl, nlc); @@ -442,6 +485,7 @@ void BKE_collection_unlink(SceneLayer *sl, LayerCollection *lc) { BKE_layer_collection_free(sl, lc); BKE_scene_layer_base_flag_recalculate(sl); + BKE_scene_layer_engine_settings_collection_recalculate(sl, lc); BLI_remlink(&sl->layer_collections, lc); MEM_freeN(lc); @@ -462,6 +506,7 @@ static void layer_collection_object_add(SceneLayer *sl, LayerCollection *lc, Obj BLI_addtail(&lc->object_bases, BLI_genericNodeN(base)); BKE_scene_layer_base_flag_recalculate(sl); + BKE_scene_layer_engine_settings_object_recalculate(sl, ob); } static void layer_collection_object_remove(SceneLayer *sl, LayerCollection *lc, Object *ob) @@ -599,6 +644,7 @@ void BKE_layer_sync_object_unlink(Scene *scene, SceneCollection *sc, Object *ob) } } BKE_scene_layer_base_flag_recalculate(sl); + BKE_scene_layer_engine_settings_object_recalculate(sl, ob); } } @@ -633,7 +679,8 @@ static void create_engine_settings_layer_collection(LayerCollection *lc, Collect return; } - collection_engine_settings_create(&lc->engine_settings, ces_type); + CollectionEngineSettings *ces = collection_engine_settings_create(ces_type); + BLI_addtail(&lc->engine_settings, ces); for (LayerCollection *lcn = lc->layer_collections.first; lcn; lcn = lcn->next) { create_engine_settings_layer_collection(lcn, ces_type); @@ -680,15 +727,16 @@ void BKE_layer_collection_engine_settings_callback_free(void) BLI_freelistN(&R_engines_settings_callbacks); } -static void collection_engine_settings_create(ListBase *lb, CollectionEngineSettingsCB_Type *ces_type) +static CollectionEngineSettings *collection_engine_settings_create(CollectionEngineSettingsCB_Type *ces_type) { /* create callback data */ CollectionEngineSettings *ces = MEM_callocN(sizeof(CollectionEngineSettings), "Collection Engine Settings"); BLI_strncpy_utf8(ces->name, ces_type->name, sizeof(ces->name)); - BLI_addtail(lb, ces); /* call callback */ ces_type->callback(NULL, ces); + + return ces; } /** @@ -697,26 +745,30 @@ static void collection_engine_settings_create(ListBase *lb, CollectionEngineSett * Usually we would pass LayerCollection->engine_settings * But depsgraph uses this for Object->collection_settings */ -void BKE_layer_collection_engine_settings_create(ListBase *lb, const char *engine_name) +CollectionEngineSettings *BKE_layer_collection_engine_settings_create(const char *engine_name) { CollectionEngineSettingsCB_Type *ces_type; ces_type = BLI_findstring(&R_engines_settings_callbacks, engine_name, offsetof(CollectionEngineSettingsCB_Type, name)); BLI_assert(ces_type); - collection_engine_settings_create(lb, ces_type); + + CollectionEngineSettings *ces = collection_engine_settings_create(ces_type); + return ces; } /** - * Free the CollectionEngineSettings ListBase - * - * Usually we would pass LayerCollection->engine_settings - * But depsgraph uses this for Object->collection_settings + * Free the CollectionEngineSettings */ -void BKE_layer_collection_engine_settings_free(ListBase *lb) +void BKE_layer_collection_engine_settings_free(CollectionEngineSettings *ces) { - for (CollectionEngineSettings *cse = lb->first; cse; cse = cse->next) { - BLI_freelistN(&cse->properties); + BLI_freelistN(&ces->properties); +} + +static void layer_collection_engine_settings_free(LayerCollection *lc) +{ + for (CollectionEngineSettings *ces = lc->engine_settings.first; ces; ces = ces->next) { + BKE_layer_collection_engine_settings_free(ces); } - BLI_freelistN(lb); + BLI_freelistN(&lc->engine_settings); } /** @@ -818,6 +870,110 @@ void BKE_collection_engine_property_use_set(CollectionEngineSettings *ces, const } } +/* Engine Settings recalculate */ + +static void collection_engine_settings_init(CollectionEngineSettings *ces, const char *engine_name) +{ + CollectionEngineSettingsCB_Type *ces_type; + ces_type = BLI_findstring(&R_engines_settings_callbacks, engine_name, offsetof(CollectionEngineSettingsCB_Type, name)); + + BLI_listbase_clear(&ces->properties); + BLI_strncpy_utf8(ces->name, ces_type->name, sizeof(ces->name)); + + /* call callback */ + ces_type->callback(NULL, ces); +} + +static void collection_engine_settings_copy(CollectionEngineSettings *ces_dst, CollectionEngineSettings *ces_src) +{ + BLI_strncpy_utf8(ces_dst->name, ces_src->name, sizeof(ces_dst->name)); + BLI_freelistN(&ces_dst->properties); + + for (CollectionEngineProperty *prop = ces_src->properties.first; prop; prop = prop->next) { + CollectionEngineProperty *prop_new = MEM_dupallocN(prop); + BLI_addtail(&ces_dst->properties, prop_new); + } +} + +/** + * Set a value from a CollectionProperty to another + */ +static void collection_engine_property_set (CollectionEngineProperty *prop_dst, CollectionEngineProperty *prop_src){ + if ((prop_src->flag & COLLECTION_PROP_USE) != 0) { + switch (prop_src->type) { + case COLLECTION_PROP_TYPE_FLOAT: + ((CollectionEnginePropertyFloat *)prop_dst)->value = ((CollectionEnginePropertyFloat *)prop_src)->value; + break; + case COLLECTION_PROP_TYPE_INT: + ((CollectionEnginePropertyInt *)prop_dst)->value = ((CollectionEnginePropertyInt *)prop_src)->value; + break; + default: + BLI_assert(false); + break; + } + } +} + +static void collection_engine_settings_merge(CollectionEngineSettings *ces_dst, CollectionEngineSettings *ces_src) +{ + CollectionEngineProperty *prop_src, *prop_dst; + + prop_dst = ces_dst->properties.first; + for (prop_src = ces_src->properties.first; prop_src; prop_src = prop_src->next, prop_dst = prop_dst->next) { + collection_engine_property_set(prop_dst, prop_src); + } +} + +static void layer_collection_engine_settings_update( + LayerCollection *lc, CollectionEngineSettings *ces_parent, + Object *ob, CollectionEngineSettings *ces_ob) +{ + if ((lc->flag & COLLECTION_VISIBLE) != 0) { + return; + } + + CollectionEngineSettings ces = {NULL}; + collection_engine_settings_copy(&ces, ces_parent); + + if (BLI_findptr(&lc->object_bases, ob, offsetof(LinkData, data)) != NULL) { + collection_engine_settings_merge(ces_ob, &ces); + } + + /* do it recursively */ + for (LayerCollection *lcn = lc->layer_collections.first; lcn; lcn = lcn->next) { + layer_collection_engine_settings_update(lcn, &ces, ob, ces_ob); + } + + BKE_layer_collection_engine_settings_free(&ces); +} + +/** + * Update the collection settings pointer allocated in the object + * This is to be flushed from the Depsgraph + */ +static void scene_layer_engine_settings_update(SceneLayer *sl, Object *ob, const char *engine_name) +{ + CollectionEngineSettings ces_layer = {NULL}, *ces_ob; + + collection_engine_settings_init(&ces_layer, engine_name); + + if (ob->collection_settings) { + BKE_layer_collection_engine_settings_free(ob->collection_settings); + MEM_freeN(ob->collection_settings); + } + + CollectionEngineSettingsCB_Type *ces_type; + ces_type = BLI_findstring(&R_engines_settings_callbacks, engine_name, offsetof(CollectionEngineSettingsCB_Type, name)); + ces_ob = collection_engine_settings_create(ces_type); + + for (LayerCollection *lc = sl->layer_collections.first; lc; lc = lc->next) { + layer_collection_engine_settings_update(lc, &ces_layer, ob, ces_ob); + } + + BKE_layer_collection_engine_settings_free(&ces_layer); + ob->collection_settings = ces_ob; +} + /* ---------------------------------------------------------------------- */ /* Iterators */ diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index 08cb9e57ab4..cc88254af3a 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -459,6 +459,11 @@ void BKE_object_free(Object *ob) } BKE_previewimg_free(&ob->preview); + + if (ob->collection_settings) { + BKE_layer_collection_engine_settings_free(ob->collection_settings); + MEM_freeN(ob->collection_settings); + } } /* actual check for internal data, not context or flags */ diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index 0ad879b9aa6..bc567edd7ad 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -1894,8 +1894,6 @@ static void write_objects(WriteData *wd, ListBase *idbase) writelist(wd, DATA, LinkData, &ob->pc_ids); writelist(wd, DATA, LodLevel, &ob->lodlevels); - - ob->collection_settings = NULL; } write_previews(wd, ob->preview); diff --git a/source/blender/draw/engines/clay/clay.c b/source/blender/draw/engines/clay/clay.c index f443606f11d..3a844d328f2 100644 --- a/source/blender/draw/engines/clay/clay.c +++ b/source/blender/draw/engines/clay/clay.c @@ -37,6 +37,8 @@ #ifdef WITH_CLAY_ENGINE /* Shaders */ +#define CLAY_ENGINE "BLENDER_CLAY" + extern char datatoc_clay_frag_glsl[]; extern char datatoc_clay_vert_glsl[]; extern char datatoc_ssao_alchemy_glsl[]; @@ -569,7 +571,7 @@ static void CLAY_create_cache(CLAY_PassList *passes, const struct bContext *C) /* TODO Create hash table of batch based on material id*/ Object *ob; - DEG_OBJECT_ITER(sl, ob) + DEG_OBJECT_ITER(sl, CLAY_ENGINE, ob); { if ((ob->base_flag & BASE_VISIBLED) == 0) { continue; @@ -715,8 +717,12 @@ void clay_engine_free(void) RenderEngineType viewport_clay_type = { NULL, NULL, - "BLENDER_CLAY", N_("Clay"), RE_INTERNAL | RE_USE_OGL_PIPELINE, + CLAY_ENGINE, N_("Clay"), RE_INTERNAL | RE_USE_OGL_PIPELINE, NULL, NULL, NULL, NULL, &CLAY_view_draw, NULL, &CLAY_collection_settings_create, {NULL, NULL, NULL} }; -#endif \ No newline at end of file + + +#undef CLAY_ENGINE + +#endif diff --git a/source/blender/makesdna/DNA_layer_types.h b/source/blender/makesdna/DNA_layer_types.h index 3a4293c8ad8..bd456b526c7 100644 --- a/source/blender/makesdna/DNA_layer_types.h +++ b/source/blender/makesdna/DNA_layer_types.h @@ -91,6 +91,7 @@ enum { BASE_VISIBLED = (1 << 1), BASE_SELECTABLED = (1 << 2), BASE_FROMDUPLI = (1 << 3), + BASE_DIRTY_ENGINE_SETTINGS = (1 << 4), }; /* LayerCollection->flag */ diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h index 080ade57c0d..b92d2cd1573 100644 --- a/source/blender/makesdna/DNA_object_types.h +++ b/source/blender/makesdna/DNA_object_types.h @@ -46,7 +46,7 @@ struct Object; struct AnimData; struct Ipo; struct BoundBox; -struct CollectionSettings; +struct CollectionEngineSettings; struct Path; struct Material; struct PartDeflect; @@ -304,7 +304,7 @@ typedef struct Object { struct PreviewImage *preview; - struct ListBase *collection_settings; /* used by depsgraph, flushed from collection-tree */ + struct CollectionEngineSettings *collection_settings; /* used by depsgraph, flushed from collection-tree */ } Object; /* Warning, this is not used anymore because hooks are now modifiers */ diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index ec9a08af287..2fb1fa9c8d6 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -2424,7 +2424,8 @@ RNA_LAYER_ENGINE_GET_SET_FLOAT(ssao_attenuation) static void rna_CollectionEngineSettings_update(bContext *C, PointerRNA *UNUSED(ptr)) { SceneLayer *sl = CTX_data_scene_layer(C); - BKE_scene_layer_engine_settings_recalculate(sl); + LayerCollection *lc = CTX_data_layer_collection(C); + BKE_scene_layer_engine_settings_collection_recalculate(sl, lc); } /***********************************/ @@ -2485,6 +2486,7 @@ static void rna_LayerCollection_hide_update(bContext *C, PointerRNA *ptr) /* hide and deselect bases that are directly influenced by this LayerCollection */ BKE_scene_layer_base_flag_recalculate(sl); + BKE_scene_layer_engine_settings_collection_recalculate(sl, lc); WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene); }