Depsgraph: Use dedicated function for group evaluation
authorSergey Sharybin <sergey.vfx@gmail.com>
Fri, 8 Dec 2017 13:45:15 +0000 (14:45 +0100)
committerSergey Sharybin <sergey.vfx@gmail.com>
Fri, 8 Dec 2017 14:05:38 +0000 (15:05 +0100)
It is still based on generic collection evaluation, but the idea is to avoid
having view_layer pointer passed from group to it's evaluation function.

This is essential for copy-on-write, where we need to pass view_layer pointer
from a copied datablock, but that copy is not yet available at construction
time. Also, this is NOT the case where we want to expand datablock at a
construction time, just to keep our life easier.

source/blender/blenkernel/BKE_group.h
source/blender/blenkernel/intern/group.c
source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
source/blender/depsgraph/intern/builder/deg_builder_relations.cc

index ac436876dc43713496b1b3ef879c694f15fc9aae..b522ad65fe783c5578c91c5c455e3c35e1d25c68 100644 (file)
@@ -55,6 +55,13 @@ bool          BKE_group_is_animated(struct Group *group, struct Object *parent);
 
 void          BKE_group_handle_recalc_and_update(const struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *parent, struct Group *group);
 
+/* Dependency graph evaluation. */
+
+void BKE_group_eval_view_layers(const struct EvaluationContext *eval_ctx,
+                                struct Group *group);
+
+/* Helper macros. */
+
 #define FOREACH_GROUP_BASE(_group, _base)                         \
        for (Base *_base = (Base *)(_group)->view_layer->object_bases.first; \
             _base;                                                   \
index 1bc2e951fe78a900db5bb45f0b586b9829e421cc..fbd4f07a93f8428b7df07c3cc57b3f325b24665e 100644 (file)
@@ -55,6 +55,8 @@
 #include "BKE_object.h"
 #include "BKE_scene.h"
 
+#define DEBUG_PRINT if (G.debug & G_DEBUG_DEPSGRAPH) printf
+
 /** Free (or release) any data used by this group (does not free the group itself). */
 void BKE_group_free(Group *group)
 {
@@ -379,3 +381,36 @@ void BKE_group_handle_recalc_and_update(const struct EvaluationContext *eval_ctx
                FOREACH_GROUP_OBJECT_END
        }
 }
+
+/* ******** Dependency graph evaluation ******** */
+
+static void group_eval_layer_collections(
+        const struct EvaluationContext *eval_ctx,
+        Group *group,
+        ListBase *layer_collections,
+        LayerCollection *parent_layer_collection)
+{
+       LINKLIST_FOREACH (LayerCollection *, layer_collection, layer_collections) {
+               /* Evaluate layer collection itself. */
+               BKE_layer_eval_layer_collection(eval_ctx,
+                                               layer_collection,
+                                               parent_layer_collection);
+               /* Evaluate nested collections. */
+               group_eval_layer_collections(eval_ctx,
+                                            group,
+                                            &layer_collection->layer_collections,
+                                            layer_collection);
+       }
+}
+
+void BKE_group_eval_view_layers(const struct EvaluationContext *eval_ctx,
+                                Group *group)
+{
+       DEBUG_PRINT("%s on %s (%p)\n", __func__, group->id.name, group);
+       BKE_layer_eval_layer_collection_pre(eval_ctx, &group->id, group->view_layer);
+       group_eval_layer_collections(eval_ctx,
+                                    group,
+                                    &group->view_layer->layer_collections,
+                                    NULL);
+       BKE_layer_eval_layer_collection_post(eval_ctx, group->view_layer);
+}
index 342ce8e862b7fb2741f5a81afcc7d492cf489c6b..17831fc1ccd6857e82bf7d0275546200635284d6 100644 (file)
@@ -422,16 +422,27 @@ void DepsgraphNodeBuilder::end_build()
 void DepsgraphNodeBuilder::build_group(Group *group)
 {
        ID *group_id = &group->id;
+       Group *group_cow = get_cow_datablock(group);
        if (group_id->tag & LIB_TAG_DOIT) {
                return;
        }
        group_id->tag |= LIB_TAG_DOIT;
-
+       /* Build group objects. */
        LINKLIST_FOREACH(Base *, base, &group->view_layer->object_bases) {
                build_object(NULL, base->object, DEG_ID_LINKED_INDIRECTLY);
        }
-
-       build_view_layer_collections(&group->id, group->view_layer);
+       /* Operation to evaluate the whole view layer.
+        *
+        * NOTE: We re-use DONE opcode even though the function does everything.
+        * This way we wouldn't need to worry about possible relations from DONE,
+        * regardless whether it's a group or scene or something else.
+        */
+       add_operation_node(group_id,
+                          DEG_NODE_TYPE_LAYER_COLLECTIONS,
+                          function_bind(BKE_group_eval_view_layers,
+                                        _1,
+                                        group_cow),
+                          DEG_OPCODE_VIEW_LAYER_DONE);
 }
 
 void DepsgraphNodeBuilder::build_object(Base *base,
index 890e6c050d0974f7322300c5a4fca16416f2825e..2caa0d4ed5a580f08b870715831abb8e2482a71c 100644 (file)
@@ -429,8 +429,6 @@ void DepsgraphRelationBuilder::build_group(Object *object, Group *group)
                LINKLIST_FOREACH(Base *, base, &group->view_layer->object_bases) {
                        build_object(NULL, base->object);
                }
-
-               build_view_layer_collections(&group->id, group->view_layer);
                group_id->tag |= LIB_TAG_DOIT;
        }