Merge branch 'master' into blender2.8
[blender.git] / source / blender / depsgraph / intern / builder / deg_builder.cc
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2016 Blender Foundation.
19  * All rights reserved.
20  *
21  * Original Author: Sergey Sharybin
22  * Contributor(s): None Yet
23  *
24  * ***** END GPL LICENSE BLOCK *****
25  */
26
27 /** \file blender/depsgraph/intern/builder/deg_builder.cc
28  *  \ingroup depsgraph
29  */
30
31 #include "intern/builder/deg_builder.h"
32
33 #include "DNA_anim_types.h"
34 #include "DNA_object_types.h"
35 #include "DNA_ID.h"
36
37 #include "BLI_utildefines.h"
38 #include "BLI_ghash.h"
39 #include "BLI_stack.h"
40
41 extern "C" {
42 #include "BKE_animsys.h"
43 }
44
45 #include "intern/depsgraph.h"
46 #include "intern/depsgraph_types.h"
47 #include "intern/eval/deg_eval_copy_on_write.h"
48 #include "intern/nodes/deg_node.h"
49 #include "intern/nodes/deg_node_id.h"
50 #include "intern/nodes/deg_node_component.h"
51 #include "intern/nodes/deg_node_operation.h"
52
53 #include "util/deg_util_foreach.h"
54
55 #include "DEG_depsgraph.h"
56
57 namespace DEG {
58
59 namespace {
60
61 void deg_graph_build_flush_visibility(Depsgraph *graph)
62 {
63         enum {
64                 DEG_NODE_VISITED = (1 << 0),
65         };
66
67         BLI_Stack *stack = BLI_stack_new(sizeof(OperationDepsNode *),
68                                          "DEG flush layers stack");
69         foreach (IDDepsNode *id_node, graph->id_nodes) {
70                 GHASH_FOREACH_BEGIN(ComponentDepsNode *, comp_node, id_node->components)
71                 {
72                         comp_node->affects_directly_visible |= id_node->is_directly_visible;
73                 }
74                 GHASH_FOREACH_END();
75         }
76         foreach (OperationDepsNode *op_node, graph->operations) {
77                 op_node->custom_flags = 0;
78                 op_node->num_links_pending = 0;
79                 foreach (DepsRelation *rel, op_node->outlinks) {
80                         if ((rel->from->type == DEG_NODE_TYPE_OPERATION) &&
81                             (rel->flag & DEPSREL_FLAG_CYCLIC) == 0)
82                         {
83                                 ++op_node->num_links_pending;
84                         }
85                 }
86                 if (op_node->num_links_pending == 0) {
87                         BLI_stack_push(stack, &op_node);
88                         op_node->custom_flags |= DEG_NODE_VISITED;
89                 }
90         }
91         while (!BLI_stack_is_empty(stack)) {
92                 OperationDepsNode *op_node;
93                 BLI_stack_pop(stack, &op_node);
94                 /* Flush layers to parents. */
95                 foreach (DepsRelation *rel, op_node->inlinks) {
96                         if (rel->from->type == DEG_NODE_TYPE_OPERATION) {
97                                 OperationDepsNode *op_from = (OperationDepsNode *)rel->from;
98                                 op_from->owner->affects_directly_visible |=
99                                         op_node->owner->affects_directly_visible;
100                         }
101                 }
102                 /* Schedule parent nodes. */
103                 foreach (DepsRelation *rel, op_node->inlinks) {
104                         if (rel->from->type == DEG_NODE_TYPE_OPERATION) {
105                                 OperationDepsNode *op_from = (OperationDepsNode *)rel->from;
106                                 if ((rel->flag & DEPSREL_FLAG_CYCLIC) == 0) {
107                                         BLI_assert(op_from->num_links_pending > 0);
108                                         --op_from->num_links_pending;
109                                 }
110                                 if ((op_from->num_links_pending == 0) &&
111                                     (op_from->custom_flags & DEG_NODE_VISITED) == 0)
112                                 {
113                                         BLI_stack_push(stack, &op_from);
114                                         op_from->custom_flags |= DEG_NODE_VISITED;
115                                 }
116                         }
117                 }
118         }
119         BLI_stack_free(stack);
120 }
121
122 }  // namespace
123
124 void deg_graph_build_finalize(Main *bmain, Depsgraph *graph)
125 {
126         /* Make sure dependencies of visible ID datablocks are visible. */
127         deg_graph_build_flush_visibility(graph);
128         /* Re-tag IDs for update if it was tagged before the relations
129          * update tag.
130          */
131         foreach (IDDepsNode *id_node, graph->id_nodes) {
132                 ID *id = id_node->id_orig;
133                 id_node->finalize_build(graph);
134                 int flag = 0;
135                 if ((id->recalc & ID_RECALC_ALL)) {
136                         AnimData *adt = BKE_animdata_from_id(id);
137                         if (adt != NULL && (adt->recalc & ADT_RECALC_ANIM) != 0) {
138                                 flag |= ID_RECALC_ANIMATION;
139                         }
140                 }
141                 /* Tag rebuild if special evaluation flags changed. */
142                 if (id_node->eval_flags != id_node->previous_eval_flags) {
143                         flag |= ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY;
144                 }
145                 /* Tag rebuild if the custom data mask changed. */
146                 if (id_node->customdata_mask != id_node->previous_customdata_mask) {
147                         flag |= ID_RECALC_GEOMETRY;
148                 }
149                 if (!deg_copy_on_write_is_expanded(id_node->id_cow)) {
150                         flag |= ID_RECALC_COPY_ON_WRITE;
151                         /* This means ID is being added to the dependency graph first
152                          * time, which is similar to "ob-visible-change"
153                          */
154                         if (GS(id->name) == ID_OB) {
155                                 flag |= ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY;
156                         }
157                 }
158                 if (flag != 0) {
159                         DEG_graph_id_tag_update(bmain,
160                                                 (::Depsgraph *)graph,
161                                                 id_node->id_orig,
162                                                 flag);
163                 }
164         }
165 }
166
167 }  // namespace DEG