2 * ***** BEGIN GPL LICENSE BLOCK *****
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.
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.
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.
18 * The Original Code is Copyright (C) 2004 Blender Foundation.
19 * All rights reserved.
21 * Contributor(s): none yet.
23 * ***** END GPL LICENSE BLOCK *****
26 /** \file blender/blenkernel/intern/depsgraph.c
35 #include "MEM_guardedalloc.h"
38 # include "BLI_winstuff.h"
41 #include "BLI_utildefines.h"
42 #include "BLI_listbase.h"
43 #include "BLI_ghash.h"
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"
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"
66 #include "BKE_library.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 #include "BKE_utildefines.h"
80 #include "depsgraph_private.h"
82 /* Queue and stack operations for dag traversal
84 * the queue store a list of freenodes to avoid successive alloc/dealloc
87 DagNodeQueue *queue_create(int slots)
90 DagNodeQueueElem *elem;
93 queue = MEM_mallocN(sizeof(DagNodeQueue), "DAG queue");
94 queue->freenodes = MEM_mallocN(sizeof(DagNodeQueue), "DAG queue");
97 queue->first = queue->last = NULL;
98 elem = MEM_mallocN(sizeof(DagNodeQueueElem), "DAG queue elem3");
101 queue->freenodes->first = queue->freenodes->last = elem;
103 for (i = 1; i < slots; i++) {
104 elem = MEM_mallocN(sizeof(DagNodeQueueElem), "DAG queue elem4");
107 queue->freenodes->last->next = elem;
108 queue->freenodes->last = elem;
110 queue->freenodes->count = slots;
114 void queue_raz(DagNodeQueue *queue)
116 DagNodeQueueElem *elem;
119 if (queue->freenodes->last)
120 queue->freenodes->last->next = elem;
122 queue->freenodes->first = queue->freenodes->last = elem;
125 queue->freenodes->count++;
129 queue->freenodes->count++;
131 queue->freenodes->last = elem;
135 void queue_delete(DagNodeQueue *queue)
137 DagNodeQueueElem *elem;
138 DagNodeQueueElem *temp;
147 elem = queue->freenodes->first;
154 MEM_freeN(queue->freenodes);
158 /* insert in queue, remove in front */
159 void push_queue(DagNodeQueue *queue, DagNode *node)
161 DagNodeQueueElem *elem;
165 fprintf(stderr, "pushing null node\n");
168 /*fprintf(stderr, "BFS push : %s %d\n", ((ID *) node->ob)->name, queue->count);*/
170 elem = queue->freenodes->first;
172 queue->freenodes->first = elem->next;
173 if (queue->freenodes->last == elem) {
174 queue->freenodes->last = NULL;
175 queue->freenodes->first = NULL;
177 queue->freenodes->count--;
179 else { /* alllocating more */
180 elem = MEM_mallocN(sizeof(DagNodeQueueElem), "DAG queue elem1");
183 queue->freenodes->first = queue->freenodes->last = elem;
185 for (i = 1; i < DAGQUEUEALLOC; i++) {
186 elem = MEM_mallocN(sizeof(DagNodeQueueElem), "DAG queue elem2");
189 queue->freenodes->last->next = elem;
190 queue->freenodes->last = elem;
192 queue->freenodes->count = DAGQUEUEALLOC;
194 elem = queue->freenodes->first;
195 queue->freenodes->first = elem->next;
199 if (queue->last != NULL)
200 queue->last->next = elem;
202 if (queue->first == NULL) {
209 /* insert in front, remove in front */
210 void push_stack(DagNodeQueue *queue, DagNode *node)
212 DagNodeQueueElem *elem;
215 elem = queue->freenodes->first;
217 queue->freenodes->first = elem->next;
218 if (queue->freenodes->last == elem) {
219 queue->freenodes->last = NULL;
220 queue->freenodes->first = NULL;
222 queue->freenodes->count--;
224 else { /* alllocating more */
225 elem = MEM_mallocN(sizeof(DagNodeQueueElem), "DAG queue elem1");
228 queue->freenodes->first = queue->freenodes->last = elem;
230 for (i = 1; i < DAGQUEUEALLOC; i++) {
231 elem = MEM_mallocN(sizeof(DagNodeQueueElem), "DAG queue elem2");
234 queue->freenodes->last->next = elem;
235 queue->freenodes->last = elem;
237 queue->freenodes->count = DAGQUEUEALLOC;
239 elem = queue->freenodes->first;
240 queue->freenodes->first = elem->next;
242 elem->next = queue->first;
245 if (queue->last == NULL)
251 DagNode *pop_queue(DagNodeQueue *queue)
253 DagNodeQueueElem *elem;
258 queue->first = elem->next;
259 if (queue->last == elem) {
264 if (queue->freenodes->last)
265 queue->freenodes->last->next = elem;
266 queue->freenodes->last = elem;
267 if (queue->freenodes->first == NULL)
268 queue->freenodes->first = elem;
272 queue->freenodes->count++;
276 fprintf(stderr, "return null\n");
281 void *pop_ob_queue(struct DagNodeQueue *queue)
283 return(pop_queue(queue)->ob);
286 DagNode *get_top_node_queue(DagNodeQueue *queue)
288 return queue->first->node;
291 int queue_count(struct DagNodeQueue *queue)
297 DagForest *dag_init(void)
300 /* use callocN to init all zero */
301 forest = MEM_callocN(sizeof(DagForest), "DAG root");
305 /* isdata = object data... */
306 // XXX this needs to be extended to be more flexible (so that not only objects are evaluated via depsgraph)...
307 static void dag_add_driver_relation(AnimData *adt, DagForest *dag, DagNode *node, int isdata)
312 for (fcu = adt->drivers.first; fcu; fcu = fcu->next) {
313 ChannelDriver *driver = fcu->driver;
315 int isdata_fcu = (isdata) || (fcu->rna_path && strstr(fcu->rna_path, "modifiers["));
317 /* loop over variables to get the target relationships */
318 for (dvar = driver->variables.first; dvar; dvar = dvar->next) {
319 /* only used targets */
320 DRIVER_TARGETS_USED_LOOPER(dvar)
323 /* FIXME: other data types need to be added here so that they can work! */
324 if (GS(dtar->id->name) == ID_OB) {
325 Object *ob = (Object *)dtar->id;
327 /* normal channel-drives-channel */
328 node1 = dag_get_node(dag, dtar->id);
330 /* check if bone... */
331 if ((ob->type == OB_ARMATURE) &&
332 ( ((dtar->rna_path) && strstr(dtar->rna_path, "pose.bones[")) ||
333 ((dtar->flag & DTAR_FLAG_STRUCT_REF) && (dtar->pchan_name[0])) ))
335 dag_add_relation(dag, node1, node, isdata_fcu ? DAG_RL_DATA_DATA : DAG_RL_DATA_OB, "Driver");
337 /* check if ob data */
338 else if (dtar->rna_path && strstr(dtar->rna_path, "data."))
339 dag_add_relation(dag, node1, node, isdata_fcu ? DAG_RL_DATA_DATA : DAG_RL_DATA_OB, "Driver");
342 dag_add_relation(dag, node1, node, isdata_fcu ? DAG_RL_OB_DATA : DAG_RL_OB_OB, "Driver");
346 DRIVER_TARGETS_LOOPER_END
351 /* XXX: forward def for material driver handling... */
352 static void dag_add_material_driver_relations(DagForest *dag, DagNode *node, Material *ma);
354 /* recursive handling for material nodetree drivers */
355 static void dag_add_material_nodetree_driver_relations(DagForest *dag, DagNode *node, bNodeTree *ntree)
359 /* nodetree itself */
361 dag_add_driver_relation(ntree->adt, dag, node, 1);
364 /* nodetree's nodes... */
365 for (n = ntree->nodes.first; n; n = n->next) {
367 if (GS(n->id->name) == ID_MA) {
368 dag_add_material_driver_relations(dag, node, (Material *)n->id);
370 else if (n->type == NODE_GROUP) {
371 dag_add_material_nodetree_driver_relations(dag, node, (bNodeTree *)n->id);
377 /* recursive handling for material drivers */
378 static void dag_add_material_driver_relations(DagForest *dag, DagNode *node, Material *ma)
380 /* Prevent infinite recursion by checking (and tagging the material) as having been visited
381 * already (see build_dag()). This assumes ma->id.flag & LIB_DOIT isn't set by anything else
382 * in the meantime... [#32017]
384 if (ma->id.flag & LIB_DOIT)
387 ma->id.flag |= LIB_DOIT;
389 /* material itself */
391 dag_add_driver_relation(ma->adt, dag, node, 1);
396 //dag_add_texture_driver_relations(DagForest *dag, DagNode *node, ID *id);
398 /* material's nodetree */
400 dag_add_material_nodetree_driver_relations(dag, node, ma->nodetree);
404 static void dag_add_collision_field_relation(DagForest *dag, Scene *scene, Object *ob, DagNode *node)
409 /* would be nice to have a list of colliders here
410 * so for now walk all objects in scene check 'same layer rule' */
411 for (base = scene->base.first; base; base = base->next) {
412 if ((base->lay & ob->lay) && base->object->pd) {
413 Object *ob1 = base->object;
414 if ((ob1->pd->deflect || ob1->pd->forcefield) && (ob1 != ob)) {
415 node2 = dag_get_node(dag, ob1);
416 dag_add_relation(dag, node2, node, DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "Field Collision");
422 static void build_dag_object(DagForest *dag, DagNode *scenenode, Scene *scene, Object *ob, int mask)
429 ParticleSystem *psys;
432 node = dag_get_node(dag, ob);
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;
441 /* also build a custom data mask for dependencies that need certain layers */
442 node->customdata_mask = 0;
444 if (ob->type == OB_ARMATURE) {
449 for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
450 for (con = pchan->constraints.first; con; con = con->next) {
451 bConstraintTypeInfo *cti = constraint_get_typeinfo(con);
452 ListBase targets = {NULL, NULL};
453 bConstraintTarget *ct;
455 if (cti && cti->get_constraint_targets) {
456 cti->get_constraint_targets(con, &targets);
458 for (ct = targets.first; ct; ct = ct->next) {
459 if (ct->tar && ct->tar != ob) {
460 // fprintf(stderr, "armature %s target :%s\n", ob->id.name, target->id.name);
461 node3 = dag_get_node(dag, ct->tar);
463 if (ct->subtarget[0]) {
464 dag_add_relation(dag, node3, node, DAG_RL_OB_DATA | DAG_RL_DATA_DATA, cti->name);
465 if (ct->tar->type == OB_MESH)
466 node3->customdata_mask |= CD_MASK_MDEFORMVERT;
468 else if (ELEM3(con->type, CONSTRAINT_TYPE_FOLLOWPATH, CONSTRAINT_TYPE_CLAMPTO, CONSTRAINT_TYPE_SPLINEIK))
469 dag_add_relation(dag, node3, node, DAG_RL_DATA_DATA | DAG_RL_OB_DATA, cti->name);
471 dag_add_relation(dag, node3, node, DAG_RL_OB_DATA, cti->name);
475 if (cti->flush_constraint_targets)
476 cti->flush_constraint_targets(con, &targets, 1);
484 /* driver dependencies, nla modifiers */
485 #if 0 // XXX old animation system
486 if (ob->nlastrips.first) {
488 bActionChannel *chan;
489 for (strip = ob->nlastrips.first; strip; strip = strip->next) {
490 if (strip->modifiers.first) {
491 bActionModifier *amod;
492 for (amod = strip->modifiers.first; amod; amod = amod->next) {
494 node2 = dag_get_node(dag, amod->ob);
495 dag_add_relation(dag, node2, node, DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "NLA Strip Modifier");
501 #endif // XXX old animation system
503 dag_add_driver_relation(ob->adt, dag, node, (ob->type == OB_ARMATURE)); // XXX isdata arg here doesn't give an accurate picture of situation
505 key = ob_get_key(ob);
507 dag_add_driver_relation(key->adt, dag, node, 1);
509 if (ob->modifiers.first) {
512 for (md = ob->modifiers.first; md; md = md->next) {
513 ModifierTypeInfo *mti = modifierType_getInfo(md->type);
515 if (mti->updateDepgraph) mti->updateDepgraph(md, dag, scene, ob, node);
519 node2 = dag_get_node(dag, ob->parent);
521 switch (ob->partype) {
523 dag_add_relation(dag, node2, node, DAG_RL_DATA_DATA | DAG_RL_OB_OB, "Parent");
525 case PARVERT1: case PARVERT3:
526 dag_add_relation(dag, node2, node, DAG_RL_DATA_OB | DAG_RL_OB_OB, "Vertex Parent");
527 node2->customdata_mask |= CD_MASK_ORIGINDEX;
530 dag_add_relation(dag, node2, node, DAG_RL_DATA_OB | DAG_RL_OB_OB, "Bone Parent");
533 if (ob->parent->type == OB_LATTICE)
534 dag_add_relation(dag, node2, node, DAG_RL_DATA_DATA | DAG_RL_OB_OB, "Lattice Parent");
535 else if (ob->parent->type == OB_CURVE) {
536 Curve *cu = ob->parent->data;
537 if (cu->flag & CU_PATH)
538 dag_add_relation(dag, node2, node, DAG_RL_DATA_OB | DAG_RL_OB_OB, "Curve Parent");
540 dag_add_relation(dag, node2, node, DAG_RL_OB_OB, "Curve Parent");
543 dag_add_relation(dag, node2, node, DAG_RL_OB_OB, "Parent");
545 /* exception case: parent is duplivert */
546 if (ob->type == OB_MBALL && (ob->parent->transflag & OB_DUPLIVERTS)) {
547 dag_add_relation(dag, node2, node, DAG_RL_DATA_DATA | DAG_RL_OB_OB, "Duplivert");
553 node2 = dag_get_node(dag, ob->proxy);
554 dag_add_relation(dag, node, node2, DAG_RL_DATA_DATA | DAG_RL_OB_OB, "Proxy");
555 /* inverted relation, so addtoroot shouldn't be set to zero */
558 if (ob->transflag & OB_DUPLI) {
559 if ((ob->transflag & OB_DUPLIGROUP) && ob->dup_group) {
561 for (go = ob->dup_group->gobject.first; go; go = go->next) {
563 node2 = dag_get_node(dag, go->ob);
564 /* node2 changes node1, this keeps animations updated in groups?? not logical? */
565 dag_add_relation(dag, node2, node, DAG_RL_OB_OB, "Dupligroup");
571 /* softbody collision */
572 if ((ob->type == OB_MESH) || (ob->type == OB_CURVE) || (ob->type == OB_LATTICE)) {
573 if (modifiers_isModifierEnabled(ob, eModifierType_Softbody)
574 || modifiers_isModifierEnabled(ob, eModifierType_Cloth)
575 || modifiers_isModifierEnabled(ob, eModifierType_Smoke)
576 || modifiers_isModifierEnabled(ob, eModifierType_DynamicPaint)
577 || ob->particlesystem.first)
578 dag_add_collision_field_relation(dag, scene, ob, node); /* TODO: use effectorweight->group */
581 /* object data drivers */
583 AnimData *adt = BKE_animdata_from_id((ID *)ob->data);
585 dag_add_driver_relation(adt, dag, node, 1);
588 /* object type/data relationships */
592 Camera *cam = (Camera *)ob->data;
595 node2 = dag_get_node(dag, cam->dof_ob);
596 dag_add_relation(dag, node2, node, DAG_RL_OB_OB, "Camera DoF");
602 Object *mom = BKE_mball_basis_find(scene, ob);
605 node2 = dag_get_node(dag, mom);
606 dag_add_relation(dag, node, node2, DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "Metaball"); // mom depends on children!
613 Curve *cu = ob->data;
616 node2 = dag_get_node(dag, cu->bevobj);
617 dag_add_relation(dag, node2, node, DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "Curve Bevel");
620 node2 = dag_get_node(dag, cu->taperobj);
621 dag_add_relation(dag, node2, node, DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "Curve Taper");
623 if (ob->type == OB_FONT) {
624 if (cu->textoncurve) {
625 node2 = dag_get_node(dag, cu->textoncurve);
626 dag_add_relation(dag, node2, node, DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "Texture On Curve");
633 /* material drivers */
637 for (a = 1; a <= ob->totcol; a++) {
638 Material *ma = give_current_material(ob, a);
641 /* recursively figure out if there are drivers, and hook these up to this object */
642 dag_add_material_driver_relations(dag, node, ma);
648 psys = ob->particlesystem.first;
652 for (; psys; psys = psys->next) {
653 BoidRule *rule = NULL;
654 BoidState *state = NULL;
655 ParticleSettings *part = psys->part;
656 ListBase *effectors = NULL;
659 dag_add_relation(dag, node, node, DAG_RL_OB_DATA, "Particle-Object Relation");
661 if (!psys_check_enabled(ob, psys))
664 if (ELEM(part->phystype, PART_PHYS_KEYED, PART_PHYS_BOIDS)) {
665 ParticleTarget *pt = psys->targets.first;
667 for (; pt; pt = pt->next) {
668 if (pt->ob && BLI_findlink(&pt->ob->particlesystem, pt->psys - 1)) {
669 node2 = dag_get_node(dag, pt->ob);
670 dag_add_relation(dag, node2, node, DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "Particle Targets");
675 if (part->ren_as == PART_DRAW_OB && part->dup_ob) {
676 node2 = dag_get_node(dag, part->dup_ob);
677 /* note that this relation actually runs in the wrong direction, the problem
678 * is that dupli system all have this (due to parenting), and the render
679 * engine instancing assumes particular ordering of objects in list */
680 dag_add_relation(dag, node, node2, DAG_RL_OB_OB, "Particle Object Visualization");
681 if (part->dup_ob->type == OB_MBALL)
682 dag_add_relation(dag, node, node2, DAG_RL_DATA_DATA, "Particle Object Visualization");
685 if (part->ren_as == PART_DRAW_GR && part->dup_group) {
686 for (go = part->dup_group->gobject.first; go; go = go->next) {
687 node2 = dag_get_node(dag, go->ob);
688 dag_add_relation(dag, node2, node, DAG_RL_OB_OB, "Particle Group Visualization");
692 effectors = pdInitEffectors(scene, ob, psys, part->effector_weights);
695 for (eff = effectors->first; eff; eff = eff->next) {
697 node2 = dag_get_node(dag, eff->ob);
698 dag_add_relation(dag, node2, node, DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "Particle Field");
703 pdEndEffectors(&effectors);
706 for (state = part->boids->states.first; state; state = state->next) {
707 for (rule = state->rules.first; rule; rule = rule->next) {
708 Object *ruleob = NULL;
709 if (rule->type == eBoidRuleType_Avoid)
710 ruleob = ((BoidRuleGoalAvoid *)rule)->ob;
711 else if (rule->type == eBoidRuleType_FollowLeader)
712 ruleob = ((BoidRuleFollowLeader *)rule)->ob;
715 node2 = dag_get_node(dag, ruleob);
716 dag_add_relation(dag, node2, node, DAG_RL_OB_DATA, "Boid Rule");
724 /* object constraints */
725 for (con = ob->constraints.first; con; con = con->next) {
726 bConstraintTypeInfo *cti = constraint_get_typeinfo(con);
727 ListBase targets = {NULL, NULL};
728 bConstraintTarget *ct;
733 /* special case for camera tracking -- it doesn't use targets to define relations */
734 if (ELEM3(cti->type, CONSTRAINT_TYPE_FOLLOWTRACK, CONSTRAINT_TYPE_CAMERASOLVER, CONSTRAINT_TYPE_OBJECTSOLVER)) {
735 int depends_on_camera = 0;
737 if (cti->type == CONSTRAINT_TYPE_FOLLOWTRACK) {
738 bFollowTrackConstraint *data = (bFollowTrackConstraint *)con->data;
740 if ((data->clip || data->flag & FOLLOWTRACK_ACTIVECLIP) && data->track[0])
741 depends_on_camera = 1;
743 if (data->depth_ob) {
744 node2 = dag_get_node(dag, data->depth_ob);
745 dag_add_relation(dag, node2, node, DAG_RL_DATA_OB | DAG_RL_OB_OB, cti->name);
748 else if (cti->type == CONSTRAINT_TYPE_OBJECTSOLVER)
749 depends_on_camera = 1;
751 if (depends_on_camera && scene->camera) {
752 node2 = dag_get_node(dag, scene->camera);
753 dag_add_relation(dag, node2, node, DAG_RL_DATA_OB | DAG_RL_OB_OB, cti->name);
756 dag_add_relation(dag, scenenode, node, DAG_RL_SCENE, "Scene Relation");
759 else if (cti->get_constraint_targets) {
760 cti->get_constraint_targets(con, &targets);
762 for (ct = targets.first; ct; ct = ct->next) {
770 node2 = dag_get_node(dag, obt);
771 if (ELEM(con->type, CONSTRAINT_TYPE_FOLLOWPATH, CONSTRAINT_TYPE_CLAMPTO))
772 dag_add_relation(dag, node2, node, DAG_RL_DATA_OB | DAG_RL_OB_OB, cti->name);
774 if (ELEM3(obt->type, OB_ARMATURE, OB_MESH, OB_LATTICE) && (ct->subtarget[0])) {
775 dag_add_relation(dag, node2, node, DAG_RL_DATA_OB | DAG_RL_OB_OB, cti->name);
776 if (obt->type == OB_MESH)
777 node2->customdata_mask |= CD_MASK_MDEFORMVERT;
780 dag_add_relation(dag, node2, node, DAG_RL_OB_OB, cti->name);
785 if (cti->flush_constraint_targets)
786 cti->flush_constraint_targets(con, &targets, 1);
791 dag_add_relation(dag, scenenode, node, DAG_RL_SCENE, "Scene Relation");
794 DagForest *build_dag(Main *bmain, Scene *sce, short mask)
814 /* clear "LIB_DOIT" flag from all materials, to prevent infinite recursion problems later [#32017] */
815 tag_main_idcode(bmain, ID_MA, FALSE);
817 /* add base node for scene. scene is always the first node in DAG */
818 scenenode = dag_add_node(dag, sce);
820 /* add current scene objects */
821 for (base = sce->base.first; base; base = base->next) {
824 build_dag_object(dag, scenenode, sce, ob, mask);
826 build_dag_object(dag, scenenode, sce, ob->proxy, mask);
828 /* handled in next loop */
830 ob->dup_group->id.flag |= LIB_DOIT;
833 /* add groups used in current scene objects */
834 for (group = bmain->group.first; group; group = group->id.next) {
835 if (group->id.flag & LIB_DOIT) {
836 for (go = group->gobject.first; go; go = go->next) {
837 build_dag_object(dag, scenenode, sce, go->ob, mask);
839 group->id.flag &= ~LIB_DOIT;
843 /* Now all relations were built, but we need to solve 1 exceptional case;
844 * When objects have multiple "parents" (for example parent + constraint working on same object)
845 * the relation type has to be synced. One of the parents can change, and should give same event to child */
847 /* nodes were callocced, so we can use node->color for temporal storage */
848 for (node = sce->theDag->DagNode.first; node; node = node->next) {
849 if (node->type == ID_OB) {
850 for (itA = node->child; itA; itA = itA->next) {
851 if (itA->node->type == ID_OB) {
852 itA->node->color |= itA->type;
856 /* also flush custom data mask */
857 ((Object *)node->ob)->customdata_mask = node->customdata_mask;
860 /* now set relations equal, so that when only one parent changes, the correct recalcs are found */
861 for (node = sce->theDag->DagNode.first; node; node = node->next) {
862 if (node->type == ID_OB) {
863 for (itA = node->child; itA; itA = itA->next) {
864 if (itA->node->type == ID_OB) {
865 itA->type |= itA->node->color;
871 /* cycle detection and solving */
872 // solve_cycles(dag);
878 void free_forest(DagForest *Dag)
879 { /* remove all nodes and deps */
883 DagNode *itN = Dag->DagNode.first;
905 BLI_ghash_free(Dag->nodeHash, NULL, NULL);
906 Dag->nodeHash = NULL;
907 Dag->DagNode.first = NULL;
908 Dag->DagNode.last = NULL;
913 DagNode *dag_find_node(DagForest *forest, void *fob)
915 if (forest->nodeHash)
916 return BLI_ghash_lookup(forest->nodeHash, fob);
921 static int ugly_hack_sorry = 1; // prevent type check
922 static int dag_print_dependencies = 0; // debugging
924 /* no checking of existence, use dag_find_node first or dag_get_node */
925 DagNode *dag_add_node(DagForest *forest, void *fob)
929 node = MEM_callocN(sizeof(DagNode), "DAG node");
932 node->color = DAG_WHITE;
934 if (ugly_hack_sorry) node->type = GS(((ID *) fob)->name); // sorry, done for pose sorting
935 if (forest->numNodes) {
936 ((DagNode *) forest->DagNode.last)->next = node;
937 forest->DagNode.last = node;
941 forest->DagNode.last = node;
942 forest->DagNode.first = node;
943 forest->numNodes = 1;
946 if (!forest->nodeHash)
947 forest->nodeHash = BLI_ghash_ptr_new("dag_add_node gh");
948 BLI_ghash_insert(forest->nodeHash, fob, node);
954 DagNode *dag_get_node(DagForest *forest, void *fob)
958 node = dag_find_node(forest, fob);
960 node = dag_add_node(forest, fob);
966 DagNode *dag_get_sub_node(DagForest *forest, void *fob)
969 DagAdjList *mainchild, *prev = NULL;
971 mainchild = ((DagNode *) forest->DagNode.first)->child;
972 /* remove from first node (scene) adj list if present */
974 if (mainchild->node == fob) {
976 prev->next = mainchild->next;
977 MEM_freeN(mainchild);
981 ((DagNode *) forest->DagNode.first)->child = mainchild->next;
982 MEM_freeN(mainchild);
987 mainchild = mainchild->next;
989 node = dag_find_node(forest, fob);
991 node = dag_add_node(forest, fob);
995 static void dag_add_parent_relation(DagForest *UNUSED(forest), DagNode *fob1, DagNode *fob2, short rel, const char *name)
997 DagAdjList *itA = fob2->parent;
999 while (itA) { /* search if relation exist already */
1000 if (itA->node == fob1) {
1007 /* create new relation and insert at head. MALLOC alert! */
1008 itA = MEM_mallocN(sizeof(DagAdjList), "DAG adj list");
1012 itA->next = fob2->parent;
1017 void dag_add_relation(DagForest *forest, DagNode *fob1, DagNode *fob2, short rel, const char *name)
1019 DagAdjList *itA = fob1->child;
1021 /* parent relation is for cycle checking */
1022 dag_add_parent_relation(forest, fob1, fob2, rel, name);
1024 while (itA) { /* search if relation exist already */
1025 if (itA->node == fob2) {
1032 /* create new relation and insert at head. MALLOC alert! */
1033 itA = MEM_mallocN(sizeof(DagAdjList), "DAG adj list");
1037 itA->next = fob1->child;
1042 static const char *dag_node_name(DagNode *node)
1044 if (node->ob == NULL)
1046 else if (ugly_hack_sorry)
1047 return ((ID *)(node->ob))->name + 2;
1049 return ((bPoseChannel *)(node->ob))->name;
1052 static void dag_node_print_dependencies(DagNode *node)
1056 printf("%s depends on:\n", dag_node_name(node));
1058 for (itA = node->parent; itA; itA = itA->next)
1059 printf(" %s through %s\n", dag_node_name(itA->node), itA->name);
1063 static int dag_node_print_dependency_recurs(DagNode *node, DagNode *endnode)
1067 if (node->color == DAG_BLACK)
1070 node->color = DAG_BLACK;
1072 if (node == endnode)
1075 for (itA = node->parent; itA; itA = itA->next) {
1076 if (dag_node_print_dependency_recurs(itA->node, endnode)) {
1077 printf(" %s depends on %s through %s.\n", dag_node_name(node), dag_node_name(itA->node), itA->name);
1085 static void dag_node_print_dependency_cycle(DagForest *dag, DagNode *startnode, DagNode *endnode, const char *name)
1089 for (node = dag->DagNode.first; node; node = node->next)
1090 node->color = DAG_WHITE;
1092 printf(" %s depends on %s through %s.\n", dag_node_name(endnode), dag_node_name(startnode), name);
1093 dag_node_print_dependency_recurs(startnode, endnode);
1097 static int dag_node_recurs_level(DagNode *node, int level)
1102 node->color = DAG_BLACK; /* done */
1105 for (itA = node->parent; itA; itA = itA->next) {
1106 if (itA->node->color == DAG_WHITE) {
1107 itA->node->ancestor_count = dag_node_recurs_level(itA->node, level);
1108 newlevel = MAX2(newlevel, level + itA->node->ancestor_count);
1111 newlevel = MAX2(newlevel, level + itA->node->ancestor_count);
1117 static void dag_check_cycle(DagForest *dag)
1122 /* debugging print */
1123 if (dag_print_dependencies)
1124 for (node = dag->DagNode.first; node; node = node->next)
1125 dag_node_print_dependencies(node);
1127 /* tag nodes unchecked */
1128 for (node = dag->DagNode.first; node; node = node->next)
1129 node->color = DAG_WHITE;
1131 for (node = dag->DagNode.first; node; node = node->next) {
1132 if (node->color == DAG_WHITE) {
1133 node->ancestor_count = dag_node_recurs_level(node, 0);
1137 /* check relations, and print errors */
1138 for (node = dag->DagNode.first; node; node = node->next) {
1139 for (itA = node->parent; itA; itA = itA->next) {
1140 if (itA->node->ancestor_count > node->ancestor_count) {
1141 if (node->ob && itA->node->ob) {
1142 printf("Dependency cycle detected:\n");
1143 dag_node_print_dependency_cycle(dag, itA->node, node, itA->name);
1149 /* parent relations are only needed for cycle checking, so free now */
1150 for (node = dag->DagNode.first; node; node = node->next) {
1151 while (node->parent) {
1152 itA = node->parent->next;
1153 MEM_freeN(node->parent);
1160 * MainDAG is the DAG of all objects in current scene
1161 * used only for drawing there is one also in each scene
1163 static DagForest *MainDag = NULL;
1165 DagForest *getMainDag(void)
1171 void setMainDag(DagForest *dag)
1179 * in theory we should sweep the whole array
1180 * but in our case the first node is the scene
1181 * and is linked to every other object
1183 * for general case we will need to add outer loop
1187 * ToDo : change pos kludge
1190 /* adjust levels for drawing in oops space */
1191 void graph_bfs(void)
1194 DagNodeQueue *nqueue;
1200 /* fprintf(stderr, "starting BFS\n ------------\n"); */
1201 nqueue = queue_create(DAGQUEUEALLOC);
1202 for (i = 0; i < 50; i++)
1206 * dagnode.first is always the root (scene)
1208 node = MainDag->DagNode.first;
1210 node->color = DAG_WHITE;
1211 node->BFS_dist = 9999;
1216 node = MainDag->DagNode.first;
1217 if (node->color == DAG_WHITE) {
1218 node->color = DAG_GRAY;
1220 push_queue(nqueue, node);
1221 while (nqueue->count) {
1222 node = pop_queue(nqueue);
1224 minheight = pos[node->BFS_dist];
1226 while (itA != NULL) {
1227 if (itA->node->color == DAG_WHITE) {
1228 itA->node->color = DAG_GRAY;
1229 itA->node->BFS_dist = node->BFS_dist + 1;
1230 itA->node->k = (float) minheight;
1231 push_queue(nqueue, itA->node);
1235 fprintf(stderr, "bfs not dag tree edge color :%i\n", itA->node->color);
1241 if (pos[node->BFS_dist] > node->k) {
1242 pos[node->BFS_dist] += 1;
1243 node->k = (float) pos[node->BFS_dist];
1246 pos[node->BFS_dist] = (int) node->k + 1;
1248 set_node_xy(node, node->BFS_dist * DEPSX * 2, pos[node->BFS_dist] * DEPSY * 2);
1249 node->color = DAG_BLACK;
1251 // fprintf(stderr, "BFS node : %20s %i %5.0f %5.0f\n", ((ID *) node->ob)->name, node->BFS_dist, node->x, node->y);
1254 queue_delete(nqueue);
1257 int pre_and_post_BFS(DagForest *dag, short mask, graph_action_func pre_func, graph_action_func post_func, void **data)
1261 node = dag->DagNode.first;
1262 return pre_and_post_source_BFS(dag, mask, node, pre_func, post_func, data);
1266 int pre_and_post_source_BFS(DagForest *dag, short mask, DagNode *source, graph_action_func pre_func, graph_action_func post_func, void **data)
1269 DagNodeQueue *nqueue;
1272 /* fprintf(stderr, "starting BFS\n ------------\n"); */
1275 * dagnode.first is always the root (scene)
1277 node = dag->DagNode.first;
1278 nqueue = queue_create(DAGQUEUEALLOC);
1280 node->color = DAG_WHITE;
1281 node->BFS_dist = 9999;
1286 if (node->color == DAG_WHITE) {
1287 node->color = DAG_GRAY;
1289 pre_func(node->ob, data);
1291 while (nqueue->count) {
1292 node = pop_queue(nqueue);
1295 while (itA != NULL) {
1296 if ((itA->node->color == DAG_WHITE) && (itA->type & mask)) {
1297 itA->node->color = DAG_GRAY;
1298 itA->node->BFS_dist = node->BFS_dist + 1;
1299 push_queue(nqueue, itA->node);
1300 pre_func(node->ob, data);
1303 else { // back or cross edge
1308 post_func(node->ob, data);
1309 node->color = DAG_BLACK;
1311 // fprintf(stderr, "BFS node : %20s %i %5.0f %5.0f\n", ((ID *) node->ob)->name, node->BFS_dist, node->x, node->y);
1314 queue_delete(nqueue);
1318 /* non recursive version of DFS, return queue -- outer loop present to catch odd cases (first level cycles)*/
1319 DagNodeQueue *graph_dfs(void)
1322 DagNodeQueue *nqueue;
1323 DagNodeQueue *retqueue;
1331 /* int is_cycle = 0; */ /* UNUSED */
1333 *fprintf(stderr, "starting DFS\n ------------\n");
1335 nqueue = queue_create(DAGQUEUEALLOC);
1336 retqueue = queue_create(MainDag->numNodes);
1337 for (i = 0; i < 50; i++)
1341 * dagnode.first is always the root (scene)
1343 node = MainDag->DagNode.first;
1345 node->color = DAG_WHITE;
1346 node->DFS_dist = 9999;
1347 node->DFS_dvtm = node->DFS_fntm = 9999;
1354 node = MainDag->DagNode.first;
1357 if (node->color == DAG_WHITE) {
1358 node->color = DAG_GRAY;
1360 node->DFS_dvtm = time;
1362 push_stack(nqueue, node);
1364 while (nqueue->count) {
1365 //graph_print_queue(nqueue);
1368 node = get_top_node_queue(nqueue);
1370 minheight = pos[node->DFS_dist];
1373 while (itA != NULL) {
1374 if (itA->node->color == DAG_WHITE) {
1375 itA->node->DFS_dvtm = time;
1376 itA->node->color = DAG_GRAY;
1379 itA->node->DFS_dist = node->DFS_dist + 1;
1380 itA->node->k = (float) minheight;
1381 push_stack(nqueue, itA->node);
1386 if (itA->node->color == DAG_GRAY) { // back edge
1387 fprintf(stderr, "dfs back edge :%15s %15s\n", ((ID *) node->ob)->name, ((ID *) itA->node->ob)->name);
1388 /* is_cycle = 1; */ /* UNUSED */
1390 else if (itA->node->color == DAG_BLACK) {
1391 /* already processed node but we may want later to change distance either to shorter to longer.
1392 * DFS_dist is the first encounter
1395 if (node->DFS_dist >= itA->node->DFS_dist)
1396 itA->node->DFS_dist = node->DFS_dist + 1;
1398 fprintf(stderr, "dfs forward or cross edge :%15s %i-%i %15s %i-%i\n",
1399 ((ID *) node->ob)->name,
1402 ((ID *) itA->node->ob)->name,
1403 itA->node->DFS_dvtm,
1404 itA->node->DFS_fntm);
1408 fprintf(stderr, "dfs unknown edge\n");
1414 node = pop_queue(nqueue);
1415 node->color = DAG_BLACK;
1417 node->DFS_fntm = time;
1419 if (node->DFS_dist > maxpos)
1420 maxpos = node->DFS_dist;
1421 if (pos[node->DFS_dist] > node->k) {
1422 pos[node->DFS_dist] += 1;
1423 node->k = (float) pos[node->DFS_dist];
1426 pos[node->DFS_dist] = (int) node->k + 1;
1428 set_node_xy(node, node->DFS_dist * DEPSX * 2, pos[node->DFS_dist] * DEPSY * 2);
1430 // 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 );
1432 push_stack(retqueue, node);
1439 // fprintf(stderr, "i size : %i\n", maxpos);
1441 queue_delete(nqueue);
1446 int pre_and_post_DFS(DagForest *dag, short mask, graph_action_func pre_func, graph_action_func post_func, void **data)
1450 node = dag->DagNode.first;
1451 return pre_and_post_source_DFS(dag, mask, node, pre_func, post_func, data);
1454 int pre_and_post_source_DFS(DagForest *dag, short mask, DagNode *source, graph_action_func pre_func, graph_action_func post_func, void **data)
1457 DagNodeQueue *nqueue;
1463 * fprintf(stderr, "starting DFS\n ------------\n");
1465 nqueue = queue_create(DAGQUEUEALLOC);
1468 * dagnode.first is always the root (scene)
1470 node = dag->DagNode.first;
1472 node->color = DAG_WHITE;
1473 node->DFS_dist = 9999;
1474 node->DFS_dvtm = node->DFS_fntm = 9999;
1483 if (node->color == DAG_WHITE) {
1484 node->color = DAG_GRAY;
1486 node->DFS_dvtm = time;
1488 push_stack(nqueue, node);
1489 pre_func(node->ob, data);
1491 while (nqueue->count) {
1493 node = get_top_node_queue(nqueue);
1496 while (itA != NULL) {
1497 if ((itA->node->color == DAG_WHITE) && (itA->type & mask) ) {
1498 itA->node->DFS_dvtm = time;
1499 itA->node->color = DAG_GRAY;
1502 itA->node->DFS_dist = node->DFS_dist + 1;
1503 push_stack(nqueue, itA->node);
1504 pre_func(node->ob, data);
1510 if (itA->node->color == DAG_GRAY) { // back edge
1513 // else if (itA->node->color == DAG_BLACK) { // cross or forward
1521 node = pop_queue(nqueue);
1522 node->color = DAG_BLACK;
1524 node->DFS_fntm = time;
1526 post_func(node->ob, data);
1532 queue_delete(nqueue);
1537 // used to get the obs owning a datablock
1538 DagNodeQueue *get_obparents(struct DagForest *dag, void *ob)
1540 DagNode *node, *node1;
1541 DagNodeQueue *nqueue;
1544 node = dag_find_node(dag, ob);
1548 else if (node->ancestor_count == 1) { // simple case
1549 nqueue = queue_create(1);
1550 push_queue(nqueue, node);
1552 else { /* need to go over the whole dag for adj list */
1553 nqueue = queue_create(node->ancestor_count);
1555 node1 = dag->DagNode.first;
1557 if (node1->DFS_fntm > node->DFS_fntm) { // a parent is finished after child. must check adj list
1559 while (itA != NULL) {
1560 if ((itA->node == node) && (itA->type == DAG_RL_DATA)) {
1561 push_queue(nqueue, node);
1566 node1 = node1->next;
1572 DagNodeQueue *get_first_ancestors(struct DagForest *dag, void *ob)
1574 DagNode *node, *node1;
1575 DagNodeQueue *nqueue;
1578 node = dag_find_node(dag, ob);
1580 /* need to go over the whole dag for adj list */
1581 nqueue = queue_create(node->ancestor_count);
1583 node1 = dag->DagNode.first;
1585 if (node1->DFS_fntm > node->DFS_fntm) {
1587 while (itA != NULL) {
1588 if (itA->node == node) {
1589 push_queue(nqueue, node);
1594 node1 = node1->next;
1600 // standard DFS list
1601 DagNodeQueue *get_all_childs(struct DagForest *dag, void *ob)
1604 DagNodeQueue *nqueue;
1605 DagNodeQueue *retqueue;
1610 nqueue = queue_create(DAGQUEUEALLOC);
1611 retqueue = queue_create(dag->numNodes); // was MainDag... why? (ton)
1613 node = dag->DagNode.first;
1615 node->color = DAG_WHITE;
1621 node = dag_find_node(dag, ob); // could be done in loop above (ton)
1622 if (node) { // can be null for newly added objects
1624 node->color = DAG_GRAY;
1626 push_stack(nqueue, node);
1628 while (nqueue->count) {
1631 node = get_top_node_queue(nqueue);
1634 while (itA != NULL) {
1635 if (itA->node->color == DAG_WHITE) {
1636 itA->node->DFS_dvtm = time;
1637 itA->node->color = DAG_GRAY;
1640 push_stack(nqueue, itA->node);
1648 node = pop_queue(nqueue);
1649 node->color = DAG_BLACK;
1652 push_stack(retqueue, node);
1656 queue_delete(nqueue);
1662 short are_obs_related(struct DagForest *dag, void *ob1, void *ob2)
1667 node = dag_find_node(dag, ob1);
1670 while (itA != NULL) {
1671 if (itA->node->ob == ob2) {
1672 return itA->node->type;
1676 return DAG_NO_RELATION;
1680 int is_acyclic(DagForest *dag)
1682 return dag->is_acyclic;
1685 void set_node_xy(DagNode *node, float x, float y)
1692 /* debug test functions */
1694 void graph_print_queue(DagNodeQueue *nqueue)
1696 DagNodeQueueElem *queueElem;
1698 queueElem = nqueue->first;
1700 fprintf(stderr, "** %s %i %i-%i ", ((ID *) queueElem->node->ob)->name, queueElem->node->color, queueElem->node->DFS_dvtm, queueElem->node->DFS_fntm);
1701 queueElem = queueElem->next;
1703 fprintf(stderr, "\n");
1706 void graph_print_queue_dist(DagNodeQueue *nqueue)
1708 DagNodeQueueElem *queueElem;
1711 queueElem = nqueue->first;
1714 fprintf(stderr, "** %25s %2.2i-%2.2i ", ((ID *) queueElem->node->ob)->name, queueElem->node->DFS_dvtm, queueElem->node->DFS_fntm);
1715 while (count < queueElem->node->DFS_dvtm - 1) { fputc(' ', stderr); count++; }
1717 while (count < queueElem->node->DFS_fntm - 2) { fputc('-', stderr); count++; }
1719 fputc('\n', stderr);
1721 queueElem = queueElem->next;
1723 fprintf(stderr, "\n");
1726 void graph_print_adj_list(void)
1731 node = (getMainDag())->DagNode.first;
1733 fprintf(stderr, "node : %s col: %i", ((ID *) node->ob)->name, node->color);
1736 fprintf(stderr, "-- %s ", ((ID *) itA->node->ob)->name);
1740 fprintf(stderr, "\n");
1745 /* ************************ API *********************** */
1747 /* mechanism to allow editors to be informed of depsgraph updates,
1748 * to do their own updates based on changes... */
1749 static void (*EditorsUpdateIDCb)(Main *bmain, ID *id) = NULL;
1750 static void (*EditorsUpdateSceneCb)(Main *bmain, Scene *scene, int updated) = NULL;
1752 void DAG_editors_update_cb(void (*id_func)(Main *bmain, ID *id), void (*scene_func)(Main *bmain, Scene *scene, int updated))
1754 EditorsUpdateIDCb = id_func;
1755 EditorsUpdateSceneCb = scene_func;
1758 static void dag_editors_id_update(Main *bmain, ID *id)
1760 if (EditorsUpdateIDCb)
1761 EditorsUpdateIDCb(bmain, id);
1764 static void dag_editors_scene_update(Main *bmain, Scene *scene, int updated)
1766 if (EditorsUpdateSceneCb)
1767 EditorsUpdateSceneCb(bmain, scene, updated);
1770 /* groups with objects in this scene need to be put in the right order as well */
1771 static void scene_sort_groups(Main *bmain, Scene *sce)
1778 /* test; are group objects all in this scene? */
1779 for (ob = bmain->object.first; ob; ob = ob->id.next) {
1780 ob->id.flag &= ~LIB_DOIT;
1781 ob->id.newid = NULL; /* newid abuse for GroupObject */
1783 for (base = sce->base.first; base; base = base->next)
1784 base->object->id.flag |= LIB_DOIT;
1786 for (group = bmain->group.first; group; group = group->id.next) {
1787 for (go = group->gobject.first; go; go = go->next) {
1788 if ((go->ob->id.flag & LIB_DOIT) == 0)
1791 /* this group is entirely in this scene */
1793 ListBase listb = {NULL, NULL};
1795 for (go = group->gobject.first; go; go = go->next)
1796 go->ob->id.newid = (ID *)go;
1798 /* in order of sorted bases we reinsert group objects */
1799 for (base = sce->base.first; base; base = base->next) {
1801 if (base->object->id.newid) {
1802 go = (GroupObject *)base->object->id.newid;
1803 base->object->id.newid = NULL;
1804 BLI_remlink(&group->gobject, go);
1805 BLI_addtail(&listb, go);
1808 /* copy the newly sorted listbase */
1809 group->gobject = listb;
1814 /* sort the base list on dependency order */
1815 void DAG_scene_sort(Main *bmain, Scene *sce)
1817 DagNode *node, *rootnode;
1818 DagNodeQueue *nqueue;
1825 tempbase.first = tempbase.last = NULL;
1827 build_dag(bmain, sce, DAG_RL_ALL_BUT_DATA);
1829 dag_check_cycle(sce->theDag);
1831 nqueue = queue_create(DAGQUEUEALLOC);
1833 for (node = sce->theDag->DagNode.first; node; node = node->next) {
1834 node->color = DAG_WHITE;
1839 rootnode = sce->theDag->DagNode.first;
1840 rootnode->color = DAG_GRAY;
1842 push_stack(nqueue, rootnode);
1844 while (nqueue->count) {
1847 node = get_top_node_queue(nqueue);
1850 while (itA != NULL) {
1851 if (itA->node->color == DAG_WHITE) {
1852 itA->node->DFS_dvtm = time;
1853 itA->node->color = DAG_GRAY;
1856 push_stack(nqueue, itA->node);
1865 node = pop_queue(nqueue);
1866 if (node->ob == sce) // we are done
1868 node->color = DAG_BLACK;
1871 base = sce->base.first;
1872 while (base && base->object != node->ob)
1875 BLI_remlink(&sce->base, base);
1876 BLI_addhead(&tempbase, base);
1882 /* temporal correction for circular dependencies */
1883 base = sce->base.first;
1885 BLI_remlink(&sce->base, base);
1886 BLI_addhead(&tempbase, base);
1887 //if (G.debug & G_DEBUG)
1888 printf("cyclic %s\n", base->object->id.name);
1889 base = sce->base.first;
1892 sce->base = tempbase;
1893 queue_delete(nqueue);
1895 /* all groups with objects in this scene gets resorted too */
1896 scene_sort_groups(bmain, sce);
1898 if (G.debug & G_DEBUG) {
1899 printf("\nordered\n");
1900 for (base = sce->base.first; base; base = base->next) {
1901 printf(" %s\n", base->object->id.name);
1905 sce->recalc |= SCE_PRV_CHANGED; /* test for 3d preview */
1908 static void lib_id_recalc_tag(Main *bmain, ID *id)
1910 id->flag |= LIB_ID_RECALC;
1911 bmain->id_tag_update[id->name[0]] = 1;
1914 static void lib_id_recalc_data_tag(Main *bmain, ID *id)
1916 id->flag |= LIB_ID_RECALC_DATA;
1917 bmain->id_tag_update[id->name[0]] = 1;
1920 /* node was checked to have lasttime != curtime and is if type ID_OB */
1921 static void flush_update_node(DagNode *node, unsigned int layer, int curtime)
1923 Main *bmain = G.main;
1926 int oldflag, changed = 0;
1927 unsigned int all_layer;
1929 node->lasttime = curtime;
1932 if (ob && (ob->recalc & OB_RECALC_ALL)) {
1933 all_layer = node->scelay;
1935 /* got an object node that changes, now check relations */
1936 for (itA = node->child; itA; itA = itA->next) {
1937 all_layer |= itA->lay;
1938 /* the relationship is visible */
1939 if ((itA->lay & layer)) { // XXX || (itA->node->ob == obedit)
1940 if (itA->node->type == ID_OB) {
1941 obc = itA->node->ob;
1942 oldflag = obc->recalc;
1944 /* got a ob->obc relation, now check if flag needs flush */
1945 if (ob->recalc & OB_RECALC_OB) {
1946 if (itA->type & DAG_RL_OB_OB) {
1947 //printf("ob %s changes ob %s\n", ob->id.name, obc->id.name);
1948 obc->recalc |= OB_RECALC_OB;
1949 lib_id_recalc_tag(bmain, &obc->id);
1951 if (itA->type & DAG_RL_OB_DATA) {
1952 //printf("ob %s changes obdata %s\n", ob->id.name, obc->id.name);
1953 obc->recalc |= OB_RECALC_DATA;
1954 lib_id_recalc_data_tag(bmain, &obc->id);
1957 if (ob->recalc & OB_RECALC_DATA) {
1958 if (itA->type & DAG_RL_DATA_OB) {
1959 //printf("obdata %s changes ob %s\n", ob->id.name, obc->id.name);
1960 obc->recalc |= OB_RECALC_OB;
1961 lib_id_recalc_tag(bmain, &obc->id);
1963 if (itA->type & DAG_RL_DATA_DATA) {
1964 //printf("obdata %s changes obdata %s\n", ob->id.name, obc->id.name);
1965 obc->recalc |= OB_RECALC_DATA;
1966 lib_id_recalc_data_tag(bmain, &obc->id);
1969 if (oldflag != obc->recalc) changed = 1;
1973 /* even nicer, we can clear recalc flags... */
1974 if ((all_layer & layer) == 0) { // XXX && (ob != obedit)) {
1975 /* but existing displaylists or derivedmesh should be freed */
1976 if (ob->recalc & OB_RECALC_DATA)
1977 BKE_object_free_display(ob);
1979 ob->recalc &= ~OB_RECALC_ALL;
1983 /* check case where child changes and parent forcing obdata to change */
1984 /* should be done regardless if this ob has recalc set */
1985 /* could merge this in with loop above...? (ton) */
1986 for (itA = node->child; itA; itA = itA->next) {
1987 /* the relationship is visible */
1988 if ((itA->lay & layer)) { // XXX || (itA->node->ob == obedit)
1989 if (itA->node->type == ID_OB) {
1990 obc = itA->node->ob;
1992 if ((obc->recalc & OB_RECALC_ALL) == OB_RECALC_OB) {
1993 /* parent has deforming info */
1994 if (itA->type & (DAG_RL_OB_DATA | DAG_RL_DATA_DATA)) {
1995 // printf("parent %s changes ob %s\n", ob->id.name, obc->id.name);
1996 obc->recalc |= OB_RECALC_DATA;
1997 lib_id_recalc_data_tag(bmain, &obc->id);
2004 /* we only go deeper if node not checked or something changed */
2005 for (itA = node->child; itA; itA = itA->next) {
2006 if (changed || itA->node->lasttime != curtime)
2007 flush_update_node(itA->node, layer, curtime);
2012 /* node was checked to have lasttime != curtime, and is of type ID_OB */
2013 static unsigned int flush_layer_node(Scene *sce, DagNode *node, int curtime)
2017 node->lasttime = curtime;
2018 node->lay = node->scelay;
2020 for (itA = node->child; itA; itA = itA->next) {
2021 if (itA->node->type == ID_OB) {
2022 if (itA->node->lasttime != curtime) {
2023 itA->lay = flush_layer_node(sce, itA->node, curtime); // lay is only set once for each relation
2025 else itA->lay = itA->node->lay;
2027 node->lay |= itA->lay;
2034 /* node was checked to have lasttime != curtime, and is of type ID_OB */
2035 static void flush_pointcache_reset(Scene *scene, DagNode *node, int curtime, int reset)
2037 Main *bmain = G.main;
2041 node->lasttime = curtime;
2043 for (itA = node->child; itA; itA = itA->next) {
2044 if (itA->node->type == ID_OB) {
2045 if (itA->node->lasttime != curtime) {
2046 ob = (Object *)(itA->node->ob);
2048 if (reset || (ob->recalc & OB_RECALC_ALL)) {
2049 if (BKE_ptcache_object_reset(scene, ob, PTCACHE_RESET_DEPSGRAPH)) {
2050 ob->recalc |= OB_RECALC_DATA;
2051 lib_id_recalc_data_tag(bmain, &ob->id);
2054 flush_pointcache_reset(scene, itA->node, curtime, 1);
2057 flush_pointcache_reset(scene, itA->node, curtime, 0);
2063 /* flush layer flags to dependencies */
2064 static void dag_scene_flush_layers(Scene *sce, int lay)
2066 DagNode *node, *firstnode;
2071 firstnode = sce->theDag->DagNode.first; // always scene node
2073 for (itA = firstnode->child; itA; itA = itA->next)
2076 sce->theDag->time++; // so we know which nodes were accessed
2077 lasttime = sce->theDag->time;
2079 /* update layer flags in nodes */
2080 for (base = sce->base.first; base; base = base->next) {
2081 node = dag_get_node(sce->theDag, base->object);
2082 node->scelay = base->object->lay;
2085 /* ensure cameras are set as if they are on a visible layer, because
2086 * they ared still used for rendering or setting the camera view
2088 * XXX, this wont work for local view / unlocked camera's */
2090 node = dag_get_node(sce->theDag, sce->camera);
2091 node->scelay |= lay;
2094 #ifdef DURIAN_CAMERA_SWITCH
2098 for (m = sce->markers.first; m; m = m->next) {
2100 node = dag_get_node(sce->theDag, m->camera);
2101 node->scelay |= lay;
2107 /* flush layer nodes to dependencies */
2108 for (itA = firstnode->child; itA; itA = itA->next)
2109 if (itA->node->lasttime != lasttime && itA->node->type == ID_OB)
2110 flush_layer_node(sce, itA->node, lasttime);
2113 static void dag_tag_renderlayers(Scene *sce, unsigned int lay)
2115 if (sce->nodetree) {
2118 unsigned int lay_changed = 0;
2120 for (base = sce->base.first; base; base = base->next)
2121 if (base->lay & lay)
2122 if (base->object->recalc)
2123 lay_changed |= base->lay;
2125 for (node = sce->nodetree->nodes.first; node; node = node->next) {
2126 if (node->id == (ID *)sce) {
2127 SceneRenderLayer *srl = BLI_findlink(&sce->r.layers, node->custom1);
2128 if (srl && (srl->lay & lay_changed))
2129 nodeUpdate(sce->nodetree, node);
2135 /* flushes all recalc flags in objects down the dependency tree */
2136 void DAG_scene_flush_update(Main *bmain, Scene *sce, unsigned int lay, const short time)
2143 if (sce->theDag == NULL) {
2144 printf("DAG zero... not allowed to happen!\n");
2145 DAG_scene_sort(bmain, sce);
2148 firstnode = sce->theDag->DagNode.first; // always scene node
2150 /* first we flush the layer flags */
2151 dag_scene_flush_layers(sce, lay);
2153 /* then we use the relationships + layer info to flush update events */
2154 sce->theDag->time++; // so we know which nodes were accessed
2155 lasttime = sce->theDag->time;
2156 for (itA = firstnode->child; itA; itA = itA->next)
2157 if (itA->node->lasttime != lasttime && itA->node->type == ID_OB)
2158 flush_update_node(itA->node, lay, lasttime);
2160 /* if update is not due to time change, do pointcache clears */
2162 sce->theDag->time++; // so we know which nodes were accessed
2163 lasttime = sce->theDag->time;
2164 for (itA = firstnode->child; itA; itA = itA->next) {
2165 if (itA->node->lasttime != lasttime && itA->node->type == ID_OB) {
2166 ob = (Object *)(itA->node->ob);
2168 if (ob->recalc & OB_RECALC_ALL) {
2169 if (BKE_ptcache_object_reset(sce, ob, PTCACHE_RESET_DEPSGRAPH)) {
2170 ob->recalc |= OB_RECALC_DATA;
2171 lib_id_recalc_data_tag(bmain, &ob->id);
2174 flush_pointcache_reset(sce, itA->node, lasttime, 1);
2177 flush_pointcache_reset(sce, itA->node, lasttime, 0);
2182 dag_tag_renderlayers(sce, lay);
2185 static int object_modifiers_use_time(Object *ob)
2189 /* check if a modifier in modifier stack needs time input */
2190 for (md = ob->modifiers.first; md; md = md->next)
2191 if (modifier_dependsOnTime(md))
2194 /* check whether any modifiers are animated */
2196 AnimData *adt = ob->adt;
2199 /* action - check for F-Curves with paths containing 'modifiers[' */
2201 for (fcu = adt->action->curves.first; fcu; fcu = fcu->next) {
2202 if (fcu->rna_path && strstr(fcu->rna_path, "modifiers["))
2207 /* This here allows modifier properties to get driven and still update properly
2209 * Workaround to get [#26764] (e.g. subsurf levels not updating when animated/driven)
2210 * working, without the updating problems ([#28525] [#28690] [#28774] [#28777]) caused
2211 * by the RNA updates cache introduced in r.38649
2213 for (fcu = adt->drivers.first; fcu; fcu = fcu->next) {
2214 if (fcu->rna_path && strstr(fcu->rna_path, "modifiers["))
2218 /* XXX: also, should check NLA strips, though for now assume that nobody uses
2219 * that and we can omit that for performance reasons... */
2225 static short animdata_use_time(AnimData *adt)
2229 if (adt == NULL) return 0;
2231 /* check action - only if assigned, and it has anim curves */
2232 if (adt->action && adt->action->curves.first)
2235 /* check NLA tracks + strips */
2236 for (nlt = adt->nla_tracks.first; nlt; nlt = nlt->next) {
2237 if (nlt->strips.first)
2241 /* If we have drivers, more likely than not, on a frame change
2242 * they'll need updating because their owner changed
2244 * This is kindof a hack to get around a whole host of problems
2245 * involving drivers using non-object datablock data (which the
2246 * depsgraph currently has no way of representing let alone correctly
2247 * dependency sort+tagging). By doing this, at least we ensure that
2248 * some commonly attempted drivers (such as scene -> current frame;
2249 * see "Driver updates fail" thread on Bf-committers dated July 2)
2250 * will work correctly, and that other non-object datablocks will have
2251 * their drivers update at least on frame change.
2253 * -- Aligorith, July 4 2011
2255 if (adt->drivers.first)
2261 static void dag_object_time_update_flags(Object *ob)
2263 if (ob->constraints.first) {
2265 for (con = ob->constraints.first; con; con = con->next) {
2266 bConstraintTypeInfo *cti = constraint_get_typeinfo(con);
2267 ListBase targets = {NULL, NULL};
2268 bConstraintTarget *ct;
2271 /* special case for camera tracking -- it doesn't use targets to define relations */
2272 if (ELEM3(cti->type, CONSTRAINT_TYPE_FOLLOWTRACK, CONSTRAINT_TYPE_CAMERASOLVER, CONSTRAINT_TYPE_OBJECTSOLVER)) {
2273 ob->recalc |= OB_RECALC_OB;
2275 else if (cti->get_constraint_targets) {
2276 cti->get_constraint_targets(con, &targets);
2278 for (ct = targets.first; ct; ct = ct->next) {
2280 ob->recalc |= OB_RECALC_OB;
2285 if (cti->flush_constraint_targets)
2286 cti->flush_constraint_targets(con, &targets, 1);
2294 /* motion path or bone child */
2295 if (ob->parent->type == OB_CURVE || ob->parent->type == OB_ARMATURE) ob->recalc |= OB_RECALC_OB;
2298 #if 0 // XXX old animation system
2299 if (ob->nlastrips.first) {
2300 if (ob->dup_group) {
2301 bActionStrip *strip;
2302 /* this case is for groups with nla, whilst nla target has no action or nla */
2303 for (strip = ob->nlastrips.first; strip; strip = strip->next) {
2305 strip->object->recalc |= OB_RECALC_ALL;
2309 #endif // XXX old animation system
2311 if (animdata_use_time(ob->adt)) {
2312 ob->recalc |= OB_RECALC_OB;
2313 ob->adt->recalc |= ADT_RECALC_ANIM;
2316 if ((ob->adt) && (ob->type == OB_ARMATURE)) ob->recalc |= OB_RECALC_DATA;
2318 if (object_modifiers_use_time(ob)) ob->recalc |= OB_RECALC_DATA;
2319 if ((ob->pose) && (ob->pose->flag & POSE_CONSTRAINTS_TIMEDEPEND)) ob->recalc |= OB_RECALC_DATA;
2322 AnimData *adt = BKE_animdata_from_id((ID *)ob->data);
2331 if (!(ob->shapeflag & OB_SHAPE_LOCK)) {
2332 ob->recalc |= OB_RECALC_DATA;
2335 if (ob->particlesystem.first)
2336 ob->recalc |= OB_RECALC_DATA;
2342 if (!(ob->shapeflag & OB_SHAPE_LOCK)) {
2343 ob->recalc |= OB_RECALC_DATA;
2349 if (cu->nurb.first == NULL && cu->str && cu->vfont)
2350 ob->recalc |= OB_RECALC_DATA;
2355 if (!(ob->shapeflag & OB_SHAPE_LOCK)) {
2356 ob->recalc |= OB_RECALC_DATA;
2361 if (ob->transflag & OB_DUPLI) ob->recalc |= OB_RECALC_DATA;
2365 if (animdata_use_time(adt)) {
2366 ob->recalc |= OB_RECALC_DATA;
2367 adt->recalc |= ADT_RECALC_ANIM;
2370 if (ob->particlesystem.first) {
2371 ParticleSystem *psys = ob->particlesystem.first;
2373 for (; psys; psys = psys->next) {
2374 if (psys_check_enabled(ob, psys)) {
2375 ob->recalc |= OB_RECALC_DATA;
2382 if (ob->recalc & OB_RECALC_OB)
2383 lib_id_recalc_tag(G.main, &ob->id);
2384 if (ob->recalc & OB_RECALC_DATA)
2385 lib_id_recalc_data_tag(G.main, &ob->id);
2388 /* flag all objects that need recalc, for changes in time for example */
2389 /* do_time: make this optional because undo resets objects to their animated locations without this */
2390 void DAG_scene_update_flags(Main *bmain, Scene *scene, unsigned int lay, const short do_time)
2398 /* set ob flags where animated systems are */
2399 for (SETLOOPER(scene, sce_iter, base)) {
2403 /* now if DagNode were part of base, the node->lay could be checked... */
2404 /* we do all now, since the scene_flush checks layers and clears recalc flags even */
2405 dag_object_time_update_flags(ob);
2408 /* handled in next loop */
2410 ob->dup_group->id.flag |= LIB_DOIT;
2414 /* we do groups each once */
2415 for (group = bmain->group.first; group; group = group->id.next) {
2416 if (group->id.flag & LIB_DOIT) {
2417 for (go = group->gobject.first; go; go = go->next) {
2418 dag_object_time_update_flags(go->ob);
2424 for (sce_iter = scene; sce_iter; sce_iter = sce_iter->set)
2425 DAG_scene_flush_update(bmain, sce_iter, lay, 1);
2428 /* test: set time flag, to disable baked systems to update */
2429 for (SETLOOPER(scene, sce_iter, base)) {
2432 ob->recalc |= OB_RECALC_TIME;
2435 /* hrmf... an exception to look at once, for invisible camera object we do it over */
2437 dag_object_time_update_flags(scene->camera);
2440 /* and store the info in groupobject */
2441 for (group = bmain->group.first; group; group = group->id.next) {
2442 if (group->id.flag & LIB_DOIT) {
2443 for (go = group->gobject.first; go; go = go->next) {
2444 go->recalc = go->ob->recalc;
2445 // printf("ob %s recalc %d\n", go->ob->id.name, go->recalc);
2447 group->id.flag &= ~LIB_DOIT;
2453 static void dag_current_scene_layers(Main *bmain, Scene **sce, unsigned int *lay)
2455 wmWindowManager *wm;
2458 /* only one scene supported currently, making more scenes work
2459 * correctly requires changes beyond just the dependency graph */
2464 if ((wm = bmain->wm.first)) {
2465 /* if we have a windowmanager, look into windows */
2466 for (win = wm->windows.first; win; win = win->next) {
2468 if (*sce == NULL) *sce = win->screen->scene;
2469 *lay |= BKE_screen_visible_layers(win->screen, win->screen->scene);
2474 /* if not, use the first sce */
2475 *sce = bmain->scene.first;
2476 if (*sce) *lay = (*sce)->lay;
2478 /* XXX for background mode, we should get the scene
2479 * from somewhere, for the -S option, but it's in
2480 * the context, how to get it here? */
2484 void DAG_ids_flush_update(Main *bmain, int time)
2489 dag_current_scene_layers(bmain, &sce, &lay);
2492 DAG_scene_flush_update(bmain, sce, lay, time);
2495 void DAG_on_visible_update(Main *bmain, const short do_time)
2503 unsigned int lay, oblay;
2505 dag_current_scene_layers(bmain, &scene, &lay);
2507 if (scene && scene->theDag) {
2509 /* derivedmeshes and displists are not saved to file so need to be
2510 * remade, tag them so they get remade in the scene update loop,
2511 * note armature poses or object matrices are preserved and do not
2512 * require updates, so we skip those */
2513 dag_scene_flush_layers(scene, lay);
2515 for (SETLOOPER(scene, sce_iter, base)) {
2517 node = (sce_iter->theDag) ? dag_get_node(sce_iter->theDag, ob) : NULL;
2518 oblay = (node) ? node->lay : ob->lay;
2520 if ((oblay & lay) & ~scene->lay_updated) {
2521 if (ELEM6(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_MBALL, OB_LATTICE))
2522 ob->recalc |= OB_RECALC_DATA;
2524 ob->dup_group->id.flag |= LIB_DOIT;
2528 for (group = bmain->group.first; group; group = group->id.next) {
2529 if (group->id.flag & LIB_DOIT) {
2530 for (go = group->gobject.first; go; go = go->next) {
2531 if (ELEM6(go->ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_MBALL, OB_LATTICE))
2532 go->ob->recalc |= OB_RECALC_DATA;
2533 if (go->ob->proxy_from)
2534 go->ob->recalc |= OB_RECALC_OB;
2537 group->id.flag &= ~LIB_DOIT;
2541 /* now tag update flags, to ensure deformers get calculated on redraw */
2542 DAG_scene_update_flags(bmain, scene, lay, do_time);
2543 scene->lay_updated |= lay;
2546 /* hack to get objects updating on layer changes */
2547 DAG_id_type_tag(bmain, ID_OB);
2549 /* so masks update on load */
2550 if (bmain->mask.first) {
2553 for (mask = bmain->mask.first; mask; mask = mask->id.next) {
2554 DAG_id_tag_update(&mask->id, 0);
2559 static void dag_id_flush_update__isDependentTexture(void *userData, Object *UNUSED(ob), ID **idpoin)
2561 struct { ID *id; int is_dependent; } *data = userData;
2563 if (*idpoin && GS((*idpoin)->name) == ID_TE) {
2564 if (data->id == (*idpoin))
2565 data->is_dependent = 1;
2569 static void dag_id_flush_update(Scene *sce, ID *id)
2571 Main *bmain = G.main;
2572 Object *obt, *ob = NULL;
2575 /* here we flush a few things before actual scene wide flush, mostly
2576 * due to only objects and not other datablocks being in the depsgraph */
2578 /* set flags & pointcache for object */
2579 if (GS(id->name) == ID_OB) {
2581 BKE_ptcache_object_reset(sce, ob, PTCACHE_RESET_DEPSGRAPH);
2583 if (ob->recalc & OB_RECALC_DATA) {
2584 /* all users of this ob->data should be checked */
2587 /* no point in trying in this cases */
2588 if (id && id->us <= 1) {
2589 dag_editors_id_update(bmain, id);
2595 /* set flags & pointcache for object data */
2597 idtype = GS(id->name);
2599 if (ELEM8(idtype, ID_ME, ID_CU, ID_MB, ID_LA, ID_LT, ID_CA, ID_AR, ID_SPK)) {
2600 for (obt = bmain->object.first; obt; obt = obt->id.next) {
2601 if (!(ob && obt == ob) && obt->data == id) {
2602 obt->recalc |= OB_RECALC_DATA;
2603 lib_id_recalc_data_tag(bmain, &obt->id);
2604 BKE_ptcache_object_reset(sce, obt, PTCACHE_RESET_DEPSGRAPH);
2609 /* set flags based on textures - can influence depgraph via modifiers */
2610 if (idtype == ID_TE) {
2611 for (obt = bmain->object.first; obt; obt = obt->id.next) {
2612 struct { ID *id; int is_dependent; } data;
2614 data.is_dependent = 0;
2616 modifiers_foreachIDLink(obt, dag_id_flush_update__isDependentTexture, &data);
2617 if (data.is_dependent) {
2618 obt->recalc |= OB_RECALC_DATA;
2619 lib_id_recalc_data_tag(bmain, &obt->id);
2622 /* particle settings can use the texture as well */
2623 if (obt->particlesystem.first) {
2624 ParticleSystem *psys = obt->particlesystem.first;
2625 MTex **mtexp, *mtex;
2627 for (; psys; psys = psys->next) {
2628 mtexp = psys->part->mtex;
2629 for (a = 0; a < MAX_MTEX; a++, mtexp++) {
2631 if (mtex && mtex->tex == (Tex *)id) {
2632 obt->recalc |= OB_RECALC_DATA;
2633 lib_id_recalc_data_tag(bmain, &obt->id);
2635 if (mtex->mapto & PAMAP_INIT)
2636 psys->recalc |= PSYS_RECALC_RESET;
2637 if (mtex->mapto & PAMAP_CHILD)
2638 psys->recalc |= PSYS_RECALC_CHILD;
2640 BKE_ptcache_object_reset(sce, obt, PTCACHE_RESET_DEPSGRAPH);
2648 /* set flags based on ShapeKey */
2649 if (idtype == ID_KE) {
2650 for (obt = bmain->object.first; obt; obt = obt->id.next) {
2651 Key *key = ob_get_key(obt);
2652 if (!(ob && obt == ob) && ((ID *)key == id)) {
2653 obt->flag |= (OB_RECALC_OB | OB_RECALC_DATA);
2654 lib_id_recalc_tag(bmain, &obt->id);
2655 lib_id_recalc_data_tag(bmain, &obt->id);
2656 BKE_ptcache_object_reset(sce, obt, PTCACHE_RESET_DEPSGRAPH);
2661 /* set flags based on particle settings */
2662 if (idtype == ID_PA) {
2663 ParticleSystem *psys;
2664 for (obt = bmain->object.first; obt; obt = obt->id.next)
2665 for (psys = obt->particlesystem.first; psys; psys = psys->next)
2666 if (&psys->part->id == id)
2667 BKE_ptcache_object_reset(sce, obt, PTCACHE_RESET_DEPSGRAPH);
2670 if (idtype == ID_MC) {
2671 MovieClip *clip = (MovieClip *) id;
2673 BKE_tracking_dopesheet_tag_update(&clip->tracking);
2675 for (obt = bmain->object.first; obt; obt = obt->id.next) {
2677 for (con = obt->constraints.first; con; con = con->next) {
2678 bConstraintTypeInfo *cti = constraint_get_typeinfo(con);
2679 if (ELEM3(cti->type, CONSTRAINT_TYPE_FOLLOWTRACK, CONSTRAINT_TYPE_CAMERASOLVER,
2680 CONSTRAINT_TYPE_OBJECTSOLVER))
2682 obt->recalc |= OB_RECALC_OB;
2688 if (sce->nodetree) {
2691 for (node = sce->nodetree->nodes.first; node; node = node->next) {
2692 if (node->id == id) {
2693 nodeUpdate(sce->nodetree, node);
2699 if (idtype == ID_MSK) {
2700 if (sce->nodetree) {
2703 for (node = sce->nodetree->nodes.first; node; node = node->next) {
2704 if (node->id == id) {
2705 nodeUpdate(sce->nodetree, node);
2711 /* camera's matrix is used to orient reconstructed stuff,
2712 * so it should happen tracking-related constraints recalculation
2713 * when camera is changing (sergey) */
2714 if (sce->camera && &sce->camera->id == id) {
2715 MovieClip *clip = BKE_object_movieclip_get(sce, sce->camera, 1);
2718 dag_id_flush_update(sce, &clip->id);
2721 /* update editors */
2722 dag_editors_id_update(bmain, id);
2726 void DAG_ids_flush_tagged(Main *bmain)
2728 ListBase *lbarray[MAX_LIBARRAY];
2731 int a, do_flush = FALSE;
2733 dag_current_scene_layers(bmain, &sce, &lay);
2735 if (!sce || !sce->theDag)
2738 /* loop over all ID types */
2739 a = set_listbasepointers(bmain, lbarray);
2742 ListBase *lb = lbarray[a];
2745 /* we tag based on first ID type character to avoid
2746 * looping over all ID's in case there are no tags */
2747 if (id && bmain->id_tag_update[id->name[0]]) {
2748 for (; id; id = id->next) {
2749 if (id->flag & (LIB_ID_RECALC | LIB_ID_RECALC_DATA)) {
2750 dag_id_flush_update(sce, id);
2757 /* flush changes to other objects */
2759 DAG_scene_flush_update(bmain, sce, lay, 0);
2762 void DAG_ids_check_recalc(Main *bmain, Scene *scene, int time)
2764 ListBase *lbarray[MAX_LIBARRAY];
2767 /* loop over all ID types */
2768 a = set_listbasepointers(bmain, lbarray);
2771 ListBase *lb = lbarray[a];
2774 /* we tag based on first ID type character to avoid
2775 * looping over all ID's in case there are no tags */
2776 if (id && bmain->id_tag_update[id->name[0]]) {
2782 dag_editors_scene_update(bmain, scene, (updated || time));
2785 void DAG_ids_clear_recalc(Main *bmain)
2787 ListBase *lbarray[MAX_LIBARRAY];
2790 /* loop over all ID types */
2791 a = set_listbasepointers(bmain, lbarray);
2794 ListBase *lb = lbarray[a];
2797 /* we tag based on first ID type character to avoid
2798 * looping over all ID's in case there are no tags */
2799 if (id && bmain->id_tag_update[id->name[0]]) {
2800 for (; id; id = id->next)
2801 if (id->flag & (LIB_ID_RECALC | LIB_ID_RECALC_DATA))
2802 id->flag &= ~(LIB_ID_RECALC | LIB_ID_RECALC_DATA);
2806 memset(bmain->id_tag_update, 0, sizeof(bmain->id_tag_update));
2809 void DAG_id_tag_update(ID *id, short flag)
2811 Main *bmain = G.main;
2813 if (id == NULL) return;
2815 /* tag ID for update */
2817 if (flag & OB_RECALC_OB)
2818 lib_id_recalc_tag(bmain, id);
2819 if (flag & (OB_RECALC_DATA | PSYS_RECALC))
2820 lib_id_recalc_data_tag(bmain, id);
2823 lib_id_recalc_tag(bmain, id);
2825 /* flag is for objects and particle systems */
2828 short idtype = GS(id->name);
2830 if (idtype == ID_OB) {
2831 /* only quick tag */
2833 ob->recalc |= (flag & OB_RECALC_ALL);
2835 else if (idtype == ID_PA) {
2836 ParticleSystem *psys;
2837 /* this is weak still, should be done delayed as well */
2838 for (ob = bmain->object.first; ob; ob = ob->id.next) {
2839 for (psys = ob->particlesystem.first; psys; psys = psys->next) {
2840 if (&psys->part->id == id) {
2841 ob->recalc |= (flag & OB_RECALC_ALL);
2842 psys->recalc |= (flag & PSYS_RECALC);
2843 lib_id_recalc_tag(bmain, &ob->id);
2844 lib_id_recalc_data_tag(bmain, &ob->id);
2849 else if (idtype == ID_VF) {
2850 /* this is weak still, should be done delayed as well */
2851 for (ob = bmain->object.first; ob; ob = ob->id.next) {
2852 if (ob->type == OB_FONT) {
2853 Curve *cu = ob->data;
2855 if (ELEM4((struct VFont *)id, cu->vfont, cu->vfontb, cu->vfonti, cu->vfontbi)) {
2856 ob->recalc |= (flag & OB_RECALC_ALL);
2862 /* disable because this is called on various ID types automatically.
2863 * where printing warning is not useful. for now just ignore */
2864 /* BLI_assert(!"invalid flag for this 'idtype'"); */
2869 void DAG_id_type_tag(struct Main *bmain, short idtype)
2871 bmain->id_tag_update[((char *)&idtype)[0]] = 1;
2874 int DAG_id_type_tagged(Main *bmain, short idtype)
2876 return bmain->id_tag_update[((char *)&idtype)[0]];
2880 /* recursively descends tree, each node only checked once */
2881 /* node is checked to be of type object */
2882 static int parent_check_node(DagNode *node, int curtime)
2886 node->lasttime = curtime;
2888 if (node->color == DAG_GRAY)
2891 for (itA = node->child; itA; itA = itA->next) {
2892 if (itA->node->type == ID_OB) {
2894 if (itA->node->color == DAG_GRAY)
2897 /* descend if not done */
2898 if (itA->node->lasttime != curtime) {
2899 itA->node->color = parent_check_node(itA->node, curtime);
2901 if (itA->node->color == DAG_GRAY)
2911 /* ******************* DAG FOR ARMATURE POSE ***************** */
2913 /* we assume its an armature with pose */
2914 void DAG_pose_sort(Object *ob)
2916 bPose *pose = ob->pose;
2917 bPoseChannel *pchan;
2920 DagNode *node2, *node3;
2923 DagNodeQueue *nqueue;