Depsgraph: Restore ID datablock tag when Object is tagged with OB_RECALC_DATA
[blender.git] / source / blender / depsgraph / intern / depsgraph_tag.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): None Yet
23  *
24  * ***** END GPL LICENSE BLOCK *****
25  */
26
27 /** \file blender/depsgraph/intern/depsgraph_tag.cc
28  *  \ingroup depsgraph
29  *
30  * Core routines for how the Depsgraph works.
31  */
32
33 #include <stdio.h>
34 #include <cstring>  /* required for memset */
35 #include <queue>
36
37 #include "BLI_utildefines.h"
38 #include "BLI_task.h"
39 #include "BLI_listbase.h"
40
41 extern "C" {
42 #include "DNA_object_types.h"
43 #include "DNA_particle_types.h"
44 #include "DNA_screen_types.h"
45 #include "DNA_windowmanager_types.h"
46
47
48 #include "BKE_idcode.h"
49 #include "BKE_library.h"
50 #include "BKE_main.h"
51 #include "BKE_node.h"
52 #include "BKE_workspace.h"
53
54 #define new new_
55 #include "BKE_screen.h"
56 #undef new
57 } /* extern "C" */
58
59 #include "DEG_depsgraph.h"
60
61 #include "intern/builder/deg_builder.h"
62 #include "intern/eval/deg_eval_flush.h"
63 #include "intern/nodes/deg_node.h"
64 #include "intern/nodes/deg_node_component.h"
65 #include "intern/nodes/deg_node_operation.h"
66
67 #include "intern/depsgraph_intern.h"
68 #include "util/deg_util_foreach.h"
69
70 /* *********************** */
71 /* Update Tagging/Flushing */
72
73 namespace DEG {
74
75 /* Data-Based Tagging ------------------------------- */
76
77 void lib_id_recalc_tag(Main *bmain, ID *id)
78 {
79         id->tag |= LIB_TAG_ID_RECALC;
80         DEG_id_type_tag(bmain, GS(id->name));
81 }
82
83 void lib_id_recalc_data_tag(Main *bmain, ID *id)
84 {
85         id->tag |= LIB_TAG_ID_RECALC_DATA;
86         DEG_id_type_tag(bmain, GS(id->name));
87 }
88
89 namespace {
90
91 void lib_id_recalc_tag_flag(Main *bmain, ID *id, int flag)
92 {
93         /* This bit of code ensures legacy object->recalc flags are still filled in
94          * the same way as it was expected with the old dependency graph.
95          *
96          * This is because some areas like motion paths and likely some other
97          * physics baking process are doing manual scene update on all the frames,
98          * trying to minimize number of updates.
99          *
100          * But this flag will also let us to re-construct entry nodes for update
101          * after relations update and after layer visibility changes.
102          */
103         if (flag) {
104                 short idtype = GS(id->name);
105                 if (idtype == ID_OB) {
106                         Object *object = (Object *)id;
107                         object->recalc |= (flag & OB_RECALC_ALL);
108                 }
109                 if (flag & OB_RECALC_OB) {
110                         lib_id_recalc_tag(bmain, id);
111                 }
112                 if (flag & (OB_RECALC_DATA | PSYS_RECALC)) {
113                         lib_id_recalc_data_tag(bmain, id);
114                 }
115         }
116         else {
117                 lib_id_recalc_tag(bmain, id);
118         }
119 }
120
121 /* Special tagging  */
122 void id_tag_update_special_zero_flag(Depsgraph *graph, IDDepsNode *id_node)
123 {
124         /* NOTE: Full ID node update for now, need to minimize that i9n the future. */
125         id_node->tag_update(graph);
126 }
127
128 /* Tag corresponding to OB_RECALC_OB. */
129 void id_tag_update_object_transform(Depsgraph *graph, IDDepsNode *id_node)
130 {
131         ComponentDepsNode *transform_comp =
132                 id_node->find_component(DEG_NODE_TYPE_TRANSFORM);
133         if (transform_comp == NULL) {
134                 DEG_ERROR_PRINTF("ERROR: Unable to find transform component for %s\n",
135                                  id_node->id_orig->name);
136                 BLI_assert(!"This is not supposed to happen!");
137                 return;
138         }
139         transform_comp->tag_update(graph);
140 }
141
142 /* Tag corresponding to OB_RECALC_DATA. */
143 void id_tag_update_object_data(Depsgraph *graph, IDDepsNode *id_node)
144 {
145         const short idtype = GS(id_node->id_orig->name);
146         ComponentDepsNode *data_comp = NULL;
147         switch (idtype) {
148                 case ID_OB:
149                 {
150                         const Object *object = (Object *)id_node->id_orig;
151                         switch (object->type) {
152                                 case OB_MESH:
153                                 case OB_CURVE:
154                                 case OB_SURF:
155                                 case OB_FONT:
156                                 case OB_MBALL:
157                                         data_comp = id_node->find_component(DEG_NODE_TYPE_GEOMETRY);
158                                         break;
159                                 case OB_ARMATURE:
160                                         data_comp = id_node->find_component(DEG_NODE_TYPE_EVAL_POSE);
161                                         break;
162                                 /* TODO(sergey): More cases here? */
163                         }
164                         break;
165                 }
166                 case ID_ME:
167                         data_comp = id_node->find_component(DEG_NODE_TYPE_GEOMETRY);
168                         break;
169                 case ID_PA:
170                         return;
171         }
172         if (data_comp == NULL) {
173                 DEG_ERROR_PRINTF("ERROR: Unable to find data component for %s\n",
174                                  id_node->id_orig->name);
175                 BLI_assert(!"This is not supposed to happen!");
176                 return;
177         }
178         data_comp->tag_update(graph);
179         /* Special legacy compatibility code, tag data ID for update when object
180          * is tagged for data update.
181          */
182         if (idtype == ID_OB) {
183                 Object *object = (Object *)id_node->id_orig;
184                 ID *data_id = (ID *)object->data;
185                 if (data_id != NULL) {
186                         IDDepsNode *data_id_node = graph->find_id_node(data_id);
187                         BLI_assert(data_id_node != NULL);
188                         /* TODO(sergey): Do we want more granular tags here? */
189                         data_id_node->tag_update(graph);
190                 }
191         }
192 }
193
194 /* Tag corresponding to OB_RECALC_TIME. */
195 void id_tag_update_object_time(Depsgraph *graph, IDDepsNode *id_node)
196 {
197         ComponentDepsNode *animation_comp =
198                 id_node->find_component(DEG_NODE_TYPE_ANIMATION);
199         if (animation_comp == NULL) {
200                 /* It's not necessarily we've got animation component in cases when
201                  * we are tagging for time updates.
202                  */
203                 return;
204         }
205         animation_comp->tag_update(graph);
206         /* TODO(sergey): More components to tag here? */
207 }
208
209 void id_tag_update_particle(Depsgraph *graph, IDDepsNode *id_node)
210 {
211         ComponentDepsNode *particle_comp =
212                 id_node->find_component(DEG_NODE_TYPE_PARAMETERS);
213         if (particle_comp == NULL) {
214                 DEG_ERROR_PRINTF("ERROR: Unable to find particle component for %s\n",
215                                  id_node->id_orig->name);
216                 BLI_assert(!"This is not supposed to happen!");
217                 return;
218         }
219         particle_comp->tag_update(graph);
220 }
221
222 #ifdef WITH_COPY_ON_WRITE
223 /* Tag corresponding to DEG_TAG_COPY_ON_WRITE. */
224 void id_tag_update_copy_on_write(Depsgraph *graph, IDDepsNode *id_node)
225 {
226         ComponentDepsNode *cow_comp =
227                 id_node->find_component(DEG_NODE_TYPE_COPY_ON_WRITE);
228         OperationDepsNode *cow_node = cow_comp->get_entry_operation();
229         cow_node->tag_update(graph);
230         cow_node->flag |= DEPSOP_FLAG_SKIP_FLUSH;
231 }
232 #endif
233
234 void deg_graph_id_tag_update(Main *bmain, Depsgraph *graph, ID *id, int flag)
235 {
236         Depsgraph *deg_graph = reinterpret_cast<DEG::Depsgraph *>(graph);
237         IDDepsNode *id_node = deg_graph->find_id_node(id);
238         /* Make sure legacy flags are all nicely update. */
239         lib_id_recalc_tag_flag(bmain, id, flag);
240         if (id_node == NULL) {
241                 /* Shouldn't happen, but better be sure here. */
242                 return;
243         }
244         /* Tag components based on flags. */
245         if (flag == 0) {
246                 id_tag_update_special_zero_flag(graph, id_node);
247                 return;
248         }
249         if (flag & OB_RECALC_OB) {
250                 id_tag_update_object_transform(graph, id_node);
251         }
252         if (flag & OB_RECALC_DATA) {
253                 id_tag_update_object_data(graph, id_node);
254         }
255         if (flag & OB_RECALC_TIME) {
256                 id_tag_update_object_time(graph, id_node);
257         }
258         if (flag & PSYS_RECALC) {
259                 /* TODO(sergey): Differentiate between different particle updates tags. */
260                 id_tag_update_particle(graph, id_node);
261         }
262 #ifdef WITH_COPY_ON_WRITE
263         if (flag & DEG_TAG_COPY_ON_WRITE) {
264                 id_tag_update_copy_on_write(graph, id_node);
265         }
266 #endif
267 }
268
269 void deg_id_tag_update(Main *bmain, ID *id, int flag)
270 {
271         lib_id_recalc_tag_flag(bmain, id, flag);
272         for (Scene *scene = (Scene *)bmain->scene.first;
273              scene != NULL;
274              scene = (Scene *)scene->id.next)
275         {
276                 if (scene->depsgraph_legacy != NULL) {
277                         Depsgraph *graph = (Depsgraph *)scene->depsgraph_legacy;
278                         deg_graph_id_tag_update(bmain, graph, id, flag);
279                 }
280         }
281 }
282
283 void deg_graph_on_visible_update(Main *bmain, Scene *scene, Depsgraph *graph)
284 {
285         /* Make sure objects are up to date. */
286         GHASH_FOREACH_BEGIN(DEG::IDDepsNode *, id_node, graph->id_hash)
287         {
288                 const short idtype = GS(id_node->id_orig->name);
289                 if (idtype != ID_OB) {
290                         /* Ignore non-object nodes on visibility changes. */
291                         continue;
292                 }
293                 int flag = 0;
294                 /* We only tag components which needs an update. Tagging everything is
295                  * not a good idea because that might reset particles cache (or any
296                  * other type of cache).
297                  *
298                  * TODO(sergey): Need to generalize this somehow.
299                  */
300                 if (idtype == ID_OB) {
301                         Object *object = (Object *)id_node->id_orig;
302                         flag |= OB_RECALC_OB;
303                         if (ELEM(object->type, OB_MESH,
304                                                OB_CURVE,
305                                                OB_SURF,
306                                                OB_FONT,
307                                                OB_MBALL))
308                         {
309                                 flag |= OB_RECALC_DATA;
310                         }
311                 }
312                 deg_graph_id_tag_update(bmain, graph, id_node->id_orig, flag);
313         }
314         GHASH_FOREACH_END();
315         /* Make sure collection properties are up to date. */
316         IDDepsNode *scene_id_node = graph->find_id_node(&scene->id);
317         BLI_assert(scene_id_node != NULL);
318         scene_id_node->tag_update(graph);
319 }
320
321 }  /* namespace */
322
323 }  // namespace DEG
324
325 /* Tag given ID for an update in all the dependency graphs. */
326 void DEG_id_tag_update(ID *id, int flag)
327 {
328         DEG_id_tag_update_ex(G.main, id, flag);
329 }
330
331 void DEG_id_tag_update_ex(Main *bmain, ID *id, int flag)
332 {
333         if (id == NULL) {
334                 /* Ideally should not happen, but old depsgraph allowed this. */
335                 return;
336         }
337         DEG_DEBUG_PRINTF("%s: id=%s flag=%d\n", __func__, id->name, flag);
338         DEG::deg_id_tag_update(bmain, id, flag);
339 }
340
341 /* Tag given ID type for update. */
342 void DEG_id_type_tag(Main *bmain, short idtype)
343 {
344         if (idtype == ID_NT) {
345                 /* Stupid workaround so parent datablocks of nested nodetree get looped
346                  * over when we loop over tagged datablock types.
347                  */
348                 DEG_id_type_tag(bmain, ID_MA);
349                 DEG_id_type_tag(bmain, ID_TE);
350                 DEG_id_type_tag(bmain, ID_LA);
351                 DEG_id_type_tag(bmain, ID_WO);
352                 DEG_id_type_tag(bmain, ID_SCE);
353         }
354
355         bmain->id_tag_update[BKE_idcode_to_index(idtype)] = 1;
356 }
357
358 /* Recursively push updates out to all nodes dependent on this,
359  * until all affected are tagged and/or scheduled up for eval
360  */
361 void DEG_ids_flush_tagged(Main *bmain, Scene *scene)
362 {
363         /* TODO(sergey): Only visible scenes? */
364         if (scene->depsgraph_legacy != NULL) {
365                 DEG::deg_graph_flush_updates(
366                         bmain,
367                         reinterpret_cast<DEG::Depsgraph *>(scene->depsgraph_legacy));
368         }
369 }
370
371 /* Update dependency graph when visible scenes/layers changes. */
372 void DEG_graph_on_visible_update(Main *bmain, Scene *scene)
373 {
374         DEG::Depsgraph *graph = (DEG::Depsgraph *)scene->depsgraph_legacy;
375         DEG::deg_graph_on_visible_update(bmain, scene, graph);
376 }
377
378 void DEG_on_visible_update(Main *bmain, const bool UNUSED(do_time))
379 {
380         for (Scene *scene = (Scene *)bmain->scene.first;
381              scene != NULL;
382              scene = (Scene *)scene->id.next)
383         {
384                 if (scene->depsgraph_legacy != NULL) {
385                         DEG_graph_on_visible_update(bmain, scene);
386                 }
387         }
388 }
389
390 /* Check if something was changed in the database and inform
391  * editors about this.
392  */
393 void DEG_ids_check_recalc(Main *bmain, Scene *scene, bool time)
394 {
395         ListBase *lbarray[MAX_LIBARRAY];
396         int a;
397         bool updated = false;
398
399         /* Loop over all ID types. */
400         a  = set_listbasepointers(bmain, lbarray);
401         while (a--) {
402                 ListBase *lb = lbarray[a];
403                 ID *id = (ID *)lb->first;
404
405                 if (id && bmain->id_tag_update[BKE_idcode_to_index(GS(id->name))]) {
406                         updated = true;
407                         break;
408                 }
409         }
410
411         DEG::deg_editors_scene_update(bmain, scene, (updated || time));
412 }
413
414 void DEG_ids_clear_recalc(Main *bmain)
415 {
416         ListBase *lbarray[MAX_LIBARRAY];
417         bNodeTree *ntree;
418         int a;
419
420         /* TODO(sergey): Re-implement POST_UPDATE_HANDLER_WORKAROUND using entry_tags
421          * and id_tags storage from the new dependency graph.
422          */
423
424         /* Loop over all ID types. */
425         a  = set_listbasepointers(bmain, lbarray);
426         while (a--) {
427                 ListBase *lb = lbarray[a];
428                 ID *id = (ID *)lb->first;
429
430                 if (id && bmain->id_tag_update[BKE_idcode_to_index(GS(id->name))]) {
431                         for (; id; id = (ID *)id->next) {
432                                 id->tag &= ~(LIB_TAG_ID_RECALC | LIB_TAG_ID_RECALC_DATA);
433
434                                 /* Some ID's contain semi-datablock nodetree */
435                                 ntree = ntreeFromID(id);
436                                 if (ntree != NULL) {
437                                         ntree->id.tag &= ~(LIB_TAG_ID_RECALC | LIB_TAG_ID_RECALC_DATA);
438                                 }
439                         }
440                 }
441         }
442
443         memset(bmain->id_tag_update, 0, sizeof(bmain->id_tag_update));
444 }