diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index 370186b628d..9a909dde9a4 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.c +++ b/source/blender/blenkernel/intern/DerivedMesh.c @@ -50,6 +50,7 @@ #include "BKE_global.h" #include "BKE_mesh.h" #include "BKE_object.h" +#include "BKE_subsurf.h" #include "BIF_gl.h" #include "BIF_glutil.h" @@ -642,6 +643,8 @@ typedef struct { DispListMesh *dlm; EditMesh *em; + + int needsFree; } SSDerivedMesh; static void ssDM_getMappedVertCoEM(DerivedMesh *dm, void *vert, float co_r[3]) @@ -1013,7 +1016,18 @@ static DispListMesh *ssDM_convertToDispListMesh(DerivedMesh *dm) return displistmesh_copy(ssdm->dlm); } -static DerivedMesh *getSSDerivedMesh(EditMesh *em, DispListMesh *dlm) +static void ssDM_release(DerivedMesh *dm) +{ + SSDerivedMesh *ssdm = (SSDerivedMesh*) dm; + + if (ssdm->needsFree) { + displistmesh_free(ssdm->dlm); + } + + MEM_freeN(dm); +} + +static DerivedMesh *getSSDerivedMesh(EditMesh *em, DispListMesh *dlm, int needsFree) { SSDerivedMesh *ssdm = MEM_mallocN(sizeof(*ssdm), "dm"); @@ -1039,10 +1053,11 @@ static DerivedMesh *getSSDerivedMesh(EditMesh *em, DispListMesh *dlm) ssdm->dm.drawFacesColored = ssDM_drawFacesColored; ssdm->dm.drawFacesEM = ssDM_drawFacesEM; - ssdm->dm.release = MEM_freeN; + ssdm->dm.release = ssDM_release; ssdm->dlm = dlm; ssdm->em = em; + ssdm->needsFree = needsFree; return (DerivedMesh*) ssdm; } @@ -1081,18 +1096,51 @@ DerivedMesh *mesh_get_derived(Object *ob) build_mesh_data(ob); dl= find_displist(&me->disp, DL_MESH); - - if(dl) { + + // XXX, This test should not be here because + // build_mesh_data should have made DLM... problem + // is there is an exception for objects from dupli, + // they only get displist built for first object. + // + // Would work fine except countall gets a derived + // mesh before the displist has been evaluated. + if (dl) { if(G.obedit && me==G.obedit->data) { - return getSSDerivedMesh(G.editMesh, dl->mesh); + return getSSDerivedMesh(G.editMesh, dl->mesh, 0); } else { - return getSSDerivedMesh(NULL, dl->mesh); + return getSSDerivedMesh(NULL, dl->mesh, 0); + } + } + } + + return NULL; +} + +DerivedMesh *mesh_get_derived_render(Object *ob) +{ + Mesh *me= ob->data; + + if (mesh_uses_displist(me)) { + if (me->subdiv==me->subdivr) { + DispList *dl= find_displist(&me->disp, DL_MESH); + + if(G.obedit && me==G.obedit->data) { + return getSSDerivedMesh(G.editMesh, dl->mesh, 0); + } else { + return getSSDerivedMesh(NULL, dl->mesh, 0); + } + } else { + if(G.obedit && me==G.obedit->data) { + DispListMesh *dlm = subsurf_make_dispListMesh_from_editmesh(G.editMesh, me->subdivr, me->flag, me->subsurftype); + return getSSDerivedMesh(G.editMesh, dlm, 1); + } else { + DispListMesh *dlm = subsurf_make_dispListMesh_from_mesh(me, me->subdivr, me->flag); + return getSSDerivedMesh(NULL, dlm, 1); } } - else return NULL; - } else { - return NULL; } + + return NULL; } DerivedMesh *mesh_get_base_derived(Object *ob) diff --git a/source/blender/blenlib/BLI_memarena.h b/source/blender/blenlib/BLI_memarena.h index c00d9b9be51..1423cae52af 100644 --- a/source/blender/blenlib/BLI_memarena.h +++ b/source/blender/blenlib/BLI_memarena.h @@ -44,7 +44,7 @@ * enough to not cause much internal fragmentation, * small enough not to waste resources */ -#define BLI_MEMARENA_STD_BUFSIZE 4096 +#define BLI_MEMARENA_STD_BUFSIZE (1<<14) struct MemArena; typedef struct MemArena MemArena; diff --git a/source/blender/render/extern/include/render.h b/source/blender/render/extern/include/render.h index af4ec2d38ee..77e2125d314 100644 --- a/source/blender/render/extern/include/render.h +++ b/source/blender/render/extern/include/render.h @@ -191,7 +191,6 @@ void ramp_spec_result(float *specr, float *specg, float *specb, ShadeInput *shi) struct VlakRen *RE_findOrAddVlak(int nr); struct VertRen *RE_findOrAddVert(int nr); struct HaloRen *RE_findOrAddHalo(int nr); -struct TFace *RE_findTFace(void); HaloRen *RE_inithalo(struct Material *ma, float *vec, float *vec1, float *orco, float hasize, float vectsize, int seed); diff --git a/source/blender/render/extern/include/render_types.h b/source/blender/render/extern/include/render_types.h index 111662be15b..7b1aeb24009 100644 --- a/source/blender/render/extern/include/render_types.h +++ b/source/blender/render/extern/include/render_types.h @@ -51,17 +51,6 @@ /* ------------------------------------------------------------------------- */ -struct TFace; - -typedef struct TFaceBlock TFaceBlock; - -struct TFaceBlock { - TFaceBlock *next; - - struct TFace *tfaces; - int numAvail; -}; - /* localized texture result data */ typedef struct TexResult { float tin, tr, tg, tb, ta; @@ -111,6 +100,8 @@ typedef struct ShadeInput } ShadeInput; +struct MemArena; + /* here only stuff to initalize the render itself */ typedef struct RE_Render { @@ -150,7 +141,11 @@ typedef struct RE_Render struct VlakRen **blovl; struct VertRen **blove; struct HaloRen **bloha; - struct TFaceBlock *tfaceBlocks; + + /* arena for allocating data for use during render, for + * example dynamic TFaces to go in the VlakRen structure. + */ + struct MemArena *memArena; int *rectaccu; int *rectz; /* z buffer: distance buffer */ diff --git a/source/blender/render/intern/source/initrender.c b/source/blender/render/intern/source/initrender.c index 5612e0a0ed8..b8c60ed3e80 100644 --- a/source/blender/render/intern/source/initrender.c +++ b/source/blender/render/intern/source/initrender.c @@ -442,14 +442,6 @@ void RE_init_render_data(void) void RE_free_render_data() { - TFaceBlock *tfb; - - while (tfb = R.tfaceBlocks) { - R.tfaceBlocks = tfb->next; - MEM_freeN(tfb->tfaces); - MEM_freeN(tfb); - } - MEM_freeN(R.blove); R.blove= NULL; MEM_freeN(R.blovl); diff --git a/source/blender/render/intern/source/renderdatabase.c b/source/blender/render/intern/source/renderdatabase.c index 811d918e04a..ee003964764 100644 --- a/source/blender/render/intern/source/renderdatabase.c +++ b/source/blender/render/intern/source/renderdatabase.c @@ -174,26 +174,6 @@ VlakRen *RE_findOrAddVlak(int nr) return v; } -/* ------------------------------------------------------------------------ */ - -TFace *RE_findTFace(void) -{ - TFaceBlock *tfb = R.tfaceBlocks; - - if (!tfb || !tfb->numAvail) { - TFaceBlock *tfbn = MEM_mallocN(sizeof(*tfbn), "TFaceBlock"); - - tfbn->tfaces = MEM_mallocN(sizeof(*tfbn->tfaces)*TABLEINITSIZE, "TFaceBlock->tfaces"); - tfbn->numAvail = TABLEINITSIZE; - tfbn->next = R.tfaceBlocks; - R.tfaceBlocks = tfbn; - - tfb = tfbn; - } - - return &tfb->tfaces[tfb->numAvail--]; -} - /* ------------------------------------------------------------------------- */ HaloRen *RE_inithalo(Material *ma, float *vec, float *vec1, diff --git a/source/blender/renderconverter/intern/convertBlenderScene.c b/source/blender/renderconverter/intern/convertBlenderScene.c index ec3de83d1b4..563600e69e1 100644 --- a/source/blender/renderconverter/intern/convertBlenderScene.c +++ b/source/blender/renderconverter/intern/convertBlenderScene.c @@ -51,6 +51,7 @@ #include "BLI_arithb.h" #include "BLI_blenlib.h" #include "BLI_rand.h" +#include "BLI_memarena.h" #include "DNA_scene_types.h" #include "DNA_lamp_types.h" @@ -75,6 +76,7 @@ #include "BKE_constraint.h" #include "BKE_displist.h" #include "BKE_deform.h" +#include "BKE_DerivedMesh.h" #include "BKE_effect.h" #include "BKE_global.h" #include "BKE_key.h" @@ -1297,8 +1299,6 @@ static void init_render_mesh(Object *ob) Material *ma; MSticky *ms = NULL; PartEff *paf; - DispList *dl; -// TFace *tface; unsigned int *vertcol; float xn, yn, zn, imat[3][3], mat[4][4]; //nor[3], float *extverts=0, *orco; @@ -1354,40 +1354,17 @@ static void init_render_mesh(Object *ob) do_puno= mesh_modifier(ob, 's'); if (mesh_uses_displist(me)) { - dl= me->disp.first; + DerivedMesh *dm = mesh_get_derived_render(ob); + dlm = dm->convertToDispListMesh(dm); + dm->release(dm); - /* Force a displist rebuild if this is a subsurf and we have a different subdiv level */ - /* also when object is in editmode, displist ordering for editmode is different, giving orco probs */ - - if((dl==NULL) || ((me->subdiv != me->subdivr)) || (G.obedit && me==G.obedit->data)) { - /* prevent subsurf called again for duplicate use of mesh, tface pointers change */ - if(dl==NULL || (me->subdivdone-1)!=me->subdivr) { - dlm= subsurf_make_dispListMesh_from_mesh(me, me->subdivr, me->flag); - dl= MEM_callocN(sizeof(*dl), "dl"); - dl->type= DL_MESH; - dl->mesh= dlm; + mvert= dlm->mvert; + totvert= dlm->totvert; - free_displist_by_type(&me->disp, DL_MESH); - BLI_addtail(&me->disp, dl); - - me->subdivdone= me->subdivr+1; /* stupid hack, add one because otherwise old files will get - * subdivdone==0, so me->subdivr==0 won't work. proper caching - * will remove this hack. - */ - } - } - - if(dl==NULL || dl->type!=DL_MESH); // here used to be a return, but why? - else { - dlm= dl->mesh; - - mvert= dlm->mvert; - totvert= dlm->totvert; - - ms= NULL; // no stick in displistmesh - } - + ms= NULL; // no stick in displistmesh } else { + DispList *dl; + dlm= NULL; mvert= me->mvert; totvert= me->totvert; @@ -1473,7 +1450,7 @@ static void init_render_mesh(Object *ob) mface= dlm->mface + start; if (dlm->tface) { tface= dlm->tface + start; - vertcol= dlm->tface->col; + vertcol= NULL; } else if (dlm->mcol) { vertcol= (unsigned int *)dlm->mcol; } else { @@ -1483,7 +1460,7 @@ static void init_render_mesh(Object *ob) mface= ((MFace*) me->mface) + start; if (me->tface) { tface= ((TFace*) me->tface) + start; - vertcol= ((TFace*) me->tface)->col; + vertcol= NULL; } else if (me->mcol) { vertcol= (unsigned int *)me->mcol; } else { @@ -1532,15 +1509,25 @@ static void init_render_mesh(Object *ob) if(len==0) R.totvlak--; else { - - if(vertcol) { - if(tface) vlr->vcol= vertcol+sizeof(TFace)*a/4; /* vertcol is int */ - else vlr->vcol= vertcol+sizeof(int)*a; + if(dlm) { + if(tface) { + vlr->tface= BLI_memarena_alloc(R.memArena, sizeof(*vlr->tface)); + vlr->vcol= vlr->tface->col; + memcpy(vlr->tface, tface, sizeof(*tface)); + } + else if (vertcol) { + vlr->vcol= BLI_memarena_alloc(R.memArena, sizeof(int)*16); + memcpy(vlr->vcol, vertcol+4*a, sizeof(int)*16); + } + } else { + if(tface) { + vlr->vcol= tface->col; + vlr->tface= tface; + } + else if (vertcol) { + vlr->vcol= vertcol+4*a; + } } - else vlr->vcol= 0; - - vlr->tface= tface; - } } else if(v2 && (ma->mode & MA_WIRE)) { @@ -1606,6 +1593,8 @@ static void init_render_mesh(Object *ob) if(do_puno) calc_vertexnormals(totverto, totvlako); mesh_modifier(ob, 'e'); // end + + if(dlm) displistmesh_free(dlm); } /* ------------------------------------------------------------------------- */ @@ -2685,6 +2674,9 @@ void RE_freeRotateBlenderScene(void) char *ctile; /* FREE */ + + BLI_memarena_free(R.memArena); + R.memArena = NULL; for(a=0; ashb) { @@ -2745,7 +2737,6 @@ void RE_freeRotateBlenderScene(void) if (mesh_uses_displist(me) && ((me->subdiv!=me->subdivr) || (ob->effect.first != NULL) || ob==G.obedit) ) { /* Need to recalc for effects since they are time dependant */ makeDispList(ob); /* XXX this should be replaced with proper caching */ - me->subdivdone= 0; /* needed to prevent multiple used meshes being recalculated */ } } else if(ob->type==OB_MBALL) { @@ -2919,6 +2910,8 @@ void RE_rotateBlenderScene(void) if(G.scene->camera==0) return; + R.memArena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE); + slurph_opt= 0; R.totvlak=R.totvert=R.totlamp=R.tothalo= 0;