diff --git a/source/blender/depsgraph/intern/depsgraph.cc b/source/blender/depsgraph/intern/depsgraph.cc index d8a9b41206b..6d3aed65a14 100644 --- a/source/blender/depsgraph/intern/depsgraph.cc +++ b/source/blender/depsgraph/intern/depsgraph.cc @@ -68,6 +68,7 @@ template static void remove_from_vector(vector *vector, const T & Depsgraph::Depsgraph(Scene *scene, ViewLayer *view_layer, eEvaluationMode mode) : time_source(NULL), need_update(true), + need_update_time(false), scene(scene), view_layer(view_layer), mode(mode), diff --git a/source/blender/depsgraph/intern/depsgraph.h b/source/blender/depsgraph/intern/depsgraph.h index f194a44346b..507d2d9ec08 100644 --- a/source/blender/depsgraph/intern/depsgraph.h +++ b/source/blender/depsgraph/intern/depsgraph.h @@ -160,6 +160,10 @@ struct Depsgraph { /* Nodes which have been tagged as "directly modified". */ GSet *entry_tags; + /* Special entry tag for time source. Allows to tag invisible dependency graphs for update when + * scene frame changes, so then when dependency graph becomes visible it is on a proper state. */ + bool need_update_time; + /* Convenience Data ................... */ /* XXX: should be collected after building (if actually needed?) */ diff --git a/source/blender/depsgraph/intern/depsgraph_eval.cc b/source/blender/depsgraph/intern/depsgraph_eval.cc index 6f3262174b4..f519fe76724 100644 --- a/source/blender/depsgraph/intern/depsgraph_eval.cc +++ b/source/blender/depsgraph/intern/depsgraph_eval.cc @@ -61,6 +61,7 @@ void DEG_evaluate_on_refresh(Depsgraph *graph) BKE_scene_frame_set(deg_graph->scene_cow, deg_graph->ctime); } DEG::deg_evaluate_on_refresh(deg_graph); + deg_graph->need_update_time = false; } /* Frame-change happened for root scene that graph belongs to. */ @@ -79,6 +80,7 @@ void DEG_evaluate_on_framechange(Main *bmain, Depsgraph *graph, float ctime) } /* Perform recalculation updates. */ DEG::deg_evaluate_on_refresh(deg_graph); + deg_graph->need_update_time = false; } bool DEG_needs_eval(Depsgraph *graph) diff --git a/source/blender/depsgraph/intern/depsgraph_tag.cc b/source/blender/depsgraph/intern/depsgraph_tag.cc index 583191490d2..f9105b53536 100644 --- a/source/blender/depsgraph/intern/depsgraph_tag.cc +++ b/source/blender/depsgraph/intern/depsgraph_tag.cc @@ -229,6 +229,9 @@ void depsgraph_tag_to_component_opcode(const ID *id, case ID_RECALC_PARAMETERS: *component_type = NodeType::PARAMETERS; break; + case ID_RECALC_TIME: + BLI_assert(!"Should be handled outside of this function"); + break; case ID_RECALC_ALL: case ID_RECALC_PSYS_ALL: BLI_assert(!"Should not happen"); @@ -360,6 +363,12 @@ static void graph_id_tag_update_single_flag(Main *bmain, } return; } + else if (tag == ID_RECALC_TIME) { + if (graph != NULL) { + graph->need_update_time = true; + } + return; + } /* Get description of what is to be tagged. */ NodeType component_type; OperationCode operation_code; @@ -664,6 +673,8 @@ const char *DEG_update_tag_as_string(IDRecalcFlag flag) return "AUDIO"; case ID_RECALC_PARAMETERS: return "PARAMETERS"; + case ID_RECALC_TIME: + return "TIME"; case ID_RECALC_ALL: return "ALL"; } diff --git a/source/blender/depsgraph/intern/eval/deg_eval_flush.cc b/source/blender/depsgraph/intern/eval/deg_eval_flush.cc index 83fcf4c6ea1..e54adcd8655 100644 --- a/source/blender/depsgraph/intern/eval/deg_eval_flush.cc +++ b/source/blender/depsgraph/intern/eval/deg_eval_flush.cc @@ -39,6 +39,7 @@ extern "C" { #include "DNA_object_types.h" +#include "DNA_scene_types.h" #include "DRW_engine.h" } /* extern "C" */ @@ -53,6 +54,7 @@ extern "C" { #include "intern/node/deg_node_factory.h" #include "intern/node/deg_node_id.h" #include "intern/node/deg_node_operation.h" +#include "intern/node/deg_node_time.h" #include "intern/eval/deg_eval_copy_on_write.h" @@ -348,9 +350,16 @@ void deg_graph_flush_updates(Main *bmain, Depsgraph *graph) BLI_assert(bmain != NULL); BLI_assert(graph != NULL); /* Nothing to update, early out. */ - if (BLI_gset_len(graph->entry_tags) == 0) { + if (BLI_gset_len(graph->entry_tags) == 0 && !graph->need_update_time) { return; } + if (graph->need_update_time) { + const Scene *scene_orig = graph->scene; + const float ctime = scene_orig->r.cfra + scene_orig->r.subframe; + DEG::TimeSourceNode *time_source = graph->find_time_source(); + graph->ctime = ctime; + time_source->tag_update(graph, DEG::DEG_UPDATE_SOURCE_TIME); + } /* Reset all flags, get ready for the flush. */ flush_prepare(graph); /* Starting from the tagged "entry" nodes, flush outwards. */ diff --git a/source/blender/editors/screen/screen_edit.c b/source/blender/editors/screen/screen_edit.c index e59477fbe6e..dddc33e3ad0 100644 --- a/source/blender/editors/screen/screen_edit.c +++ b/source/blender/editors/screen/screen_edit.c @@ -1457,6 +1457,8 @@ void ED_update_for_newframe(Main *bmain, Depsgraph *depsgraph) { Scene *scene = DEG_get_input_scene(depsgraph); + DEG_id_tag_update_ex(bmain, &scene->id, ID_RECALC_TIME); + #ifdef DURIAN_CAMERA_SWITCH void *camera = BKE_scene_camera_switch_find(scene); if (camera && scene->camera != camera) { diff --git a/source/blender/makesdna/DNA_ID.h b/source/blender/makesdna/DNA_ID.h index cad1af8eb50..dc4164169f9 100644 --- a/source/blender/makesdna/DNA_ID.h +++ b/source/blender/makesdna/DNA_ID.h @@ -616,6 +616,10 @@ typedef enum IDRecalcFlag { ID_RECALC_PARAMETERS = (1 << 21), + /* Makes it so everything what depends on time. + * Basically, the same what changing frame in a timeline will do. */ + ID_RECALC_TIME = (1 << 22), + /*************************************************************************** * Pseudonyms, to have more semantic meaning in the actual code without * using too much low-level and implementation specific tags. */