Changeset View
Changeset View
Standalone View
Standalone View
source/blender/blenkernel/intern/depsgraph.c
| Show First 20 Lines • Show All 1,386 Lines • ▼ Show 20 Lines | static void dag_scene_build(Main *bmain, Scene *sce) | ||||
| nqueue = queue_create(DAGQUEUEALLOC); | nqueue = queue_create(DAGQUEUEALLOC); | ||||
| for (node = sce->theDag->DagNode.first; node; node = node->next) { | for (node = sce->theDag->DagNode.first; node; node = node->next) { | ||||
| node->color = DAG_WHITE; | node->color = DAG_WHITE; | ||||
| } | } | ||||
| time = 1; | time = 1; | ||||
brecht: Shouldn't this be `return false`? | |||||
Not Done Inline ActionsYou're absolutely right. sergey: You're absolutely right. | |||||
| rootnode = sce->theDag->DagNode.first; | rootnode = sce->theDag->DagNode.first; | ||||
| rootnode->color = DAG_GRAY; | rootnode->color = DAG_GRAY; | ||||
| time++; | time++; | ||||
| push_stack(nqueue, rootnode); | push_stack(nqueue, rootnode); | ||||
| while (nqueue->count) { | while (nqueue->count) { | ||||
| skip = 0; | skip = 0; | ||||
| ▲ Show 20 Lines • Show All 739 Lines • ▼ Show 20 Lines | static void dag_group_on_visible_update(Group *group) | ||||
| if (group->id.flag & LIB_DOIT) | if (group->id.flag & LIB_DOIT) | ||||
| return; | return; | ||||
| group->id.flag |= LIB_DOIT; | group->id.flag |= LIB_DOIT; | ||||
| for (go = group->gobject.first; go; go = go->next) { | for (go = group->gobject.first; go; go = go->next) { | ||||
| if (ELEM6(go->ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_MBALL, OB_LATTICE)) { | if (ELEM6(go->ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_MBALL, OB_LATTICE)) { | ||||
| go->ob->recalc |= OB_RECALC_DATA; | go->ob->recalc |= OB_RECALC_DATA; | ||||
| go->ob->id.flag |= LIB_DOIT; | |||||
| lib_id_recalc_tag(G.main, &go->ob->id); | lib_id_recalc_tag(G.main, &go->ob->id); | ||||
| } | } | ||||
| if (go->ob->proxy_from) { | if (go->ob->proxy_from) { | ||||
| go->ob->recalc |= OB_RECALC_OB; | go->ob->recalc |= OB_RECALC_OB; | ||||
| go->ob->id.flag |= LIB_DOIT; | |||||
| lib_id_recalc_tag(G.main, &go->ob->id); | lib_id_recalc_tag(G.main, &go->ob->id); | ||||
| } | } | ||||
| if (go->ob->dup_group) | if (go->ob->dup_group) | ||||
| dag_group_on_visible_update(go->ob->dup_group); | dag_group_on_visible_update(go->ob->dup_group); | ||||
| } | } | ||||
| } | } | ||||
| static void dag_on_visible_flush(Scene *scene) | |||||
| { | |||||
| DagNode *root_node = scene->theDag->DagNode.first, *node; | |||||
| DagNodeQueue *queue; | |||||
| for (node = root_node; node != NULL; node = node->next) { | |||||
| node->color = DAG_WHITE; | |||||
| } | |||||
| queue = queue_create(DAGQUEUEALLOC); | |||||
| for (node = root_node; node != NULL; node = node->next) { | |||||
| if (node->color == DAG_WHITE) { | |||||
| push_stack(queue, node); | |||||
| node->color = DAG_GRAY; | |||||
| while (queue->count) { | |||||
| DagNode *current_node = get_top_node_queue(queue); | |||||
| DagAdjList *itA; | |||||
| bool skip = false; | |||||
| for (itA = current_node->child; itA; itA = itA->next) { | |||||
| if (itA->node->color == DAG_WHITE) { | |||||
| itA->node->color = DAG_GRAY; | |||||
| push_stack(queue, itA->node); | |||||
| skip = true; | |||||
| break; | |||||
| } | |||||
| } | |||||
| if (!skip) { | |||||
| current_node = pop_queue(queue); | |||||
| if (current_node->type == ID_OB) { | |||||
| Object *current_object = current_node->ob; | |||||
| for (itA = current_node->child; itA; itA = itA->next) { | |||||
| if (itA->node->type == ID_OB) { | |||||
| Object *object = itA->node->ob; | |||||
| if (object->id.flag & LIB_DOIT) { | |||||
| if (object->recalc & OB_RECALC_DATA) { | |||||
| current_object->recalc |= OB_RECALC_DATA; | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| node->color = DAG_BLACK; | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| queue_delete(queue); | |||||
| } | |||||
| void DAG_on_visible_update(Main *bmain, const bool do_time) | void DAG_on_visible_update(Main *bmain, const bool do_time) | ||||
| { | { | ||||
| ListBase listbase; | ListBase listbase; | ||||
| DagSceneLayer *dsl; | DagSceneLayer *dsl; | ||||
| /* get list of visible scenes and layers */ | /* get list of visible scenes and layers */ | ||||
| dag_current_scene_layers(bmain, &listbase); | dag_current_scene_layers(bmain, &listbase); | ||||
| for (dsl = listbase.first; dsl; dsl = dsl->next) { | for (dsl = listbase.first; dsl; dsl = dsl->next) { | ||||
| Scene *scene = dsl->scene; | Scene *scene = dsl->scene; | ||||
| Scene *sce_iter; | Scene *sce_iter; | ||||
| Base *base; | Base *base; | ||||
| Object *ob; | Object *ob; | ||||
| DagNode *node; | DagNode *node; | ||||
| unsigned int lay = dsl->layer, oblay; | unsigned int lay = dsl->layer, oblay; | ||||
| /* derivedmeshes and displists are not saved to file so need to be | /* derivedmeshes and displists are not saved to file so need to be | ||||
| * remade, tag them so they get remade in the scene update loop, | * remade, tag them so they get remade in the scene update loop, | ||||
| * note armature poses or object matrices are preserved and do not | * note armature poses or object matrices are preserved and do not | ||||
| * require updates, so we skip those */ | * require updates, so we skip those */ | ||||
| for (sce_iter = scene; sce_iter; sce_iter = sce_iter->set) | for (sce_iter = scene; sce_iter; sce_iter = sce_iter->set) | ||||
| dag_scene_flush_layers(sce_iter, lay); | dag_scene_flush_layers(sce_iter, lay); | ||||
| BKE_main_id_tag_idcode(bmain, ID_GR, false); | BKE_main_id_tag_idcode(bmain, ID_GR, false); | ||||
| BKE_main_id_tag_idcode(bmain, ID_OB, false); | |||||
| for (SETLOOPER(scene, sce_iter, base)) { | for (SETLOOPER(scene, sce_iter, base)) { | ||||
| ob = base->object; | ob = base->object; | ||||
| node = (sce_iter->theDag) ? dag_get_node(sce_iter->theDag, ob) : NULL; | node = (sce_iter->theDag) ? dag_get_node(sce_iter->theDag, ob) : NULL; | ||||
| oblay = (node) ? node->lay : ob->lay; | oblay = (node) ? node->lay : ob->lay; | ||||
| if ((oblay & lay) & ~scene->lay_updated) { | if ((oblay & lay) & ~scene->lay_updated) { | ||||
| ob->id.flag |= LIB_DOIT; | |||||
| if (ELEM6(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_MBALL, OB_LATTICE)) { | if (ELEM6(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_MBALL, OB_LATTICE)) { | ||||
| ob->recalc |= OB_RECALC_DATA; | ob->recalc |= OB_RECALC_DATA; | ||||
| lib_id_recalc_tag(bmain, &ob->id); | lib_id_recalc_tag(bmain, &ob->id); | ||||
| } | } | ||||
| if (ob->proxy && (ob->proxy_group == NULL)) { | if (ob->proxy && (ob->proxy_group == NULL)) { | ||||
| ob->proxy->recalc |= OB_RECALC_DATA; | ob->proxy->recalc |= OB_RECALC_DATA; | ||||
| lib_id_recalc_tag(bmain, &ob->id); | lib_id_recalc_tag(bmain, &ob->id); | ||||
| } | } | ||||
| if (ob->dup_group) | if (ob->dup_group) | ||||
| dag_group_on_visible_update(ob->dup_group); | dag_group_on_visible_update(ob->dup_group); | ||||
| } | } | ||||
Not Done Inline ActionsIs this case really only possible with dupligroups? I wonder if it is possible to create a setup where an object depends on another object that is not in the scene. brecht: Is this case really only possible with dupligroups? I wonder if it is possible to create a… | |||||
Not Done Inline ActionsI'm not sure about this. Thought you might know.. sergey: I'm not sure about this. Thought you might know.. | |||||
Not Done Inline ActionsIt seems to be possible. In the example .blend you can remove the dupligroup and add a curve, then use BezierCircle as the bevel object, and it will give the same problem because BezierCircle is in the other scene. So this code always has to run regardless if there is a group, which isn't so bad I think. brecht: It seems to be possible.
In the example .blend you can remove the dupligroup and add a curve… | |||||
| } | } | ||||
| /* It is possible that some object depends on an objects which isn't in the scene. | |||||
| * We do need those objects to be evaluated as well on visible changes, so all | |||||
| * dependencies for objects from the scene are met. | |||||
| * | |||||
| * Unfortunately, we don't have parent relations on this state, so we're to use | |||||
| * DFS over the whole DAG to gather such dependencies. | |||||
| * | |||||
| * This is probably not so bad since visible update is called really rarely. | |||||
| */ | |||||
| dag_on_visible_flush(scene); | |||||
| BKE_main_id_tag_idcode(bmain, ID_GR, false); | BKE_main_id_tag_idcode(bmain, ID_GR, false); | ||||
| BKE_main_id_tag_idcode(bmain, ID_OB, false); | |||||
| /* now tag update flags, to ensure deformers get calculated on redraw */ | /* now tag update flags, to ensure deformers get calculated on redraw */ | ||||
| DAG_scene_update_flags(bmain, scene, lay, do_time); | DAG_scene_update_flags(bmain, scene, lay, do_time); | ||||
| scene->lay_updated |= lay; | scene->lay_updated |= lay; | ||||
| } | } | ||||
| BLI_freelistN(&listbase); | BLI_freelistN(&listbase); | ||||
| ▲ Show 20 Lines • Show All 780 Lines • Show Last 20 Lines | |||||
Shouldn't this be return false?