Depsgraph: Fix missing point cache reset when physics changes
authorSergey Sharybin <sergey.vfx@gmail.com>
Wed, 14 Nov 2018 10:24:54 +0000 (11:24 +0100)
committerSergey Sharybin <sergey.vfx@gmail.com>
Wed, 14 Nov 2018 13:08:39 +0000 (14:08 +0100)
Among all the lines moved around, the general idea is quite simple.
Actually, there are two ideas implemented there.

First one, is when object itself is tagged for update, we tag its
point cache component for evaluation, which makes it so point cache
is properly reset. We do it implicitly because otherwise we'll need
to go everywhere and add explicit tag in almost all the properties.

Second thing is, we link all collider and force fields to a point
cache component using special type of link. This type of link only
allows flush if change is caused by a user update. This way reset
does not happen when change is caused due to animation, but will
properly happen when user causes indirect change to the objects
which are part of physics simulation.

26 files changed:
source/blender/blenkernel/BKE_object.h
source/blender/blenkernel/intern/object_update.c
source/blender/depsgraph/DEG_depsgraph.h
source/blender/depsgraph/DEG_depsgraph_build.h
source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
source/blender/depsgraph/intern/builder/deg_builder_nodes.h
source/blender/depsgraph/intern/builder/deg_builder_relations.cc
source/blender/depsgraph/intern/builder/deg_builder_relations.h
source/blender/depsgraph/intern/debug/deg_debug_relations_graphviz.cc
source/blender/depsgraph/intern/depsgraph.h
source/blender/depsgraph/intern/depsgraph_build.cc
source/blender/depsgraph/intern/depsgraph_eval.cc
source/blender/depsgraph/intern/depsgraph_physics.cc
source/blender/depsgraph/intern/depsgraph_tag.cc
source/blender/depsgraph/intern/depsgraph_type_defines.cc
source/blender/depsgraph/intern/depsgraph_types.h
source/blender/depsgraph/intern/eval/deg_eval_flush.cc
source/blender/depsgraph/intern/nodes/deg_node.h
source/blender/depsgraph/intern/nodes/deg_node_component.cc
source/blender/depsgraph/intern/nodes/deg_node_component.h
source/blender/depsgraph/intern/nodes/deg_node_id.cc
source/blender/depsgraph/intern/nodes/deg_node_id.h
source/blender/depsgraph/intern/nodes/deg_node_operation.cc
source/blender/depsgraph/intern/nodes/deg_node_operation.h
source/blender/depsgraph/intern/nodes/deg_node_time.cc
source/blender/depsgraph/intern/nodes/deg_node_time.h

index 8085c5416008a0e8956f6e8011fbeda477b2e57e..6d950ec01f642541e8f14a374f3406bbb6e519d6 100644 (file)
@@ -245,7 +245,7 @@ void BKE_object_eval_uber_data(
         struct Scene *scene,
         struct Object *ob);
 
