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_global.h"
|
||||||
#include "BKE_mesh.h"
|
#include "BKE_mesh.h"
|
||||||
#include "BKE_object.h"
|
#include "BKE_object.h"
|
||||||
|
#include "BKE_subsurf.h"
|
||||||
|
|
||||||
#include "BIF_gl.h"
|
#include "BIF_gl.h"
|
||||||
#include "BIF_glutil.h"
|
#include "BIF_glutil.h"
|
||||||
@ -642,6 +643,8 @@ typedef struct {
|
|||||||
|
|
||||||
DispListMesh *dlm;
|
DispListMesh *dlm;
|
||||||
EditMesh *em;
|
EditMesh *em;
|
||||||
|
|
||||||
|
int needsFree;
|
||||||
} SSDerivedMesh;
|
} SSDerivedMesh;
|
||||||
|
|
||||||
static void ssDM_getMappedVertCoEM(DerivedMesh *dm, void *vert, float co_r[3])
|
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);
|
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");
|
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.drawFacesColored = ssDM_drawFacesColored;
|
||||||
ssdm->dm.drawFacesEM = ssDM_drawFacesEM;
|
ssdm->dm.drawFacesEM = ssDM_drawFacesEM;
|
||||||
|
|
||||||
ssdm->dm.release = MEM_freeN;
|
ssdm->dm.release = ssDM_release;
|
||||||
|
|
||||||
ssdm->dlm = dlm;
|
ssdm->dlm = dlm;
|
||||||
ssdm->em = em;
|
ssdm->em = em;
|
||||||
|
ssdm->needsFree = needsFree;
|
||||||
|
|
||||||
return (DerivedMesh*) ssdm;
|
return (DerivedMesh*) ssdm;
|
||||||
}
|
}
|
||||||
@ -1081,18 +1096,51 @@ DerivedMesh *mesh_get_derived(Object *ob)
|
|||||||
|
|
||||||
build_mesh_data(ob);
|
build_mesh_data(ob);
|
||||||
dl= find_displist(&me->disp, DL_MESH);
|
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) {
|
if(G.obedit && me==G.obedit->data) {
|
||||||
return getSSDerivedMesh(G.editMesh, dl->mesh);
|
return getSSDerivedMesh(G.editMesh, dl->mesh, 0);
|
||||||
} else {
|
} 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)
|
DerivedMesh *mesh_get_base_derived(Object *ob)
|
||||||
|
@ -44,7 +44,7 @@
|
|||||||
* enough to not cause much internal fragmentation,
|
* enough to not cause much internal fragmentation,
|
||||||
* small enough not to waste resources
|
* small enough not to waste resources
|
||||||
*/
|
*/
|
||||||
#define BLI_MEMARENA_STD_BUFSIZE 4096
|
#define BLI_MEMARENA_STD_BUFSIZE (1<<14)
|
||||||
|
|
||||||
struct MemArena;
|
struct MemArena;
|
||||||
typedef struct MemArena 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 VlakRen *RE_findOrAddVlak(int nr);
|
||||||
struct VertRen *RE_findOrAddVert(int nr);
|
struct VertRen *RE_findOrAddVert(int nr);
|
||||||
struct HaloRen *RE_findOrAddHalo(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,
|
HaloRen *RE_inithalo(struct Material *ma, float *vec, float *vec1, float *orco, float hasize,
|
||||||
float vectsize, int seed);
|
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 */
|
/* localized texture result data */
|
||||||
typedef struct TexResult {
|
typedef struct TexResult {
|
||||||
float tin, tr, tg, tb, ta;
|
float tin, tr, tg, tb, ta;
|
||||||
@ -111,6 +100,8 @@ typedef struct ShadeInput
|
|||||||
|
|
||||||
} ShadeInput;
|
} ShadeInput;
|
||||||
|
|
||||||
|
struct MemArena;
|
||||||
|
|
||||||
/* here only stuff to initalize the render itself */
|
/* here only stuff to initalize the render itself */
|
||||||
typedef struct RE_Render
|
typedef struct RE_Render
|
||||||
{
|
{
|
||||||
@ -150,7 +141,11 @@ typedef struct RE_Render
|
|||||||
struct VlakRen **blovl;
|
struct VlakRen **blovl;
|
||||||
struct VertRen **blove;
|
struct VertRen **blove;
|
||||||
struct HaloRen **bloha;
|
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 *rectaccu;
|
||||||
int *rectz; /* z buffer: distance buffer */
|
int *rectz; /* z buffer: distance buffer */
|
||||||
|
@ -442,14 +442,6 @@ void RE_init_render_data(void)
|
|||||||
|
|
||||||
void RE_free_render_data()
|
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);
|
MEM_freeN(R.blove);
|
||||||
R.blove= NULL;
|
R.blove= NULL;
|
||||||
MEM_freeN(R.blovl);
|
MEM_freeN(R.blovl);
|
||||||
|
@ -174,26 +174,6 @@ VlakRen *RE_findOrAddVlak(int nr)
|
|||||||
return v;
|
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,
|
HaloRen *RE_inithalo(Material *ma, float *vec, float *vec1,
|
||||||
|
@ -51,6 +51,7 @@
|
|||||||
#include "BLI_arithb.h"
|
#include "BLI_arithb.h"
|
||||||
#include "BLI_blenlib.h"
|
#include "BLI_blenlib.h"
|
||||||
#include "BLI_rand.h"
|
#include "BLI_rand.h"
|
||||||
|
#include "BLI_memarena.h"
|
||||||
|
|
||||||
#include "DNA_scene_types.h"
|
#include "DNA_scene_types.h"
|
||||||
#include "DNA_lamp_types.h"
|
#include "DNA_lamp_types.h"
|
||||||
@ -75,6 +76,7 @@
|
|||||||
#include "BKE_constraint.h"
|
#include "BKE_constraint.h"
|
||||||
#include "BKE_displist.h"
|
#include "BKE_displist.h"
|
||||||
#include "BKE_deform.h"
|
#include "BKE_deform.h"
|
||||||
|
#include "BKE_DerivedMesh.h"
|
||||||
#include "BKE_effect.h"
|
#include "BKE_effect.h"
|
||||||
#include "BKE_global.h"
|
#include "BKE_global.h"
|
||||||
#include "BKE_key.h"
|
#include "BKE_key.h"
|
||||||
@ -1297,8 +1299,6 @@ static void init_render_mesh(Object *ob)
|
|||||||
Material *ma;
|
Material *ma;
|
||||||
MSticky *ms = NULL;
|
MSticky *ms = NULL;
|
||||||
PartEff *paf;
|
PartEff *paf;
|
||||||
DispList *dl;
|
|
||||||
// TFace *tface;
|
|
||||||
unsigned int *vertcol;
|
unsigned int *vertcol;
|
||||||
float xn, yn, zn, imat[3][3], mat[4][4]; //nor[3],
|
float xn, yn, zn, imat[3][3], mat[4][4]; //nor[3],
|
||||||
float *extverts=0, *orco;
|
float *extverts=0, *orco;
|
||||||
@ -1354,40 +1354,17 @@ static void init_render_mesh(Object *ob)
|
|||||||
do_puno= mesh_modifier(ob, 's');
|
do_puno= mesh_modifier(ob, 's');
|
||||||
|
|
||||||
if (mesh_uses_displist(me)) {
|
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 */
|
mvert= dlm->mvert;
|
||||||
/* also when object is in editmode, displist ordering for editmode is different, giving orco probs */
|
totvert= dlm->totvert;
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
free_displist_by_type(&me->disp, DL_MESH);
|
ms= NULL; // no stick in displistmesh
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
DispList *dl;
|
||||||
|
|
||||||
dlm= NULL;
|
dlm= NULL;
|
||||||
mvert= me->mvert;
|
mvert= me->mvert;
|
||||||
totvert= me->totvert;
|
totvert= me->totvert;
|
||||||
@ -1473,7 +1450,7 @@ static void init_render_mesh(Object *ob)
|
|||||||
mface= dlm->mface + start;
|
mface= dlm->mface + start;
|
||||||
if (dlm->tface) {
|
if (dlm->tface) {
|
||||||
tface= dlm->tface + start;
|
tface= dlm->tface + start;
|
||||||
vertcol= dlm->tface->col;
|
vertcol= NULL;
|
||||||
} else if (dlm->mcol) {
|
} else if (dlm->mcol) {
|
||||||
vertcol= (unsigned int *)dlm->mcol;
|
vertcol= (unsigned int *)dlm->mcol;
|
||||||
} else {
|
} else {
|
||||||
@ -1483,7 +1460,7 @@ static void init_render_mesh(Object *ob)
|
|||||||
mface= ((MFace*) me->mface) + start;
|
mface= ((MFace*) me->mface) + start;
|
||||||
if (me->tface) {
|
if (me->tface) {
|
||||||
tface= ((TFace*) me->tface) + start;
|
tface= ((TFace*) me->tface) + start;
|
||||||
vertcol= ((TFace*) me->tface)->col;
|
vertcol= NULL;
|
||||||
} else if (me->mcol) {
|
} else if (me->mcol) {
|
||||||
vertcol= (unsigned int *)me->mcol;
|
vertcol= (unsigned int *)me->mcol;
|
||||||
} else {
|
} else {
|
||||||
@ -1532,15 +1509,25 @@ static void init_render_mesh(Object *ob)
|
|||||||
|
|
||||||
if(len==0) R.totvlak--;
|
if(len==0) R.totvlak--;
|
||||||
else {
|
else {
|
||||||
|
if(dlm) {
|
||||||
if(vertcol) {
|
if(tface) {
|
||||||
if(tface) vlr->vcol= vertcol+sizeof(TFace)*a/4; /* vertcol is int */
|
vlr->tface= BLI_memarena_alloc(R.memArena, sizeof(*vlr->tface));
|
||||||
else vlr->vcol= vertcol+sizeof(int)*a;
|
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)) {
|
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);
|
if(do_puno) calc_vertexnormals(totverto, totvlako);
|
||||||
|
|
||||||
mesh_modifier(ob, 'e'); // end
|
mesh_modifier(ob, 'e'); // end
|
||||||
|
|
||||||
|
if(dlm) displistmesh_free(dlm);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------- */
|
/* ------------------------------------------------------------------------- */
|
||||||
@ -2685,6 +2674,9 @@ void RE_freeRotateBlenderScene(void)
|
|||||||
char *ctile;
|
char *ctile;
|
||||||
|
|
||||||
/* FREE */
|
/* FREE */
|
||||||
|
|
||||||
|
BLI_memarena_free(R.memArena);
|
||||||
|
R.memArena = NULL;
|
||||||
|
|
||||||
for(a=0; a<R.totlamp; a++) {
|
for(a=0; a<R.totlamp; a++) {
|
||||||
if(R.la[a]->shb) {
|
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) ) {
|
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 */
|
/* Need to recalc for effects since they are time dependant */
|
||||||
makeDispList(ob); /* XXX this should be replaced with proper caching */
|
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) {
|
else if(ob->type==OB_MBALL) {
|
||||||
@ -2919,6 +2910,8 @@ void RE_rotateBlenderScene(void)
|
|||||||
|
|
||||||
if(G.scene->camera==0) return;
|
if(G.scene->camera==0) return;
|
||||||
|
|
||||||
|
R.memArena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE);
|
||||||
|
|
||||||
slurph_opt= 0;
|
slurph_opt= 0;
|
||||||
|
|
||||||
R.totvlak=R.totvert=R.totlamp=R.tothalo= 0;
|
R.totvlak=R.totvert=R.totlamp=R.tothalo= 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user