Depsgraph: refactor tagging after time changes
This reverts {rB1693a5efe91999b60b3dc0bdff727473b3bd00bb} and implements an alternative solution. The old patch had the problem that the depsgraph would always evaluate at the current frame of the original scene (even when `DEG_evaluate_on_framechange` was used). Now it is possible to evaluate the depsgraph at a specific frame without having to change the original scene. Reviewers: sergey, sybren Differential Revision: https://developer.blender.org/D8616
This commit is contained in:
parent
948e080fc5
commit
263148dbac
Notes:
blender-bot
2023-02-14 09:29:42 +01:00
Referenced by issue #95246, Undo bone rotation after previous frame/keyframe jump operators undoes frame jump as well (frame in UI is still the same though) Referenced by issue #82769, Crash rendering particle animation with particle caches [disk cache works though] Referenced by issue #80166, Animating Shape Key Max/Min Range works in viewport but not when rendering Referenced by issue #80035, Crash to desktop with creating a new scene with a motion tracking file loaded Referenced by issue #71234, Custom property doesnt update when rendering animation Referenced by issue #66913, Issue with Undoing after using next/previous keyframe shortcut.
|
@ -127,6 +127,12 @@ void DEG_graph_id_tag_update(struct Main *bmain,
|
|||
struct ID *id,
|
||||
int flag);
|
||||
|
||||
/* Tag all dependency graphs when time has changed. */
|
||||
void DEG_time_tag_update(struct Main *bmain);
|
||||
|
||||
/* Tag a dependency graph when time has changed. */
|
||||
void DEG_graph_time_tag_update(struct Depsgraph *depsgraph);
|
||||
|
||||
/* Mark a particular datablock type as having changing. This does
|
||||
* not cause any updates but is used by external render engines to detect if for
|
||||
* example a datablock was removed. */
|
||||
|
@ -155,8 +161,6 @@ void DEG_evaluate_on_framechange(Depsgraph *graph, float ctime);
|
|||
/* Data changed recalculation entry point. */
|
||||
void DEG_evaluate_on_refresh(Depsgraph *graph);
|
||||
|
||||
bool DEG_needs_eval(Depsgraph *graph);
|
||||
|
||||
/* Editors Integration -------------------------- */
|
||||
|
||||
/* Mechanism to allow editors to be informed of depsgraph updates,
|
||||
|
|
|
@ -63,7 +63,6 @@ namespace deg {
|
|||
Depsgraph::Depsgraph(Main *bmain, Scene *scene, ViewLayer *view_layer, eEvaluationMode mode)
|
||||
: time_source(nullptr),
|
||||
need_update(true),
|
||||
need_update_time(false),
|
||||
bmain(bmain),
|
||||
scene(scene),
|
||||
view_layer(view_layer),
|
||||
|
@ -103,6 +102,11 @@ TimeSourceNode *Depsgraph::find_time_source() const
|
|||
return time_source;
|
||||
}
|
||||
|
||||
void Depsgraph::tag_time_source()
|
||||
{
|
||||
time_source->tag_update(this, DEG_UPDATE_SOURCE_TIME);
|
||||
}
|
||||
|
||||
IDNode *Depsgraph::find_id_node(const ID *id) const
|
||||
{
|
||||
return id_hash.lookup_default(id, nullptr);
|
||||
|
|
|
@ -68,6 +68,7 @@ struct Depsgraph {
|
|||
|
||||
TimeSourceNode *add_time_source();
|
||||
TimeSourceNode *find_time_source() const;
|
||||
void tag_time_source();
|
||||
|
||||
IDNode *find_id_node(const ID *id) const;
|
||||
IDNode *add_id_node(ID *id, ID *id_cow_hint = nullptr);
|
||||
|
@ -121,10 +122,6 @@ struct Depsgraph {
|
|||
/* Nodes which have been tagged as "directly modified". */
|
||||
Set<OperationNode *> 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?) */
|
||||
|
|
|
@ -47,38 +47,37 @@
|
|||
|
||||
namespace deg = blender::deg;
|
||||
|
||||
static void deg_flush_updates_and_refresh(deg::Depsgraph *deg_graph)
|
||||
{
|
||||
/* Update the time on the cow scene. */
|
||||
if (deg_graph->scene_cow) {
|
||||
BKE_scene_frame_set(deg_graph->scene_cow, deg_graph->ctime);
|
||||
}
|
||||
|
||||
deg::deg_graph_flush_updates(deg_graph);
|
||||
deg::deg_evaluate_on_refresh(deg_graph);
|
||||
}
|
||||
|
||||
/* Evaluate all nodes tagged for updating. */
|
||||
void DEG_evaluate_on_refresh(Depsgraph *graph)
|
||||
{
|
||||
deg::Depsgraph *deg_graph = reinterpret_cast<deg::Depsgraph *>(graph);
|
||||
deg_graph->ctime = BKE_scene_frame_get(deg_graph->scene);
|
||||
/* Update time in scene. */
|
||||
if (deg_graph->scene_cow) {
|
||||
BKE_scene_frame_set(deg_graph->scene_cow, deg_graph->ctime);
|
||||
const Scene *scene = DEG_get_input_scene(graph);
|
||||
const float ctime = BKE_scene_frame_get(scene);
|
||||
|
||||
if (ctime != deg_graph->ctime) {
|
||||
deg_graph->tag_time_source();
|
||||
deg_graph->ctime = ctime;
|
||||
}
|
||||
deg::deg_graph_flush_updates(deg_graph);
|
||||
deg::deg_evaluate_on_refresh(deg_graph);
|
||||
deg_graph->need_update_time = false;
|
||||
|
||||
deg_flush_updates_and_refresh(deg_graph);
|
||||
}
|
||||
|
||||
/* Frame-change happened for root scene that graph belongs to. */
|
||||
void DEG_evaluate_on_framechange(Depsgraph *graph, float ctime)
|
||||
{
|
||||
deg::Depsgraph *deg_graph = reinterpret_cast<deg::Depsgraph *>(graph);
|
||||
deg_graph->tag_time_source();
|
||||
deg_graph->ctime = ctime;
|
||||
deg_graph->need_update_time = true;
|
||||
deg::deg_graph_flush_updates(deg_graph);
|
||||
/* Update time in scene. */
|
||||
if (deg_graph->scene_cow) {
|
||||
BKE_scene_frame_set(deg_graph->scene_cow, deg_graph->ctime);
|
||||
}
|
||||
/* Perform recalculation updates. */
|
||||
deg::deg_evaluate_on_refresh(deg_graph);
|
||||
deg_graph->need_update_time = false;
|
||||
}
|
||||
|
||||
bool DEG_needs_eval(Depsgraph *graph)
|
||||
{
|
||||
deg::Depsgraph *deg_graph = reinterpret_cast<deg::Depsgraph *>(graph);
|
||||
return !deg_graph->entry_tags.is_empty() || deg_graph->need_update_time;
|
||||
deg_flush_updates_and_refresh(deg_graph);
|
||||
}
|
||||
|
|
|
@ -66,6 +66,7 @@
|
|||
#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"
|
||||
|
||||
namespace deg = blender::deg;
|
||||
|
||||
|
@ -230,9 +231,6 @@ void depsgraph_tag_to_component_opcode(const ID *id,
|
|||
case ID_RECALC_SOURCE:
|
||||
*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");
|
||||
|
@ -372,12 +370,6 @@ void graph_id_tag_update_single_flag(Main *bmain,
|
|||
}
|
||||
return;
|
||||
}
|
||||
if (tag == ID_RECALC_TIME) {
|
||||
if (graph != nullptr) {
|
||||
graph->need_update_time = true;
|
||||
}
|
||||
return;
|
||||
}
|
||||
/* Get description of what is to be tagged. */
|
||||
NodeType component_type;
|
||||
OperationCode operation_code;
|
||||
|
@ -462,8 +454,8 @@ const char *update_source_as_string(eUpdateSource source)
|
|||
|
||||
int deg_recalc_flags_for_legacy_zero()
|
||||
{
|
||||
return ID_RECALC_ALL & ~(ID_RECALC_PSYS_ALL | ID_RECALC_ANIMATION | ID_RECALC_SOURCE |
|
||||
ID_RECALC_TIME | ID_RECALC_EDITORS);
|
||||
return ID_RECALC_ALL &
|
||||
~(ID_RECALC_PSYS_ALL | ID_RECALC_ANIMATION | ID_RECALC_SOURCE | ID_RECALC_EDITORS);
|
||||
}
|
||||
|
||||
int deg_recalc_flags_effective(Depsgraph *graph, int flags)
|
||||
|
@ -734,8 +726,6 @@ 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_SOURCE:
|
||||
return "SOURCE";
|
||||
case ID_RECALC_ALL:
|
||||
|
@ -772,6 +762,19 @@ void DEG_graph_id_tag_update(struct Main *bmain,
|
|||
deg::graph_id_tag_update(bmain, graph, id, flag, deg::DEG_UPDATE_SOURCE_USER_EDIT);
|
||||
}
|
||||
|
||||
void DEG_time_tag_update(struct Main *bmain)
|
||||
{
|
||||
for (deg::Depsgraph *depsgraph : deg::get_all_registered_graphs(bmain)) {
|
||||
DEG_graph_time_tag_update(reinterpret_cast<::Depsgraph *>(depsgraph));
|
||||
}
|
||||
}
|
||||
|
||||
void DEG_graph_time_tag_update(struct Depsgraph *depsgraph)
|
||||
{
|
||||
deg::Depsgraph *deg_graph = reinterpret_cast<deg::Depsgraph *>(depsgraph);
|
||||
deg_graph->tag_time_source();
|
||||
}
|
||||
|
||||
/* Mark a particular datablock type as having changing. */
|
||||
void DEG_graph_id_type_tag(Depsgraph *depsgraph, short id_type)
|
||||
{
|
||||
|
|
|
@ -357,14 +357,9 @@ void deg_graph_flush_updates(Depsgraph *graph)
|
|||
BLI_assert(graph != nullptr);
|
||||
Main *bmain = graph->bmain;
|
||||
|
||||
graph->time_source->flush_update_tag(graph);
|
||||
|
||||
/* Nothing to update, early out. */
|
||||
if (graph->need_update_time) {
|
||||
const Scene *scene_orig = graph->scene;
|
||||
const float ctime = BKE_scene_frame_get(scene_orig);
|
||||
TimeSourceNode *time_source = graph->find_time_source();
|
||||
graph->ctime = ctime;
|
||||
time_source->tag_update(graph, DEG_UPDATE_SOURCE_TIME);
|
||||
}
|
||||
if (graph->entry_tags.is_empty()) {
|
||||
return;
|
||||
}
|
||||
|
@ -412,6 +407,8 @@ void deg_graph_clear_tags(Depsgraph *graph)
|
|||
}
|
||||
/* Clear any entry tags which haven't been flushed. */
|
||||
graph->entry_tags.clear();
|
||||
|
||||
graph->time_source->tagged_for_update = false;
|
||||
}
|
||||
|
||||
} // namespace deg
|
||||
|
|
|
@ -31,8 +31,16 @@
|
|||
namespace blender {
|
||||
namespace deg {
|
||||
|
||||
void TimeSourceNode::tag_update(Depsgraph *graph, eUpdateSource /*source*/)
|
||||
void TimeSourceNode::tag_update(Depsgraph * /*graph*/, eUpdateSource /*source*/)
|
||||
{
|
||||
tagged_for_update = true;
|
||||
}
|
||||
|
||||
void TimeSourceNode::flush_update_tag(Depsgraph *graph)
|
||||
{
|
||||
if (!tagged_for_update) {
|
||||
return;
|
||||
}
|
||||
for (Relation *rel : outlinks) {
|
||||
Node *node = rel->to;
|
||||
node->tag_update(graph, DEG_UPDATE_SOURCE_TIME);
|
||||
|
|
|
@ -30,10 +30,14 @@ namespace deg {
|
|||
|
||||
/* Time Source Node. */
|
||||
struct TimeSourceNode : public Node {
|
||||
bool tagged_for_update = false;
|
||||
|
||||
// TODO: evaluate() operation needed
|
||||
|
||||
virtual void tag_update(Depsgraph *graph, eUpdateSource source) override;
|
||||
|
||||
void flush_update_tag(Depsgraph *graph);
|
||||
|
||||
DEG_DEPSNODE_DECLARE;
|
||||
};
|
||||
|
||||
|
|
|
@ -1576,7 +1576,7 @@ 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);
|
||||
DEG_time_tag_update(bmain);
|
||||
|
||||
#ifdef DURIAN_CAMERA_SWITCH
|
||||
void *camera = BKE_scene_camera_switch_find(scene);
|
||||
|
|
|
@ -686,10 +686,6 @@ 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),
|
||||
|
||||
/* Input has changed and datablock is to be reload from disk.
|
||||
* Applies to movie clips to inform that copy-on-written version is to be refreshed for the new
|
||||
* input file or for color space changes. */
|
||||
|
|
Loading…
Reference in New Issue