-void BKE_object_eval_cloth(
+void BKE_object_eval_ptcache_reset(
         struct Depsgraph *depsgraph,
         struct Scene *scene,
         struct Object *object);
index 902237d7ac81aac2836ea668ce6175caf6c4298f..267f64aa53f14bfd9f6a4171c2f02681b7af1b4c 100644 (file)
@@ -343,9 +343,9 @@ void BKE_object_eval_uber_data(Depsgraph *depsgraph,
        BKE_object_batch_cache_dirty_tag(ob);
 }
 
-void BKE_object_eval_cloth(Depsgraph *depsgraph,
-                           Scene *scene,
-                           Object *object)
+void BKE_object_eval_ptcache_reset(Depsgraph *depsgraph,
+                                   Scene *scene,
+                                   Object *object)
 {
        DEG_debug_print_eval(depsgraph, __func__, object->id.name, object);
        BKE_ptcache_object_reset(scene, object, PTCACHE_RESET_DEPSGRAPH);
index 75572a9144042463fabbb9d915ffea19ea3397c9..fa2675297bc2182691f9f7ff08ed42a72a861fd7 100644 (file)
@@ -147,11 +147,12 @@ typedef enum eDepsgraph_Tag {
        /* Tag shading components for update.
         * Only parameters of material changed).
         */
-       DEG_TAG_SHADING_UPDATE  = (1 << 9),
-       DEG_TAG_SELECT_UPDATE   = (1 << 10),
-       DEG_TAG_BASE_FLAGS_UPDATE = (1 << 11),
+       DEG_TAG_SHADING_UPDATE       = (1 << 9),
+       DEG_TAG_SELECT_UPDATE        = (1 << 10),
+       DEG_TAG_BASE_FLAGS_UPDATE    = (1 << 11),
+       DEG_TAG_POINT_CACHE_UPDATE   = (1 << 12),
        /* Only inform editors about the change. Don't modify datablock itself. */
-       DEG_TAG_EDITORS_UPDATE = (1 << 12),
+       DEG_TAG_EDITORS_UPDATE = (1 << 13),
 } eDepsgraph_Tag;
 
 const char *DEG_update_tag_as_string(eDepsgraph_Tag flag);
index 1895b483644dc0ea04b72d1b16ca3c13f16dfeab..93e9b5be2cccc53c29b7ce1727e6079cccceafd9 100644 (file)
@@ -131,15 +131,15 @@ typedef enum eDepsObjectComponentType {
        DEG_OB_COMP_CACHE,
 } eDepsObjectComponentType;
 
-void DEG_add_scene_relation(struct DepsNodeHandle *node,
+void DEG_add_scene_relation(struct DepsNodeHandle *node_handle,
                             struct Scene *scene,
                             eDepsSceneComponentType component,
                             const char *description);
-void DEG_add_object_relation(struct DepsNodeHandle *node,
+void DEG_add_object_relation(struct DepsNodeHandle *node_handle,
                              struct Object *object,
                              eDepsObjectComponentType component,
                              const char *description);
-void DEG_add_object_relation_with_customdata(struct DepsNodeHandle *node,
+void DEG_add_object_relation_with_customdata(struct DepsNodeHandle *node_handle,
                                              struct Object *object,
                                              eDepsObjectComponentType component,
                                              uint64_t customdata_mask,
@@ -154,9 +154,18 @@ void DEG_add_object_cache_relation(struct DepsNodeHandle *handle,
                                    eDepsObjectComponentType component,
                                    const char *description);
 
+/* Adds relations from the given component of a given object to the given node
+ * handle AND the component to the point cache component of the node's ID.
+ */
+void DEG_add_object_pointcache_relation(struct DepsNodeHandle *node_handle,
+                                        struct Object *object,
+                                        eDepsObjectComponentType component,
+                                        const char *description);
+
 void DEG_add_special_eval_flag(struct DepsNodeHandle *handle, struct ID *id, uint32_t flag);
 
-struct Depsgraph *DEG_get_graph_from_handle(struct DepsNodeHandle *handle);
+struct ID *DEG_get_id_from_handle(struct DepsNodeHandle *node_handle);
+struct Depsgraph *DEG_get_graph_from_handle(struct DepsNodeHandle *node_handle);
 
 /* ************************************************ */
 
index e8e3e241ebfc890d208611060b40ee34fa202388..637fd5887a07e3aedb0e63355aec26fa87f23904 100644 (file)
@@ -399,7 +399,10 @@ void DepsgraphNodeBuilder::end_build()
                if (op_node == NULL) {
                        continue;
                }
-               op_node->tag_update(graph_);
+               /* Since the tag is coming from a saved copy of entry tags, this means
+                * that originally node was explicitly tagged for user update.
+                */
+               op_node->tag_update(graph_, DEG_UPDATE_SOURCE_USER_EDIT);
        }
 }
 
@@ -818,6 +821,22 @@ void DepsgraphNodeBuilder::build_object_constraints(Object *object)
                           DEG_OPCODE_TRANSFORM_CONSTRAINTS);
 }
 
+void DepsgraphNodeBuilder::build_object_pointcache(Object *object)
+{
+       if (!BKE_ptcache_object_has(scene_, object, 0)) {
+               return;
+       }
+       Scene *scene_cow = get_cow_datablock(scene_);
+       Object *object_cow = get_cow_datablock(object);
+       add_operation_node(&object->id,
+                          DEG_NODE_TYPE_POINT_CACHE,
+                          function_bind(BKE_object_eval_ptcache_reset,
+                                        _1,
+                                        scene_cow,
+                                        object_cow),
+                          DEG_OPCODE_POINT_CACHE_RESET);
+}
+
 /**
  * Build graph nodes for AnimData block
  * \param id: ID-Block which hosts the AnimData
@@ -1123,15 +1142,6 @@ void DepsgraphNodeBuilder::build_particles(Object *object,
                                break;
                }
        }
-
-       /* TODO(sergey): Do we need a point cache operations here? */
-       add_operation_node(&object->id,
-                          DEG_NODE_TYPE_CACHE,
-                          function_bind(BKE_ptcache_object_reset,
-                                        scene_cow,
-                                        ob_cow,
-                                        PTCACHE_RESET_DEPSGRAPH),
-                          DEG_OPCODE_POINT_CACHE_RESET);
 }
 
 void DepsgraphNodeBuilder::build_particle_settings(ParticleSettings *part) {
@@ -1147,19 +1157,6 @@ void DepsgraphNodeBuilder::build_particle_settings(ParticleSettings *part) {
                           DEG_OPCODE_PARTICLE_SETTINGS_EVAL);
 }
 
-void DepsgraphNodeBuilder::build_cloth(Object *object)
-{
-       Scene *scene_cow = get_cow_datablock(scene_);
-       Object *object_cow = get_cow_datablock(object);
-       add_operation_node(&object->id,
-                          DEG_NODE_TYPE_CACHE,
-                          function_bind(BKE_object_eval_cloth,
-                                        _1,
-                                        scene_cow,
-                                        object_cow),
-                          DEG_OPCODE_GEOMETRY_CLOTH_MODIFIER);
-}
-
 /* Shapekeys */
 void DepsgraphNodeBuilder::build_shapekeys(Key *key)
 {
@@ -1204,13 +1201,6 @@ void DepsgraphNodeBuilder::build_object_data_geometry(
                                     DEG_OPCODE_PLACEHOLDER,
                                     "Eval Init");
        op_node->set_as_entry();
-       // TODO: "Done" operation
-       /* Cloth modifier. */
-       LISTBASE_FOREACH (ModifierData *, md, &object->modifiers) {
-               if (md->type == eModifierType_Cloth) {
-                       build_cloth(object);
-               }
-       }
        /* Materials. */
        if (object->totcol != 0) {
                if (object->type == OB_MESH) {
@@ -1221,7 +1211,6 @@ void DepsgraphNodeBuilder::build_object_data_geometry(
                                                         object_cow),
                                           DEG_OPCODE_SHADING);
                }
-
                for (int a = 1; a <= object->totcol; a++) {
                        Material *ma = give_current_material(object, a);
                        if (ma != NULL) {
@@ -1229,10 +1218,9 @@ void DepsgraphNodeBuilder::build_object_data_geometry(
                        }
                }
        }
-       /* Geometry collision. */
-       if (ELEM(object->type, OB_MESH, OB_CURVE, OB_LATTICE)) {
-               // add geometry collider relations
-       }
+       /* Point caches. */
+       build_object_pointcache(object);
+       /* Geometry. */
        build_object_data_geometry_datablock((ID *)object->data, is_object_visible);
 }
 
index b826a2979ccd4e2645f62e6060639d088195924b..3c0c5f749ca504479f464abcd6df91fcda8b9d05 100644 (file)
@@ -183,6 +183,7 @@ struct DepsgraphNodeBuilder {
        void build_object_data_speaker(Object *object);
        void build_object_transform(Object *object);
        void build_object_constraints(Object *object);
+       void build_object_pointcache(Object *object);
        void build_pose_constraints(Object *object,
                                    bPoseChannel *pchan,
                                    int pchan_index,
@@ -190,7 +191,6 @@ struct DepsgraphNodeBuilder {
        void build_rigidbody(Scene *scene);
        void build_particles(Object *object, bool is_object_visible);
        void build_particle_settings(ParticleSettings *part);
-       void build_cloth(Object *object);
        void build_animdata(ID *id);
        void build_animdata_nlastrip_targets(ListBase *strips);
        void build_action(bAction *action);
index d336bfb6188b091277442d9eda2e3a889de3b053..e66c3a25e336726d4198d57896488ddb7c4f16b4 100644 (file)
@@ -87,6 +87,7 @@ extern "C" {
 #include "BKE_node.h"
 #include "BKE_object.h"
 #include "BKE_particle.h"
+#include "BKE_pointcache.h"
 #include "BKE_rigidbody.h"
 #include "BKE_shader_fx.h"
 #include "BKE_shrinkwrap.h"
@@ -184,9 +185,13 @@ static bool check_id_has_anim_component(ID *id)
               (!BLI_listbase_is_empty(&adt->nla_tracks));
 }
 
-static eDepsOperation_Code bone_target_opcode(ID *target, const char *subtarget, ID *id, const char *component_subdata, RootPChanMap *root_map)
+static eDepsOperation_Code bone_target_opcode(ID *target,
+                                              const char *subtarget,
+                                              ID *id,
+                                              const char *component_subdata,
+                                              RootPChanMap *root_map)
 {
-       /* same armature  */
+       /* Same armature.  */
        if (target == id) {
                /* Using "done" here breaks in-chain deps, while using
                 * "ready" here breaks most production rigs instead.
@@ -197,7 +202,6 @@ static eDepsOperation_Code bone_target_opcode(ID *target, const char *subtarget,
                        return DEG_OPCODE_BONE_READY;
                }
        }
-
        return DEG_OPCODE_BONE_DONE;
 }
 
@@ -642,6 +646,8 @@ void DepsgraphRelationBuilder::build_object(Base *base, Object *object)
        if (object->dup_group != NULL) {
                build_collection(object, object->dup_group);
        }
+       /* Point caches. */
+       build_object_pointcache(object);
 }
 
 void DepsgraphRelationBuilder::build_object_flags(Base *base, Object *object)
@@ -846,11 +852,47 @@ void DepsgraphRelationBuilder::build_object_parent(Object *object)
                        break;
                }
        }
+}
 
-       /* exception case: parent is duplivert */
-       if ((object->type == OB_MBALL) && (object->parent->transflag & OB_DUPLIVERTS)) {
-               //dag_add_relation(dag, node2, node, DAG_RL_DATA_DATA | DAG_RL_OB_OB, "Duplivert");
+void DepsgraphRelationBuilder::build_object_pointcache(Object *object)
+{
+       ComponentKey point_cache_key(&object->id, DEG_NODE_TYPE_POINT_CACHE);
+       /* Different point caches are affecting different aspects of life of the
+        * object. We keep track of those aspects and avoid duplicate relations. */
+       enum {
+               FLAG_TRANSFORM = (1 << 0),
+               FLAG_GEOMETRY = (1 << 1),
+               FLAG_ALL = (FLAG_TRANSFORM | FLAG_GEOMETRY),
+       };
+       ListBase ptcache_id_list;
+       BKE_ptcache_ids_from_object(&ptcache_id_list, object, scene_, 0);
+       int handled_components = 0;
+       LISTBASE_FOREACH (PTCacheID *, ptcache_id, &ptcache_id_list) {
+               /* Check which components needs the point cache. */
+               int flag;
+               if (ptcache_id->type == PTCACHE_TYPE_RIGIDBODY) {
+                       flag = FLAG_TRANSFORM;
+                       ComponentKey transform_key(&object->id,
+                                                  DEG_NODE_TYPE_TRANSFORM);
+                       add_relation(point_cache_key,
+                                    transform_key,
+                                    "Point Cache -> Rigid Body");
+               }
+               else {
+                       flag = FLAG_GEOMETRY;
+                       ComponentKey geometry_key(&object->id,
+                                                  DEG_NODE_TYPE_GEOMETRY);
+                       add_relation(point_cache_key,
+                                    geometry_key,
+                                    "Point Cache -> Geometry");
+               }
+               /* Tag that we did handle that component. */
+               handled_components |= flag;
+               if (handled_components == FLAG_ALL) {
+                       break;
+               }
        }
+       BLI_freelistN(&ptcache_id_list);
 }
 
 void DepsgraphRelationBuilder::build_constraints(ID *id,
@@ -1744,12 +1786,6 @@ void DepsgraphRelationBuilder::build_particles(Object *object)
         */
        ComponentKey transform_key(&object->id, DEG_NODE_TYPE_TRANSFORM);
        add_relation(transform_key, obdata_ubereval_key, "Partcile Eval");
-
-       OperationKey point_cache_reset_key(&object->id,
-                                          DEG_NODE_TYPE_CACHE,
-                                          DEG_OPCODE_POINT_CACHE_RESET);
-       add_relation(transform_key, point_cache_reset_key, "Object Transform -> Point Cache Reset");
-       add_relation(point_cache_reset_key, obdata_ubereval_key, "Point Cache Reset -> UberEval");
 }
 
 void DepsgraphRelationBuilder::build_particle_settings(ParticleSettings *part)
@@ -1783,19 +1819,6 @@ void DepsgraphRelationBuilder::build_particles_visualization_object(
        }
 }
 
-void DepsgraphRelationBuilder::build_cloth(Object *object,
-                                           ModifierData * /*md*/)
-{
-       OperationKey cache_key(&object->id,
-                              DEG_NODE_TYPE_CACHE,
-                              DEG_OPCODE_GEOMETRY_CLOTH_MODIFIER);
-       /* Cache component affects on modifier. */
-       OperationKey modifier_key(&object->id,
-                                 DEG_NODE_TYPE_GEOMETRY,
-                                 DEG_OPCODE_GEOMETRY_UBEREVAL);
-       add_relation(cache_key, modifier_key, "Cloth Cache -> Cloth");
-}
-
 /* Shapekeys */
 void DepsgraphRelationBuilder::build_shapekeys(Key *key)
 {
@@ -1869,9 +1892,6 @@ void DepsgraphRelationBuilder::build_object_data_geometry(Object *object)
                                TimeSourceKey time_src_key;
                                add_relation(time_src_key, obdata_ubereval_key, "Time Source");
                        }
-                       if (md->type == eModifierType_Cloth) {
-                               build_cloth(object, md);
-                       }
                }
        }
        /* Grease Pencil Modifiers */
