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_group_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; | ||||
| bool has_updated_group = false; | |||||
| /* 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) { | ||||
| 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); | ||||
| has_updated_group = true; | |||||
brechtUnsubmitted 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… | |||||
sergeyAuthorUnsubmitted Not Done Inline ActionsI'm not sure about this. Thought you might know.. sergey: I'm not sure about this. Thought you might know.. | |||||
brechtUnsubmitted 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 objects from dupli-groups depends on objects which are | |||||
| * not in the dupli-group. We do need this objects to be evaluated as well on | |||||
| * visible changes, so all dependencies for objects from the dupli-group 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. | |||||
| */ | |||||
| if (has_updated_group) { | |||||
| dag_group_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?