Cleanup: use '_len' instead of '_size' w/ BLI API
[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
53 #define new new_
54 #include "BKE_screen.h"
55 #undef new
56 } /* extern "C" */
57
58 #include "DEG_depsgraph.h"
59
60 #include "intern/builder/deg_builder.h"
61 #include "intern/eval/deg_eval_flush.h"
62 #include "intern/nodes/deg_node.h"
63 #include "intern/nodes/deg_node_component.h"
64 #include "intern/nodes/deg_node_id.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 /* Legacy depsgraph did some special trickery for things like particle systems
74  * when tagging ID for an update. Ideally that tagging needs to become obsolete
75  * in favor of havng dedicated node for that which gets tagged, but for until
76  * design of those areas is more clear we'll do the same legacy code here.
77  *                                                                  - sergey -
78  */
79 #define DEPSGRAPH_USE_LEGACY_TAGGING
80
81 namespace {
82
83 /* Data-Based Tagging ------------------------------- */
84
85 void lib_id_recalc_tag(Main *bmain, ID *id)
86 {
87         id->recalc |= ID_RECALC;
88         DEG_id_type_tag(bmain, GS(id->name));
89 }
90
91 void lib_id_recalc_data_tag(Main *bmain, ID *id)
92 {
93         id->recalc |= ID_RECALC_DATA;
94         DEG_id_type_tag(bmain, GS(id->name));
95 }
96
97 void lib_id_recalc_tag_flag(Main *bmain, ID *id, int flag)
98 {
99         if (flag) {
100                 /* This bit of code ensures legacy object->recalc flags
101                  * are still filled in the same way as it was expected
102                  * with the old dependency graph.
103                  *
104                  * This is because some areas like motion paths and likely
105                  * some other physics baking process are doing manual scene
106                  * update on all the frames, trying to minimize number of
107                  * updates.
108                  *
109                  * But this flag will also let us to re-construct entry
110                  * nodes for update after relations update and after layer
111                  * visibility changes.
112                  */
113                 ID_Type idtype = GS(id->name);
114                 if (idtype == ID_OB) {
115                         Object *object = (Object *)id;
116                         object->recalc |= (flag & OB_RECALC_ALL);
117                 }
118
119                 if (flag & OB_RECALC_OB)
120                         lib_id_recalc_tag(bmain, id);
121                 if (flag & (OB_RECALC_DATA | PSYS_RECALC))
122                         lib_id_recalc_data_tag(bmain, id);
123         }
124         else {
125                 lib_id_recalc_tag(bmain, id);
126         }
127 }
128
129 #ifdef DEPSGRAPH_USE_LEGACY_TAGGING
130 void depsgraph_legacy_handle_update_tag(Main *bmain, ID *id, short flag)
131 {
132         if (flag) {
133                 Object *object;
134                 short idtype = GS(id->name);
135                 if (idtype == ID_PA) {
136                         ParticleSystem *psys;
137                         for (object = (Object *)bmain->object.first;
138                              object != NULL;
139                              object = (Object *)object->id.next)
140                         {
141                                 for (psys = (ParticleSystem *)object->particlesystem.first;
142                                      psys != NULL;
143                                      psys = (ParticleSystem *)psys->next)
144                                 {
145                                         if (&psys->part->id == id) {
146                                                 DEG_id_tag_update_ex(bmain, &object->id, flag & OB_RECALC_ALL);
147                                                 psys->recalc |= (flag & PSYS_RECALC);
148                                         }
149                                 }
150                         }
151                 }
152         }
153 }
154 #endif
155
156 }  /* namespace */
157
158 /* Tag all nodes in ID-block for update.
159  * This is a crude measure, but is most convenient for old code.
160  */
161 void DEG_graph_id_tag_update(Main *bmain, Depsgraph *graph, ID *id)
162 {
163         DEG::Depsgraph *deg_graph = reinterpret_cast<DEG::Depsgraph *>(graph);
164         DEG::IDDepsNode *node = deg_graph->find_id_node(id);
165         lib_id_recalc_tag(bmain, id);
166         if (node != NULL) {
167                 node->tag_update(deg_graph);
168         }
169 }
170
171 /* Tag given ID for an update in all the dependency graphs. */
172 void DEG_id_tag_update(ID *id, short flag)
173 {
174         DEG_id_tag_update_ex(G.main, id, flag);
175 }
176
177 void DEG_id_tag_update_ex(Main *bmain, ID *id, short flag)
178 {
179         if (id == NULL) {
180                 /* Ideally should not happen, but old depsgraph allowed this. */
181                 return;
182         }
183         DEG_DEBUG_PRINTF("%s: id=%s flag=%d\n", __func__, id->name, flag);
184         lib_id_recalc_tag_flag(bmain, id, flag);
185         for (Scene *scene = (Scene *)bmain->scene.first;
186              scene != NULL;
187              scene = (Scene *)scene->id.next)
188         {
189                 if (scene->depsgraph) {
190                         Depsgraph *graph = scene->depsgraph;
191                         if (flag == 0) {
192                                 /* TODO(sergey): Currently blender is still tagging IDs
193                                  * for recalc just using flag=0. This isn't totally correct
194                                  * but we'd better deal with such cases and don't fail.
195                                  */
196                                 DEG_graph_id_tag_update(bmain, graph, id);
197                                 continue;
198                         }
199                         if (flag & OB_RECALC_DATA && GS(id->name) == ID_OB) {
200                                 Object *object = (Object *)id;
201                                 if (object->data != NULL) {
202                                         DEG_graph_id_tag_update(bmain,
203                                                                 graph,
204                                                                 (ID *)object->data);
205                                 }
206                         }
207                         if (flag & (OB_RECALC_OB | OB_RECALC_DATA)) {
208                                 DEG_graph_id_tag_update(bmain, graph, id);
209                         }
210                         else if (flag & OB_RECALC_TIME) {
211                                 DEG_graph_id_tag_update(bmain, graph, id);
212                         }
213                 }
214         }
215
216 #ifdef DEPSGRAPH_USE_LEGACY_TAGGING
217         /* Special handling from the legacy depsgraph.
218          * TODO(sergey): Need to get rid of those once all the areas
219          * are re-formulated in terms of franular nodes.
220          */
221         depsgraph_legacy_handle_update_tag(bmain, id, flag);
222 #endif
223 }
224
225 /* Mark a particular datablock type as having changing. */
226 void DEG_id_type_tag(Main *bmain, short idtype)
227 {
228         if (idtype == ID_NT) {
229                 /* Stupid workaround so parent datablocks of nested nodetree get looped
230                  * over when we loop over tagged datablock types.
231                  */
232                 DEG_id_type_tag(bmain, ID_MA);
233                 DEG_id_type_tag(bmain, ID_TE);
234                 DEG_id_type_tag(bmain, ID_LA);
235                 DEG_id_type_tag(bmain, ID_WO);
236                 DEG_id_type_tag(bmain, ID_SCE);
237         }
238
239         bmain->id_tag_update[BKE_idcode_to_index(idtype)] = 1;
240 }
241
242 /* Recursively push updates out to all nodes dependent on this,
243  * until all affected are tagged and/or scheduled up for eval
244  */
245 void DEG_ids_flush_tagged(Main *bmain)
246 {
247         for (Scene *scene = (Scene *)bmain->scene.first;
248              scene != NULL;
249              scene = (Scene *)scene->id.next)
250         {
251                 DEG_scene_flush_update(bmain, scene);
252         }
253 }
254
255 void DEG_scene_flush_update(Main *bmain, Scene *scene)
256 {
257         if (scene->depsgraph == NULL) {
258                 return;
259         }
260         DEG::deg_graph_flush_updates(
261                 bmain,
262                 reinterpret_cast<DEG::Depsgraph *>(scene->depsgraph));
263 }
264
265 /* Update dependency graph when visible scenes/layers changes. */
266 void DEG_graph_on_visible_update(Main *bmain, Scene *scene)
267 {
268         DEG::Depsgraph *graph = reinterpret_cast<DEG::Depsgraph *>(scene->depsgraph);
269         wmWindowManager *wm = (wmWindowManager *)bmain->wm.first;
270         int old_layers = graph->layers;
271         if (wm != NULL) {
272                 BKE_main_id_tag_listbase(&bmain->scene, LIB_TAG_DOIT, true);
273                 graph->layers = 0;
274                 for (wmWindow *win = (wmWindow *)wm->windows.first;
275                      win != NULL;
276                      win = (wmWindow *)win->next)
277                 {
278                         Scene *scene = win->screen->scene;
279                         if (scene->id.tag & LIB_TAG_DOIT) {
280                                 graph->layers |= BKE_screen_visible_layers(win->screen, scene);
281                                 scene->id.tag &= ~LIB_TAG_DOIT;
282                         }
283                 }
284         }
285         else {
286                 /* All the layers for background render for now. */
287                 graph->layers = (1 << 20) - 1;
288         }
289         if (old_layers != graph->layers) {
290                 /* Tag all objects which becomes visible (or which becomes needed for dependencies)
291                  * for recalc.
292                  *
293                  * This is mainly needed on file load only, after that updates of invisible objects
294                  * will be stored in the pending list.
295                  */
296                 foreach (DEG::IDDepsNode *id_node, graph->id_nodes) {
297                         ID *id = id_node->id;
298                         if ((id->recalc & ID_RECALC_ALL) != 0 ||
299                             (id_node->layers & scene->lay_updated) == 0)
300                         {
301                                 id_node->tag_update(graph);
302                         }
303                         /* A bit of magic: if object->recalc is set it means somebody tagged
304                          * it for update. If corresponding ID recalc flags are zero it means
305                          * graph has been evaluated after that and the recalc was skipped
306                          * because of visibility check.
307                          */
308                         if (GS(id->name) == ID_OB) {
309                                 Object *object = (Object *)id;
310                                 if ((id->recalc & ID_RECALC_ALL) == 0 &&
311                                     (object->recalc & OB_RECALC_ALL) != 0)
312                                 {
313                                         id_node->tag_update(graph);
314                                         DEG::ComponentDepsNode *anim_comp =
315                                                 id_node->find_component(DEG::DEG_NODE_TYPE_ANIMATION);
316                                         if (anim_comp != NULL && object->recalc & OB_RECALC_TIME) {
317                                                 anim_comp->tag_update(graph);
318                                         }
319                                 }
320                         }
321                 }
322         }
323         scene->lay_updated |= graph->layers;
324         /* If graph is tagged for update, we don't need to bother with updates here,
325          * nodes will be re-created.
326          */
327         if (graph->need_update) {
328                 return;
329         }
330         /* Special trick to get local view to work.  */
331         LISTBASE_FOREACH (Base *, base, &scene->base) {
332                 Object *object = base->object;
333                 DEG::IDDepsNode *id_node = graph->find_id_node(&object->id);
334                 id_node->layers = 0;
335         }
336         LISTBASE_FOREACH (Base *, base, &scene->base) {
337                 Object *object = base->object;
338                 DEG::IDDepsNode *id_node = graph->find_id_node(&object->id);
339                 id_node->layers |= base->lay;
340                 if (object == scene->camera || object->type == OB_CAMERA) {
341                         /* Camera should always be updated, it used directly by viewport. */
342                         id_node->layers |= (unsigned int)(-1);
343                 }
344         }
345         DEG::deg_graph_build_flush_layers(graph);
346         LISTBASE_FOREACH (Base *, base, &scene->base) {
347                 Object *object = base->object;
348                 DEG::IDDepsNode *id_node = graph->find_id_node(&object->id);
349                 GHASH_FOREACH_BEGIN(DEG::ComponentDepsNode *, comp, id_node->components)
350                 {
351                         id_node->layers |= comp->layers;
352                 }
353                 GHASH_FOREACH_END();
354         }
355 }
356
357 void DEG_on_visible_update(Main *bmain, const bool UNUSED(do_time))
358 {
359         for (Scene *scene = (Scene *)bmain->scene.first;
360              scene != NULL;
361              scene = (Scene *)scene->id.next)
362         {
363                 if (scene->depsgraph != NULL) {
364                         DEG_graph_on_visible_update(bmain, scene);
365                 }
366         }
367 }
368
369 /* Check if something was changed in the database and inform
370  * editors about this.
371  */
372 void DEG_ids_check_recalc(Main *bmain, Scene *scene, bool time)
373 {
374         ListBase *lbarray[MAX_LIBARRAY];
375         int a;
376         bool updated = false;
377
378         /* Loop over all ID types. */
379         a  = set_listbasepointers(bmain, lbarray);
380         while (a--) {
381                 ListBase *lb = lbarray[a];
382                 ID *id = (ID *)lb->first;
383
384                 if (id && bmain->id_tag_update[BKE_idcode_to_index(GS(id->name))]) {
385                         updated = true;
386                         break;
387                 }
388         }
389
390         DEG::deg_editors_scene_update(bmain, scene, (updated || time));
391 }
392
393 void DEG_ids_clear_recalc(Main *bmain)
394 {
395         ListBase *lbarray[MAX_LIBARRAY];
396         bNodeTree *ntree;
397         int a;
398
399         /* TODO(sergey): Re-implement POST_UPDATE_HANDLER_WORKAROUND using entry_tags
400          * and id_tags storage from the new dependency graph.
401          */
402
403         /* Loop over all ID types. */
404         a  = set_listbasepointers(bmain, lbarray);
405         while (a--) {
406                 ListBase *lb = lbarray[a];
407                 ID *id = (ID *)lb->first;
408
409                 if (id && bmain->id_tag_update[BKE_idcode_to_index(GS(id->name))]) {
410                         for (; id; id = (ID *)id->next) {
411                                 id->recalc &= ~ID_RECALC_ALL;
412
413                                 /* Some ID's contain semi-datablock nodetree */
414                                 ntree = ntreeFromID(id);
415                                 if (ntree != NULL) {
416                                         ntree->id.recalc &= ~ID_RECALC_ALL;
417                                 }
418                         }
419                 }
420         }
421
422         memset(bmain->id_tag_update, 0, sizeof(bmain->id_tag_update));
423 }