Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/blenkernel/intern/object_dupli.c')
-rw-r--r--source/blender/blenkernel/intern/object_dupli.c122
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;