Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/blenkernel/intern/layer.c')
-rw-r--r--source/blender/blenkernel/intern/layer.c1014
1 files changed, 678 insertions, 336 deletions
diff --git a/source/blender/blenkernel/intern/layer.c b/source/blender/blenkernel/intern/layer.c
index ef4816af54d..caa60450133 100644
--- a/source/blender/blenkernel/intern/layer.c
+++ b/source/blender/blenkernel/intern/layer.c
@@ -24,14 +24,18 @@
* \ingroup bke
*/
+#include <string.h>
+
#include "BLI_listbase.h"
#include "BLI_string.h"
#include "BLI_string_utf8.h"
#include "BLI_string_utils.h"
#include "BLT_translation.h"
-#include "BKE_layer.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"
#include "BKE_node.h"
@@ -42,25 +46,29 @@
#include "DNA_node_types.h"
#include "DNA_scene_types.h"
+#include "DRW_engine.h"
+
#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);
-static LayerCollection *layer_collection_add(SceneLayer *sl, ListBase *lb, SceneCollection *sc);
+static LayerCollection *layer_collection_add(SceneLayer *sl, LayerCollection *parent, SceneCollection *sc);
static LayerCollection *find_layer_collection_by_scene_collection(LayerCollection *lc, const SceneCollection *sc);
-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 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 object_bases_Iterator_next(Iterator *iter, const int flag);
/* RenderLayer */
/**
* Returns the SceneLayer to be used for rendering
+ * Most of the time BKE_scene_layer_context_active should be used instead
*/
-SceneLayer *BKE_scene_layer_active(struct Scene *scene)
+SceneLayer *BKE_scene_layer_render_active(const Scene *scene)
{
SceneLayer *sl = BLI_findlink(&scene->render_layers, scene->active_layer);
BLI_assert(sl);
@@ -68,6 +76,17 @@ SceneLayer *BKE_scene_layer_active(struct Scene *scene)
}
/**
+ * Returns the SceneLayer to be used for drawing, outliner, and
+ * other context related areas.
+ */
+SceneLayer *BKE_scene_layer_context_active(Scene *scene)
+{
+ /* waiting for workspace to get the layer from context*/
+ TODO_LAYER_CONTEXT;
+ return BKE_scene_layer_render_active(scene);
+}
+
+/**
* Add a new renderlayer
* by default, a renderlayer has the master collection
*/
@@ -87,7 +106,7 @@ SceneLayer *BKE_scene_layer_add(Scene *scene, const char *name)
BLI_uniquename(&scene->render_layers, sl, DATA_("SceneLayer"), '.', offsetof(SceneLayer, name), sizeof(sl->name));
SceneCollection *sc = BKE_collection_master(scene);
- layer_collection_add(sl, &sl->layer_collections, sc);
+ layer_collection_add(sl, NULL, sc);
return sl;
}
@@ -129,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) {
@@ -176,7 +202,7 @@ static bool find_scene_collection_in_scene_collections(ListBase *lb, const Layer
/**
* Find the SceneLayer a LayerCollection belongs to
*/
-SceneLayer *BKE_scene_layer_find_from_collection(Scene *scene, LayerCollection *lc)
+SceneLayer *BKE_scene_layer_find_from_collection(const Scene *scene, LayerCollection *lc)
{
for (SceneLayer *sl = scene->render_layers.first; sl; sl = sl->next) {
if (find_scene_collection_in_scene_collections(&sl->layer_collections, lc)) {
@@ -210,7 +236,7 @@ void BKE_scene_layer_base_select(struct SceneLayer *sl, Base *selbase)
}
}
-static void scene_layer_object_base_unref(SceneLayer* sl, Base *base)
+static void scene_layer_object_base_unref(SceneLayer *sl, Base *base)
{
base->refcount--;
@@ -220,125 +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;
- }
- else {
- base->flag &= ~BASE_VISIBLED;
+ if (base->collection_properties) {
+ IDP_FreeProperty(base->collection_properties);
+ MEM_freeN(base->collection_properties);
}
- if (is_selectable) {
- base->flag |= BASE_SELECTABLED;
- }
- else {
- 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 (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;
- }
- }
-}
-
-/**
- * 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 SceneLayer *sl, const char *engine_name)
-{
- 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(sl, base->object, engine_name);
- base->flag &= ~BASE_DIRTY_ENGINE_SETTINGS;
- }
+ BLI_remlink(&sl->object_bases, base);
+ MEM_freeN(base);
}
-
- sl->flag &= ~SCENE_LAYER_ENGINE_DIRTY;
}
/**
@@ -356,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;
}
@@ -377,7 +296,16 @@ static void layer_collection_free(SceneLayer *sl, LayerCollection *lc)
BLI_freelistN(&lc->object_bases);
BLI_freelistN(&lc->overrides);
- layer_collection_engine_settings_free(lc);
+
+ if (lc->properties) {
+ IDP_FreeProperty(lc->properties);
+ 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);
@@ -450,7 +378,7 @@ int BKE_layer_collection_count(SceneLayer *sl)
/**
* Recursively get the index for a given collection
*/
-static int index_from_collection(ListBase *lb, LayerCollection *lc, int *i)
+static int index_from_collection(ListBase *lb, const LayerCollection *lc, int *i)
{
for (LayerCollection *lcol = lb->first; lcol; lcol = lcol->next) {
if (lcol == lc) {
@@ -470,19 +398,364 @@ static int index_from_collection(ListBase *lb, LayerCollection *lc, int *i)
/**
* Return -1 if not found
*/
-int BKE_layer_collection_findindex(SceneLayer *sl, LayerCollection *lc)
+int BKE_layer_collection_findindex(SceneLayer *sl, const LayerCollection *lc)
{
int i = 0;
return index_from_collection(&sl->layer_collections, lc, &i);
}
/**
+ * Lookup the listbase that contains \a lc.
+ */
+static ListBase *layer_collection_listbase_find(ListBase *lb, LayerCollection *lc)
+{
+ for (LayerCollection *lc_iter = lb->first; lc_iter; lc_iter = lc_iter->next) {
+ if (lc_iter == lc) {
+ return lb;
+ }
+
+ ListBase *lb_child_result;
+ if ((lb_child_result = layer_collection_listbase_find(&lc_iter->layer_collections, lc))) {
+ return lb_child_result;
+ }
+ }
+
+ return NULL;
+}
+
+#if 0
+/**
+ * Lookup the listbase that contains \a sc.
+ */
+static ListBase *scene_collection_listbase_find(ListBase *lb, SceneCollection *sc)
+{
+ for (SceneCollection *sc_iter = lb->first; sc_iter; sc_iter = sc_iter->next) {
+ if (sc_iter == sc) {
+ return lb;
+ }
+
+ ListBase *lb_child_result;
+ if ((lb_child_result = scene_collection_listbase_find(&sc_iter->scene_collections, sc))) {
+ return lb_child_result;
+ }
+ }
+
+ return NULL;
+}
+#endif
+
+/* ---------------------------------------------------------------------- */
+/* Outliner drag and drop */
+
+/**
+ * Nest a LayerCollection into another one
+ * Both collections must be from the same SceneLayer, return true if succeded.
+ *
+ * The LayerCollection will effectively be moved into the
+ * new (nested) position. So all the settings, overrides, ... go with it, and
+ * if the collection was directly linked to the SceneLayer it's then unlinked.
+ *
+ * For the other SceneLayers we simply resync the tree, without changing directly
+ * linked collections (even if they link to the same SceneCollection)
+ *
+ * \param lc_src LayerCollection to nest into \a lc_dst
+ * \param lc_dst LayerCollection to have \a lc_src inserted into
+ */
+
+static void layer_collection_swap(
+ SceneLayer *sl, ListBase *lb_a, ListBase *lb_b,
+ LayerCollection *lc_a, LayerCollection *lc_b)
+{
+ if (lb_a == NULL) {
+ lb_a = layer_collection_listbase_find(&sl->layer_collections, lc_a);
+ }
+
+ if (lb_b == NULL) {
+ lb_b = layer_collection_listbase_find(&sl->layer_collections, lc_b);
+ }
+
+ BLI_assert(lb_a);
+ BLI_assert(lb_b);
+
+ BLI_listbases_swaplinks(lb_a, lb_b, lc_a, lc_b);
+}
+
+/**
+ * Move \a lc_src into \a lc_dst. Both have to be stored in \a sl.
+ * If \a lc_src is directly linked to the SceneLayer it's unlinked
+ */
+bool BKE_layer_collection_move_into(const Scene *scene, LayerCollection *lc_dst, LayerCollection *lc_src)
+{
+ SceneLayer *sl = BKE_scene_layer_find_from_collection(scene, lc_src);
+ bool is_directly_linked = false;
+
+ if ((!sl) || (sl != BKE_scene_layer_find_from_collection(scene, lc_dst))) {
+ return false;
+ }
+
+ /* We can't nest the collection into itself */
+ if (lc_src->scene_collection == lc_dst->scene_collection) {
+ return false;
+ }
+
+ /* Collection is already where we wanted it to be */
+ if (lc_dst->layer_collections.last == lc_src) {
+ return false;
+ }
+
+ /* Collection is already where we want it to be in the scene tree
+ * but we want to swap it in the layer tree still */
+ if (lc_dst->scene_collection->scene_collections.last == lc_src->scene_collection) {
+ LayerCollection *lc_swap = lc_dst->layer_collections.last;
+ layer_collection_swap(sl, &lc_dst->layer_collections, NULL, lc_dst->layer_collections.last, lc_src);
+
+ if (BLI_findindex(&sl->layer_collections, lc_swap) != -1) {
+ BKE_collection_unlink(sl, lc_swap);
+ }
+ return true;
+ }
+ else {
+ LayerCollection *lc_temp;
+ is_directly_linked = BLI_findindex(&sl->layer_collections, lc_src) != -1;
+
+ if (!is_directly_linked) {
+ /* lc_src will be invalid after BKE_collection_move_into!
+ * so we swap it with lc_temp to preserve its settings */
+ lc_temp = BKE_collection_link(sl, lc_src->scene_collection);
+ layer_collection_swap(sl, &sl->layer_collections, NULL, lc_temp, lc_src);
+ }
+
+ if (!BKE_collection_move_into(scene, lc_dst->scene_collection, lc_src->scene_collection)) {
+ if (!is_directly_linked) {
+ /* Swap back and remove */
+ layer_collection_swap(sl, NULL, NULL, lc_temp, lc_src);
+ BKE_collection_unlink(sl, lc_temp);
+ }
+ return false;
+ }
+ }
+
+ LayerCollection *lc_new = BLI_findptr(&lc_dst->layer_collections, lc_src->scene_collection, offsetof(LayerCollection, scene_collection));
+ BLI_assert(lc_new);
+ layer_collection_swap(sl, &lc_dst->layer_collections, NULL, lc_new, lc_src);
+
+ /* If it's directly linked, unlink it after the swap */
+ if (BLI_findindex(&sl->layer_collections, lc_new) != -1) {
+ BKE_collection_unlink(sl, lc_new);
+ }
+
+ return true;
+}
+
+/**
+ * Move \a lc_src above \a lc_dst. Both have to be stored in \a sl.
+ * If \a lc_src is directly linked to the SceneLayer it's unlinked
+ */
+bool BKE_layer_collection_move_above(const Scene *scene, LayerCollection *lc_dst, LayerCollection *lc_src)
+{
+ SceneLayer *sl = BKE_scene_layer_find_from_collection(scene, lc_src);
+ const bool is_directly_linked_src = BLI_findindex(&sl->layer_collections, lc_src) != -1;
+ const bool is_directly_linked_dst = BLI_findindex(&sl->layer_collections, lc_dst) != -1;
+
+ if ((!sl) || (sl != BKE_scene_layer_find_from_collection(scene, lc_dst))) {
+ return false;
+ }
+
+ /* Collection is already where we wanted it to be */
+ if (lc_dst->prev == lc_src) {
+ return false;
+ }
+
+ /* Collection is already where we want it to be in the scene tree
+ * but we want to swap it in the layer tree still */
+ if (lc_dst->prev && lc_dst->prev->scene_collection == lc_src->scene_collection) {
+ LayerCollection *lc_swap = lc_dst->prev;
+ layer_collection_swap(sl, NULL, NULL, lc_dst->prev, lc_src);
+
+ if (BLI_findindex(&sl->layer_collections, lc_swap) != -1) {
+ BKE_collection_unlink(sl, lc_swap);
+ }
+ return true;
+ }
+ /* We don't allow to move above/below a directly linked collection
+ * unless the source collection is also directly linked */
+ else if (is_directly_linked_dst) {
+ /* Both directly linked to the SceneLayer, just need to swap */
+ if (is_directly_linked_src) {
+ BLI_remlink(&sl->layer_collections, lc_src);
+ BLI_insertlinkbefore(&sl->layer_collections, lc_dst, lc_src);
+ return true;
+ }
+ else {
+ return false;
+ }
+ }
+ else {
+ LayerCollection *lc_temp;
+
+ if (!is_directly_linked_src) {
+ /* lc_src will be invalid after BKE_collection_move_into!
+ * so we swap it with lc_temp to preserve its settings */
+ lc_temp = BKE_collection_link(sl, lc_src->scene_collection);
+ layer_collection_swap(sl, &sl->layer_collections, NULL, lc_temp, lc_src);
+ }
+
+ if (!BKE_collection_move_above(scene, lc_dst->scene_collection, lc_src->scene_collection)) {
+ if (!is_directly_linked_src) {
+ /* Swap back and remove */
+ layer_collection_swap(sl, NULL, NULL, lc_temp, lc_src);
+ BKE_collection_unlink(sl, lc_temp);
+ }
+ return false;
+ }
+ }
+
+ LayerCollection *lc_new = lc_dst->prev;
+ BLI_assert(lc_new);
+ layer_collection_swap(sl, NULL, NULL, lc_new, lc_src);
+
+ /* If it's directly linked, unlink it after the swap */
+ if (BLI_findindex(&sl->layer_collections, lc_new) != -1) {
+ BKE_collection_unlink(sl, lc_new);
+ }
+
+ return true;
+}
+
+/**
+ * Move \a lc_src below \a lc_dst. Both have to be stored in \a sl.
+ * If \a lc_src is directly linked to the SceneLayer it's unlinked
+ */
+bool BKE_layer_collection_move_below(const Scene *scene, LayerCollection *lc_dst, LayerCollection *lc_src)
+{
+ SceneLayer *sl = BKE_scene_layer_find_from_collection(scene, lc_src);
+ const bool is_directly_linked_src = BLI_findindex(&sl->layer_collections, lc_src) != -1;
+ const bool is_directly_linked_dst = BLI_findindex(&sl->layer_collections, lc_dst) != -1;
+
+ if ((!sl) || (sl != BKE_scene_layer_find_from_collection(scene, lc_dst))) {
+ return false;
+ }
+
+ /* Collection is already where we wanted it to be */
+ if (lc_dst->next == lc_src) {
+ return false;
+ }
+
+ /* Collection is already where we want it to be in the scene tree
+ * but we want to swap it in the layer tree still */
+ if (lc_dst->next && lc_dst->next->scene_collection == lc_src->scene_collection) {
+ LayerCollection *lc_swap = lc_dst->next;
+ layer_collection_swap(sl, NULL, NULL, lc_dst->next, lc_src);
+
+ if (BLI_findindex(&sl->layer_collections, lc_swap) != -1) {
+ BKE_collection_unlink(sl, lc_swap);
+ }
+ return true;
+ }
+ /* We don't allow to move above/below a directly linked collection
+ * unless the source collection is also directly linked */
+ else if (is_directly_linked_dst) {
+ /* Both directly linked to the SceneLayer, just need to swap */
+ if (is_directly_linked_src) {
+ BLI_remlink(&sl->layer_collections, lc_src);
+ BLI_insertlinkafter(&sl->layer_collections, lc_dst, lc_src);
+ return true;
+ }
+ else {
+ return false;
+ }
+ }
+ else {
+ LayerCollection *lc_temp;
+
+ if (!is_directly_linked_src) {
+ /* lc_src will be invalid after BKE_collection_move_into!
+ * so we swap it with lc_temp to preserve its settings */
+ lc_temp = BKE_collection_link(sl, lc_src->scene_collection);
+ layer_collection_swap(sl, &sl->layer_collections, NULL, lc_temp, lc_src);
+ }
+
+ if (!BKE_collection_move_below(scene, lc_dst->scene_collection, lc_src->scene_collection)) {
+ if (!is_directly_linked_src) {
+ /* Swap back and remove */
+ layer_collection_swap(sl, NULL, NULL, lc_temp, lc_src);
+ BKE_collection_unlink(sl, lc_temp);
+ }
+ return false;
+ }
+ }
+
+ LayerCollection *lc_new = lc_dst->next;
+ BLI_assert(lc_new);
+ layer_collection_swap(sl, NULL, NULL, lc_new, lc_src);
+
+ /* If it's directly linked, unlink it after the swap */
+ if (BLI_findindex(&sl->layer_collections, lc_new) != -1) {
+ BKE_collection_unlink(sl, lc_new);
+ }
+
+ return true;
+}
+
+static bool layer_collection_resync(SceneLayer *sl, LayerCollection *lc, const SceneCollection *sc)
+{
+ if (lc->scene_collection == sc) {
+ ListBase collections = {NULL};
+ BLI_movelisttolist(&collections, &lc->layer_collections);
+
+ for (SceneCollection *sc_nested = sc->scene_collections.first; sc_nested; sc_nested = sc_nested->next) {
+ LayerCollection *lc_nested = BLI_findptr(&collections, sc_nested, offsetof(LayerCollection, scene_collection));
+ if (lc_nested) {
+ BLI_remlink(&collections, lc_nested);
+ BLI_addtail(&lc->layer_collections, lc_nested);
+ }
+ else {
+ layer_collection_add(sl, lc, sc_nested);
+ }
+ }
+
+ for (LayerCollection *lc_nested = collections.first; lc_nested; lc_nested = lc_nested->next) {
+ layer_collection_free(sl, lc_nested);
+ }
+ BLI_freelistN(&collections);
+
+ BLI_assert(BLI_listbase_count(&lc->layer_collections) ==
+ BLI_listbase_count(&sc->scene_collections));
+
+ return true;
+ }
+
+ for (LayerCollection *lc_nested = lc->layer_collections.first; lc_nested; lc_nested = lc_nested->next) {
+ if (layer_collection_resync(sl, lc_nested, sc)) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+/**
+ * Update the scene layers so that any LayerCollection that points
+ * to \a sc is re-synced again
+ */
+void BKE_layer_collection_resync(const Scene *scene, const SceneCollection *sc)
+{
+ for (SceneLayer *sl = scene->render_layers.first; sl; sl = sl->next) {
+ for (LayerCollection *lc = sl->layer_collections.first; lc; lc = lc->next) {
+ layer_collection_resync(sl, lc, sc);
+ }
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+/**
* Link a collection to a renderlayer
* The collection needs to be created separately
*/
LayerCollection *BKE_collection_link(SceneLayer *sl, SceneCollection *sc)
{
- LayerCollection *lc = layer_collection_add(sl, &sl->layer_collections, sc);
+ LayerCollection *lc = layer_collection_add(sl, NULL, sc);
sl->active_collection = BKE_layer_collection_findindex(sl, lc);
return lc;
}
@@ -494,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;
@@ -514,9 +784,6 @@ 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)
@@ -544,30 +811,39 @@ static void layer_collection_populate(SceneLayer *sl, LayerCollection *lc, Scene
layer_collection_objects_populate(sl, lc, &sc->filter_objects);
for (SceneCollection *nsc = sc->scene_collections.first; nsc; nsc = nsc->next) {
- layer_collection_add(sl, &lc->layer_collections, nsc);
+ layer_collection_add(sl, lc, nsc);
}
}
-static LayerCollection *layer_collection_add(SceneLayer *sl, ListBase *lb, SceneCollection *sc)
+static LayerCollection *layer_collection_add(SceneLayer *sl, LayerCollection *parent, SceneCollection *sc)
{
+ IDPropertyTemplate val = {0};
LayerCollection *lc = MEM_callocN(sizeof(LayerCollection), "Collection Base");
- BLI_addtail(lb, lc);
lc->scene_collection = sc;
- lc->flag = COLLECTION_VISIBLE + COLLECTION_SELECTABLE + COLLECTION_FOLDED;
+ lc->flag = COLLECTION_VISIBLE | COLLECTION_SELECTABLE;
+
+ lc->properties = IDP_New(IDP_GROUP, &val, ROOT_PROP);
+ collection_engine_settings_init(lc->properties, false);
+
+ if (parent != NULL) {
+ BLI_addtail(&parent->layer_collections, lc);
+ }
+ else {
+ BLI_addtail(&sl->layer_collections, lc);
+ }
- layer_collection_create_engine_settings(lc);
layer_collection_populate(sl, lc, sc);
+
return lc;
}
-
/* ---------------------------------------------------------------------- */
/**
* See if render layer has the scene collection linked directly, or indirectly (nested)
*/
-bool BKE_scene_layer_has_collection(struct SceneLayer *sl, struct SceneCollection *sc)
+bool BKE_scene_layer_has_collection(SceneLayer *sl, const SceneCollection *sc)
{
for (LayerCollection *lc = sl->layer_collections.first; lc; lc = lc->next) {
if (find_layer_collection_by_scene_collection(lc, sc) != NULL) {
@@ -619,7 +895,7 @@ void BKE_layer_sync_new_scene_collection(Scene *scene, const SceneCollection *sc
for (LayerCollection *lc = sl->layer_collections.first; lc; lc = lc->next) {
LayerCollection *lc_parent = find_layer_collection_by_scene_collection(lc, sc_parent);
if (lc_parent) {
- layer_collection_add(sl, &lc_parent->layer_collections, sc);
+ layer_collection_add(sl, lc_parent, sc);
}
}
}
@@ -628,7 +904,7 @@ void BKE_layer_sync_new_scene_collection(Scene *scene, const SceneCollection *sc
/**
* Add a corresponding ObjectBase to all the equivalent LayerCollection
*/
-void BKE_layer_sync_object_link(Scene *scene, SceneCollection *sc, Object *ob)
+void BKE_layer_sync_object_link(const Scene *scene, SceneCollection *sc, Object *ob)
{
for (SceneLayer *sl = scene->render_layers.first; sl; sl = sl->next) {
for (LayerCollection *lc = sl->layer_collections.first; lc; lc = lc->next) {
@@ -644,7 +920,7 @@ void BKE_layer_sync_object_link(Scene *scene, SceneCollection *sc, Object *ob)
* Remove the equivalent object base to all layers that have this collection
* also remove all reference to ob in the filter_objects
*/
-void BKE_layer_sync_object_unlink(Scene *scene, SceneCollection *sc, Object *ob)
+void BKE_layer_sync_object_unlink(const Scene *scene, SceneCollection *sc, Object *ob)
{
for (SceneLayer *sl = scene->render_layers.first; sl; sl = sl->next) {
for (LayerCollection *lc = sl->layer_collections.first; lc; lc = lc->next) {
@@ -653,8 +929,6 @@ void BKE_layer_sync_object_unlink(Scene *scene, SceneCollection *sc, Object *ob)
layer_collection_object_remove(sl, found, ob);
}
}
- BKE_scene_layer_base_flag_recalculate(sl);
- BKE_scene_layer_engine_settings_object_recalculate(sl, ob);
}
}
@@ -683,14 +957,24 @@ typedef struct CollectionEngineSettingsCB_Type {
} CollectionEngineSettingsCB_Type;
+static void create_engine_settings_scene(Scene *scene, CollectionEngineSettingsCB_Type *ces_type)
+{
+ if (collection_engine_get(scene->collection_properties, COLLECTION_MODE_NONE, ces_type->name)) {
+ return;
+ }
+
+ IDProperty *props = collection_engine_settings_create(ces_type, true);
+ IDP_AddToGroup(scene->collection_properties, props);
+}
+
static void create_engine_settings_layer_collection(LayerCollection *lc, CollectionEngineSettingsCB_Type *ces_type)
{
- if (BKE_layer_collection_engine_get(lc, ces_type->name)) {
+ if (BKE_layer_collection_engine_get(lc, COLLECTION_MODE_NONE, ces_type->name)) {
return;
}
- CollectionEngineSettings *ces = collection_engine_settings_create(ces_type);
- BLI_addtail(&lc->engine_settings, ces);
+ IDProperty *props = collection_engine_settings_create(ces_type, false);
+ IDP_AddToGroup(lc->properties, props);
for (LayerCollection *lcn = lc->layer_collections.first; lcn; lcn = lcn->next) {
create_engine_settings_layer_collection(lcn, ces_type);
@@ -699,6 +983,9 @@ static void create_engine_settings_layer_collection(LayerCollection *lc, Collect
static void create_engines_settings_scene(Scene *scene, CollectionEngineSettingsCB_Type *ces_type)
{
+ /* populate the scene with the new settings */
+ create_engine_settings_scene(scene, ces_type);
+
for (SceneLayer *sl = scene->render_layers.first; sl; sl = sl->next) {
for (LayerCollection *lc = sl->layer_collections.first; lc; lc = lc->next) {
create_engine_settings_layer_collection(lc, ces_type);
@@ -712,7 +999,8 @@ void BKE_layer_collection_engine_settings_callback_register(
CollectionEngineSettingsCB_Type *ces_type;
/* cleanup in case it existed */
- ces_type = BLI_findstring(&R_engines_settings_callbacks, engine_name, offsetof(CollectionEngineSettingsCB_Type, name));
+ ces_type = BLI_findstring(&R_engines_settings_callbacks, engine_name,
+ offsetof(CollectionEngineSettingsCB_Type, name));
if (ces_type) {
BLI_remlink(&R_engines_settings_callbacks, ces_type);
@@ -737,257 +1025,214 @@ void BKE_layer_collection_engine_settings_callback_free(void)
BLI_freelistN(&R_engines_settings_callbacks);
}
-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));
-
- /* call callback */
- ces_type->callback(NULL, ces);
-
- return ces;
-}
-
/**
- * Initialize a CollectionEngineSettings
+ * Create a root IDProperty for this engine
*
- * Usually we would pass LayerCollection->engine_settings
- * But depsgraph uses this for Object->collection_settings
+ * \param populate whether we want to pre-fill the collection with the default properties
*/
-CollectionEngineSettings *BKE_layer_collection_engine_settings_create(const char *engine_name)
+static IDProperty *collection_engine_settings_create(CollectionEngineSettingsCB_Type *ces_type, const bool populate)
{
- CollectionEngineSettingsCB_Type *ces_type;
- ces_type = BLI_findstring(&R_engines_settings_callbacks, engine_name, offsetof(CollectionEngineSettingsCB_Type, name));
- BLI_assert(ces_type);
+ IDProperty *props;
+ IDPropertyTemplate val = {0};
+
+ props = IDP_New(IDP_GROUP, &val, ces_type->name);
+ props->subtype = IDP_GROUP_SUB_ENGINE_RENDER;
+
+ /* properties */
+ if (populate) {
+ ces_type->callback(NULL, props);
+ }
- CollectionEngineSettings *ces = collection_engine_settings_create(ces_type);
- return ces;
+ return props;
}
-/**
- * Free the CollectionEngineSettings
- */
-void BKE_layer_collection_engine_settings_free(CollectionEngineSettings *ces)
+static void layer_collection_create_mode_settings_object(IDProperty *root, const bool populate)
{
- BLI_freelistN(&ces->properties);
+ IDProperty *props;
+ IDPropertyTemplate val = {0};
+
+ props = IDP_New(IDP_GROUP, &val, "ObjectMode");
+ props->subtype = IDP_GROUP_SUB_MODE_OBJECT;
+
+ /* properties */
+ if (populate) {
+ OBJECT_collection_settings_create(props);
+ }
+
+ IDP_AddToGroup(root, props);
}
-static void layer_collection_engine_settings_free(LayerCollection *lc)
+static void layer_collection_create_mode_settings_edit(IDProperty *root, const bool populate)
{
- for (CollectionEngineSettings *ces = lc->engine_settings.first; ces; ces = ces->next) {
- BKE_layer_collection_engine_settings_free(ces);
+ IDProperty *props;
+ IDPropertyTemplate val = {0};
+
+ props = IDP_New(IDP_GROUP, &val, "EditMode");
+ props->subtype = IDP_GROUP_SUB_MODE_EDIT;
+
+ /* properties */
+ if (populate) {
+ EDIT_MESH_collection_settings_create(props);
}
- BLI_freelistN(&lc->engine_settings);
+
+ IDP_AddToGroup(root, props);
}
-/**
- * Initialize the render settings for a single LayerCollection
- */
-static void layer_collection_create_engine_settings(LayerCollection *lc)
+static void collection_create_render_settings(IDProperty *root, const bool populate)
{
CollectionEngineSettingsCB_Type *ces_type;
for (ces_type = R_engines_settings_callbacks.first; ces_type; ces_type = ces_type->next) {
- create_engine_settings_layer_collection(lc, ces_type);
+ IDProperty *props = collection_engine_settings_create(ces_type, populate);
+ IDP_AddToGroup(root, props);
}
}
-/**
- * Return layer collection engine settings for specified engine
- */
-CollectionEngineSettings *BKE_layer_collection_engine_get(LayerCollection *lc, const char *engine_name)
+static void collection_create_mode_settings(IDProperty *root, const bool populate)
{
- CollectionEngineSettings *ces;
- ces = BLI_findstring(&lc->engine_settings, engine_name, offsetof(CollectionEngineSettings, name));
- return ces;
+ /* XXX TODO: put all those engines in the R_engines_settings_callbacks
+ * and have IDP_AddToGroup outside the callbacks */
+ layer_collection_create_mode_settings_object(root, populate);
+ layer_collection_create_mode_settings_edit(root, populate);
}
-/* ---------------------------------------------------------------------- */
-/* Engine Settings Properties */
-
-void BKE_collection_engine_property_add_float(CollectionEngineSettings *ces, const char *name, float value)
+static int idproperty_group_subtype(const int mode_type)
{
- CollectionEnginePropertyFloat *prop;
- prop = MEM_callocN(sizeof(CollectionEnginePropertyFloat), "collection engine settings float");
- prop->data.type = COLLECTION_PROP_TYPE_FLOAT;
- BLI_strncpy_utf8(prop->data.name, name, sizeof(prop->data.name));
- prop->value = value;
- BLI_addtail(&ces->properties, prop);
-}
+ int idgroup_type;
-void BKE_collection_engine_property_add_int(CollectionEngineSettings *ces, const char *name, int value)
-{
- CollectionEnginePropertyInt *prop;
- prop = MEM_callocN(sizeof(CollectionEnginePropertyInt), "collection engine settings int");
- prop->data.type = COLLECTION_PROP_TYPE_INT;
- BLI_strncpy_utf8(prop->data.name, name, sizeof(prop->data.name));
- prop->value = value;
- BLI_addtail(&ces->properties, prop);
+ switch (mode_type) {
+ case COLLECTION_MODE_OBJECT:
+ idgroup_type = IDP_GROUP_SUB_MODE_OBJECT;
+ break;
+ case COLLECTION_MODE_EDIT:
+ idgroup_type = IDP_GROUP_SUB_MODE_EDIT;
+ break;
+ default:
+ case COLLECTION_MODE_NONE:
+ return IDP_GROUP_SUB_ENGINE_RENDER;
+ break;
+ }
+
+ return idgroup_type;
}
-CollectionEngineProperty *BKE_collection_engine_property_get(CollectionEngineSettings *ces, const char *name)
+/**
+ * Return collection enginne settings for either Object s of LayerCollection s
+ */
+static IDProperty *collection_engine_get(
+ IDProperty *root, const int type, const char *engine_name)
{
- return BLI_findstring(&ces->properties, name, offsetof(CollectionEngineProperty, name));
+ const int subtype = idproperty_group_subtype(type);
+
+ if (subtype == IDP_GROUP_SUB_ENGINE_RENDER) {
+ return IDP_GetPropertyFromGroup(root, engine_name);
+ }
+ else {
+ IDProperty *prop;
+ for (prop = root->data.group.first; prop; prop = prop->next) {
+ if (prop->subtype == subtype) {
+ return prop;
+ }
+ }
+ }
+
+ BLI_assert(false);
+ return NULL;
}
-int BKE_collection_engine_property_value_get_int(CollectionEngineSettings *ces, const char *name)
+/**
+ * Return collection engine settings from Object for specified engine of mode
+ */
+IDProperty *BKE_object_collection_engine_get(Object *ob, const int type, const char *engine_name)
{
- CollectionEnginePropertyInt *prop;
- prop = (CollectionEnginePropertyInt *)BLI_findstring(&ces->properties, name, offsetof(CollectionEngineProperty, name));
- return prop->value;
+ return collection_engine_get(ob->base_collection_properties, type, engine_name);
}
-
-float BKE_collection_engine_property_value_get_float(CollectionEngineSettings *ces, const char *name)
+/**
+ * Return layer collection engine settings for specified engine
+ */
+IDProperty *BKE_layer_collection_engine_get(LayerCollection *lc, const int type, const char *engine_name)
{
- CollectionEnginePropertyFloat *prop;
- prop = (CollectionEnginePropertyFloat *)BLI_findstring(&ces->properties, name, offsetof(CollectionEngineProperty, name));
- return prop->value;
+ return collection_engine_get(lc->properties, type, engine_name);
}
-void BKE_collection_engine_property_value_set_int(CollectionEngineSettings *ces, const char *name, int value)
+/* ---------------------------------------------------------------------- */
+/* Engine Settings Properties */
+
+void BKE_collection_engine_property_add_float(IDProperty *props, const char *name, float value)
{
- CollectionEnginePropertyInt *prop;
- prop = (CollectionEnginePropertyInt *)BLI_findstring(&ces->properties, name, offsetof(CollectionEngineProperty, name));
- prop->value = value;
- prop->data.flag |= COLLECTION_PROP_USE;
+ IDPropertyTemplate val = {0};
+ val.f = value;
+ IDP_AddToGroup(props, IDP_New(IDP_FLOAT, &val, name));
}
-void BKE_collection_engine_property_value_set_float(CollectionEngineSettings *ces, const char *name, float value)
+void BKE_collection_engine_property_add_int(IDProperty *props, const char *name, int value)
{
- CollectionEnginePropertyFloat *prop;
- prop = (CollectionEnginePropertyFloat *)BLI_findstring(&ces->properties, name, offsetof(CollectionEngineProperty, name));
- prop->value = value;
- prop->data.flag |= COLLECTION_PROP_USE;
+ IDPropertyTemplate val = {0};
+ val.i = value;
+ IDP_AddToGroup(props, IDP_New(IDP_INT, &val, name));
}
-bool BKE_collection_engine_property_use_get(CollectionEngineSettings *ces, const char *name)
+void BKE_collection_engine_property_add_bool(IDProperty *props, const char *name, bool value)
{
- CollectionEngineProperty *prop;
- prop = (CollectionEngineProperty *)BLI_findstring(&ces->properties, name, offsetof(CollectionEngineProperty, name));
- return ((prop->flag & COLLECTION_PROP_USE) != 0);
+ IDPropertyTemplate val = {0};
+ val.i = value;
+ IDP_AddToGroup(props, IDP_New(IDP_INT, &val, name));
}
-void BKE_collection_engine_property_use_set(CollectionEngineSettings *ces, const char *name, bool value)
+int BKE_collection_engine_property_value_get_int(IDProperty *props, const char *name)
{
- CollectionEngineProperty *prop;
- prop = (CollectionEngineProperty *)BLI_findstring(&ces->properties, name, offsetof(CollectionEngineProperty, name));
-
- if (value) {
- prop->flag |= COLLECTION_PROP_USE;
- }
- else {
- prop->flag &= ~COLLECTION_PROP_USE;
- }
+ IDProperty *idprop = IDP_GetPropertyFromGroup(props, name);
+ return idprop ? idprop->data.val : 0;
}
-/* Engine Settings recalculate */
-
-static void collection_engine_settings_init(CollectionEngineSettings *ces, const char *engine_name)
+float BKE_collection_engine_property_value_get_float(IDProperty *props, const char *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);
+ IDProperty *idprop = IDP_GetPropertyFromGroup(props, name);
+ return idprop ? *((float *)&idprop->data.val) : 0.0f;
}
-static void collection_engine_settings_copy(CollectionEngineSettings *ces_dst, CollectionEngineSettings *ces_src)
+bool BKE_collection_engine_property_value_get_bool(IDProperty *props, const char *name)
{
- 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);
- }
+ IDProperty *idprop = IDP_GetPropertyFromGroup(props, name);
+ return idprop ? idprop->data.val : 0;
}
-/**
- * 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) {
- /* mark the property as used, so the engine knows if the value was ever set*/
- prop_dst->flag |= COLLECTION_PROP_USE;
- 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;
- }
- }
+void BKE_collection_engine_property_value_set_int(IDProperty *props, const char *name, int value)
+{
+ IDProperty *idprop = IDP_GetPropertyFromGroup(props, name);
+ idprop->data.val = value;
}
-static void collection_engine_settings_merge(CollectionEngineSettings *ces_dst, CollectionEngineSettings *ces_src)
+void BKE_collection_engine_property_value_set_float(IDProperty *props, const char *name, float value)
{
- 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);
- }
+ IDProperty *idprop = IDP_GetPropertyFromGroup(props, name);
+ *(float *)&idprop->data.val = value;
}
-static void layer_collection_engine_settings_update(
- LayerCollection *lc, CollectionEngineSettings *ces_parent,
- Base *base, CollectionEngineSettings *ces_ob)
+void BKE_collection_engine_property_value_set_bool(IDProperty *props, const char *name, bool value)
{
- if ((lc->flag & COLLECTION_VISIBLE) == 0) {
- return;
- }
-
- CollectionEngineSettings ces = {NULL};
- collection_engine_settings_copy(&ces, ces_parent);
-
- CollectionEngineSettings *ces_lc = BKE_layer_collection_engine_get(lc, ces.name);
- collection_engine_settings_merge(&ces, ces_lc);
+ IDProperty *idprop = IDP_GetPropertyFromGroup(props, name);
+ idprop->data.val = value;
+}
- if (BLI_findptr(&lc->object_bases, base, offsetof(LinkData, data)) != NULL) {
- collection_engine_settings_merge(ces_ob, &ces);
- }
+/* Engine Settings recalculate */
- /* do it recursively */
- for (LayerCollection *lcn = lc->layer_collections.first; lcn; lcn = lcn->next) {
- layer_collection_engine_settings_update(lcn, &ces, base, ces_ob);
- }
+/* get all the default settings defined in scene and merge them here */
+static void collection_engine_settings_init(IDProperty *root, const bool populate)
+{
+ /* render engines */
+ collection_create_render_settings(root, populate);
- BKE_layer_collection_engine_settings_free(&ces);
+ /* mode engines */
+ collection_create_mode_settings(root, populate);
}
/**
- * Update the collection settings pointer allocated in the object
- * This is to be flushed from the Depsgraph
+ * Initialize the render setings
+ * It's used mainly for scenes
*/
-static void scene_layer_engine_settings_update(SceneLayer *sl, Object *ob, const char *engine_name)
+void BKE_layer_collection_engine_settings_create(IDProperty *root)
{
- Base *base = BKE_scene_layer_base_find(sl, ob);
- 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, base, ces_ob);
- }
-
- BKE_layer_collection_engine_settings_free(&ces_layer);
- ob->collection_settings = ces_ob;
+ collection_engine_settings_init(root, true);
}
/* ---------------------------------------------------------------------- */
@@ -1094,3 +1339,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;
+ }
+ }
+}