From 54b2127fadd53ccabeeee6b7bc75a10495643255 Mon Sep 17 00:00:00 2001 From: Janne Karhu Date: Sat, 12 Feb 2011 21:54:50 +0000 Subject: [PATCH] Fix for [#25857] create_dupli_list incorrect behaviour with particle systems * Particle duplis are now always created with render percentage if G.rendering is set. * This is not yet a perfect solution (hair for example won't yet work correctly), but it's good to have even partial functionality here until a proper way to handle this is implemented. --- source/blender/blenkernel/intern/anim.c | 7 ++- .../blender/makesrna/intern/rna_object_api.c | 50 ++++++++++++++++++- 2 files changed, 54 insertions(+), 3 deletions(-) diff --git a/source/blender/blenkernel/intern/anim.c b/source/blender/blenkernel/intern/anim.c index ab1da04e683..2c52e0b0c49 100644 --- a/source/blender/blenkernel/intern/anim.c +++ b/source/blender/blenkernel/intern/anim.c @@ -1173,6 +1173,8 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p int a, b, counter, hair = 0; int totpart, totchild, totgroup=0, pa_num; + int no_draw_flag = PARS_UNEXIST; + if(psys==0) return; /* simple preventing of too deep nested groups */ @@ -1185,6 +1187,9 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p if(!psys_check_enabled(par, psys)) return; + + if(G.rendering == 0) + no_draw_flag |= PARS_NO_DISP; ctime = bsystem_time(scene, par, (float)scene->r.cfra, 0.0); @@ -1280,7 +1285,7 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p for(pa=psys->particles,counter=0; aflag & (PARS_UNEXIST+PARS_NO_DISP)) + if(pa->flag & no_draw_flag) continue; pa_num = pa->num; diff --git a/source/blender/makesrna/intern/rna_object_api.c b/source/blender/makesrna/intern/rna_object_api.c index 468a97f5269..ac4b86b4036 100644 --- a/source/blender/makesrna/intern/rna_object_api.c +++ b/source/blender/makesrna/intern/rna_object_api.c @@ -235,6 +235,50 @@ static Mesh *rna_Object_create_mesh(Object *ob, ReportList *reports, Scene *sce, return tmpmesh; } +/* mostly a copy from convertblender.c */ +static void dupli_render_particle_set(Scene *scene, Object *ob, int level, int enable) +{ + /* ugly function, but we need to set particle systems to their render + * settings before calling object_duplilist, to get render level duplis */ + Group *group; + GroupObject *go; + ParticleSystem *psys; + DerivedMesh *dm; + float mat[4][4]; + + unit_m4(mat); + + if(level >= MAX_DUPLI_RECUR) + return; + + if(ob->transflag & OB_DUPLIPARTS) { + for(psys=ob->particlesystem.first; psys; psys=psys->next) { + if(ELEM(psys->part->ren_as, PART_DRAW_OB, PART_DRAW_GR)) { + if(enable) + psys_render_set(ob, psys, mat, mat, 1, 1, 0.f); + else + psys_render_restore(ob, psys); + } + } + + if(level == 0 && enable) { + /* this is to make sure we get render level duplis in groups: + * the derivedmesh must be created before init_render_mesh, + * since object_duplilist does dupliparticles before that */ + dm = mesh_create_derived_render(scene, ob, CD_MASK_BAREMESH|CD_MASK_MTFACE|CD_MASK_MCOL); + dm->release(dm); + + for(psys=ob->particlesystem.first; psys; psys=psys->next) + psys_get_modifier(ob, psys)->flag &= ~eParticleSystemFlag_psys_updated; + } + } + + if(ob->dup_group==NULL) return; + group= ob->dup_group; + + for(go= group->gobject.first; go; go= go->next) + dupli_render_particle_set(scene, go->ob, level+1, enable); +} /* When no longer needed, duplilist should be freed with Object.free_duplilist */ static void rna_Object_create_duplilist(Object *ob, ReportList *reports, Scene *sce) { @@ -250,9 +294,11 @@ static void rna_Object_create_duplilist(Object *ob, ReportList *reports, Scene * free_object_duplilist(ob->duplilist); ob->duplilist= NULL; } - + if(G.rendering) + dupli_render_particle_set(sce, ob, 0, 1); ob->duplilist= object_duplilist(sce, ob); - + if(G.rendering) + dupli_render_particle_set(sce, ob, 0, 0); /* ob->duplilist should now be freed with Object.free_duplilist */ }