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.
This commit is contained in:
@@ -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);
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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; a<dl->nr; 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();
|
||||
|
||||
Reference in New Issue
Block a user