diff options
Diffstat (limited to 'source/blender/blenkernel/intern/object_dupli.c')
-rw-r--r-- | source/blender/blenkernel/intern/object_dupli.c | 122 |
1 files changed, 77 insertions, 45 deletions
diff --git a/source/blender/blenkernel/intern/object_dupli.c b/source/blender/blenkernel/intern/object_dupli.c index 24a5f7e849b..3ee6cb9e85d 100644 --- a/source/blender/blenkernel/intern/object_dupli.c +++ b/source/blender/blenkernel/intern/object_dupli.c @@ -62,6 +62,7 @@ #include "BKE_lattice.h" #include "BKE_main.h" #include "BKE_mesh.h" +#include "BKE_mesh_sample.h" #include "BKE_object.h" #include "BKE_particle.h" #include "BKE_scene.h" @@ -1601,13 +1602,56 @@ static int count_hair_verts(ParticleSystem *psys) return numverts; } +static void dupli_strands_data_update(CacheLibrary *cachelib, DupliObjectData *data, + DupliObject *dob, bool calc_strands_base) { + ParticleSystem *psys; + for (psys = dob->ob->particlesystem.first; psys; psys = psys->next) { + if (cachelib->data_types & CACHE_TYPE_HAIR) { + if (psys->part && psys->part->type == PART_HAIR) { + int numstrands = psys->totpart; + int numverts = count_hair_verts(psys); + ParticleData *pa; + HairKey *hkey; + int p, k; + + Strands *strands = BKE_strands_new(numstrands, numverts); + StrandsCurve *scurve = strands->curves; + StrandsVertex *svert = strands->verts; + + for (p = 0, pa = psys->particles; p < psys->totpart; ++p, ++pa) { + float hairmat[4][4]; + psys_mat_hair_to_object(dob->ob, data->dm, psys->part->from, pa, hairmat); + + scurve->numverts = pa->totkey; + copy_m3_m4(scurve->root_matrix, hairmat); + BKE_mesh_sample_from_particle(&scurve->msurf, psys, data->dm, pa); + + for (k = 0, hkey = pa->hair; k < pa->totkey; ++k, ++hkey) { + copy_v3_v3(svert->co, hkey->co); + if (calc_strands_base) + copy_v3_v3(svert->base, hkey->co); + svert->time = hkey->time; + svert->weight = hkey->weight; + ++svert; + } + ++scurve; + } + + BKE_dupli_object_data_add_strands(data, psys->name, strands); + } + } + } +} + typedef struct DupliObjectDataFromGroupState { EvaluationContext *eval_ctx; Scene *scene; + CacheLibrary *cachelib; + bool calc_strands_base; } DupliObjectDataFromGroupState; typedef struct DupliObjectDataFromGroupTask { - Object *object; + DupliObject *dob; DupliObjectData *data; } DupliObjectDataFromGroupTask; @@ -1615,18 +1659,21 @@ static void dupli_object_data_from_group_func(TaskPool *pool, void *taskdata, in { DupliObjectDataFromGroupState *state = (DupliObjectDataFromGroupState *)BLI_task_pool_userdata(pool); DupliObjectDataFromGroupTask *task = (DupliObjectDataFromGroupTask *)taskdata; + Object *object = task->dob->ob; DerivedMesh *dm; if (state->eval_ctx->mode == DAG_EVAL_RENDER) { - dm = mesh_create_derived_render(state->scene, task->object, CD_MASK_BAREMESH); + dm = mesh_create_derived_render(state->scene, object, CD_MASK_BAREMESH); } else { - dm = mesh_create_derived_view(state->scene, task->object, CD_MASK_BAREMESH); + dm = mesh_create_derived_view(state->scene, object, CD_MASK_BAREMESH); } if (dm != NULL) { BKE_dupli_object_data_set_mesh(task->data, dm); } + + dupli_strands_data_update(state->cachelib, task->data, task->dob, state->calc_strands_base); } void BKE_dupli_cache_from_group(Scene *scene, Group *group, CacheLibrary *cachelib, DupliCache *dupcache, EvaluationContext *eval_ctx, bool calc_strands_base) @@ -1651,62 +1698,29 @@ void BKE_dupli_cache_from_group(Scene *scene, Group *group, CacheLibrary *cachel state.eval_ctx = eval_ctx; state.scene = scene; + state.cachelib = cachelib; + state.calc_strands_base = calc_strands_base; task_pool = BLI_task_pool_create(task_scheduler, &state); for (dob = dupcache->duplilist.first; dob; dob = dob->next) { DupliObjectData *data = BKE_dupli_cache_find_data(dupcache, dob->ob); if (!data) { - ParticleSystem *psys; - + bool strands_handled = false; data = dupli_cache_add_object_data(dupcache, dob->ob); - if (cachelib->data_types & CACHE_TYPE_DERIVED_MESH) { if (dob->ob->type == OB_MESH) { /* TODO(sergey): Consider using memory pool instead. */ DupliObjectDataFromGroupTask *task = MEM_mallocN(sizeof(DupliObjectDataFromGroupTask), - "dupcache task"); - task->object = dob->ob; + "dupcache task"); + task->dob = dob; task->data = data; BLI_task_pool_push(task_pool, dupli_object_data_from_group_func, task, true, TASK_PRIORITY_LOW); + /* Task is getting care of strands as well. */ + strands_handled = true; } } - - for (psys = dob->ob->particlesystem.first; psys; psys = psys->next) { - if (cachelib->data_types & CACHE_TYPE_HAIR) { - if (psys->part && psys->part->type == PART_HAIR) { - int numstrands = psys->totpart; - int numverts = count_hair_verts(psys); - ParticleData *pa; - HairKey *hkey; - int p, k; - - Strands *strands = BKE_strands_new(numstrands, numverts); - StrandsCurve *scurve = strands->curves; - StrandsVertex *svert = strands->verts; - - for (p = 0, pa = psys->particles; p < psys->totpart; ++p, ++pa) { - float hairmat[4][4]; - psys_mat_hair_to_object(dob->ob, data->dm, psys->part->from, pa, hairmat); - - scurve->numverts = pa->totkey; - copy_m3_m4(scurve->root_matrix, hairmat); - - for (k = 0, hkey = pa->hair; k < pa->totkey; ++k, ++hkey) { - copy_v3_v3(svert->co, hkey->co); - if (calc_strands_base) - copy_v3_v3(svert->base, hkey->co); - svert->time = hkey->time; - svert->weight = hkey->weight; - - ++svert; - } - - ++scurve; - } - - BKE_dupli_object_data_add_strands(data, psys->name, strands); - } - } + if (!strands_handled) { + dupli_strands_data_update(cachelib, data, dob, calc_strands_base); } } } @@ -1717,12 +1731,26 @@ void BKE_dupli_cache_from_group(Scene *scene, Group *group, CacheLibrary *cachel /* ------------------------------------------------------------------------- */ +static void object_dupli_cache_apply_modifiers(Object *ob, Scene *scene, eCacheLibrary_EvalMode eval_mode) +{ + CacheLibrary *cachelib = ob->cache_library; + int frame = scene->r.cfra; + CacheProcessData process_data; + + process_data.lay = ob->lay; + copy_m4_m4(process_data.mat, ob->obmat); + process_data.dupcache = ob->dup_cache; + + BKE_cache_process_dupli_cache(cachelib, &process_data, scene, ob->dup_group, (float)frame, (float)frame, eval_mode); +} + void BKE_object_dupli_cache_update(Scene *scene, Object *ob, EvaluationContext *eval_ctx, float frame) { const eCacheLibrary_EvalMode eval_mode = eval_ctx->mode == DAG_EVAL_RENDER ? CACHE_LIBRARY_EVAL_RENDER : CACHE_LIBRARY_EVAL_REALTIME; bool is_dupligroup = (ob->transflag & OB_DUPLIGROUP) && ob->dup_group; bool is_cached = ob->cache_library && (ob->cache_library->source_mode == CACHE_LIBRARY_SOURCE_CACHE || ob->cache_library->display_mode == CACHE_LIBRARY_DISPLAY_RESULT); + bool do_modifiers = ob->cache_library && ob->cache_library->display_mode == CACHE_LIBRARY_DISPLAY_MODIFIERS; /* cache is a group duplicator feature only */ if (is_dupligroup && is_cached) { @@ -1745,6 +1773,10 @@ void BKE_object_dupli_cache_update(Scene *scene, Object *ob, EvaluationContext * if (!(ob->cache_library->flag & CACHE_LIBRARY_BAKING)) { /* TODO at this point we could apply animation offset */ BKE_cache_read_dupli_cache(ob->cache_library, ob->dup_cache, scene, ob->dup_group, frame, eval_mode, true); + + if (do_modifiers) { + object_dupli_cache_apply_modifiers(ob, scene, eval_mode); + } } ob->dup_cache->flag &= ~DUPCACHE_FLAG_DIRTY; |