diff options
27 files changed, 598 insertions, 306 deletions
diff --git a/source/blender/blenkernel/BKE_layer.h b/source/blender/blenkernel/BKE_layer.h index 07d1c255188..9e7155cf482 100644 --- a/source/blender/blenkernel/BKE_layer.h +++ b/source/blender/blenkernel/BKE_layer.h @@ -44,6 +44,7 @@ extern "C" { #define ROOT_PROP "root" +struct EvaluationContext; struct LayerCollection; struct ID; struct IDProperty; @@ -72,12 +73,6 @@ struct SceneLayer *BKE_scene_layer_find_from_collection(const struct Scene *scen struct Base *BKE_scene_layer_base_find(struct SceneLayer *sl, struct Object *ob); void BKE_scene_layer_base_deselect_all(struct SceneLayer *sl); 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_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 Scene *scene, struct SceneLayer *sl); void BKE_layer_collection_free(struct SceneLayer *sl, struct LayerCollection *lc); @@ -129,6 +124,18 @@ void BKE_collection_engine_property_value_set_int(struct IDProperty *props, cons void BKE_collection_engine_property_value_set_float(struct IDProperty *props, const char *name, float value); void BKE_collection_engine_property_value_set_bool(struct IDProperty *props, const char *name, bool value); +/* evaluation */ + +void BKE_layer_eval_layer_collection_pre(struct EvaluationContext *eval_ctx, + struct Scene *scene, + struct SceneLayer *scene_layer); +void BKE_layer_eval_layer_collection(struct EvaluationContext *eval_ctx, + struct Scene *scene, + struct LayerCollection *layer_collection, + struct LayerCollection *parent_layer_collection); +void BKE_layer_eval_layer_collection_post(struct EvaluationContext *eval_ctx, + struct SceneLayer *scene_layer); + /* iterators */ void BKE_selected_objects_Iterator_begin(Iterator *iter, void *data_in); @@ -188,18 +195,18 @@ void BKE_visible_bases_Iterator_end(Iterator *iter); IteratorBeginCb func_begin; \ IteratorCb func_next, func_end; \ void *data_in; \ - \ + \ if (flag == SELECT) { \ - func_begin = &BKE_selected_objects_Iterator_begin; \ - func_next = &BKE_selected_objects_Iterator_next; \ - func_end = &BKE_selected_objects_Iterator_end; \ - data_in = (sl); \ + func_begin = &BKE_selected_objects_Iterator_begin; \ + func_next = &BKE_selected_objects_Iterator_next; \ + func_end = &BKE_selected_objects_Iterator_end; \ + data_in = (sl); \ } \ else { \ - func_begin = BKE_scene_objects_Iterator_begin; \ - func_next = BKE_scene_objects_Iterator_next; \ - func_end = BKE_scene_objects_Iterator_end; \ - data_in = (scene); \ + func_begin = BKE_scene_objects_Iterator_begin; \ + func_next = BKE_scene_objects_Iterator_next; \ + func_end = BKE_scene_objects_Iterator_end; \ + data_in = (scene); \ } \ ITER_BEGIN(func_begin, func_next, func_end, data_in, Object *, _instance) @@ -208,24 +215,20 @@ void BKE_visible_bases_Iterator_end(Iterator *iter); ITER_END \ } -/* temporary hacky solution waiting for final depsgraph evaluation */ -#define DEG_OBJECT_ITER(scene_, sl_, instance_) \ +/* temporary hacky solution waiting for CoW depsgraph implementation */ +#define DEG_OBJECT_ITER(sl_, instance_) \ { \ + /* flush all the depsgraph data to objects */ \ Object *instance_; \ - /* temporary solution, waiting for depsgraph update */ \ - BKE_scene_layer_engine_settings_update(scene_, sl_); \ - \ - /* flush all the data to objects*/ \ Base *base_; \ for (base_ = (sl_)->object_bases.first; base_; base_ = base_->next) { \ - if ((base_->flag & BASE_VISIBLED) == 0) { \ - continue; \ - } \ - \ - instance_ = base_->object; \ - instance_->base_flag = base_->flag; + if ((base_->flag & BASE_VISIBLED) != 0) { \ + instance_ = base_->object; \ + instance_->base_flag = base_->flag; \ + instance_->base_collection_properties = base_->collection_properties; #define DEG_OBJECT_ITER_END \ + } \ } \ } diff --git a/source/blender/blenkernel/intern/collection.c b/source/blender/blenkernel/intern/collection.c index b4662393151..b16162dfbc0 100644 --- a/source/blender/blenkernel/intern/collection.c +++ b/source/blender/blenkernel/intern/collection.c @@ -119,7 +119,6 @@ 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); @@ -165,7 +164,6 @@ bool BKE_collection_remove(Scene *scene, SceneCollection *sc) /* check all layers that use this collection and clear them */ for (SceneLayer *sl = scene->render_layers.first; sl; sl = sl->next) { layer_collection_remove(sl, &sl->layer_collections, sc); - BKE_scene_layer_base_flag_recalculate(sl); sl->active_collection = 0; } diff --git a/source/blender/blenkernel/intern/layer.c b/source/blender/blenkernel/intern/layer.c index 45ef1adc2e9..242ab9ae159 100644 --- a/source/blender/blenkernel/intern/layer.c +++ b/source/blender/blenkernel/intern/layer.c @@ -33,6 +33,8 @@ #include "BLT_translation.h" #include "BKE_collection.h" +#include "BKE_depsgraph.h" +#include "BKE_global.h" #include "BKE_idprop.h" #include "BKE_layer.h" #include "BKE_main.h" @@ -48,6 +50,8 @@ #include "MEM_guardedalloc.h" +#define DEBUG_PRINT if (G.debug & G_DEBUG_DEPSGRAPH) printf + /* prototype */ struct CollectionEngineSettingsCB_Type; static void layer_collection_free(SceneLayer *sl, LayerCollection *lc); @@ -56,7 +60,6 @@ static LayerCollection *find_layer_collection_by_scene_collection(LayerCollectio static IDProperty *collection_engine_settings_create(struct CollectionEngineSettingsCB_Type *ces_type, const bool populate); static IDProperty *collection_engine_get(IDProperty *root, const int type, const char *engine_name); static void collection_engine_settings_init(IDProperty *root, const bool populate); -static void scene_layer_engine_settings_update(Scene *scene, SceneLayer *sl, Object *ob); static void object_bases_Iterator_next(Iterator *iter, const int flag); /* RenderLayer */ @@ -145,6 +148,13 @@ bool BKE_scene_layer_remove(Main *bmain, Scene *scene, SceneLayer *sl) void BKE_scene_layer_free(SceneLayer *sl) { sl->basact = NULL; + + for (Base *base = sl->object_bases.first; base; base = base->next) { + if (base->collection_properties) { + IDP_FreeProperty(base->collection_properties); + MEM_freeN(base->collection_properties); + } + } BLI_freelistN(&sl->object_bases); for (LayerCollection *lc = sl->layer_collections.first; lc; lc = lc->next) { @@ -236,124 +246,14 @@ static void scene_layer_object_base_unref(SceneLayer *sl, Base *base) sl->basact = NULL; } - BLI_remlink(&sl->object_bases, base); - MEM_freeN(base); - } -} - -static void layer_collection_base_flag_recalculate( - LayerCollection *lc, const bool tree_is_visible, const bool tree_is_selectable) -{ - bool is_visible = tree_is_visible && ((lc->flag & COLLECTION_VISIBLE) != 0); - /* an object can only be selected if it's visible */ - bool is_selectable = tree_is_selectable && is_visible && ((lc->flag & COLLECTION_SELECTABLE) != 0); - - for (LinkData *link = lc->object_bases.first; link; link = link->next) { - Base *base = link->data; - - if (is_visible) { - base->flag |= BASE_VISIBLED; - } - - if (is_selectable) { - base->flag |= BASE_SELECTABLED; - } - } - - for (LayerCollection *lcn = lc->layer_collections.first; lcn; lcn = lcn->next) { - layer_collection_base_flag_recalculate(lcn, is_visible, is_selectable); - } -} - -/** - * Re-evaluate the ObjectBase flags for SceneLayer - */ -void BKE_scene_layer_base_flag_recalculate(SceneLayer *sl) -{ - for (Base *base = sl->object_bases.first; base; base = base->next) { - base->flag &= ~(BASE_VISIBLED | BASE_SELECTABLED); - } - - for (LayerCollection *lc = sl->layer_collections.first; lc; lc = lc->next) { - layer_collection_base_flag_recalculate(lc, true, true); - } - - /* if base is not selectabled, clear select */ - for (Base *base = sl->object_bases.first; base; base = base->next) { - if ((base->flag & BASE_SELECTABLED) == 0) { - base->flag &= ~BASE_SELECTED; + if (base->collection_properties) { + IDP_FreeProperty(base->collection_properties); + MEM_freeN(base->collection_properties); } - } -} - -/** - * Tag Scene Layer to recalculation - * - * Temporary function, waiting for real depsgraph - */ -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); - } -} -/** - * Re-calculate the engine settings for all the objects in SceneLayer - * - * Temporary function, waiting for real depsgraph - */ -void BKE_scene_layer_engine_settings_update(struct Scene *scene, struct SceneLayer *sl) -{ - if ((sl->flag & SCENE_LAYER_ENGINE_DIRTY) == 0) { - return; - } - - /* do the complete settings update */ - 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(scene, sl, base->object); - base->flag &= ~BASE_DIRTY_ENGINE_SETTINGS; - } + BLI_remlink(&sl->object_bases, base); + MEM_freeN(base); } - - sl->flag &= ~SCENE_LAYER_ENGINE_DIRTY; } /** @@ -371,7 +271,11 @@ static Base *object_base_add(SceneLayer *sl, Object *ob) /* do not bump user count, leave it for SceneCollections */ base->object = ob; BLI_addtail(&sl->object_bases, base); + + IDPropertyTemplate val = {0}; + base->collection_properties = IDP_New(IDP_GROUP, &val, ROOT_PROP); } + base->refcount++; return base; } @@ -398,6 +302,11 @@ static void layer_collection_free(SceneLayer *sl, LayerCollection *lc) MEM_freeN(lc->properties); } + if (lc->properties_evaluated) { + IDP_FreeProperty(lc->properties_evaluated); + MEM_freeN(lc->properties_evaluated); + } + for (LayerCollection *nlc = lc->layer_collections.first; nlc; nlc = nlc->next) { layer_collection_free(sl, nlc); } @@ -858,9 +767,6 @@ LayerCollection *BKE_collection_link(SceneLayer *sl, SceneCollection *sc) 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); sl->active_collection = 0; @@ -879,8 +785,15 @@ 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); + if ((lc->flag_evaluated & COLLECTION_VISIBLE) != 0) { + base->flag |= BASE_VISIBLED; + + if ((lc->flag_evaluated & COLLECTION_SELECTABLE) != 0) { + base->flag |= BASE_SELECTABLED; + } + + IDP_SyncGroupValues(base->collection_properties, lc->properties_evaluated); + } } static void layer_collection_object_remove(SceneLayer *sl, LayerCollection *lc, Object *ob) @@ -1020,8 +933,6 @@ void BKE_layer_sync_object_unlink(const Scene *scene, SceneCollection *sc, Objec layer_collection_object_remove(sl, found, ob); } } - BKE_scene_layer_base_flag_recalculate(sl); - BKE_scene_layer_engine_settings_object_recalculate(sl, ob); } } @@ -1237,7 +1148,7 @@ static IDProperty *collection_engine_get( */ IDProperty *BKE_object_collection_engine_get(Object *ob, const int type, const char *engine_name) { - return collection_engine_get(ob->collection_properties, type, engine_name); + return collection_engine_get(ob->base_collection_properties, type, engine_name); } /** * Return layer collection engine settings for specified engine @@ -1328,72 +1239,6 @@ void BKE_layer_collection_engine_settings_create(IDProperty *root) collection_engine_settings_init(root, true); } -static void collection_engine_settings_copy(IDProperty *props_dst, IDProperty *props_src) -{ - IDP_MergeGroup(props_dst, props_src, true); -} - -static void collection_engine_settings_merge(IDProperty *props_dst, IDProperty *props_src) -{ - IDP_SyncGroupValues(props_dst, props_src); -} - -static void layer_collection_engine_settings_update( - LayerCollection *lc, IDProperty *props_parent, - Base *base, IDProperty *props_object) -{ - if ((lc->flag & COLLECTION_VISIBLE) == 0) { - return; - } - - IDPropertyTemplate val = {0}; - IDProperty *props_collection = IDP_New(IDP_GROUP, &val, ROOT_PROP); - collection_engine_settings_copy(props_collection, props_parent); - - collection_engine_settings_merge(props_collection, lc->properties); - - if (BLI_findptr(&lc->object_bases, base, offsetof(LinkData, data)) != NULL) { - collection_engine_settings_merge(props_object, props_collection); - } - - /* do it recursively */ - for (LayerCollection *lcn = lc->layer_collections.first; lcn; lcn = lcn->next) { - layer_collection_engine_settings_update(lcn, props_collection, base, props_object); - } - - IDP_FreeProperty(props_collection); - MEM_freeN(props_collection); -} - -/** - * Update the collection settings pointer allocated in the object - * This is to be flushed from the Depsgraph - */ -static void scene_layer_engine_settings_update(Scene *scene, SceneLayer *sl, Object *ob) -{ - Base *base = BKE_scene_layer_base_find(sl, ob); - IDPropertyTemplate val = {0}; - - IDProperty *layer_properties = IDP_New(IDP_GROUP, &val, ROOT_PROP); - collection_engine_settings_copy(layer_properties, scene->collection_properties); - - /* start fresh */ - if (ob->collection_properties) { - IDP_FreeProperty(ob->collection_properties); - MEM_freeN(ob->collection_properties); - } - - ob->collection_properties = IDP_New(IDP_GROUP, &val, ROOT_PROP); - collection_engine_settings_copy(ob->collection_properties, scene->collection_properties); - - for (LayerCollection *lc = sl->layer_collections.first; lc; lc = lc->next) { - layer_collection_engine_settings_update(lc, layer_properties, base, ob->collection_properties); - } - - IDP_FreeProperty(layer_properties); - MEM_freeN(layer_properties); -} - /* ---------------------------------------------------------------------- */ /* Iterators */ @@ -1498,3 +1343,100 @@ void BKE_visible_bases_Iterator_end(Iterator *UNUSED(iter)) { /* do nothing */ } + +/* Evaluation */ + +/** + * Reset props + * + * If props_ref is pasted, copy props from it + */ +static void idproperty_reset(IDProperty **props, IDProperty *props_ref) +{ + IDPropertyTemplate val = {0}; + + if (*props) { + IDP_FreeProperty(*props); + MEM_freeN(*props); + } + *props = IDP_New(IDP_GROUP, &val, ROOT_PROP); + + if (props_ref) { + IDP_MergeGroup(*props, props_ref, true); + } +} + +void BKE_layer_eval_layer_collection_pre(EvaluationContext *UNUSED(eval_ctx), + Scene *scene, SceneLayer *scene_layer) +{ + DEBUG_PRINT("%s on %s\n", __func__, scene_layer->name); + for (Base *base = scene_layer->object_bases.first; base != NULL; base = base->next) { + base->flag &= ~(BASE_VISIBLED | BASE_SELECTABLED); + idproperty_reset(&base->collection_properties, scene->collection_properties); + } + + /* TODO(sergey): Is it always required? */ + scene_layer->flag |= SCENE_LAYER_ENGINE_DIRTY; +} + +void BKE_layer_eval_layer_collection(EvaluationContext *UNUSED(eval_ctx), + Scene *scene, + LayerCollection *layer_collection, + LayerCollection *parent_layer_collection) +{ + DEBUG_PRINT("%s on %s, parent %s\n", + __func__, + layer_collection->scene_collection->name, + (parent_layer_collection != NULL) ? parent_layer_collection->scene_collection->name : "NONE"); + + /* visibility */ + layer_collection->flag_evaluated = layer_collection->flag; + bool is_visible = (layer_collection->flag & COLLECTION_VISIBLE) != 0; + bool is_selectable = is_visible && ((layer_collection->flag & COLLECTION_SELECTABLE) != 0); + + if (parent_layer_collection != NULL) { + is_visible &= (parent_layer_collection->flag_evaluated & COLLECTION_VISIBLE) != 0; + is_selectable &= (parent_layer_collection->flag_evaluated & COLLECTION_SELECTABLE) != 0; + layer_collection->flag_evaluated &= parent_layer_collection->flag_evaluated; + } + + /* overrides */ + if (parent_layer_collection != NULL) { + idproperty_reset(&layer_collection->properties_evaluated, parent_layer_collection->properties_evaluated); + } + else if (layer_collection->prev != NULL) { + idproperty_reset(&layer_collection->properties_evaluated, NULL); + } + else { + idproperty_reset(&layer_collection->properties_evaluated, scene->collection_properties); + } + + if (is_visible) { + IDP_MergeGroup(layer_collection->properties_evaluated, layer_collection->properties, true); + } + + for (LinkData *link = layer_collection->object_bases.first; link != NULL; link = link->next) { + Base *base = link->data; + + if (is_visible) { + IDP_SyncGroupValues(base->collection_properties, layer_collection->properties_evaluated); + base->flag |= BASE_VISIBLED; + } + + if (is_selectable) { + base->flag |= BASE_SELECTABLED; + } + } +} + +void BKE_layer_eval_layer_collection_post(EvaluationContext *UNUSED(eval_ctx), + SceneLayer *scene_layer) +{ + DEBUG_PRINT("%s on %s\n", __func__, scene_layer->name); + /* if base is not selectabled, clear select */ + for (Base *base = scene_layer->object_bases.first; base; base = base->next) { + if ((base->flag & BASE_SELECTABLED) == 0) { + base->flag &= ~BASE_SELECTED; + } + } +} diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index 0b427a3cf9d..8b306a9ae14 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -460,10 +460,8 @@ void BKE_object_free(Object *ob) BKE_previewimg_free(&ob->preview); - if (ob->collection_properties) { - IDP_FreeProperty(ob->collection_properties); - MEM_freeN(ob->collection_properties); - } + /* don't free, let the base free it */ + ob->base_collection_properties = NULL; } /* actual check for internal data, not context or flags */ @@ -1192,12 +1190,6 @@ Object *BKE_object_copy_ex(Main *bmain, Object *ob, bool copy_caches) /* Do not copy object's preview (mostly due to the fact renderers create temp copy of objects). */ obn->preview = NULL; - if (ob->collection_properties) { - IDPropertyTemplate val = {0}; - obn->collection_properties = IDP_New(IDP_GROUP, &val, ROOT_PROP); - IDP_MergeGroup(obn->collection_properties, ob->collection_properties, true); - } - return obn; } diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 88d7424a278..2c9d1a47320 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -5604,8 +5604,7 @@ static void direct_link_object(FileData *fd, Object *ob) ob->preview = direct_link_preview_image(fd, ob->preview); - ob->collection_properties = newdataadr(fd, ob->collection_properties); - IDP_DirectLinkGroup_OrFree(&ob->collection_properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd); + ob->base_collection_properties = NULL; } /* ************ READ SCENE ***************** */ @@ -5840,6 +5839,7 @@ static void lib_link_scene(FileData *fd, Main *main) /* we only bump the use count for the collection objects */ base->object = newlibadr(fd, sce->id.lib, base->object); base->flag |= BASE_DIRTY_ENGINE_SETTINGS; + base->collection_properties = NULL; } } @@ -5975,6 +5975,7 @@ static void direct_link_layer_collections(FileData *fd, ListBase *lb) lc->properties = newdataadr(fd, lc->properties); IDP_DirectLinkGroup_OrFree(&lc->properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd); } + lc->properties_evaluated = NULL; direct_link_layer_collections(fd, &lc->layer_collections); } @@ -6250,8 +6251,6 @@ static void direct_link_scene(FileData *fd, Scene *sce) link_list(fd, &sl->object_bases); sl->basact = newdataadr(fd, sl->basact); direct_link_layer_collections(fd, &sl->layer_collections); - /* tag scene layer to update for collection tree evaluation */ - BKE_scene_layer_base_flag_recalculate(sl); } sce->collection_properties = newdataadr(fd, sce->collection_properties); diff --git a/source/blender/blenloader/intern/versioning_280.c b/source/blender/blenloader/intern/versioning_280.c index c93e11a6231..58724459a45 100644 --- a/source/blender/blenloader/intern/versioning_280.c +++ b/source/blender/blenloader/intern/versioning_280.c @@ -139,9 +139,6 @@ void do_versions_after_linking_280(Main *main) lc = lc->next; } - /* but we still need to make the flags synced */ - BKE_scene_layer_base_flag_recalculate(sl); - /* convert active base */ if (scene->basact) { sl->basact = BKE_scene_layer_base_find(sl, scene->basact->object); @@ -217,10 +214,6 @@ void do_versions_after_linking_280(Main *main) scene->collection_properties = IDP_New(IDP_GROUP, &val, ROOT_PROP); BKE_layer_collection_engine_settings_create(scene->collection_properties); } - - for (Object *ob = main->object.first; ob; ob = ob->id.next) { - ob->collection_properties = IDP_New(IDP_GROUP, &val, ROOT_PROP); - } } } diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index d5fa4204602..6550ad9a2fd 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -1921,10 +1921,6 @@ static void write_object(WriteData *wd, Object *ob) writelist(wd, DATA, LodLevel, &ob->lodlevels); write_previews(wd, ob->preview); - - if (ob->collection_properties) { - IDP_WriteProperty(ob->collection_properties, wd); - } } } diff --git a/source/blender/depsgraph/CMakeLists.txt b/source/blender/depsgraph/CMakeLists.txt index 2d32e85bf64..a266f30fe11 100644 --- a/source/blender/depsgraph/CMakeLists.txt +++ b/source/blender/depsgraph/CMakeLists.txt @@ -43,11 +43,13 @@ set(SRC intern/builder/deg_builder.cc intern/builder/deg_builder_cycle.cc intern/builder/deg_builder_nodes.cc + intern/builder/deg_builder_nodes_layer.cc intern/builder/deg_builder_nodes_rig.cc intern/builder/deg_builder_nodes_scene.cc intern/builder/deg_builder_pchanmap.cc intern/builder/deg_builder_relations.cc intern/builder/deg_builder_relations_keys.cc + intern/builder/deg_builder_relations_layer.cc intern/builder/deg_builder_relations_rig.cc intern/builder/deg_builder_relations_scene.cc intern/builder/deg_builder_transitive.cc diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.h b/source/blender/depsgraph/intern/builder/deg_builder_nodes.h index c9d1d7dd0f8..d28aaf6a10a 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.h +++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.h @@ -41,6 +41,7 @@ struct Image; struct FCurve; struct Group; struct Key; +struct LayerCollection; struct Main; struct Material; struct Mask; @@ -161,6 +162,17 @@ struct DepsgraphNodeBuilder { void build_mask(Mask *mask); void build_movieclip(MovieClip *clip); + struct LayerCollectionState { + int index; + LayerCollection *parent; + }; + void build_layer_collection(Scene *scene, + LayerCollection *layer_collection, + LayerCollectionState *state); + void build_layer_collections(Scene *scene, + ListBase *layer_collections, + LayerCollectionState *state); + void build_scene_layer_collections(Scene *scene); protected: Main *m_bmain; Depsgraph *m_graph; diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes_layer.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes_layer.cc new file mode 100644 index 00000000000..494ae585272 --- /dev/null +++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes_layer.cc @@ -0,0 +1,121 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2013 Blender Foundation. + * All rights reserved. + * + * Original Author: Joshua Leung + * Contributor(s): Based on original depsgraph.c code - Blender Foundation (2005-2013) + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/depsgraph/intern/builder/deg_builder_nodes_scene.cc + * \ingroup depsgraph + * + * Methods for constructing depsgraph's nodes + */ + +#include "intern/builder/deg_builder_nodes.h" + +#include <stdio.h> +#include <stdlib.h> + +#include "MEM_guardedalloc.h" + +extern "C" { +#include "BLI_utildefines.h" + +#include "BKE_layer.h" + +#include "DNA_scene_types.h" + +#include "DEG_depsgraph.h" +#include "DEG_depsgraph_build.h" +} /* extern "C" */ + +#include "intern/builder/deg_builder.h" +#include "intern/nodes/deg_node.h" +#include "intern/nodes/deg_node_component.h" +#include "intern/nodes/deg_node_operation.h" +#include "intern/depsgraph_types.h" +#include "intern/depsgraph_intern.h" +#include "util/deg_util_foreach.h" + +namespace DEG { + +void DepsgraphNodeBuilder::build_layer_collection(Scene *scene, + LayerCollection *layer_collection, + LayerCollectionState *state) +{ + /* TODO(sergey): This will attempt to create component for each collection. + * Harmless but could be optimized. + */ + ComponentDepsNode *comp = add_component_node(&scene->id, DEPSNODE_TYPE_LAYER_COLLECTIONS); + + add_operation_node(comp, + DEPSOP_TYPE_EXEC, + function_bind(BKE_layer_eval_layer_collection, + _1, + scene, + layer_collection, + state->parent), + DEG_OPCODE_SCENE_LAYER_EVAL, + layer_collection->scene_collection->name, + state->index); + ++state->index; + + /* Recurs into nested layer collections. */ + LayerCollection *parent = state->parent; + state->parent = layer_collection; + build_layer_collections(scene, &layer_collection->layer_collections, state); + state->parent = parent; +} + +void DepsgraphNodeBuilder::build_layer_collections(Scene *scene, + ListBase *layer_collections, + LayerCollectionState *state) +{ + LINKLIST_FOREACH (LayerCollection *, layer_collection, layer_collections) { + build_layer_collection(scene, layer_collection, state); + } +} + +void DepsgraphNodeBuilder::build_scene_layer_collections(Scene *scene) +{ + LayerCollectionState state; + state.index = 0; + LINKLIST_FOREACH (SceneLayer *, scene_layer, &scene->render_layers) { + ComponentDepsNode *comp = add_component_node(&scene->id, DEPSNODE_TYPE_LAYER_COLLECTIONS); + + add_operation_node(comp, + DEPSOP_TYPE_EXEC, + function_bind(BKE_layer_eval_layer_collection_pre, _1, scene, scene_layer), + DEG_OPCODE_SCENE_LAYER_INIT, + scene_layer->name); + add_operation_node(comp, + DEPSOP_TYPE_EXEC, + function_bind(BKE_layer_eval_layer_collection_post, _1, scene_layer), + DEG_OPCODE_SCENE_LAYER_DONE, + scene_layer->name); + + state.parent = NULL; + build_layer_collections(scene, &scene_layer->layer_collections, &state); + } +} + +} // namespace DEG diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes_scene.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes_scene.cc index 2141f7f6499..3f9febc1228 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_nodes_scene.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes_scene.cc @@ -129,6 +129,9 @@ void DepsgraphNodeBuilder::build_scene(Main *bmain, Scene *scene) LINKLIST_FOREACH (MovieClip *, clip, &bmain->movieclip) { build_movieclip(clip); } + + /* Collections. */ + build_scene_layer_collections(scene); } } // namespace DEG diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.h b/source/blender/depsgraph/intern/builder/deg_builder_relations.h index 07700b5c267..557f2dd36b8 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.h +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.h @@ -54,6 +54,7 @@ struct ID; struct FCurve; struct Group; struct Key; +struct LayerCollection; struct Main; struct Mask; struct Material; @@ -234,6 +235,20 @@ struct DepsgraphRelationBuilder void add_collision_relations(const OperationKey &key, Scene *scene, Object *ob, Group *group, int layer, bool dupli, const char *name); void add_forcefield_relations(const OperationKey &key, Scene *scene, Object *ob, ParticleSystem *psys, EffectorWeights *eff, bool add_absorption, const char *name); + struct LayerCollectionState { + int index; + OperationKey init_key; + OperationKey done_key; + OperationKey prev_key; + }; + void build_layer_collection(Scene *scene, + LayerCollection *layer_collection, + LayerCollectionState *state); + void build_layer_collections(Scene *scene, + ListBase *layer_collections, + LayerCollectionState *state); + void build_scene_layer_collections(Scene *scene); + template <typename KeyType> OperationDepsNode *find_operation_node(const KeyType &key); diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations_layer.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations_layer.cc new file mode 100644 index 00000000000..46bef7a0131 --- /dev/null +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations_layer.cc @@ -0,0 +1,134 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2013 Blender Foundation. + * All rights reserved. + * + * Original Author: Joshua Leung + * Contributor(s): Based on original depsgraph.c code - Blender Foundation (2005-2013) + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/depsgraph/intern/builder/deg_builder_relations_scene.cc + * \ingroup depsgraph + * + * Methods for constructing depsgraph + */ + +#include "intern/builder/deg_builder_relations.h" + +#include <stdio.h> +#include <stdlib.h> +#include <cstring> /* required for STREQ later on. */ + +#include "MEM_guardedalloc.h" + +extern "C" { +#include "BLI_blenlib.h" +#include "BLI_utildefines.h" + +#include "DNA_node_types.h" +#include "DNA_object_types.h" +#include "DNA_scene_types.h" + +#include "BKE_layer.h" +#include "BKE_main.h" +#include "BKE_node.h" + +#include "DEG_depsgraph.h" +#include "DEG_depsgraph_build.h" +} /* extern "C" */ + +#include "intern/builder/deg_builder.h" +#include "intern/builder/deg_builder_pchanmap.h" + +#include "intern/nodes/deg_node.h" +#include "intern/nodes/deg_node_component.h" +#include "intern/nodes/deg_node_operation.h" + +#include "intern/depsgraph_intern.h" +#include "intern/depsgraph_types.h" + +#include "util/deg_util_foreach.h" + +namespace DEG { + +void DepsgraphRelationBuilder::build_layer_collection(Scene *scene, + LayerCollection *layer_collection, + LayerCollectionState *state) +{ + OperationKey layer_key(&scene->id, + DEPSNODE_TYPE_LAYER_COLLECTIONS, + DEG_OPCODE_SCENE_LAYER_EVAL, + layer_collection->scene_collection->name, + state->index); + add_relation(state->prev_key, + layer_key, + DEPSREL_TYPE_OPERATION, + "Layer collection order"); + + ++state->index; + state->prev_key = layer_key; + + /* Recurs into nested layer collections. */ + build_layer_collections(scene, + &layer_collection->layer_collections, + state); +} + +void DepsgraphRelationBuilder::build_layer_collections(Scene *scene, + ListBase *layer_collections, + LayerCollectionState *state) +{ + LINKLIST_FOREACH (LayerCollection *, layer_collection, layer_collections) { + /* Recurs into the layer. */ + build_layer_collection(scene, layer_collection, state); + } +} + +void DepsgraphRelationBuilder::build_scene_layer_collections(Scene *scene) +{ + LayerCollectionState state; + state.index = 0; + LINKLIST_FOREACH (SceneLayer *, scene_layer, &scene->render_layers) { + OperationKey init_key(&scene->id, + DEPSNODE_TYPE_LAYER_COLLECTIONS, + DEG_OPCODE_SCENE_LAYER_INIT, + scene_layer->name); + OperationKey done_key(&scene->id, + DEPSNODE_TYPE_LAYER_COLLECTIONS, + DEG_OPCODE_SCENE_LAYER_DONE, + scene_layer->name); + + state.init_key = init_key; + state.done_key = done_key; + state.prev_key = init_key; + + build_layer_collections(scene, + &scene_layer->layer_collections, + &state); + + + add_relation(state.prev_key, + done_key, + DEPSREL_TYPE_OPERATION, + "Layer collection order"); + } +} + +} // namespace DEG diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations_scene.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations_scene.cc index 2e2182609d5..3a007c4153a 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations_scene.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations_scene.cc @@ -116,6 +116,9 @@ void DepsgraphRelationBuilder::build_scene(Main *bmain, Scene *scene) build_movieclip(clip); } + /* Collections. */ + build_scene_layer_collections(scene); + for (Depsgraph::OperationNodes::const_iterator it_op = m_graph->operations.begin(); it_op != m_graph->operations.end(); ++it_op) diff --git a/source/blender/depsgraph/intern/debug/deg_debug_graphviz.cc b/source/blender/depsgraph/intern/debug/deg_debug_graphviz.cc index 0d56ce71c7d..d49d5e1b000 100644 --- a/source/blender/depsgraph/intern/debug/deg_debug_graphviz.cc +++ b/source/blender/depsgraph/intern/debug/deg_debug_graphviz.cc @@ -83,15 +83,16 @@ static const int deg_debug_node_type_color_map[][2] = { {DEPSNODE_TYPE_SUBGRAPH, 3}, /* Outer Types */ - {DEPSNODE_TYPE_PARAMETERS, 4}, - {DEPSNODE_TYPE_PROXY, 5}, - {DEPSNODE_TYPE_ANIMATION, 6}, - {DEPSNODE_TYPE_TRANSFORM, 7}, - {DEPSNODE_TYPE_GEOMETRY, 8}, - {DEPSNODE_TYPE_SEQUENCER, 9}, - {DEPSNODE_TYPE_SHADING, 10}, - {DEPSNODE_TYPE_CACHE, 11}, - {-1, 0} + {DEPSNODE_TYPE_PARAMETERS, 4}, + {DEPSNODE_TYPE_PROXY, 5}, + {DEPSNODE_TYPE_ANIMATION, 6}, + {DEPSNODE_TYPE_TRANSFORM, 7}, + {DEPSNODE_TYPE_GEOMETRY, 8}, + {DEPSNODE_TYPE_SEQUENCER, 9}, + {DEPSNODE_TYPE_SHADING, 10}, + {DEPSNODE_TYPE_CACHE, 11}, + {DEPSNODE_TYPE_LAYER_COLLECTIONS, 12}, + {-1, 0} }; #endif @@ -403,6 +404,7 @@ static void deg_debug_graphviz_node(const DebugContext &ctx, case DEPSNODE_TYPE_BONE: case DEPSNODE_TYPE_SHADING: case DEPSNODE_TYPE_CACHE: + case DEPSNODE_TYPE_LAYER_COLLECTIONS: case DEPSNODE_TYPE_EVAL_PARTICLES: { ComponentDepsNode *comp_node = (ComponentDepsNode *)node; diff --git a/source/blender/depsgraph/intern/depsgraph_type_defines.cc b/source/blender/depsgraph/intern/depsgraph_type_defines.cc index 39c189629f2..6c3e3805169 100644 --- a/source/blender/depsgraph/intern/depsgraph_type_defines.cc +++ b/source/blender/depsgraph/intern/depsgraph_type_defines.cc @@ -130,6 +130,10 @@ static const char *stringify_opcode(eDepsOperation_Code opcode) STRINGIFY_OPCODE(BONE_DONE); STRINGIFY_OPCODE(PSYS_EVAL); + STRINGIFY_OPCODE(SCENE_LAYER_INIT); + STRINGIFY_OPCODE(SCENE_LAYER_EVAL); + STRINGIFY_OPCODE(SCENE_LAYER_DONE); + case DEG_NUM_OPCODES: return "SpecialCase"; #undef STRINGIFY_OPCODE } diff --git a/source/blender/depsgraph/intern/depsgraph_types.h b/source/blender/depsgraph/intern/depsgraph_types.h index c9c4329769d..6b9a6e0191e 100644 --- a/source/blender/depsgraph/intern/depsgraph_types.h +++ b/source/blender/depsgraph/intern/depsgraph_types.h @@ -135,6 +135,8 @@ typedef enum eDepsNode_Type { DEPSNODE_TYPE_SHADING, /* Cache Component */ DEPSNODE_TYPE_CACHE, + /* Component which contains all operations needed for layer collections evaluation. */ + DEPSNODE_TYPE_LAYER_COLLECTIONS, } eDepsNode_Type; /* Identifiers for common operations (as an enum). */ @@ -243,6 +245,11 @@ typedef enum eDepsOperation_Code { /* XXX: placeholder - Particle System eval */ DEG_OPCODE_PSYS_EVAL, + /* Collections ------------------------------------- */ + DEG_OPCODE_SCENE_LAYER_INIT, + DEG_OPCODE_SCENE_LAYER_EVAL, + DEG_OPCODE_SCENE_LAYER_DONE, + DEG_NUM_OPCODES, } eDepsOperation_Code; diff --git a/source/blender/depsgraph/intern/nodes/deg_node_component.cc b/source/blender/depsgraph/intern/nodes/deg_node_component.cc index 06f91ac7fdc..9549cbcfeef 100644 --- a/source/blender/depsgraph/intern/nodes/deg_node_component.cc +++ b/source/blender/depsgraph/intern/nodes/deg_node_component.cc @@ -406,6 +406,11 @@ static DepsNodeFactoryImpl<ShadingComponentDepsNode> DNTI_SHADING; DEG_DEPSNODE_DEFINE(CacheComponentDepsNode, DEPSNODE_TYPE_CACHE, "Cache Component"); static DepsNodeFactoryImpl<CacheComponentDepsNode> DNTI_CACHE; +/* Layer COllections Defines ============================ */ + +DEG_DEPSNODE_DEFINE(LayerCollectionsDepsNode, DEPSNODE_TYPE_LAYER_COLLECTIONS, "Layer Collections Component"); +static DepsNodeFactoryImpl<LayerCollectionsDepsNode> DNTI_LAYER_COLLECTIONS; + /* Node Types Register =================================== */ @@ -425,6 +430,8 @@ void deg_register_component_depsnodes() deg_register_node_typeinfo(&DNTI_SHADING); deg_register_node_typeinfo(&DNTI_CACHE); + + deg_register_node_typeinfo(&DNTI_LAYER_COLLECTIONS); } } // namespace DEG diff --git a/source/blender/depsgraph/intern/nodes/deg_node_component.h b/source/blender/depsgraph/intern/nodes/deg_node_component.h index 969771a29c9..bb94401562d 100644 --- a/source/blender/depsgraph/intern/nodes/deg_node_component.h +++ b/source/blender/depsgraph/intern/nodes/deg_node_component.h @@ -201,6 +201,10 @@ struct CacheComponentDepsNode : public ComponentDepsNode { DEG_DEPSNODE_DECLARE; }; +struct LayerCollectionsDepsNode : public ComponentDepsNode { + DEG_DEPSNODE_DECLARE; +}; + void deg_register_component_depsnodes(); diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c index 65fd77a5155..34cd1e7e7c4 100644 --- a/source/blender/draw/intern/draw_manager.c +++ b/source/blender/draw/intern/draw_manager.c @@ -1721,11 +1721,10 @@ void DRW_draw_view(const bContext *C) /* ideally only refresh when objects are added/removed */ /* or render properties / materials change */ if (cache_is_dirty) { - Scene *scene = CTX_data_scene(C); SceneLayer *sl = CTX_data_scene_layer(C); DRW_engines_cache_init(); - DEG_OBJECT_ITER(scene, sl, ob); + DEG_OBJECT_ITER(sl, ob); { DRW_engines_cache_populate(ob); } diff --git a/source/blender/editors/render/render_shading.c b/source/blender/editors/render/render_shading.c index 490182b17ed..b58bd43a35e 100644 --- a/source/blender/editors/render/render_shading.c +++ b/source/blender/editors/render/render_shading.c @@ -631,6 +631,7 @@ static int render_layer_add_exec(bContext *C, wmOperator *UNUSED(op)) scene->active_layer = BLI_listbase_count(&scene->render_layers) - 1; DAG_id_tag_update(&scene->id, 0); + DAG_relations_tag_update(CTX_data_main(C)); WM_event_add_notifier(C, NC_SCENE | ND_LAYER, scene); return OPERATOR_FINISHED; @@ -660,6 +661,7 @@ static int render_layer_remove_exec(bContext *C, wmOperator *UNUSED(op)) } DAG_id_tag_update(&scene->id, 0); + DAG_relations_tag_update(CTX_data_main(C)); WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene); return OPERATOR_FINISHED; diff --git a/source/blender/editors/space_outliner/outliner_collections.c b/source/blender/editors/space_outliner/outliner_collections.c index c5cfd47486f..e9c49ffdb14 100644 --- a/source/blender/editors/space_outliner/outliner_collections.c +++ b/source/blender/editors/space_outliner/outliner_collections.c @@ -26,6 +26,7 @@ #include "BKE_context.h" #include "BKE_collection.h" +#include "BKE_depsgraph.h" #include "BKE_layer.h" #include "BKE_report.h" @@ -120,6 +121,7 @@ static int collection_link_exec(bContext *C, wmOperator *op) BKE_collection_link(sl, sc); + DAG_relations_tag_update(CTX_data_main(C)); WM_main_add_notifier(NC_SCENE | ND_LAYER, NULL); return OPERATOR_FINISHED; } @@ -217,6 +219,7 @@ static int collection_unlink_exec(bContext *C, wmOperator *op) SceneLayer *sl = CTX_data_scene_layer(C); BKE_collection_unlink(sl, lc); + DAG_relations_tag_update(CTX_data_main(C)); WM_main_add_notifier(NC_SCENE | ND_LAYER, NULL); return OPERATOR_FINISHED; } @@ -244,6 +247,7 @@ static int collection_new_exec(bContext *C, wmOperator *UNUSED(op)) SceneCollection *sc = BKE_collection_add(scene, NULL, NULL); BKE_collection_link(sl, sc); + DAG_relations_tag_update(CTX_data_main(C)); WM_main_add_notifier(NC_SCENE | ND_LAYER, NULL); return OPERATOR_FINISHED; } @@ -342,6 +346,7 @@ static int collection_delete_exec(bContext *C, wmOperator *UNUSED(op)) TODO_LAYER_OVERRIDE; /* handle overrides */ outliner_tree_traverse(soops, &soops->tree, 0, TSE_SELECTED, collection_delete_cb, &data); + DAG_relations_tag_update(CTX_data_main(C)); WM_main_add_notifier(NC_SCENE | ND_LAYER, NULL); return OPERATOR_FINISHED; diff --git a/source/blender/editors/space_outliner/outliner_draw.c b/source/blender/editors/space_outliner/outliner_draw.c index 5d1323bbdd8..cbfe0828103 100644 --- a/source/blender/editors/space_outliner/outliner_draw.c +++ b/source/blender/editors/space_outliner/outliner_draw.c @@ -245,15 +245,13 @@ static void restrictbutton_gp_layer_flag_cb(bContext *C, void *UNUSED(poin), voi WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL); } -static void restrictbutton_collection_hide_cb(bContext *C, void *poin, void *poin2) +static void restrictbutton_collection_hide_cb(bContext *C, void *poin, void *UNUSED(poin2)) { Scene *scene = poin; - LayerCollection *collection = poin2; - SceneLayer *sl = BKE_scene_layer_find_from_collection(scene, collection); /* 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, collection); + /* TODO(sergey): Use proper flag for tagging here. */ + DAG_id_tag_update(&scene->id, 0); WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene); WM_event_add_notifier(C, NC_SCENE | ND_LAYER_CONTENT, NULL); } @@ -264,10 +262,9 @@ static void restrictbutton_collection_hide_select_cb(bContext *C, void *poin, vo LayerCollection *collection = poin2; if ((collection->flag & COLLECTION_SELECTABLE) == 0) { - SceneLayer *sl = BKE_scene_layer_find_from_collection(scene, collection); - /* deselect bases that are directly influenced by this LayerCollection */ - BKE_scene_layer_base_flag_recalculate(sl); + /* TODO(sergey): Use proper flag for tagging here. */ + DAG_id_tag_update(&scene->id, 0); WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, CTX_data_scene(C)); } WM_event_add_notifier(C, NC_SCENE | ND_LAYER_CONTENT, NULL); diff --git a/source/blender/editors/space_outliner/outliner_tools.c b/source/blender/editors/space_outliner/outliner_tools.c index a2753dac644..34879c09583 100644 --- a/source/blender/editors/space_outliner/outliner_tools.c +++ b/source/blender/editors/space_outliner/outliner_tools.c @@ -847,11 +847,13 @@ static void collection_cb(int event, TreeElement *te, TreeStoreElem *UNUSED(tsel } else { BKE_collection_unlink(sl, lc); + DAG_relations_tag_update(CTX_data_main(C)); WM_event_add_notifier(C, NC_SCENE | ND_LAYER, scene); } } else if (event == OL_COLLECTION_OP_COLLECTION_DEL) { if (BKE_collection_remove(scene, sc)) { + DAG_relations_tag_update(CTX_data_main(C)); WM_event_add_notifier(C, NC_SCENE | ND_LAYER, scene); } else { diff --git a/source/blender/makesdna/DNA_layer_types.h b/source/blender/makesdna/DNA_layer_types.h index fa419103a77..6fe3a9f1c8a 100644 --- a/source/blender/makesdna/DNA_layer_types.h +++ b/source/blender/makesdna/DNA_layer_types.h @@ -43,6 +43,7 @@ typedef struct Base { unsigned int lay; int flag_legacy; int pad; + struct IDProperty *collection_properties; /* used by depsgraph, flushed from collection-tree */ } Base; typedef struct CollectionOverride { @@ -55,11 +56,14 @@ typedef struct LayerCollection { struct LayerCollection *next, *prev; struct SceneCollection *scene_collection; short flag; - short pad[3]; + /* TODO(sergey): Get rid of this once we've got CoW in DEG, */ + short flag_evaluated; + short pad[2]; ListBase object_bases; /* (ObjectBase *)LinkData->data - synced with collection->objects and collection->filter_objects */ ListBase overrides; ListBase layer_collections; /* synced with collection->collections */ struct IDProperty *properties; /* overrides */ + struct IDProperty *properties_evaluated; } LayerCollection; typedef struct SceneLayer { diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h index 59ed6f1222f..a0ed163a4cb 100644 --- a/source/blender/makesdna/DNA_object_types.h +++ b/source/blender/makesdna/DNA_object_types.h @@ -303,7 +303,7 @@ typedef struct Object { struct PreviewImage *preview; - struct IDProperty *collection_properties; /* used by depsgraph, flushed from collection-tree */ + struct IDProperty *base_collection_properties; /* used by depsgraph, flushed from base */ } 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 fb83726d1d3..5a97d4d9c64 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -2273,37 +2273,62 @@ static PointerRNA rna_SceneCollection_objects_get(CollectionPropertyIterator *it return rna_pointer_inherit_refine(&iter->parent, &RNA_Object, ((LinkData *)internal->link)->data); } -static int rna_SceneCollection_move_above(ID *id, SceneCollection *sc_src, SceneCollection *sc_dst) +static int rna_SceneCollection_move_above(ID *id, SceneCollection *sc_src, Main *bmain, SceneCollection *sc_dst) { Scene *scene = (Scene *)id; - return BKE_collection_move_above(scene, sc_dst, sc_src); + + if (!BKE_collection_move_above(scene, sc_dst, sc_src)) { + return 0; + } + + DAG_relations_tag_update(bmain); + WM_main_add_notifier(NC_SCENE | ND_LAYER, NULL); + + return 1; } -static int rna_SceneCollection_move_below(ID *id, SceneCollection *sc_src, SceneCollection *sc_dst) +static int rna_SceneCollection_move_below(ID *id, SceneCollection *sc_src, Main *bmain, SceneCollection *sc_dst) { Scene *scene = (Scene *)id; - return BKE_collection_move_below(scene, sc_dst, sc_src); + + if (!BKE_collection_move_below(scene, sc_dst, sc_src)) { + return 0; + } + + DAG_relations_tag_update(bmain); + WM_main_add_notifier(NC_SCENE | ND_LAYER, NULL); + + return 1; } -static int rna_SceneCollection_move_into(ID *id, SceneCollection *sc_src, SceneCollection *sc_dst) +static int rna_SceneCollection_move_into(ID *id, SceneCollection *sc_src, Main *bmain, SceneCollection *sc_dst) { Scene *scene = (Scene *)id; - return BKE_collection_move_into(scene, sc_dst, sc_src); + + if (!BKE_collection_move_into(scene, sc_dst, sc_src)) { + return 0; + } + + DAG_relations_tag_update(bmain); + WM_main_add_notifier(NC_SCENE | ND_LAYER, NULL); + + return 1; } -static SceneCollection *rna_SceneCollection_new(ID *id, SceneCollection *sc_parent, const char *name) +static SceneCollection *rna_SceneCollection_new( + ID *id, SceneCollection *sc_parent, Main *bmain, const char *name) { Scene *scene = (Scene *)id; SceneCollection *sc = BKE_collection_add(scene, sc_parent, name); - DAG_id_tag_update(&scene->id, 0); + DAG_relations_tag_update(bmain); WM_main_add_notifier(NC_SCENE | ND_LAYER, NULL); return sc; } static void rna_SceneCollection_remove( - ID *id, SceneCollection *sc_parent, ReportList *reports, PointerRNA *sc_ptr) + ID *id, SceneCollection *sc_parent, Main *bmain, ReportList *reports, PointerRNA *sc_ptr) { Scene *scene = (Scene *)id; SceneCollection *sc = sc_ptr->data; @@ -2323,7 +2348,7 @@ static void rna_SceneCollection_remove( RNA_POINTER_INVALIDATE(sc_ptr); - DAG_id_tag_update(&scene->id, 0); + DAG_relations_tag_update(bmain); WM_main_add_notifier(NC_SCENE | ND_LAYER, NULL); } @@ -2455,9 +2480,9 @@ RNA_LAYER_MODE_EDIT_GET_SET_FLOAT(backwire_opacity) static void rna_LayerCollectionEngineSettings_update(bContext *C, PointerRNA *UNUSED(ptr)) { - SceneLayer *sl = CTX_data_scene_layer(C); - LayerCollection *lc = CTX_data_layer_collection(C); - BKE_scene_layer_engine_settings_collection_recalculate(sl, lc); + Scene *scene = CTX_data_scene(C); + /* TODO(sergey): Use proper flag for tagging here. */ + DAG_id_tag_update(&scene->id, 0); } /***********************************/ @@ -2500,33 +2525,55 @@ static PointerRNA rna_LayerCollection_objects_get(CollectionPropertyIterator *it return rna_pointer_inherit_refine(&iter->parent, &RNA_Object, base->object); } -static int rna_LayerCollection_move_above(ID *id, LayerCollection *lc_src, LayerCollection *lc_dst) +static int rna_LayerCollection_move_above(ID *id, LayerCollection *lc_src, Main *bmain, LayerCollection *lc_dst) { Scene *scene = (Scene *)id; - return BKE_layer_collection_move_above(scene, lc_dst, lc_src); + + if (!BKE_layer_collection_move_above(scene, lc_dst, lc_src)) { + return 0; + } + + DAG_relations_tag_update(bmain); + WM_main_add_notifier(NC_SCENE | ND_LAYER, NULL); + + return 1; } -static int rna_LayerCollection_move_below(ID *id, LayerCollection *lc_src, LayerCollection *lc_dst) +static int rna_LayerCollection_move_below(ID *id, LayerCollection *lc_src, Main *bmain, LayerCollection *lc_dst) { Scene *scene = (Scene *)id; - return BKE_layer_collection_move_below(scene, lc_dst, lc_src); + + if (!BKE_layer_collection_move_below(scene, lc_dst, lc_src)) { + return 0; + } + + DAG_relations_tag_update(bmain); + WM_main_add_notifier(NC_SCENE | ND_LAYER, NULL); + + return 1; } -static int rna_LayerCollection_move_into(ID *id, LayerCollection *lc_src, LayerCollection *lc_dst) +static int rna_LayerCollection_move_into(ID *id, LayerCollection *lc_src, Main *bmain, LayerCollection *lc_dst) { Scene *scene = (Scene *)id; - return BKE_layer_collection_move_into(scene, lc_dst, lc_src); + + if (!BKE_layer_collection_move_into(scene, lc_dst, lc_src)) { + return 0; + } + + DAG_relations_tag_update(bmain); + WM_main_add_notifier(NC_SCENE | ND_LAYER, NULL); + + return 1; } -static void rna_LayerCollection_hide_update(bContext *C, PointerRNA *ptr) +static void rna_LayerCollection_hide_update(bContext *C, PointerRNA *UNUSED(ptr)) { Scene *scene = CTX_data_scene(C); - LayerCollection *lc = ptr->data; - SceneLayer *sl = BKE_scene_layer_find_from_collection(scene, lc); /* 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); + /* TODO(sergey): Use proper flag for tagging here. */ + DAG_id_tag_update(&scene->id, 0); WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene); } @@ -2536,10 +2583,10 @@ static void rna_LayerCollection_hide_select_update(bContext *C, PointerRNA *ptr) if ((lc->flag & COLLECTION_SELECTABLE) == 0) { Scene *scene = CTX_data_scene(C); - SceneLayer *sl = BKE_scene_layer_find_from_collection(scene, lc); /* deselect bases that are directly influenced by this LayerCollection */ - BKE_scene_layer_base_flag_recalculate(sl); + /* TODO(sergey): Use proper flag for tagging here. */ + DAG_id_tag_update(&scene->id, 0); WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, CTX_data_scene(C)); } } @@ -2586,7 +2633,6 @@ LayerCollection * rna_SceneLayer_collection_link( Scene *scene = (Scene *)id; LayerCollection *lc = BKE_collection_link(sl, sc); - /* TODO(sergey/dfelinto): Only update relations for the current scenelayer. */ DAG_relations_tag_update(bmain); WM_main_add_notifier(NC_SCENE | ND_LAYER, scene); @@ -2605,10 +2651,7 @@ static void rna_SceneLayer_collection_unlink( BKE_collection_unlink(sl, lc); - /* needed otherwise the depgraph will contain freed objects which can crash, see [#20958] */ - /* TODO(sergey/dfelinto): Only update relations for the current scenelayer. */ DAG_relations_tag_update(bmain); - WM_main_add_notifier(NC_SCENE | ND_LAYER | ND_OB_ACTIVE, scene); } @@ -2769,12 +2812,14 @@ static void rna_SceneLayer_active_layer_set(PointerRNA *ptr, PointerRNA value) if (index != -1) scene->active_layer = index; } -static SceneLayer *rna_SceneLayer_new(ID *id, Scene *UNUSED(sce), const char *name) +static SceneLayer *rna_SceneLayer_new( + ID *id, Scene *UNUSED(sce), Main *bmain, const char *name) { Scene *scene = (Scene *)id; SceneLayer *sl = BKE_scene_layer_add(scene, name); DAG_id_tag_update(&scene->id, 0); + DAG_relations_tag_update(bmain); WM_main_add_notifier(NC_SCENE | ND_LAYER, NULL); return sl; @@ -2795,6 +2840,7 @@ static void rna_SceneLayer_remove( RNA_POINTER_INVALIDATE(sl_ptr); DAG_id_tag_update(&scene->id, 0); + DAG_relations_tag_update(bmain); WM_main_add_notifier(NC_SCENE | ND_LAYER, NULL); } @@ -5686,7 +5732,7 @@ static void rna_def_scene_collections(BlenderRNA *brna, PropertyRNA *cprop) func = RNA_def_function(srna, "new", "rna_SceneCollection_new"); RNA_def_function_ui_description(func, "Add a collection to scene"); - RNA_def_function_flag(func, FUNC_USE_SELF_ID); + RNA_def_function_flag(func, FUNC_USE_SELF_ID | FUNC_USE_MAIN); parm = RNA_def_string(func, "name", "SceneCollection", 0, "", "New name for the collection (not unique)"); RNA_def_parameter_flags(parm, 0, PARM_REQUIRED); parm = RNA_def_pointer(func, "result", "SceneCollection", "", "Newly created collection"); @@ -5694,7 +5740,7 @@ static void rna_def_scene_collections(BlenderRNA *brna, PropertyRNA *cprop) func = RNA_def_function(srna, "remove", "rna_SceneCollection_remove"); RNA_def_function_ui_description(func, "Remove a collection layer"); - RNA_def_function_flag(func, FUNC_USE_REPORTS | FUNC_USE_SELF_ID); + RNA_def_function_flag(func, FUNC_USE_SELF_ID | FUNC_USE_MAIN | FUNC_USE_REPORTS); parm = RNA_def_pointer(func, "layer", "SceneCollection", "", "Collection to remove"); RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED | PARM_RNAPTR); RNA_def_parameter_clear_flags(parm, PROP_THICK_WRAP, 0); @@ -5776,21 +5822,21 @@ static void rna_def_scene_collection(BlenderRNA *brna) /* Functions */ func = RNA_def_function(srna, "move_above", "rna_SceneCollection_move_above"); RNA_def_function_ui_description(func, "Move collection after another"); - RNA_def_function_flag(func, FUNC_USE_SELF_ID); + RNA_def_function_flag(func, FUNC_USE_SELF_ID | FUNC_USE_MAIN); parm = RNA_def_pointer(func, "sc_dst", "SceneCollection", "Collection", "Reference collection above which the collection will move"); parm = RNA_def_boolean(func, "result", false, "Result", "Whether the operation succeded"); RNA_def_function_return(func, parm); func = RNA_def_function(srna, "move_below", "rna_SceneCollection_move_below"); RNA_def_function_ui_description(func, "Move collection before another"); - RNA_def_function_flag(func, FUNC_USE_SELF_ID); + RNA_def_function_flag(func, FUNC_USE_SELF_ID | FUNC_USE_MAIN); parm = RNA_def_pointer(func, "sc_dst", "SceneCollection", "Collection", "Reference collection below which the collection will move"); parm = RNA_def_boolean(func, "result", false, "Result", "Whether the operation succeded"); RNA_def_function_return(func, parm); func = RNA_def_function(srna, "move_into", "rna_SceneCollection_move_into"); RNA_def_function_ui_description(func, "Move collection into another"); - RNA_def_function_flag(func, FUNC_USE_SELF_ID); + RNA_def_function_flag(func, FUNC_USE_SELF_ID | FUNC_USE_MAIN); parm = RNA_def_pointer(func, "sc_dst", "SceneCollection", "Collection", "Collection to insert into"); parm = RNA_def_boolean(func, "result", false, "Result", "Whether the operation succeded"); RNA_def_function_return(func, parm); @@ -6075,21 +6121,21 @@ static void rna_def_layer_collection(BlenderRNA *brna) /* Functions */ func = RNA_def_function(srna, "move_above", "rna_LayerCollection_move_above"); RNA_def_function_ui_description(func, "Move collection after another"); - RNA_def_function_flag(func, FUNC_USE_SELF_ID); + RNA_def_function_flag(func, FUNC_USE_SELF_ID | FUNC_USE_MAIN); parm = RNA_def_pointer(func, "lc_dst", "LayerCollection", "Collection", "Reference collection above which the collection will move"); parm = RNA_def_boolean(func, "result", false, "Result", "Whether the operation succeded"); RNA_def_function_return(func, parm); func = RNA_def_function(srna, "move_below", "rna_LayerCollection_move_below"); RNA_def_function_ui_description(func, "Move collection before another"); - RNA_def_function_flag(func, FUNC_USE_SELF_ID); + RNA_def_function_flag(func, FUNC_USE_SELF_ID | FUNC_USE_MAIN); parm = RNA_def_pointer(func, "lc_dst", "LayerCollection", "Collection", "Reference collection below which the collection will move"); parm = RNA_def_boolean(func, "result", false, "Result", "Whether the operation succeded"); RNA_def_function_return(func, parm); func = RNA_def_function(srna, "move_into", "rna_LayerCollection_move_into"); RNA_def_function_ui_description(func, "Move collection into another"); - RNA_def_function_flag(func, FUNC_USE_SELF_ID); + RNA_def_function_flag(func, FUNC_USE_SELF_ID | FUNC_USE_MAIN); parm = RNA_def_pointer(func, "lc_dst", "LayerCollection", "Collection", "Collection to insert into"); parm = RNA_def_boolean(func, "result", false, "Result", "Whether the operation succeded"); RNA_def_function_return(func, parm); @@ -6267,7 +6313,7 @@ static void rna_def_scene_layers(BlenderRNA *brna, PropertyRNA *cprop) func = RNA_def_function(srna, "new", "rna_SceneLayer_new"); RNA_def_function_ui_description(func, "Add a render layer to scene"); - RNA_def_function_flag(func, FUNC_USE_SELF_ID); + RNA_def_function_flag(func, FUNC_USE_SELF_ID | FUNC_USE_MAIN); parm = RNA_def_string(func, "name", "SceneLayer", 0, "", "New name for the render layer (not unique)"); RNA_def_parameter_flags(parm, 0, PARM_REQUIRED); parm = RNA_def_pointer(func, "result", "SceneLayer", "", "Newly created render layer"); @@ -6275,7 +6321,7 @@ static void rna_def_scene_layers(BlenderRNA *brna, PropertyRNA *cprop) func = RNA_def_function(srna, "remove", "rna_SceneLayer_remove"); RNA_def_function_ui_description(func, "Remove a render layer"); - RNA_def_function_flag(func, FUNC_USE_MAIN | FUNC_USE_REPORTS | FUNC_USE_SELF_ID); + RNA_def_function_flag(func, FUNC_USE_SELF_ID | FUNC_USE_MAIN | FUNC_USE_REPORTS); parm = RNA_def_pointer(func, "layer", "SceneLayer", "", "Render layer to remove"); RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED | PARM_RNAPTR); RNA_def_parameter_clear_flags(parm, PROP_THICK_WRAP, 0); |