Merge branch 'master' into blender2.8
[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 extern "C" {
38 #include "BLI_utildefines.h"
39
40 #include "DNA_object_types.h"
41 #include "DNA_particle_types.h"
42 #include "DNA_screen_types.h"
43 #include "DNA_windowmanager_types.h"
44
45 #include "BLI_task.h"
46 #include "BLI_listbase.h"
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
57 #include "DEG_depsgraph.h"
58 } /* extern "C" */
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_operation.h"
65
66 #include "intern/depsgraph_intern.h"
67 #include "util/deg_util_foreach.h"
68
69 /* *********************** */
70 /* Update Tagging/Flushing */
71
72 /* Legacy depsgraph did some special trickery for things like particle systems
73  * when tagging ID for an update. Ideally that tagging needs to become obsolete
74  * in favor of havng dedicated node for that which gets tagged, but for until
75  * design of those areas is more clear we'll do the same legacy code here.
76  *                                                                  - sergey -
77  */
78 #define DEPSGRAPH_USE_LEGACY_TAGGING
79
80 namespace {
81
82 /* Data-Based Tagging ------------------------------- */
83
84 void lib_id_recalc_tag(Main *bmain, ID *id)
85 {
86         id->tag |= LIB_TAG_ID_RECALC;
87         DEG_id_type_tag(bmain, GS(id->name));
88 }
89
90 void lib_id_recalc_data_tag(Main *bmain, ID *id)
91 {
92         id->tag |= LIB_TAG_ID_RECALC_DATA;
93         DEG_id_type_tag(bmain, GS(id->name));
94 }
95
96 void lib_id_recalc_tag_flag(Main *bmain, ID *id, int flag)
97 {
98         if (flag) {
99                 /* This bit of code ensures legacy object->recalc flags
100                  * are still filled in the same way as it was expected
101                  * with the old dependency graph.
102                  *
103                  * This is because some areas like motion paths and likely
104                  * some other physics baking process are doing manual scene
105                  * update on all the frames, trying to minimize number of
106                  * updates.
107                  *
108                  * But this flag will also let us to re-construct entry
109                  * nodes for update after relations update and after layer
110                  * visibility changes.
111                  */
112                 short idtype = GS(id->name);
113                 if (idtype == ID_OB) {
114                         Object *object = (Object *)id;
115                         object->recalc |= (flag & OB_RECALC_ALL);
116                 }
117
118                 if (flag & OB_RECALC_OB)
119                         lib_id_recalc_tag(bmain, id);
120                 if (flag & (OB_RECALC_DATA | PSYS_RECALC))
121                         lib_id_recalc_data_tag(bmain, id);
122         }
123         else {
124                 lib_id_recalc_tag(bmain, id);
125         }
126 }
127
128 #ifdef DEPSGRAPH_USE_LEGACY_TAGGING
129 void depsgraph_legacy_handle_update_tag(Main *bmain, ID *id, short flag)
130 {
131         if (flag) {
132                 Object *object;
133                 short idtype = GS(id->name);
134                 if (idtype == ID_PA) {
135                         ParticleSystem *psys;
136                         for (object = (Object *)bmain->object.first;
137                              object != NULL;
138                              object = (Object *)object->id.next)
139                         {
140                                 for (psys = (ParticleSystem *)object->particlesystem.first;
141                                      psys != NULL;
142                                      psys = (ParticleSystem *)psys->next)
143                                 {
144                                         if (&psys->part->id == id) {
145                                                 DEG_id_tag_update_ex(bmain, &object->id, flag & OB_RECALC_ALL);
146                                                 psys->recalc |= (flag & PSYS_RECALC);
147                                         }
148                                 }
149                         }
150                 }
151         }
152 }
153 #endif
154
155 }  /* namespace */
156
157 /* Tag all nodes in ID-block for update.
158  * This is a crude measure, but is most convenient for old code.
159  */
160 void DEG_graph_id_tag_update(Main *bmain, Depsgraph *graph, ID *id)
161 {
162         DEG::Depsgraph *deg_graph = reinterpret_cast<DEG::Depsgraph *>(graph);
163         DEG::IDDepsNode *node = deg_graph->find_id_node(id);
164         lib_id_recalc_tag(bmain, id);
165         if (node != NULL) {
166                 node->tag_update(deg_graph);
167         }
168 }
169
170 /* Tag nodes related to a specific piece of data */
171 void DEG_graph_data_tag_update(Depsgraph *graph, const PointerRNA *ptr)
172 {
173         DEG::Depsgraph *deg_graph = reinterpret_cast<DEG::Depsgraph *>(graph);
174         DEG::DepsNode *node = deg_graph->find_node_from_pointer(ptr, NULL);
175         if (node != NULL) {
176                 node->tag_update(deg_graph);
177         }
178         else {
179                 printf("Missing node in %s\n", __func__);
180                 BLI_assert(!"Shouldn't happens since it'll miss crucial update.");
181         }
182 }
183
184 /* Tag nodes related to a specific property. */
185 void DEG_graph_property_tag_update(Depsgraph *graph,
186                                    const PointerRNA *ptr,
187                                    const PropertyRNA *prop)
188 {
189         DEG::Depsgraph *deg_graph = reinterpret_cast<DEG::Depsgraph *>(graph);
190         DEG::DepsNode *node = deg_graph->find_node_from_pointer(ptr, prop);
191         if (node != NULL) {
192                 node->tag_update(deg_graph);
193         }
194         else {
195                 printf("Missing node in %s\n", __func__);
196                 BLI_assert(!"Shouldn't happens since it'll miss crucial update.");
197         }
198 }
199
200 /* Tag given ID for an update in all the dependency graphs. */
201 void DEG_id_tag_update(ID *id, short flag)
202 {
203         DEG_id_tag_update_ex(G.main, id, flag);
204 }
205
206 void DEG_id_tag_update_ex(Main *bmain, ID *id, short flag)
207 {
208         if (id == NULL) {
209                 /* Ideally should not happen, but old depsgraph allowed this. */
210                 return;
211         }
212         DEG_DEBUG_PRINTF("%s: id=%s flag=%d\n", __func__, id->name, flag);
213         lib_id_recalc_tag_flag(bmain, id, flag);
214         for (Scene *scene = (Scene *)bmain->scene.first;
215              scene != NULL;
216              scene = (Scene *)scene->id.next)
217         {
218                 if (scene->depsgraph) {
219                         Depsgraph *graph = scene->depsgraph;
220                         if (flag == 0) {
221                                 /* TODO(sergey): Currently blender is still tagging IDs
222                                  * for recalc just using flag=0. This isn't totally correct
223                                  * but we'd better deal with such cases and don't fail.
224                                  */
225                                 DEG_graph_id_tag_update(bmain, graph, id);
226                                 continue;
227                         }
228                         if (flag & OB_RECALC_DATA && GS(id->name) == ID_OB) {
229                                 Object *object = (Object *)id;
230                                 if (object->data != NULL) {
231                                         DEG_graph_id_tag_update(bmain,
232                                                                 graph,
233                                                                 (ID *)object->data);
234                                 }
235                         }
236                         if (flag & (OB_RECALC_OB | OB_RECALC_DATA)) {
237                                 DEG_graph_id_tag_update(bmain, graph, id);
238                         }
239                         else if (flag & OB_RECALC_TIME) {
240                                 DEG_graph_id_tag_update(bmain, graph, id);
241                         }
242                 }
243         }
244
245 #ifdef DEPSGRAPH_USE_LEGACY_TAGGING
246         /* Special handling from the legacy depsgraph.
247          * TODO(sergey): Need to get rid of those once all the areas
248          * are re-formulated in terms of franular nodes.
249          */
250         depsgraph_legacy_handle_update_tag(bmain, id, flag);
251 #endif
252 }
253
254 /* Tag given ID type for update. */
255 void DEG_id_type_tag(Main *bmain, short idtype)
256 {
257         if (idtype == ID_NT) {
258                 /* Stupid workaround so parent datablocks of nested nodetree get looped
259                  * over when we loop over tagged datablock types.
260                  */
261                 DEG_id_type_tag(bmain, ID_MA);
262                 DEG_id_type_tag(bmain, ID_TE);
263                 DEG_id_type_tag(bmain, ID_LA);
264                 DEG_id_type_tag(bmain, ID_WO);
265                 DEG_id_type_tag(bmain, ID_SCE);
266         }
267
268         bmain->id_tag_update[BKE_idcode_to_index(idtype)] = 1;
269 }
270
271 /* Recursively push updates out to all nodes dependent on this,
272  * until all affected are tagged and/or scheduled up for eval
273  */
274 void DEG_ids_flush_tagged(Main *bmain)
275 {
276         for (Scene *scene = (Scene *)bmain->scene.first;
277              scene != NULL;
278              scene = (Scene *)scene->id.next)
279         {
280                 /* TODO(sergey): Only visible scenes? */
281                 if (scene->depsgraph != NULL) {
282                         DEG::deg_graph_flush_updates(
283                                 bmain,
284                                 reinterpret_cast<DEG::Depsgraph *>(scene->depsgraph));
285                 }
286         }
287 }
288
289 /* Update dependency graph when visible scenes/layers changes. */
290 void DEG_graph_on_visible_update(Main *bmain, Scene *scene)
291 {
292         (void) bmain;
293         DEG::Depsgraph *graph = reinterpret_cast<DEG::Depsgraph *>(scene->depsgraph);
294         GHASH_FOREACH_BEGIN(DEG::IDDepsNode *, id_node, graph->id_hash)
295         {
296                 id_node->tag_update(graph);
297         }
298         GHASH_FOREACH_END();
299 }
300
301 void DEG_on_visible_update(Main *bmain, const bool UNUSED(do_time))
302 {
303         for (Scene *scene = (Scene *)bmain->scene.first;
304              scene != NULL;
305              scene = (Scene *)scene->id.next)
306         {
307                 if (scene->depsgraph != NULL) {
308                         DEG_graph_on_visible_update(bmain, scene);
309                 }
310         }
311 }
312
313 /* Check if something was changed in the database and inform
314  * editors about this.
315  */
316 void DEG_ids_check_recalc(Main *bmain, Scene *scene, bool time)
317 {
318         ListBase *lbarray[MAX_LIBARRAY];
319         int a;
320         bool updated = false;
321
322         /* Loop over all ID types. */
323         a  = set_listbasepointers(bmain, lbarray);
324         while (a--) {
325                 ListBase *lb = lbarray[a];
326                 ID *id = (ID *)lb->first;
327
328                 if (id && bmain->id_tag_update[BKE_idcode_to_index(GS(id->name))]) {
329                         updated = true;
330                         break;
331                 }
332         }
333
334         DEG::deg_editors_scene_update(bmain, scene, (updated || time));
335 }
336
337 void DEG_ids_clear_recalc(Main *bmain)
338 {
339         ListBase *lbarray[MAX_LIBARRAY];
340         bNodeTree *ntree;
341         int a;
342
343         /* TODO(sergey): Re-implement POST_UPDATE_HANDLER_WORKAROUND using entry_tags
344          * and id_tags storage from the new dependency graph.
345          */
346
347         /* Loop over all ID types. */
348         a  = set_listbasepointers(bmain, lbarray);
349         while (a--) {
350                 ListBase *lb = lbarray[a];
351                 ID *id = (ID *)lb->first;
352
353                 if (id && bmain->id_tag_update[BKE_idcode_to_index(GS(id->name))]) {
354                         for (; id; id = (ID *)id->next) {
355                                 id->tag &= ~(LIB_TAG_ID_RECALC | LIB_TAG_ID_RECALC_DATA);
356
357                                 /* Some ID's contain semi-datablock nodetree */
358                                 ntree = ntreeFromID(id);
359                                 if (ntree != NULL) {
360                                         ntree->id.tag &= ~(LIB_TAG_ID_RECALC | LIB_TAG_ID_RECALC_DATA);
361                                 }
362                         }
363                 }
364         }
365
366         memset(bmain->id_tag_update, 0, sizeof(bmain->id_tag_update));
367 }