forked from bartvdbraak/blender
- added mesh_get_derived_render
- cancelled previous commit to add RE_findTFAce, instead just added a MemArena to render struct... free'd at end of render, can be used to store other data as well - switch rendering to using DerivedMesh API... this is slightly more inefficient now because it is doing some unnecessary copying. Can be fixed by defining a DerivedMesh function to convert the object into a render object (on todo list)
This commit is contained in:
parent
7dbb253908
commit
67eaf69f3f
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -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; a<R.totlamp; a++) {
|
||||
if(R.la[a]->shb) {
|
||||
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user