svn merge -r 12653:12664 https://svn.blender.org/svnroot/bf-blender/trunk/blender
[blender.git] / source / blender / render / intern / source / rendercore.c
1 /**
2  * $Id$
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19  *
20  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
21  * All rights reserved.
22  *
23  * Contributors: Hos, Robert Wenzlaff.
24  * Contributors: 2004/2005/2006 Blender Foundation, full recode
25  *
26  * ***** END GPL LICENSE BLOCK *****
27  */
28
29 /* system includes */
30 #include <stdio.h>
31 #include <math.h>
32 #include <string.h>
33
34 /* External modules: */
35 #include "MEM_guardedalloc.h"
36
37 #include "BLI_arithb.h"
38 #include "BLI_blenlib.h"
39 #include "BLI_jitter.h"
40 #include "BLI_rand.h"
41 #include "BLI_threads.h"
42
43 #include "BKE_utildefines.h"
44
45 #include "DNA_image_types.h"
46 #include "DNA_lamp_types.h"
47 #include "DNA_material_types.h"
48 #include "DNA_meshdata_types.h"
49
50 #include "BKE_global.h"
51 #include "BKE_image.h"
52 #include "BKE_main.h"
53 #include "BKE_node.h"
54 #include "BKE_texture.h"
55
56 #include "IMB_imbuf_types.h"
57 #include "IMB_imbuf.h"
58
59 /* local include */
60 #include "renderpipeline.h"
61 #include "render_types.h"
62 #include "renderdatabase.h"
63 #include "pixelblending.h"
64 #include "pixelshading.h"
65 #include "shadbuf.h"
66 #include "shading.h"
67 #include "sss.h"
68 #include "zbuf.h"
69
70 #include "PIL_time.h"
71
72 /* own include */
73 #include "rendercore.h"
74
75
76 /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
77 /* defined in pipeline.c, is hardcopy of active dynamic allocated Render */
78 /* only to be used here in this file, it's for speed */
79 extern struct Render R;
80 /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
81
82 /* x and y are current pixels in rect to be rendered */
83 /* do not normalize! */
84 void calc_view_vector(float *view, float x, float y)
85 {
86
87         view[2]= -ABS(R.clipsta);
88         
89         if(R.r.mode & R_ORTHO) {
90                 view[0]= view[1]= 0.0f;
91         }
92         else {
93                 
94                 if(R.r.mode & R_PANORAMA)
95                         x-= R.panodxp;
96                 
97                 /* move x and y to real viewplane coords */
98                 x= (x/(float)R.winx);
99                 view[0]= R.viewplane.xmin + x*(R.viewplane.xmax - R.viewplane.xmin);
100                 
101                 y= (y/(float)R.winy);
102                 view[1]= R.viewplane.ymin + y*(R.viewplane.ymax - R.viewplane.ymin);
103                 
104 //              if(R.flag & R_SEC_FIELD) {
105 //                      if(R.r.mode & R_ODDFIELD) view[1]= (y+R.ystart)*R.ycor;
106 //                      else view[1]= (y+R.ystart+1.0)*R.ycor;
107 //              }
108 //              else view[1]= (y+R.ystart+R.bluroffsy+0.5)*R.ycor;
109         
110                 if(R.r.mode & R_PANORAMA) {
111                         float u= view[0] + R.panodxv; float v= view[2];
112                         view[0]= R.panoco*u + R.panosi*v;
113                         view[2]= -R.panosi*u + R.panoco*v;
114                 }
115         }
116 }
117
118 void calc_renderco_ortho(float *co, float x, float y, int z)
119 {
120         /* x and y 3d coordinate can be derived from pixel coord and winmat */
121         float fx= 2.0f/(R.winx*R.winmat[0][0]);
122         float fy= 2.0f/(R.winy*R.winmat[1][1]);
123         float zco;
124         
125         co[0]= (x - 0.5f*R.winx)*fx - R.winmat[3][0]/R.winmat[0][0];
126         co[1]= (y - 0.5f*R.winy)*fy - R.winmat[3][1]/R.winmat[1][1];
127         
128         zco= ((float)z)/2147483647.0f;
129         co[2]= R.winmat[3][2]/( R.winmat[2][3]*zco - R.winmat[2][2] );
130 }
131
132 void calc_renderco_zbuf(float *co, float *view, int z)
133 {
134         float fac, zco;
135         
136         /* inverse of zbuf calc: zbuf = MAXZ*hoco_z/hoco_w */
137         zco= ((float)z)/2147483647.0f;
138         co[2]= R.winmat[3][2]/( R.winmat[2][3]*zco - R.winmat[2][2] );
139
140         fac= co[2]/view[2];
141         co[0]= fac*view[0];
142         co[1]= fac*view[1];
143 }
144
145 /* also used in zbuf.c and shadbuf.c */
146 int count_mask(unsigned short mask)
147 {
148         if(R.samples)
149                 return (R.samples->cmask[mask & 255]+R.samples->cmask[mask>>8]);
150         return 0;
151 }
152
153 static int calchalo_z(HaloRen *har, int zz)
154 {
155         
156         if(har->type & HA_ONLYSKY) {
157                 if(zz!=0x7FFFFFFF) zz= - 0x7FFFFF;
158         }
159         else {
160                 zz= (zz>>8);
161         }
162         return zz;
163 }
164
165 static void halo_pixelstruct(HaloRen *har, float *rb, float dist, float xn, float yn, PixStr *ps)
166 {
167         float col[4], accol[4];
168         int amount, amountm, zz, flarec;
169         
170         amount= 0;
171         accol[0]=accol[1]=accol[2]=accol[3]= 0.0f;
172         flarec= har->flarec;
173         
174         while(ps) {
175                 amountm= count_mask(ps->mask);
176                 amount+= amountm;
177                 
178                 zz= calchalo_z(har, ps->z);
179                 if(zz> har->zs) {
180                         float fac;
181                         
182                         shadeHaloFloat(har, col, zz, dist, xn, yn, flarec);
183                         fac= ((float)amountm)/(float)R.osa;
184                         accol[0]+= fac*col[0];
185                         accol[1]+= fac*col[1];
186                         accol[2]+= fac*col[2];
187                         accol[3]+= fac*col[3];
188                         flarec= 0;
189                 }
190                 
191                 ps= ps->next;
192         }
193         /* now do the sky sub-pixels */
194         amount= R.osa-amount;
195         if(amount) {
196                 float fac;
197
198                 shadeHaloFloat(har, col, 0x7FFFFF, dist, xn, yn, flarec);
199                 fac= ((float)amount)/(float)R.osa;
200                 accol[0]+= fac*col[0];
201                 accol[1]+= fac*col[1];
202                 accol[2]+= fac*col[2];
203                 accol[3]+= fac*col[3];
204         }
205         col[0]= accol[0];
206         col[1]= accol[1];
207         col[2]= accol[2];
208         col[3]= accol[3];
209         
210         addalphaAddfacFloat(rb, col, har->add);
211         
212 }
213
214 static void halo_tile(RenderPart *pa, float *pass, unsigned int lay)
215 {
216         HaloRen *har = NULL;
217         rcti disprect= pa->disprect, testrect= pa->disprect;
218         float dist, xsq, ysq, xn, yn, *rb;
219         float col[4];
220         long *rd= NULL;
221         int a, *rz, zz, y;
222         short minx, maxx, miny, maxy, x;
223
224         /* we don't render halos in the cropped area, gives errors in flare counter */
225         if(pa->crop) {
226                 testrect.xmin+= pa->crop;
227                 testrect.xmax-= pa->crop;
228                 testrect.ymin+= pa->crop;
229                 testrect.ymax-= pa->crop;
230         }
231         
232         for(a=0; a<R.tothalo; a++) {
233                 if((a & 255)==0)
234                         har= R.bloha[a>>8];
235                 else har++;
236
237                 /* layer test, clip halo with y */
238                 if((har->lay & lay)==0);
239                 else if(testrect.ymin > har->maxy);
240                 else if(testrect.ymax < har->miny);
241                 else {
242                         
243                         minx= floor(har->xs-har->rad);
244                         maxx= ceil(har->xs+har->rad);
245                         
246                         if(testrect.xmin > maxx);
247                         else if(testrect.xmax < minx);
248                         else {
249                                 
250                                 minx= MAX2(minx, testrect.xmin);
251                                 maxx= MIN2(maxx, testrect.xmax);
252                         
253                                 miny= MAX2(har->miny, testrect.ymin);
254                                 maxy= MIN2(har->maxy, testrect.ymax);
255                         
256                                 for(y=miny; y<maxy; y++) {
257                                         int rectofs= (y-disprect.ymin)*pa->rectx + (minx - disprect.xmin);
258                                         rb= pass + 4*rectofs;
259                                         rz= pa->rectz + rectofs;
260                                         
261                                         if(pa->rectdaps)
262                                                 rd= pa->rectdaps + rectofs;
263                                         
264                                         yn= (y-har->ys)*R.ycor;
265                                         ysq= yn*yn;
266                                         
267                                         for(x=minx; x<maxx; x++, rb+=4, rz++) {
268                                                 xn= x- har->xs;
269                                                 xsq= xn*xn;
270                                                 dist= xsq+ysq;
271                                                 if(dist<har->radsq) {
272                                                         if(rd && *rd) {
273                                                                 halo_pixelstruct(har, rb, dist, xn, yn, (PixStr *)*rd);
274                                                         }
275                                                         else {
276                                                                 zz= calchalo_z(har, *rz);
277                                                                 if(zz> har->zs) {
278                                                                         shadeHaloFloat(har, col, zz, dist, xn, yn, har->flarec);
279                                                                         addalphaAddfacFloat(rb, col, har->add);
280                                                                 }
281                                                         }
282                                                 }
283                                                 if(rd) rd++;
284                                         }
285                                 }
286                         }
287                 }
288                 if(R.test_break() ) break; 
289         }
290 }
291
292 static void lamphalo_tile(RenderPart *pa, RenderLayer *rl)
293 {
294         ShadeInput shi;
295         float *pass= rl->rectf;
296         float fac;
297         long *rd= pa->rectdaps;
298         int x, y, *rz= pa->rectz;
299         
300         shade_input_initialize(&shi, pa, rl, 0);
301         
302         for(y=pa->disprect.ymin; y<pa->disprect.ymax; y++) {
303                 for(x=pa->disprect.xmin; x<pa->disprect.xmax; x++, rz++, pass+=4) {
304                         
305                         calc_view_vector(shi.view, x, y);
306                         
307                         if(rd && *rd) {
308                                 PixStr *ps= (PixStr *)*rd;
309                                 int samp, totsamp= 0;
310                                 
311                                 while(ps) {
312                                         if(R.r.mode & R_ORTHO)
313                                                 calc_renderco_ortho(shi.co, (float)x, (float)y, ps->z);
314                                         else
315                                                 calc_renderco_zbuf(shi.co, shi.view, ps->z);
316                                         
317                                         totsamp+= samp= count_mask(ps->mask);
318                                         fac= ((float)samp)/(float)R.osa;
319                                         renderspothalo(&shi, pass, fac);
320                                         ps= ps->next;
321                                 }
322                                 if(totsamp<R.osa) {
323                                         fac= ((float)R.osa-totsamp)/(float)R.osa;
324                                         shi.co[2]= 0.0f;
325                                         renderspothalo(&shi, pass, fac);
326                                 }
327                         }
328                         else {
329                                 if(R.r.mode & R_ORTHO)
330                                         calc_renderco_ortho(shi.co, (float)x, (float)y, *rz);
331                                 else
332                                         calc_renderco_zbuf(shi.co, shi.view, *rz);
333                                 
334                                 renderspothalo(&shi, pass, 1.0f);
335                         }
336                         
337                         if(rd) rd++;
338                 }
339                 if(y&1)
340                         if(R.test_break()) break; 
341         }
342 }                               
343
344
345 /* ********************* MAINLOOPS ******************** */
346
347 /* osa version */
348 static void add_filt_passes(RenderLayer *rl, int curmask, int rectx, int offset, ShadeInput *shi, ShadeResult *shr)
349 {
350         RenderPass *rpass;
351         
352         for(rpass= rl->passes.first; rpass; rpass= rpass->next) {
353                 float *fp, *col= NULL;
354                 int pixsize= 3;
355                 
356                 switch(rpass->passtype) {
357                         case SCE_PASS_RGBA:
358                                 col= shr->col;
359                                 pixsize= 4;
360                                 break;
361                         case SCE_PASS_DIFFUSE:
362                                 col= shr->diff;
363                                 break;
364                         case SCE_PASS_SPEC:
365                                 col= shr->spec;
366                                 break;
367                         case SCE_PASS_SHADOW:
368                                 col= shr->shad;
369                                 break;
370                         case SCE_PASS_AO:
371                                 col= shr->ao;
372                                 break;
373                         case SCE_PASS_REFLECT:
374                                 col= shr->refl;
375                                 break;
376                         case SCE_PASS_REFRACT:
377                                 col= shr->refr;
378                                 break;
379                         case SCE_PASS_RADIO:
380                                 col= shr->rad;
381                                 break;
382                         case SCE_PASS_NORMAL:
383                                 col= shr->nor;
384                                 break;
385                         case SCE_PASS_UV:
386                                 /* box filter only, gauss will screwup UV too much */
387                                 if(shi->totuv) {
388                                         float mult= (float)count_mask(curmask)/(float)R.osa;
389                                         fp= rpass->rect + 3*offset;
390                                         fp[0]+= mult*(0.5f + 0.5f*shi->uv[0].uv[0]);
391                                         fp[1]+= mult*(0.5f + 0.5f*shi->uv[0].uv[1]);
392                                         fp[2]+= mult;
393                                 }
394                                 break;
395                         case SCE_PASS_INDEXOB:
396                                 /* no filter */
397                                 if(shi->vlr) {
398                                         fp= rpass->rect + offset;
399                                         if(*fp==0.0f)
400                                                 *fp= (float)shi->vlr->ob->index;
401                                 }
402                                 break;
403                         case SCE_PASS_VECTOR:
404                         {
405                                 /* add minimum speed in pixel, no filter */
406                                 fp= rpass->rect + 4*offset;
407                                 if( (ABS(shr->winspeed[0]) + ABS(shr->winspeed[1]))< (ABS(fp[0]) + ABS(fp[1])) ) {
408                                         fp[0]= shr->winspeed[0];
409                                         fp[1]= shr->winspeed[1];
410                                 }
411                                 if( (ABS(shr->winspeed[2]) + ABS(shr->winspeed[3]))< (ABS(fp[2]) + ABS(fp[3])) ) {
412                                         fp[2]= shr->winspeed[2];
413                                         fp[3]= shr->winspeed[3];
414                                 }
415                         }
416                                 break;
417                 }
418                 if(col) {
419                         fp= rpass->rect + pixsize*offset;
420                         add_filt_fmask_pixsize(curmask, col, fp, rectx, pixsize);
421                 }
422         }
423 }
424
425 /* non-osa version */
426 static void add_passes(RenderLayer *rl, int offset, ShadeInput *shi, ShadeResult *shr)
427 {
428         RenderPass *rpass;
429         
430         for(rpass= rl->passes.first; rpass; rpass= rpass->next) {
431                 float *fp, *col= NULL, uvcol[3];
432                 int a, pixsize= 3;
433                 
434                 switch(rpass->passtype) {
435                         case SCE_PASS_RGBA:
436                                 col= shr->col;
437                                 pixsize= 4;
438                                 break;
439                         case SCE_PASS_DIFFUSE:
440                                 col= shr->diff;
441                                 break;
442                         case SCE_PASS_SPEC:
443                                 col= shr->spec;
444                                 break;
445                         case SCE_PASS_SHADOW:
446                                 col= shr->shad;
447                                 break;
448                         case SCE_PASS_AO:
449                                 col= shr->ao;
450                                 break;
451                         case SCE_PASS_REFLECT:
452                                 col= shr->refl;
453                                 break;
454                         case SCE_PASS_REFRACT:
455                                 col= shr->refr;
456                                 break;
457                         case SCE_PASS_RADIO:
458                                 col= shr->rad;
459                                 break;
460                         case SCE_PASS_NORMAL:
461                                 col= shr->nor;
462                                 break;
463                         case SCE_PASS_UV:
464                                 if(shi->totuv) {
465                                         uvcol[0]= 0.5f + 0.5f*shi->uv[0].uv[0];
466                                         uvcol[1]= 0.5f + 0.5f*shi->uv[0].uv[1];
467                                         uvcol[2]= 1.0f;
468                                         col= uvcol;
469                                 }
470                                 break;
471                         case SCE_PASS_VECTOR:
472                                 col= shr->winspeed;
473                                 pixsize= 4;
474                                 break;
475                         case SCE_PASS_INDEXOB:
476                                 if(shi->vlr) {
477                                         fp= rpass->rect + offset;
478                                         *fp= (float)shi->vlr->ob->index;
479                                 }
480                                 break;
481                 }
482                 if(col) {
483                         fp= rpass->rect + pixsize*offset;
484                         for(a=0; a<pixsize; a++)
485                                 fp[a]= col[a];
486                 }
487         }
488 }
489
490 /* only do sky, is default in the solid layer (shade_tile) btw */
491 static void sky_tile(RenderPart *pa, float *pass)
492 {
493         float col[4];
494         int x, y;
495         
496         if(R.r.alphamode!=R_ADDSKY)
497                 return;
498         
499         for(y=pa->disprect.ymin; y<pa->disprect.ymax; y++) {
500                 for(x=pa->disprect.xmin; x<pa->disprect.xmax; x++, pass+=4) {
501                         if(pass[3]<1.0f) {
502                                 if(pass[3]==0.0f)
503                                         shadeSkyPixel(pass, x, y);
504                                 else {
505                                         shadeSkyPixel(col, x, y);
506                                         addAlphaOverFloat(col, pass);
507                                         QUATCOPY(pass, col);
508                                 }
509                         }
510                 }
511                 
512                 if(y&1)
513                         if(R.test_break()) break; 
514         }
515 }
516
517 static void shadeDA_tile(RenderPart *pa, RenderLayer *rl)
518 {
519         RenderResult *rr= pa->result;
520         ShadeSample ssamp;
521         float *fcol, *rf, *rectf= rl->rectf;
522         long *rd, *rectdaps= pa->rectdaps;
523         int samp;
524         int x, y, seed, crop=0, offs=0, od, addpassflag;
525         
526         if(R.test_break()) return; 
527         
528         /* irregular shadowb buffer creation */
529         if(R.r.mode & R_SHADOW)
530                 ISB_create(pa, NULL);
531         
532         /* we set per pixel a fixed seed, for random AO and shadow samples */
533         seed= pa->rectx*pa->disprect.ymin;
534         
535         /* general shader info, passes */
536         shade_sample_initialize(&ssamp, pa, rl);
537         addpassflag= rl->passflag & ~(SCE_PASS_Z|SCE_PASS_COMBINED);
538                                 
539         /* filtered render, for now we assume only 1 filter size */
540         if(pa->crop) {
541                 crop= 1;
542                 rectf+= 4*(pa->rectx + 1);
543                 rectdaps+= pa->rectx + 1;
544                 offs= pa->rectx + 1;
545         }
546         
547         /* scanline updates have to be 2 lines behind */
548         rr->renrect.ymin= 0;
549         rr->renrect.ymax= -2*crop;
550         rr->renlay= rl;
551                                 
552         for(y=pa->disprect.ymin+crop; y<pa->disprect.ymax-crop; y++, rr->renrect.ymax++) {
553                 rf= rectf;
554                 rd= rectdaps;
555                 od= offs;
556                 
557                 for(x=pa->disprect.xmin+crop; x<pa->disprect.xmax-crop; x++, rd++, rf+=4, od++) {
558                         BLI_thread_srandom(pa->thread, seed++);
559                         
560                         if(*rd) {
561                                 if(shade_samples(&ssamp, (PixStr *)(*rd), x, y)) {
562                                         for(samp=0; samp<ssamp.tot; samp++) {
563                                                 
564                                                 fcol= ssamp.shr[samp].combined;
565                                                 add_filt_fmask(ssamp.shi[samp].mask, fcol, rf, pa->rectx);
566                                                 
567                                                 if(addpassflag)
568                                                         add_filt_passes(rl, ssamp.shi[samp].mask, pa->rectx, od, &ssamp.shi[samp], &ssamp.shr[samp]);
569                                         }
570                                 }
571                         }
572                 }
573                 
574                 rectf+= 4*pa->rectx;
575                 rectdaps+= pa->rectx;
576                 offs+= pa->rectx;
577                 
578                 if(y&1) if(R.test_break()) break; 
579         }
580         
581         /* disable scanline updating */
582         rr->renlay= NULL;
583         
584         if(R.r.mode & R_SHADOW)
585                 ISB_free(pa);
586 }
587
588 /* ************* pixel struct ******** */
589
590
591 static PixStrMain *addpsmain(ListBase *lb)
592 {
593         PixStrMain *psm;
594         
595         psm= (PixStrMain *)MEM_mallocN(sizeof(PixStrMain),"pixstrMain");
596         BLI_addtail(lb, psm);
597         
598         psm->ps= (PixStr *)MEM_mallocN(4096*sizeof(PixStr),"pixstr");
599         psm->counter= 0;
600         
601         return psm;
602 }
603
604 static void freeps(ListBase *lb)
605 {
606         PixStrMain *psm, *psmnext;
607         
608         for(psm= lb->first; psm; psm= psmnext) {
609                 psmnext= psm->next;
610                 if(psm->ps)
611                         MEM_freeN(psm->ps);
612                 MEM_freeN(psm);
613         }
614         lb->first= lb->last= NULL;
615 }
616
617 static void addps(ListBase *lb, long *rd, int facenr, int z, unsigned short mask)
618 {
619         PixStrMain *psm;
620         PixStr *ps, *last= NULL;
621         
622         if(*rd) {       
623                 ps= (PixStr *)(*rd);
624                 
625                 while(ps) {
626                         if( ps->facenr == facenr ) {
627                                 ps->mask |= mask;
628                                 return;
629                         }
630                         last= ps;
631                         ps= ps->next;
632                 }
633         }
634         
635         /* make new PS (pixel struct) */
636         psm= lb->last;
637         
638         if(psm->counter==4095)
639                 psm= addpsmain(lb);
640         
641         ps= psm->ps + psm->counter++;
642         
643         if(last) last->next= ps;
644         else *rd= (long)ps;
645         
646         ps->next= NULL;
647         ps->facenr= facenr;
648         ps->z= z;
649         ps->mask = mask;
650         ps->shadfac= 0;
651 }
652
653 static void make_pixelstructs(RenderPart *pa, ListBase *lb)
654 {
655         long *rd= pa->rectdaps;
656         int *rp= pa->rectp;
657         int *rz= pa->rectz;
658         int x, y;
659         int mask= 1<<pa->sample;
660         
661         for(y=0; y<pa->recty; y++) {
662                 for(x=0; x<pa->rectx; x++, rd++, rp++) {
663                         if(*rp) {
664                                 addps(lb, rd, *rp, *(rz+x), mask);
665                         }
666                 }
667                 rz+= pa->rectx;
668         }
669 }
670
671 static void edge_enhance_add(RenderPart *pa, float *rectf, float *arect)
672 {
673         float addcol[4];
674         int pix;
675         
676         if(arect==NULL)
677                 return;
678         
679         for(pix= pa->rectx*pa->recty; pix>0; pix--, arect++, rectf+=4) {
680                 if(*arect != 0.0f) {
681                         addcol[0]= *arect * R.r.edgeR;
682                         addcol[1]= *arect * R.r.edgeG;
683                         addcol[2]= *arect * R.r.edgeB;
684                         addcol[3]= *arect;
685                         addAlphaOverFloat(rectf, addcol);
686                 }
687         }
688 }
689
690
691 static void convert_to_key_alpha(RenderPart *pa, float *rectf)
692 {
693         int y;
694         
695         for(y= pa->rectx*pa->recty; y>0; y--, rectf+=4) {
696                 if(rectf[3] >= 1.0f);
697                 else if(rectf[3] > 0.0f) {
698                         rectf[0] /= rectf[3];
699                         rectf[1] /= rectf[3];
700                         rectf[2] /= rectf[3];
701                 }
702         }
703 }
704
705 /* adds only alpha values */
706 static void edge_enhance_tile(RenderPart *pa, float *rectf)     
707 {
708         /* use zbuffer to define edges, add it to the image */
709         int y, x, col, *rz, *rz1, *rz2, *rz3;
710         int zval1, zval2, zval3;
711         float *rf;
712         
713         /* shift values in zbuffer 4 to the right (anti overflows), for filter we need multiplying with 12 max */
714         rz= pa->rectz;
715         if(rz==NULL) return;
716         
717         for(y=0; y<pa->recty; y++)
718                 for(x=0; x<pa->rectx; x++, rz++) (*rz)>>= 4;
719         
720         rz1= pa->rectz;
721         rz2= rz1+pa->rectx;
722         rz3= rz2+pa->rectx;
723         
724         rf= rectf+pa->rectx+1;
725         
726         for(y=0; y<pa->recty-2; y++) {
727                 for(x=0; x<pa->rectx-2; x++, rz1++, rz2++, rz3++, rf++) {
728                         
729                         /* prevent overflow with sky z values */
730                         zval1=   rz1[0] + 2*rz1[1] +   rz1[2];
731                         zval2=  2*rz2[0]           + 2*rz2[2];
732                         zval3=   rz3[0] + 2*rz3[1] +   rz3[2];
733                         
734                         col= ( 4*rz2[1] - (zval1 + zval2 + zval3)/3 );
735                         if(col<0) col= -col;
736                         
737                         col >>= 5;
738                         if(col > (1<<16)) col= (1<<16);
739                         else col= (R.r.edgeint*col)>>8;
740                         
741                         if(col>0) {
742                                 float fcol;
743                                 
744                                 if(col>255) fcol= 1.0f;
745                                 else fcol= (float)col/255.0f;
746                                 
747                                 if(R.osa)
748                                         *rf+= fcol/(float)R.osa;
749                                 else
750                                         *rf= fcol;
751                         }
752                 }
753                 rz1+= 2;
754                 rz2+= 2;
755                 rz3+= 2;
756                 rf+= 2;
757         }
758         
759         /* shift back zbuf values, we might need it still */
760         rz= pa->rectz;
761         for(y=0; y<pa->recty; y++)
762                 for(x=0; x<pa->rectx; x++, rz++) (*rz)<<= 4;
763         
764 }
765
766 static void reset_sky_speed(RenderPart *pa, RenderLayer *rl)
767 {
768         /* for all pixels with max speed, set to zero */
769         float *fp;
770         int a;
771         
772         fp= RE_RenderLayerGetPass(rl, SCE_PASS_VECTOR);
773         if(fp==NULL) return;
774         
775         for(a= 4*pa->rectx*pa->recty - 1; a>=0; a--)
776                 if(fp[a] == PASS_VECTOR_MAX) fp[a]= 0.0f;
777 }
778
779
780 static unsigned short *make_solid_mask(RenderPart *pa)
781
782         long *rd= pa->rectdaps;
783         unsigned short *solidmask, *sp;
784         int x;
785         
786         if(rd==NULL) return NULL;
787         
788         sp=solidmask= MEM_mallocN(sizeof(short)*pa->rectx*pa->recty, "solidmask");
789         
790         for(x=pa->rectx*pa->recty; x>0; x--, rd++, sp++) {
791                 if(*rd) {
792                         PixStr *ps= (PixStr *)*rd;
793                         
794                         *sp= ps->mask;
795                         for(ps= ps->next; ps; ps= ps->next)
796                                 *sp |= ps->mask;
797                 }
798                 else
799                         *sp= 0;
800         }
801                         
802         return solidmask;
803 }
804
805 static void addAlphaOverFloatMask(float *dest, float *source, unsigned short dmask, unsigned short smask)
806 {
807         unsigned short shared= dmask & smask;
808         float mul= 1.0 - source[3];
809         
810         if(shared) {    /* overlapping masks */
811                 
812                 /* masks differ, we make a mixture of 'add' and 'over' */
813                 if(shared!=dmask) {
814                         float shared_bits= (float)count_mask(shared);           /* alpha over */
815                         float tot_bits= (float)count_mask(smask|dmask);         /* alpha add */
816                         
817                         float add= (tot_bits - shared_bits)/tot_bits;           /* add level */
818                         mul= add + (1.0f-add)*mul;
819                 }
820         }
821         else if(dmask && smask) {
822                 /* works for premul only, of course */
823                 dest[0]+= source[0];
824                 dest[1]+= source[1];
825                 dest[2]+= source[2];
826                 dest[3]+= source[3];
827                 
828                 return;
829         }
830
831         dest[0]= (mul*dest[0]) + source[0];
832         dest[1]= (mul*dest[1]) + source[1];
833         dest[2]= (mul*dest[2]) + source[2];
834         dest[3]= (mul*dest[3]) + source[3];
835 }
836
837
838 /* main call for shading Delta Accum, for OSA */
839 /* supposed to be fully threadable! */
840 void zbufshadeDA_tile(RenderPart *pa)
841 {
842         RenderResult *rr= pa->result;
843         RenderLayer *rl;
844         ListBase psmlist= {NULL, NULL};
845         float *edgerect= NULL;
846         
847         set_part_zbuf_clipflag(pa);
848         
849         /* allocate the necessary buffers */
850                                 /* zbuffer inits these rects */
851         pa->rectp= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectp");
852         pa->rectz= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectz");
853         
854         for(rl= rr->layers.first; rl; rl= rl->next) {
855
856                 /* initialize pixelstructs and edge buffer */
857                 addpsmain(&psmlist);
858                 pa->rectdaps= MEM_callocN(sizeof(long)*pa->rectx*pa->recty+4, "zbufDArectd");
859                 
860                 if(rl->layflag & SCE_LAY_EDGE) 
861                         if(R.r.mode & R_EDGE) 
862                                 edgerect= MEM_callocN(sizeof(float)*pa->rectx*pa->recty, "rectedge");
863                 
864                 /* always fill visibility */
865                 for(pa->sample=0; pa->sample<R.osa; pa->sample++) {
866                         zbuffer_solid(pa, rl->lay, rl->layflag);
867                         make_pixelstructs(pa, &psmlist);
868                         
869                         if(rl->layflag & SCE_LAY_EDGE) 
870                                 if(R.r.mode & R_EDGE) 
871                                         edge_enhance_tile(pa, edgerect);
872                         
873                         if(R.test_break()) break; 
874                 }
875                 
876                 /* shades solid */
877                 if(rl->layflag & SCE_LAY_SOLID) 
878                         shadeDA_tile(pa, rl);
879                 
880                 /* lamphalo after solid, before ztra, looks nicest because ztra does own halo */
881                 if(R.flag & R_LAMPHALO)
882                         if(rl->layflag & SCE_LAY_HALO)
883                                 lamphalo_tile(pa, rl);
884                 
885                 /* halo before ztra, because ztra fills in zbuffer now */
886                 if(R.flag & R_HALO)
887                         if(rl->layflag & SCE_LAY_HALO)
888                                 halo_tile(pa, rl->rectf, rl->lay);
889                 
890                 /* transp layer */
891                 if(R.flag & R_ZTRA) {
892                         if(rl->layflag & SCE_LAY_ZTRA) {
893                                 unsigned short *ztramask, *solidmask= NULL; /* 16 bits, MAX_OSA */
894                                 
895                                 /* allocate, but not free here, for asynchronous display of this rect in main thread */
896                                 rl->acolrect= MEM_callocN(4*sizeof(float)*pa->rectx*pa->recty, "alpha layer");
897                                 
898                                 /* swap for live updates, and it is used in zbuf.c!!! */
899                                 SWAP(float *, rl->acolrect, rl->rectf);
900                                 ztramask= zbuffer_transp_shade(pa, rl, rl->rectf);
901                                 SWAP(float *, rl->acolrect, rl->rectf);
902                                 
903                                 /* zbuffer transp only returns ztramask if there's solid rendered */
904                                 if(ztramask)
905                                         solidmask= make_solid_mask(pa);
906                                 
907                                 if(ztramask && solidmask) {
908                                         unsigned short *sps= solidmask, *spz= ztramask;
909                                         unsigned short fullmask= (1<<R.osa)-1;
910                                         float *fcol= rl->rectf; float *acol= rl->acolrect;
911                                         int x;
912                                         
913                                         for(x=pa->rectx*pa->recty; x>0; x--, acol+=4, fcol+=4, sps++, spz++) {
914                                                 if(*sps == fullmask)
915                                                         addAlphaOverFloat(fcol, acol);
916                                                 else
917                                                         addAlphaOverFloatMask(fcol, acol, *sps, *spz);
918                                         }
919                                 }
920                                 else {
921                                         float *fcol= rl->rectf; float *acol= rl->acolrect;
922                                         int x;
923                                         for(x=pa->rectx*pa->recty; x>0; x--, acol+=4, fcol+=4) {
924                                                 addAlphaOverFloat(fcol, acol);
925                                         }
926                                 }
927                                 if(solidmask) MEM_freeN(solidmask);
928                                 if(ztramask) MEM_freeN(ztramask);
929                         }
930                 }
931                 /* sky before edge */
932                 if(rl->layflag & SCE_LAY_SKY)
933                         sky_tile(pa, rl->rectf);
934
935                 /* extra layers */
936                 if(rl->layflag & SCE_LAY_EDGE) 
937                         if(R.r.mode & R_EDGE) 
938                                 edge_enhance_add(pa, rl->rectf, edgerect);
939                 
940                 if(rl->passflag & SCE_PASS_Z)
941                         convert_zbuf_to_distbuf(pa, rl);
942                 
943                 if(rl->passflag & SCE_PASS_VECTOR)
944                         reset_sky_speed(pa, rl);
945                 
946                 /* de-premul alpha */
947                 if(R.r.alphamode & R_ALPHAKEY)
948                         convert_to_key_alpha(pa, rl->rectf);
949                 
950                 /* free stuff within loop! */
951                 MEM_freeN(pa->rectdaps); pa->rectdaps= NULL;
952                 freeps(&psmlist);
953                 
954                 if(edgerect) MEM_freeN(edgerect);
955                 edgerect= NULL;
956         }
957         
958         /* free all */
959         MEM_freeN(pa->rectp); pa->rectp= NULL;
960         MEM_freeN(pa->rectz); pa->rectz= NULL;
961         MEM_freeN(pa->clipflag); pa->clipflag= NULL;
962         
963         /* display active layer */
964         rr->renrect.ymin=rr->renrect.ymax= 0;
965         rr->renlay= render_get_active_layer(&R, rr);
966 }
967
968
969 /* ------------------------------------------------------------------------ */
970
971 /* non OSA case, full tile render */
972 /* supposed to be fully threadable! */
973 void zbufshade_tile(RenderPart *pa)
974 {
975         ShadeSample ssamp;
976         RenderResult *rr= pa->result;
977         RenderLayer *rl;
978         PixStr ps;
979         float *edgerect= NULL;
980         int addpassflag;
981         
982         /* fake pixel struct, to comply to osa render */
983         ps.next= NULL;
984         ps.mask= 0xFFFF;
985         
986         set_part_zbuf_clipflag(pa);
987         
988         /* zbuffer code clears/inits rects */
989         pa->rectp= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectp");
990         pa->rectz= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectz");
991
992         for(rl= rr->layers.first; rl; rl= rl->next) {
993                 
994                 /* general shader info, passes */
995                 shade_sample_initialize(&ssamp, pa, rl);
996                 addpassflag= rl->passflag & ~(SCE_PASS_Z|SCE_PASS_COMBINED);
997                 
998                 zbuffer_solid(pa, rl->lay, rl->layflag);
999                 
1000                 if(!R.test_break()) {   /* NOTE: this if() is not consistant */
1001                         
1002                         /* edges only for solid part, ztransp doesn't support it yet anti-aliased */
1003                         if(rl->layflag & SCE_LAY_EDGE) {
1004                                 if(R.r.mode & R_EDGE) {
1005                                         edgerect= MEM_callocN(sizeof(float)*pa->rectx*pa->recty, "rectedge");
1006                                         edge_enhance_tile(pa, edgerect);
1007                                 }
1008                         }
1009                         
1010                         /* initialize scanline updates for main thread */
1011                         rr->renrect.ymin= 0;
1012                         rr->renlay= rl;
1013                         
1014                         if(rl->layflag & SCE_LAY_SOLID) {
1015                                 float *fcol= rl->rectf;
1016                                 int x, y, *rp= pa->rectp, *rz= pa->rectz, offs=0, seed;
1017                                 
1018                                 /* we set per pixel a fixed seed, for random AO and shadow samples */
1019                                 seed= pa->rectx*pa->disprect.ymin;
1020                                 
1021                                 /* irregular shadowb buffer creation */
1022                                 if(R.r.mode & R_SHADOW)
1023                                         ISB_create(pa, NULL);
1024                                 
1025                                 for(y=pa->disprect.ymin; y<pa->disprect.ymax; y++, rr->renrect.ymax++) {
1026                                         for(x=pa->disprect.xmin; x<pa->disprect.xmax; x++, rz++, rp++, fcol+=4, offs++) {
1027                                                 /* per pixel fixed seed */
1028                                                 BLI_thread_srandom(pa->thread, seed++);
1029                                                 
1030                                                 if(*rp) {
1031                                                         ps.facenr= *rp;
1032                                                         ps.z= *rz;
1033                                                         if(shade_samples(&ssamp, &ps, x, y)) {
1034                                                                 QUATCOPY(fcol, ssamp.shr[0].combined);
1035                                                                 
1036                                                                 /* passes */
1037                                                                 if(addpassflag)
1038                                                                         add_passes(rl, offs, ssamp.shi, ssamp.shr);
1039                                                         }
1040                                                 }
1041                                         }
1042                                         if(y&1)
1043                                                 if(R.test_break()) break; 
1044                                 }
1045                                 
1046                                 if(R.r.mode & R_SHADOW)
1047                                         ISB_free(pa);
1048                         }
1049                         
1050                         /* disable scanline updating */
1051                         rr->renlay= NULL;
1052                 }
1053                 
1054                 /* lamphalo after solid, before ztra, looks nicest because ztra does own halo */
1055                 if(R.flag & R_LAMPHALO)
1056                         if(rl->layflag & SCE_LAY_HALO)
1057                                 lamphalo_tile(pa, rl);
1058                 
1059                 /* halo before ztra, because ztra fills in zbuffer now */
1060                 if(R.flag & R_HALO)
1061                         if(rl->layflag & SCE_LAY_HALO)
1062                                 halo_tile(pa, rl->rectf, rl->lay);
1063                 
1064                 if(R.flag & R_ZTRA) {
1065                         if(rl->layflag & SCE_LAY_ZTRA) {
1066                                 float *fcol, *acol;
1067                                 int x;
1068                                 
1069                                 /* allocate, but not free here, for asynchronous display of this rect in main thread */
1070                                 rl->acolrect= MEM_callocN(4*sizeof(float)*pa->rectx*pa->recty, "alpha layer");
1071                                 
1072                                 /* swap for live updates */
1073                                 SWAP(float *, rl->acolrect, rl->rectf);
1074                                 zbuffer_transp_shade(pa, rl, rl->rectf);
1075                                 SWAP(float *, rl->acolrect, rl->rectf);
1076                                 
1077                                 fcol= rl->rectf; acol= rl->acolrect;
1078                                 for(x=pa->rectx*pa->recty; x>0; x--, acol+=4, fcol+=4) {
1079                                         addAlphaOverFloat(fcol, acol);
1080                                 }
1081                         }
1082                 }
1083                 
1084                 /* sky before edge */
1085                 if(rl->layflag & SCE_LAY_SKY)
1086                         sky_tile(pa, rl->rectf);
1087                 
1088                 if(!R.test_break()) {
1089                         if(rl->layflag & SCE_LAY_EDGE) 
1090                                 if(R.r.mode & R_EDGE)
1091                                         edge_enhance_add(pa, rl->rectf, edgerect);
1092                 }
1093                 
1094                 if(rl->passflag & SCE_PASS_Z)
1095                         convert_zbuf_to_distbuf(pa, rl);
1096                 
1097                 if(rl->passflag & SCE_PASS_VECTOR)
1098                         reset_sky_speed(pa, rl);
1099                 
1100                 /* de-premul alpha */
1101                 if(R.r.alphamode & R_ALPHAKEY)
1102                         convert_to_key_alpha(pa, rl->rectf);
1103                 
1104                 if(edgerect) MEM_freeN(edgerect);
1105                 edgerect= NULL;
1106         }
1107
1108         /* display active layer */
1109         rr->renrect.ymin=rr->renrect.ymax= 0;
1110         rr->renlay= render_get_active_layer(&R, rr);
1111         
1112         MEM_freeN(pa->rectp); pa->rectp= NULL;
1113         MEM_freeN(pa->rectz); pa->rectz= NULL;
1114         MEM_freeN(pa->clipflag); pa->clipflag= NULL;
1115 }
1116
1117 /* SSS preprocess tile render, fully threadable */
1118 typedef struct ZBufSSSHandle {
1119         RenderPart *pa;
1120         ListBase psmlist;
1121         int totps;
1122 } ZBufSSSHandle;
1123
1124 static void addps_sss(void *cb_handle, int facenr, int x, int y, int z)
1125 {
1126         ZBufSSSHandle *handle = cb_handle;
1127         RenderPart *pa= handle->pa;
1128
1129         /* extra border for filter gives double samples on part edges,
1130            don't use those */
1131         if(x<pa->crop || x>=pa->rectx-pa->crop)
1132                 return;
1133         if(y<pa->crop || y>=pa->recty-pa->crop)
1134                 return;
1135         
1136         if(pa->rectall) {
1137                 long *rs= pa->rectall + pa->rectx*y + x;
1138
1139                 addps(&handle->psmlist, rs, facenr, z, 0);
1140                 handle->totps++;
1141         }
1142         if(pa->rectz) {
1143                 int *rz= pa->rectz + pa->rectx*y + x;
1144                 int *rp= pa->rectp + pa->rectx*y + x;
1145
1146                 if(z < *rz) {
1147                         if(*rp == 0)
1148                                 handle->totps++;
1149                         *rz= z;
1150                         *rp= facenr;
1151                 }
1152         }
1153         if(pa->rectbackz) {
1154                 int *rz= pa->rectbackz + pa->rectx*y + x;
1155                 int *rp= pa->rectbackp + pa->rectx*y + x;
1156
1157                 if(z >= *rz) {
1158                         if(*rp == 0)
1159                                 handle->totps++;
1160                         *rz= z;
1161                         *rp= facenr;
1162                 }
1163         }
1164 }
1165
1166 static void shade_sample_sss(ShadeSample *ssamp, Material *mat, VlakRen *vlr, int quad, float x, float y, float z, float *co, float *color, float *area)
1167 {
1168         ShadeInput *shi= ssamp->shi;
1169         ShadeResult shr;
1170         float texfac, orthoarea, nor[3];
1171
1172         /* normal flipping must be disabled to make back scattering work, so that
1173            backside faces actually face any lighting from the back */
1174         shi->puno= 0;
1175         
1176         /* cache for shadow */
1177         shi->samplenr++;
1178         
1179         if(quad) 
1180                 shade_input_set_triangle_i(shi, vlr, 0, 2, 3);
1181         else
1182                 shade_input_set_triangle_i(shi, vlr, 0, 1, 2);
1183
1184         /* we don't want flipped normals, they screw up back scattering */
1185         if(vlr->noflag & R_FLIPPED_NO)
1186                 VecMulf(shi->facenor, -1.0f);
1187
1188         /* center pixel */
1189         x += 0.5f;
1190         y += 0.5f;
1191
1192         /* we estimate the area here using shi->dxco and shi->dyco. we need to
1193            enabled shi->osatex these are filled. we compute two areas, one with
1194            the normal pointed at the camera and one with the original normal, and
1195            then clamp to avoid a too large contribution from a single pixel */
1196         shi->osatex= 1;
1197
1198         VECCOPY(nor, shi->facenor);
1199         calc_view_vector(shi->facenor, x, y);
1200         Normalize(shi->facenor);
1201         shade_input_set_viewco(shi, x, y, z);
1202         orthoarea= VecLength(shi->dxco)*VecLength(shi->dyco);
1203
1204         VECCOPY(shi->facenor, nor);
1205         shade_input_set_viewco(shi, x, y, z);
1206         *area= VecLength(shi->dxco)*VecLength(shi->dyco);
1207         *area= MIN2(*area, 2.0f*orthoarea);
1208
1209         shi->osatex= 0;
1210
1211         shade_input_set_uv(shi);
1212         shade_input_set_normals(shi);
1213
1214         /* not a pretty solution, but fixes common cases */
1215         if(vlr->ob && vlr->ob->transflag & OB_NEG_SCALE) {
1216                 VecMulf(shi->vn, -1.0f);
1217                 VecMulf(shi->vno, -1.0f);
1218         }
1219
1220         /* if nodetree, use the material that we are currently preprocessing
1221            instead of the node material */
1222         if(shi->mat->nodetree && shi->mat->use_nodes)
1223                 shi->mat= mat;
1224
1225         /* init material vars */
1226         // note, keep this synced with render_types.h
1227         memcpy(&shi->r, &shi->mat->r, 23*sizeof(float));
1228         shi->har= shi->mat->har;
1229         
1230         /* render */
1231         shade_input_set_shade_texco(shi);
1232         
1233         shade_samples_do_AO(ssamp);
1234         shade_material_loop(shi, &shr);
1235         
1236         VECCOPY(co, shi->co);
1237         VECCOPY(color, shr.combined);
1238
1239         /* texture blending */
1240         texfac= shi->mat->sss_texfac;
1241
1242         if(texfac == 0.0f) {
1243                 if(shr.col[0]!=0.0f) color[0] /= shr.col[0];
1244                 if(shr.col[1]!=0.0f) color[1] /= shr.col[1];
1245                 if(shr.col[2]!=0.0f) color[2] /= shr.col[2];
1246         }
1247         else if(texfac != 1.0f) {
1248                 if(shr.col[0]!=0.0f) color[0] *= pow(shr.col[0], texfac)/shr.col[0];
1249                 if(shr.col[1]!=0.0f) color[1] *= pow(shr.col[1], texfac)/shr.col[1];
1250                 if(shr.col[2]!=0.0f) color[2] *= pow(shr.col[2], texfac)/shr.col[2];
1251         }
1252 }
1253
1254 static void zbufshade_sss_free(RenderPart *pa)
1255 {
1256         MEM_freeN(pa->clipflag); pa->clipflag= NULL;
1257 #if 0
1258         MEM_freeN(pa->rectall); pa->rectall= NULL;
1259         freeps(&handle.psmlist);
1260 #else
1261         MEM_freeN(pa->rectz); pa->rectz= NULL;
1262         MEM_freeN(pa->rectp); pa->rectp= NULL;
1263         MEM_freeN(pa->rectbackz); pa->rectbackz= NULL;
1264         MEM_freeN(pa->rectbackp); pa->rectbackp= NULL;
1265 #endif
1266 }
1267
1268 void zbufshade_sss_tile(RenderPart *pa)
1269 {
1270         Render *re= &R;
1271         ShadeSample ssamp;
1272         ZBufSSSHandle handle;
1273         RenderResult *rr= pa->result;
1274         RenderLayer *rl= rr->layers.first;
1275         VlakRen *vlr;
1276         Material *mat= re->sss_mat;
1277         float (*co)[3], (*color)[3], *area, *fcol= rl->rectf;
1278         int x, y, seed, quad, totpoint, display = !(re->r.scemode & R_PREVIEWBUTS);
1279         int *rz, *rp, *rbz, *rbp;
1280 #if 0
1281         PixStr *ps;
1282         long *rs;
1283         int z;
1284 #endif
1285
1286         set_part_zbuf_clipflag(pa);
1287
1288         /* setup pixelstr list and buffer for zbuffering */
1289         handle.pa= pa;
1290         handle.totps= 0;
1291
1292 #if 0
1293         handle.psmlist.first= handle.psmlist.last= NULL;
1294         addpsmain(&handle.psmlist);
1295
1296         pa->rectall= MEM_callocN(sizeof(long)*pa->rectx*pa->recty+4, "rectall");
1297 #else
1298         pa->rectp= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectp");
1299         pa->rectz= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectz");
1300         pa->rectbackp= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectbackp");
1301         pa->rectbackz= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectbackz");
1302 #endif
1303
1304         /* create the pixelstrs to be used later */
1305         zbuffer_sss(pa, rl->lay, &handle, addps_sss);
1306
1307         if(handle.totps==0) {
1308                 zbufshade_sss_free(pa);
1309                 return;
1310         }
1311
1312         co= MEM_mallocN(sizeof(float)*3*handle.totps, "SSSCo");
1313         color= MEM_mallocN(sizeof(float)*3*handle.totps, "SSSColor");
1314         area= MEM_mallocN(sizeof(float)*handle.totps, "SSSArea");
1315
1316 #if 0
1317         /* create ISB (does not work currently!) */
1318         if(re->r.mode & R_SHADOW)
1319                 ISB_create(pa, NULL);
1320 #endif
1321
1322         /* setup shade sample with correct passes */
1323         memset(&ssamp, 0, sizeof(ssamp));
1324         shade_sample_initialize(&ssamp, pa, rl);
1325         ssamp.shi[0].passflag= SCE_PASS_DIFFUSE|SCE_PASS_AO|SCE_PASS_RADIO;
1326         ssamp.shi[0].passflag |= SCE_PASS_RGBA;
1327         ssamp.shi[0].combinedflag= ~(SCE_PASS_SPEC);
1328         ssamp.tot= 1;
1329
1330         if(display) {
1331                 /* initialize scanline updates for main thread */
1332                 rr->renrect.ymin= 0;
1333                 rr->renlay= rl;
1334         }
1335         
1336         seed= pa->rectx*pa->disprect.ymin;
1337 #if 0
1338         rs= pa->rectall;
1339 #else
1340         rz= pa->rectz;
1341         rp= pa->rectp;
1342         rbz= pa->rectbackz;
1343         rbp= pa->rectbackp;
1344 #endif
1345         totpoint= 0;
1346
1347         for(y=pa->disprect.ymin; y<pa->disprect.ymax; y++, rr->renrect.ymax++) {
1348                 for(x=pa->disprect.xmin; x<pa->disprect.xmax; x++, fcol+=4) {
1349                         /* per pixel fixed seed */
1350                         BLI_thread_srandom(pa->thread, seed++);
1351                         
1352 #if 0
1353                         if(rs) {
1354                                 /* for each sample in this pixel, shade it */
1355                                 for(ps=(PixStr*)*rs; ps; ps=ps->next) {
1356                                         vlr= RE_findOrAddVlak(re, (ps->facenr-1) & RE_QUAD_MASK);
1357                                         quad= (ps->facenr & RE_QUAD_OFFS);
1358                                         z= ps->z;
1359
1360                                         shade_sample_sss(&ssamp, mat, vlr, quad, x, y, z,
1361                                                 co[totpoint], color[totpoint], &area[totpoint]);
1362
1363                                         totpoint++;
1364
1365                                         VECADD(fcol, fcol, color);
1366                                         fcol[3]= 1.0f;
1367                                 }
1368
1369                                 rs++;
1370                         }
1371 #else
1372                         if(rp) {
1373                                 if(*rp != 0) {
1374                                         /* shade front */
1375                                         vlr= RE_findOrAddVlak(re, (*rp-1) & RE_QUAD_MASK);
1376                                         quad= ((*rp) & RE_QUAD_OFFS);
1377
1378                                         shade_sample_sss(&ssamp, mat, vlr, quad, x, y, *rz,
1379                                                 co[totpoint], color[totpoint], &area[totpoint]);
1380                                         
1381                                         VECADD(fcol, fcol, color[totpoint]);
1382                                         fcol[3]= 1.0f;
1383                                         totpoint++;
1384                                 }
1385
1386                                 rp++; rz++;
1387                         }
1388
1389                         if(rbp) {
1390                                 if(*rbp != 0 && *rbp != *(rp-1)) {
1391                                         /* shade back */
1392                                         vlr= RE_findOrAddVlak(re, (*rbp-1) & RE_QUAD_MASK);
1393                                         quad= ((*rbp) & RE_QUAD_OFFS);
1394
1395                                         shade_sample_sss(&ssamp, mat, vlr, quad, x, y, *rbz,
1396                                                 co[totpoint], color[totpoint], &area[totpoint]);
1397                                         
1398                                         /* to indicate this is a back sample */
1399                                         area[totpoint]= -area[totpoint];
1400
1401                                         VECADD(fcol, fcol, color[totpoint]);
1402                                         fcol[3]= 1.0f;
1403                                         totpoint++;
1404                                 }
1405
1406                                 rbz++; rbp++;
1407                         }
1408 #endif
1409                 }
1410
1411                 if(y&1)
1412                         if(re->test_break()) break; 
1413         }
1414
1415         /* note: after adding we do not free these arrays, sss keeps them */
1416         if(totpoint > 0) {
1417                 sss_add_points(re, co, color, area, totpoint);
1418         }
1419         else {
1420                 MEM_freeN(co);
1421                 MEM_freeN(color);
1422                 MEM_freeN(area);
1423         }
1424         
1425 #if 0
1426         if(re->r.mode & R_SHADOW)
1427                 ISB_free(pa);
1428 #endif
1429                 
1430         if(display) {
1431                 /* display active layer */
1432                 rr->renrect.ymin=rr->renrect.ymax= 0;
1433                 rr->renlay= render_get_active_layer(&R, rr);
1434         }
1435         
1436         zbufshade_sss_free(pa);
1437 }
1438
1439 /* ------------------------------------------------------------------------ */
1440
1441 static void renderhalo_post(RenderResult *rr, float *rectf, HaloRen *har)       /* postprocess version */
1442 {
1443         float dist, xsq, ysq, xn, yn, colf[4], *rectft, *rtf;
1444         float haloxs, haloys;
1445         int minx, maxx, miny, maxy, x, y;
1446
1447         /* calculate the disprect mapped coordinate for halo. note: rectx is disprect corrected */
1448         haloxs= har->xs - R.disprect.xmin;
1449         haloys= har->ys - R.disprect.ymin;
1450         
1451         har->miny= miny= haloys - har->rad/R.ycor;
1452         har->maxy= maxy= haloys + har->rad/R.ycor;
1453         
1454         if(maxy<0);
1455         else if(rr->recty<miny);
1456         else {
1457                 minx= floor(haloxs-har->rad);
1458                 maxx= ceil(haloxs+har->rad);
1459                         
1460                 if(maxx<0);
1461                 else if(rr->rectx<minx);
1462                 else {
1463                 
1464                         if(minx<0) minx= 0;
1465                         if(maxx>=rr->rectx) maxx= rr->rectx-1;
1466                         if(miny<0) miny= 0;
1467                         if(maxy>rr->recty) maxy= rr->recty;
1468         
1469                         rectft= rectf+ 4*rr->rectx*miny;
1470
1471                         for(y=miny; y<maxy; y++) {
1472         
1473                                 rtf= rectft+4*minx;
1474                                 
1475                                 yn= (y - haloys)*R.ycor;
1476                                 ysq= yn*yn;
1477                                 
1478                                 for(x=minx; x<=maxx; x++) {
1479                                         xn= x - haloxs;
1480                                         xsq= xn*xn;
1481                                         dist= xsq+ysq;
1482                                         if(dist<har->radsq) {
1483                                                 
1484                                                 shadeHaloFloat(har, colf, 0x7FFFFF, dist, xn, yn, har->flarec);
1485                                                 addalphaAddfacFloat(rtf, colf, har->add);
1486                                         }
1487                                         rtf+=4;
1488                                 }
1489         
1490                                 rectft+= 4*rr->rectx;
1491                                 
1492                                 if(R.test_break()) break; 
1493                         }
1494                 }
1495         }
1496
1497 /* ------------------------------------------------------------------------ */
1498
1499 static void renderflare(RenderResult *rr, float *rectf, HaloRen *har)
1500 {
1501         extern float hashvectf[];
1502         HaloRen fla;
1503         Material *ma;
1504         float *rc, rad, alfa, visifac, vec[3];
1505         int b, type;
1506         
1507         fla= *har;
1508         fla.linec= fla.ringc= fla.flarec= 0;
1509         
1510         rad= har->rad;
1511         alfa= har->alfa;
1512         
1513         visifac= R.ycor*(har->pixels);
1514         /* all radials added / r^3  == 1.0f! */
1515         visifac /= (har->rad*har->rad*har->rad);
1516         visifac*= visifac;
1517
1518         ma= har->mat;
1519         
1520         /* first halo: just do */
1521         
1522         har->rad= rad*ma->flaresize*visifac;
1523         har->radsq= har->rad*har->rad;
1524         har->zs= fla.zs= 0;
1525         
1526         har->alfa= alfa*visifac;
1527
1528         renderhalo_post(rr, rectf, har);
1529         
1530         /* next halo's: the flares */
1531         rc= hashvectf + ma->seed2;
1532         
1533         for(b=1; b<har->flarec; b++) {
1534                 
1535                 fla.r= fabs(rc[0]);
1536                 fla.g= fabs(rc[1]);
1537                 fla.b= fabs(rc[2]);
1538                 fla.alfa= ma->flareboost*fabs(alfa*visifac*rc[3]);
1539                 fla.hard= 20.0f + fabs(70*rc[7]);
1540                 fla.tex= 0;
1541                 
1542                 type= (int)(fabs(3.9*rc[6]));
1543
1544                 fla.rad= ma->subsize*sqrt(fabs(2.0f*har->rad*rc[4]));
1545                 
1546                 if(type==3) {
1547                         fla.rad*= 3.0f;
1548                         fla.rad+= R.rectx/10;
1549                 }
1550                 
1551                 fla.radsq= fla.rad*fla.rad;
1552                 
1553                 vec[0]= 1.4*rc[5]*(har->xs-R.winx/2);
1554                 vec[1]= 1.4*rc[5]*(har->ys-R.winy/2);
1555                 vec[2]= 32.0f*sqrt(vec[0]*vec[0] + vec[1]*vec[1] + 1.0f);
1556                 
1557                 fla.xs= R.winx/2 + vec[0] + (1.2+rc[8])*R.rectx*vec[0]/vec[2];
1558                 fla.ys= R.winy/2 + vec[1] + (1.2+rc[8])*R.rectx*vec[1]/vec[2];
1559
1560                 if(R.flag & R_SEC_FIELD) {
1561                         if(R.r.mode & R_ODDFIELD) fla.ys += 0.5;
1562                         else fla.ys -= 0.5;
1563                 }
1564                 if(type & 1) fla.type= HA_FLARECIRC;
1565                 else fla.type= 0;
1566                 renderhalo_post(rr, rectf, &fla);
1567
1568                 fla.alfa*= 0.5;
1569                 if(type & 2) fla.type= HA_FLARECIRC;
1570                 else fla.type= 0;
1571                 renderhalo_post(rr, rectf, &fla);
1572                 
1573                 rc+= 7;
1574         }
1575 }
1576
1577 /* needs recode... integrate this better! */
1578 void add_halo_flare(Render *re)
1579 {
1580         RenderResult *rr= re->result;
1581         RenderLayer *rl;
1582         HaloRen *har = NULL;
1583         int a, mode, do_draw=0;
1584         
1585         /* for now, we get the first renderlayer in list with halos set */
1586         for(rl= rr->layers.first; rl; rl= rl->next)
1587                 if(rl->layflag & SCE_LAY_HALO)
1588                         break;
1589
1590         if(rl==NULL || rl->rectf==NULL)
1591                 return;
1592         
1593         mode= R.r.mode;
1594         R.r.mode &= ~R_PANORAMA;
1595         
1596         project_renderdata(&R, projectverto, 0, 0);
1597         
1598         for(a=0; a<R.tothalo; a++) {
1599                 if((a & 255)==0) har= R.bloha[a>>8];
1600                 else har++;
1601                 
1602                 if(har->flarec) {
1603                         do_draw= 1;
1604                         renderflare(rr, rl->rectf, har);
1605                 }
1606         }
1607
1608         if(do_draw) {
1609                 /* weak... the display callback wants an active renderlayer pointer... */
1610                 rr->renlay= rl;
1611                 re->display_draw(rr, NULL);
1612         }
1613         
1614         R.r.mode= mode; 
1615 }
1616
1617 /* ************************* used for shaded view ************************ */
1618
1619 /* if *re, then initialize, otherwise execute */
1620 void RE_shade_external(Render *re, ShadeInput *shi, ShadeResult *shr)
1621 {
1622         static VlakRen vlr;
1623         
1624         /* init */
1625         if(re) {
1626                 R= *re;
1627                 
1628                 /* fake render face */
1629                 memset(&vlr, 0, sizeof(VlakRen));
1630                 vlr.lay= -1;
1631                 
1632                 return;
1633         }
1634         shi->vlr= &vlr;
1635         
1636         if(shi->mat->nodetree && shi->mat->use_nodes)
1637                 ntreeShaderExecTree(shi->mat->nodetree, shi, shr);
1638         else {
1639                 /* copy all relevant material vars, note, keep this synced with render_types.h */
1640                 memcpy(&shi->r, &shi->mat->r, 23*sizeof(float));
1641                 shi->har= shi->mat->har;
1642                 
1643                 shade_material_loop(shi, shr);
1644         }
1645 }
1646
1647 /* ************************* bake ************************ */
1648
1649 #define FTOCHAR(val) val<=0.0f?0: (val>=1.0f?255: (char)(255.0f*val))
1650
1651 typedef struct BakeShade {
1652         ShadeSample ssamp;
1653         VlakRen *vlr;
1654         
1655         ZSpan *zspan;
1656         Image *ima;
1657         ImBuf *ibuf;
1658         
1659         int rectx, recty, quad, type, vdone, ready;
1660         
1661         unsigned int *rect;
1662         float *rect_float;
1663 } BakeShade;
1664
1665 static void do_bake_shade(void *handle, int x, int y, float u, float v)
1666 {
1667         BakeShade *bs= handle;
1668         ShadeSample *ssamp= &bs->ssamp;
1669         ShadeInput *shi= ssamp->shi;
1670         ShadeResult shr;
1671         VlakRen *vlr= bs->vlr;
1672         float l, *v1, *v2, *v3;
1673         
1674         /* fast threadsafe break test */
1675         if(R.test_break())
1676                 return;
1677         
1678         /* setup render coordinates */
1679         if(bs->quad) {
1680                 v1= vlr->v1->co;
1681                 v2= vlr->v3->co;
1682                 v3= vlr->v4->co;
1683         }
1684         else {
1685                 v1= vlr->v1->co;
1686                 v2= vlr->v2->co;
1687                 v3= vlr->v3->co;
1688         }
1689         
1690         /* renderco */
1691         l= 1.0f-u-v;
1692         
1693         shi->co[0]= l*v3[0]+u*v1[0]+v*v2[0];
1694         shi->co[1]= l*v3[1]+u*v1[1]+v*v2[1];
1695         shi->co[2]= l*v3[2]+u*v1[2]+v*v2[2];
1696         
1697         /* set up view vector */
1698         VECCOPY(shi->view, shi->co);
1699         Normalize(shi->view);
1700         
1701         /* no face normal flip */
1702         shi->puno= 0;
1703         
1704         /* cache for shadow */
1705         shi->samplenr++;
1706         
1707         if(bs->quad) 
1708                 shade_input_set_triangle_i(shi, vlr, 0, 2, 3);
1709         else
1710                 shade_input_set_triangle_i(shi, vlr, 0, 1, 2);
1711         
1712         shi->u= -u;
1713         shi->v= -v;
1714         shi->xs= x;
1715         shi->ys= y;
1716         
1717         shade_input_set_normals(shi);
1718
1719         /* init material vars */
1720         memcpy(&shi->r, &shi->mat->r, 23*sizeof(float));        // note, keep this synced with render_types.h
1721         shi->har= shi->mat->har;
1722         
1723         if(bs->type==RE_BAKE_AO) {
1724                 ambient_occlusion(shi);
1725                 ambient_occlusion_to_diffuse(shi, shr.combined);
1726         }
1727         else {
1728                 
1729                 shade_input_set_shade_texco(shi);
1730                 
1731                 shade_samples_do_AO(ssamp);
1732                 
1733                 if(shi->mat->nodetree && shi->mat->use_nodes) {
1734                         ntreeShaderExecTree(shi->mat->nodetree, shi, &shr);
1735                         shi->mat= vlr->mat;             /* shi->mat is being set in nodetree */
1736                 }
1737                 else
1738                         shade_material_loop(shi, &shr);
1739                 
1740                 if(bs->type==RE_BAKE_NORMALS) {
1741                         shr.combined[0]= shi->vn[0]/2.0f + 0.5f;
1742                         shr.combined[1]= 0.5f - shi->vn[1]/2.0f;
1743                         shr.combined[2]= shi->vn[2]/2.0f + 0.5f;
1744                 }
1745                 else if(bs->type==RE_BAKE_TEXTURE) {
1746                         shr.combined[0]= shi->r;
1747                         shr.combined[1]= shi->g;
1748                         shr.combined[2]= shi->b;
1749                 }
1750         }
1751         
1752         if(bs->rect) {
1753                 char *col= (char *)(bs->rect + bs->rectx*y + x);
1754                 col[0]= FTOCHAR(shr.combined[0]);
1755                 col[1]= FTOCHAR(shr.combined[1]);
1756                 col[2]= FTOCHAR(shr.combined[2]);
1757                 col[3]= 255;
1758         }
1759         else {
1760                 float *col= bs->rect_float + 4*(bs->rectx*y + x);
1761                 VECCOPY(col, shr.combined);
1762                 col[3]= 1.0f;
1763         }
1764 }
1765
1766 static int get_next_bake_face(BakeShade *bs)
1767 {
1768         VlakRen *vlr;
1769         MTFace *tface;
1770         static int v= 0, vdone= 0;
1771         
1772         if(bs==NULL) {
1773                 vlr= NULL;
1774                 v= vdone= 0;
1775                 return 0;
1776         }
1777         
1778         BLI_lock_thread(LOCK_CUSTOM1);  
1779         
1780         for(; v<R.totvlak; v++) {
1781                 vlr= RE_findOrAddVlak(&R, v);
1782                 
1783                 if(vlr->ob->flag & SELECT) {
1784                         tface= RE_vlakren_get_tface(&R, vlr, 0, NULL, 0);
1785
1786                         if(tface && tface->tpage) {
1787                                 Image *ima= tface->tpage;
1788                                 ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL);
1789                                 float vec[4]= {0.0f, 0.0f, 0.0f, 0.0f};
1790                                 
1791                                 if(ibuf==NULL)
1792                                         continue;
1793                                 
1794                                 if(ibuf->rect==NULL && ibuf->rect_float==NULL)
1795                                         continue;
1796                                 
1797                                 if(ibuf->rect_float && !(ibuf->channels==0 || ibuf->channels==4))
1798                                         continue;
1799                                 
1800                                 /* find the image for the first time? */
1801                                 if(ima->id.flag & LIB_DOIT) {
1802                                         ima->id.flag &= ~LIB_DOIT;
1803                                         
1804                                         /* we either fill in float or char, this ensures things go fine */
1805                                         if(ibuf->rect_float)
1806                                                 imb_freerectImBuf(ibuf);
1807                                         /* clear image */
1808                                         if(R.r.bake_flag & R_BAKE_CLEAR)
1809                                                 IMB_rectfill(ibuf, vec);
1810                                 
1811                                         /* might be read by UI to set active image for display */
1812                                         R.bakebuf= ima;
1813                                 }                               
1814                                 
1815                                 bs->vlr= vlr;
1816                                 
1817                                 bs->vdone++;    /* only for error message if nothing was rendered */
1818                                 v++;
1819                                 
1820                                 BLI_unlock_thread(LOCK_CUSTOM1);
1821                                 return 1;
1822                         }
1823                 }
1824         }
1825         
1826         BLI_unlock_thread(LOCK_CUSTOM1);
1827         return 0;
1828 }
1829
1830 /* already have tested for tface and ima and zspan */
1831 static void shade_tface(BakeShade *bs)
1832 {
1833         VlakRen *vlr= bs->vlr;
1834         MTFace *tface= RE_vlakren_get_tface(&R, vlr, 0, NULL, 0);
1835         Image *ima= tface->tpage;
1836         float vec[4][2];
1837         int a, i1, i2, i3;
1838         
1839         /* check valid zspan */
1840         if(ima!=bs->ima) {
1841                 bs->ima= ima;
1842                 bs->ibuf= BKE_image_get_ibuf(ima, NULL);
1843                 /* note, these calls only free/fill contents of zspan struct, not zspan itself */
1844                 zbuf_free_span(bs->zspan);
1845                 zbuf_alloc_span(bs->zspan, bs->ibuf->x, bs->ibuf->y);
1846         }                               
1847         
1848         bs->rectx= bs->ibuf->x;
1849         bs->recty= bs->ibuf->y;
1850         bs->rect= bs->ibuf->rect;
1851         bs->rect_float= bs->ibuf->rect_float;
1852         bs->quad= 0;
1853         
1854         /* get pixel level vertex coordinates */
1855         for(a=0; a<4; a++) {
1856                 vec[a][0]= tface->uv[a][0]*(float)bs->rectx - 0.5f;
1857                 vec[a][1]= tface->uv[a][1]*(float)bs->recty - 0.5f;
1858         }
1859         
1860         /* UV indices have to be corrected for possible quad->tria splits */
1861         i1= 0; i2= 1; i3= 2;
1862         vlr_set_uv_indices(vlr, &i1, &i2, &i3);
1863         zspan_scanconvert(bs->zspan, bs, vec[i1], vec[i2], vec[i3], do_bake_shade);
1864         
1865         if(vlr->v4) {
1866                 bs->quad= 1;
1867                 zspan_scanconvert(bs->zspan, bs, vec[0], vec[2], vec[3], do_bake_shade);
1868         }
1869 }
1870
1871 static void *do_bake_thread(void *bs_v)
1872 {
1873         BakeShade *bs= bs_v;
1874         
1875         while(get_next_bake_face(bs)) {
1876                 shade_tface(bs);
1877                 
1878                 /* fast threadsafe break test */
1879                 if(R.test_break())
1880                         break;
1881         }
1882         bs->ready= 1;
1883         
1884         return NULL;
1885 }
1886
1887 /* using object selection tags, the faces with UV maps get baked */
1888 /* render should have been setup */
1889 /* returns 0 if nothing was handled */
1890 int RE_bake_shade_all_selected(Render *re, int type)
1891 {
1892         BakeShade handles[BLENDER_MAX_THREADS];
1893         ListBase threads;
1894         Image *ima;
1895         int a, vdone=0;
1896         
1897         /* initialize static vars */
1898         get_next_bake_face(NULL);
1899         
1900         /* baker uses this flag to detect if image was initialized */
1901         for(ima= G.main->image.first; ima; ima= ima->id.next)
1902                 ima->id.flag |= LIB_DOIT;
1903         
1904         /* initialize render global */
1905         R= *re;
1906         R.bakebuf= NULL;
1907         
1908         BLI_init_threads(&threads, do_bake_thread, re->r.threads);
1909
1910         /* get the threads running */
1911         for(a=0; a<re->r.threads; a++) {
1912                 /* set defaults in handles */
1913                 memset(&handles[a], 0, sizeof(BakeShade));
1914                 
1915                 handles[a].ssamp.shi[0].lay= re->scene->lay;
1916                 handles[a].ssamp.shi[0].passflag= SCE_PASS_COMBINED;
1917                 handles[a].ssamp.shi[0].combinedflag= ~(SCE_PASS_SPEC);
1918                 handles[a].ssamp.shi[0].thread= a;
1919                 handles[a].ssamp.tot= 1;
1920                 
1921                 handles[a].type= type;
1922                 handles[a].zspan= MEM_callocN(sizeof(ZSpan), "zspan for bake");
1923                 
1924                 BLI_insert_thread(&threads, &handles[a]);
1925         }
1926         
1927         /* wait for everything to be done */
1928         a= 0;
1929         while(a!=re->r.threads) {
1930                 
1931                 PIL_sleep_ms(50);
1932
1933                 for(a=0; a<re->r.threads; a++)
1934                         if(handles[a].ready==0)
1935                                 break;
1936         }
1937         
1938         /* filter images */
1939         for(ima= G.main->image.first; ima; ima= ima->id.next) {
1940                 if((ima->id.flag & LIB_DOIT)==0) {
1941                         ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL);
1942                         for(a=0; a<re->r.bake_filter; a++)
1943                                 IMB_filter_extend(ibuf);
1944                         ibuf->userflags |= IB_BITMAPDIRTY;
1945                 }
1946         }
1947         
1948         /* calculate return value */
1949         for(a=0; a<re->r.threads; a++) {
1950                 vdone+= handles[a].vdone;
1951                 
1952                 zbuf_free_span(handles[a].zspan);
1953                 MEM_freeN(handles[a].zspan);
1954         }
1955         
1956         BLI_end_threads(&threads);
1957         return vdone;
1958 }
1959
1960 struct Image *RE_bake_shade_get_image(void)
1961 {
1962         return R.bakebuf;
1963 }
1964