From 515592438f0f5665cadbd12c7698554bd2b89146 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Tue, 30 Mar 2010 12:23:13 +0000 Subject: [PATCH] Baking for dupligroup & linked library objects - library data allows pointcache writing (hard to know how this should work long term so ifdef'd for now) - changing the frame now updates the dupligroup objects - BKE_ptcache_ids_from_object(), option to get the id's from duplis note! scene_update_tagged() is called from the main() loop, and runs BKE_ptcache_quick_cache_all(), this could become a performance issue, especially with duplis, should probably not call BKE_ptcache_quick_cache_all() all the time, even when not playing back animation. (commits 27856 by Campbell from render25 branch) --- source/blender/blenkernel/BKE_pointcache.h | 2 +- source/blender/blenkernel/intern/pointcache.c | 36 +++++++++++++++---- source/blender/blenkernel/intern/scene.c | 27 ++++++++++---- source/blender/editors/object/object_edit.c | 2 +- .../blender/editors/physics/particle_edit.c | 2 +- .../editors/physics/physics_pointcache.c | 10 +++--- .../editors/transform/transform_conversions.c | 3 +- .../makesrna/intern/rna_object_force.c | 14 ++++---- 8 files changed, 69 insertions(+), 27 deletions(-) diff --git a/source/blender/blenkernel/BKE_pointcache.h b/source/blender/blenkernel/BKE_pointcache.h index 55f11e1066b..170965a223a 100644 --- a/source/blender/blenkernel/BKE_pointcache.h +++ b/source/blender/blenkernel/BKE_pointcache.h @@ -236,7 +236,7 @@ void BKE_ptcache_id_from_cloth(PTCacheID *pid, struct Object *ob, struct ClothMo void BKE_ptcache_id_from_smoke(PTCacheID *pid, struct Object *ob, struct SmokeModifierData *smd); void BKE_ptcache_id_from_smoke_turbulence(PTCacheID *pid, struct Object *ob, struct SmokeModifierData *smd); -void BKE_ptcache_ids_from_object(struct ListBase *lb, struct Object *ob); +void BKE_ptcache_ids_from_object(struct ListBase *lb, struct Object *ob, struct Scene *scene, int duplis); /***************** Global funcs ****************************/ void BKE_ptcache_remove(void); diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c index cbe294f1347..8efa9e29698 100644 --- a/source/blender/blenkernel/intern/pointcache.c +++ b/source/blender/blenkernel/intern/pointcache.c @@ -48,6 +48,7 @@ #include "WM_api.h" +#include "BKE_anim.h" #include "BKE_blender.h" #include "BKE_cloth.h" #include "BKE_depsgraph.h" @@ -90,6 +91,9 @@ #define PTCACHE_DATA_FROM(data, type, from) if(data[type]) { memcpy(data[type], from, ptcache_data_size[type]); } #define PTCACHE_DATA_TO(data, type, index, to) if(data[type]) { memcpy(to, (char*)data[type] + (index ? index * ptcache_data_size[type] : 0), ptcache_data_size[type]); } +/* could be made into a pointcache option */ +#define DURIAN_POINTCACHE_LIB_OK 1 + int ptcache_data_size[] = { sizeof(int), // BPHYS_DATA_INDEX 3 * sizeof(float), // BPHYS_DATA_LOCATION: @@ -982,7 +986,7 @@ void BKE_ptcache_id_from_cloth(PTCacheID *pid, Object *ob, ClothModifierData *cl pid->info_types= 0; } -void BKE_ptcache_ids_from_object(ListBase *lb, Object *ob) +void BKE_ptcache_ids_from_object(ListBase *lb, Object *ob, Scene *scene, int duplis) { PTCacheID *pid; ParticleSystem *psys; @@ -1024,6 +1028,23 @@ void BKE_ptcache_ids_from_object(ListBase *lb, Object *ob) } } } + + if(scene && (duplis-- > 0) && (ob->transflag & OB_DUPLI)) { + ListBase *lb_dupli_ob; + + if((lb_dupli_ob=object_duplilist(scene, ob))) { + DupliObject *dob; + for(dob= lb_dupli_ob->first; dob; dob= dob->next) { + ListBase lb_dupli_pid; + BKE_ptcache_ids_from_object(&lb_dupli_pid, dob->ob, scene, duplis); + addlisttolist(lb, &lb_dupli_pid); + if(lb_dupli_pid.first) + printf("Adding Dupli\n"); + } + + free_object_duplilist(lb_dupli_ob); /* does restore */ + } + } } @@ -1132,10 +1153,11 @@ static PTCacheFile *ptcache_file_open(PTCacheID *pid, int mode, int cfra) FILE *fp = NULL; char filename[(FILE_MAXDIR+FILE_MAXFILE)*2]; +#ifndef DURIAN_POINTCACHE_LIB_OK /* don't allow writing for linked objects */ if(pid->ob->id.lib && mode == PTCACHE_FILE_WRITE) return NULL; - +#endif if (!G.relbase_valid && (pid->cache->flag & PTCACHE_EXTERNAL)==0) return NULL; /* save blend file before using disk pointcache */ BKE_ptcache_id_filename(pid, filename, cfra, 1, 1); @@ -1873,9 +1895,11 @@ void BKE_ptcache_id_clear(PTCacheID *pid, int mode, int cfra) if(!pid->cache || pid->cache->flag & PTCACHE_BAKED) return; +#ifndef DURIAN_POINTCACHE_LIB_OK /* don't allow clearing for linked objects */ if(pid->ob->id.lib) return; +#endif /*if (!G.relbase_valid) return; *//* save blend file before using pointcache */ @@ -2310,7 +2334,7 @@ static int count_quick_cache(Scene *scene, int *quick_step) for(base = scene->base.first; base; base = base->next) { if(base->object) { - BKE_ptcache_ids_from_object(&pidlist, base->object); + BKE_ptcache_ids_from_object(&pidlist, base->object, scene, MAX_DUPLI_RECUR); for(pid=pidlist.first; pid; pid=pid->next) { if((pid->cache->flag & PTCACHE_BAKED) @@ -2408,7 +2432,7 @@ void BKE_ptcache_make_cache(PTCacheBaker* baker) /* get all pids from the object and search for smoke low res */ ListBase pidlist2; PTCacheID *pid2; - BKE_ptcache_ids_from_object(&pidlist2, pid->ob); + BKE_ptcache_ids_from_object(&pidlist2, pid->ob, scene, MAX_DUPLI_RECUR); for(pid2=pidlist2.first; pid2; pid2=pid2->next) { if(pid2->type == PTCACHE_TYPE_SMOKE_DOMAIN) { @@ -2443,7 +2467,7 @@ void BKE_ptcache_make_cache(PTCacheBaker* baker) } else for(base=scene->base.first; base; base= base->next) { /* cache/bake everything in the scene */ - BKE_ptcache_ids_from_object(&pidlist, base->object); + BKE_ptcache_ids_from_object(&pidlist, base->object, scene, MAX_DUPLI_RECUR); for(pid=pidlist.first; pid; pid=pid->next) { cache = pid->cache; @@ -2525,7 +2549,7 @@ void BKE_ptcache_make_cache(PTCacheBaker* baker) } } else for(base=scene->base.first; base; base= base->next) { - BKE_ptcache_ids_from_object(&pidlist, base->object); + BKE_ptcache_ids_from_object(&pidlist, base->object, scene, MAX_DUPLI_RECUR); for(pid=pidlist.first; pid; pid=pid->next) { /* skip hair particles */ diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index dd2a3143d3d..51b18800474 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -891,15 +891,18 @@ float frame_to_float (Scene *scene, int cfra) /* see also bsystem_time in objec return ctime; } -static void scene_update_newframe(Scene *sce, unsigned int lay) +static void scene_update_newframe(Scene *scene, unsigned int lay) { Base *base; Object *ob; - for(base= sce->base.first; base; base= base->next) { + for(base= scene->base.first; base; base= base->next) { ob= base->object; - object_handle_update(sce, ob); // bke_object.h + object_handle_update(scene, ob); // bke_object.h + + if(ob->dup_group && (ob->transflag & OB_DUPLIGROUP)) + group_handle_recalc_and_update(scene, ob, ob->dup_group); /* only update layer when an ipo */ // XXX old animation system @@ -914,6 +917,7 @@ void scene_update_tagged(Scene *scene) { Scene *sce; Base *base; + Object *ob; float ctime = frame_to_float(scene, scene->r.cfra); /* update all objects: drivers, matrices, displists, etc. flags set @@ -922,12 +926,23 @@ void scene_update_tagged(Scene *scene) /* sets first, we allow per definition current scene to have dependencies on sets, but not the other way around. */ if(scene->set) { - for(SETLOOPER(scene->set, base)) - object_handle_update(scene, base->object); + for(SETLOOPER(scene->set, base)) { + ob= base->object; + + object_handle_update(scene, ob); + + if(ob->dup_group && (ob->transflag & OB_DUPLIGROUP)) + group_handle_recalc_and_update(scene, ob, ob->dup_group); + } } for(base= scene->base.first; base; base= base->next) { - object_handle_update(scene, base->object); + ob= base->object; + + object_handle_update(scene, ob); + + if(ob->dup_group && (ob->transflag & OB_DUPLIGROUP)) + group_handle_recalc_and_update(scene, ob, ob->dup_group); } /* recalc scene animation data here (for sequencer) */ diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c index dcf4c072f92..a2ad5cf4471 100644 --- a/source/blender/editors/object/object_edit.c +++ b/source/blender/editors/object/object_edit.c @@ -285,7 +285,7 @@ void ED_object_exit_editmode(bContext *C, int flag) scene->obedit= NULL; // XXX for context /* flag object caches as outdated */ - BKE_ptcache_ids_from_object(&pidlist, obedit); + BKE_ptcache_ids_from_object(&pidlist, obedit, NULL, 0); for(pid=pidlist.first; pid; pid=pid->next) { if(pid->type != PTCACHE_TYPE_PARTICLES) /* particles don't need reset on geometry change */ pid->cache->flag |= PTCACHE_OUTDATED; diff --git a/source/blender/editors/physics/particle_edit.c b/source/blender/editors/physics/particle_edit.c index 43fc4985d3d..d20e0e87934 100644 --- a/source/blender/editors/physics/particle_edit.c +++ b/source/blender/editors/physics/particle_edit.c @@ -203,7 +203,7 @@ static PTCacheEdit *pe_get_current(Scene *scene, Object *ob, int create) pset->scene = scene; pset->object = ob; - BKE_ptcache_ids_from_object(&pidlist, ob); + BKE_ptcache_ids_from_object(&pidlist, ob, NULL, 0); /* in the case of only one editable thing, set pset->edittype accordingly */ if(pidlist.first && pidlist.first == pidlist.last) { diff --git a/source/blender/editors/physics/physics_pointcache.c b/source/blender/editors/physics/physics_pointcache.c index 19f4d8457c1..57a123d8f17 100644 --- a/source/blender/editors/physics/physics_pointcache.c +++ b/source/blender/editors/physics/physics_pointcache.c @@ -33,6 +33,7 @@ #include "DNA_scene_types.h" +#include "BKE_anim.h" #include "BKE_context.h" #include "BKE_particle.h" #include "BKE_report.h" @@ -125,7 +126,7 @@ static int ptcache_free_bake_all_exec(bContext *C, wmOperator *op) ListBase pidlist; for(base=scene->base.first; base; base= base->next) { - BKE_ptcache_ids_from_object(&pidlist, base->object); + BKE_ptcache_ids_from_object(&pidlist, base->object, scene, MAX_DUPLI_RECUR); for(pid=pidlist.first; pid; pid=pid->next) { pid->cache->flag &= ~PTCACHE_BAKED; @@ -178,7 +179,7 @@ static int ptcache_bake_exec(bContext *C, wmOperator *op) PTCacheID *pid; ListBase pidlist; - BKE_ptcache_ids_from_object(&pidlist, ob); + BKE_ptcache_ids_from_object(&pidlist, ob, scene, MAX_DUPLI_RECUR); for(pid=pidlist.first; pid; pid=pid->next) { if(pid->cache == cache) @@ -290,7 +291,7 @@ static int ptcache_add_new_exec(bContext *C, wmOperator *op) PTCacheID *pid; ListBase pidlist; - BKE_ptcache_ids_from_object(&pidlist, ob); + BKE_ptcache_ids_from_object(&pidlist, ob, scene, MAX_DUPLI_RECUR); for(pid=pidlist.first; pid; pid=pid->next) { if(pid->cache == cache) { @@ -308,12 +309,13 @@ static int ptcache_add_new_exec(bContext *C, wmOperator *op) static int ptcache_remove_exec(bContext *C, wmOperator *op) { PointerRNA ptr= CTX_data_pointer_get_type(C, "PointCache", &RNA_PointCache); + Scene *scene= CTX_data_scene(C); Object *ob= ptr.id.data; PointCache *cache= ptr.data; PTCacheID *pid; ListBase pidlist; - BKE_ptcache_ids_from_object(&pidlist, ob); + BKE_ptcache_ids_from_object(&pidlist, ob, scene, MAX_DUPLI_RECUR); for(pid=pidlist.first; pid; pid=pid->next) { if(pid->cache == cache) { diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index 96616f57575..f9c537e1c20 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -48,6 +48,7 @@ #include "DNA_view3d_types.h" #include "DNA_constraint_types.h" +#include "BKE_anim.h" #include "BKE_action.h" #include "BKE_armature.h" #include "BKE_blender.h" @@ -4940,7 +4941,7 @@ void special_aftertrans_update(bContext *C, TransInfo *t) continue; /* flag object caches as outdated */ - BKE_ptcache_ids_from_object(&pidlist, ob); + BKE_ptcache_ids_from_object(&pidlist, ob, t->scene, MAX_DUPLI_RECUR); for(pid=pidlist.first; pid; pid=pid->next) { if(pid->type != PTCACHE_TYPE_PARTICLES) /* particles don't need reset on geometry change */ pid->cache->flag |= PTCACHE_OUTDATED; diff --git a/source/blender/makesrna/intern/rna_object_force.c b/source/blender/makesrna/intern/rna_object_force.c index 296179db238..4a74833bf7b 100644 --- a/source/blender/makesrna/intern/rna_object_force.c +++ b/source/blender/makesrna/intern/rna_object_force.c @@ -108,7 +108,7 @@ static void rna_Cache_change(Main *bmain, Scene *scene, PointerRNA *ptr) cache->flag |= PTCACHE_OUTDATED; - BKE_ptcache_ids_from_object(&pidlist, ob); + BKE_ptcache_ids_from_object(&pidlist, ob, NULL, 0); DAG_id_flush_update(&ob->id, OB_RECALC_DATA); @@ -133,7 +133,7 @@ static void rna_Cache_toggle_disk_cache(Main *bmain, Scene *scene, PointerRNA *p if(!ob) return; - BKE_ptcache_ids_from_object(&pidlist, ob); + BKE_ptcache_ids_from_object(&pidlist, ob, NULL, 0); for(pid=pidlist.first; pid; pid=pid->next) { if(pid->cache==cache) @@ -160,7 +160,7 @@ static void rna_Cache_idname_change(Main *bmain, Scene *scene, PointerRNA *ptr) /* TODO: check for proper characters */ - BKE_ptcache_ids_from_object(&pidlist, ob); + BKE_ptcache_ids_from_object(&pidlist, ob, NULL, 0); if(cache->flag & PTCACHE_EXTERNAL) { for(pid=pidlist.first; pid; pid=pid->next) { @@ -219,7 +219,7 @@ static void rna_Cache_list_begin(CollectionPropertyIterator *iter, PointerRNA *p PTCacheID *pid; ListBase pidlist; - BKE_ptcache_ids_from_object(&pidlist, ob); + BKE_ptcache_ids_from_object(&pidlist, ob, NULL, 0); for(pid=pidlist.first; pid; pid=pid->next) { if(pid->cache == cache) { @@ -237,7 +237,7 @@ static void rna_Cache_active_point_cache_index_range(PointerRNA *ptr, int *min, PTCacheID *pid; ListBase pidlist; - BKE_ptcache_ids_from_object(&pidlist, ob); + BKE_ptcache_ids_from_object(&pidlist, ob, NULL, 0); *min= 0; *max= 0; @@ -261,7 +261,7 @@ static int rna_Cache_active_point_cache_index_get(PointerRNA *ptr) ListBase pidlist; int num = 0; - BKE_ptcache_ids_from_object(&pidlist, ob); + BKE_ptcache_ids_from_object(&pidlist, ob, NULL, 0); for(pid=pidlist.first; pid; pid=pid->next) { if(pid->cache == cache) { @@ -282,7 +282,7 @@ static void rna_Cache_active_point_cache_index_set(struct PointerRNA *ptr, int v PTCacheID *pid; ListBase pidlist; - BKE_ptcache_ids_from_object(&pidlist, ob); + BKE_ptcache_ids_from_object(&pidlist, ob, NULL, 0); for(pid=pidlist.first; pid; pid=pid->next) { if(pid->cache == cache) {