20b029371f1a7fdaa8c31813fecb86bc4fd2fa1c
[blender.git] / source / blender / blenkernel / intern / depsgraph.c
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) 2004 Blender Foundation.
19  * All rights reserved.
20  *
21  * Contributor(s): none yet.
22  *
23  * ***** END GPL LICENSE BLOCK *****
24  */
25
26 /** \file blender/blenkernel/intern/depsgraph.c
27  *  \ingroup bke
28  */
29
30  
31 #include <stdio.h>
32 #include <string.h>
33 #include <math.h>
34
35 #include "MEM_guardedalloc.h"
36
37 #ifdef WIN32
38 #  include "BLI_winstuff.h"
39 #endif
40
41 #include "BLI_utildefines.h"
42 #include "BLI_listbase.h"
43 #include "BLI_ghash.h"
44
45 #include "DNA_anim_types.h"
46 #include "DNA_camera_types.h"
47 #include "DNA_group_types.h"
48 #include "DNA_lattice_types.h"
49 #include "DNA_key_types.h"
50 #include "DNA_material_types.h"
51 #include "DNA_mesh_types.h"
52 #include "DNA_node_types.h"
53 #include "DNA_scene_types.h"
54 #include "DNA_screen_types.h"
55 #include "DNA_windowmanager_types.h"
56 #include "DNA_movieclip_types.h"
57 #include "DNA_mask_types.h"
58
59 #include "BKE_animsys.h"
60 #include "BKE_action.h"
61 #include "BKE_effect.h"
62 #include "BKE_fcurve.h"
63 #include "BKE_global.h"
64 #include "BKE_group.h"
65 #include "BKE_key.h"
66 #include "BKE_library.h"
67 #include "BKE_main.h"
68 #include "BKE_node.h"
69 #include "BKE_material.h"
70 #include "BKE_mball.h"
71 #include "BKE_modifier.h"
72 #include "BKE_object.h"
73 #include "BKE_particle.h"
74 #include "BKE_pointcache.h"
75 #include "BKE_scene.h"
76 #include "BKE_screen.h"
77 #include "BKE_tracking.h"
78
79 #include "depsgraph_private.h"
80  
81 /* Queue and stack operations for dag traversal 
82  *
83  * the queue store a list of freenodes to avoid successive alloc/dealloc
84  */
85
86 DagNodeQueue *queue_create(int slots)
87 {
88         DagNodeQueue *queue;
89         DagNodeQueueElem *elem;
90         int i;
91         
92         queue = MEM_mallocN(sizeof(DagNodeQueue), "DAG queue");
93         queue->freenodes = MEM_mallocN(sizeof(DagNodeQueue), "DAG queue");
94         queue->count = 0;
95         queue->maxlevel = 0;
96         queue->first = queue->last = NULL;
97         elem = MEM_mallocN(sizeof(DagNodeQueueElem), "DAG queue elem3");
98         elem->node = NULL;
99         elem->next = NULL;
100         queue->freenodes->first = queue->freenodes->last = elem;
101         
102         for (i = 1; i < slots; i++) {
103                 elem = MEM_mallocN(sizeof(DagNodeQueueElem), "DAG queue elem4");
104                 elem->node = NULL;
105                 elem->next = NULL;
106                 queue->freenodes->last->next = elem;
107                 queue->freenodes->last = elem;
108         }
109         queue->freenodes->count = slots;
110         return queue;
111 }
112
113 void queue_raz(DagNodeQueue *queue)
114 {
115         DagNodeQueueElem *elem;
116         
117         elem = queue->first;
118         if (queue->freenodes->last)
119                 queue->freenodes->last->next = elem;
120         else
121                 queue->freenodes->first = queue->freenodes->last = elem;
122         
123         elem->node = NULL;
124         queue->freenodes->count++;
125         while (elem->next) {
126                 elem = elem->next;
127                 elem->node = NULL;
128                 queue->freenodes->count++;
129         }
130         queue->freenodes->last = elem;
131         queue->count = 0;
132 }
133
134 void queue_delete(DagNodeQueue *queue)
135 {
136         DagNodeQueueElem *elem;
137         DagNodeQueueElem *temp;
138         
139         elem = queue->first;
140         while (elem) {
141                 temp = elem;
142                 elem = elem->next;
143                 MEM_freeN(temp);
144         }
145         
146         elem = queue->freenodes->first;
147         while (elem) {
148                 temp = elem;
149                 elem = elem->next;
150                 MEM_freeN(temp);
151         }
152         
153         MEM_freeN(queue->freenodes);                    
154         MEM_freeN(queue);                       
155 }
156
157 /* insert in queue, remove in front */
158 void push_queue(DagNodeQueue *queue, DagNode *node)
159 {
160         DagNodeQueueElem *elem;
161         int i;
162
163         if (node == NULL) {
164                 fprintf(stderr, "pushing null node\n");
165                 return;
166         }
167         /*fprintf(stderr, "BFS push : %s %d\n", ((ID *) node->ob)->name, queue->count);*/
168
169         elem = queue->freenodes->first;
170         if (elem != NULL) {
171                 queue->freenodes->first = elem->next;
172                 if (queue->freenodes->last == elem) {
173                         queue->freenodes->last = NULL;
174                         queue->freenodes->first = NULL;
175                 }
176                 queue->freenodes->count--;
177         }
178         else { /* alllocating more */
179                 elem = MEM_mallocN(sizeof(DagNodeQueueElem), "DAG queue elem1");
180                 elem->node = NULL;
181                 elem->next = NULL;
182                 queue->freenodes->first = queue->freenodes->last = elem;
183
184                 for (i = 1; i < DAGQUEUEALLOC; i++) {
185                         elem = MEM_mallocN(sizeof(DagNodeQueueElem), "DAG queue elem2");
186                         elem->node = NULL;
187                         elem->next = NULL;
188                         queue->freenodes->last->next = elem;
189                         queue->freenodes->last = elem;
190                 }
191                 queue->freenodes->count = DAGQUEUEALLOC;
192                         
193                 elem = queue->freenodes->first; 
194                 queue->freenodes->first = elem->next;   
195         }
196         elem->next = NULL;
197         elem->node = node;
198         if (queue->last != NULL)
199                 queue->last->next = elem;
200         queue->last = elem;
201         if (queue->first == NULL) {
202                 queue->first = elem;
203         }
204         queue->count++;
205 }
206
207
208 /* insert in front, remove in front */
209 void push_stack(DagNodeQueue *queue, DagNode *node)
210 {
211         DagNodeQueueElem *elem;
212         int i;
213
214         elem = queue->freenodes->first; 
215         if (elem != NULL) {
216                 queue->freenodes->first = elem->next;
217                 if (queue->freenodes->last == elem) {
218                         queue->freenodes->last = NULL;
219                         queue->freenodes->first = NULL;
220                 }
221                 queue->freenodes->count--;
222         }
223         else { /* alllocating more */
224                 elem = MEM_mallocN(sizeof(DagNodeQueueElem), "DAG queue elem1");
225                 elem->node = NULL;
226                 elem->next = NULL;
227                 queue->freenodes->first = queue->freenodes->last = elem;
228
229                 for (i = 1; i < DAGQUEUEALLOC; i++) {
230                         elem = MEM_mallocN(sizeof(DagNodeQueueElem), "DAG queue elem2");
231                         elem->node = NULL;
232                         elem->next = NULL;
233                         queue->freenodes->last->next = elem;
234                         queue->freenodes->last = elem;
235                 }
236                 queue->freenodes->count = DAGQUEUEALLOC;
237                         
238                 elem = queue->freenodes->first; 
239                 queue->freenodes->first = elem->next;   
240         }
241         elem->next = queue->first;
242         elem->node = node;
243         queue->first = elem;
244         if (queue->last == NULL)
245                 queue->last = elem;
246         queue->count++;
247 }
248
249
250 DagNode *pop_queue(DagNodeQueue *queue)
251 {
252         DagNodeQueueElem *elem;
253         DagNode *node;
254
255         elem = queue->first;
256         if (elem) {
257                 queue->first = elem->next;
258                 if (queue->last == elem) {
259                         queue->last = NULL;
260                         queue->first = NULL;
261                 }
262                 queue->count--;
263                 if (queue->freenodes->last)
264                         queue->freenodes->last->next = elem;
265                 queue->freenodes->last = elem;
266                 if (queue->freenodes->first == NULL)
267                         queue->freenodes->first = elem;
268                 node = elem->node;
269                 elem->node = NULL;
270                 elem->next = NULL;
271                 queue->freenodes->count++;
272                 return node;
273         }
274         else {
275                 fprintf(stderr, "return null\n");
276                 return NULL;
277         }
278 }
279
280 void    *pop_ob_queue(struct DagNodeQueue *queue)
281 {
282         return(pop_queue(queue)->ob);
283 }
284
285 DagNode *get_top_node_queue(DagNodeQueue *queue)
286 {
287         return queue->first->node;
288 }
289
290 int     queue_count(struct DagNodeQueue *queue)
291 {
292         return queue->count;
293 }
294
295
296 DagForest *dag_init(void)
297 {
298         DagForest *forest;
299         /* use callocN to init all zero */
300         forest = MEM_callocN(sizeof(DagForest), "DAG root");
301         return forest;
302 }
303
304 /* isdata = object data... */
305 // XXX this needs to be extended to be more flexible (so that not only objects are evaluated via depsgraph)...
306 static void dag_add_driver_relation(AnimData *adt, DagForest *dag, DagNode *node, int isdata)
307 {
308         FCurve *fcu;
309         DagNode *node1;
310         
311         for (fcu = adt->drivers.first; fcu; fcu = fcu->next) {
312                 ChannelDriver *driver = fcu->driver;
313                 DriverVar *dvar;
314                 int isdata_fcu = (isdata) || (fcu->rna_path && strstr(fcu->rna_path, "modifiers["));
315                 
316                 /* loop over variables to get the target relationships */
317                 for (dvar = driver->variables.first; dvar; dvar = dvar->next) {
318                         /* only used targets */
319                         DRIVER_TARGETS_USED_LOOPER(dvar) 
320                         {
321                                 if (dtar->id) {
322                                         /* FIXME: other data types need to be added here so that they can work! */
323                                         if (GS(dtar->id->name) == ID_OB) {
324                                                 Object *ob = (Object *)dtar->id;
325                                                 
326                                                 /* normal channel-drives-channel */
327                                                 node1 = dag_get_node(dag, dtar->id);
328                                                 
329                                                 /* check if bone... */
330                                                 if ((ob->type == OB_ARMATURE) &&
331                                                     ( ((dtar->rna_path) && strstr(dtar->rna_path, "pose.bones[")) ||
332                                                       ((dtar->flag & DTAR_FLAG_STRUCT_REF) && (dtar->pchan_name[0])) ))
333                                                 {
334                                                         dag_add_relation(dag, node1, node, isdata_fcu ? DAG_RL_DATA_DATA : DAG_RL_DATA_OB, "Driver");
335                                                 }
336                                                 /* check if ob data */
337                                                 else if (dtar->rna_path && strstr(dtar->rna_path, "data."))
338                                                         dag_add_relation(dag, node1, node, isdata_fcu ? DAG_RL_DATA_DATA : DAG_RL_DATA_OB, "Driver");
339                                                 /* normal */
340                                                 else
341                                                         dag_add_relation(dag, node1, node, isdata_fcu ? DAG_RL_OB_DATA : DAG_RL_OB_OB, "Driver");
342                                         }
343                                 }
344                         }
345                         DRIVER_TARGETS_LOOPER_END
346                 }
347         }
348 }
349
350 /* XXX: forward def for material driver handling... */
351 static void dag_add_material_driver_relations(DagForest *dag, DagNode *node, Material *ma);
352
353 /* recursive handling for material nodetree drivers */
354 static void dag_add_material_nodetree_driver_relations(DagForest *dag, DagNode *node, bNodeTree *ntree)
355 {
356         bNode *n;
357
358         /* nodetree itself */
359         if (ntree->adt) {
360                 dag_add_driver_relation(ntree->adt, dag, node, 1);
361         }
362         
363         /* nodetree's nodes... */
364         for (n = ntree->nodes.first; n; n = n->next) {
365                 if (n->id) {
366                         if (GS(n->id->name) == ID_MA) {
367                                 dag_add_material_driver_relations(dag, node, (Material *)n->id);
368                         }
369                         else if (n->type == NODE_GROUP) {
370                                 dag_add_material_nodetree_driver_relations(dag, node, (bNodeTree *)n->id);
371                         }
372                 }
373         }
374 }
375
376 /* recursive handling for material drivers */
377 static void dag_add_material_driver_relations(DagForest *dag, DagNode *node, Material *ma)
378 {
379         /* Prevent infinite recursion by checking (and tagging the material) as having been visited 
380          * already (see build_dag()). This assumes ma->id.flag & LIB_DOIT isn't set by anything else
381          * in the meantime... [#32017]
382          */
383         if (ma->id.flag & LIB_DOIT)
384                 return;
385         else
386                 ma->id.flag |= LIB_DOIT;
387         
388         /* material itself */
389         if (ma->adt) {
390                 dag_add_driver_relation(ma->adt, dag, node, 1);
391         }
392
393         /* textures */
394         // TODO...
395         //dag_add_texture_driver_relations(DagForest *dag, DagNode *node, ID *id);
396
397         /* material's nodetree */
398         if (ma->nodetree) {
399                 dag_add_material_nodetree_driver_relations(dag, node, ma->nodetree);
400         }
401 }
402
403 static void dag_add_collision_field_relation(DagForest *dag, Scene *scene, Object *ob, DagNode *node, int skip_forcefield){
404         Base *base;
405         DagNode *node2;
406
407         /* would be nice to have a list of colliders here
408          * so for now walk all objects in scene check 'same layer rule' */
409         for (base = scene->base.first; base; base = base->next) {
410                 if ((base->lay & ob->lay) && base->object->pd) {
411                         Object *ob1 = base->object;
412                         if ((ob1->pd->deflect || ob1->pd->forcefield) && (ob1 != ob)) {
413                                 if (skip_forcefield && ob1->pd->forcefield == skip_forcefield)
414                                         continue;
415                                 node2 = dag_get_node(dag, ob1);                                 
416                                 dag_add_relation(dag, node2, node, DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "Field Collision");
417                         }
418                 }
419         }
420 }
421
422 static void build_dag_object(DagForest *dag, DagNode *scenenode, Scene *scene, Object *ob, int mask)
423 {
424         bConstraint *con;
425         DagNode *node;
426         DagNode *node2;
427         DagNode *node3;
428         Key *key;
429         ParticleSystem *psys;
430         int addtoroot = 1;
431         
432         node = dag_get_node(dag, ob);
433         
434         if ((ob->data) && (mask & DAG_RL_DATA)) {
435                 node2 = dag_get_node(dag, ob->data);
436                 dag_add_relation(dag, node, node2, DAG_RL_DATA, "Object-Data Relation");
437                 node2->first_ancestor = ob;
438                 node2->ancestor_count += 1;
439         }
440
441         /* also build a custom data mask for dependencies that need certain layers */
442         node->customdata_mask = 0;
443         
444         if (ob->type == OB_ARMATURE) {
445                 if (ob->pose) {
446                         bPoseChannel *pchan;
447                         
448                         for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
449                                 for (con = pchan->constraints.first; con; con = con->next) {
450                                         bConstraintTypeInfo *cti = constraint_get_typeinfo(con);
451                                         ListBase targets = {NULL, NULL};
452                                         bConstraintTarget *ct;
453                                         
454                                         if (cti && cti->get_constraint_targets) {
455                                                 cti->get_constraint_targets(con, &targets);
456                                                 
457                                                 for (ct = targets.first; ct; ct = ct->next) {
458                                                         if (ct->tar && ct->tar != ob) {
459                                                                 // fprintf(stderr, "armature %s target :%s\n", ob->id.name, target->id.name);
460                                                                 node3 = dag_get_node(dag, ct->tar);
461                                                                 
462                                                                 if (ct->subtarget[0]) {
463                                                                         dag_add_relation(dag, node3, node, DAG_RL_OB_DATA | DAG_RL_DATA_DATA, cti->name);
464                                                                         if (ct->tar->type == OB_MESH)
465                                                                                 node3->customdata_mask |= CD_MASK_MDEFORMVERT;
466                                                                 }
467                                                                 else if (ELEM3(con->type, CONSTRAINT_TYPE_FOLLOWPATH, CONSTRAINT_TYPE_CLAMPTO, CONSTRAINT_TYPE_SPLINEIK))       
468                                                                         dag_add_relation(dag, node3, node, DAG_RL_DATA_DATA | DAG_RL_OB_DATA, cti->name);
469                                                                 else
470                                                                         dag_add_relation(dag, node3, node, DAG_RL_OB_DATA, cti->name);
471                                                         }
472                                                 }
473                                                 
474                                                 if (cti->flush_constraint_targets)
475                                                         cti->flush_constraint_targets(con, &targets, 1);
476                                         }
477                                         
478                                 }
479                         }
480                 }
481         }
482         
483         /* driver dependencies, nla modifiers */
484 #if 0 // XXX old animation system
485         if (ob->nlastrips.first) {
486                 bActionStrip *strip;
487                 bActionChannel *chan;
488                 for (strip = ob->nlastrips.first; strip; strip = strip->next) {
489                         if (strip->modifiers.first) {
490                                 bActionModifier *amod;
491                                 for (amod = strip->modifiers.first; amod; amod = amod->next) {
492                                         if (amod->ob) {
493                                                 node2 = dag_get_node(dag, amod->ob);
494                                                 dag_add_relation(dag, node2, node, DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "NLA Strip Modifier");
495                                         }
496                                 }
497                         }
498                 }
499         }
500 #endif // XXX old animation system
501         if (ob->adt)
502                 dag_add_driver_relation(ob->adt, dag, node, (ob->type == OB_ARMATURE));  // XXX isdata arg here doesn't give an accurate picture of situation
503                 
504         key = BKE_key_from_object(ob);
505         if (key && key->adt)
506                 dag_add_driver_relation(key->adt, dag, node, 1);
507
508         if (ob->modifiers.first) {
509                 ModifierData *md;
510                 
511                 for (md = ob->modifiers.first; md; md = md->next) {
512                         ModifierTypeInfo *mti = modifierType_getInfo(md->type);
513                         
514                         if (mti->updateDepgraph) mti->updateDepgraph(md, dag, scene, ob, node);
515                 }
516         }
517         if (ob->parent) {
518                 node2 = dag_get_node(dag, ob->parent);
519                 
520                 switch (ob->partype) {
521                         case PARSKEL:
522                                 dag_add_relation(dag, node2, node, DAG_RL_DATA_DATA | DAG_RL_OB_OB, "Parent");
523                                 break;
524                         case PARVERT1: case PARVERT3:
525                                 dag_add_relation(dag, node2, node, DAG_RL_DATA_OB | DAG_RL_OB_OB, "Vertex Parent");
526                                 node2->customdata_mask |= CD_MASK_ORIGINDEX;
527                                 break;
528                         case PARBONE:
529                                 dag_add_relation(dag, node2, node, DAG_RL_DATA_OB | DAG_RL_OB_OB, "Bone Parent");
530                                 break;
531                         default:
532                                 if (ob->parent->type == OB_LATTICE)
533                                         dag_add_relation(dag, node2, node, DAG_RL_DATA_DATA | DAG_RL_OB_OB, "Lattice Parent");
534                                 else if (ob->parent->type == OB_CURVE) {
535                                         Curve *cu = ob->parent->data;
536                                         if (cu->flag & CU_PATH) 
537                                                 dag_add_relation(dag, node2, node, DAG_RL_DATA_OB | DAG_RL_OB_OB, "Curve Parent");
538                                         else
539                                                 dag_add_relation(dag, node2, node, DAG_RL_OB_OB, "Curve Parent");
540                                 }
541                                 else
542                                         dag_add_relation(dag, node2, node, DAG_RL_OB_OB, "Parent");
543                 }
544                 /* exception case: parent is duplivert */
545                 if (ob->type == OB_MBALL && (ob->parent->transflag & OB_DUPLIVERTS)) {
546                         dag_add_relation(dag, node2, node, DAG_RL_DATA_DATA | DAG_RL_OB_OB, "Duplivert");
547                 }
548                 
549                 addtoroot = 0;
550         }
551         if (ob->proxy) {
552                 node2 = dag_get_node(dag, ob->proxy);
553                 dag_add_relation(dag, node, node2, DAG_RL_DATA_DATA | DAG_RL_OB_OB, "Proxy");
554                 /* inverted relation, so addtoroot shouldn't be set to zero */
555         }
556         
557         if (ob->transflag & OB_DUPLI) {
558                 if ((ob->transflag & OB_DUPLIGROUP) && ob->dup_group) {
559                         GroupObject *go;
560                         for (go = ob->dup_group->gobject.first; go; go = go->next) {
561                                 if (go->ob) {
562                                         node2 = dag_get_node(dag, go->ob);
563                                         /* node2 changes node1, this keeps animations updated in groups?? not logical? */
564                                         dag_add_relation(dag, node2, node, DAG_RL_OB_OB, "Dupligroup");
565                                 }
566                         }
567                 }
568         }
569
570         /* softbody collision  */
571         if ((ob->type == OB_MESH) || (ob->type == OB_CURVE) || (ob->type == OB_LATTICE)) {
572                 if (ob->particlesystem.first ||
573                     modifiers_isModifierEnabled(ob, eModifierType_Softbody) ||
574                     modifiers_isModifierEnabled(ob, eModifierType_Cloth) ||
575                     modifiers_isModifierEnabled(ob, eModifierType_DynamicPaint))
576                 {
577                         dag_add_collision_field_relation(dag, scene, ob, node, 0);  /* TODO: use effectorweight->group */
578                 }
579                 else if (modifiers_isModifierEnabled(ob, eModifierType_Smoke)) {
580                         dag_add_collision_field_relation(dag, scene, ob, node, PFIELD_SMOKEFLOW);
581                 }
582         }
583         
584         /* object data drivers */
585         if (ob->data) {
586                 AnimData *adt = BKE_animdata_from_id((ID *)ob->data);
587                 if (adt)
588                         dag_add_driver_relation(adt, dag, node, 1);
589         }
590         
591         /* object type/data relationships */
592         switch (ob->type) {
593                 case OB_CAMERA:
594                 {
595                         Camera *cam = (Camera *)ob->data;
596                         
597                         if (cam->dof_ob) {
598                                 node2 = dag_get_node(dag, cam->dof_ob);
599                                 dag_add_relation(dag, node2, node, DAG_RL_OB_OB, "Camera DoF");
600                         }
601                 }
602                 break;
603                 case OB_MBALL: 
604                 {
605                         Object *mom = BKE_mball_basis_find(scene, ob);
606                         
607                         if (mom != ob) {
608                                 node2 = dag_get_node(dag, mom);
609                                 dag_add_relation(dag, node, node2, DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "Metaball");  // mom depends on children!
610                         }
611                 }
612                 break;
613                 case OB_CURVE:
614                 case OB_FONT:
615                 {
616                         Curve *cu = ob->data;
617                         
618                         if (cu->bevobj) {
619                                 node2 = dag_get_node(dag, cu->bevobj);
620                                 dag_add_relation(dag, node2, node, DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "Curve Bevel");
621                         }
622                         if (cu->taperobj) {
623                                 node2 = dag_get_node(dag, cu->taperobj);
624                                 dag_add_relation(dag, node2, node, DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "Curve Taper");
625                         }
626                         if (ob->type == OB_FONT) {
627                                 if (cu->textoncurve) {
628                                         node2 = dag_get_node(dag, cu->textoncurve);
629                                         dag_add_relation(dag, node2, node, DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "Texture On Curve");
630                                 }
631                         }
632                 }
633                 break;
634         }
635         
636         /* material drivers */
637         if (ob->totcol) {
638                 int a;
639                 
640                 for (a = 1; a <= ob->totcol; a++) {
641                         Material *ma = give_current_material(ob, a);
642                         
643                         if (ma) {
644                                 /* recursively figure out if there are drivers, and hook these up to this object */
645                                 dag_add_material_driver_relations(dag, node, ma);
646                         }
647                 }
648         }
649         
650         /* particles */
651         psys = ob->particlesystem.first;
652         if (psys) {
653                 GroupObject *go;
654
655                 for (; psys; psys = psys->next) {
656                         BoidRule *rule = NULL;
657                         BoidState *state = NULL;
658                         ParticleSettings *part = psys->part;
659                         ListBase *effectors = NULL;
660                         EffectorCache *eff;
661
662                         dag_add_relation(dag, node, node, DAG_RL_OB_DATA, "Particle-Object Relation");
663
664                         if (!psys_check_enabled(ob, psys))
665                                 continue;
666
667                         if (ELEM(part->phystype, PART_PHYS_KEYED, PART_PHYS_BOIDS)) {
668                                 ParticleTarget *pt = psys->targets.first;
669
670                                 for (; pt; pt = pt->next) {
671                                         if (pt->ob && BLI_findlink(&pt->ob->particlesystem, pt->psys - 1)) {
672                                                 node2 = dag_get_node(dag, pt->ob);
673                                                 dag_add_relation(dag, node2, node, DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "Particle Targets");
674                                         }
675                                 }
676                         }
677
678                         if (part->ren_as == PART_DRAW_OB && part->dup_ob) {
679                                 node2 = dag_get_node(dag, part->dup_ob);
680                                 /* note that this relation actually runs in the wrong direction, the problem
681                                  * is that dupli system all have this (due to parenting), and the render
682                                  * engine instancing assumes particular ordering of objects in list */
683                                 dag_add_relation(dag, node, node2, DAG_RL_OB_OB, "Particle Object Visualization");
684                                 if (part->dup_ob->type == OB_MBALL)
685                                         dag_add_relation(dag, node, node2, DAG_RL_DATA_DATA, "Particle Object Visualization");
686                         }
687
688                         if (part->ren_as == PART_DRAW_GR && part->dup_group) {
689                                 for (go = part->dup_group->gobject.first; go; go = go->next) {
690                                         node2 = dag_get_node(dag, go->ob);
691                                         dag_add_relation(dag, node2, node, DAG_RL_OB_OB, "Particle Group Visualization");
692                                 }
693                         }
694
695                         effectors = pdInitEffectors(scene, ob, psys, part->effector_weights);
696
697                         if (effectors) {
698                                 for (eff = effectors->first; eff; eff = eff->next) {
699                                         if (eff->psys) {
700                                                 node2 = dag_get_node(dag, eff->ob);
701                                                 dag_add_relation(dag, node2, node, DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "Particle Field");
702                                         }
703                                 }
704                         }
705
706                         pdEndEffectors(&effectors);
707
708                         if (part->boids) {
709                                 for (state = part->boids->states.first; state; state = state->next) {
710                                         for (rule = state->rules.first; rule; rule = rule->next) {
711                                                 Object *ruleob = NULL;
712                                                 if (rule->type == eBoidRuleType_Avoid)
713                                                         ruleob = ((BoidRuleGoalAvoid *)rule)->ob;
714                                                 else if (rule->type == eBoidRuleType_FollowLeader)
715                                                         ruleob = ((BoidRuleFollowLeader *)rule)->ob;
716
717                                                 if (ruleob) {
718                                                         node2 = dag_get_node(dag, ruleob);
719                                                         dag_add_relation(dag, node2, node, DAG_RL_OB_DATA, "Boid Rule");
720                                                 }
721                                         }
722                                 }
723                         }
724                 }
725         }
726         
727         /* object constraints */
728         for (con = ob->constraints.first; con; con = con->next) {
729                 bConstraintTypeInfo *cti = constraint_get_typeinfo(con);
730                 ListBase targets = {NULL, NULL};
731                 bConstraintTarget *ct;
732                 
733                 if (!cti)
734                         continue;
735
736                 /* special case for camera tracking -- it doesn't use targets to define relations */
737                 if (ELEM3(cti->type, CONSTRAINT_TYPE_FOLLOWTRACK, CONSTRAINT_TYPE_CAMERASOLVER, CONSTRAINT_TYPE_OBJECTSOLVER)) {
738                         int depends_on_camera = 0;
739
740                         if (cti->type == CONSTRAINT_TYPE_FOLLOWTRACK) {
741                                 bFollowTrackConstraint *data = (bFollowTrackConstraint *)con->data;
742
743                                 if ((data->clip || data->flag & FOLLOWTRACK_ACTIVECLIP) && data->track[0])
744                                         depends_on_camera = 1;
745
746                                 if (data->depth_ob) {
747                                         node2 = dag_get_node(dag, data->depth_ob);
748                                         dag_add_relation(dag, node2, node, DAG_RL_DATA_OB | DAG_RL_OB_OB, cti->name);
749                                 }
750                         }
751                         else if (cti->type == CONSTRAINT_TYPE_OBJECTSOLVER)
752                                 depends_on_camera = 1;
753
754                         if (depends_on_camera && scene->camera) {
755                                 node2 = dag_get_node(dag, scene->camera);
756                                 dag_add_relation(dag, node2, node, DAG_RL_DATA_OB | DAG_RL_OB_OB, cti->name);
757                         }
758
759                         dag_add_relation(dag, scenenode, node, DAG_RL_SCENE, "Scene Relation");
760                         addtoroot = 0;
761                 }
762                 else if (cti->get_constraint_targets) {
763                         cti->get_constraint_targets(con, &targets);
764                         
765                         for (ct = targets.first; ct; ct = ct->next) {
766                                 Object *obt;
767                                 
768                                 if (ct->tar)
769                                         obt = ct->tar;
770                                 else
771                                         continue;
772                                 
773                                 node2 = dag_get_node(dag, obt);
774                                 if (ELEM(con->type, CONSTRAINT_TYPE_FOLLOWPATH, CONSTRAINT_TYPE_CLAMPTO))
775                                         dag_add_relation(dag, node2, node, DAG_RL_DATA_OB | DAG_RL_OB_OB, cti->name);
776                                 else {
777                                         if (ELEM3(obt->type, OB_ARMATURE, OB_MESH, OB_LATTICE) && (ct->subtarget[0])) {
778                                                 dag_add_relation(dag, node2, node, DAG_RL_DATA_OB | DAG_RL_OB_OB, cti->name);
779                                                 if (obt->type == OB_MESH)
780                                                         node2->customdata_mask |= CD_MASK_MDEFORMVERT;
781                                         }
782                                         else
783                                                 dag_add_relation(dag, node2, node, DAG_RL_OB_OB, cti->name);
784                                 }
785                                 addtoroot = 0;
786                         }
787                         
788                         if (cti->flush_constraint_targets)
789                                 cti->flush_constraint_targets(con, &targets, 1);
790                 }
791         }
792
793         if (addtoroot == 1)
794                 dag_add_relation(dag, scenenode, node, DAG_RL_SCENE, "Scene Relation");
795 }
796
797 DagForest *build_dag(Main *bmain, Scene *sce, short mask)
798 {
799         Base *base;
800         Object *ob;
801         Group *group;
802         GroupObject *go;
803         DagNode *node;
804         DagNode *scenenode;
805         DagForest *dag;
806         DagAdjList *itA;
807
808         dag = sce->theDag;
809         sce->dagisvalid = 1;
810         if (dag)
811                 free_forest(dag);
812         else {
813                 dag = dag_init();
814                 sce->theDag = dag;
815         }
816         
817         /* clear "LIB_DOIT" flag from all materials, to prevent infinite recursion problems later [#32017] */
818         tag_main_idcode(bmain, ID_MA, FALSE);
819         
820         /* add base node for scene. scene is always the first node in DAG */
821         scenenode = dag_add_node(dag, sce);     
822         
823         /* add current scene objects */
824         for (base = sce->base.first; base; base = base->next) {
825                 ob = base->object;
826                 
827                 build_dag_object(dag, scenenode, sce, ob, mask);
828                 if (ob->proxy)
829                         build_dag_object(dag, scenenode, sce, ob->proxy, mask);
830                 
831                 /* handled in next loop */
832                 if (ob->dup_group) 
833                         ob->dup_group->id.flag |= LIB_DOIT;
834         }
835         
836         /* add groups used in current scene objects */
837         for (group = bmain->group.first; group; group = group->id.next) {
838                 if (group->id.flag & LIB_DOIT) {
839                         for (go = group->gobject.first; go; go = go->next) {
840                                 build_dag_object(dag, scenenode, sce, go->ob, mask);
841                         }
842                         group->id.flag &= ~LIB_DOIT;
843                 }
844         }
845         
846         /* Now all relations were built, but we need to solve 1 exceptional case;
847          * When objects have multiple "parents" (for example parent + constraint working on same object)
848          * the relation type has to be synced. One of the parents can change, and should give same event to child */
849         
850         /* nodes were callocced, so we can use node->color for temporal storage */
851         for (node = sce->theDag->DagNode.first; node; node = node->next) {
852                 if (node->type == ID_OB) {
853                         for (itA = node->child; itA; itA = itA->next) {
854                                 if (itA->node->type == ID_OB) {
855                                         itA->node->color |= itA->type;
856                                 }
857                         }
858
859                         /* also flush custom data mask */
860                         ((Object *)node->ob)->customdata_mask = node->customdata_mask;
861                 }
862         }
863         /* now set relations equal, so that when only one parent changes, the correct recalcs are found */
864         for (node = sce->theDag->DagNode.first; node; node = node->next) {
865                 if (node->type == ID_OB) {
866                         for (itA = node->child; itA; itA = itA->next) {
867                                 if (itA->node->type == ID_OB) {
868                                         itA->type |= itA->node->color;
869                                 }
870                         }
871                 }
872         }
873         
874         /* cycle detection and solving */
875         // solve_cycles(dag);   
876         
877         return dag;
878 }
879
880
881 void free_forest(DagForest *Dag) 
882 {  /* remove all nodes and deps */
883         DagNode *tempN;
884         DagAdjList *tempA;      
885         DagAdjList *itA;
886         DagNode *itN = Dag->DagNode.first;
887         
888         while (itN) {
889                 itA = itN->child;       
890                 while (itA) {
891                         tempA = itA;
892                         itA = itA->next;
893                         MEM_freeN(tempA);                       
894                 }
895                 
896                 itA = itN->parent;      
897                 while (itA) {
898                         tempA = itA;
899                         itA = itA->next;
900                         MEM_freeN(tempA);                       
901                 }
902                 
903                 tempN = itN;
904                 itN = itN->next;
905                 MEM_freeN(tempN);
906         }
907
908         BLI_ghash_free(Dag->nodeHash, NULL, NULL);
909         Dag->nodeHash = NULL;
910         Dag->DagNode.first = NULL;
911         Dag->DagNode.last = NULL;
912         Dag->numNodes = 0;
913
914 }
915
916 DagNode *dag_find_node(DagForest *forest, void *fob)
917 {
918         if (forest->nodeHash)
919                 return BLI_ghash_lookup(forest->nodeHash, fob);
920
921         return NULL;
922 }
923
924 static int ugly_hack_sorry = 1;  // prevent type check
925 static int dag_print_dependencies = 0; // debugging
926
927 /* no checking of existence, use dag_find_node first or dag_get_node */
928 DagNode *dag_add_node(DagForest *forest, void *fob)
929 {
930         DagNode *node;
931                 
932         node = MEM_callocN(sizeof(DagNode), "DAG node");
933         if (node) {
934                 node->ob = fob;
935                 node->color = DAG_WHITE;
936
937                 if (ugly_hack_sorry) node->type = GS(((ID *) fob)->name);   // sorry, done for pose sorting
938                 if (forest->numNodes) {
939                         ((DagNode *) forest->DagNode.last)->next = node;
940                         forest->DagNode.last = node;
941                         forest->numNodes++;
942                 }
943                 else {
944                         forest->DagNode.last = node;
945                         forest->DagNode.first = node;
946                         forest->numNodes = 1;
947                 }
948
949                 if (!forest->nodeHash)
950                         forest->nodeHash = BLI_ghash_ptr_new("dag_add_node gh");
951                 BLI_ghash_insert(forest->nodeHash, fob, node);
952         }
953
954         return node;
955 }
956
957 DagNode *dag_get_node(DagForest *forest, void *fob)
958 {
959         DagNode *node;
960         
961         node = dag_find_node(forest, fob);
962         if (!node) 
963                 node = dag_add_node(forest, fob);
964         return node;
965 }
966
967
968
969 DagNode *dag_get_sub_node(DagForest *forest, void *fob)
970 {
971         DagNode *node;
972         DagAdjList *mainchild, *prev = NULL;
973         
974         mainchild = ((DagNode *) forest->DagNode.first)->child;
975         /* remove from first node (scene) adj list if present */
976         while (mainchild) {
977                 if (mainchild->node == fob) {
978                         if (prev) {
979                                 prev->next = mainchild->next;
980                                 MEM_freeN(mainchild);
981                                 break;
982                         }
983                         else {
984                                 ((DagNode *) forest->DagNode.first)->child = mainchild->next;
985                                 MEM_freeN(mainchild);
986                                 break;
987                         }
988                 }
989                 prev = mainchild;
990                 mainchild = mainchild->next;
991         }
992         node = dag_find_node(forest, fob);
993         if (!node) 
994                 node = dag_add_node(forest, fob);
995         return node;
996 }
997
998 static void dag_add_parent_relation(DagForest *UNUSED(forest), DagNode *fob1, DagNode *fob2, short rel, const char *name) 
999 {
1000         DagAdjList *itA = fob2->parent;
1001         
1002         while (itA) { /* search if relation exist already */
1003                 if (itA->node == fob1) {
1004                         itA->type |= rel;
1005                         itA->count += 1;
1006                         return;
1007                 }
1008                 itA = itA->next;
1009         }
1010         /* create new relation and insert at head. MALLOC alert! */
1011         itA = MEM_mallocN(sizeof(DagAdjList), "DAG adj list");
1012         itA->node = fob1;
1013         itA->type = rel;
1014         itA->count = 1;
1015         itA->next = fob2->parent;
1016         itA->name = name;
1017         fob2->parent = itA;
1018 }
1019
1020 void dag_add_relation(DagForest *forest, DagNode *fob1, DagNode *fob2, short rel, const char *name) 
1021 {
1022         DagAdjList *itA = fob1->child;
1023         
1024         /* parent relation is for cycle checking */
1025         dag_add_parent_relation(forest, fob1, fob2, rel, name);
1026
1027         while (itA) { /* search if relation exist already */
1028                 if (itA->node == fob2) {
1029                         itA->type |= rel;
1030                         itA->count += 1;
1031                         return;
1032                 }
1033                 itA = itA->next;
1034         }
1035         /* create new relation and insert at head. MALLOC alert! */
1036         itA = MEM_mallocN(sizeof(DagAdjList), "DAG adj list");
1037         itA->node = fob2;
1038         itA->type = rel;
1039         itA->count = 1;
1040         itA->next = fob1->child;
1041         itA->name = name;
1042         fob1->child = itA;
1043 }
1044
1045 static const char *dag_node_name(DagNode *node)
1046 {
1047         if (node->ob == NULL)
1048                 return "null";
1049         else if (ugly_hack_sorry)
1050                 return ((ID *)(node->ob))->name + 2;
1051         else
1052                 return ((bPoseChannel *)(node->ob))->name;
1053 }
1054
1055 static void dag_node_print_dependencies(DagNode *node)
1056 {
1057         DagAdjList *itA;
1058
1059         printf("%s depends on:\n", dag_node_name(node));
1060
1061         for (itA = node->parent; itA; itA = itA->next)
1062                 printf("  %s through %s\n", dag_node_name(itA->node), itA->name);
1063         printf("\n");
1064 }
1065
1066 static int dag_node_print_dependency_recurs(DagNode *node, DagNode *endnode)
1067 {
1068         DagAdjList *itA;
1069
1070         if (node->color == DAG_BLACK)
1071                 return 0;
1072
1073         node->color = DAG_BLACK;
1074
1075         if (node == endnode)
1076                 return 1;
1077
1078         for (itA = node->parent; itA; itA = itA->next) {
1079                 if (dag_node_print_dependency_recurs(itA->node, endnode)) {
1080                         printf("  %s depends on %s through %s.\n", dag_node_name(node), dag_node_name(itA->node), itA->name);
1081                         return 1;
1082                 }
1083         }
1084
1085         return 0;
1086 }
1087
1088 static void dag_node_print_dependency_cycle(DagForest *dag, DagNode *startnode, DagNode *endnode, const char *name)
1089 {
1090         DagNode *node;
1091
1092         for (node = dag->DagNode.first; node; node = node->next)
1093                 node->color = DAG_WHITE;
1094
1095         printf("  %s depends on %s through %s.\n", dag_node_name(endnode), dag_node_name(startnode), name);
1096         dag_node_print_dependency_recurs(startnode, endnode);
1097         printf("\n");
1098 }
1099
1100 static int dag_node_recurs_level(DagNode *node, int level)
1101 {
1102         DagAdjList *itA;
1103         int newlevel;
1104
1105         node->color = DAG_BLACK; /* done */
1106         newlevel = ++level;
1107         
1108         for (itA = node->parent; itA; itA = itA->next) {
1109                 if (itA->node->color == DAG_WHITE) {
1110                         itA->node->ancestor_count = dag_node_recurs_level(itA->node, level);
1111                         newlevel = MAX2(newlevel, level + itA->node->ancestor_count);
1112                 }
1113                 else
1114                         newlevel = MAX2(newlevel, level + itA->node->ancestor_count);
1115         }
1116         
1117         return newlevel;
1118 }
1119
1120 static void dag_check_cycle(DagForest *dag)
1121 {
1122         DagNode *node;
1123         DagAdjList *itA;
1124
1125         /* debugging print */
1126         if (dag_print_dependencies)
1127                 for (node = dag->DagNode.first; node; node = node->next)
1128                         dag_node_print_dependencies(node);
1129
1130         /* tag nodes unchecked */
1131         for (node = dag->DagNode.first; node; node = node->next)
1132                 node->color = DAG_WHITE;
1133         
1134         for (node = dag->DagNode.first; node; node = node->next) {
1135                 if (node->color == DAG_WHITE) {
1136                         node->ancestor_count = dag_node_recurs_level(node, 0);
1137                 }
1138         }
1139         
1140         /* check relations, and print errors */
1141         for (node = dag->DagNode.first; node; node = node->next) {
1142                 for (itA = node->parent; itA; itA = itA->next) {
1143                         if (itA->node->ancestor_count > node->ancestor_count) {
1144                                 if (node->ob && itA->node->ob) {
1145                                         printf("Dependency cycle detected:\n");
1146                                         dag_node_print_dependency_cycle(dag, itA->node, node, itA->name);
1147                                 }
1148                         }
1149                 }
1150         }
1151
1152         /* parent relations are only needed for cycle checking, so free now */
1153         for (node = dag->DagNode.first; node; node = node->next) {
1154                 while (node->parent) {
1155                         itA = node->parent->next;
1156                         MEM_freeN(node->parent);                        
1157                         node->parent = itA;
1158                 }
1159         }
1160 }
1161
1162 /*
1163  * MainDAG is the DAG of all objects in current scene
1164  * used only for drawing there is one also in each scene
1165  */
1166 static DagForest *MainDag = NULL;
1167
1168 DagForest *getMainDag(void)
1169 {
1170         return MainDag;
1171 }
1172
1173
1174 void setMainDag(DagForest *dag)
1175 {
1176         MainDag = dag;
1177 }
1178
1179
1180 /*
1181  * note for BFS/DFS
1182  * in theory we should sweep the whole array
1183  * but in our case the first node is the scene
1184  * and is linked to every other object
1185  *
1186  * for general case we will need to add outer loop
1187  */
1188
1189 /*
1190  * ToDo : change pos kludge
1191  */
1192
1193 /* adjust levels for drawing in oops space */
1194 void graph_bfs(void)
1195 {
1196         DagNode *node;
1197         DagNodeQueue *nqueue;
1198         int pos[50];
1199         int i;
1200         DagAdjList *itA;
1201         int minheight;
1202         
1203         /* fprintf(stderr, "starting BFS\n ------------\n"); */
1204         nqueue = queue_create(DAGQUEUEALLOC);
1205         for (i = 0; i < 50; i++)
1206                 pos[i] = 0;
1207         
1208         /* Init
1209          * dagnode.first is always the root (scene)
1210          */
1211         node = MainDag->DagNode.first;
1212         while (node) {
1213                 node->color = DAG_WHITE;
1214                 node->BFS_dist = 9999;
1215                 node->k = 0;
1216                 node = node->next;
1217         }
1218         
1219         node = MainDag->DagNode.first;
1220         if (node->color == DAG_WHITE) {
1221                 node->color = DAG_GRAY;
1222                 node->BFS_dist = 1;
1223                 push_queue(nqueue, node);
1224                 while (nqueue->count) {
1225                         node = pop_queue(nqueue);
1226                         
1227                         minheight = pos[node->BFS_dist];
1228                         itA = node->child;
1229                         while (itA != NULL) {
1230                                 if (itA->node->color == DAG_WHITE) {
1231                                         itA->node->color = DAG_GRAY;
1232                                         itA->node->BFS_dist = node->BFS_dist + 1;
1233                                         itA->node->k = (float) minheight;
1234                                         push_queue(nqueue, itA->node);
1235                                 }
1236                                 
1237                                 else {
1238                                         fprintf(stderr, "bfs not dag tree edge color :%i\n", itA->node->color);
1239                                 }
1240
1241                                 
1242                                 itA = itA->next;
1243                         }
1244                         if (pos[node->BFS_dist] > node->k) {
1245                                 pos[node->BFS_dist] += 1;                               
1246                                 node->k = (float) pos[node->BFS_dist];
1247                         }
1248                         else {
1249                                 pos[node->BFS_dist] = (int) node->k + 1;
1250                         }
1251                         set_node_xy(node, node->BFS_dist * DEPSX * 2, pos[node->BFS_dist] * DEPSY * 2);
1252                         node->color = DAG_BLACK;
1253
1254                         // fprintf(stderr, "BFS node : %20s %i %5.0f %5.0f\n", ((ID *) node->ob)->name, node->BFS_dist, node->x, node->y);
1255                 }
1256         }
1257         queue_delete(nqueue);
1258 }
1259
1260 int pre_and_post_BFS(DagForest *dag, short mask, graph_action_func pre_func, graph_action_func post_func, void **data)
1261 {
1262         DagNode *node;
1263         
1264         node = dag->DagNode.first;
1265         return pre_and_post_source_BFS(dag, mask,  node,  pre_func,  post_func, data);
1266 }
1267
1268
1269 int pre_and_post_source_BFS(DagForest *dag, short mask, DagNode *source, graph_action_func pre_func, graph_action_func post_func, void **data)
1270 {
1271         DagNode *node;
1272         DagNodeQueue *nqueue;
1273         DagAdjList *itA;
1274         int retval = 0;
1275         /* fprintf(stderr, "starting BFS\n ------------\n"); */
1276         
1277         /* Init
1278          * dagnode.first is always the root (scene)
1279          */
1280         node = dag->DagNode.first;
1281         nqueue = queue_create(DAGQUEUEALLOC);
1282         while (node) {
1283                 node->color = DAG_WHITE;
1284                 node->BFS_dist = 9999;
1285                 node = node->next;
1286         }
1287         
1288         node = source;
1289         if (node->color == DAG_WHITE) {
1290                 node->color = DAG_GRAY;
1291                 node->BFS_dist = 1;
1292                 pre_func(node->ob, data);
1293                 
1294                 while (nqueue->count) {
1295                         node = pop_queue(nqueue);
1296                         
1297                         itA = node->child;
1298                         while (itA != NULL) {
1299                                 if ((itA->node->color == DAG_WHITE) && (itA->type & mask)) {
1300                                         itA->node->color = DAG_GRAY;
1301                                         itA->node->BFS_dist = node->BFS_dist + 1;
1302                                         push_queue(nqueue, itA->node);
1303                                         pre_func(node->ob, data);
1304                                 }
1305                                 
1306                                 else { // back or cross edge
1307                                         retval = 1;
1308                                 }
1309                                 itA = itA->next;
1310                         }
1311                         post_func(node->ob, data);
1312                         node->color = DAG_BLACK;
1313
1314                         // fprintf(stderr, "BFS node : %20s %i %5.0f %5.0f\n", ((ID *) node->ob)->name, node->BFS_dist, node->x, node->y);
1315                 }
1316         }
1317         queue_delete(nqueue);
1318         return retval;
1319 }
1320
1321 /* non recursive version of DFS, return queue -- outer loop present to catch odd cases (first level cycles)*/
1322 DagNodeQueue *graph_dfs(void)
1323 {
1324         DagNode *node;
1325         DagNodeQueue *nqueue;
1326         DagNodeQueue *retqueue;
1327         int pos[50];
1328         int i;
1329         DagAdjList *itA;
1330         int time;
1331         int skip = 0;
1332         int minheight;
1333         int maxpos = 0;
1334         /* int  is_cycle = 0; */ /* UNUSED */
1335         /*
1336          *fprintf(stderr, "starting DFS\n ------------\n");
1337          */     
1338         nqueue = queue_create(DAGQUEUEALLOC);
1339         retqueue = queue_create(MainDag->numNodes);
1340         for (i = 0; i < 50; i++)
1341                 pos[i] = 0;
1342         
1343         /* Init
1344          * dagnode.first is always the root (scene)
1345          */
1346         node = MainDag->DagNode.first;
1347         while (node) {
1348                 node->color = DAG_WHITE;
1349                 node->DFS_dist = 9999;
1350                 node->DFS_dvtm = node->DFS_fntm = 9999;
1351                 node->k = 0;
1352                 node =  node->next;
1353         }
1354         
1355         time = 1;
1356         
1357         node = MainDag->DagNode.first;
1358
1359         do {
1360                 if (node->color == DAG_WHITE) {
1361                         node->color = DAG_GRAY;
1362                         node->DFS_dist = 1;
1363                         node->DFS_dvtm = time;
1364                         time++;
1365                         push_stack(nqueue, node);
1366                         
1367                         while (nqueue->count) {
1368                                 //graph_print_queue(nqueue);
1369
1370                                 skip = 0;
1371                                 node = get_top_node_queue(nqueue);
1372                         
1373                                 minheight = pos[node->DFS_dist];
1374
1375                                 itA = node->child;
1376                                 while (itA != NULL) {
1377                                         if (itA->node->color == DAG_WHITE) {
1378                                                 itA->node->DFS_dvtm = time;
1379                                                 itA->node->color = DAG_GRAY;
1380
1381                                                 time++;
1382                                                 itA->node->DFS_dist = node->DFS_dist + 1;
1383                                                 itA->node->k = (float) minheight;
1384                                                 push_stack(nqueue, itA->node);
1385                                                 skip = 1;
1386                                                 break;
1387                                         }
1388                                         else {
1389                                                 if (itA->node->color == DAG_GRAY) { // back edge
1390                                                         fprintf(stderr, "dfs back edge :%15s %15s\n", ((ID *) node->ob)->name, ((ID *) itA->node->ob)->name);
1391                                                         /* is_cycle = 1; */ /* UNUSED */
1392                                                 }
1393                                                 else if (itA->node->color == DAG_BLACK) {
1394                                                         /* already processed node but we may want later to change distance either to shorter to longer.
1395                                                          * DFS_dist is the first encounter
1396                                                          */
1397 #if 0
1398                                                         if (node->DFS_dist >= itA->node->DFS_dist)
1399                                                                 itA->node->DFS_dist = node->DFS_dist + 1;
1400
1401                                                         fprintf(stderr, "dfs forward or cross edge :%15s %i-%i %15s %i-%i\n",
1402                                                                 ((ID *) node->ob)->name,
1403                                                                 node->DFS_dvtm,
1404                                                                 node->DFS_fntm,
1405                                                                 ((ID *) itA->node->ob)->name,
1406                                                                 itA->node->DFS_dvtm,
1407                                                                 itA->node->DFS_fntm);
1408 #endif
1409                                                 }
1410                                                 else
1411                                                         fprintf(stderr, "dfs unknown edge\n");
1412                                         }
1413                                         itA = itA->next;
1414                                 }
1415
1416                                 if (!skip) {
1417                                         node = pop_queue(nqueue);
1418                                         node->color = DAG_BLACK;
1419
1420                                         node->DFS_fntm = time;
1421                                         time++;
1422                                         if (node->DFS_dist > maxpos)
1423                                                 maxpos = node->DFS_dist;
1424                                         if (pos[node->DFS_dist] > node->k) {
1425                                                 pos[node->DFS_dist] += 1;
1426                                                 node->k = (float) pos[node->DFS_dist];
1427                                         }
1428                                         else {
1429                                                 pos[node->DFS_dist] = (int) node->k + 1;
1430                                         }
1431                                         set_node_xy(node, node->DFS_dist * DEPSX * 2, pos[node->DFS_dist] * DEPSY * 2);
1432                                 
1433                                         // fprintf(stderr, "DFS node : %20s %i %i %i %i\n", ((ID *) node->ob)->name, node->BFS_dist, node->DFS_dist, node->DFS_dvtm, node->DFS_fntm );
1434
1435                                         push_stack(retqueue, node);
1436                                 
1437                                 }
1438                         }
1439                 }
1440                 node = node->next;
1441         } while (node);
1442 //      fprintf(stderr, "i size : %i\n", maxpos);
1443
1444         queue_delete(nqueue);
1445         return(retqueue);
1446 }
1447
1448 /* unused */
1449 int pre_and_post_DFS(DagForest *dag, short mask, graph_action_func pre_func, graph_action_func post_func, void **data)
1450 {
1451         DagNode *node;
1452
1453         node = dag->DagNode.first;
1454         return pre_and_post_source_DFS(dag, mask,  node,  pre_func,  post_func, data);
1455 }
1456
1457 int pre_and_post_source_DFS(DagForest *dag, short mask, DagNode *source, graph_action_func pre_func, graph_action_func post_func, void **data)
1458 {
1459         DagNode *node;
1460         DagNodeQueue *nqueue;
1461         DagAdjList *itA;
1462         int time;
1463         int skip = 0;
1464         int retval = 0;
1465         /*
1466          * fprintf(stderr, "starting DFS\n ------------\n");
1467          */     
1468         nqueue = queue_create(DAGQUEUEALLOC);
1469         
1470         /* Init
1471          * dagnode.first is always the root (scene)
1472          */
1473         node = dag->DagNode.first;
1474         while (node) {
1475                 node->color = DAG_WHITE;
1476                 node->DFS_dist = 9999;
1477                 node->DFS_dvtm = node->DFS_fntm = 9999;
1478                 node->k = 0;
1479                 node =  node->next;
1480         }
1481         
1482         time = 1;
1483         
1484         node = source;
1485         do {
1486                 if (node->color == DAG_WHITE) {
1487                         node->color = DAG_GRAY;
1488                         node->DFS_dist = 1;
1489                         node->DFS_dvtm = time;
1490                         time++;
1491                         push_stack(nqueue, node);
1492                         pre_func(node->ob, data);
1493
1494                         while (nqueue->count) {
1495                                 skip = 0;
1496                                 node = get_top_node_queue(nqueue);
1497                                                                 
1498                                 itA = node->child;
1499                                 while (itA != NULL) {
1500                                         if ((itA->node->color == DAG_WHITE) && (itA->type & mask) ) {
1501                                                 itA->node->DFS_dvtm = time;
1502                                                 itA->node->color = DAG_GRAY;
1503                                                 
1504                                                 time++;
1505                                                 itA->node->DFS_dist = node->DFS_dist + 1;
1506                                                 push_stack(nqueue, itA->node);
1507                                                 pre_func(node->ob, data);
1508
1509                                                 skip = 1;
1510                                                 break;
1511                                         }
1512                                         else {
1513                                                 if (itA->node->color == DAG_GRAY) { // back edge
1514                                                         retval = 1;
1515                                                 }
1516 //                                              else if (itA->node->color == DAG_BLACK) { // cross or forward
1517 //
1518 //                                              }
1519                                         }
1520                                         itA = itA->next;
1521                                 }                       
1522                                 
1523                                 if (!skip) {
1524                                         node = pop_queue(nqueue);
1525                                         node->color = DAG_BLACK;
1526                                         
1527                                         node->DFS_fntm = time;
1528                                         time++;
1529                                         post_func(node->ob, data);
1530                                 }
1531                         }
1532                 }
1533                 node = node->next;
1534         } while (node);
1535         queue_delete(nqueue);
1536         return(retval);
1537 }
1538
1539
1540 // used to get the obs owning a datablock
1541 DagNodeQueue *get_obparents(struct DagForest *dag, void *ob)
1542 {
1543         DagNode *node, *node1;
1544         DagNodeQueue *nqueue;
1545         DagAdjList *itA;
1546
1547         node = dag_find_node(dag, ob);
1548         if (node == NULL) {
1549                 return NULL;
1550         }
1551         else if (node->ancestor_count == 1) { // simple case
1552                 nqueue = queue_create(1);
1553                 push_queue(nqueue, node);
1554         }
1555         else { /* need to go over the whole dag for adj list */
1556                 nqueue = queue_create(node->ancestor_count);
1557                 
1558                 node1 = dag->DagNode.first;
1559                 do {
1560                         if (node1->DFS_fntm > node->DFS_fntm) { // a parent is finished after child. must check adj list
1561                                 itA = node->child;
1562                                 while (itA != NULL) {
1563                                         if ((itA->node == node) && (itA->type == DAG_RL_DATA)) {
1564                                                 push_queue(nqueue, node);
1565                                         }
1566                                         itA = itA->next;
1567                                 }
1568                         }
1569                         node1 = node1->next;
1570                 } while (node1);
1571         }
1572         return nqueue;
1573 }
1574
1575 DagNodeQueue *get_first_ancestors(struct DagForest   *dag, void *ob)
1576 {
1577         DagNode *node, *node1;
1578         DagNodeQueue *nqueue;
1579         DagAdjList *itA;
1580         
1581         node = dag_find_node(dag, ob);
1582         
1583         /* need to go over the whole dag for adj list */
1584         nqueue = queue_create(node->ancestor_count);
1585         
1586         node1 = dag->DagNode.first;
1587         do {
1588                 if (node1->DFS_fntm > node->DFS_fntm) { 
1589                         itA = node->child;
1590                         while (itA != NULL) {
1591                                 if (itA->node == node) {
1592                                         push_queue(nqueue, node);
1593                                 }
1594                                 itA = itA->next;
1595                         }
1596                 }
1597                 node1 = node1->next;
1598         } while (node1);
1599         
1600         return nqueue;  
1601 }
1602
1603 // standard DFS list
1604 DagNodeQueue *get_all_childs(struct DagForest    *dag, void *ob)
1605 {
1606         DagNode *node;
1607         DagNodeQueue *nqueue;
1608         DagNodeQueue *retqueue;
1609         DagAdjList *itA;
1610         int time;
1611         int skip = 0;
1612
1613         nqueue = queue_create(DAGQUEUEALLOC);
1614         retqueue = queue_create(dag->numNodes); // was MainDag... why? (ton)
1615         
1616         node = dag->DagNode.first;
1617         while (node) {
1618                 node->color = DAG_WHITE;
1619                 node =  node->next;
1620         }
1621         
1622         time = 1;
1623         
1624         node = dag_find_node(dag, ob);   // could be done in loop above (ton)
1625         if (node) { // can be null for newly added objects
1626                 
1627                 node->color = DAG_GRAY;
1628                 time++;
1629                 push_stack(nqueue, node);
1630                 
1631                 while (nqueue->count) {
1632                         
1633                         skip = 0;
1634                         node = get_top_node_queue(nqueue);
1635                                         
1636                         itA = node->child;
1637                         while (itA != NULL) {
1638                                 if (itA->node->color == DAG_WHITE) {
1639                                         itA->node->DFS_dvtm = time;
1640                                         itA->node->color = DAG_GRAY;
1641                                         
1642                                         time++;
1643                                         push_stack(nqueue, itA->node);
1644                                         skip = 1;
1645                                         break;
1646                                 } 
1647                                 itA = itA->next;
1648                         }                       
1649                         
1650                         if (!skip) {
1651                                 node = pop_queue(nqueue);
1652                                 node->color = DAG_BLACK;
1653                                 
1654                                 time++;
1655                                 push_stack(retqueue, node);
1656                         }
1657                 }
1658         }
1659         queue_delete(nqueue);
1660         return(retqueue);
1661 }
1662
1663 /* unused */
1664 #if 0
1665 short   are_obs_related(struct DagForest    *dag, void *ob1, void *ob2)
1666 {
1667         DagNode *node;
1668         DagAdjList *itA;
1669         
1670         node = dag_find_node(dag, ob1);
1671         
1672         itA = node->child;
1673         while (itA != NULL) {
1674                 if (itA->node->ob == ob2) {
1675                         return itA->node->type;
1676                 } 
1677                 itA = itA->next;
1678         }
1679         return DAG_NO_RELATION;
1680 }
1681 #endif
1682
1683 int is_acyclic(DagForest *dag)
1684 {
1685         return dag->is_acyclic;
1686 }
1687
1688 void set_node_xy(DagNode *node, float x, float y)
1689 {
1690         node->x = x;
1691         node->y = y;
1692 }
1693
1694
1695 /* debug test functions */
1696
1697 void graph_print_queue(DagNodeQueue *nqueue)
1698 {       
1699         DagNodeQueueElem *queueElem;
1700         
1701         queueElem = nqueue->first;
1702         while (queueElem) {
1703                 fprintf(stderr, "** %s %i %i-%i ", ((ID *) queueElem->node->ob)->name, queueElem->node->color, queueElem->node->DFS_dvtm, queueElem->node->DFS_fntm);
1704                 queueElem = queueElem->next;            
1705         }
1706         fprintf(stderr, "\n");
1707 }
1708
1709 void graph_print_queue_dist(DagNodeQueue *nqueue)
1710 {       
1711         DagNodeQueueElem *queueElem;
1712         int count;
1713         
1714         queueElem = nqueue->first;
1715         count = 0;
1716         while (queueElem) {
1717                 fprintf(stderr, "** %25s %2.2i-%2.2i ", ((ID *) queueElem->node->ob)->name, queueElem->node->DFS_dvtm, queueElem->node->DFS_fntm);
1718                 while (count < queueElem->node->DFS_dvtm - 1) { fputc(' ', stderr); count++; }
1719                 fputc('|', stderr);
1720                 while (count < queueElem->node->DFS_fntm - 2) { fputc('-', stderr); count++; }
1721                 fputc('|', stderr);
1722                 fputc('\n', stderr);
1723                 count = 0;
1724                 queueElem = queueElem->next;            
1725         }
1726         fprintf(stderr, "\n");
1727 }
1728
1729 void graph_print_adj_list(void)
1730 {
1731         DagNode *node;
1732         DagAdjList *itA;
1733         
1734         node = (getMainDag())->DagNode.first;
1735         while (node) {
1736                 fprintf(stderr, "node : %s col: %i", ((ID *) node->ob)->name, node->color);
1737                 itA = node->child;
1738                 while (itA) {
1739                         fprintf(stderr, "-- %s ", ((ID *) itA->node->ob)->name);
1740                         
1741                         itA = itA->next;
1742                 }
1743                 fprintf(stderr, "\n");
1744                 node = node->next;
1745         }
1746 }
1747
1748 /* ************************ API *********************** */
1749
1750 /* mechanism to allow editors to be informed of depsgraph updates,
1751  * to do their own updates based on changes... */
1752 static void (*EditorsUpdateIDCb)(Main *bmain, ID *id) = NULL;
1753 static void (*EditorsUpdateSceneCb)(Main *bmain, Scene *scene, int updated) = NULL;
1754
1755 void DAG_editors_update_cb(void (*id_func)(Main *bmain, ID *id), void (*scene_func)(Main *bmain, Scene *scene, int updated))
1756 {
1757         EditorsUpdateIDCb = id_func;
1758         EditorsUpdateSceneCb = scene_func;
1759 }
1760
1761 static void dag_editors_id_update(Main *bmain, ID *id)
1762 {
1763         if (EditorsUpdateIDCb)
1764                 EditorsUpdateIDCb(bmain, id);
1765 }
1766
1767 static void dag_editors_scene_update(Main *bmain, Scene *scene, int updated)
1768 {
1769         if (EditorsUpdateSceneCb)
1770                 EditorsUpdateSceneCb(bmain, scene, updated);
1771 }
1772
1773 /* groups with objects in this scene need to be put in the right order as well */
1774 static void scene_sort_groups(Main *bmain, Scene *sce)
1775 {
1776         Base *base;
1777         Group *group;
1778         GroupObject *go;
1779         Object *ob;
1780         
1781         /* test; are group objects all in this scene? */
1782         for (ob = bmain->object.first; ob; ob = ob->id.next) {
1783                 ob->id.flag &= ~LIB_DOIT;
1784                 ob->id.newid = NULL; /* newid abuse for GroupObject */
1785         }
1786         for (base = sce->base.first; base; base = base->next)
1787                 base->object->id.flag |= LIB_DOIT;
1788         
1789         for (group = bmain->group.first; group; group = group->id.next) {
1790                 for (go = group->gobject.first; go; go = go->next) {
1791                         if ((go->ob->id.flag & LIB_DOIT) == 0)
1792                                 break;
1793                 }
1794                 /* this group is entirely in this scene */
1795                 if (go == NULL) {
1796                         ListBase listb = {NULL, NULL};
1797                         
1798                         for (go = group->gobject.first; go; go = go->next)
1799                                 go->ob->id.newid = (ID *)go;
1800                         
1801                         /* in order of sorted bases we reinsert group objects */
1802                         for (base = sce->base.first; base; base = base->next) {
1803                                 
1804                                 if (base->object->id.newid) {
1805                                         go = (GroupObject *)base->object->id.newid;
1806                                         base->object->id.newid = NULL;
1807                                         BLI_remlink(&group->gobject, go);
1808                                         BLI_addtail(&listb, go);
1809                                 }
1810                         }
1811                         /* copy the newly sorted listbase */
1812                         group->gobject = listb;
1813                 }
1814         }
1815 }
1816
1817 /* sort the base list on dependency order */
1818 void DAG_scene_sort(Main *bmain, Scene *sce)
1819 {
1820         DagNode *node, *rootnode;
1821         DagNodeQueue *nqueue;
1822         DagAdjList *itA;
1823         int time;
1824         int skip = 0;
1825         ListBase tempbase;
1826         Base *base;
1827         
1828         tempbase.first = tempbase.last = NULL;
1829         
1830         build_dag(bmain, sce, DAG_RL_ALL_BUT_DATA);
1831         
1832         dag_check_cycle(sce->theDag);
1833
1834         nqueue = queue_create(DAGQUEUEALLOC);
1835         
1836         for (node = sce->theDag->DagNode.first; node; node = node->next) {
1837                 node->color = DAG_WHITE;
1838         }
1839         
1840         time = 1;
1841         
1842         rootnode = sce->theDag->DagNode.first;
1843         rootnode->color = DAG_GRAY;
1844         time++;
1845         push_stack(nqueue, rootnode);
1846         
1847         while (nqueue->count) {
1848                 
1849                 skip = 0;
1850                 node = get_top_node_queue(nqueue);
1851                 
1852                 itA = node->child;
1853                 while (itA != NULL) {
1854                         if (itA->node->color == DAG_WHITE) {
1855                                 itA->node->DFS_dvtm = time;
1856                                 itA->node->color = DAG_GRAY;
1857                                 
1858                                 time++;
1859                                 push_stack(nqueue, itA->node);
1860                                 skip = 1;
1861                                 break;
1862                         } 
1863                         itA = itA->next;
1864                 }                       
1865                 
1866                 if (!skip) {
1867                         if (node) {
1868                                 node = pop_queue(nqueue);
1869                                 if (node->ob == sce)    // we are done
1870                                         break;
1871                                 node->color = DAG_BLACK;
1872                                 
1873                                 time++;
1874                                 base = sce->base.first;
1875                                 while (base && base->object != node->ob)
1876                                         base = base->next;
1877                                 if (base) {
1878                                         BLI_remlink(&sce->base, base);
1879                                         BLI_addhead(&tempbase, base);
1880                                 }
1881                         }       
1882                 }
1883         }
1884         
1885         /* temporal correction for circular dependencies */
1886         base = sce->base.first;
1887         while (base) {
1888                 BLI_remlink(&sce->base, base);
1889                 BLI_addhead(&tempbase, base);
1890                 //if (G.debug & G_DEBUG)
1891                 printf("cyclic %s\n", base->object->id.name);
1892                 base = sce->base.first;
1893         }
1894         
1895         sce->base = tempbase;
1896         queue_delete(nqueue);
1897         
1898         /* all groups with objects in this scene gets resorted too */
1899         scene_sort_groups(bmain, sce);
1900         
1901         if (G.debug & G_DEBUG) {
1902                 printf("\nordered\n");
1903                 for (base = sce->base.first; base; base = base->next) {
1904                         printf(" %s\n", base->object->id.name);
1905                 }
1906         }
1907         /* temporal...? */
1908         sce->recalc |= SCE_PRV_CHANGED; /* test for 3d preview */
1909 }
1910
1911 static void lib_id_recalc_tag(Main *bmain, ID *id)
1912 {
1913         id->flag |= LIB_ID_RECALC;
1914         bmain->id_tag_update[id->name[0]] = 1;
1915 }
1916
1917 static void lib_id_recalc_data_tag(Main *bmain, ID *id)
1918 {
1919         id->flag |= LIB_ID_RECALC_DATA;
1920         bmain->id_tag_update[id->name[0]] = 1;
1921 }
1922
1923 /* node was checked to have lasttime != curtime and is if type ID_OB */
1924 static void flush_update_node(DagNode *node, unsigned int layer, int curtime)
1925 {
1926         Main *bmain = G.main;
1927         DagAdjList *itA;
1928         Object *ob, *obc;
1929         int oldflag, changed = 0;
1930         unsigned int all_layer;
1931         
1932         node->lasttime = curtime;
1933         
1934         ob = node->ob;
1935         if (ob && (ob->recalc & OB_RECALC_ALL)) {
1936                 all_layer = node->scelay;
1937
1938                 /* got an object node that changes, now check relations */
1939                 for (itA = node->child; itA; itA = itA->next) {
1940                         all_layer |= itA->lay;
1941                         /* the relationship is visible */
1942                         if ((itA->lay & layer)) { // XXX || (itA->node->ob == obedit)
1943                                 if (itA->node->type == ID_OB) {
1944                                         obc = itA->node->ob;
1945                                         oldflag = obc->recalc;
1946                                         
1947                                         /* got a ob->obc relation, now check if flag needs flush */
1948                                         if (ob->recalc & OB_RECALC_OB) {
1949                                                 if (itA->type & DAG_RL_OB_OB) {
1950                                                         //printf("ob %s changes ob %s\n", ob->id.name, obc->id.name);
1951                                                         obc->recalc |= OB_RECALC_OB;
1952                                                         lib_id_recalc_tag(bmain, &obc->id);
1953                                                 }
1954                                                 if (itA->type & DAG_RL_OB_DATA) {
1955                                                         //printf("ob %s changes obdata %s\n", ob->id.name, obc->id.name);
1956                                                         obc->recalc |= OB_RECALC_DATA;
1957                                                         lib_id_recalc_data_tag(bmain, &obc->id);
1958                                                 }
1959                                         }
1960                                         if (ob->recalc & OB_RECALC_DATA) {
1961                                                 if (itA->type & DAG_RL_DATA_OB) {
1962                                                         //printf("obdata %s changes ob %s\n", ob->id.name, obc->id.name);
1963                                                         obc->recalc |= OB_RECALC_OB;
1964                                                         lib_id_recalc_tag(bmain, &obc->id);
1965                                                 }
1966                                                 if (itA->type & DAG_RL_DATA_DATA) {
1967                                                         //printf("obdata %s changes obdata %s\n", ob->id.name, obc->id.name);
1968                                                         obc->recalc |= OB_RECALC_DATA;
1969                                                         lib_id_recalc_data_tag(bmain, &obc->id);
1970                                                 }
1971                                         }
1972                                         if (oldflag != obc->recalc) changed = 1;
1973                                 }
1974                         }
1975                 }
1976                 /* even nicer, we can clear recalc flags...  */
1977                 if ((all_layer & layer) == 0) { // XXX && (ob != obedit)) {
1978                         /* but existing displaylists or derivedmesh should be freed */
1979                         if (ob->recalc & OB_RECALC_DATA)
1980                                 BKE_object_free_display(ob);
1981                         
1982                         ob->recalc &= ~OB_RECALC_ALL;
1983                 }
1984         }
1985         
1986         /* check case where child changes and parent forcing obdata to change */
1987         /* should be done regardless if this ob has recalc set */
1988         /* could merge this in with loop above...? (ton) */
1989         for (itA = node->child; itA; itA = itA->next) {
1990                 /* the relationship is visible */
1991                 if ((itA->lay & layer)) {       // XXX  || (itA->node->ob == obedit)
1992                         if (itA->node->type == ID_OB) {
1993                                 obc = itA->node->ob;
1994                                 /* child moves */
1995                                 if ((obc->recalc & OB_RECALC_ALL) == OB_RECALC_OB) {
1996                                         /* parent has deforming info */
1997                                         if (itA->type & (DAG_RL_OB_DATA | DAG_RL_DATA_DATA)) {
1998                                                 // printf("parent %s changes ob %s\n", ob->id.name, obc->id.name);
1999                                                 obc->recalc |= OB_RECALC_DATA;
2000                                                 lib_id_recalc_data_tag(bmain, &obc->id);
2001                                         }
2002                                 }
2003                         }
2004                 }
2005         }
2006         
2007         /* we only go deeper if node not checked or something changed  */
2008         for (itA = node->child; itA; itA = itA->next) {
2009                 if (changed || itA->node->lasttime != curtime)
2010                         flush_update_node(itA->node, layer, curtime);
2011         }
2012         
2013 }
2014
2015 /* node was checked to have lasttime != curtime, and is of type ID_OB */
2016 static unsigned int flush_layer_node(Scene *sce, DagNode *node, int curtime)
2017 {
2018         DagAdjList *itA;
2019         
2020         node->lasttime = curtime;
2021         node->lay = node->scelay;
2022         
2023         for (itA = node->child; itA; itA = itA->next) {
2024                 if (itA->node->type == ID_OB) {
2025                         if (itA->node->lasttime != curtime) {
2026                                 itA->lay = flush_layer_node(sce, itA->node, curtime);  // lay is only set once for each relation
2027                         }
2028                         else itA->lay = itA->node->lay;
2029                         
2030                         node->lay |= itA->lay;
2031                 }
2032         }
2033
2034         return node->lay;
2035 }
2036
2037 /* node was checked to have lasttime != curtime, and is of type ID_OB */
2038 static void flush_pointcache_reset(Scene *scene, DagNode *node, int curtime, int reset)
2039 {
2040         Main *bmain = G.main;
2041         DagAdjList *itA;
2042         Object *ob;
2043         
2044         node->lasttime = curtime;
2045         
2046         for (itA = node->child; itA; itA = itA->next) {
2047                 if (itA->node->type == ID_OB) {
2048                         if (itA->node->lasttime != curtime) {
2049                                 ob = (Object *)(itA->node->ob);
2050
2051                                 if (reset || (ob->recalc & OB_RECALC_ALL)) {
2052                                         if (BKE_ptcache_object_reset(scene, ob, PTCACHE_RESET_DEPSGRAPH)) {
2053                                                 ob->recalc |= OB_RECALC_DATA;
2054                                                 lib_id_recalc_data_tag(bmain, &ob->id);
2055                                         }
2056
2057                                         flush_pointcache_reset(scene, itA->node, curtime, 1);
2058                                 }
2059                                 else
2060                                         flush_pointcache_reset(scene, itA->node, curtime, 0);
2061                         }
2062                 }
2063         }
2064 }
2065
2066 /* flush layer flags to dependencies */
2067 static void dag_scene_flush_layers(Scene *sce, int lay)
2068 {
2069         DagNode *node, *firstnode;
2070         DagAdjList *itA;
2071         Base *base;
2072         int lasttime;
2073
2074         firstnode = sce->theDag->DagNode.first;  // always scene node
2075
2076         for (itA = firstnode->child; itA; itA = itA->next)
2077                 itA->lay = 0;
2078
2079         sce->theDag->time++;    // so we know which nodes were accessed
2080         lasttime = sce->theDag->time;
2081
2082         /* update layer flags in nodes */
2083         for (base = sce->base.first; base; base = base->next) {
2084                 node = dag_get_node(sce->theDag, base->object);
2085                 node->scelay = base->object->lay;
2086         }
2087
2088         /* ensure cameras are set as if they are on a visible layer, because
2089          * they ared still used for rendering or setting the camera view
2090          *
2091          * XXX, this wont work for local view / unlocked camera's */
2092         if (sce->camera) {
2093                 node = dag_get_node(sce->theDag, sce->camera);
2094                 node->scelay |= lay;
2095         }
2096
2097 #ifdef DURIAN_CAMERA_SWITCH
2098         {
2099                 TimeMarker *m;
2100
2101                 for (m = sce->markers.first; m; m = m->next) {
2102                         if (m->camera) {
2103                                 node = dag_get_node(sce->theDag, m->camera);
2104                                 node->scelay |= lay;
2105                         }
2106                 }
2107         }
2108 #endif
2109
2110         /* flush layer nodes to dependencies */
2111         for (itA = firstnode->child; itA; itA = itA->next)
2112                 if (itA->node->lasttime != lasttime && itA->node->type == ID_OB)
2113                         flush_layer_node(sce, itA->node, lasttime);
2114 }
2115
2116 static void dag_tag_renderlayers(Scene *sce, unsigned int lay)
2117 {
2118         if (sce->nodetree) {
2119                 bNode *node;
2120                 Base *base;
2121                 unsigned int lay_changed = 0;
2122                 
2123                 for (base = sce->base.first; base; base = base->next)
2124                         if (base->lay & lay)
2125                                 if (base->object->recalc)
2126                                         lay_changed |= base->lay;
2127                         
2128                 for (node = sce->nodetree->nodes.first; node; node = node->next) {
2129                         if (node->id == (ID *)sce) {
2130                                 SceneRenderLayer *srl = BLI_findlink(&sce->r.layers, node->custom1);
2131                                 if (srl && (srl->lay & lay_changed))
2132                                         nodeUpdate(sce->nodetree, node);
2133                         }
2134                 }
2135         }
2136 }
2137
2138 /* flushes all recalc flags in objects down the dependency tree */
2139 void DAG_scene_flush_update(Main *bmain, Scene *sce, unsigned int lay, const short time)
2140 {
2141         DagNode *firstnode;
2142         DagAdjList *itA;
2143         Object *ob;
2144         int lasttime;
2145         
2146         if (sce->theDag == NULL) {
2147                 printf("DAG zero... not allowed to happen!\n");
2148                 DAG_scene_sort(bmain, sce);
2149         }
2150         
2151         firstnode = sce->theDag->DagNode.first;  // always scene node
2152
2153         /* first we flush the layer flags */
2154         dag_scene_flush_layers(sce, lay);
2155
2156         /* then we use the relationships + layer info to flush update events */
2157         sce->theDag->time++;    // so we know which nodes were accessed
2158         lasttime = sce->theDag->time;
2159         for (itA = firstnode->child; itA; itA = itA->next)
2160                 if (itA->node->lasttime != lasttime && itA->node->type == ID_OB)
2161                         flush_update_node(itA->node, lay, lasttime);
2162
2163         /* if update is not due to time change, do pointcache clears */
2164         if (!time) {
2165                 sce->theDag->time++;    // so we know which nodes were accessed
2166                 lasttime = sce->theDag->time;
2167                 for (itA = firstnode->child; itA; itA = itA->next) {
2168                         if (itA->node->lasttime != lasttime && itA->node->type == ID_OB) {
2169                                 ob = (Object *)(itA->node->ob);
2170
2171                                 if (ob->recalc & OB_RECALC_ALL) {
2172                                         if (BKE_ptcache_object_reset(sce, ob, PTCACHE_RESET_DEPSGRAPH)) {
2173                                                 ob->recalc |= OB_RECALC_DATA;
2174                                                 lib_id_recalc_data_tag(bmain, &ob->id);
2175                                         }
2176
2177                                         flush_pointcache_reset(sce, itA->node, lasttime, 1);
2178                                 }
2179                                 else
2180                                         flush_pointcache_reset(sce, itA->node, lasttime, 0);
2181                         }
2182                 }
2183         }
2184         
2185         dag_tag_renderlayers(sce, lay);
2186 }
2187
2188 static int object_modifiers_use_time(Object *ob)
2189 {
2190         ModifierData *md;
2191         
2192         /* check if a modifier in modifier stack needs time input */
2193         for (md = ob->modifiers.first; md; md = md->next)
2194                 if (modifier_dependsOnTime(md))
2195                         return 1;
2196         
2197         /* check whether any modifiers are animated */
2198         if (ob->adt) {
2199                 AnimData *adt = ob->adt;
2200                 FCurve *fcu;
2201                 
2202                 /* action - check for F-Curves with paths containing 'modifiers[' */
2203                 if (adt->action) {
2204                         for (fcu = adt->action->curves.first; fcu; fcu = fcu->next) {
2205                                 if (fcu->rna_path && strstr(fcu->rna_path, "modifiers["))
2206                                         return 1;
2207                         }
2208                 }
2209                 
2210                 /* This here allows modifier properties to get driven and still update properly
2211                  *
2212                  * Workaround to get [#26764] (e.g. subsurf levels not updating when animated/driven)
2213                  * working, without the updating problems ([#28525] [#28690] [#28774] [#28777]) caused
2214                  * by the RNA updates cache introduced in r.38649
2215                  */
2216                 for (fcu = adt->drivers.first; fcu; fcu = fcu->next) {
2217                         if (fcu->rna_path && strstr(fcu->rna_path, "modifiers["))
2218                                 return 1;
2219                 }
2220                 
2221                 /* XXX: also, should check NLA strips, though for now assume that nobody uses
2222                  * that and we can omit that for performance reasons... */
2223         }
2224         
2225         return 0;
2226 }
2227
2228 static short animdata_use_time(AnimData *adt)
2229 {
2230         NlaTrack *nlt;
2231         
2232         if (adt == NULL) return 0;
2233         
2234         /* check action - only if assigned, and it has anim curves */
2235         if (adt->action && adt->action->curves.first)
2236                 return 1;
2237         
2238         /* check NLA tracks + strips */
2239         for (nlt = adt->nla_tracks.first; nlt; nlt = nlt->next) {
2240                 if (nlt->strips.first)
2241                         return 1;
2242         }
2243         
2244         /* If we have drivers, more likely than not, on a frame change
2245          * they'll need updating because their owner changed
2246          * 
2247          * This is kindof a hack to get around a whole host of problems
2248          * involving drivers using non-object datablock data (which the 
2249          * depsgraph currently has no way of representing let alone correctly
2250          * dependency sort+tagging). By doing this, at least we ensure that 
2251          * some commonly attempted drivers (such as scene -> current frame;
2252          * see "Driver updates fail" thread on Bf-committers dated July 2)
2253          * will work correctly, and that other non-object datablocks will have
2254          * their drivers update at least on frame change.
2255          *
2256          * -- Aligorith, July 4 2011
2257          */
2258         if (adt->drivers.first)
2259                 return 1;
2260         
2261         return 0;
2262 }
2263
2264 static void dag_object_time_update_flags(Object *ob)
2265 {
2266         if (ob->constraints.first) {
2267                 bConstraint *con;
2268                 for (con = ob->constraints.first; con; con = con->next) {
2269                         bConstraintTypeInfo *cti = constraint_get_typeinfo(con);
2270                         ListBase targets = {NULL, NULL};
2271                         bConstraintTarget *ct;
2272                         
2273                         if (cti) {
2274                                 /* special case for camera tracking -- it doesn't use targets to define relations */
2275                                 if (ELEM3(cti->type, CONSTRAINT_TYPE_FOLLOWTRACK, CONSTRAINT_TYPE_CAMERASOLVER, CONSTRAINT_TYPE_OBJECTSOLVER)) {
2276                                         ob->recalc |= OB_RECALC_OB;
2277                                 }
2278                                 else if (cti->get_constraint_targets) {
2279                                         cti->get_constraint_targets(con, &targets);
2280                                         
2281                                         for (ct = targets.first; ct; ct = ct->next) {
2282                                                 if (ct->tar) {
2283                                                         ob->recalc |= OB_RECALC_OB;
2284                                                         break;
2285                                                 }
2286                                         }
2287                                         
2288                                         if (cti->flush_constraint_targets)
2289                                                 cti->flush_constraint_targets(con, &targets, 1);
2290                                 }
2291                                 
2292                         }
2293                 }
2294         }
2295         
2296         if (ob->parent) {
2297                 /* motion path or bone child */
2298                 if (ob->parent->type == OB_CURVE || ob->parent->type == OB_ARMATURE) ob->recalc |= OB_RECALC_OB;
2299         }
2300         
2301 #if 0 // XXX old animation system
2302         if (ob->nlastrips.first) {
2303                 if (ob->dup_group) {
2304                         bActionStrip *strip;
2305                         /* this case is for groups with nla, whilst nla target has no action or nla */
2306                         for (strip = ob->nlastrips.first; strip; strip = strip->next) {
2307                                 if (strip->object)
2308                                         strip->object->recalc |= OB_RECALC_ALL;
2309                         }
2310                 }
2311         }
2312 #endif // XXX old animation system
2313         
2314         if (animdata_use_time(ob->adt)) {
2315                 ob->recalc |= OB_RECALC_OB;
2316                 ob->adt->recalc |= ADT_RECALC_ANIM;
2317         }
2318         
2319         if ((ob->adt) && (ob->type == OB_ARMATURE)) ob->recalc |= OB_RECALC_DATA;
2320         
2321         if (object_modifiers_use_time(ob)) ob->recalc |= OB_RECALC_DATA;
2322         if ((ob->pose) && (ob->pose->flag & POSE_CONSTRAINTS_TIMEDEPEND)) ob->recalc |= OB_RECALC_DATA;
2323         
2324         {
2325                 AnimData *adt = BKE_animdata_from_id((ID *)ob->data);
2326                 Mesh *me;
2327                 Curve *cu;
2328                 Lattice *lt;
2329                 
2330                 switch (ob->type) {
2331                         case OB_MESH:
2332                                 me = ob->data;
2333                                 if (me->key) {
2334                                         if (!(ob->shapeflag & OB_SHAPE_LOCK)) {
2335                                                 ob->recalc |= OB_RECALC_DATA;
2336                                         }
2337                                 }
2338                                 if (ob->particlesystem.first)
2339                                         ob->recalc |= OB_RECALC_DATA;
2340                                 break;
2341                         case OB_CURVE:
2342                         case OB_SURF:
2343                                 cu = ob->data;
2344                                 if (cu->key) {
2345                                         if (!(ob->shapeflag & OB_SHAPE_LOCK)) {
2346                                                 ob->recalc |= OB_RECALC_DATA;
2347                                         }
2348                                 }
2349                                 break;
2350                         case OB_FONT:
2351                                 cu = ob->data;
2352                                 if (cu->nurb.first == NULL && cu->str && cu->vfont)
2353                                         ob->recalc |= OB_RECALC_DATA;
2354                                 break;
2355                         case OB_LATTICE:
2356                                 lt = ob->data;
2357                                 if (lt->key) {
2358                                         if (!(ob->shapeflag & OB_SHAPE_LOCK)) {
2359                                                 ob->recalc |= OB_RECALC_DATA;
2360                                         }
2361                                 }
2362                                 break;
2363                         case OB_MBALL:
2364                                 if (ob->transflag & OB_DUPLI) ob->recalc |= OB_RECALC_DATA;
2365                                 break;
2366                 }
2367                 
2368                 if (animdata_use_time(adt)) {
2369                         ob->recalc |= OB_RECALC_DATA;
2370                         adt->recalc |= ADT_RECALC_ANIM;
2371                 }
2372
2373                 if (ob->particlesystem.first) {
2374                         ParticleSystem *psys = ob->particlesystem.first;
2375
2376                         for (; psys; psys = psys->next) {
2377                                 if (psys_check_enabled(ob, psys)) {
2378                                         ob->recalc |= OB_RECALC_DATA;
2379                                         break;
2380                                 }
2381                         }
2382                 }
2383         }               
2384
2385         if (ob->recalc & OB_RECALC_OB)
2386                 lib_id_recalc_tag(G.main, &ob->id);
2387         if (ob->recalc & OB_RECALC_DATA)
2388                 lib_id_recalc_data_tag(G.main, &ob->id);
2389
2390 }
2391 /* flag all objects that need recalc, for changes in time for example */
2392 /* do_time: make this optional because undo resets objects to their animated locations without this */
2393 void DAG_scene_update_flags(Main *bmain, Scene *scene, unsigned int lay, const short do_time)
2394 {
2395         Base *base;
2396         Object *ob;
2397         Group *group;
2398         GroupObject *go;
2399         Scene *sce_iter;
2400
2401         /* set ob flags where animated systems are */
2402         for (SETLOOPER(scene, sce_iter, base)) {
2403                 ob = base->object;
2404
2405                 if (do_time) {
2406                         /* now if DagNode were part of base, the node->lay could be checked... */
2407                         /* we do all now, since the scene_flush checks layers and clears recalc flags even */
2408                         dag_object_time_update_flags(ob);
2409                 }
2410
2411                 /* handled in next loop */
2412                 if (ob->dup_group)
2413                         ob->dup_group->id.flag |= LIB_DOIT;
2414         }
2415
2416         if (do_time) {
2417                 /* we do groups each once */
2418                 for (group = bmain->group.first; group; group = group->id.next) {
2419                         if (group->id.flag & LIB_DOIT) {
2420                                 for (go = group->gobject.first; go; go = go->next) {
2421                                         dag_object_time_update_flags(go->ob);
2422                                 }
2423                         }
2424                 }
2425         }
2426
2427         for (sce_iter = scene; sce_iter; sce_iter = sce_iter->set)
2428                 DAG_scene_flush_update(bmain, sce_iter, lay, 1);
2429         
2430         if (do_time) {
2431                 /* test: set time flag, to disable baked systems to update */
2432                 for (SETLOOPER(scene, sce_iter, base)) {
2433                         ob = base->object;
2434                         if (ob->recalc)
2435                                 ob->recalc |= OB_RECALC_TIME;
2436                 }
2437
2438                 /* hrmf... an exception to look at once, for invisible camera object we do it over */
2439                 if (scene->camera)
2440                         dag_object_time_update_flags(scene->camera);
2441         }
2442
2443         /* and store the info in groupobject */
2444         for (group = bmain->group.first; group; group = group->id.next) {
2445                 if (group->id.flag & LIB_DOIT) {
2446                         for (go = group->gobject.first; go; go = go->next) {
2447                                 go->recalc = go->ob->recalc;
2448                                 // printf("ob %s recalc %d\n", go->ob->id.name, go->recalc);
2449                         }
2450                         group->id.flag &= ~LIB_DOIT;
2451                 }
2452         }
2453         
2454 }
2455
2456 static void dag_current_scene_layers(Main *bmain, Scene **sce, unsigned int *lay)
2457 {
2458         wmWindowManager *wm;
2459         wmWindow *win;
2460
2461         /* only one scene supported currently, making more scenes work
2462          * correctly requires changes beyond just the dependency graph */
2463
2464         *sce = NULL;
2465         *lay = 0;
2466
2467         if ((wm = bmain->wm.first)) {
2468                 /* if we have a windowmanager, look into windows */
2469                 for (win = wm->windows.first; win; win = win->next) {
2470                         if (win->screen) {
2471                                 if (*sce == NULL) *sce = win->screen->scene;
2472                                 *lay |= BKE_screen_visible_layers(win->screen, win->screen->scene);
2473                         }
2474                 }
2475         }
2476         else {
2477                 /* if not, use the first sce */
2478                 *sce = bmain->scene.first;
2479                 if (*sce) *lay = (*sce)->lay;
2480
2481                 /* XXX for background mode, we should get the scene
2482                  * from somewhere, for the -S option, but it's in
2483                  * the context, how to get it here? */
2484         }
2485 }
2486
2487 void DAG_ids_flush_update(Main *bmain, int time)
2488 {
2489         Scene *sce;
2490         unsigned int lay;
2491
2492         dag_current_scene_layers(bmain, &sce, &lay);
2493
2494         if (sce)
2495                 DAG_scene_flush_update(bmain, sce, lay, time);
2496 }
2497
2498 void DAG_on_visible_update(Main *bmain, const short do_time)
2499 {
2500         Scene *scene;
2501         Base *base;
2502         Object *ob;
2503         Group *group;
2504         GroupObject *go;
2505         DagNode *node;
2506         unsigned int lay, oblay;
2507
2508         dag_current_scene_layers(bmain, &scene, &lay);
2509
2510         if (scene && scene->theDag) {
2511                 Scene *sce_iter;
2512                 /* derivedmeshes and displists are not saved to file so need to be
2513                  * remade, tag them so they get remade in the scene update loop,
2514                  * note armature poses or object matrices are preserved and do not
2515                  * require updates, so we skip those */
2516                 dag_scene_flush_layers(scene, lay);
2517
2518                 for (SETLOOPER(scene, sce_iter, base)) {
2519                         ob = base->object;
2520                         node = (sce_iter->theDag) ? dag_get_node(sce_iter->theDag, ob) : NULL;
2521                         oblay = (node) ? node->lay : ob->lay;
2522
2523                         if ((oblay & lay) & ~scene->lay_updated) {
2524                                 if (ELEM6(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_MBALL, OB_LATTICE))
2525                                         ob->recalc |= OB_RECALC_DATA;
2526                                 if (ob->dup_group) 
2527                                         ob->dup_group->id.flag |= LIB_DOIT;
2528                         }
2529                 }
2530
2531                 for (group = bmain->group.first; group; group = group->id.next) {
2532                         if (group->id.flag & LIB_DOIT) {
2533                                 for (go = group->gobject.first; go; go = go->next) {
2534                                         if (ELEM6(go->ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_MBALL, OB_LATTICE))
2535                                                 go->ob->recalc |= OB_RECALC_DATA;
2536                                         if (go->ob->proxy_from)
2537                                                 go->ob->recalc |= OB_RECALC_OB;
2538                                 }
2539                                 
2540                                 group->id.flag &= ~LIB_DOIT;
2541                         }
2542                 }
2543
2544                 /* now tag update flags, to ensure deformers get calculated on redraw */
2545                 DAG_scene_update_flags(bmain, scene, lay, do_time);
2546                 scene->lay_updated |= lay;
2547         }
2548
2549         /* hack to get objects updating on layer changes */
2550         DAG_id_type_tag(bmain, ID_OB);
2551
2552         /* so masks update on load */
2553         if (bmain->mask.first) {
2554                 Mask *mask;
2555
2556                 for (mask = bmain->mask.first; mask; mask = mask->id.next) {
2557                         DAG_id_tag_update(&mask->id, 0);
2558                 }
2559         }
2560 }
2561
2562 static void dag_id_flush_update__isDependentTexture(void *userData, Object *UNUSED(ob), ID **idpoin)
2563 {
2564         struct { ID *id; int is_dependent; } *data = userData;
2565         
2566         if (*idpoin && GS((*idpoin)->name) == ID_TE) {
2567                 if (data->id == (*idpoin))
2568                         data->is_dependent = 1;
2569         }
2570 }
2571
2572 static void dag_id_flush_update(Scene *sce, ID *id)
2573 {
2574         Main *bmain = G.main;
2575         Object *obt, *ob = NULL;
2576         short idtype;
2577
2578         /* here we flush a few things before actual scene wide flush, mostly
2579          * due to only objects and not other datablocks being in the depsgraph */
2580
2581         /* set flags & pointcache for object */
2582         if (GS(id->name) == ID_OB) {
2583                 ob = (Object *)id;
2584                 BKE_ptcache_object_reset(sce, ob, PTCACHE_RESET_DEPSGRAPH);
2585
2586                 if (ob->recalc & OB_RECALC_DATA) {
2587                         /* all users of this ob->data should be checked */
2588                         id = ob->data;
2589
2590                         /* no point in trying in this cases */
2591                         if (id && id->us <= 1) {
2592                                 dag_editors_id_update(bmain, id);
2593                                 id = NULL;
2594                         }
2595                 }
2596         }
2597
2598         /* set flags & pointcache for object data */
2599         if (id) {
2600                 idtype = GS(id->name);
2601
2602
2603                 if (OB_DATA_SUPPORT_ID(idtype)) {
2604                         for (obt = bmain->object.first; obt; obt = obt->id.next) {
2605                                 if (!(ob && obt == ob) && obt->data == id) {
2606                                         obt->recalc |= OB_RECALC_DATA;
2607                                         lib_id_recalc_data_tag(bmain, &obt->id);
2608                                         BKE_ptcache_object_reset(sce, obt, PTCACHE_RESET_DEPSGRAPH);
2609                                 }
2610                         }
2611                 }
2612                 
2613                 /* set flags based on textures - can influence depgraph via modifiers */
2614                 if (idtype == ID_TE) {
2615                         for (obt = bmain->object.first; obt; obt = obt->id.next) {
2616                                 struct { ID *id; int is_dependent; } data;
2617                                 data.id = id;
2618                                 data.is_dependent = 0;
2619
2620                                 modifiers_foreachIDLink(obt, dag_id_flush_update__isDependentTexture, &data);
2621                                 if (data.is_dependent) {
2622                                         obt->recalc |= OB_RECALC_DATA;
2623                                         lib_id_recalc_data_tag(bmain, &obt->id);
2624                                 }
2625
2626                                 /* particle settings can use the texture as well */
2627                                 if (obt->particlesystem.first) {
2628                                         ParticleSystem *psys = obt->particlesystem.first;
2629                                         MTex **mtexp, *mtex;
2630                                         int a;
2631                                         for (; psys; psys = psys->next) {
2632                                                 mtexp = psys->part->mtex;
2633                                                 for (a = 0; a < MAX_MTEX; a++, mtexp++) {
2634                                                         mtex = *mtexp;
2635                                                         if (mtex && mtex->tex == (Tex *)id) {
2636                                                                 obt->recalc |= OB_RECALC_DATA;
2637                                                                 lib_id_recalc_data_tag(bmain, &obt->id);
2638
2639                                                                 if (mtex->mapto & PAMAP_INIT)
2640                                                                         psys->recalc |= PSYS_RECALC_RESET;
2641                                                                 if (mtex->mapto & PAMAP_CHILD)
2642                                                                         psys->recalc |= PSYS_RECALC_CHILD;
2643
2644                                                                 BKE_ptcache_object_reset(sce, obt, PTCACHE_RESET_DEPSGRAPH);
2645                                                         }
2646                                                 }
2647                                         }
2648                                 }
2649                         }
2650                 }
2651                 
2652                 /* set flags based on ShapeKey */
2653                 if (idtype == ID_KE) {
2654                         for (obt = bmain->object.first; obt; obt = obt->id.next) {
2655                                 Key *key = BKE_key_from_object(obt);
2656                                 if (!(ob && obt == ob) && ((ID *)key == id)) {
2657                                         obt->flag |= (OB_RECALC_OB | OB_RECALC_DATA);
2658                                         lib_id_recalc_tag(bmain, &obt->id);
2659                                         lib_id_recalc_data_tag(bmain, &obt->id);
2660                                         BKE_ptcache_object_reset(sce, obt, PTCACHE_RESET_DEPSGRAPH);
2661                                 }
2662                         }
2663                 }
2664                 
2665                 /* set flags based on particle settings */
2666                 if (idtype == ID_PA) {
2667                         ParticleSystem *psys;
2668                         for (obt = bmain->object.first; obt; obt = obt->id.next)
2669                                 for (psys = obt->particlesystem.first; psys; psys = psys->next)
2670                                         if (&psys->part->id == id)
2671                                                 BKE_ptcache_object_reset(sce, obt, PTCACHE_RESET_DEPSGRAPH);
2672                 }
2673
2674                 if (idtype == ID_MC) {
2675                         MovieClip *clip = (MovieClip *) id;
2676
2677                         BKE_tracking_dopesheet_tag_update(&clip->tracking);
2678
2679                         for (obt = bmain->object.first; obt; obt = obt->id.next) {
2680                                 bConstraint *con;
2681                                 for (con = obt->constraints.first; con; con = con->next) {
2682                                         bConstraintTypeInfo *cti = constraint_get_typeinfo(con);
2683                                         if (ELEM3(cti->type, CONSTRAINT_TYPE_FOLLOWTRACK, CONSTRAINT_TYPE_CAMERASOLVER,
2684                                                   CONSTRAINT_TYPE_OBJECTSOLVER))
2685                                         {
2686                                                 obt->recalc |= OB_RECALC_OB;
2687                                                 break;
2688                                         }
2689                                 }
2690                         }
2691
2692                         if (sce->nodetree) {
2693                                 bNode *node;
2694
2695                                 for (node = sce->nodetree->nodes.first; node; node = node->next) {
2696                                         if (node->id == id) {
2697                                                 nodeUpdate(sce->nodetree, node);
2698                                         }
2699                                 }
2700                         }
2701                 }
2702
2703                 if (idtype == ID_MSK) {
2704                         if (sce->nodetree) {
2705                                 bNode *node;
2706
2707                                 for (node = sce->nodetree->nodes.first; node; node = node->next) {
2708                                         if (node->id == id) {
2709                                                 nodeUpdate(sce->nodetree, node);
2710                                         }
2711                                 }
2712                         }
2713                 }
2714
2715                 /* camera's matrix is used to orient reconstructed stuff,
2716                  * so it should happen tracking-related constraints recalculation
2717                  * when camera is changing (sergey) */
2718                 if (sce->camera && &sce->camera->id == id) {
2719                         MovieClip *clip = BKE_object_movieclip_get(sce, sce->camera, 1);
2720
2721                         if (clip)
2722                                 dag_id_flush_update(sce, &clip->id);
2723                 }
2724
2725                 /* update editors */
2726                 dag_editors_id_update(bmain, id);
2727         }
2728 }
2729
2730 void DAG_ids_flush_tagged(Main *bmain)
2731 {
2732         ListBase *lbarray[MAX_LIBARRAY];
2733         Scene *sce;
2734         unsigned int lay;
2735         int a, do_flush = FALSE;
2736
2737         dag_current_scene_layers(bmain, &sce, &lay);
2738
2739         if (!sce || !sce->theDag)
2740                 return;
2741
2742         /* loop over all ID types */
2743         a  = set_listbasepointers(bmain, lbarray);
2744
2745         while (a--) {
2746                 ListBase *lb = lbarray[a];
2747                 ID *id = lb->first;
2748
2749                 /* we tag based on first ID type character to avoid 
2750                  * looping over all ID's in case there are no tags */
2751                 if (id && bmain->id_tag_update[id->name[0]]) {
2752                         for (; id; id = id->next) {
2753                                 if (id->flag & (LIB_ID_RECALC | LIB_ID_RECALC_DATA)) {
2754                                         dag_id_flush_update(sce, id);
2755                                         do_flush = TRUE;
2756                                 }
2757                         }
2758                 }
2759         }
2760
2761         /* flush changes to other objects */
2762         if (do_flush)
2763                 DAG_scene_flush_update(bmain, sce, lay, 0);
2764 }
2765
2766 void DAG_ids_check_recalc(Main *bmain, Scene *scene, int time)
2767 {
2768         ListBase *lbarray[MAX_LIBARRAY];
2769         int a, updated = 0;
2770
2771         /* loop over all ID types */
2772         a  = set_listbasepointers(bmain, lbarray);
2773
2774         while (a--) {
2775                 ListBase *lb = lbarray[a];
2776                 ID *id = lb->first;
2777
2778                 /* we tag based on first ID type character to avoid 
2779                  * looping over all ID's in case there are no tags */
2780                 if (id && bmain->id_tag_update[id->name[0]]) {
2781                         updated = 1;
2782                         break;
2783                 }
2784         }
2785
2786         dag_editors_scene_update(bmain, scene, (updated || time));
2787 }
2788
2789 void DAG_ids_clear_recalc(Main *bmain)
2790 {
2791         ListBase *lbarray[MAX_LIBARRAY];
2792         int a;
2793
2794         /* loop over all ID types */
2795         a  = set_listbasepointers(bmain, lbarray);
2796
2797         while (a--) {
2798                 ListBase *lb = lbarray[a];
2799                 ID *id = lb->first;
2800
2801                 /* we tag based on first ID type character to avoid 
2802                  * looping over all ID's in case there are no tags */
2803                 if (id && bmain->id_tag_update[id->name[0]]) {
2804                         for (; id; id = id->next)
2805                                 if (id->flag & (LIB_ID_RECALC | LIB_ID_RECALC_DATA))
2806                                         id->flag &= ~(LIB_ID_RECALC | LIB_ID_RECALC_DATA);
2807                 }
2808         }
2809
2810         memset(bmain->id_tag_update, 0, sizeof(bmain->id_tag_update));
2811 }
2812
2813 void DAG_id_tag_update(ID *id, short flag)
2814 {
2815         Main *bmain = G.main;
2816
2817         if (id == NULL) return;
2818         
2819         /* tag ID for update */
2820         if (flag) {
2821                 if (flag & OB_RECALC_OB)
2822                         lib_id_recalc_tag(bmain, id);
2823                 if (flag & (OB_RECALC_DATA | PSYS_RECALC))
2824                         lib_id_recalc_data_tag(bmain, id);
2825         }
2826         else
2827                 lib_id_recalc_tag(bmain, id);
2828
2829         /* flag is for objects and particle systems */
2830         if (flag) {
2831                 Object *ob;
2832                 short idtype = GS(id->name);
2833
2834                 if (idtype == ID_OB) {
2835                         /* only quick tag */
2836                         ob = (Object *)id;
2837                         ob->recalc |= (flag & OB_RECALC_ALL);
2838                 }
2839                 else if (idtype == ID_PA) {
2840                         ParticleSystem *psys;
2841                         /* this is weak still, should be done delayed as well */
2842                         for (ob = bmain->object.first; ob; ob = ob->id.next) {
2843                                 for (psys = ob->particlesystem.first; psys; psys = psys->next) {
2844                                         if (&psys->part->id == id) {
2845                                                 ob->recalc |= (flag & OB_RECALC_ALL);
2846                                                 psys->recalc |= (flag & PSYS_RECALC);
2847                                                 lib_id_recalc_tag(bmain, &ob->id);
2848                                                 lib_id_recalc_data_tag(bmain, &ob->id);
2849                                         }
2850                                 }
2851                         }
2852                 }
2853                 else if (idtype == ID_VF) {
2854                         /* this is weak still, should be done delayed as well */
2855                         for (ob = bmain->object.first; ob; ob = ob->id.next) {
2856                                 if (ob->type == OB_FONT) {
2857                                         Curve *cu = ob->data;
2858
2859                                         if (ELEM4((struct VFont *)id, cu->vfont, cu->vfontb, cu->vfonti, cu->vfontbi)) {
2860                                                 ob->recalc |= (flag & OB_RECALC_ALL);
2861                                         }
2862                                 }
2863                         }
2864                 }
2865                 else {
2866                         /* disable because this is called on various ID types automatically.
2867                          * where printing warning is not useful. for now just ignore */
2868                         /* BLI_assert(!"invalid flag for this 'idtype'"); */
2869                 }
2870         }
2871 }
2872
2873 void DAG_id_type_tag(struct Main *bmain, short idtype)
2874 {
2875         bmain->id_tag_update[((char *)&idtype)[0]] = 1;
2876 }
2877
2878 int DAG_id_type_tagged(Main *bmain, short idtype)
2879 {
2880         return bmain->id_tag_update[((char *)&idtype)[0]];
2881 }
2882
2883 #if 0 // UNUSED
2884 /* recursively descends tree, each node only checked once */
2885 /* node is checked to be of type object */
2886 static int parent_check_node(DagNode *node, int curtime)
2887 {
2888         DagAdjList *itA;
2889         
2890         node->lasttime = curtime;
2891         
2892         if (node->color == DAG_GRAY)
2893                 return DAG_GRAY;
2894         
2895         for (itA = node->child; itA; itA = itA->next) {
2896                 if (itA->node->type == ID_OB) {
2897                         
2898                         if (itA->node->color == DAG_GRAY)
2899                                 return DAG_GRAY;
2900
2901                         /* descend if not done */
2902                         if (itA->node->lasttime != curtime) {
2903                                 itA->node->color = parent_check_node(itA->node, curtime);
2904                         
2905                                 if (itA->node->color == DAG_GRAY)
2906                                         return DAG_GRAY;
2907                         }
2908                 }
2909         }
2910         
2911         return DAG_WHITE;
2912 }
2913 #endif
2914
2915 /* ******************* DAG FOR ARMATURE POSE ***************** */
2916
2917 /* we assume its an armature with pose */
2918 void DAG_pose_sort(Object *ob)
2919 {
2920         bPose *pose = ob->pose;
2921         bPoseChannel *pchan;
2922         bConstraint *con;
2923         DagNode *node;
2924         DagNode *node2, *node3;
2925         DagNode *rootnode;
2926         DagForest *dag;
2927         DagNodeQueue *nqueue;