Layers: get/update CollectionEngineSettings (depsgraph placeholder)

Every time:
  * A collection settings is set
  * A collection visibility changes
  * An object is added/removed/ ...

We need to recalculate the "accumulated" CollectionEngineSettings that
the render engine should use for an object.

This is to be handled by the depsgraph. Meanwhile this code should allow
us to start using those settings in the render engines.

Note: We are storing this in the objects, which means we can only have
one active calculated option every time.

This is intended to get the conversation with the Depsgraph department
going.
This commit is contained in:
Dalai Felinto 2017-02-07 16:54:09 +01:00
parent 6bf9c8ac89
commit 6432c8cc00
9 changed files with 205 additions and 33 deletions

View File

@ -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_; \

View File

@ -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);

View File

@ -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 */

View File

@ -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 */

View File

@ -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);

View File

@ -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
#undef CLAY_ENGINE
#endif

View File

@ -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 */

View File

@ -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 */

View File

@ -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);
}