diff options
Diffstat (limited to 'source/blender/radiosity/intern/source/radpostprocess.c')
-rw-r--r-- | source/blender/radiosity/intern/source/radpostprocess.c | 871 |
1 files changed, 871 insertions, 0 deletions
diff --git a/source/blender/radiosity/intern/source/radpostprocess.c b/source/blender/radiosity/intern/source/radpostprocess.c new file mode 100644 index 00000000000..8cbbfb1f4de --- /dev/null +++ b/source/blender/radiosity/intern/source/radpostprocess.c @@ -0,0 +1,871 @@ +/* *************************************** + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + + + + radpostprocess.c nov/dec 1992 + may 1999 + + - faces + - filtering and node-limit + - apply to meshes + $Id$ + + *************************************** */ + +#include <stdlib.h> +#include <math.h> + +#ifdef WIN32 +#include "BLI_winstuff.h" +#endif + +#include "MEM_guardedalloc.h" + +#include "BLI_blenlib.h" +#include "BLI_arithb.h" + +#include "DNA_material_types.h" +#include "DNA_mesh_types.h" +#include "DNA_object_types.h" +#include "DNA_radio_types.h" + +#include "BKE_utildefines.h" +#include "BKE_global.h" +#include "BKE_main.h" +#include "BKE_mesh.h" +#include "BKE_object.h" +#include "BKE_material.h" + +#include "BIF_screen.h" /* waitcursor */ +#include "BIF_editview.h" /* deselectall */ + +#include "BDR_editobject.h" /* delete_obj */ + +#include "radio.h" + +/* locals? not. done in radio.h... */ +/* void rad_addmesh(void); */ +/* void rad_replacemesh(void); */ + +void addaccu(register char *z, register char *t) +{ + register int div, mul; + + mul= *t; + div= mul+1; + (*t)++; + + t[1]= (mul*t[1]+z[1])/div; + t[2]= (mul*t[2]+z[2])/div; + t[3]= (mul*t[3]+z[3])/div; + +} + +void addaccuweight(register char *z, register char *t, int w) +{ + register int div, mul; + + if(w==0) w= 1; + + mul= *t; + div= mul+w; + if(div>255) return; + (*t)= div; + + t[1]= (mul*t[1]+w*z[1])/div; + t[2]= (mul*t[2]+w*z[2])/div; + t[3]= (mul*t[3]+w*z[3])/div; + +} + +void triaweight(Face *face, int *w1, int *w2, int *w3) +{ + float n1[3], n2[3], n3[3], temp; + + n1[0]= face->v2[0]-face->v1[0]; + n1[1]= face->v2[1]-face->v1[1]; + n1[2]= face->v2[2]-face->v1[2]; + n2[0]= face->v3[0]-face->v2[0]; + n2[1]= face->v3[1]-face->v2[1]; + n2[2]= face->v3[2]-face->v2[2]; + n3[0]= face->v1[0]-face->v3[0]; + n3[1]= face->v1[1]-face->v3[1]; + n3[2]= face->v1[2]-face->v3[2]; + Normalise(n1); + Normalise(n2); + Normalise(n3); + temp= 32.0/(PI); + *w1= 0.5+temp*acos(-n1[0]*n3[0]-n1[1]*n3[1]-n1[2]*n3[2]); + *w2= 0.5+temp*acos(-n1[0]*n2[0]-n1[1]*n2[1]-n1[2]*n2[2]); + *w3= 0.5+temp*acos(-n2[0]*n3[0]-n2[1]*n3[1]-n2[2]*n3[2]); + +} + + + +void init_face_tab() +{ + int a= 0; + + if(RG.facebase==0) { + RG.facebase= MEM_callocN(sizeof(void *)*RAD_MAXFACETAB, "init_face_tab"); + } + for(a=0; a<RAD_MAXFACETAB; a++) { + if(RG.facebase[a]==0) break; + MEM_freeN(RG.facebase[a]); + RG.facebase[a]= 0; + } + RG.totface= 0; +} + +Face *addface() +{ + Face *face; + int a; + + if(RG.totface<0 || RG.totface>RAD_MAXFACETAB*1024 ) { + printf("error in addface: %d\n", RG.totface); + return 0; + } + a= RG.totface>>10; + face= RG.facebase[a]; + if(face==0) { + face= MEM_callocN(1024*sizeof(Face),"addface"); + RG.facebase[a]= face; + } + face+= (RG.totface & 1023); + + RG.totface++; + + return face; + +} + +void makeface(float *v1, float *v2, float *v3, float *v4, RNode *rn) +{ + Face *face; + + face= addface(); + face->v1= v1; + face->v2= v2; + face->v3= v3; + face->v4= v4; + face->col= rn->col; + face->matindex= rn->par->matindex; +} + + +void anchorQuadface(RNode *rn, float *v1, float *v2, float *v3, float *v4, int flag) +{ + + switch(flag) { + case 1: + makeface(rn->v1, v1, rn->v4, 0, rn); + makeface(v1, rn->v3, rn->v4, 0, rn); + makeface(v1, rn->v2, rn->v3, 0, rn); + break; + case 2: + makeface(rn->v2, v2, rn->v1, 0, rn); + makeface(v2, rn->v4, rn->v1, 0, rn); + makeface(v2, rn->v3, rn->v4, 0, rn); + break; + case 4: + makeface(rn->v3, v3, rn->v2, 0, rn); + makeface(v3, rn->v1, rn->v2, 0, rn); + makeface(v3, rn->v4, rn->v1, 0, rn); + break; + case 8: + makeface(rn->v4, v4, rn->v3, 0, rn); + makeface(v4, rn->v2, rn->v3, 0, rn); + makeface(v4, rn->v1, rn->v2, 0, rn); + break; + + case 3: + makeface(rn->v1, v1, rn->v4, 0, rn); + makeface(v1, v2, rn->v4, 0, rn); + makeface(v1, rn->v2, v2, 0, rn); + makeface(v2, rn->v3, rn->v4, 0, rn); + break; + case 6: + makeface(rn->v2, v2, rn->v1, 0, rn); + makeface(v2, v3, rn->v1, 0, rn); + makeface(v2, rn->v3, v3, 0, rn); + makeface(v3, rn->v4, rn->v1, 0, rn); + break; + case 12: + makeface(rn->v3, v3, rn->v2, 0, rn); + makeface(v3, v4, rn->v2, 0, rn); + makeface(v3, rn->v4, v4, 0, rn); + makeface(v4, rn->v1, rn->v2, 0, rn); + break; + case 9: + makeface(rn->v4, v4, rn->v3, 0, rn); + makeface(v4, v1, rn->v3, 0, rn); + makeface(v4, rn->v1, v1, 0, rn); + makeface(v1, rn->v2, rn->v3, 0, rn); + break; + + case 5: + makeface(rn->v1, v1, v3, rn->v4, rn); + makeface(v1, rn->v2, rn->v3, v3, rn); + break; + case 10: + makeface(rn->v2, v2, v4, rn->v1, rn); + makeface(v2, rn->v3, rn->v4, v4, rn); + break; + + case 7: + makeface(rn->v1, v1, v3, rn->v4, rn); + makeface(v1, v2, v3, 0, rn); + makeface(v1, rn->v2, v2, 0, rn); + makeface(v2, rn->v3, v3, 0, rn); + break; + case 14: + makeface(rn->v2, v2, v4, rn->v1, rn); + makeface(v2, v3, v4, 0, rn); + makeface(v2, rn->v3, v3, 0, rn); + makeface(v3, rn->v4, v4, 0, rn); + break; + case 13: + makeface(rn->v3, v3, v1, rn->v2, rn); + makeface(v3, v4, v1, 0, rn); + makeface(v3, rn->v4, v4, 0, rn); + makeface(v4, rn->v1, v1, 0, rn); + break; + case 11: + makeface(rn->v4, v4, v2, rn->v3, rn); + makeface(v4, v1, v2, 0, rn); + makeface(v4, rn->v1, v1, 0, rn); + makeface(v1, rn->v2, v2, 0, rn); + break; + + case 15: + makeface(v1, v2, v3, v4, rn); + makeface(v1, rn->v2, v2, 0, rn); + makeface(v2, rn->v3, v3, 0, rn); + makeface(v3, rn->v4, v4, 0, rn); + makeface(v4, rn->v1, v1, 0, rn); + break; + } +} + +void anchorTriface(RNode *rn, float *v1, float *v2, float *v3, int flag) +{ + switch(flag) { + case 1: + makeface(rn->v1, v1, rn->v3, 0, rn); + makeface(v1, rn->v2, rn->v3, 0, rn); + break; + case 2: + makeface(rn->v2, v2, rn->v1, 0, rn); + makeface(v2, rn->v3, rn->v1, 0, rn); + break; + case 4: + makeface(rn->v3, v3, rn->v2, 0, rn); + makeface(v3, rn->v1, rn->v2, 0, rn); + break; + + case 3: + makeface(rn->v1, v2, rn->v3, 0, rn); + makeface(rn->v1, v1, v2, 0, rn); + makeface(v1, rn->v2, v2, 0, rn); + break; + case 6: + makeface(rn->v2, v3, rn->v1, 0, rn); + makeface(rn->v2, v2, v3, 0, rn); + makeface(v2, rn->v3, v3, 0, rn); + break; + case 5: + makeface(rn->v3, v1, rn->v2, 0, rn); + makeface(rn->v3, v3, v1, 0, rn); + makeface(v3, rn->v1, v1, 0, rn); + break; + + case 7: + makeface(v1, v2, v3, 0, rn); + makeface(rn->v1, v1, v3, 0, rn); + makeface(rn->v2, v2, v1, 0, rn); + makeface(rn->v3, v3, v2, 0, rn); + break; + } +} + + +float *findmiddlevertex(RNode *node, RNode *nb, float *v1, float *v2) +{ + int test= 0; + + if(nb==0) return 0; + + if(nb->ed1==node) { + if(nb->v1==v1 || nb->v1==v2) test++; + if(nb->v2==v1 || nb->v2==v2) test+=2; + if(test==1) return nb->v2; + else if(test==2) return nb->v1; + } + else if(nb->ed2==node) { + if(nb->v2==v1 || nb->v2==v2) test++; + if(nb->v3==v1 || nb->v3==v2) test+=2; + if(test==1) return nb->v3; + else if(test==2) return nb->v2; + } + else if(nb->ed3==node) { + if(nb->type==4) { + if(nb->v3==v1 || nb->v3==v2) test++; + if(nb->v4==v1 || nb->v4==v2) test+=2; + if(test==1) return nb->v4; + else if(test==2) return nb->v3; + + } + else { + if(nb->v3==v1 || nb->v3==v2) test++; + if(nb->v1==v1 || nb->v1==v2) test+=2; + if(test==1) return nb->v1; + else if(test==2) return nb->v3; + } + } + else if(nb->ed4==node) { + if(nb->v4==v1 || nb->v4==v2) test++; + if(nb->v1==v1 || nb->v1==v2) test+=2; + if(test==1) return nb->v1; + else if(test==2) return nb->v4; + } + return 0; +} + +void make_face_tab() /* zorgt voor ankers */ +{ + RNode *rn, **el; + Face *face = NULL; + float *v1, *v2, *v3, *v4; + int a, flag, w1, w2, w3; + char *charcol; + + if(RG.totelem==0) return; + + init_face_tab(); + + RG.igamma= 1.0/RG.gamma; + RG.radfactor= RG.radfac*pow(64*64, RG.igamma); + + /* vlakkleuren omzetten */ + el= RG.elem; + for(a=RG.totelem; a>0; a--, el++) { + rn= *el; + charcol= (char *)&( rn->col ); + + charcol[3]= calculatecolor(rn->totrad[0]); + charcol[2]= calculatecolor(rn->totrad[1]); + charcol[1]= calculatecolor(rn->totrad[2]); + } + + /* nodes aflopen en Face's maken */ + el= RG.elem; + for(a=RG.totelem; a>0; a--, el++) { + + rn= *el; + + rn->v1[3]= 0.0; + rn->v2[3]= 0.0; + rn->v3[3]= 0.0; + if(rn->v4) rn->v4[3]= 0.0; + + /* test edges op subdivide */ + flag= 0; + v1= v2= v3= v4= 0; + if(rn->ed1) { + v1= findmiddlevertex(rn, rn->ed1->down1, rn->v1, rn->v2); + if(v1) flag |= 1; + } + if(rn->ed2) { + v2= findmiddlevertex(rn, rn->ed2->down1, rn->v2, rn->v3); + if(v2) flag |= 2; + } + if(rn->ed3) { + if(rn->type==4) + v3= findmiddlevertex(rn, rn->ed3->down1, rn->v3, rn->v4); + else + v3= findmiddlevertex(rn, rn->ed3->down1, rn->v3, rn->v1); + if(v3) flag |= 4; + } + if(rn->ed4) { + v4= findmiddlevertex(rn, rn->ed4->down1, rn->v4, rn->v1); + if(v4) flag |= 8; + } + + /* met flag en vertexpointers kunnen nu Face's gemaakt*/ + + if(flag==0) { + makeface(rn->v1, rn->v2, rn->v3, rn->v4, rn); + } + else if(rn->type==4) anchorQuadface(rn, v1, v2, v3, v4, flag); + else anchorTriface(rn, v1, v2, v3, flag); + } + + /* optellen */ + for(a=0; a<RG.totface; a++) { + + RAD_NEXTFACE(a); + + if(face->v4) { + addaccuweight( (char *)&(face->col), (char *)(face->v1+3), 16 ); + addaccuweight( (char *)&(face->col), (char *)(face->v2+3), 16 ); + addaccuweight( (char *)&(face->col), (char *)(face->v3+3), 16 ); + addaccuweight( (char *)&(face->col), (char *)(face->v4+3), 16 ); + } + else { + triaweight(face, &w1, &w2, &w3); + addaccuweight( (char *)&(face->col), (char *)(face->v1+3), w1 ); + addaccuweight( (char *)&(face->col), (char *)(face->v2+3), w2 ); + addaccuweight( (char *)&(face->col), (char *)(face->v3+3), w3 ); + } + } + +} + +void filterFaces() +{ + /* alle kleuren van vertices in faces en weer terug */ + + Face *face = NULL; + int a, w1, w2, w3; + + if(RG.totface==0) return; + + /* wissen */ + for(a=0; a<RG.totface; a++) { + RAD_NEXTFACE(a); + face->col= 0; + } + + /* optellen: punten bij vlakken */ + for(a=0; a<RG.totface; a++) { + RAD_NEXTFACE(a); + + if(face->v4) { + addaccuweight( (char *)(face->v1+3), (char *)&(face->col), 16 ); + addaccuweight( (char *)(face->v2+3), (char *)&(face->col), 16 ); + addaccuweight( (char *)(face->v3+3), (char *)&(face->col), 16 ); + addaccuweight( (char *)(face->v4+3), (char *)&(face->col), 16 ); + } + else { + triaweight(face, &w1, &w2, &w3); + addaccuweight( (char *)(face->v1+3), (char *)&(face->col), w1 ); + addaccuweight( (char *)(face->v2+3), (char *)&(face->col), w2 ); + addaccuweight( (char *)(face->v3+3), (char *)&(face->col), w3 ); + } + } + + /* wissen */ + for(a=0; a<RG.totface; a++) { + RAD_NEXTFACE(a); + face->v1[3]= 0.0; + face->v2[3]= 0.0; + face->v3[3]= 0.0; + if(face->v4) face->v4[3]= 0.0; + } + + + /* optellen: vlakken bij punten */ + for(a=0; a<RG.totface; a++) { + + RAD_NEXTFACE(a); + + if(face->v4) { + addaccuweight( (char *)&(face->col), (char *)(face->v1+3), 16 ); + addaccuweight( (char *)&(face->col), (char *)(face->v2+3), 16 ); + addaccuweight( (char *)&(face->col), (char *)(face->v3+3), 16 ); + addaccuweight( (char *)&(face->col), (char *)(face->v4+3), 16 ); + } + else { + triaweight(face, &w1, &w2, &w3); + addaccuweight( (char *)&(face->col), (char *)(face->v1+3), w1 ); + addaccuweight( (char *)&(face->col), (char *)(face->v2+3), w2 ); + addaccuweight( (char *)&(face->col), (char *)(face->v3+3), w3 ); + } + } +} + +void calcfiltrad(RNode *rn, float *cd) +{ + float area; + + cd[0]= 2.0*rn->totrad[0]; + cd[1]= 2.0*rn->totrad[1]; + cd[2]= 2.0*rn->totrad[2]; + area= 2.0; + + if(rn->ed1) { + cd[0]+= rn->ed1->totrad[0]; + cd[1]+= rn->ed1->totrad[1]; + cd[2]+= rn->ed1->totrad[2]; + area+= 1.0; + } + if(rn->ed2) { + cd[0]+= rn->ed2->totrad[0]; + cd[1]+= rn->ed2->totrad[1]; + cd[2]+= rn->ed2->totrad[2]; + area+= 1.0; + } + if(rn->ed3) { + cd[0]+= rn->ed3->totrad[0]; + cd[1]+= rn->ed3->totrad[1]; + cd[2]+= rn->ed3->totrad[2]; + area+= 1.0; + } + if(rn->ed4) { + cd[0]+= rn->ed4->totrad[0]; + cd[1]+= rn->ed4->totrad[1]; + cd[2]+= rn->ed4->totrad[2]; + area+= 1.0; + } + cd[0]/= area; + cd[1]/= area; + cd[2]/= area; + +} + +void filterNodes() +{ + /* alle kleuren van nodes in tempblok en weer terug */ + + RNode *rn, **el; + float *coldata, *cd; + int a; + + if(RG.totelem==0) return; + /* de upnodes moeten kleur hebben */ + el= RG.elem; + for(a=0; a<RG.totelem; a++, el++) { + rn= *el; + if(rn->up) { + rn->up->totrad[0]= 0.0; + rn->up->totrad[1]= 0.0; + rn->up->totrad[2]= 0.0; + if(rn->up->up) { + rn->up->up->totrad[0]= 0.0; + rn->up->up->totrad[1]= 0.0; + rn->up->up->totrad[2]= 0.0; + } + } + } + el= RG.elem; + for(a=0; a<RG.totelem; a++, el++) { + rn= *el; + if(rn->up) { + rn->up->totrad[0]+= 0.5*rn->totrad[0]; + rn->up->totrad[1]+= 0.5*rn->totrad[1]; + rn->up->totrad[2]+= 0.5*rn->totrad[2]; + if(rn->up->up) { + rn->up->up->totrad[0]+= 0.25*rn->totrad[0]; + rn->up->up->totrad[1]+= 0.25*rn->totrad[1]; + rn->up->up->totrad[2]+= 0.25*rn->totrad[2]; + } + } + } + + /* met area optellen */ + cd= coldata= MEM_mallocN(3*4*RG.totelem, "filterNodes"); + el= RG.elem; + for(a=0; a<RG.totelem; a++, el++) { + calcfiltrad(*el, cd); + cd+= 3; + } + + cd= coldata; + el= RG.elem; + for(a=0; a<RG.totelem; a++, el++) { + rn= *el; + VECCOPY(rn->totrad, cd); + cd+= 3; + } + MEM_freeN(coldata); +} + +void removeEqualNodes(short limit) +{ + /* nodes met kleur gelijk aan elkaar: verwijderen */ + RNode **el, *rn, *rn1; + float thresh, f1, f2; + int a, foundone=1, ok; + int c1, c2; + + if(limit==0) return; + + thresh= 1.0/(256.0*RG.radfactor); + thresh= 3.0*pow(thresh, RG.gamma); + + waitcursor(1); + + while(foundone) { + foundone= 0; + + el= RG.elem; + for(a=RG.totelem; a>1; a--, el++) { + rn= *el; + rn1= *(el+1); + + if(rn!=rn->par->first && rn1!=rn1->par->first) { + if(rn->up && rn->up==rn1->up) { + f1= rn->totrad[0]+ rn->totrad[1]+ rn->totrad[2]; + f2= rn1->totrad[0]+ rn1->totrad[1]+ rn1->totrad[2]; + + ok= 0; + if(f1<thresh && f2<thresh) ok= 1; + else { + c1= calculatecolor(rn->totrad[0]); + c2= calculatecolor(rn1->totrad[0]); + + if( abs(c1-c2)<=limit ) { + c1= calculatecolor(rn->totrad[1]); + c2= calculatecolor(rn1->totrad[1]); + + if( abs(c1-c2)<=limit ) { + c1= calculatecolor(rn->totrad[2]); + c2= calculatecolor(rn1->totrad[2]); + + if( abs(c1-c2)<=limit ) { + ok= 1; + } + } + } + } + + if(ok) { + rn->up->totrad[0]= 0.5*(rn->totrad[0]+rn1->totrad[0]); + rn->up->totrad[1]= 0.5*(rn->totrad[1]+rn1->totrad[1]); + rn->up->totrad[2]= 0.5*(rn->totrad[2]+rn1->totrad[2]); + rn1= rn->up; + deleteNodes(rn1); + if(rn1->down1) ; + else { + foundone++; + a--; el++; + } + } + } + } + } + if(foundone) { + makeGlobalElemArray(); + } + } + waitcursor(0); +} + +#define BLSIZE 32000 + +void rad_addmesh(void) +{ + Face *face = NULL; + Object *ob; + Mesh *me; + MVert *mvert; + MFace *mface; + Material *ma=0; + unsigned int *md, *coldata, *cd; + float **fpp, **poindata; + float cent[3], min[3], max[3]; + int a, vcount, vlnr, startf, endf; + + if(RG.totface==0) return; + + /* make sure there's alpha in the color, to distinguish */ + for(a=0; a<RG.totface; a++) { + RAD_NEXTFACE(a); + *((unsigned int *)face->v1+3) |= 0x1000000; + *((unsigned int *)face->v2+3) |= 0x1000000; + *((unsigned int *)face->v3+3) |= 0x1000000; + if(face->v4) { + *((unsigned int *)face->v4+3) |= 0x1000000; + } + } + + /* we write in blocks of BLSIZE vertices max */ + coldata= MEM_mallocN(4*BLSIZE, "writefaces"); + poindata= MEM_mallocN(sizeof(void *)*BLSIZE, "writefaces1"); + + vlnr= 0; + endf= 0; + while(endf<RG.totface) { + + cd= coldata; + fpp= poindata; + startf= endf; + vcount= 0; + + face= RG.facebase[(startf-1)>>10]+((startf-1) & 1023); + for(vlnr=startf; vlnr<RG.totface; vlnr++) { + RAD_NEXTFACE(vlnr); + + if( *((unsigned int *)face->v1+3) & 0x1000000 ) { /* is a color */ + *cd= *((unsigned int *)face->v1+3); + *((unsigned int *)face->v1+3) = vcount; + *fpp= face->v1; + fpp++; vcount++; cd++; + } + if( *((unsigned int *)face->v2+3) & 0x1000000 ) { + *cd= *((unsigned int *)face->v2+3); + *((unsigned int *)face->v2+3) = vcount; + *fpp= face->v2; + fpp++; vcount++; cd++; + } + if( *((unsigned int *)face->v3+3) & 0x1000000 ) { + *cd= *((unsigned int *)face->v3+3); + *((unsigned int *)face->v3+3) = vcount; + *fpp= face->v3; + fpp++; vcount++; cd++; + } + if(face->v4 && ( *((unsigned int *)face->v4+3) & 0x1000000 ) ) { + *cd= *((unsigned int *)face->v4+3); + *((unsigned int *)face->v4+3) = vcount; + *fpp= face->v4; + fpp++; vcount++; cd++; + } + + if(vcount>=BLSIZE-4) { + vlnr++; + break; + } + } + + /* we now make the Mesh */ + endf= vlnr; + + ob= add_object(OB_MESH); + + me= ob->data; + me->totvert= vcount; + me->totface= endf-startf; + me->flag= 0; + me->mvert= MEM_callocN(me->totvert*sizeof(MVert), "mverts"); + me->mcol= MEM_callocN(4*me->totface*sizeof(MCol), "mverts"); + me->mface= MEM_callocN(me->totface*sizeof(MFace), "mface"); + + + /* materials, and set VCOL flag */ + for(a=0; a<RG.totmat; a++) { + assign_material(ob, RG.matar[a], a+1); + ma= RG.matar[a]; + if(ma) ma->mode |= MA_VERTEXCOL; + } + + /* verts */ + mvert= me->mvert; + fpp= poindata; + for(a=0; a<me->totvert; a++, mvert++, fpp++) { + VECCOPY(mvert->co, *fpp); + } + + /* faces and mcol */ + mface= me->mface; + md= (unsigned int *)me->mcol; + + face= RG.facebase[(startf-1)>>10]+((startf-1) & 1023); + for(a=startf; a<endf; a++, md+=4, mface++) { + RAD_NEXTFACE(a); + mface->v1= *((unsigned int *)face->v1+3); + mface->v2= *((unsigned int *)face->v2+3); + mface->v3= *((unsigned int *)face->v3+3); + if(face->v4) mface->v4= *((unsigned int *)face->v4+3); + + mface->edcode= 3; + test_index_mface(mface, face->v4 ? 4 : 3); + mface->mat_nr= face->matindex; + + md[0]= coldata[mface->v1]; + md[1]= coldata[mface->v2]; + md[2]= coldata[mface->v3]; + md[3]= coldata[mface->v4]; + } + + /* boundbox en centrenew */ + + INIT_MINMAX(min, max); + + mvert= me->mvert; + for(a=0; a<me->totvert; a++, mvert++) { + DO_MINMAX(mvert->co, min, max); + } + + cent[0]= (min[0]+max[0])/2.0; + cent[1]= (min[1]+max[1])/2.0; + cent[2]= (min[2]+max[2])/2.0; + + mvert= me->mvert; + for(a=0; a<me->totvert; a++, mvert++) { + VecSubf(mvert->co, mvert->co, cent); + } + + VECCOPY(ob->loc, cent); + tex_space_mesh(me); + + /* restore colors */ + face= RG.facebase[(startf-1)>>10]+((startf-1) & 1023); + for(a=startf; a<endf; a++) { + RAD_NEXTFACE(a); + + cd= ((unsigned int *)face->v1+3); + if( *cd < 0x1000000 ) *cd= coldata[*cd]; + cd= ((unsigned int *)face->v2+3); + if( *cd < 0x1000000 ) *cd= coldata[*cd]; + cd= ((unsigned int *)face->v3+3); + if( *cd < 0x1000000 ) *cd= coldata[*cd]; + if(face->v4) { + cd= ((unsigned int *)face->v4+3); + if( *cd < 0x1000000 ) *cd= coldata[*cd]; + } + } + } + + MEM_freeN(coldata); + MEM_freeN(poindata); + +} + +void rad_replacemesh(void) +{ + RPatch *rp; + + deselectall(); + + rp= RG.patchbase.first; + while(rp) { + if( exist_object(rp->from)) rp->from->flag |= SELECT; + rp= rp->next; + } + + copy_objectflags(); + delete_obj(1); + + rad_addmesh(); +} + |