diff options
Diffstat (limited to 'source/blender/radiosity')
-rw-r--r-- | source/blender/radiosity/extern/include/radio.h | 1 | ||||
-rw-r--r-- | source/blender/radiosity/intern/source/radnode.c | 5 | ||||
-rw-r--r-- | source/blender/radiosity/intern/source/radpostprocess.c | 140 |
3 files changed, 58 insertions, 88 deletions
diff --git a/source/blender/radiosity/extern/include/radio.h b/source/blender/radiosity/extern/include/radio.h index ba1917e9191..1bdd847930d 100644 --- a/source/blender/radiosity/extern/include/radio.h +++ b/source/blender/radiosity/extern/include/radio.h @@ -86,6 +86,7 @@ extern void setnodelimit(float limit); extern float *mallocVert(void); extern float *callocVert(void); extern void freeVert(float *vert); +extern int totalRadVert(void); extern RNode *mallocNode(void); extern RNode *callocNode(void); extern void freeNode(RNode *node); diff --git a/source/blender/radiosity/intern/source/radnode.c b/source/blender/radiosity/intern/source/radnode.c index 15901a66f1e..168ad2de725 100644 --- a/source/blender/radiosity/intern/source/radnode.c +++ b/source/blender/radiosity/intern/source/radnode.c @@ -259,6 +259,11 @@ void freeVert(float *vert) Ntotvert--; } +int totalRadVert() +{ + return Ntotvert; +} + RNode *mallocNode() { Ntotnode++; diff --git a/source/blender/radiosity/intern/source/radpostprocess.c b/source/blender/radiosity/intern/source/radpostprocess.c index 36ac0445933..b75f94dcf0a 100644 --- a/source/blender/radiosity/intern/source/radpostprocess.c +++ b/source/blender/radiosity/intern/source/radpostprocess.c @@ -52,6 +52,7 @@ #include "BLI_blenlib.h" #include "BLI_arithb.h" +#include "BLI_ghash.h" #include "BIF_toolbox.h" // notice() #include "DNA_material_types.h" @@ -684,6 +685,24 @@ void removeEqualNodes(short limit) waitcursor(0); } +unsigned int rad_find_or_add_mvert(Mesh *me, MFace *mf, RNode *orignode, float *w, float *radco, GHash *hash) +{ + MVert *mvert = BLI_ghash_lookup(hash, radco); + + if(!mvert) { + mvert = &me->mvert[me->totvert]; + VECCOPY(mvert->co, radco); + me->totvert++; + + BLI_ghash_insert(hash, radco, mvert); + } + + InterpWeightsQ3Dfl(orignode->v1, orignode->v2, orignode->v3, + orignode->v4, mvert->co, w); + + return (unsigned int)(mvert - me->mvert); +} + void rad_addmesh(void) { Face *face = NULL; @@ -691,25 +710,28 @@ void rad_addmesh(void) Mesh *me; MVert *mvert; MFace *mf; + RNode *node; Material *ma=0; - float **vco, **vertexco; - float cent[3], min[3], max[3]; - int a, nvert, i; + GHash *verthash; unsigned int *mcol; - + float cent[3], min[3], max[3], w[4][4]; + int a; + if(RG.totface==0) return; if(RG.totmat==MAXMAT) notice("warning: cannot assign more than 16 materials to 1 mesh"); - + /* create the mesh */ ob= add_object(OB_MESH); me= ob->data; - me->totvert= 0; + me->totvert= totalRadVert(); me->totface= RG.totface; me->flag= 0; + + me->mvert= CustomData_add_layer(&me->vdata, CD_MVERT, 0, NULL, me->totvert); me->mface= CustomData_add_layer(&me->fdata, CD_MFACE, 0, NULL, me->totface); me->mcol= CustomData_add_layer(&me->fdata, CD_MCOL, 0, NULL, me->totface); @@ -723,104 +745,46 @@ void rad_addmesh(void) if(ma) ma->mode |= MA_VERTEXCOL; } - /* copy face data, load Face vertex colors into mcol, with alpha added */ - mcol= (unsigned int*)me->mcol; - for(a=0; a<me->totface; a++, mcol+=4) { - RAD_NEXTFACE(a); - - CustomData_copy_data(RG.mfdata, &me->fdata, face->orig, a, 1); - - mcol[0]= *((unsigned int*)face->v1+3) | 0x1000000; - mcol[1]= *((unsigned int*)face->v2+3) | 0x1000000; - mcol[2]= *((unsigned int*)face->v3+3) | 0x1000000; - if(face->v4) - mcol[3]= *((unsigned int*)face->v4+3) | 0x1000000; - } - - /* clear Face vertex color memory for vertex index assignment */ - for(a=0; a<me->totface; a++) { - RAD_NEXTFACE(a); - - *((unsigned int*)face->v1+3)= ~0; - *((unsigned int*)face->v2+3)= ~0; - *((unsigned int*)face->v3+3)= ~0; - if(face->v4) - *((unsigned int*)face->v4+3)= ~0; - } + /* create vertices and faces in one go, adding vertices to the end of the + mvert array if they were not added already */ + me->totvert= 0; + verthash= BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp); - /* create faces and create array with pointers to vertex coords */ - vco= vertexco= MEM_mallocN(sizeof(float *)*4*RG.totface, "radiovertexco"); + mcol= (unsigned int*)me->mcol; mf= me->mface; - for(a=0; a<me->totface; a++, mf++) { + for(a=0; a<me->totface; a++, mf++, mcol+=4) { RAD_NEXTFACE(a); - nvert= (face->v4)? 4: 3; - for(i=0; i<nvert; i++) { - unsigned int *col= ((unsigned int**)&face->v1)[i] + 3; + /* the original node that this node is a subnode of */ + node= RG.mfdatanodes[face->orig]; - if (*col == ~0) { - /* vertex has no index yet, so assign one */ - *col= me->totvert; - *vco= ((float**)&face->v1)[i]; - me->totvert++; - vco++; - } - - ((unsigned int*)&mf->v1)[i] = *col; - } - } - - /* create vertices */ - me->mvert= CustomData_add_layer(&me->vdata, CD_MVERT, 0, NULL, me->totvert); - mvert= me->mvert; - for(vco=vertexco, a=0; a<me->totvert; a++, mvert++, vco++) { - VECCOPY(mvert->co, *vco); - } - - MEM_freeN(vertexco); - - /* assign face data */ - mf= me->mface; - - for(a=0; a<me->totface; a++, mf++ ) { - RNode *orignode; - float w[4][4]; - float *subco; - - RAD_NEXTFACE(a); - nvert= (face->v4)? 4: 3; + /* set mverts from the radio data, and compute interpolation weights */ + mf->v1= rad_find_or_add_mvert(me, mf, node, w[0], face->v1, verthash); + mf->v2= rad_find_or_add_mvert(me, mf, node, w[1], face->v2, verthash); + mf->v3= rad_find_or_add_mvert(me, mf, node, w[2], face->v3, verthash); + if(face->v4) + mf->v4= rad_find_or_add_mvert(me, mf, node, w[3], face->v4, verthash); - /* copy */ + /* copy face and interpolate data */ mf->mat_nr= face->matindex; - orignode= RG.mfdatanodes[face->orig]; - - for(i=0; i<nvert; i++) { - subco= (me->mvert + ((unsigned int*)&mf->v1)[i])->co; - - InterpWeightsQ3Dfl(orignode->v1, orignode->v2, orignode->v3, - orignode->v4, subco, w[i]); - } - + CustomData_copy_data(RG.mfdata, &me->fdata, face->orig, a, 1); CustomData_interp(RG.mfdata, &me->fdata, &face->orig, NULL, (float*)w, 1, a); - } - - /* restore vertex colors, and test_index */ - mf= me->mface; - mcol= (unsigned int*)me->mcol; - for(a=0; a<me->totface; a++, mf++, mcol+=4) { - RAD_NEXTFACE(a); - *((unsigned int*)face->v1+3)= mcol[0]; - *((unsigned int*)face->v2+3)= mcol[1]; - *((unsigned int*)face->v3+3)= mcol[2]; + /* load face vertex colors, with alpha added */ + mcol[0]= *((unsigned int*)face->v1+3) | 0x1000000; + mcol[1]= *((unsigned int*)face->v2+3) | 0x1000000; + mcol[2]= *((unsigned int*)face->v3+3) | 0x1000000; if(face->v4) - *((unsigned int*)face->v4+3)= mcol[3]; + mcol[3]= *((unsigned int*)face->v4+3) | 0x1000000; + /* reorder face indices if needed to make face->v4 == 0 */ test_index_face(mf, &me->fdata, a, face->v4? 4: 3); } + BLI_ghash_free(verthash, NULL, NULL); + /* boundbox and centre new */ INIT_MINMAX(min, max); |