index e5854fa8d20d67bfbc1ea3616db5072075aa8444..e86c6504693e661402961e98fb9818a81cca6b78 100644 (file)
@@ -217,6 +217,7 @@ struct DepsgraphRelationBuilder
        void build_object_data_lightprobe(Object *object);
        void build_object_data_speaker(Object *object);
        void build_object_parent(Object *object);
+       void build_object_pointcache(Object *object);
        void build_constraints(ID *id,
                               eDepsNode_Type component_type,
                               const char *component_subdata,
@@ -244,7 +245,6 @@ struct DepsgraphRelationBuilder
        void build_particles_visualization_object(Object *object,
                                                  ParticleSystem *psys,
                                                  Object *draw_object);
-       void build_cloth(Object *object, ModifierData *md);
        void build_ik_pose(Object *object,
                           bPoseChannel *pchan,
                           bConstraint *con,
index 47cb3ebcd914a2ea4ac54a36abe6a52dc08fee4b..39dfac2fca744cb564eab0bad91d799c8b88e5f4 100644 (file)
@@ -69,6 +69,7 @@ static const char *deg_debug_colors[] = {
     "#33a02c", "#fb9a99", "#e31a1c",
     "#fdbf6f", "#ff7f00", "#cab2d6",
     "#6a3d9a", "#ffff99", "#b15928",
+    "#ff00ff",
 };
 #endif
 static const char *deg_debug_colors_light[] = {
@@ -76,6 +77,7 @@ static const char *deg_debug_colors_light[] = {
     "#fb8072", "#80b1d3", "#fdb462",
     "#b3de69", "#fccde5", "#d9d9d9",
     "#bc80bd", "#ccebc5", "#ffed6f",
+    "#ff00ff",
 };
 
 #ifdef COLOR_SCHEME_NODE_TYPE
@@ -84,18 +86,19 @@ static const int deg_debug_node_type_color_map[][2] = {
     {DEG_NODE_TYPE_ID_REF,       1},
 
     /* Outer Types */
-    {DEG_NODE_TYPE_PARAMETERS,        2},
-    {DEG_NODE_TYPE_PROXY,             3},
-    {DEG_NODE_TYPE_ANIMATION,         4},
-    {DEG_NODE_TYPE_TRANSFORM,         5},
-    {DEG_NODE_TYPE_GEOMETRY,          6},
-    {DEG_NODE_TYPE_SEQUENCER,         7},
-    {DEG_NODE_TYPE_SHADING,           8},
+    {DEG_NODE_TYPE_PARAMETERS,         2},
+    {DEG_NODE_TYPE_PROXY,              3},
+    {DEG_NODE_TYPE_ANIMATION,          4},
+    {DEG_NODE_TYPE_TRANSFORM,          5},
+    {DEG_NODE_TYPE_GEOMETRY,           6},
+    {DEG_NODE_TYPE_SEQUENCER,          7},
+    {DEG_NODE_TYPE_SHADING,            8},
     {DEG_NODE_TYPE_SHADING_PARAMETERS, 9},
-    {DEG_NODE_TYPE_CACHE,             10},
-    {DEG_NODE_TYPE_LAYER_COLLECTIONS, 11},
-    {DEG_NODE_TYPE_COPY_ON_WRITE,     12},
-    {-1,                              0}
+    {DEG_NODE_TYPE_CACHE,              10},
+    {DEG_NODE_TYPE_POINT_CACHE,        11},
+    {DEG_NODE_TYPE_LAYER_COLLECTIONS , 12},
+    {DEG_NODE_TYPE_COPY_ON_WRITE,      13},
+    {-1,                               0}
 };
 #endif
 
@@ -264,10 +267,14 @@ static void deg_debug_graphviz_relation_style(const DebugContext &ctx,
 {
        const char *style_default = "solid";
        const char *style_no_flush = "dashed";
+       const char *style_flush_user_only = "dotted";
        const char *style = style_default;
        if (rel->flag & DEPSREL_FLAG_NO_FLUSH) {
                style = style_no_flush;
        }
+       if (rel->flag & DEPSREL_FLAG_FLUSH_USER_EDIT_ONLY) {
+               style = style_flush_user_only;
+       }
        deg_debug_fprintf(ctx, "%s", style);
 }
 
@@ -403,6 +410,7 @@ static void deg_debug_graphviz_node(const DebugContext &ctx,
                case DEG_NODE_TYPE_SHADING:
                case DEG_NODE_TYPE_SHADING_PARAMETERS:
                case DEG_NODE_TYPE_CACHE:
+               case DEG_NODE_TYPE_POINT_CACHE:
                case DEG_NODE_TYPE_LAYER_COLLECTIONS:
                case DEG_NODE_TYPE_EVAL_PARTICLES:
                case DEG_NODE_TYPE_COPY_ON_WRITE:
index 3e7d34414eac9b2c4a6baa3fc44b1dad62449c2f..bbf1f883bde56aeede53fdbe10885db8151ca8f4 100644 (file)
@@ -72,11 +72,13 @@ struct OperationDepsNode;
 /* Settings/Tags on Relationship */
 typedef enum eDepsRelation_Flag {
        /* "cyclic" link - when detecting cycles, this relationship was the one
-        * which triggers a cyclic relationship to exist in the graph.
-        */
-       DEPSREL_FLAG_CYCLIC     = (1 << 0),
+        * which triggers a cyclic relationship to exist in the graph. */
+       DEPSREL_FLAG_CYCLIC               = (1 << 0),
        /* Update flush will not go through this relation. */
-       DEPSREL_FLAG_NO_FLUSH   = (1 << 1),
+       DEPSREL_FLAG_NO_FLUSH             = (1 << 1),
+       /* Only flush along the relation is update comes from a node which was
+        * affected by user input. */
+       DEPSREL_FLAG_FLUSH_USER_EDIT_ONLY = (1 << 2),
 } eDepsRelation_Flag;
 
 /* B depends on A (A -> B) */
index f5b84b91dbe6a2973823649e6c69cbf7246a448b..64adfa1ceeaaf8d8dbf90ff6871c11c19c1e815c 100644 (file)
@@ -99,38 +99,38 @@ static DEG::eDepsNode_Type deg_build_object_component_type(
        return DEG::DEG_NODE_TYPE_UNDEFINED;
 }
 
-static DEG::DepsNodeHandle *get_handle(DepsNodeHandle *handle)
+static DEG::DepsNodeHandle *get_node_handle(DepsNodeHandle *node_handle)
 {
-       return reinterpret_cast<DEG::DepsNodeHandle *>(handle);
+       return reinterpret_cast<DEG::DepsNodeHandle *>(node_handle);
 }
 
-void DEG_add_scene_relation(DepsNodeHandle *handle,
+void DEG_add_scene_relation(DepsNodeHandle *node_handle,
                             Scene *scene,
                             eDepsSceneComponentType component,
                             const char *description)
 {
        DEG::eDepsNode_Type type = deg_build_scene_component_type(component);
        DEG::ComponentKey comp_key(&scene->id, type);
-       DEG::DepsNodeHandle *deg_handle = get_handle(handle);
-       deg_handle->builder->add_node_handle_relation(comp_key,
-                                                     deg_handle,
-                                                     description);
+       DEG::DepsNodeHandle *deg_node_handle = get_node_handle(node_handle);
+       deg_node_handle->builder->add_node_handle_relation(comp_key,
+                                                          deg_node_handle,
+                                                          description);
 }
 
-void DEG_add_object_relation(DepsNodeHandle *handle,
+void DEG_add_object_relation(DepsNodeHandle *node_handle,
                              Object *object,
                              eDepsObjectComponentType component,
                              const char *description)
 {
        DEG::eDepsNode_Type type = deg_build_object_component_type(component);
        DEG::ComponentKey comp_key(&object->id, type);
-       DEG::DepsNodeHandle *deg_handle = get_handle(handle);
-       deg_handle->builder->add_node_handle_relation(comp_key,
-                                                     deg_handle,
-                                                     description);
+       DEG::DepsNodeHandle *deg_node_handle = get_node_handle(node_handle);
+       deg_node_handle->builder->add_node_handle_relation(comp_key,
+                                                          deg_node_handle,
+                                                          description);
 }
 
-void DEG_add_object_relation_with_customdata(DepsNodeHandle *handle,
+void DEG_add_object_relation_with_customdata(DepsNodeHandle *node_handle,
                                              Object *object,
                                              eDepsObjectComponentType component,
                                              uint64_t customdata_mask,
@@ -138,29 +138,29 @@ void DEG_add_object_relation_with_customdata(DepsNodeHandle *handle,
 {
        DEG::eDepsNode_Type type = deg_build_object_component_type(component);
        DEG::ComponentKey comp_key(&object->id, type);
-       DEG::DepsNodeHandle *deg_handle = get_handle(handle);
-       deg_handle->builder->add_node_handle_relation(comp_key,
-                                                     deg_handle,
-                                                     description);
+       DEG::DepsNodeHandle *deg_node_handle = get_node_handle(node_handle);
+       deg_node_handle->builder->add_node_handle_relation(comp_key,
+                                                          deg_node_handle,
+                                                          description);
        if (object->type == OB_MESH) {
-               deg_handle->builder->add_customdata_mask(comp_key, customdata_mask);
+               deg_node_handle->builder->add_customdata_mask(comp_key, customdata_mask);
        }
 }
 
-void DEG_add_object_cache_relation(DepsNodeHandle *handle,
+void DEG_add_object_cache_relation(DepsNodeHandle *node_handle,
                                    CacheFile *cache_file,
                                    eDepsObjectComponentType component,
                                    const char *description)
 {
        DEG::eDepsNode_Type type = deg_build_object_component_type(component);
        DEG::ComponentKey comp_key(&cache_file->id, type);
-       DEG::DepsNodeHandle *deg_handle = get_handle(handle);
-       deg_handle->builder->add_node_handle_relation(comp_key,
-                                                     deg_handle,
-                                                     description);
+       DEG::DepsNodeHandle *deg_node_handle = get_node_handle(node_handle);
+       deg_node_handle->builder->add_node_handle_relation(comp_key,
+                                                          deg_node_handle,
+                                                          description);
 }
 
-void DEG_add_bone_relation(DepsNodeHandle *handle,
+void DEG_add_bone_relation(DepsNodeHandle *node_handle,
                            Object *object,
                            const char *bone_name,
                            eDepsObjectComponentType component,
@@ -168,25 +168,50 @@ void DEG_add_bone_relation(DepsNodeHandle *handle,
 {
        DEG::eDepsNode_Type type = deg_build_object_component_type(component);
        DEG::ComponentKey comp_key(&object->id, type, bone_name);
-       DEG::DepsNodeHandle *deg_handle = get_handle(handle);
-       /* XXX: "Geometry Eval" might not always be true, but this only gets called
-        * from modifier building now.
-        */
-       deg_handle->builder->add_node_handle_relation(comp_key,
-                                                     deg_handle,
-                                                     description);
+       DEG::DepsNodeHandle *deg_node_handle = get_node_handle(node_handle);
+       deg_node_handle->builder->add_node_handle_relation(comp_key,
+                                                          deg_node_handle,
+                                                          description);
+}
+
+void DEG_add_object_pointcache_relation(struct DepsNodeHandle *node_handle,
+                                        struct Object *object,
+                                        eDepsObjectComponentType component,
+                                        const char *description)
+{
+       DEG::eDepsNode_Type type = deg_build_object_component_type(component);
+       DEG::ComponentKey comp_key(&object->id, type);
+       DEG::DepsNodeHandle *deg_node_handle = get_node_handle(node_handle);
+       DEG::DepsgraphRelationBuilder *relation_builder = deg_node_handle->builder;
+       /* Add relation from source to the node handle. */
+       relation_builder->add_node_handle_relation(
+               comp_key, deg_node_handle, description);
+       /* Node deduct point cache component and connect source to it. */
+       ID *id = DEG_get_id_from_handle(node_handle);
+       DEG::ComponentKey point_cache_key(id, DEG::DEG_NODE_TYPE_POINT_CACHE);
+       DEG::DepsRelation *rel = relation_builder->add_relation(
+               comp_key, point_cache_key, "Point Cache");
+       rel->flag |= DEG::DEPSREL_FLAG_FLUSH_USER_EDIT_ONLY;
 }
 
-void DEG_add_special_eval_flag(struct DepsNodeHandle *handle, ID *id, uint32_t flag)
+void DEG_add_special_eval_flag(struct DepsNodeHandle *node_handle,
+                               ID *id,
+                               uint32_t flag)
 {
-       DEG::DepsNodeHandle *deg_handle = get_handle(handle);
-       deg_handle->builder->add_special_eval_flag(id, flag);
+       DEG::DepsNodeHandle *deg_node_handle = get_node_handle(node_handle);
+       deg_node_handle->builder->add_special_eval_flag(id, flag);
 }
 
-struct Depsgraph *DEG_get_graph_from_handle(struct DepsNodeHandle *handle)
+struct ID *DEG_get_id_from_handle(struct DepsNodeHandle *node_handle)
 {
-       DEG::DepsNodeHandle *deg_handle = get_handle(handle);
-       DEG::DepsgraphRelationBuilder *relation_builder = deg_handle->builder;
+       DEG::DepsNodeHandle *deg_handle = get_node_handle(node_handle);
+       return deg_handle->node->owner->owner->id_orig;
+}
+
+struct Depsgraph *DEG_get_graph_from_handle(struct DepsNodeHandle *node_handle)
+{
+       DEG::DepsNodeHandle *deg_node_handle = get_node_handle(node_handle);
+       DEG::DepsgraphRelationBuilder *relation_builder = deg_node_handle->builder;
        return reinterpret_cast<Depsgraph *>(relation_builder->getGraph());
 }
 
@@ -267,11 +292,9 @@ void DEG_graph_tag_relations_update(Depsgraph *graph)
         * TODO(sergey): Try to make it so we don't flush updates
         * to the whole depsgraph.
         */
-       {
-               DEG::IDDepsNode *id_node = deg_graph->find_id_node(&deg_graph->scene->id);
-               if (id_node != NULL) {
-                       id_node->tag_update(deg_graph);
-               }
+       DEG::IDDepsNode *id_node = deg_graph->find_id_node(&deg_graph->scene->id);
+       if (id_node != NULL) {
+               id_node->tag_update(deg_graph, DEG::DEG_UPDATE_SOURCE_RELATIONS);
        }
 }
 
index 5b6516509b0cbea15234417c38b7f98191132c5b..49eccd76f386f4f5e75232aaf290cdebced2a616 100644 (file)
@@ -80,7 +80,7 @@ void DEG_evaluate_on_framechange(Main *bmain,
        /* Update time on primary timesource. */
        DEG::TimeSourceDepsNode *tsrc = deg_graph->find_time_source();
        tsrc->cfra = ctime;
-       tsrc->tag_update(deg_graph);
+       tsrc->tag_update(deg_graph, DEG::DEG_UPDATE_SOURCE_TIME);
        DEG::deg_graph_flush_updates(bmain, deg_graph);
        /* Update time in scene. */
        if (deg_graph->scene_cow) {
index 0a54caebacee57ed811ae4846c1a94e4f6065ad8..88d4c25f7264de2a289d78b4af3348aafb22773b 100644 (file)
@@ -122,8 +122,10 @@ void DEG_add_collision_relations(DepsNodeHandle *handle,
                            ob1,
                            modifiers_findByType(ob1, (ModifierType)modifier_type)))
                {
-                       DEG_add_object_relation(handle, ob1, DEG_OB_COMP_TRANSFORM, name);
-                       DEG_add_object_relation(handle, ob1, DEG_OB_COMP_GEOMETRY, name);
+                       DEG_add_object_pointcache_relation(
+                               handle, ob1, DEG_OB_COMP_TRANSFORM, name);
+                       DEG_add_object_pointcache_relation(
+                               handle, ob1, DEG_OB_COMP_GEOMETRY, name);
                }
        }
 }
@@ -146,26 +148,25 @@ void DEG_add_forcefield_relations(DepsNodeHandle *handle,
                if (relation->pd->forcefield == skip_forcefield) {
                        continue;
                }
-               DEG_add_object_relation(
+               DEG_add_object_pointcache_relation(
                        handle, relation->ob, DEG_OB_COMP_TRANSFORM, name);
                if (relation->psys) {
                        /* TODO(sergey): Consider going more granular with more dedicated
-                        * particle system operation.
-                        */
-                       DEG_add_object_relation(
+                        * particle system operation. */
+                       DEG_add_object_pointcache_relation(
                                handle, relation->ob, DEG_OB_COMP_GEOMETRY, name);
                }
                if (relation->pd->forcefield == PFIELD_SMOKEFLOW &&
                    relation->pd->f_source != NULL)
                {
-                       DEG_add_object_relation(handle,
-                                               relation->pd->f_source,
-                                               DEG_OB_COMP_TRANSFORM,
-                                               "Smoke Force Domain");
-                       DEG_add_object_relation(handle,
-                                               relation->pd->f_source,
-                                               DEG_OB_COMP_GEOMETRY,
-                                               "Smoke Force Domain");
+                       DEG_add_object_pointcache_relation(handle,
+                                                          relation->pd->f_source,
+                                                          DEG_OB_COMP_TRANSFORM,
+                                                          "Smoke Force Domain");
+                       DEG_add_object_pointcache_relation(handle,
+                                                          relation->pd->f_source,
+                                                          DEG_OB_COMP_GEOMETRY,
+                                                          "Smoke Force Domain");
                }
                if (add_absorption && (relation->pd->flag & PFIELD_VISIBILITY)) {
                        DEG_add_collision_relations(handle,
index e2a87f16408bead0e492c6f4440c54cc5c18018e..6374354a154d6e154b98142bb9178b48ada4925d 100644 (file)
@@ -204,6 +204,10 @@ void depsgraph_tag_to_component_opcode(const ID *id,
                        depsgraph_base_flags_tag_to_component_opcode(id,
                                                                     component_type,
                                                                     operation_code);
+                       break;
+               case DEG_TAG_POINT_CACHE_UPDATE:
+                       *component_type = DEG_NODE_TYPE_POINT_CACHE;
+                       break;
                case DEG_TAG_EDITORS_UPDATE:
                        /* There is no such node in depsgraph, this tag is to be handled
                         * separately.
@@ -249,20 +253,20 @@ void depsgraph_tag_component(Depsgraph *graph,
                return;
        }
        if (operation_code == DEG_OPCODE_OPERATION) {
-               component_node->tag_update(graph);
+               component_node->tag_update(graph, DEG_UPDATE_SOURCE_USER_EDIT);
        }
        else {
                OperationDepsNode *operation_node =
                        component_node->find_operation(operation_code);
                if (operation_node != NULL) {
-                       operation_node->tag_update(graph);
+                       operation_node->tag_update(graph, DEG_UPDATE_SOURCE_USER_EDIT);
                }
        }
        /* If component depends on copy-on-write, tag it as well. */
        if (component_node->need_tag_cow_before_update()) {
                ComponentDepsNode *cow_comp =
                        id_node->find_component(DEG_NODE_TYPE_COPY_ON_WRITE);
-               cow_comp->tag_update(graph);
+               cow_comp->tag_update(graph, DEG_UPDATE_SOURCE_USER_EDIT);
                id_node->id_orig->recalc |= ID_RECALC_COPY_ON_WRITE;
        }
 }
@@ -364,7 +368,7 @@ static void deg_graph_id_tag_update_single_flag(Main *bmain,
        }
        /* Tag corresponding dependency graph operation for update. */
        if (component_type == DEG_NODE_TYPE_ID_REF) {
-               id_node->tag_update(graph);
+               id_node->tag_update(graph, DEG_UPDATE_SOURCE_USER_EDIT);
        }
        else {
                depsgraph_tag_component(graph, id_node, component_type, operation_code);
@@ -427,7 +431,7 @@ void deg_graph_node_tag_zero(Main *bmain, Depsgraph *graph, IDDepsNode *id_node)
                if (comp_node->type == DEG_NODE_TYPE_ANIMATION) {
                        continue;
                }
-               comp_node->tag_update(graph);
+               comp_node->tag_update(graph, DEG_UPDATE_SOURCE_USER_EDIT);
        }
        GHASH_FOREACH_END();
        deg_graph_id_tag_legacy_compat(bmain, graph, id, (eDepsgraph_Tag)0);
@@ -463,6 +467,11 @@ void deg_graph_id_tag_update(Main *bmain, Depsgraph *graph, ID *id, int flag)
        }
        /* Special case for nested node tree datablocks. */
        id_tag_update_ntree_special(bmain, graph, id, flag);
+       /* Direct update tags means that something outside of simulated/cached
+        * physics did change and that cache is to be invalidated.
+        */
+       deg_graph_id_tag_update_single_flag(
+               bmain, graph, id, id_node, DEG_TAG_POINT_CACHE_UPDATE);
 }
 
 void deg_id_tag_update(Main *bmain, ID *id, int flag)
@@ -515,7 +524,7 @@ void deg_graph_on_visible_update(Main *bmain, Depsgraph *graph)
                deg_graph_id_tag_update(bmain, graph, id_node->id_orig, flag);
                if (id_type == ID_SCE) {
                        /* Make sure collection properties are up to date. */
-                       id_node->tag_update(graph);
+                       id_node->tag_update(graph, DEG_UPDATE_SOURCE_VISIBILITY);
                }
                /* Now when ID is updated to the new visibility state, prevent it from
                 * being re-tagged again. Simplest way to do so is to pretend that it
@@ -590,6 +599,7 @@ const char *DEG_update_tag_as_string(eDepsgraph_Tag flag)
                case DEG_TAG_SHADING_UPDATE: return "SHADING_UPDATE";
                case DEG_TAG_SELECT_UPDATE: return "SELECT_UPDATE";
                case DEG_TAG_BASE_FLAGS_UPDATE: return "BASE_FLAGS_UPDATE";
+               case DEG_TAG_POINT_CACHE_UPDATE: return "POINT_CACHE_UPDATE";
                case DEG_TAG_EDITORS_UPDATE: return "EDITORS_UPDATE";
        }
        BLI_assert(!"Unhandled update flag, should never happen!");
index ae1f8db51ebd056578d3403e83df6074cf5da5d3..44e216565701cac2ef90ce6995fde09976755b8f 100644 (file)
@@ -100,6 +100,7 @@ const char *nodeTypeAsString(eDepsNode_Type type)
                STRINGIFY_TYPE(SHADING);
                STRINGIFY_TYPE(SHADING_PARAMETERS);
                STRINGIFY_TYPE(CACHE);
+               STRINGIFY_TYPE(POINT_CACHE);
                STRINGIFY_TYPE(BATCH_CACHE);
                /* Duplication. */
                STRINGIFY_TYPE(DUPLI);
@@ -139,7 +140,6 @@ const char *operationCodeAsString(eDepsOperation_Code opcode)
                STRINGIFY_OPCODE(RIGIDBODY_TRANSFORM_COPY);
                /* Geometry. */
                STRINGIFY_OPCODE(GEOMETRY_UBEREVAL);
-               STRINGIFY_OPCODE(GEOMETRY_CLOTH_MODIFIER);
                STRINGIFY_OPCODE(GEOMETRY_SHAPEKEY);
                /* Object data. */
                STRINGIFY_OPCODE(LIGHT_PROBE_EVAL);
index ef64fe8c5fef04233bc1a9600d0a5f3192db1f03..32ffcd79c74bf2a0f510a938a0df2beec8175122 100644 (file)
@@ -150,7 +150,10 @@ typedef enum eDepsNode_Type {
        /* Material Shading Component */
        DEG_NODE_TYPE_SHADING,
        DEG_NODE_TYPE_SHADING_PARAMETERS,
+       /* Point cache Component */
+       DEG_NODE_TYPE_POINT_CACHE,
        /* Cache Component */
+       /* TODO(sergey); Verify that we really need this. */
        DEG_NODE_TYPE_CACHE,
        /* Batch Cache Component - TODO (dfelinto/sergey) rename to make it more generic. */
        DEG_NODE_TYPE_BATCH_CACHE,
@@ -209,9 +212,10 @@ typedef enum eDepsOperation_Code {
        DEG_OPCODE_RIGIDBODY_TRANSFORM_COPY,
 
        /* Geometry. ---------------------------------------- */
+
        /* Evaluate the whole geometry, including modifiers. */
        DEG_OPCODE_GEOMETRY_UBEREVAL,
-       DEG_OPCODE_GEOMETRY_CLOTH_MODIFIER,
+       /* Evaluation of a shape key. */
        DEG_OPCODE_GEOMETRY_SHAPEKEY,
 
        /* Object data. ------------------------------------- */
@@ -287,4 +291,19 @@ typedef enum eDepsOperation_Code {
 } eDepsOperation_Code;
 const char *operationCodeAsString(eDepsOperation_Code opcode);
 
+/* Source of the dependency graph node update tag.
+ *
+ * NOTE: This is a bit mask, so accumulation of sources is possible.
+ */
+typedef enum eDepsTag_Source {
+       /* Update is caused by a time change. */
+       DEG_UPDATE_SOURCE_TIME       = (1 << 0),
+       /* Update caused by user directly or indirectly influencing the node. */
+       DEG_UPDATE_SOURCE_USER_EDIT  = (1 << 1),
+       /* Update is happening as a special response for the relations update. */
+       DEG_UPDATE_SOURCE_RELATIONS  = (1 << 2),
+       /* Update is happening due to visibility change. */
+       DEG_UPDATE_SOURCE_VISIBILITY = (1 << 3),
+} eDepsTag_Source;
+
 }  // namespace DEG
index 975723ef8a313de1c70c6c20fdc208e406641729..61edc1e37955385d957d8337d119bdd005d8fa52 100644 (file)
@@ -202,19 +202,32 @@ BLI_INLINE OperationDepsNode *flush_schedule_children(
 {
        OperationDepsNode *result = NULL;
        foreach (DepsRelation *rel, op_node->outlinks) {
+               /* Flush is forbidden, completely. */
                if (rel->flag & DEPSREL_FLAG_NO_FLUSH) {
                        continue;
                }
+               /* Relation only allows flushes on user changes, but the node was not
+                * affected by user. */
+               if ((rel->flag & DEPSREL_FLAG_FLUSH_USER_EDIT_ONLY) &&
+                   (op_node->flag & DEPSOP_FLAG_USER_MODIFIED) == 0)
+               {
+                       continue;
+               }
                OperationDepsNode *to_node = (OperationDepsNode *)rel->to;
-               if (to_node->scheduled == false) {
-                       if (result != NULL) {
-                               queue->push_front(to_node);
-                       }
-                       else {
-                               result = to_node;
-                       }
-                       to_node->scheduled = true;
+               /* Always flush flushable flags, so children always know what happened
+                * to their parents. */
+               to_node->flag |= (op_node->flag & DEPSOP_FLAG_FLUSH);
+               /* Flush update over the relation, if it was not flushed yet. */
+               if (to_node->scheduled) {
+                       continue;
+               }
+               if (result != NULL) {
+                       queue->push_front(to_node);
+               }
+               else {
+                       result = to_node;
                }
+               to_node->scheduled = true;
        }
        return result;
 }
@@ -408,7 +421,9 @@ static void graph_clear_operation_func(
        Depsgraph *graph = (Depsgraph *)data_v;
        OperationDepsNode *node = graph->operations[i];
        /* Clear node's "pending update" settings. */
-       node->flag &= ~(DEPSOP_FLAG_DIRECTLY_MODIFIED | DEPSOP_FLAG_NEEDS_UPDATE);
+       node->flag &= ~(DEPSOP_FLAG_DIRECTLY_MODIFIED |
+                       DEPSOP_FLAG_NEEDS_UPDATE |
+                       DEPSOP_FLAG_USER_MODIFIED);
 }
 
 /* Clear tags from all operation nodes. */
index ef2a73258fdb5879eab29534b9fe2f69bf4172dd..7a837d17ceb308e29fe371efbd031ec10f50c9f9 100644 (file)
@@ -98,7 +98,8 @@ struct DepsNode {
        virtual void init(const ID * /*id*/,
                          const char * /*subdata*/) {}
 
-       virtual void tag_update(Depsgraph * /*graph*/) {}
+       virtual void tag_update(Depsgraph * /*graph*/,
+                               eDepsTag_Source /*source*/) {}
 
        virtual OperationDepsNode *get_entry_operation() { return NULL; }
        virtual OperationDepsNode *get_exit_operation() { return NULL; }
index d6c3eb6157d98a40dd5a57a561b4745994d2f5ba..4bb9b9d17b3c754e7af5b21e728a1f32a2833cd5 100644 (file)
@@ -283,20 +283,20 @@ void ComponentDepsNode::clear_operations()
        operations.clear();
 }
 
-void ComponentDepsNode::tag_update(Depsgraph *graph)
+void ComponentDepsNode::tag_update(Depsgraph *graph, eDepsTag_Source source)
 {
        OperationDepsNode *entry_op = get_entry_operation();
        if (entry_op != NULL && entry_op->flag & DEPSOP_FLAG_NEEDS_UPDATE) {
                return;
        }
        foreach (OperationDepsNode *op_node, operations) {
-               op_node->tag_update(graph);
+               op_node->tag_update(graph, source);
        }
        // It is possible that tag happens before finalization.
        if (operations_map != NULL) {
                GHASH_FOREACH_BEGIN(OperationDepsNode *, op_node, operations_map)
                {
-                       op_node->tag_update(graph);
+                       op_node->tag_update(graph, source);
                }
                GHASH_FOREACH_END();
        }
@@ -392,8 +392,9 @@ DEG_COMPONENT_NODE_DEFINE(Geometry,          GEOMETRY,           ID_RECALC_GEOME
 DEG_COMPONENT_NODE_DEFINE(LayerCollections,  LAYER_COLLECTIONS,  0);
 DEG_COMPONENT_NODE_DEFINE(Parameters,        PARAMETERS,         ID_RECALC);
 DEG_COMPONENT_NODE_DEFINE(Particles,         EVAL_PARTICLES,     ID_RECALC_GEOMETRY);
-DEG_COMPONENT_NODE_DEFINE(Proxy,             PROXY,              ID_RECALC_GEOMETRY);
+DEG_COMPONENT_NODE_DEFINE(PointCache,        POINT_CACHE,        0);
 DEG_COMPONENT_NODE_DEFINE(Pose,              EVAL_POSE,          ID_RECALC_GEOMETRY);
+DEG_COMPONENT_NODE_DEFINE(Proxy,             PROXY,              ID_RECALC_GEOMETRY);
 DEG_COMPONENT_NODE_DEFINE(Sequencer,         SEQUENCER,          ID_RECALC);
 DEG_COMPONENT_NODE_DEFINE(Shading,           SHADING,            ID_RECALC_DRAW);
 DEG_COMPONENT_NODE_DEFINE(ShadingParameters, SHADING_PARAMETERS, ID_RECALC_DRAW);
@@ -414,6 +415,7 @@ void deg_register_component_depsnodes()
        deg_register_node_typeinfo(&DNTI_LAYER_COLLECTIONS);
        deg_register_node_typeinfo(&DNTI_PARAMETERS);
        deg_register_node_typeinfo(&DNTI_EVAL_PARTICLES);
+       deg_register_node_typeinfo(&DNTI_POINT_CACHE);
        deg_register_node_typeinfo(&DNTI_PROXY);
        deg_register_node_typeinfo(&DNTI_EVAL_POSE);
        deg_register_node_typeinfo(&DNTI_SEQUENCER);
index 244884554faf794ca21cfb9b64835e34f0d73401..e3057e1d3cefd0377db0e5fc4bbefdbf4fe6b32a 100644 (file)
@@ -69,9 +69,9 @@ struct ComponentDepsNode : public DepsNode {
        ComponentDepsNode();
        ~ComponentDepsNode();
 
-       void init(const ID *id, const char *subdata);
+       void init(const ID *id, const char *subdata) override;
 
-       virtual string identifier() const;
+       virtual string identifier() const override;
 
        /* Find an existing operation, if requested operation does not exist
         * NULL will be returned.
@@ -120,10 +120,10 @@ struct ComponentDepsNode : public DepsNode {
 
        void clear_operations();
 
-       void tag_update(Depsgraph *graph);
+       virtual void tag_update(Depsgraph *graph, eDepsTag_Source source) override;
 
-       OperationDepsNode *get_entry_operation();
-       OperationDepsNode *get_exit_operation();
+       virtual OperationDepsNode *get_entry_operation() override;
+       virtual OperationDepsNode *get_exit_operation() override;
 
        void finalize_build(Depsgraph *graph);
 
@@ -191,8 +191,9 @@ DEG_COMPONENT_NODE_DECLARE_GENERIC(Geometry);
 DEG_COMPONENT_NODE_DECLARE_GENERIC(LayerCollections);
 DEG_COMPONENT_NODE_DECLARE_GENERIC(Parameters);
 DEG_COMPONENT_NODE_DECLARE_GENERIC(Particles);
-DEG_COMPONENT_NODE_DECLARE_GENERIC(Proxy);
 DEG_COMPONENT_NODE_DECLARE_GENERIC(Pose);
+DEG_COMPONENT_NODE_DECLARE_GENERIC(PointCache);
+DEG_COMPONENT_NODE_DECLARE_GENERIC(Proxy);
 DEG_COMPONENT_NODE_DECLARE_GENERIC(Sequencer);
 DEG_COMPONENT_NODE_DECLARE_NO_COW_TAG_ON_UPDATE(Shading);
 DEG_COMPONENT_NODE_DECLARE_GENERIC(ShadingParameters);
index d8890547f163c27f3e8561853f8e07c3a211dd3c..808379006afc72a5151cfef5fb6bb32ed768439a 100644 (file)
@@ -204,11 +204,11 @@ ComponentDepsNode *IDDepsNode::add_component(eDepsNode_Type type,
        return comp_node;
 }
 
-void IDDepsNode::tag_update(Depsgraph *graph)
+void IDDepsNode::tag_update(Depsgraph *graph, eDepsTag_Source source)
 {
        GHASH_FOREACH_BEGIN(ComponentDepsNode *, comp_node, components)
        {
-               comp_node->tag_update(graph);
+               comp_node->tag_update(graph, source);
        }
        GHASH_FOREACH_END();
 }
index 44b4c91de4e5912f5550bbf484abd7fb91a9b5d2..ed87e7f6ef1795b8a325ac9009eda5fa7a2aa584 100644 (file)
@@ -49,19 +49,19 @@ struct IDDepsNode : public DepsNode {
                const char *name;
        };
 
-       void init(const ID *id, const char *subdata);
+       virtual void init(const ID *id, const char *subdata) override;
        void init_copy_on_write(ID *id_cow_hint = NULL);
        ~IDDepsNode();
        void destroy();
 
-       virtual string identifier() const;
+       virtual string identifier() const override;
 
        ComponentDepsNode *find_component(eDepsNode_Type type,
                                          const char *name = "") const;
        ComponentDepsNode *add_component(eDepsNode_Type type,
                                         const char *name = "");
 
-       void tag_update(Depsgraph *graph);
+       virtual void tag_update(Depsgraph *graph, eDepsTag_Source source) override;
 
        void finalize_build(Depsgraph *graph);
 
index d9af3cbf2a452d50f781f3f1f856c4d574e9efab..ef1882dd7151291d8264e3bd53a08910fa50c6b3 100644 (file)
@@ -75,14 +75,23 @@ string OperationDepsNode::full_identifier() const
        return owner_str + "." + identifier();
 }
 
-void OperationDepsNode::tag_update(Depsgraph *graph)
+void OperationDepsNode::tag_update(Depsgraph *graph, eDepsTag_Source source)
 {
-       if (flag & DEPSOP_FLAG_NEEDS_UPDATE) {
-               return;
+       if ((flag & DEPSOP_FLAG_NEEDS_UPDATE) == 0) {
+               graph->add_entry_tag(this);
        }
        /* Tag for update, but also note that this was the source of an update. */
        flag |= (DEPSOP_FLAG_NEEDS_UPDATE | DEPSOP_FLAG_DIRECTLY_MODIFIED);
-       graph->add_entry_tag(this);
+       switch (source) {
+               case DEG_UPDATE_SOURCE_TIME:
+               case DEG_UPDATE_SOURCE_RELATIONS:
+               case DEG_UPDATE_SOURCE_VISIBILITY:
+                       /* Currently nothing. */
+                       break;
+               case DEG_UPDATE_SOURCE_USER_EDIT:
+                       flag |= DEPSOP_FLAG_USER_MODIFIED;
+                       break;
+       }
 }
 
 void OperationDepsNode::set_as_entry()
index 7eeb99d984a7311aae9538941210d13cdf414211..71c03945d489864fad25d6715442dfacd24adaf9 100644 (file)
@@ -40,13 +40,17 @@ namespace DEG {
 
 struct ComponentDepsNode;
 
-/* Flags for Depsgraph Nodes */
+/* Flags for Depsgraph Nodes. */
 typedef enum eDepsOperation_Flag {
-       /* node needs to be updated */
+       /* Node needs to be updated. */
        DEPSOP_FLAG_NEEDS_UPDATE       = (1 << 0),
-
-       /* node was directly modified, causing need for update */
+       /* Node was directly modified, causing need for update. */
        DEPSOP_FLAG_DIRECTLY_MODIFIED  = (1 << 1),
+       /* Node was updated due to user input. */
+       DEPSOP_FLAG_USER_MODIFIED      = (1 << 2),
+
+       /* Set of flags which gets flushed along the relations. */
+       DEPSOP_FLAG_FLUSH = (DEPSOP_FLAG_USER_MODIFIED)
 } eDepsOperation_Flag;
 
 /* Atomic Operation - Base type for all operations */
@@ -54,17 +58,21 @@ struct OperationDepsNode : public DepsNode {
        OperationDepsNode();
        ~OperationDepsNode();
 
-       string identifier() const;
+       virtual string identifier() const override;
        string full_identifier() const;
 
-       void tag_update(Depsgraph *graph);
+       virtual void tag_update(Depsgraph *graph, eDepsTag_Source source) override;
 
        bool is_noop() const { return (bool)evaluate == false; }
 
-       OperationDepsNode *get_entry_operation() { return this; }
-       OperationDepsNode *get_exit_operation() { return this; }
+       virtual OperationDepsNode *get_entry_operation() override {
+               return this;
+       }
+       virtual OperationDepsNode *get_exit_operation() override {
+               return this;
+       }
 
-       /* Set this operation as compoonent's entry/exit operation. */
+       /* Set this operation as component's entry/exit operation. */
        void set_as_entry();
        void set_as_exit();
 
index 1295af666bf2810052c706fef34dfd7439de84ae..a788b999305f03135399fb64fcbeebd0408d2f79 100644 (file)
 
 namespace DEG {
 
-void TimeSourceDepsNode::tag_update(Depsgraph *graph)
+void TimeSourceDepsNode::tag_update(Depsgraph *graph,
+                                    eDepsTag_Source /*source*/)
 {
        foreach (DepsRelation *rel, outlinks) {
                DepsNode *node = rel->to;
-               node->tag_update(graph);
+               node->tag_update(graph, DEG_UPDATE_SOURCE_TIME);
        }
 }
 
index 93f3edef9cf825e3275fe86466ef8230020f2340..7253dc106d44c0f1a5fb5c816bf0e5b85cdae93f 100644 (file)
@@ -44,7 +44,7 @@ struct TimeSourceDepsNode : public DepsNode {
 
        // TODO: evaluate() operation needed
 
-       void tag_update(Depsgraph *graph);
+       virtual void tag_update(Depsgraph *graph, eDepsTag_Source source) override;
 
        DEG_DEPSNODE_DECLARE;
 };