22b091a67a59616a7def9fb6fd55c04061dae3f1
[blender.git] / source / blender / radiosity / intern / source / radpostprocess.c
1 /* ***************************************
2  *
3  * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version. The Blender
9  * Foundation also sells licenses for use in proprietary software under
10  * the Blender License.  See http://www.blender.org/BL/ for information
11  * about this.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software Foundation,
20  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
21  *
22  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
23  * All rights reserved.
24  *
25  * The Original Code is: all of this file.
26  *
27  * Contributor(s): none yet.
28  *
29  * ***** END GPL/BL DUAL LICENSE BLOCK *****
30
31
32
33     radpostprocess.c    nov/dec 1992
34                                                 may 1999
35
36     - faces
37     - filtering and node-limit
38     - apply to meshes
39     $Id$
40
41  *************************************** */
42
43 #include <stdlib.h>
44 #include <string.h>
45 #include <math.h>
46
47 #ifdef HAVE_CONFIG_H
48 #include <config.h>
49 #endif
50
51 #include "MEM_guardedalloc.h"
52
53 #include "BLI_blenlib.h"
54 #include "BLI_arithb.h"
55 #include "BIF_toolbox.h"  // notice()
56
57 #include "DNA_material_types.h"
58 #include "DNA_mesh_types.h"
59 #include "DNA_meshdata_types.h"
60 #include "DNA_object_types.h"
61 #include "DNA_radio_types.h"
62
63 #include "BKE_utildefines.h"
64 #include "BKE_global.h"
65 #include "BKE_main.h"
66 #include "BKE_mesh.h"
67 #include "BKE_object.h"
68 #include "BKE_material.h"
69
70 #include "BIF_screen.h"         /* waitcursor */
71 #include "BIF_editview.h"       /* deselectall */
72
73 #include "BDR_editobject.h"     /* delete_obj */
74
75 #include "radio.h"
76
77 /* locals? not. done in radio.h...  */
78 /*  void rad_addmesh(void); */
79 /*  void rad_replacemesh(void); */
80
81 void addaccu(register char *z, register char *t)
82 {
83         register int div, mul;
84
85         mul= *t;
86         div= mul+1;
87         (*t)++;
88
89         t[1]= (mul*t[1]+z[1])/div;
90         t[2]= (mul*t[2]+z[2])/div;
91         t[3]= (mul*t[3]+z[3])/div;
92
93 }
94
95 void addaccuweight(register char *z, register char *t, int w)
96 {
97         register int div, mul;
98         
99         if(w==0) w= 1;
100         
101         mul= *t;
102         div= mul+w;
103         if(div>255) return;
104         (*t)= div;
105
106         t[1]= (mul*t[1]+w*z[1])/div;
107         t[2]= (mul*t[2]+w*z[2])/div;
108         t[3]= (mul*t[3]+w*z[3])/div;
109
110 }
111
112 void triaweight(Face *face, int *w1, int *w2, int *w3)
113 {
114         float n1[3], n2[3], n3[3], temp;
115
116         n1[0]= face->v2[0]-face->v1[0];
117         n1[1]= face->v2[1]-face->v1[1];
118         n1[2]= face->v2[2]-face->v1[2];
119         n2[0]= face->v3[0]-face->v2[0];
120         n2[1]= face->v3[1]-face->v2[1];
121         n2[2]= face->v3[2]-face->v2[2];
122         n3[0]= face->v1[0]-face->v3[0];
123         n3[1]= face->v1[1]-face->v3[1];
124         n3[2]= face->v1[2]-face->v3[2];
125         Normalise(n1);
126         Normalise(n2);
127         Normalise(n3);
128         temp= 32.0/(PI);
129         *w1= 0.5+temp*acos(-n1[0]*n3[0]-n1[1]*n3[1]-n1[2]*n3[2]);
130         *w2= 0.5+temp*acos(-n1[0]*n2[0]-n1[1]*n2[1]-n1[2]*n2[2]);
131         *w3= 0.5+temp*acos(-n2[0]*n3[0]-n2[1]*n3[1]-n2[2]*n3[2]);
132         
133 }
134
135
136
137 void init_face_tab()
138 {
139         int a= 0;
140
141         if(RG.facebase==0) {
142                 RG.facebase= MEM_callocN(sizeof(void *)*RAD_MAXFACETAB, "init_face_tab");
143         }
144         for(a=0; a<RAD_MAXFACETAB; a++) {
145                 if(RG.facebase[a]==0) break;
146                 MEM_freeN(RG.facebase[a]);
147                 RG.facebase[a]= 0;
148         }
149         RG.totface= 0;
150 }
151
152 Face *addface()
153 {
154         Face *face;
155         int a;
156
157         if(RG.totface<0 || RG.totface>RAD_MAXFACETAB*1024 ) {
158                 printf("error in addface: %d\n", RG.totface);
159                 return 0;
160         }
161         a= RG.totface>>10;
162         face= RG.facebase[a];
163         if(face==0) {
164                 face= MEM_callocN(1024*sizeof(Face),"addface");
165                 RG.facebase[a]= face;
166         }
167         face+= (RG.totface & 1023);
168         
169         RG.totface++;
170         
171         return face;
172
173 }
174
175 #define HALFUV(uv, uv1, uv2) {uv[0] = 0.5 * (uv1[0] + uv2[0]); uv[1] = 0.5 * (uv1[1] + uv2[1]);}
176 #define COPYUV(dst, src) {dst[0] = src[0]; dst[1] = src[1];}
177
178 void dofaceuv(Face *face, float uvs[8][2], short flag1, short flag2, short flag3, short flag4)
179 {
180         COPYUV(face->uv[0], uvs[flag1]);
181         COPYUV(face->uv[1], uvs[flag2]);
182         COPYUV(face->uv[2], uvs[flag3]);
183         COPYUV(face->uv[3], uvs[flag4]);
184 }
185
186 Face * makeface(float *v1, float *v2, float *v3, float *v4, RNode *rn, short hasUV)
187 {
188         Face *face;
189         
190         face= addface();
191         face->v1= v1;
192         face->v2= v2;
193         face->v3= v3;
194         face->v4= v4;
195         face->col= rn->col;
196         face->matindex= rn->par->matindex;
197         face->tface = rn->tface;
198
199         if (hasUV)
200                 memcpy(face->uv, rn->uv, sizeof(float) * 4 * 2);
201
202         return face;
203 }
204
205 void anchorQuadface(RNode *rn, float *v1, float *v2, float *v3, float *v4, int flag)
206 {
207         Face *face;
208         float uvs[8][2];
209
210         memcpy(uvs, rn->uv, sizeof(float) * 4 * 2);
211         HALFUV(uvs[4], rn->uv[0], rn->uv[1]);
212         HALFUV(uvs[5], rn->uv[1], rn->uv[2]);
213         HALFUV(uvs[6], rn->uv[2], rn->uv[3]);
214         HALFUV(uvs[7], rn->uv[3], rn->uv[0]);
215
216         switch(flag) {
217                 case 1:
218                         face = makeface(rn->v1, v1, rn->v4, NULL, rn, 0);
219                         dofaceuv(face, uvs, 0, 4, 3, 0);
220
221                         face = makeface(v1, rn->v3, rn->v4, NULL, rn, 0);
222                         dofaceuv(face, uvs, 4, 2, 3, 0);
223                         
224                         face = makeface(v1, rn->v2, rn->v3, NULL, rn, 0);
225                         dofaceuv(face, uvs, 4, 1, 2, 0);
226
227                         break;
228                 case 2:
229                         face = makeface(rn->v2, v2, rn->v1, NULL, rn, 0);
230                         dofaceuv(face, uvs, 1, 5, 0, 0);
231
232                         face = makeface(v2, rn->v4, rn->v1, NULL, rn, 0);
233                         dofaceuv(face, uvs, 5, 3, 0, 0);
234
235                         face = makeface(v2, rn->v3, rn->v4, NULL, rn, 0);
236                         dofaceuv(face, uvs, 5, 2, 3, 0);
237
238                         break;
239                 case 4:
240                         face = makeface(rn->v3, v3, rn->v2, NULL, rn, 0);
241                         dofaceuv(face, uvs, 2, 6, 1, 0);
242
243                         face = makeface(v3, rn->v1, rn->v2, NULL, rn, 0);
244                         dofaceuv(face, uvs, 6, 0, 1, 0);
245
246                         face = makeface(v3, rn->v4, rn->v1, NULL, rn, 0);
247                         dofaceuv(face, uvs, 6, 3, 0, 0);
248
249                         break;
250                 case 8:
251                         face = makeface(rn->v4, v4, rn->v3, NULL, rn, 0);
252                         dofaceuv(face, uvs, 3, 7, 2, 0);
253
254                         face = makeface(v4, rn->v2, rn->v3, NULL, rn, 0);
255                         dofaceuv(face, uvs, 7, 1, 2, 0);
256
257                         face = makeface(v4, rn->v1, rn->v2, NULL, rn, 0);
258                         dofaceuv(face, uvs, 7, 0, 1, 0);
259
260                         break;
261                         
262                 case 3:
263                         face = makeface(rn->v1, v1, rn->v4, NULL, rn, 0);
264                         dofaceuv(face, uvs, 0, 4, 3, 0);
265
266                         face = makeface(v1, v2, rn->v4, NULL, rn, 0);
267                         dofaceuv(face, uvs, 4, 5, 3, 0);
268
269                         face = makeface(v1, rn->v2, v2, NULL, rn, 0);
270                         dofaceuv(face, uvs, 4, 1, 5, 0);
271
272                         face = makeface(v2, rn->v3, rn->v4, NULL, rn, 0);
273                         dofaceuv(face, uvs, 5, 2, 3, 0);
274
275                         break;
276                 case 6:
277                         face = makeface(rn->v2, v2, rn->v1, NULL, rn, 0);
278                         dofaceuv(face, uvs, 1, 5, 0, 0);
279
280                         face = makeface(v2, v3, rn->v1, NULL, rn, 0);
281                         dofaceuv(face, uvs, 5, 6, 0, 0);
282
283                         face = makeface(v2, rn->v3, v3, NULL, rn, 0);
284                         dofaceuv(face, uvs, 5, 2, 6, 0);
285
286                         face = makeface(v3, rn->v4, rn->v1, NULL, rn, 0);
287                         dofaceuv(face, uvs, 6, 3, 0, 0);
288
289                         break;
290                 case 12:
291                         face = makeface(rn->v3, v3, rn->v2, NULL, rn, 0);
292                         dofaceuv(face, uvs, 2, 6, 1, 0);
293
294                         face = makeface(v3, v4, rn->v2, NULL, rn, 0);
295                         dofaceuv(face, uvs, 6, 7, 1, 0);
296
297                         face = makeface(v3, rn->v4, v4, NULL, rn, 0);
298                         dofaceuv(face, uvs, 6, 3, 7, 0);
299
300                         face = makeface(v4, rn->v1, rn->v2, NULL, rn, 0);
301                         dofaceuv(face, uvs, 7, 0, 1, 0);
302
303                         break;
304                 case 9:
305                         face = makeface(rn->v4, v4, rn->v3, NULL, rn, 0);
306                         dofaceuv(face, uvs, 3, 7, 2, 0);
307
308                         face = makeface(v4, v1, rn->v3, NULL, rn, 0);
309                         dofaceuv(face, uvs, 7, 4, 2, 0);
310
311                         face = makeface(v4, rn->v1, v1, NULL, rn, 0);
312                         dofaceuv(face, uvs, 7, 0, 4, 0);
313
314                         face = makeface(v1, rn->v2, rn->v3, NULL, rn, 0);
315                         dofaceuv(face, uvs, 4, 1, 2, 0);
316
317                         break;
318                         
319                 case 5:
320                         face = makeface(rn->v1, v1, v3, rn->v4, rn, 0);
321                         dofaceuv(face, uvs, 0, 4, 6, 3);
322
323                         face = makeface(v1, rn->v2, rn->v3, v3, rn, 0);
324                         dofaceuv(face, uvs, 4, 1, 2, 6);
325
326                         break;
327                 case 10:
328                         face = makeface(rn->v1, rn->v2, v2, v4, rn, 0);
329                         dofaceuv(face, uvs, 0, 1, 5, 7);
330
331                         face = makeface(v4, v2, rn->v3, rn->v4, rn, 0);
332                         dofaceuv(face, uvs, 7, 5, 2, 3);
333
334                         break;
335                         
336                 case 7:
337                         face = makeface(rn->v1, v1, v3, rn->v4, rn, 0);
338                         dofaceuv(face, uvs, 0, 4, 6, 3);
339
340                         face = makeface(v1, v2, v3, NULL, rn, 0);
341                         dofaceuv(face, uvs, 4, 5, 6, 0);
342
343                         face = makeface(v1, rn->v2, v2, NULL, rn, 0);
344                         dofaceuv(face, uvs, 4, 1, 5, 0);
345
346                         face = makeface(v2, rn->v3, v3, NULL, rn, 0);
347                         dofaceuv(face, uvs, 5, 2, 6, 0);
348
349                         break;
350                 case 14:
351                         face = makeface(rn->v2, v2, v4, rn->v1, rn, 0);
352                         dofaceuv(face, uvs, 1, 5, 7, 0);
353
354                         face = makeface(v2, v3, v4, NULL, rn, 0);
355                         dofaceuv(face, uvs, 5, 6, 7, 0);
356
357                         face = makeface(v2, rn->v3, v3, NULL, rn, 0);
358                         dofaceuv(face, uvs, 5, 2, 6, 0);
359
360                         face = makeface(v3, rn->v4, v4, NULL, rn, 0);
361                         dofaceuv(face, uvs, 6, 3, 7, 0);
362
363                         break;
364                 case 13:
365                         face = makeface(rn->v3, v3, v1, rn->v2, rn, 0);
366                         dofaceuv(face, uvs, 2, 6, 4, 1);
367
368                         face = makeface(v3, v4, v1, NULL, rn, 0);
369                         dofaceuv(face, uvs, 6, 7, 4, 0);
370
371                         face = makeface(v3, rn->v4, v4, NULL, rn, 0);
372                         dofaceuv(face, uvs, 6, 3, 7, 0);
373
374                         face = makeface(v4, rn->v1, v1, NULL, rn, 0);
375                         dofaceuv(face, uvs, 7, 0, 4, 0);
376
377                         break;
378                 case 11:
379                         face = makeface(rn->v4, v4, v2, rn->v3, rn, 0);
380                         dofaceuv(face, uvs, 3, 7, 5, 2);
381
382                         face = makeface(v4, v1, v2, NULL, rn, 0);
383                         dofaceuv(face, uvs, 7, 4, 5, 0);
384
385                         face = makeface(v4, rn->v1, v1, NULL, rn, 0);
386                         dofaceuv(face, uvs, 7, 0, 4, 0);
387
388                         face = makeface(v1, rn->v2, v2, NULL, rn, 0);
389                         dofaceuv(face, uvs, 4, 1, 5, 0);
390
391                         break;
392                 
393                 case 15:
394                         face = makeface(v1, v2, v3, v4, rn, 0);
395                         dofaceuv(face, uvs, 4, 5, 6, 7);
396
397                         face = makeface(v1, rn->v2, v2, NULL, rn, 0);
398                         dofaceuv(face, uvs, 4, 1, 5, 0);
399
400                         face = makeface(v2, rn->v3, v3, NULL, rn, 0);
401                         dofaceuv(face, uvs, 5, 2, 6, 0);
402
403                         face = makeface(v3, rn->v4, v4, NULL, rn, 0);
404                         dofaceuv(face, uvs, 6, 3, 7, 0);
405
406                         face = makeface(v4, rn->v1, v1, NULL, rn, 0);
407                         dofaceuv(face, uvs, 7, 0, 4, 0);
408
409                         break;
410         }
411 }
412
413 void anchorTriface(RNode *rn, float *v1, float *v2, float *v3, int flag)
414 {
415         Face *face;
416         float uvs[8][2];
417
418         memcpy(uvs, rn->uv, sizeof(float) * 4 * 2);
419         HALFUV(uvs[4], rn->uv[0], rn->uv[1]);
420         HALFUV(uvs[5], rn->uv[1], rn->uv[2]);
421         HALFUV(uvs[6], rn->uv[2], rn->uv[0]);
422
423         switch(flag) {
424                 case 1:
425                         face = makeface(rn->v1, v1, rn->v3, NULL, rn, 0);
426                         dofaceuv(face, uvs, 0, 4, 2, 0);
427
428                         face = makeface(v1, rn->v2, rn->v3, NULL, rn, 0);
429                         dofaceuv(face, uvs, 4, 1, 2, 0);
430
431                         break;
432                 case 2:
433                         face = makeface(rn->v2, v2, rn->v1, NULL, rn, 0);
434                         dofaceuv(face, uvs, 1, 5, 0, 0);
435
436                         face = makeface(v2, rn->v3, rn->v1, NULL, rn, 0);
437                         dofaceuv(face, uvs, 5, 2, 0, 0);
438
439                         break;
440                 case 4:
441                         face = makeface(rn->v3, v3, rn->v2, NULL, rn, 0);
442                         dofaceuv(face, uvs, 2, 6, 1, 0);
443
444                         face = makeface(v3, rn->v1, rn->v2, NULL, rn, 0);
445                         dofaceuv(face, uvs, 6, 0, 1, 0);
446
447                         break;
448                         
449                 case 3:
450                         face = makeface(rn->v1, v2, rn->v3, NULL, rn, 0);
451                         dofaceuv(face, uvs, 0, 5, 2, 0);
452
453                         face = makeface(rn->v1, v1, v2, NULL, rn, 0);
454                         dofaceuv(face, uvs, 0, 4, 5, 0);
455
456                         face = makeface(v1, rn->v2, v2, NULL, rn, 0);
457                         dofaceuv(face, uvs, 4, 1, 5, 0);
458
459                         break;
460                 case 6:
461                         face = makeface(rn->v2, v3, rn->v1, NULL, rn, 0);
462                         dofaceuv(face, uvs, 1, 6, 0, 0);
463
464                         face = makeface(rn->v2, v2, v3, NULL, rn, 0);
465                         dofaceuv(face, uvs, 1, 5, 6, 0);
466
467                         face = makeface(v2, rn->v3, v3, NULL, rn, 0);
468                         dofaceuv(face, uvs, 5, 2, 6, 0);
469
470                         break;
471                 case 5:
472                         face = makeface(rn->v3, v1, rn->v2, NULL, rn, 0);
473                         dofaceuv(face, uvs, 2, 4, 1, 0);
474
475                         face = makeface(rn->v3, v3, v1, NULL, rn, 0);
476                         dofaceuv(face, uvs, 2, 6, 4, 0);
477
478                         face = makeface(v3, rn->v1, v1, NULL, rn, 0);
479                         dofaceuv(face, uvs, 6, 0, 4, 0);
480
481                         break;
482                         
483                 case 7:
484                         face = makeface(v1, v2, v3, NULL, rn, 0);
485                         dofaceuv(face, uvs, 4, 5, 6, 0);
486
487                         face = makeface(rn->v1, v1, v3, NULL, rn, 0);
488                         dofaceuv(face, uvs, 0, 4, 6, 0);
489
490                         face = makeface(rn->v2, v2, v1, NULL, rn, 0);
491                         dofaceuv(face, uvs, 1, 5, 4, 0);
492
493                         face = makeface(rn->v3, v3, v2, NULL, rn, 0);
494                         dofaceuv(face, uvs, 2, 6, 5, 0);
495
496                         break;
497         }       
498 }
499
500
501 float *findmiddlevertex(RNode *node, RNode *nb, float *v1, float *v2)
502 {
503         int test= 0;
504
505         if(nb==0) return 0;
506         
507         if(nb->ed1==node) {
508                 if(nb->v1==v1 || nb->v1==v2) test++;
509                 if(nb->v2==v1 || nb->v2==v2) test+=2;
510                 if(test==1) return nb->v2;
511                 else if(test==2) return nb->v1;
512         }
513         else if(nb->ed2==node) {
514                 if(nb->v2==v1 || nb->v2==v2) test++;
515                 if(nb->v3==v1 || nb->v3==v2) test+=2;
516                 if(test==1) return nb->v3;
517                 else if(test==2) return nb->v2;
518         }
519         else if(nb->ed3==node) {
520                 if(nb->type==4) {
521                         if(nb->v3==v1 || nb->v3==v2) test++;
522                         if(nb->v4==v1 || nb->v4==v2) test+=2;
523                         if(test==1) return nb->v4;
524                         else if(test==2) return nb->v3;
525                 }
526                 else {
527                         if(nb->v3==v1 || nb->v3==v2) test++;
528                         if(nb->v1==v1 || nb->v1==v2) test+=2;
529                         if(test==1) return nb->v1;
530                         else if(test==2) return nb->v3;
531                 }
532         }
533         else if(nb->ed4==node) {
534                 if(nb->v4==v1 || nb->v4==v2) test++;
535                 if(nb->v1==v1 || nb->v1==v2) test+=2;
536                 if(test==1) return nb->v1;
537                 else if(test==2) return nb->v4;
538         }
539         return 0;
540 }
541
542 void make_face_tab()    /* takes care of anchoring */
543 {
544         RNode *rn, **el;
545         Face *face = NULL;
546         float *v1, *v2, *v3, *v4;
547         int a, flag, w1, w2, w3;
548         char *charcol;
549
550         if(RG.totelem==0) return;
551         
552         init_face_tab();
553         
554         RG.igamma= 1.0/RG.gamma;
555         RG.radfactor= RG.radfac*pow(64*64, RG.igamma);
556
557         /* convert face colors */
558         el= RG.elem;
559         for(a=RG.totelem; a>0; a--, el++) {
560                 rn= *el;
561                 charcol= (char *)&( rn->col );
562
563                 charcol[3]= calculatecolor(rn->totrad[0]);
564                 charcol[2]= calculatecolor(rn->totrad[1]);
565                 charcol[1]= calculatecolor(rn->totrad[2]);
566         }
567         
568         /* check nodes and make faces */
569         el= RG.elem;
570         for(a=RG.totelem; a>0; a--, el++) {
571
572                 rn= *el;
573                 
574                 rn->v1[3]= 0.0;
575                 rn->v2[3]= 0.0;
576                 rn->v3[3]= 0.0;
577                 if(rn->v4) rn->v4[3]= 0.0;
578                 
579                 /* test edges for subdivide */
580                 flag= 0;
581                 v1= v2= v3= v4= 0;
582                 if(rn->ed1) {
583                         v1= findmiddlevertex(rn, rn->ed1->down1, rn->v1, rn->v2);
584                         if(v1) flag |= 1;
585                 }
586                 if(rn->ed2) {
587                         v2= findmiddlevertex(rn, rn->ed2->down1, rn->v2, rn->v3);
588                         if(v2) flag |= 2;
589                 }
590                 if(rn->ed3) {
591                         if(rn->type==4)
592                                 v3= findmiddlevertex(rn, rn->ed3->down1, rn->v3, rn->v4);
593                         else
594                                 v3= findmiddlevertex(rn, rn->ed3->down1, rn->v3, rn->v1);
595                         if(v3) flag |= 4;
596                 }
597                 if(rn->ed4) {
598                         v4= findmiddlevertex(rn, rn->ed4->down1, rn->v4, rn->v1);
599                         if(v4) flag |= 8;
600                 }
601                 
602                 /* using flag and vertexpointers now Faces can be made */
603                 
604                 if(flag==0) {
605                         makeface(rn->v1, rn->v2, rn->v3, rn->v4, rn, 1);
606                 }
607                 else if(rn->type==4) anchorQuadface(rn, v1, v2, v3, v4, flag);
608                 else anchorTriface(rn, v1, v2, v3, flag);
609         }
610         
611         /* add */
612         for(a=0; a<RG.totface; a++) {
613                 
614                 RAD_NEXTFACE(a);
615                 
616                 if(face->v4) {
617                         addaccuweight( (char *)&(face->col), (char *)(face->v1+3), 16 );
618                         addaccuweight( (char *)&(face->col), (char *)(face->v2+3), 16 );
619                         addaccuweight( (char *)&(face->col), (char *)(face->v3+3), 16 );
620                         addaccuweight( (char *)&(face->col), (char *)(face->v4+3), 16 );
621                 }
622                 else {
623                         triaweight(face, &w1, &w2, &w3);
624                         addaccuweight( (char *)&(face->col), (char *)(face->v1+3), w1 );
625                         addaccuweight( (char *)&(face->col), (char *)(face->v2+3), w2 );
626                         addaccuweight( (char *)&(face->col), (char *)(face->v3+3), w3 );
627                 }
628         }
629
630 }
631
632 void filterFaces()
633 {
634         /* put vertex colors in faces, and put them back */
635         
636         Face *face = NULL;
637         int a, w1, w2, w3;
638
639         if(RG.totface==0) return;
640
641         /* clear */
642         for(a=0; a<RG.totface; a++) {
643                 RAD_NEXTFACE(a);
644                 face->col= 0;
645         }
646         
647         /* add: vertices with faces */
648         for(a=0; a<RG.totface; a++) {
649                 RAD_NEXTFACE(a);
650                 
651                 if(face->v4) {
652                         addaccuweight( (char *)(face->v1+3), (char *)&(face->col), 16 );
653                         addaccuweight( (char *)(face->v2+3), (char *)&(face->col), 16 );
654                         addaccuweight( (char *)(face->v3+3), (char *)&(face->col), 16 );
655                         addaccuweight( (char *)(face->v4+3), (char *)&(face->col), 16 );
656                 }
657                 else {
658                         triaweight(face, &w1, &w2, &w3);
659                         addaccuweight( (char *)(face->v1+3), (char *)&(face->col), w1 );
660                         addaccuweight( (char *)(face->v2+3), (char *)&(face->col), w2 );
661                         addaccuweight( (char *)(face->v3+3), (char *)&(face->col), w3 );
662                 }
663         }
664         
665         /* clear */
666         for(a=0; a<RG.totface; a++) {
667                 RAD_NEXTFACE(a);
668                 face->v1[3]= 0.0;
669                 face->v2[3]= 0.0;
670                 face->v3[3]= 0.0;
671                 if(face->v4) face->v4[3]= 0.0;
672         }
673
674
675         /* add: faces with vertices */
676         for(a=0; a<RG.totface; a++) {
677                 
678                 RAD_NEXTFACE(a);
679                 
680                 if(face->v4) {
681                         addaccuweight( (char *)&(face->col), (char *)(face->v1+3), 16 );
682                         addaccuweight( (char *)&(face->col), (char *)(face->v2+3), 16 );
683                         addaccuweight( (char *)&(face->col), (char *)(face->v3+3), 16 );
684                         addaccuweight( (char *)&(face->col), (char *)(face->v4+3), 16 );
685                 }
686                 else {
687                         triaweight(face, &w1, &w2, &w3);
688                         addaccuweight( (char *)&(face->col), (char *)(face->v1+3), w1 );
689                         addaccuweight( (char *)&(face->col), (char *)(face->v2+3), w2 );
690                         addaccuweight( (char *)&(face->col), (char *)(face->v3+3), w3 );
691                 }
692         }
693 }
694
695 void calcfiltrad(RNode *rn, float *cd)
696 {
697         float area;
698
699         cd[0]= 2.0*rn->totrad[0];
700         cd[1]= 2.0*rn->totrad[1];
701         cd[2]= 2.0*rn->totrad[2];
702         area= 2.0;
703         
704         if(rn->ed1) {
705                 cd[0]+= rn->ed1->totrad[0];
706                 cd[1]+= rn->ed1->totrad[1];
707                 cd[2]+= rn->ed1->totrad[2];
708                 area+= 1.0;
709         }
710         if(rn->ed2) {
711                 cd[0]+= rn->ed2->totrad[0];
712                 cd[1]+= rn->ed2->totrad[1];
713                 cd[2]+= rn->ed2->totrad[2];
714                 area+= 1.0;
715         }
716         if(rn->ed3) {
717                 cd[0]+= rn->ed3->totrad[0];
718                 cd[1]+= rn->ed3->totrad[1];
719                 cd[2]+= rn->ed3->totrad[2];
720                 area+= 1.0;
721         }
722         if(rn->ed4) {
723                 cd[0]+= rn->ed4->totrad[0];
724                 cd[1]+= rn->ed4->totrad[1];
725                 cd[2]+= rn->ed4->totrad[2];
726                 area+= 1.0;
727         }
728         cd[0]/= area;
729         cd[1]/= area;
730         cd[2]/= area;
731         
732 }
733
734 void filterNodes()
735 {
736         /* colors from nodes in tempblock and back */
737         
738         RNode *rn, **el;
739         float *coldata, *cd;
740         int a;
741
742         if(RG.totelem==0) return;
743         /* the up-nodes need a color */
744         el= RG.elem;
745         for(a=0; a<RG.totelem; a++, el++) {
746                 rn= *el;
747                 if(rn->up) {
748                         rn->up->totrad[0]= 0.0;
749                         rn->up->totrad[1]= 0.0;
750                         rn->up->totrad[2]= 0.0;
751                         if(rn->up->up) {
752                                 rn->up->up->totrad[0]= 0.0;
753                                 rn->up->up->totrad[1]= 0.0;
754                                 rn->up->up->totrad[2]= 0.0;
755                         }
756                 }
757         }
758         el= RG.elem;
759         for(a=0; a<RG.totelem; a++, el++) {
760                 rn= *el;
761                 if(rn->up) {
762                         rn->up->totrad[0]+= 0.5*rn->totrad[0];
763                         rn->up->totrad[1]+= 0.5*rn->totrad[1];
764                         rn->up->totrad[2]+= 0.5*rn->totrad[2];
765                         if(rn->up->up) {
766                                 rn->up->up->totrad[0]+= 0.25*rn->totrad[0];
767                                 rn->up->up->totrad[1]+= 0.25*rn->totrad[1];
768                                 rn->up->up->totrad[2]+= 0.25*rn->totrad[2];
769                         }
770                 }
771         }
772         
773         /* add using area */
774         cd= coldata= MEM_mallocN(3*4*RG.totelem, "filterNodes");
775         el= RG.elem;
776         for(a=0; a<RG.totelem; a++, el++) {
777                 calcfiltrad(*el, cd);
778                 cd+= 3;
779         }
780         
781         cd= coldata;
782         el= RG.elem;
783         for(a=0; a<RG.totelem; a++, el++) {
784                 rn= *el;
785                 VECCOPY(rn->totrad, cd);
786                 cd+= 3;
787         }
788         MEM_freeN(coldata);
789 }
790
791 void removeEqualNodes(short limit)
792 {
793         /* nodes with equal colors: remove */
794         RNode **el, *rn, *rn1;
795         float thresh, f1, f2;
796         int a, foundone=1, ok;
797         int c1, c2;
798         
799         if(limit==0) return;
800         
801         thresh= 1.0/(256.0*RG.radfactor);
802         thresh= 3.0*pow(thresh, RG.gamma);
803         
804         waitcursor(1);
805                 
806         while(foundone) {
807                 foundone= 0;
808                 
809                 el= RG.elem;
810                 for(a=RG.totelem; a>1; a--, el++) {
811                         rn= *el;
812                         rn1= *(el+1);
813                         
814                         if(rn!=rn->par->first && rn1!=rn1->par->first) {
815                                 if(rn->up && rn->up==rn1->up) {
816                                         f1= rn->totrad[0]+ rn->totrad[1]+ rn->totrad[2];
817                                         f2= rn1->totrad[0]+ rn1->totrad[1]+ rn1->totrad[2];
818                                         
819                                         ok= 0;
820                                         if(f1<thresh && f2<thresh) ok= 1;
821                                         else {
822                                                 c1= calculatecolor(rn->totrad[0]);
823                                                 c2= calculatecolor(rn1->totrad[0]);
824                                                 
825                                                 if( abs(c1-c2)<=limit ) {
826                                                         c1= calculatecolor(rn->totrad[1]);
827                                                         c2= calculatecolor(rn1->totrad[1]);
828                                                         
829                                                         if( abs(c1-c2)<=limit ) {
830                                                                 c1= calculatecolor(rn->totrad[2]);
831                                                                 c2= calculatecolor(rn1->totrad[2]);
832                                                                 
833                                                                 if( abs(c1-c2)<=limit ) {
834                                                                         ok= 1;
835                                                                 }
836                                                         }
837                                                 }
838                                         }
839                                         
840                                         if(ok) {
841                                                 rn->up->totrad[0]= 0.5f*(rn->totrad[0]+rn1->totrad[0]);
842                                                 rn->up->totrad[1]= 0.5f*(rn->totrad[1]+rn1->totrad[1]);
843                                                 rn->up->totrad[2]= 0.5f*(rn->totrad[2]+rn1->totrad[2]);
844                                                 rn1= rn->up;
845                                                 deleteNodes(rn1);
846                                                 if(rn1->down1) ;
847                                                 else {
848                                                         foundone++;
849                                                         a--; el++;
850                                                 }
851                                         }
852                                 }
853                         }
854                 }
855                 if(foundone) {
856                         makeGlobalElemArray();
857                 }
858         }
859         waitcursor(0);
860 }
861
862 #define BLSIZE  32000
863
864 void rad_addmesh(void)
865 {
866         Face *face = NULL;
867         Object *ob;
868         Mesh *me;
869         MVert *mvert;
870         MFace *mface;
871         TFace *tface;
872         Material *ma=0;
873         unsigned int *md, *coldata, *cd;
874         float **fpp, **poindata;
875         float cent[3], min[3], max[3];
876         int a, vcount, vlnr, startf, endf;
877         
878         if(RG.totface==0) return;
879         
880         if(RG.totmat==MAXMAT) notice("warning: cannot assign more than 16 materials to 1 mesh");
881         
882         /* make sure there's alpha in the color, to distinguish */
883         for(a=0; a<RG.totface; a++) {
884                 RAD_NEXTFACE(a);
885                 *((unsigned int *)face->v1+3) |= 0x1000000; 
886                 *((unsigned int *)face->v2+3) |= 0x1000000;
887                 *((unsigned int *)face->v3+3) |= 0x1000000;
888                 if(face->v4) {
889                         *((unsigned int *)face->v4+3) |= 0x1000000;
890                 }
891         }
892         
893         /* we write in blocks of BLSIZE vertices max */
894         coldata= MEM_mallocN(4*BLSIZE, "writefaces");
895         poindata= MEM_mallocN(sizeof(void *)*BLSIZE, "writefaces1");
896         
897         vlnr= 0; 
898         endf= 0;
899         while(endf<RG.totface) {
900                 
901                 cd= coldata;
902                 fpp= poindata;
903                 startf= endf;
904                 vcount= 0;
905         
906                 face= RG.facebase[(startf-1)>>10]+((startf-1) & 1023);
907                 for(vlnr=startf; vlnr<RG.totface; vlnr++) {
908                         RAD_NEXTFACE(vlnr);
909
910                         if( *((unsigned int *)face->v1+3) & 0x1000000 ) { /* is a color */
911                                 *cd= *((unsigned int *)face->v1+3);
912                                 *((unsigned int *)face->v1+3) = vcount;
913                                 *fpp= face->v1;
914                                 fpp++; vcount++; cd++;
915                         }
916                         if( *((unsigned int *)face->v2+3) & 0x1000000 ) {
917                                 *cd= *((unsigned int *)face->v2+3);
918                                 *((unsigned int *)face->v2+3) = vcount;
919                                 *fpp= face->v2;
920                                 fpp++; vcount++; cd++;
921                         }
922                         if( *((unsigned int *)face->v3+3) & 0x1000000 ) {
923                                 *cd= *((unsigned int *)face->v3+3);
924                                 *((unsigned int *)face->v3+3) = vcount;
925                                 *fpp= face->v3;
926                                 fpp++; vcount++; cd++;
927                         }
928                         if(face->v4 && ( *((unsigned int *)face->v4+3) & 0x1000000 ) ) {
929                                 *cd= *((unsigned int *)face->v4+3);
930                                 *((unsigned int *)face->v4+3) = vcount;
931                                 *fpp= face->v4;
932                                 fpp++; vcount++; cd++;
933                         }
934
935                         if(vcount>=BLSIZE-4) {
936                                 vlnr++;
937                                 break;
938                         }
939                 }
940
941                 /* we now make the Mesh */
942                 endf= vlnr;
943
944                 ob= add_object(OB_MESH);
945                 
946                 me= ob->data;
947                 me->totvert= vcount;
948                 me->totface= endf-startf;
949                 me->flag= 0;
950                 me->mvert= MEM_callocN(me->totvert*sizeof(MVert), "mverts");
951                 //me->mcol= MEM_callocN(4*me->totface*sizeof(MCol), "mverts");
952                 me->mface= MEM_callocN(me->totface*sizeof(MFace), "mface");
953                 me->tface= MEM_callocN(me->totface*sizeof(TFace), "tface");
954
955                 /* materials, and set VCOL flag */
956                 for(a=0; a<RG.totmat; a++) {
957                         assign_material(ob, RG.matar[a], a+1);
958                         ma= RG.matar[a];
959                         if(ma) ma->mode |= MA_VERTEXCOL;
960                 }
961
962                 /* verts */
963                 mvert= me->mvert;
964                 fpp= poindata;
965                 for(a=0; a<me->totvert; a++, mvert++, fpp++) {
966                         VECCOPY(mvert->co, *fpp);
967                 }
968
969                 /* faces, mcol and uv */
970                 mface= me->mface;
971                 tface = me->tface;
972                 md= (unsigned int *)me->mcol;
973
974                 face= RG.facebase[(startf-1)>>10]+((startf-1) & 1023);
975                 for(a=startf; a<endf; a++, md+=4, mface++, tface++) {
976                         RAD_NEXTFACE(a);
977                         mface->v1= *((unsigned int *)face->v1+3);
978                         mface->v2= *((unsigned int *)face->v2+3);
979                         mface->v3= *((unsigned int *)face->v3+3);
980                         if(face->v4) mface->v4= *((unsigned int *)face->v4+3);
981                         test_index_face(mface, NULL, NULL, face->v4 ? 4 : 3);
982                         mface->mat_nr= face->matindex;
983
984                         if (face->tface) {
985                                 memcpy(tface, face->tface, sizeof(TFace));
986                         }
987
988                         memcpy(tface->uv, face->uv, sizeof(float) * 4 * 2);
989                         tface->col[0]= coldata[mface->v1];
990                         tface->col[1]= coldata[mface->v2];
991                         tface->col[2]= coldata[mface->v3];
992                         tface->col[3]= coldata[mface->v4];
993                 }
994                 
995                 /* boundbox and centrenew */
996                 
997                 INIT_MINMAX(min, max);
998
999                 mvert= me->mvert;
1000                 for(a=0; a<me->totvert; a++, mvert++) {
1001                         DO_MINMAX(mvert->co, min, max);
1002                 }
1003
1004                 cent[0]= (min[0]+max[0])/2.0f;
1005                 cent[1]= (min[1]+max[1])/2.0f;
1006                 cent[2]= (min[2]+max[2])/2.0f;
1007
1008                 mvert= me->mvert;
1009                 for(a=0; a<me->totvert; a++, mvert++) {
1010                         VecSubf(mvert->co, mvert->co, cent);
1011                 }
1012                 
1013                 VECCOPY(ob->loc, cent);
1014                 
1015                 /* restore colors */
1016                 face= RG.facebase[(startf-1)>>10]+((startf-1) & 1023);
1017                 for(a=startf; a<endf; a++) {
1018                         RAD_NEXTFACE(a);
1019
1020                         cd= ((unsigned int *)face->v1+3);
1021                         if( *cd < 0x1000000 ) *cd= coldata[*cd];
1022                         cd= ((unsigned int *)face->v2+3);
1023                         if( *cd < 0x1000000 ) *cd= coldata[*cd];
1024                         cd= ((unsigned int *)face->v3+3);
1025                         if( *cd < 0x1000000 ) *cd= coldata[*cd];
1026                         if(face->v4) {
1027                                 cd= ((unsigned int *)face->v4+3);
1028                                 if( *cd < 0x1000000 ) *cd= coldata[*cd];
1029                         }
1030                 }
1031                 /* by default, meshes need edge list */
1032                 make_edges(me); 
1033         }
1034                 
1035         MEM_freeN(coldata);
1036         MEM_freeN(poindata);
1037         
1038 }
1039
1040 void rad_replacemesh(void)
1041 {
1042         RPatch *rp;
1043         
1044         deselectall();
1045         
1046         rp= RG.patchbase.first;
1047         while(rp) {
1048                 if( exist_object(rp->from)) {
1049                         if (rp->from->type == OB_MESH) {
1050                                 rp->from->flag |= SELECT;
1051                         }
1052                 }
1053                 rp= rp->next;
1054         }
1055         
1056         copy_objectflags();
1057         delete_obj(1);
1058         
1059         rad_addmesh();
1060 }
1061