diff options
Diffstat (limited to 'source/blender/blenkernel/intern/particle_system.c')
-rw-r--r-- | source/blender/blenkernel/intern/particle_system.c | 103 |
1 files changed, 65 insertions, 38 deletions
diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c index af1db36b648..a8ccd12874e 100644 --- a/source/blender/blenkernel/intern/particle_system.c +++ b/source/blender/blenkernel/intern/particle_system.c @@ -105,13 +105,13 @@ static int get_current_display_percentage(ParticleSystem *psys) return psys->part->disp; } -static void alloc_particles(ParticleSystem *psys, int new_totpart) +static void alloc_particles(Object *ob, ParticleSystem *psys, int new_totpart) { ParticleData *newpars = 0, *pa; - int i, child_nbr, totpart, totsaved = 0; + int i, totpart, totsaved = 0; - if(new_totpart<0){ - if(psys->part->distr==PART_DISTR_GRID){ + if(new_totpart<0) { + if(psys->part->distr==PART_DISTR_GRID) { totpart= psys->part->grid_res; totpart*=totpart*totpart; } @@ -123,7 +123,7 @@ static void alloc_particles(ParticleSystem *psys, int new_totpart) if(totpart) newpars= MEM_callocN(totpart*sizeof(ParticleData), "particles"); - if(psys->particles){ + if(psys->particles) { totsaved=MIN2(psys->totpart,totpart); /*save old pars*/ if(totsaved) @@ -136,16 +136,7 @@ static void alloc_particles(ParticleSystem *psys, int new_totpart) } psys->particles=newpars; - child_nbr= (psys->renderdata)? psys->part->ren_child_nbr: psys->part->child_nbr; - if(child_nbr && psys->part->childtype){ - if(psys->child) - MEM_freeN(psys->child); - psys->child = NULL; - if(totpart) - psys->child= MEM_callocN(totpart*child_nbr*sizeof(ChildParticle), "child_particles"); - psys->totchild=totpart*child_nbr; - } - else if(psys->child){ + if(psys->child) { MEM_freeN(psys->child); psys->child=0; psys->totchild=0; @@ -154,6 +145,32 @@ static void alloc_particles(ParticleSystem *psys, int new_totpart) psys->totpart=totpart; } +static int get_alloc_child_particles_tot(ParticleSystem *psys) +{ + int child_nbr; + + if(!psys->part->childtype) + return 0; + + child_nbr= (psys->renderdata)? psys->part->ren_child_nbr: psys->part->child_nbr; + return psys->totpart*child_nbr; +} + +static void alloc_child_particles(ParticleSystem *psys, int tot) +{ + if(psys->child){ + MEM_freeN(psys->child); + psys->child=0; + psys->totchild=0; + } + + if(psys->part->childtype) { + psys->totchild= tot; + if(psys->totchild) + psys->child= MEM_callocN(psys->totchild*sizeof(ChildParticle), "child_particles"); + } +} + /* only run this if from == PART_FROM_FACE */ void psys_calc_dmfaces(Object *ob, DerivedMesh *dm, ParticleSystem *psys) { @@ -607,7 +624,7 @@ void psys_thread_distribute_particle(ParticleThread *thread, ParticleData *pa, C } mf= dm->getFaceData(dm, ctx->index[p], CD_MFACE); - + //switch(distr){ // case PART_DISTR_JIT: // i=index[p]; @@ -741,12 +758,16 @@ void *exec_distribution(void *data) if(thread->ctx->from == PART_FROM_CHILD) { totpart= psys->totchild; - cpa= psys->child + thread->num; + cpa= psys->child; - rng_skip(thread->rng, 5*thread->num); - for(p=thread->num; p<totpart; p+=thread->tot, cpa+=thread->tot) { - psys_thread_distribute_particle(thread, NULL, cpa, p); - rng_skip(thread->rng, 5*(thread->tot-1)); + for(p=0; p<totpart; p++, cpa++) { + if(thread->ctx->skip) /* simplification skip */ + rng_skip(thread->rng, 5*thread->ctx->skip[p]); + + if((p+thread->num) % thread->tot == 0) + psys_thread_distribute_particle(thread, NULL, cpa, p); + else /* thread skip */ + rng_skip(thread->rng, 5); } } else { @@ -757,7 +778,7 @@ void *exec_distribution(void *data) } return 0; -} +} /* creates a distribution of coordinates on a DerivedMesh */ /* */ @@ -813,7 +834,6 @@ int psys_threads_init_distribution(ParticleThread *threads, DerivedMesh *finaldm if(from==PART_FROM_CHILD){ distr=PART_DISTR_RAND; - cpa=psys->child; if(part->from!=PART_FROM_PARTICLE && part->childtype==PART_CHILD_FACES){ dm= finaldm; children=1; @@ -828,7 +848,7 @@ int psys_threads_init_distribution(ParticleThread *threads, DerivedMesh *finaldm BLI_kdtree_balance(tree); - totpart=psys->totchild; + totpart=get_alloc_child_particles_tot(psys); cfrom=from=PART_FROM_FACE; if(part->flag&PART_CHILD_SEAMS){ @@ -879,6 +899,8 @@ int psys_threads_init_distribution(ParticleThread *threads, DerivedMesh *finaldm /* no need to figure out distribution */ int child_nbr= (psys->renderdata)? part->ren_child_nbr: part->child_nbr; + alloc_child_particles(psys, 1.0f); + cpa=psys->child; for(i=0; i<child_nbr; i++){ for(p=0; p<psys->totpart; p++,cpa++){ float length=2.0; @@ -1100,7 +1122,7 @@ int psys_threads_init_distribution(ParticleThread *threads, DerivedMesh *finaldm sum[0]= 0.0f; for(i=0;i<tot; i++) sum[i+1]= sum[i]+weight[i]*totweight; - + if(part->flag&PART_TRAND){ float pos; @@ -1156,9 +1178,6 @@ int psys_threads_init_distribution(ParticleThread *threads, DerivedMesh *finaldm } /* 5. */ - if(children) - from=PART_FROM_CHILD; - ctx->tree= tree; ctx->seams= seams; ctx->totseam= totseam; @@ -1169,17 +1188,21 @@ int psys_threads_init_distribution(ParticleThread *threads, DerivedMesh *finaldm ctx->jitoff= jitoff; ctx->weight= weight; ctx->maxweight= maxweight; - ctx->from= from; + ctx->from= (children)? PART_FROM_CHILD: from; ctx->cfrom= cfrom; ctx->distr= distr; ctx->dm= dm; ctx->tpars= tpars; - seed= 31415926 + ctx->psys->seed; + if(children) { + totpart= psys_render_simplify_distribution(ctx, totpart); + alloc_child_particles(psys, totpart); + } - if(from!=PART_FROM_CHILD || psys->totchild < 10000) + if(!children || psys->totchild < 10000) totthread= 1; + seed= 31415926 + ctx->psys->seed; for(i=0; i<totthread; i++) { threads[i].rng= rng_new(seed); threads[i].tot= totthread; @@ -1323,6 +1346,7 @@ void psys_threads_free(ParticleThread *threads) if(ctx->jitoff) MEM_freeN(ctx->jitoff); if(ctx->weight) MEM_freeN(ctx->weight); if(ctx->index) MEM_freeN(ctx->index); + if(ctx->skip) MEM_freeN(ctx->skip); if(ctx->seams) MEM_freeN(ctx->seams); //if(ctx->vertpart) MEM_freeN(ctx->vertpart); BLI_kdtree_free(ctx->tree); @@ -4188,13 +4212,16 @@ static void psys_update_path_cache(Object *ob, ParticleSystemModifierData *psmd, if(distr){ if(alloc) - alloc_particles(psys,psys->totpart); + alloc_particles(ob,psys,psys->totpart); - if(psys->totchild && part->childtype){ - distribute_particles(ob,psys,PART_FROM_CHILD); + if(get_alloc_child_particles_tot(psys)) { + /* don't generate children while computing the hair keys */ + if(!(psys->part->type == PART_HAIR) || (psys->flag & PSYS_HAIR_DONE)) { + distribute_particles(ob,psys,PART_FROM_CHILD); - if(part->from!=PART_FROM_PARTICLE && part->childtype==PART_CHILD_FACES && part->parents!=0.0) - psys_find_parents(ob,psmd,psys); + if(part->from!=PART_FROM_PARTICLE && part->childtype==PART_CHILD_FACES && part->parents!=0.0) + psys_find_parents(ob,psmd,psys); + } } } @@ -4413,11 +4440,11 @@ static void system_step(Object *ob, ParticleSystem *psys, ParticleSystemModifier if(init) { if(distr) { if(alloc) - alloc_particles(psys, totpart); + alloc_particles(ob, psys, totpart); distribute_particles(ob, psys, part->from); - if(psys->totchild && part->childtype) + if(get_alloc_child_particles_tot(psys)) distribute_particles(ob, psys, PART_FROM_CHILD); } initialize_all_particles(ob, psys, psmd); |