From 8517a7a3cd93532ef1ff53ccbf07e8fc14a5109e Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Mon, 28 Jun 2010 11:07:02 +0000 Subject: Fix #20965: metaballs partticles and volume material crash rendering Fix #21187: 2.5svn26947 - particles + meta sphere = crash in rendering Use separated displists for mballs in view3d and render stuff. Do not recalculate displist for view3d while rendering - mball.c uses several global variables which shouldn't be accepted from parallel threads. --- source/blender/blenkernel/BKE_displist.h | 1 + source/blender/blenkernel/BKE_lattice.h | 2 +- source/blender/blenkernel/BKE_mball.h | 4 +- source/blender/blenkernel/intern/displist.c | 16 +++++-- source/blender/blenkernel/intern/lattice.c | 4 +- source/blender/blenkernel/intern/mball.c | 10 ++--- .../blender/render/intern/source/convertblender.c | 50 +++++++++------------- 7 files changed, 43 insertions(+), 44 deletions(-) (limited to 'source/blender') diff --git a/source/blender/blenkernel/BKE_displist.h b/source/blender/blenkernel/BKE_displist.h index 9e75e55adf6..df0627f61ba 100644 --- a/source/blender/blenkernel/BKE_displist.h +++ b/source/blender/blenkernel/BKE_displist.h @@ -93,6 +93,7 @@ extern void makeDispListCurveTypes(struct Scene *scene, struct Object *ob, int f extern void makeDispListCurveTypes_forRender(struct Scene *scene, struct Object *ob, struct ListBase *dispbase, struct DerivedMesh **derivedFinal, int forOrco); extern void makeDispListCurveTypes_forOrco(struct Scene *scene, struct Object *ob, struct ListBase *dispbase); extern void makeDispListMBall(struct Scene *scene, struct Object *ob); +extern void makeDispListMBall_forRender(struct Scene *scene, struct Object *ob, struct ListBase *dispbase); extern void shadeDispList(struct Scene *scene, struct Base *base); extern void shadeMeshMCol(struct Scene *scene, struct Object *ob, struct Mesh *me); diff --git a/source/blender/blenkernel/BKE_lattice.h b/source/blender/blenkernel/BKE_lattice.h index f35dff53cd5..880f3f7e724 100644 --- a/source/blender/blenkernel/BKE_lattice.h +++ b/source/blender/blenkernel/BKE_lattice.h @@ -49,7 +49,7 @@ void init_latt_deform(struct Object *oblatt, struct Object *ob); void calc_latt_deform(struct Object *, float *co, float weight); void end_latt_deform(struct Object *); -int object_deform_mball(struct Object *ob); +int object_deform_mball(struct Object *ob, struct ListBase *dispbase); void outside_lattice(struct Lattice *lt); void curve_deform_verts(struct Scene *scene, struct Object *cuOb, struct Object *target, diff --git a/source/blender/blenkernel/BKE_mball.h b/source/blender/blenkernel/BKE_mball.h index 130969d4892..5d41f4e374e 100644 --- a/source/blender/blenkernel/BKE_mball.h +++ b/source/blender/blenkernel/BKE_mball.h @@ -164,12 +164,12 @@ struct MetaBall *add_mball(char *name); struct MetaBall *copy_mball(struct MetaBall *mb); void make_local_mball(struct MetaBall *mb); void tex_space_mball(struct Object *ob); -float *make_orco_mball(struct Object *ob); +float *make_orco_mball(struct Object *ob, struct ListBase *dispbase); void copy_mball_properties(struct Scene *scene, struct Object *active_object); struct Object *find_basis_mball(struct Scene *scene, struct Object *ob); int is_basis_mball(struct Object *ob); int is_mball_basis_for(struct Object *ob1, struct Object *ob2); -void metaball_polygonize(struct Scene *scene, struct Object *ob); +void metaball_polygonize(struct Scene *scene, struct Object *ob, struct ListBase *dispbase); void calc_mballco(struct MetaElem *ml, float *vec); float densfunc(struct MetaElem *ball, float x, float y, float z); float metaball(float x, float y, float z); diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c index a958d8c353b..716d3110bc3 100644 --- a/source/blender/blenkernel/intern/displist.c +++ b/source/blender/blenkernel/intern/displist.c @@ -1172,20 +1172,30 @@ void makeDispListMBall(Scene *scene, Object *ob) { if(!ob || ob->type!=OB_MBALL) return; + // XXX: mball stuff uses plenty of global variables + // while this is unchanged updating during render is unsafe + if(G.rendering) return; + freedisplist(&(ob->disp)); - + if(ob->type==OB_MBALL) { if(ob==find_basis_mball(scene, ob)) { - metaball_polygonize(scene, ob); + metaball_polygonize(scene, ob, &ob->disp); tex_space_mball(ob); - object_deform_mball(ob); + object_deform_mball(ob, &ob->disp); } } boundbox_displist(ob); } +void makeDispListMBall_forRender(Scene *scene, Object *ob, ListBase *dispbase) +{ + metaball_polygonize(scene, ob, dispbase); + object_deform_mball(ob, dispbase); +} + static ModifierData *curve_get_tesselate_point(Scene *scene, Object *ob, int forRender, int editmode) { ModifierData *md = modifiers_getVirtualModifierList(ob); diff --git a/source/blender/blenkernel/intern/lattice.c b/source/blender/blenkernel/intern/lattice.c index 1954bac7e93..5824afd9ded 100644 --- a/source/blender/blenkernel/intern/lattice.c +++ b/source/blender/blenkernel/intern/lattice.c @@ -869,12 +869,12 @@ void lattice_deform_verts(Object *laOb, Object *target, DerivedMesh *dm, end_latt_deform(laOb); } -int object_deform_mball(Object *ob) +int object_deform_mball(Object *ob, ListBase *dispbase) { if(ob->parent && ob->parent->type==OB_LATTICE && ob->partype==PARSKEL) { DispList *dl; - for (dl=ob->disp.first; dl; dl=dl->next) { + for (dl=dispbase->first; dl; dl=dl->next) { lattice_deform_verts(ob->parent, ob, NULL, (float(*)[3]) dl->verts, dl->nr, NULL); } diff --git a/source/blender/blenkernel/intern/mball.c b/source/blender/blenkernel/intern/mball.c index a15dad16e41..da9740a1486 100644 --- a/source/blender/blenkernel/intern/mball.c +++ b/source/blender/blenkernel/intern/mball.c @@ -226,7 +226,7 @@ void tex_space_mball(Object *ob) boundbox_set_from_min_max(bb, min, max); } -float *make_orco_mball(Object *ob) +float *make_orco_mball(Object *ob, ListBase *dispbase) { BoundBox *bb; DispList *dl; @@ -243,7 +243,7 @@ float *make_orco_mball(Object *ob) loc[2]= (bb->vec[0][2]+bb->vec[1][2])/2.0f; size[2]= bb->vec[1][2]-loc[2]; - dl= ob->disp.first; + dl= dispbase->first; orcodata= MEM_mallocN(sizeof(float)*3*dl->nr, "MballOrco"); data= dl->verts; @@ -2088,7 +2088,7 @@ void init_metaball_octal_tree(int depth) subdivide_metaball_octal_node(node, size[0], size[1], size[2], metaball_tree->depth); } -void metaball_polygonize(Scene *scene, Object *ob) +void metaball_polygonize(Scene *scene, Object *ob, ListBase *dispbase) { PROCESS mbproc; MetaBall *mb; @@ -2105,7 +2105,6 @@ void metaball_polygonize(Scene *scene, Object *ob) object_scale_to_mat3(ob, smat); - freedisplist(&ob->disp); curindex= totindex= 0; indices= 0; thresh= mb->thresh; @@ -2174,9 +2173,8 @@ void metaball_polygonize(Scene *scene, Object *ob) } if(curindex) { - dl= MEM_callocN(sizeof(DispList), "mbaldisp"); - BLI_addtail(&ob->disp, dl); + BLI_addtail(dispbase, dl); dl->type= DL_INDEX4; dl->nr= mbproc.vertices.count; dl->parts= curindex; diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c index eaef6571c4f..582b5926509 100644 --- a/source/blender/render/intern/source/convertblender.c +++ b/source/blender/render/intern/source/convertblender.c @@ -851,25 +851,23 @@ static void autosmooth(Render *re, ObjectRen *obr, float mat[][4], int degr) static float *get_object_orco(Render *re, Object *ob) { float *orco; - + if (!re->orco_hash) re->orco_hash = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "get_object_orco gh"); - + orco = BLI_ghash_lookup(re->orco_hash, ob); - + if (!orco) { if (ELEM(ob->type, OB_CURVE, OB_FONT)) { orco = make_orco_curve(re->scene, ob); } else if (ob->type==OB_SURF) { orco = make_orco_surf(ob); - } else if (ob->type==OB_MBALL) { - orco = make_orco_mball(ob); } - + if (orco) BLI_ghash_insert(re->orco_hash, ob, orco); } - + return orco; } @@ -2369,6 +2367,7 @@ static void init_render_mball(Render *re, ObjectRen *obr) Material *ma; float *data, *nors, *orco, mat[4][4], imat[3][3], xn, yn, zn; int a, need_orco, vlakindex, *index; + ListBase dispbase= {NULL, NULL}; if (ob!=find_basis_mball(re->scene, ob)) return; @@ -2383,14 +2382,22 @@ static void init_render_mball(Render *re, ObjectRen *obr) if(ma->texco & TEXCO_ORCO) { need_orco= 1; } - - makeDispListMBall(re->scene, ob); - dl= ob->disp.first; + + makeDispListMBall_forRender(re->scene, ob, &dispbase); + dl= dispbase.first; if(dl==0) return; data= dl->verts; nors= dl->nors; - orco= get_object_orco(re, ob); + if(need_orco) { + orco= get_object_orco(re, ob); + + if (!orco) { + /* orco hasn't been found in cache - create new one and add to cache */ + orco= make_orco_mball(ob, &dispbase); + set_object_orco(re, ob, orco); + } + } for(a=0; anr; a++, data+=3, nors+=3, orco+=3) { @@ -2447,10 +2454,7 @@ static void init_render_mball(Render *re, ObjectRen *obr) } /* enforce display lists remade */ - freedisplist(&ob->disp); - - /* this enforces remake for real, orco displist is small (in scale) */ - ob->recalc |= OB_RECALC_DATA; + freedisplist(&dispbase); } /* ------------------------------------------------------------------------- */ @@ -4545,7 +4549,6 @@ static void init_render_object(Render *re, Object *ob, Object *par, DupliObject void RE_Database_Free(Render *re) { - Object *ob = NULL; LampRen *lar; /* statistics for debugging render memory usage */ @@ -4572,21 +4575,8 @@ void RE_Database_Free(Render *re) BLI_freelistN(&re->lights); free_renderdata_tables(re); - - /* free orco. check all objects because of duplis and sets */ - ob= G.main->object.first; - while(ob) { - if(ob->type==OB_MBALL) { - if(ob->disp.first && ob->disp.first!=ob->disp.last) { - DispList *dl= ob->disp.first; - BLI_remlink(&ob->disp, dl); - freedisplist(&ob->disp); - BLI_addtail(&ob->disp, dl); - } - } - ob= ob->id.next; - } + /* free orco */ free_mesh_orco_hash(re); #if 0 /* radio can be redone better */ end_radio_render(); -- cgit v1.2.3