Merge branch 'master' into blender2.8
[blender.git] / source / blender / depsgraph / intern / depsgraph.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): Sergey Sharybin
23  *
24  * ***** END GPL LICENSE BLOCK *****
25  */
26
27 /** \file blender/depsgraph/intern/depsgraph.cc
28  *  \ingroup depsgraph
29  *
30  * Core routines for how the Depsgraph works.
31  */
32
33 #include "intern/depsgraph.h" /* own include */
34
35 #include "MEM_guardedalloc.h"
36
37 #include "BLI_utildefines.h"
38 #include "BLI_console.h"
39 #include "BLI_hash.h"
40 #include "BLI_ghash.h"
41 #include "BLI_listbase.h"
42
43 extern "C" {
44 #include "DNA_action_types.h"
45 #include "DNA_armature_types.h"
46 #include "DNA_constraint_types.h"
47 #include "DNA_key_types.h"
48 #include "DNA_object_types.h"
49 #include "DNA_sequence_types.h"
50
51 #include "RNA_access.h"
52
53 #include "BKE_scene.h"
54 }
55
56 #include <algorithm>
57 #include <cstring>
58
59 #include "DEG_depsgraph.h"
60 #include "DEG_depsgraph_debug.h"
61
62 #include "intern/eval/deg_eval_copy_on_write.h"
63
64 #include "intern/nodes/deg_node.h"
65 #include "intern/nodes/deg_node_component.h"
66 #include "intern/nodes/deg_node_id.h"
67 #include "intern/nodes/deg_node_operation.h"
68 #include "intern/nodes/deg_node_time.h"
69
70 #include "intern/depsgraph_intern.h"
71 #include "util/deg_util_foreach.h"
72
73 namespace DEG {
74
75 static DEG_EditorUpdateIDCb deg_editor_update_id_cb = NULL;
76 static DEG_EditorUpdateSceneCb deg_editor_update_scene_cb = NULL;
77
78 /* TODO(sergey): Find a better place for this. */
79 template <typename T>
80 static void remove_from_vector(vector<T> *vector, const T& value)
81 {
82         vector->erase(std::remove(vector->begin(), vector->end(), value),
83                       vector->end());
84 }
85
86 Depsgraph::Depsgraph(Scene *scene,
87                      ViewLayer *view_layer,
88                      eEvaluationMode mode)
89   : time_source(NULL),
90     need_update(true),
91     scene(scene),
92     view_layer(view_layer),
93     mode(mode),
94     ctime(BKE_scene_frame_get(scene)),
95     scene_cow(NULL),
96     is_active(false)
97 {
98         BLI_spin_init(&lock);
99         id_hash = BLI_ghash_ptr_new("Depsgraph id hash");
100         entry_tags = BLI_gset_ptr_new("Depsgraph entry_tags");
101         debug_flags = G.debug;
102         memset(id_type_updated, 0, sizeof(id_type_updated));
103         memset(physics_relations, 0, sizeof(physics_relations));
104 }
105
106 Depsgraph::~Depsgraph()
107 {
108         clear_id_nodes();
109         BLI_ghash_free(id_hash, NULL, NULL);
110         BLI_gset_free(entry_tags, NULL);
111         if (time_source != NULL) {
112                 OBJECT_GUARDED_DELETE(time_source, TimeSourceDepsNode);
113         }
114         BLI_spin_end(&lock);
115 }
116
117 /* Query Conditions from RNA ----------------------- */
118
119 static bool pointer_to_component_node_criteria(
120         const PointerRNA *ptr,
121         const PropertyRNA *prop,
122         ID **id,
123         eDepsNode_Type *type,
124         const char **subdata,
125         eDepsOperation_Code *operation_code,
126         const char **operation_name,
127         int *operation_name_tag)
128 {
129         if (ptr->type == NULL) {
130                 return false;
131         }
132         /* Set default values for returns. */
133         *id = (ID *)ptr->id.data;
134         *subdata = "";
135         *operation_code = DEG_OPCODE_OPERATION;
136         *operation_name = "";
137         *operation_name_tag = -1;
138         /* Handling of commonly known scenarios. */
139         if (ptr->type == &RNA_PoseBone) {
140                 bPoseChannel *pchan = (bPoseChannel *)ptr->data;
141                 if (prop != NULL && RNA_property_is_idprop(prop)) {
142                         *type = DEG_NODE_TYPE_PARAMETERS;
143                         *operation_code = DEG_OPCODE_ID_PROPERTY;
144                         *operation_name = RNA_property_identifier((PropertyRNA *)prop);
145                         *operation_name_tag = -1;
146                 }
147                 else {
148                         /* Bone - generally, we just want the bone component. */
149                         *type = DEG_NODE_TYPE_BONE;
150                         *subdata = pchan->name;
151                 }
152                 return true;
153         }
154         else if (ptr->type == &RNA_Bone) {
155                 Bone *bone = (Bone *)ptr->data;
156                 /* armature-level bone, but it ends up going to bone component anyway */
157                 // NOTE: the ID in thise case will end up being bArmature.
158                 *type = DEG_NODE_TYPE_BONE;
159                 *subdata = bone->name;
160                 return true;
161         }
162         else if (RNA_struct_is_a(ptr->type, &RNA_Constraint)) {
163                 Object *object = (Object *)ptr->id.data;
164                 bConstraint *con = (bConstraint *)ptr->data;
165                 /* Check whether is object or bone constraint. */
166                 /* NOTE: Currently none of the area can address transform of an object
167                  * at a given constraint, but for rigging one might use constraint
168                  * influence to be used to drive some corrective shape keys or so.
169                  */
170                 if (BLI_findindex(&object->constraints, con) != -1) {
171                         *type = DEG_NODE_TYPE_TRANSFORM;
172                         *operation_code = DEG_OPCODE_TRANSFORM_LOCAL;
173                         return true;
174                 }
175                 else if (object->pose != NULL) {
176                         LISTBASE_FOREACH(bPoseChannel *, pchan, &object->pose->chanbase) {
177                                 if (BLI_findindex(&pchan->constraints, con) != -1) {
178                                         *type = DEG_NODE_TYPE_BONE;
179                                         *operation_code = DEG_OPCODE_BONE_LOCAL;
180                                         *subdata = pchan->name;
181                                         return true;
182                                 }
183                         }
184                 }
185         }
186         else if (RNA_struct_is_a(ptr->type, &RNA_Modifier)) {
187                 *type = DEG_NODE_TYPE_GEOMETRY;
188                 return true;
189         }
190         else if (ptr->type == &RNA_Object) {
191                 /* Transforms props? */
192                 if (prop != NULL) {
193                         const char *prop_identifier = RNA_property_identifier((PropertyRNA *)prop);
194                         /* TODO(sergey): How to optimize this? */
195                         if (strstr(prop_identifier, "location") ||
196                             strstr(prop_identifier, "rotation") ||
197                             strstr(prop_identifier, "scale") ||
198                             strstr(prop_identifier, "matrix_"))
199                         {
200                                 *type = DEG_NODE_TYPE_TRANSFORM;
201                                 return true;
202                         }
203                         else if (strstr(prop_identifier, "data")) {
204                                 /* We access object.data, most likely a geometry.
205                                  * Might be a bone tho..
206                                  */
207                                 *type = DEG_NODE_TYPE_GEOMETRY;
208                                 return true;
209                         }
210                 }
211         }
212         else if (ptr->type == &RNA_ShapeKey) {
213                 *id = (ID *)ptr->id.data;
214                 *type = DEG_NODE_TYPE_GEOMETRY;
215                 return true;
216         }
217         else if (ptr->type == &RNA_Key) {
218                 *id = (ID *)ptr->id.data;
219                 *type = DEG_NODE_TYPE_GEOMETRY;
220                 return true;
221         }
222         else if (RNA_struct_is_a(ptr->type, &RNA_Sequence)) {
223                 Sequence *seq = (Sequence *)ptr->data;
224                 /* Sequencer strip */
225                 *type = DEG_NODE_TYPE_SEQUENCER;
226                 *subdata = seq->name; // xxx?
227                 return true;
228         }
229         else if (RNA_struct_is_a(ptr->type, &RNA_NodeSocket)) {
230                 *type = DEG_NODE_TYPE_SHADING;
231                 return true;
232         }
233         else if (ptr->type == &RNA_Curve) {
234                 *id = (ID *)ptr->id.data;
235                 *type = DEG_NODE_TYPE_GEOMETRY;
236                 return true;
237         }
238         if (prop != NULL) {
239                 /* All unknown data effectively falls under "parameter evaluation". */
240                 if (RNA_property_is_idprop(prop)) {
241                         *type = DEG_NODE_TYPE_PARAMETERS;
242                         *operation_code = DEG_OPCODE_ID_PROPERTY;
243                         *operation_name = RNA_property_identifier((PropertyRNA *)prop);
244                         *operation_name_tag = -1;
245                 }
246                 else {
247                         *type = DEG_NODE_TYPE_PARAMETERS;
248                         *operation_code = DEG_OPCODE_PARAMETERS_EVAL;
249                         *operation_name = "";
250                         *operation_name_tag = -1;
251                 }
252                 return true;
253         }
254         return false;
255 }
256
257 /* Convenience wrapper to find node given just pointer + property. */
258 DepsNode *Depsgraph::find_node_from_pointer(const PointerRNA *ptr,
259                                             const PropertyRNA *prop) const
260 {
261         ID *id;
262         eDepsNode_Type node_type;
263         const char *component_name, *operation_name;
264         eDepsOperation_Code operation_code;
265         int operation_name_tag;
266
267         if (pointer_to_component_node_criteria(
268                          ptr, prop,
269                          &id, &node_type, &component_name,
270                          &operation_code, &operation_name, &operation_name_tag))
271         {
272                 IDDepsNode *id_node = find_id_node(id);
273                 if (id_node == NULL) {
274                         return NULL;
275                 }
276                 ComponentDepsNode *comp_node =
277                         id_node->find_component(node_type, component_name);
278                 if (comp_node == NULL) {
279                         return NULL;
280                 }
281                 if (operation_code == DEG_OPCODE_OPERATION) {
282                         return comp_node;
283                 }
284                 return comp_node->find_operation(operation_code,
285                                                  operation_name,
286                                                  operation_name_tag);
287         }
288         return NULL;
289 }
290
291 /* Node Management ---------------------------- */
292
293 TimeSourceDepsNode *Depsgraph::add_time_source()
294 {
295         if (time_source == NULL) {
296                 DepsNodeFactory *factory = deg_type_get_factory(DEG_NODE_TYPE_TIMESOURCE);
297                 time_source = (TimeSourceDepsNode *)factory->create_node(NULL, "", "Time Source");
298         }
299         return time_source;
300 }
301
302 TimeSourceDepsNode *Depsgraph::find_time_source() const
303 {
304         return time_source;
305 }
306
307 IDDepsNode *Depsgraph::find_id_node(const ID *id) const
308 {
309         return reinterpret_cast<IDDepsNode *>(BLI_ghash_lookup(id_hash, id));
310 }
311
312 IDDepsNode *Depsgraph::add_id_node(ID *id, ID *id_cow_hint)
313 {
314         BLI_assert((id->tag & LIB_TAG_COPIED_ON_WRITE) == 0);
315         IDDepsNode *id_node = find_id_node(id);
316         if (!id_node) {
317                 DepsNodeFactory *factory = deg_type_get_factory(DEG_NODE_TYPE_ID_REF);
318                 id_node = (IDDepsNode *)factory->create_node(id, "", id->name);
319                 id_node->init_copy_on_write(id_cow_hint);
320                 /* Register node in ID hash.
321                  *
322                  * NOTE: We address ID nodes by the original ID pointer they are
323                  * referencing to.
324                  */
325                 BLI_ghash_insert(id_hash, id, id_node);
326                 id_nodes.push_back(id_node);
327         }
328         return id_node;
329 }
330
331 void Depsgraph::clear_id_nodes_conditional(const std::function <bool (ID_Type id_type)>& filter)
332 {
333         foreach (IDDepsNode *id_node, id_nodes) {
334                 if (id_node->id_cow == NULL) {
335                         /* This means builder "stole" ownership of the copy-on-written
336                          * datablock for her own dirty needs.
337                          */
338                         continue;
339                 }
340                 if (!deg_copy_on_write_is_expanded(id_node->id_cow)) {
341                         continue;
342                 }
343                 const ID_Type id_type = GS(id_node->id_cow->name);
344                 if (filter(id_type)) {
345                         id_node->destroy();
346                 }
347         }
348 }
349
350 void Depsgraph::clear_id_nodes()
351 {
352         /* Free memory used by ID nodes. */
353
354         /* Stupid workaround to ensure we free IDs in a proper order. */
355         clear_id_nodes_conditional([](ID_Type id_type) { return id_type == ID_SCE; });
356         clear_id_nodes_conditional([](ID_Type id_type) { return id_type != ID_PA; });
357
358         foreach (IDDepsNode *id_node, id_nodes) {
359                 OBJECT_GUARDED_DELETE(id_node, IDDepsNode);
360         }
361         /* Clear containers. */
362         BLI_ghash_clear(id_hash, NULL, NULL);
363         id_nodes.clear();
364         /* Clear physics relation caches. */
365         deg_clear_physics_relations(this);
366 }
367
368 /* Add new relationship between two nodes. */
369 DepsRelation *Depsgraph::add_new_relation(OperationDepsNode *from,
370                                           OperationDepsNode *to,
371                                           const char *description,
372                                           bool check_unique)
373 {
374         DepsRelation *rel = NULL;
375         if (check_unique) {
376                 rel = check_nodes_connected(from, to, description);
377         }
378         if (rel != NULL) {
379                 return rel;
380         }
381         /* Create new relation, and add it to the graph. */
382         rel = OBJECT_GUARDED_NEW(DepsRelation, from, to, description);
383         /* TODO(sergey): Find a better place for this. */
384 #ifdef WITH_OPENSUBDIV
385         ComponentDepsNode *comp_node = from->owner;
386         if (comp_node->type == DEG_NODE_TYPE_GEOMETRY) {
387                 IDDepsNode *id_to = to->owner->owner;
388                 IDDepsNode *id_from = from->owner->owner;
389                 if (id_to != id_from && (id_to->id_orig->recalc & ID_RECALC_ALL)) {
390                         if ((id_from->eval_flags & DAG_EVAL_NEED_CPU) == 0) {
391                                 id_from->tag_update(this);
392                                 id_from->eval_flags |= DAG_EVAL_NEED_CPU;
393                         }
394                 }
395         }
396 #endif
397         return rel;
398 }
399
400 /* Add new relation between two nodes */
401 DepsRelation *Depsgraph::add_new_relation(DepsNode *from, DepsNode *to,
402                                           const char *description,
403                                           bool check_unique)
404 {
405         DepsRelation *rel = NULL;
406         if (check_unique) {
407                 rel = check_nodes_connected(from, to, description);
408         }
409         if (rel != NULL) {
410                 return rel;
411         }
412         /* Create new relation, and add it to the graph. */
413         rel = OBJECT_GUARDED_NEW(DepsRelation, from, to, description);
414         return rel;
415 }
416
417 DepsRelation *Depsgraph::check_nodes_connected(const DepsNode *from,
418                                                const DepsNode *to,
419                                                const char *description)
420 {
421         foreach (DepsRelation *rel, from->outlinks) {
422                 BLI_assert(rel->from == from);
423                 if (rel->to != to) {
424                         continue;
425                 }
426                 if (description != NULL && !STREQ(rel->name, description)) {
427                         continue;
428                 }
429                 return rel;
430         }
431         return NULL;
432 }
433
434 /* ************************ */
435 /* Relationships Management */
436
437 DepsRelation::DepsRelation(DepsNode *from,
438                            DepsNode *to,
439                            const char *description)
440   : from(from),
441     to(to),
442     name(description),
443     flag(0)
444 {
445         /* Hook it up to the nodes which use it.
446          *
447          * NOTE: We register relation in the nodes which this link connects to here
448          * in constructor but we don't unregister it in the destructor.
449          *
450          * Reasoning:
451          *
452          * - Destructor is currently used on global graph destruction, so there's no
453          *   real need in avoiding dangling pointers, all the memory is to be freed
454          *   anyway.
455          *
456          * - Unregistering relation is not a cheap operation, so better to have it
457          *   as an explicit call if we need this.
458          */
459         from->outlinks.push_back(this);
460         to->inlinks.push_back(this);
461 }
462
463 DepsRelation::~DepsRelation()
464 {
465         /* Sanity check. */
466         BLI_assert(from != NULL && to != NULL);
467 }
468
469 void DepsRelation::unlink()
470 {
471         /* Sanity check. */
472         BLI_assert(from != NULL && to != NULL);
473         remove_from_vector(&from->outlinks, this);
474         remove_from_vector(&to->inlinks, this);
475 }
476
477 /* Low level tagging -------------------------------------- */
478
479 /* Tag a specific node as needing updates. */
480 void Depsgraph::add_entry_tag(OperationDepsNode *node)
481 {
482         /* Sanity check. */
483         if (node == NULL) {
484                 return;
485         }
486         /* Add to graph-level set of directly modified nodes to start searching from.
487          * NOTE: this is necessary since we have several thousand nodes to play with...
488          */
489         BLI_gset_insert(entry_tags, node);
490 }
491
492 void Depsgraph::clear_all_nodes()
493 {
494         clear_id_nodes();
495         if (time_source != NULL) {
496                 OBJECT_GUARDED_DELETE(time_source, TimeSourceDepsNode);
497                 time_source = NULL;
498         }
499 }
500
501 ID *Depsgraph::get_cow_id(const ID *id_orig) const
502 {
503         IDDepsNode *id_node = find_id_node(id_orig);
504         if (id_node == NULL) {
505                 /* This function is used from places where we expect ID to be either
506                  * already a copy-on-write version or have a corresponding copy-on-write
507                  * version.
508                  *
509                  * We try to enforce that in debug builds, for for release we play a bit
510                  * safer game here.
511                  */
512                 if ((id_orig->tag & LIB_TAG_COPIED_ON_WRITE) == 0) {
513                         /* TODO(sergey): This is nice sanity check to have, but it fails
514                          * in following situations:
515                          *
516                          * - Material has link to texture, which is not needed by new
517                          *   shading system and hence can be ignored at construction.
518                          * - Object or mesh has material at a slot which is not used (for
519                          *   example, object has material slot by materials are set to
520                          *   object data).
521                          */
522                         // BLI_assert(!"Request for non-existing copy-on-write ID");
523                 }
524                 return (ID *)id_orig;
525         }
526         return id_node->id_cow;
527 }
528
529 void deg_editors_id_update(const DEGEditorUpdateContext *update_ctx, ID *id)
530 {
531         if (deg_editor_update_id_cb != NULL) {
532                 deg_editor_update_id_cb(update_ctx, id);
533         }
534 }
535
536 void deg_editors_scene_update(const DEGEditorUpdateContext *update_ctx,
537                               bool updated)
538 {
539         if (deg_editor_update_scene_cb != NULL) {
540                 deg_editor_update_scene_cb(update_ctx, updated);
541         }
542 }
543
544 bool deg_terminal_do_color(void)
545 {
546         return (G.debug & G_DEBUG_DEPSGRAPH_PRETTY) != 0;
547 }
548
549 string deg_color_for_pointer(const void *pointer)
550 {
551         if (!deg_terminal_do_color()) {
552                 return "";
553         }
554         int r, g, b;
555         BLI_hash_pointer_to_color(pointer, &r, &g, &b);
556         char buffer[64];
557         BLI_snprintf(buffer, sizeof(buffer), TRUECOLOR_ANSI_COLOR_FORMAT, r, g, b);
558         return string(buffer);
559 }
560
561 string deg_color_end(void)
562 {
563         if (!deg_terminal_do_color()) {
564                 return "";
565         }
566         return string(TRUECOLOR_ANSI_COLOR_FINISH);
567 }
568
569 }  // namespace DEG
570
571 /* **************** */
572 /* Public Graph API */
573
574 /* Initialize a new Depsgraph */
575 Depsgraph *DEG_graph_new(Scene *scene,
576                          ViewLayer *view_layer,
577                          eEvaluationMode mode)
578 {
579         DEG::Depsgraph *deg_depsgraph = OBJECT_GUARDED_NEW(DEG::Depsgraph,
580                                                            scene,
581                                                            view_layer,
582                                                            mode);
583         return reinterpret_cast<Depsgraph *>(deg_depsgraph);
584 }
585
586 /* Free graph's contents and graph itself */
587 void DEG_graph_free(Depsgraph *graph)
588 {
589         using DEG::Depsgraph;
590         DEG::Depsgraph *deg_depsgraph = reinterpret_cast<DEG::Depsgraph *>(graph);
591         OBJECT_GUARDED_DELETE(deg_depsgraph, Depsgraph);
592 }
593
594 /* Set callbacks which are being called when depsgraph changes. */
595 void DEG_editors_set_update_cb(DEG_EditorUpdateIDCb id_func,
596                                DEG_EditorUpdateSceneCb scene_func)
597 {
598         DEG::deg_editor_update_id_cb = id_func;
599         DEG::deg_editor_update_scene_cb = scene_func;
600 }
601
602 bool DEG_is_active(const struct Depsgraph *depsgraph)
603 {
604         if (depsgraph == NULL) {
605                 /* Happens for such cases as work object in what_does_obaction(),
606                  * and sine render pipeline parts. Shouldn't really be accepting
607                  * NULL depsgraph, but is quite hard to get proper one in those
608                  * cases.
609                  */
610                 return false;
611         }
612         const DEG::Depsgraph *deg_graph =
613                 reinterpret_cast<const DEG::Depsgraph *>(depsgraph);
614         return deg_graph->is_active;
615 }
616
617 void DEG_make_active(struct Depsgraph *depsgraph)
618 {
619         DEG::Depsgraph *deg_graph = reinterpret_cast<DEG::Depsgraph *>(depsgraph);
620         deg_graph->is_active = true;
621         /* TODO(sergey): Copy data from evaluated state to original. */
622 }
623
624 void DEG_make_inactive(struct Depsgraph *depsgraph)
625 {
626         DEG::Depsgraph *deg_graph = reinterpret_cast<DEG::Depsgraph *>(depsgraph);
627         deg_graph->is_active = false;
628 }
629
630 /* Evaluation and debug */
631
632 static DEG::string depsgraph_name_for_logging(struct Depsgraph *depsgraph)
633 {
634         const char *name = DEG_debug_name_get(depsgraph);
635         if (name[0] == '\0') {
636                 return "";
637         }
638         return "[" + DEG::string(name) + "]: ";
639 }
640
641 void DEG_debug_print_begin(struct Depsgraph *depsgraph)
642 {
643         fprintf(stdout, "%s",
644                 depsgraph_name_for_logging(depsgraph).c_str());
645 }
646
647 void DEG_debug_print_eval(struct Depsgraph *depsgraph,
648                           const char *function_name,
649                           const char *object_name,
650                           const void *object_address)
651 {
652         if ((DEG_debug_flags_get(depsgraph) & G_DEBUG_DEPSGRAPH_EVAL) == 0) {
653                 return;
654         }
655         fprintf(stdout,
656                 "%s%s on %s %s(%p)%s\n",
657                 depsgraph_name_for_logging(depsgraph).c_str(),
658                 function_name,
659                 object_name,
660                 DEG::deg_color_for_pointer(object_address).c_str(),
661                 object_address,
662                 DEG::deg_color_end().c_str());
663         fflush(stdout);
664 }
665
666 void DEG_debug_print_eval_subdata(struct Depsgraph *depsgraph,
667                                   const char *function_name,
668                                   const char *object_name,
669                                   const void *object_address,
670                                   const char *subdata_comment,
671                                   const char *subdata_name,
672                                   const void *subdata_address)
673 {
674         if ((DEG_debug_flags_get(depsgraph) & G_DEBUG_DEPSGRAPH_EVAL) == 0) {
675                 return;
676         }
677         fprintf(stdout,
678                 "%s%s on %s %s(%p)%s %s %s %s(%p)%s\n",
679                 depsgraph_name_for_logging(depsgraph).c_str(),
680                 function_name,
681                 object_name,
682                 DEG::deg_color_for_pointer(object_address).c_str(),
683                 object_address,
684                 DEG::deg_color_end().c_str(),
685                 subdata_comment,
686                 subdata_name,
687                 DEG::deg_color_for_pointer(subdata_address).c_str(),
688                 subdata_address,
689                 DEG::deg_color_end().c_str());
690         fflush(stdout);
691 }
692
693 void DEG_debug_print_eval_subdata_index(struct Depsgraph *depsgraph,
694                                         const char *function_name,
695                                         const char *object_name,
696                                         const void *object_address,
697                                         const char *subdata_comment,
698                                         const char *subdata_name,
699                                         const void *subdata_address,
700                                         const int subdata_index)
701 {
702         if ((DEG_debug_flags_get(depsgraph) & G_DEBUG_DEPSGRAPH_EVAL) == 0) {
703                 return;
704         }
705         fprintf(stdout,
706                 "%s%s on %s %s(%p)%s %s %s[%d] %s(%p)%s\n",
707                 depsgraph_name_for_logging(depsgraph).c_str(),
708                 function_name,
709                 object_name,
710                 DEG::deg_color_for_pointer(object_address).c_str(),
711                 object_address,
712                 DEG::deg_color_end().c_str(),
713                 subdata_comment,
714                 subdata_name,
715                 subdata_index,
716                 DEG::deg_color_for_pointer(subdata_address).c_str(),
717                 subdata_address,
718                 DEG::deg_color_end().c_str());
719         fflush(stdout);
720 }
721
722 void DEG_debug_print_eval_parent_typed(struct Depsgraph *depsgraph,
723                                        const char *function_name,
724                                        const char *object_name,
725                                        const void *object_address,
726                                        const char *parent_comment,
727                                        const char *parent_name,
728                                        const void *parent_address)
729 {
730         if ((DEG_debug_flags_get(depsgraph) & G_DEBUG_DEPSGRAPH_EVAL) == 0) {
731                 return;
732         }
733         fprintf(stdout,
734                 "%s%s on %s %s(%p) [%s] %s %s %s(%p)%s\n",
735                 depsgraph_name_for_logging(depsgraph).c_str(),
736                 function_name,
737                 object_name,
738                 DEG::deg_color_for_pointer(object_address).c_str(),
739                 object_address,
740                 DEG::deg_color_end().c_str(),
741                 parent_comment,
742                 parent_name,
743                 DEG::deg_color_for_pointer(parent_address).c_str(),
744                 parent_address,
745                 DEG::deg_color_end().c_str());
746         fflush(stdout);
747 }
748
749 void DEG_debug_print_eval_time(struct Depsgraph *depsgraph,
750                                const char *function_name,
751                                const char *object_name,
752                                const void *object_address,
753                                float time)
754 {
755         if ((DEG_debug_flags_get(depsgraph) & G_DEBUG_DEPSGRAPH_EVAL) == 0) {
756                 return;
757         }
758         fprintf(stdout,
759                 "%s%s on %s %s(%p)%s at time %f\n",
760                 depsgraph_name_for_logging(depsgraph).c_str(),
761                 function_name,
762                 object_name,
763                 DEG::deg_color_for_pointer(object_address).c_str(),
764                 object_address,
765                 DEG::deg_color_end().c_str(),
766                 time);
767         fflush(stdout);
768 }