diff options
Diffstat (limited to 'source/blender/blenkernel/intern/depsgraph.c')
-rw-r--r-- | source/blender/blenkernel/intern/depsgraph.c | 205 |
1 files changed, 130 insertions, 75 deletions
diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c index 0c9248c1eb9..142f80a350e 100644 --- a/source/blender/blenkernel/intern/depsgraph.c +++ b/source/blender/blenkernel/intern/depsgraph.c @@ -29,35 +29,16 @@ #include <string.h> #include <math.h> -#include "BLI_blenlib.h" -#include "BLI_math.h" #include "BLI_winstuff.h" #include "DNA_anim_types.h" -#include "DNA_action_types.h" -#include "DNA_armature_types.h" -#include "DNA_boid_types.h" -#include "DNA_curve_types.h" #include "DNA_camera_types.h" -#include "DNA_ID.h" -#include "DNA_effect_types.h" #include "DNA_group_types.h" #include "DNA_lattice_types.h" -#include "DNA_lamp_types.h" #include "DNA_key_types.h" #include "DNA_mesh_types.h" -#include "DNA_modifier_types.h" -#include "DNA_nla_types.h" -#include "DNA_object_types.h" -#include "DNA_object_force.h" -#include "DNA_object_fluidsim.h" -#include "DNA_outliner_types.h" -#include "DNA_particle_types.h" #include "DNA_scene_types.h" #include "DNA_screen_types.h" -#include "DNA_space_types.h" -#include "DNA_view2d_types.h" -#include "DNA_view3d_types.h" #include "DNA_windowmanager_types.h" #include "BLI_ghash.h" @@ -75,7 +56,6 @@ #include "BKE_object.h" #include "BKE_particle.h" #include "BKE_pointcache.h" -#include "BKE_utildefines.h" #include "BKE_scene.h" #include "BKE_screen.h" @@ -488,11 +468,6 @@ static void build_dag_object(DagForest *dag, DagNode *scenenode, Scene *scene, O addtoroot = 0; } - if (ob->track) { - node2 = dag_get_node(dag,ob->track); - dag_add_relation(dag,node2,node,DAG_RL_OB_OB, "Track To"); - addtoroot = 0; - } if (ob->proxy) { node2 = dag_get_node(dag, ob->proxy); dag_add_relation(dag, node, node2, DAG_RL_DATA_DATA|DAG_RL_OB_OB, "Proxy"); @@ -828,7 +803,7 @@ DagNode * dag_add_node (DagForest *forest, void * fob) } if(!forest->nodeHash) - forest->nodeHash= BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp); + forest->nodeHash= BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "dag_add_node gh"); BLI_ghash_insert(forest->nodeHash, fob, node); } @@ -971,7 +946,7 @@ static void dag_node_print_dependency_cycle(DagForest *dag, DagNode *startnode, { DagNode *node; - for(node = dag->DagNode.first; node; node= node->next) + for(node = dag->DagNode.first; node; node= node->next) node->color= DAG_WHITE; printf(" %s depends on %s through %s.\n", dag_node_name(endnode), dag_node_name(startnode), name); @@ -1553,7 +1528,7 @@ int is_acyclic( DagForest *dag) { void set_node_xy(DagNode *node, float x, float y) { - node->x = x; + node->x = x; node->y = y; } @@ -1779,8 +1754,8 @@ static void flush_update_node(DagNode *node, unsigned int layer, int curtime) node->lasttime= curtime; ob= node->ob; - if(ob && (ob->recalc & OB_RECALC)) { - all_layer= ob->lay; + if(ob && (ob->recalc & OB_RECALC_ALL)) { + all_layer= node->scelay; /* got an object node that changes, now check relations */ for(itA = node->child; itA; itA= itA->next) { @@ -1822,7 +1797,7 @@ static void flush_update_node(DagNode *node, unsigned int layer, int curtime) if(ob->recalc & OB_RECALC_DATA) object_free_display(ob); - ob->recalc &= ~OB_RECALC; + ob->recalc &= ~OB_RECALC_ALL; } } @@ -1835,7 +1810,7 @@ static void flush_update_node(DagNode *node, unsigned int layer, int curtime) if(itA->node->type==ID_OB) { obc= itA->node->ob; /* child moves */ - if((obc->recalc & OB_RECALC)==OB_RECALC_OB) { + if((obc->recalc & OB_RECALC_ALL)==OB_RECALC_OB) { /* parent has deforming info */ if(itA->type & (DAG_RL_OB_DATA|DAG_RL_DATA_DATA)) { // printf("parent %s changes ob %s\n", ob->id.name, obc->id.name); @@ -1889,7 +1864,7 @@ static void flush_pointcache_reset(Scene *scene, DagNode *node, int curtime, int if(itA->node->lasttime!=curtime) { ob= (Object*)(node->ob); - if(reset || (ob->recalc & OB_RECALC)) { + if(reset || (ob->recalc & OB_RECALC_ALL)) { if(BKE_ptcache_object_reset(scene, ob, PTCACHE_RESET_DEPSGRAPH)) ob->recalc |= OB_RECALC_DATA; @@ -1902,42 +1877,72 @@ static void flush_pointcache_reset(Scene *scene, DagNode *node, int curtime, int } } -/* flushes all recalc flags in objects down the dependency tree */ -void DAG_scene_flush_update(Scene *sce, unsigned int lay, int time) +/* flush layer flags to dependencies */ +static void dag_scene_flush_layers(Scene *sce, int lay) { - DagNode *firstnode, *node; + DagNode *node, *firstnode; DagAdjList *itA; - Object *ob; Base *base; int lasttime; - - if(sce->theDag==NULL) { - printf("DAG zero... not allowed to happen!\n"); - DAG_scene_sort(sce); - } - + firstnode= sce->theDag->DagNode.first; // always scene node for(itA = firstnode->child; itA; itA= itA->next) itA->lay= 0; - - /* first we flush the layer flags */ + sce->theDag->time++; // so we know which nodes were accessed lasttime= sce->theDag->time; - + /* update layer flags in nodes */ for(base= sce->base.first; base; base= base->next) { node= dag_get_node(sce->theDag, base->object); - if(node) - node->scelay= base->object->lay; - else - node->scelay= 0; + node->scelay= base->object->lay; + } + + /* ensure cameras are set as if they are on a visible layer, because + they ared still used for rendering or setting the camera view */ + if(sce->camera) { + node= dag_get_node(sce->theDag, sce->camera); + node->scelay |= lay; + } + +#ifdef DURIAN_CAMERA_SWITCH + { + TimeMarker *m; + + for(m= sce->markers.first; m; m= m->next) { + if(m->camera) { + node= dag_get_node(sce->theDag, m->camera); + node->scelay |= lay; + } + } } +#endif + /* flush layer nodes to dependencies */ for(itA = firstnode->child; itA; itA= itA->next) if(itA->node->lasttime!=lasttime && itA->node->type==ID_OB) flush_layer_node(sce, itA->node, lasttime); +} + +/* flushes all recalc flags in objects down the dependency tree */ +void DAG_scene_flush_update(Scene *sce, unsigned int lay, int time) +{ + DagNode *firstnode; + DagAdjList *itA; + Object *ob; + int lasttime; + + if(sce->theDag==NULL) { + printf("DAG zero... not allowed to happen!\n"); + DAG_scene_sort(sce); + } + firstnode= sce->theDag->DagNode.first; // always scene node + + /* first we flush the layer flags */ + dag_scene_flush_layers(sce, lay); + /* then we use the relationships + layer info to flush update events */ sce->theDag->time++; // so we know which nodes were accessed lasttime= sce->theDag->time; @@ -1953,7 +1958,7 @@ void DAG_scene_flush_update(Scene *sce, unsigned int lay, int time) if(itA->node->lasttime!=lasttime && itA->node->type==ID_OB) { ob= (Object*)(itA->node->ob); - if(ob->recalc & OB_RECALC) { + if(ob->recalc & OB_RECALC_ALL) { if(BKE_ptcache_object_reset(sce, ob, PTCACHE_RESET_DEPSGRAPH)) ob->recalc |= OB_RECALC_DATA; @@ -1969,11 +1974,30 @@ void DAG_scene_flush_update(Scene *sce, unsigned int lay, int time) static int object_modifiers_use_time(Object *ob) { ModifierData *md; - + + /* check if a modifier in modifier stack needs time input */ for (md=ob->modifiers.first; md; md=md->next) if (modifier_dependsOnTime(md)) return 1; - + + /* check whether any modifiers are animated */ + if (ob->adt) { + AnimData *adt = ob->adt; + + /* action - check for F-Curves with paths containing 'modifiers[' */ + if (adt->action) { + FCurve *fcu; + + for (fcu = adt->action->curves.first; fcu; fcu = fcu->next) { + if (fcu->rna_path && strstr(fcu->rna_path, "modifiers[")) + return 1; + } + } + + // XXX: also, should check NLA strips, though for now assume that nobody uses + // that and we can omit that for performance reasons... + } + return 0; } @@ -2033,14 +2057,14 @@ static void dag_object_time_update_flags(Object *ob) /* this case is for groups with nla, whilst nla target has no action or nla */ for(strip= ob->nlastrips.first; strip; strip= strip->next) { if(strip->object) - strip->object->recalc |= OB_RECALC; + strip->object->recalc |= OB_RECALC_ALL; } } } #endif // XXX old animation system if(animdata_use_time(ob->adt)) { - ob->recalc |= OB_RECALC; + ob->recalc |= OB_RECALC_OB; ob->adt->recalc |= ADT_RECALC_ANIM; } @@ -2193,7 +2217,7 @@ static void dag_current_scene_layers(Main *bmain, Scene **sce, unsigned int *lay *sce= bmain->scene.first; if(*sce) *lay= (*sce)->lay; - /* XXX for background mode, we should get the scen + /* XXX for background mode, we should get the scene from somewhere, for the -S option, but it's in the context, how to get it here? */ } @@ -2219,19 +2243,24 @@ void DAG_on_load_update(void) Object *ob; Group *group; GroupObject *go; - unsigned int lay; + DagNode *node; + unsigned int lay, oblay; dag_current_scene_layers(bmain, &scene, &lay); - if(scene) { + if(scene && scene->theDag) { /* derivedmeshes and displists are not saved to file so need to be remade, tag them so they get remade in the scene update loop, note armature poses or object matrices are preserved and do not require updates, so we skip those */ + dag_scene_flush_layers(scene, lay); + for(SETLOOPER(scene, base)) { ob= base->object; + node= (sce->theDag)? dag_get_node(sce->theDag, ob): NULL; + oblay= (node)? node->lay: ob->lay; - if(base->lay & lay) { + if(oblay & lay) { if(ELEM5(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_MBALL)) ob->recalc |= OB_RECALC_DATA; if(ob->dup_group) @@ -2244,6 +2273,8 @@ void DAG_on_load_update(void) for(go= group->gobject.first; go; go= go->next) { if(ELEM5(go->ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_MBALL)) go->ob->recalc |= OB_RECALC_DATA; + if(go->ob->proxy_from) + go->ob->recalc |= OB_RECALC_OB; } group->id.flag &= ~LIB_DOIT; @@ -2255,6 +2286,16 @@ void DAG_on_load_update(void) } } +static void dag_id_flush_update__isDependentTexture(void *userData, Object *ob, ID **idpoin) +{ + struct { ID *id; int is_dependent; } *data = userData; + + if(*idpoin && GS((*idpoin)->name)==ID_TE) { + if (data->id == (*idpoin)) + data->is_dependent = 1; + } +} + void DAG_id_flush_update(ID *id, short flag) { Main *bmain= G.main; @@ -2271,7 +2312,7 @@ void DAG_id_flush_update(ID *id, short flag) /* set flags & pointcache for object */ if(GS(id->name) == ID_OB) { ob= (Object*)id; - ob->recalc |= (flag & OB_RECALC); + ob->recalc |= (flag & OB_RECALC_ALL); BKE_ptcache_object_reset(sce, ob, PTCACHE_RESET_DEPSGRAPH); if(flag & OB_RECALC_DATA) { @@ -2279,15 +2320,10 @@ void DAG_id_flush_update(ID *id, short flag) id= ob->data; /* no point in trying in this cases */ - if(!id || id->us <= 1) - id= NULL; - /* curves and surfaces only need to mark one object, since - otherwise cu->displist would be computed multiple times */ - else if(ob->type==OB_CURVE || ob->type==OB_SURF) - id= NULL; - /* also for locked shape keys we make an exception */ - else if(ob_get_key(ob) && (ob->shapeflag & OB_SHAPE_LOCK)) + if(id && id->us <= 1) { + dag_editors_update(bmain, id); id= NULL; + } } } @@ -2296,25 +2332,44 @@ void DAG_id_flush_update(ID *id, short flag) idtype= GS(id->name); if(ELEM7(idtype, ID_ME, ID_CU, ID_MB, ID_LA, ID_LT, ID_CA, ID_AR)) { + int first_ob= 1; for(obt=bmain->object.first; obt; obt= obt->id.next) { if(!(ob && obt == ob) && obt->data == id) { + + /* try to avoid displist recalculation for linked curves */ + if (!first_ob && ELEM(obt->type, OB_CURVE, OB_SURF)) { + /* if curve object has got derivedFinal it means this + object has got constructive modifiers and object + should be recalculated anyhow */ + if (!obt->derivedFinal) + continue; + } + obt->recalc |= OB_RECALC_DATA; BKE_ptcache_object_reset(sce, obt, PTCACHE_RESET_DEPSGRAPH); - /* for these we only flag one object, otherwise cu->displist - would be computed multiple times */ - if(obt->type==OB_CURVE || obt->type==OB_SURF) - break; + first_ob= 0; } } } + /* set flags based on textures - can influence depgraph via modifiers */ + if(idtype == ID_TE) { + for(obt=bmain->object.first; obt; obt= obt->id.next) { + struct { ID *id; int is_dependent; } data = {id, 0}; + + modifiers_foreachIDLink(obt, dag_id_flush_update__isDependentTexture, &data); + if (data.is_dependent) + obt->recalc |= OB_RECALC_DATA; + } + } + /* set flags based on ShapeKey */ if(idtype == ID_KE) { for(obt=bmain->object.first; obt; obt= obt->id.next) { Key *key= ob_get_key(obt); if(!(ob && obt == ob) && ((ID *)key == id)) { - obt->flag |= (OB_RECALC|OB_RECALC_DATA); + obt->flag |= (OB_RECALC_OB|OB_RECALC_DATA); BKE_ptcache_object_reset(sce, obt, PTCACHE_RESET_DEPSGRAPH); } } @@ -2327,7 +2382,7 @@ void DAG_id_flush_update(ID *id, short flag) for(psys=obt->particlesystem.first; psys; psys=psys->next) { if(&psys->part->id == id) { BKE_ptcache_object_reset(sce, obt, PTCACHE_RESET_DEPSGRAPH); - obt->recalc |= (flag & OB_RECALC); + obt->recalc |= (flag & OB_RECALC_ALL); psys->recalc |= (flag & PSYS_RECALC); } } @@ -2407,7 +2462,7 @@ void DAG_id_update_flags(ID *id) GroupObject *go; /* primitive; tag all... this call helps building groups for particles */ for(go= group->gobject.first; go; go= go->next) - go->ob->recalc= OB_RECALC; + go->ob->recalc= OB_RECALC_ALL; } } else { |