Depsgraph: Comb code to a better state all over
[blender.git] / source / blender / depsgraph / intern / depsgraph_build.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) 2013 Blender Foundation.
19  * All rights reserved.
20  *
21  * Original Author: Joshua Leung
22  * Contributor(s): Based on original depsgraph.c code - Blender Foundation (2005-2013)
23  *
24  * ***** END GPL LICENSE BLOCK *****
25  */
26
27 /** \file blender/depsgraph/intern/depsgraph_build.cc
28  *  \ingroup depsgraph
29  *
30  * Methods for constructing depsgraph.
31  */
32
33 #include "MEM_guardedalloc.h"
34
35 #include "BLI_utildefines.h"
36 #include "BLI_ghash.h"
37 #include "BLI_listbase.h"
38
39 #include "PIL_time.h"
40 #include "PIL_time_utildefines.h"
41
42 extern "C" {
43 #include "DNA_cachefile_types.h"
44 #include "DNA_object_types.h"
45 #include "DNA_scene_types.h"
46
47 #include "BKE_main.h"
48 #include "BKE_scene.h"
49 } /* extern "C" */
50
51 #include "DEG_depsgraph.h"
52 #include "DEG_depsgraph_debug.h"
53 #include "DEG_depsgraph_build.h"
54
55 #include "builder/deg_builder.h"
56 #include "builder/deg_builder_cycle.h"
57 #include "builder/deg_builder_nodes.h"
58 #include "builder/deg_builder_relations.h"
59 #include "builder/deg_builder_transitive.h"
60
61 #include "intern/debug/deg_debug.h"
62
63 #include "intern/node/deg_node.h"
64 #include "intern/node/deg_node_component.h"
65 #include "intern/node/deg_node_id.h"
66 #include "intern/node/deg_node_operation.h"
67
68 #include "intern/depsgraph_type.h"
69
70 /* ****************** */
71 /* External Build API */
72
73 static DEG::NodeType deg_build_scene_component_type(
74         eDepsSceneComponentType component)
75 {
76         switch (component) {
77                 case DEG_SCENE_COMP_PARAMETERS:     return DEG::NodeType::PARAMETERS;
78                 case DEG_SCENE_COMP_ANIMATION:      return DEG::NodeType::ANIMATION;
79                 case DEG_SCENE_COMP_SEQUENCER:      return DEG::NodeType::SEQUENCER;
80         }
81         return DEG::NodeType::UNDEFINED;
82 }
83
84 static DEG::NodeType deg_build_object_component_type(
85         eDepsObjectComponentType component)
86 {
87         switch (component) {
88                 case DEG_OB_COMP_PARAMETERS:        return DEG::NodeType::PARAMETERS;
89                 case DEG_OB_COMP_PROXY:             return DEG::NodeType::PROXY;
90                 case DEG_OB_COMP_ANIMATION:         return DEG::NodeType::ANIMATION;
91                 case DEG_OB_COMP_TRANSFORM:         return DEG::NodeType::TRANSFORM;
92                 case DEG_OB_COMP_GEOMETRY:          return DEG::NodeType::GEOMETRY;
93                 case DEG_OB_COMP_EVAL_POSE:         return DEG::NodeType::EVAL_POSE;
94                 case DEG_OB_COMP_BONE:              return DEG::NodeType::BONE;
95                 case DEG_OB_COMP_SHADING:           return DEG::NodeType::SHADING;
96                 case DEG_OB_COMP_CACHE:             return DEG::NodeType::CACHE;
97         }
98         return DEG::NodeType::UNDEFINED;
99 }
100
101 static DEG::DepsNodeHandle *get_node_handle(DepsNodeHandle *node_handle)
102 {
103         return reinterpret_cast<DEG::DepsNodeHandle *>(node_handle);
104 }
105
106 void DEG_add_scene_relation(DepsNodeHandle *node_handle,
107                             Scene *scene,
108                             eDepsSceneComponentType component,
109                             const char *description)
110 {
111         DEG::NodeType type = deg_build_scene_component_type(component);
112         DEG::ComponentKey comp_key(&scene->id, type);
113         DEG::DepsNodeHandle *deg_node_handle = get_node_handle(node_handle);
114         deg_node_handle->builder->add_node_handle_relation(comp_key,
115                                                            deg_node_handle,
116                                                            description);
117 }
118
119 void DEG_add_object_relation(DepsNodeHandle *node_handle,
120                              Object *object,
121                              eDepsObjectComponentType component,
122                              const char *description)
123 {
124         DEG::NodeType type = deg_build_object_component_type(component);
125         DEG::ComponentKey comp_key(&object->id, type);
126         DEG::DepsNodeHandle *deg_node_handle = get_node_handle(node_handle);
127         deg_node_handle->builder->add_node_handle_relation(comp_key,
128                                                            deg_node_handle,
129                                                            description);
130 }
131
132 void DEG_add_object_cache_relation(DepsNodeHandle *node_handle,
133                                    CacheFile *cache_file,
134                                    eDepsObjectComponentType component,
135                                    const char *description)
136 {
137         DEG::NodeType type = deg_build_object_component_type(component);
138         DEG::ComponentKey comp_key(&cache_file->id, type);
139         DEG::DepsNodeHandle *deg_node_handle = get_node_handle(node_handle);
140         deg_node_handle->builder->add_node_handle_relation(comp_key,
141                                                            deg_node_handle,
142                                                            description);
143 }
144
145 void DEG_add_bone_relation(DepsNodeHandle *node_handle,
146                            Object *object,
147                            const char *bone_name,
148                            eDepsObjectComponentType component,
149                            const char *description)
150 {
151         DEG::NodeType type = deg_build_object_component_type(component);
152         DEG::ComponentKey comp_key(&object->id, type, bone_name);
153         DEG::DepsNodeHandle *deg_node_handle = get_node_handle(node_handle);
154         deg_node_handle->builder->add_node_handle_relation(comp_key,
155                                                            deg_node_handle,
156                                                            description);
157 }
158
159 void DEG_add_object_pointcache_relation(struct DepsNodeHandle *node_handle,
160                                         struct Object *object,
161                                         eDepsObjectComponentType component,
162                                         const char *description)
163 {
164         DEG::NodeType type = deg_build_object_component_type(component);
165         DEG::ComponentKey comp_key(&object->id, type);
166         DEG::DepsNodeHandle *deg_node_handle = get_node_handle(node_handle);
167         DEG::DepsgraphRelationBuilder *relation_builder = deg_node_handle->builder;
168         /* Add relation from source to the node handle. */
169         relation_builder->add_node_handle_relation(
170                 comp_key, deg_node_handle, description);
171         /* Node deduct point cache component and connect source to it. */
172         ID *id = DEG_get_id_from_handle(node_handle);
173         DEG::ComponentKey point_cache_key(id, DEG::NodeType::POINT_CACHE);
174         DEG::Relation *rel = relation_builder->add_relation(
175                 comp_key, point_cache_key, "Point Cache");
176         if (rel != NULL) {
177                 rel->flag |= DEG::RELATION_FLAG_FLUSH_USER_EDIT_ONLY;
178         }
179         else {
180                 fprintf(stderr,
181                         "Error in point cache relation from %s to ^%s.\n",
182                         object->id.name,
183                         id->name);
184         }
185 }
186
187 void DEG_add_generic_id_relation(struct DepsNodeHandle *node_handle,
188                                  struct ID *id,
189                                  const char *description)
190 {
191         DEG::OperationKey operation_key(
192                 id,
193                 DEG::NodeType::GENERIC_DATABLOCK,
194                 DEG::OperationCode::GENERIC_DATABLOCK_UPDATE);
195         DEG::DepsNodeHandle *deg_node_handle = get_node_handle(node_handle);
196         deg_node_handle->builder->add_node_handle_relation(operation_key,
197                                                            deg_node_handle,
198                                                            description);
199 }
200
201 void DEG_add_special_eval_flag(struct DepsNodeHandle *node_handle,
202                                ID *id,
203                                uint32_t flag)
204 {
205         DEG::DepsNodeHandle *deg_node_handle = get_node_handle(node_handle);
206         deg_node_handle->builder->add_special_eval_flag(id, flag);
207 }
208
209 void DEG_add_customdata_mask(struct DepsNodeHandle *node_handle,
210                              struct Object *object,
211                              uint64_t mask)
212 {
213         DEG::DepsNodeHandle *deg_node_handle = get_node_handle(node_handle);
214         deg_node_handle->builder->add_customdata_mask(object, mask);
215 }
216
217 struct ID *DEG_get_id_from_handle(struct DepsNodeHandle *node_handle)
218 {
219         DEG::DepsNodeHandle *deg_handle = get_node_handle(node_handle);
220         return deg_handle->node->owner->owner->id_orig;
221 }
222
223 struct Depsgraph *DEG_get_graph_from_handle(struct DepsNodeHandle *node_handle)
224 {
225         DEG::DepsNodeHandle *deg_node_handle = get_node_handle(node_handle);
226         DEG::DepsgraphRelationBuilder *relation_builder = deg_node_handle->builder;
227         return reinterpret_cast<Depsgraph *>(relation_builder->getGraph());
228 }
229
230 /* ******************** */
231 /* Graph Building API's */
232
233 /* Build depsgraph for the given scene layer, and dump results in given
234  * graph container.
235  */
236 void DEG_graph_build_from_view_layer(Depsgraph *graph,
237                                       Main *bmain,
238                                       Scene *scene,
239                                       ViewLayer *view_layer)
240 {
241         double start_time = 0.0;
242         if (G.debug & G_DEBUG_DEPSGRAPH_BUILD) {
243                 start_time = PIL_check_seconds_timer();
244         }
245         DEG::Depsgraph *deg_graph = reinterpret_cast<DEG::Depsgraph *>(graph);
246         /* Perform sanity checks. */
247         BLI_assert(BLI_findindex(&scene->view_layers, view_layer) != -1);
248         BLI_assert(deg_graph->scene == scene);
249         BLI_assert(deg_graph->view_layer == view_layer);
250         /* Generate all the nodes in the graph first */
251         DEG::DepsgraphNodeBuilder node_builder(bmain, deg_graph);
252         node_builder.begin_build();
253         node_builder.build_view_layer(scene,
254                                        view_layer,
255                                        DEG::DEG_ID_LINKED_DIRECTLY);
256         node_builder.end_build();
257         /* Hook up relationships between operations - to determine evaluation
258          * order. */
259         DEG::DepsgraphRelationBuilder relation_builder(bmain, deg_graph);
260         relation_builder.begin_build();
261         relation_builder.build_view_layer(scene, view_layer);
262         relation_builder.build_copy_on_write_relations();
263         /* Detect and solve cycles. */
264         DEG::deg_graph_detect_cycles(deg_graph);
265         /* Simplify the graph by removing redundant relations (to optimize
266          * traversal later). */
267         /* TODO: it would be useful to have an option to disable this in cases where
268          *       it is causing trouble. */
269         if (G.debug_value == 799) {
270                 DEG::deg_graph_transitive_reduction(deg_graph);
271         }
272         /* Store pointers to commonly used valuated datablocks. */
273         deg_graph->scene_cow = (Scene *)deg_graph->get_cow_id(&deg_graph->scene->id);
274         /* Flush visibility layer and re-schedule nodes for update. */
275         DEG::deg_graph_build_finalize(bmain, deg_graph);
276         DEG_graph_on_visible_update(bmain, graph);
277 #if 0
278         if (!DEG_debug_consistency_check(deg_graph)) {
279                 printf("Consistency validation failed, ABORTING!\n");
280                 abort();
281         }
282 #endif
283         /* Relations are up to date. */
284         deg_graph->need_update = false;
285         /* Finish statistics. */
286         if (G.debug & G_DEBUG_DEPSGRAPH_BUILD) {
287                 printf("Depsgraph built in %f seconds.\n",
288                        PIL_check_seconds_timer() - start_time);
289         }
290 }
291
292 /* Tag graph relations for update. */
293 void DEG_graph_tag_relations_update(Depsgraph *graph)
294 {
295         DEG_DEBUG_PRINTF(graph, TAG, "%s: Tagging relations for update.\n", __func__);
296         DEG::Depsgraph *deg_graph = reinterpret_cast<DEG::Depsgraph *>(graph);
297         deg_graph->need_update = true;
298         /* NOTE: When relations are updated, it's quite possible that
299          * we've got new bases in the scene. This means, we need to
300          * re-create flat array of bases in view layer.
301          *
302          * TODO(sergey): Try to make it so we don't flush updates
303          * to the whole depsgraph. */
304         DEG::IDNode *id_node = deg_graph->find_id_node(&deg_graph->scene->id);
305         if (id_node != NULL) {
306                 id_node->tag_update(deg_graph, DEG::DEG_UPDATE_SOURCE_RELATIONS);
307         }
308 }
309
310 /* Create or update relations in the specified graph. */
311 void DEG_graph_relations_update(Depsgraph *graph,
312                                 Main *bmain,
313                                 Scene *scene,
314                                 ViewLayer *view_layer)
315 {
316         DEG::Depsgraph *deg_graph = (DEG::Depsgraph *)graph;
317         if (!deg_graph->need_update) {
318                 /* Graph is up to date, nothing to do. */
319                 return;
320         }
321         DEG_graph_build_from_view_layer(graph, bmain, scene, view_layer);
322 }
323
324 /* Tag all relations for update. */
325 void DEG_relations_tag_update(Main *bmain)
326 {
327         DEG_GLOBAL_DEBUG_PRINTF(TAG, "%s: Tagging relations for update.\n", __func__);
328         LISTBASE_FOREACH (Scene *, scene, &bmain->scene) {
329                 LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) {
330                         Depsgraph *depsgraph =
331                                 (Depsgraph *)BKE_scene_get_depsgraph(scene,
332                                                                      view_layer,
333                                                                      false);
334                         if (depsgraph != NULL) {
335                                 DEG_graph_tag_relations_update(depsgraph);
336                         }
337                 }
338         }
339 }