Blender V4.3
deg_builder_transitive.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2015 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
10
11#include "MEM_guardedalloc.h"
12
16
18#include "intern/depsgraph.hh"
20
21namespace blender::deg {
22
23/* -------------------------------------------------- */
24
25/* Performs a transitive reduction to remove redundant relations.
26 * https://en.wikipedia.org/wiki/Transitive_reduction
27 *
28 * XXX The current implementation is somewhat naive and has O(V*E) worst case
29 * runtime.
30 * A more optimized algorithm can be implemented later, e.g.
31 *
32 * http://www.sciencedirect.com/science/article/pii/0304397588900321/pdf?md5=3391e309b708b6f9cdedcd08f84f4afc&pid=1-s2.0-0304397588900321-main.pdf
33 *
34 * Care has to be taken to make sure the algorithm can handle the cyclic case
35 * too! (unless we can to prevent this case early on).
36 */
37
38enum {
41};
42
44{
45 if (node->custom_flags & OP_VISITED) {
46 return;
47 }
48 node->custom_flags |= OP_VISITED;
49 for (Relation *rel : node->inlinks) {
51 /* Do this only in inlinks loop, so the target node does not get
52 * flagged. */
53 rel->from->custom_flags |= OP_REACHABLE;
54 }
55}
56
58{
59 int num_removed_relations = 0;
60 Vector<Relation *> relations_to_remove;
61
62 for (OperationNode *target : graph->operations) {
63 /* Clear tags. */
64 for (OperationNode *node : graph->operations) {
65 node->custom_flags = 0;
66 }
67 /* Mark nodes from which we can reach the target
68 * start with children, so the target node and direct children are not
69 * flagged. */
70 target->custom_flags |= OP_VISITED;
71 for (Relation *rel : target->inlinks) {
73 }
74 /* Remove redundant paths to the target. */
75 for (Relation *rel : target->inlinks) {
76 if (rel->from->type == NodeType::TIMESOURCE) {
77 /* HACK: time source nodes don't get "custom_flags" flag
78 * set/cleared. */
79 /* TODO: there will be other types in future, so iterators above
80 * need modifying. */
81 continue;
82 }
83 if (rel->from->custom_flags & OP_REACHABLE) {
84 relations_to_remove.append(rel);
85 }
86 }
87 for (Relation *rel : relations_to_remove) {
88 rel->unlink();
89 delete rel;
90 }
91 num_removed_relations += relations_to_remove.size();
92 relations_to_remove.clear();
93 }
94 DEG_DEBUG_PRINTF((::Depsgraph *)graph, BUILD, "Removed %d relations\n", num_removed_relations);
95}
96
97} // namespace blender::deg
Read Guarded memory(de)allocation.
int64_t size() const
void append(const T &value)
#define DEG_DEBUG_PRINTF(depsgraph, type,...)
Definition deg_debug.h:45
void deg_graph_transitive_reduction(Depsgraph *graph)
static void deg_graph_tag_paths_recursive(Node *node)