diff --git a/source/blender/blenkernel/BKE_object.h b/source/blender/blenkernel/BKE_object.h index 8085c541600..6d950ec01f6 100644 --- a/source/blender/blenkernel/BKE_object.h +++ b/source/blender/blenkernel/BKE_object.h @@ -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); diff --git a/source/blender/blenkernel/intern/object_update.c b/source/blender/blenkernel/intern/object_update.c index 902237d7ac8..267f64aa53f 100644 --- a/source/blender/blenkernel/intern/object_update.c +++ b/source/blender/blenkernel/intern/object_update.c @@ -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); diff --git a/source/blender/depsgraph/DEG_depsgraph.h b/source/blender/depsgraph/DEG_depsgraph.h index 75572a91440..fa2675297bc 100644 --- a/source/blender/depsgraph/DEG_depsgraph.h +++ b/source/blender/depsgraph/DEG_depsgraph.h @@ -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); diff --git a/source/blender/depsgraph/DEG_depsgraph_build.h b/source/blender/depsgraph/DEG_depsgraph_build.h index 1895b483644..93e9b5be2cc 100644 --- a/source/blender/depsgraph/DEG_depsgraph_build.h +++ b/source/blender/depsgraph/DEG_depsgraph_build.h @@ -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); /* ************************************************ */ diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc index e8e3e241ebf..637fd5887a0 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc @@ -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); } diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.h b/source/blender/depsgraph/intern/builder/deg_builder_nodes.h index b826a2979cc..3c0c5f749ca 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.h +++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.h @@ -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); diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc index d336bfb6188..e66c3a25e33 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc @@ -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 */ diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.h b/source/blender/depsgraph/intern/builder/deg_builder_relations.h index e5854fa8d20..e86c6504693 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.h +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.h @@ -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, diff --git a/source/blender/depsgraph/intern/debug/deg_debug_relations_graphviz.cc b/source/blender/depsgraph/intern/debug/deg_debug_relations_graphviz.cc index 47cb3ebcd91..39dfac2fca7 100644 --- a/source/blender/depsgraph/intern/debug/deg_debug_relations_graphviz.cc +++ b/source/blender/depsgraph/intern/debug/deg_debug_relations_graphviz.cc @@ -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: diff --git a/source/blender/depsgraph/intern/depsgraph.h b/source/blender/depsgraph/intern/depsgraph.h index 3e7d34414ea..bbf1f883bde 100644 --- a/source/blender/depsgraph/intern/depsgraph.h +++ b/source/blender/depsgraph/intern/depsgraph.h @@ -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) */ diff --git a/source/blender/depsgraph/intern/depsgraph_build.cc b/source/blender/depsgraph/intern/depsgraph_build.cc index f5b84b91dbe..64adfa1ceea 100644 --- a/source/blender/depsgraph/intern/depsgraph_build.cc +++ b/source/blender/depsgraph/intern/depsgraph_build.cc @@ -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(handle); + return reinterpret_cast(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_special_eval_flag(struct DepsNodeHandle *handle, ID *id, uint32_t flag) +void DEG_add_object_pointcache_relation(struct DepsNodeHandle *node_handle, + struct Object *object, + eDepsObjectComponentType component, + const char *description) { - DEG::DepsNodeHandle *deg_handle = get_handle(handle); - deg_handle->builder->add_special_eval_flag(id, flag); + 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; } -struct Depsgraph *DEG_get_graph_from_handle(struct DepsNodeHandle *handle) +void DEG_add_special_eval_flag(struct DepsNodeHandle *node_handle, + ID *id, + uint32_t flag) { - DEG::DepsNodeHandle *deg_handle = get_handle(handle); - DEG::DepsgraphRelationBuilder *relation_builder = deg_handle->builder; + DEG::DepsNodeHandle *deg_node_handle = get_node_handle(node_handle); + deg_node_handle->builder->add_special_eval_flag(id, flag); +} + +struct ID *DEG_get_id_from_handle(struct DepsNodeHandle *node_handle) +{ + 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(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(°_graph->scene->id); - if (id_node != NULL) { - id_node->tag_update(deg_graph); - } + DEG::IDDepsNode *id_node = deg_graph->find_id_node(°_graph->scene->id); + if (id_node != NULL) { + id_node->tag_update(deg_graph, DEG::DEG_UPDATE_SOURCE_RELATIONS); } } diff --git a/source/blender/depsgraph/intern/depsgraph_eval.cc b/source/blender/depsgraph/intern/depsgraph_eval.cc index 5b6516509b0..49eccd76f38 100644 --- a/source/blender/depsgraph/intern/depsgraph_eval.cc +++ b/source/blender/depsgraph/intern/depsgraph_eval.cc @@ -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) { diff --git a/source/blender/depsgraph/intern/depsgraph_physics.cc b/source/blender/depsgraph/intern/depsgraph_physics.cc index 0a54caebace..88d4c25f726 100644 --- a/source/blender/depsgraph/intern/depsgraph_physics.cc +++ b/source/blender/depsgraph/intern/depsgraph_physics.cc @@ -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, diff --git a/source/blender/depsgraph/intern/depsgraph_tag.cc b/source/blender/depsgraph/intern/depsgraph_tag.cc index e2a87f16408..6374354a154 100644 --- a/source/blender/depsgraph/intern/depsgraph_tag.cc +++ b/source/blender/depsgraph/intern/depsgraph_tag.cc @@ -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!"); diff --git a/source/blender/depsgraph/intern/depsgraph_type_defines.cc b/source/blender/depsgraph/intern/depsgraph_type_defines.cc index ae1f8db51eb..44e21656570 100644 --- a/source/blender/depsgraph/intern/depsgraph_type_defines.cc +++ b/source/blender/depsgraph/intern/depsgraph_type_defines.cc @@ -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); diff --git a/source/blender/depsgraph/intern/depsgraph_types.h b/source/blender/depsgraph/intern/depsgraph_types.h index ef64fe8c5fe..32ffcd79c74 100644 --- a/source/blender/depsgraph/intern/depsgraph_types.h +++ b/source/blender/depsgraph/intern/depsgraph_types.h @@ -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 diff --git a/source/blender/depsgraph/intern/eval/deg_eval_flush.cc b/source/blender/depsgraph/intern/eval/deg_eval_flush.cc index 975723ef8a3..61edc1e3795 100644 --- a/source/blender/depsgraph/intern/eval/deg_eval_flush.cc +++ b/source/blender/depsgraph/intern/eval/deg_eval_flush.cc @@ -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; } - 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; + /* 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; + /* 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. */ diff --git a/source/blender/depsgraph/intern/nodes/deg_node.h b/source/blender/depsgraph/intern/nodes/deg_node.h index ef2a73258fd..7a837d17ceb 100644 --- a/source/blender/depsgraph/intern/nodes/deg_node.h +++ b/source/blender/depsgraph/intern/nodes/deg_node.h @@ -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; } diff --git a/source/blender/depsgraph/intern/nodes/deg_node_component.cc b/source/blender/depsgraph/intern/nodes/deg_node_component.cc index d6c3eb6157d..4bb9b9d17b3 100644 --- a/source/blender/depsgraph/intern/nodes/deg_node_component.cc +++ b/source/blender/depsgraph/intern/nodes/deg_node_component.cc @@ -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); diff --git a/source/blender/depsgraph/intern/nodes/deg_node_component.h b/source/blender/depsgraph/intern/nodes/deg_node_component.h index 244884554fa..e3057e1d3ce 100644 --- a/source/blender/depsgraph/intern/nodes/deg_node_component.h +++ b/source/blender/depsgraph/intern/nodes/deg_node_component.h @@ -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); diff --git a/source/blender/depsgraph/intern/nodes/deg_node_id.cc b/source/blender/depsgraph/intern/nodes/deg_node_id.cc index d8890547f16..808379006af 100644 --- a/source/blender/depsgraph/intern/nodes/deg_node_id.cc +++ b/source/blender/depsgraph/intern/nodes/deg_node_id.cc @@ -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(); } diff --git a/source/blender/depsgraph/intern/nodes/deg_node_id.h b/source/blender/depsgraph/intern/nodes/deg_node_id.h index 44b4c91de4e..ed87e7f6ef1 100644 --- a/source/blender/depsgraph/intern/nodes/deg_node_id.h +++ b/source/blender/depsgraph/intern/nodes/deg_node_id.h @@ -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); diff --git a/source/blender/depsgraph/intern/nodes/deg_node_operation.cc b/source/blender/depsgraph/intern/nodes/deg_node_operation.cc index d9af3cbf2a4..ef1882dd715 100644 --- a/source/blender/depsgraph/intern/nodes/deg_node_operation.cc +++ b/source/blender/depsgraph/intern/nodes/deg_node_operation.cc @@ -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() diff --git a/source/blender/depsgraph/intern/nodes/deg_node_operation.h b/source/blender/depsgraph/intern/nodes/deg_node_operation.h index 7eeb99d984a..71c03945d48 100644 --- a/source/blender/depsgraph/intern/nodes/deg_node_operation.h +++ b/source/blender/depsgraph/intern/nodes/deg_node_operation.h @@ -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(); diff --git a/source/blender/depsgraph/intern/nodes/deg_node_time.cc b/source/blender/depsgraph/intern/nodes/deg_node_time.cc index 1295af666bf..a788b999305 100644 --- a/source/blender/depsgraph/intern/nodes/deg_node_time.cc +++ b/source/blender/depsgraph/intern/nodes/deg_node_time.cc @@ -37,11 +37,12 @@ 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); } } diff --git a/source/blender/depsgraph/intern/nodes/deg_node_time.h b/source/blender/depsgraph/intern/nodes/deg_node_time.h index 93f3edef9cf..7253dc106d4 100644 --- a/source/blender/depsgraph/intern/nodes/deg_node_time.h +++ b/source/blender/depsgraph/intern/nodes/deg_node_time.h @@ -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; };