Patch #8034: "soft" option for halos, which avoids ugly intersections
[blender-staging.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 <float.h>
33 #include <string.h>
34
35 /* External modules: */
36 #include "MEM_guardedalloc.h"
37
38 #include "BLI_arithb.h"
39 #include "BLI_blenlib.h"
40 #include "BLI_jitter.h"
41 #include "BLI_rand.h"
42 #include "BLI_threads.h"
43
44 #include "BKE_utildefines.h"
45
46 #include "DNA_image_types.h"
47 #include "DNA_lamp_types.h"
48 #include "DNA_material_types.h"
49 #include "DNA_meshdata_types.h"
50
51 #include "BKE_global.h"
52 #include "BKE_image.h"
53 #include "BKE_main.h"
54 #include "BKE_node.h"
55 #include "BKE_texture.h"
56
57 #include "IMB_imbuf_types.h"
58 #include "IMB_imbuf.h"
59
60 /* local include */
61 #include "renderpipeline.h"
62 #include "render_types.h"
63 #include "renderdatabase.h"
64 #include "occlusion.h"
65 #include "pixelblending.h"
66 #include "pixelshading.h"
67 #include "shadbuf.h"
68 #include "shading.h"
69 #include "sss.h"
70 #include "zbuf.h"
71 #include "RE_raytrace.h"
72
73 #include "PIL_time.h"
74
75 /* own include */
76 #include "rendercore.h"
77
78
79 /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
80 /* defined in pipeline.c, is hardcopy of active dynamic allocated Render */
81 /* only to be used here in this file, it's for speed */
82 extern struct Render R;
83 /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
84
85 /* x and y are current pixels in rect to be rendered */
86 /* do not normalize! */
87 void calc_view_vector(float *view, float x, float y)
88 {
89
90         view[2]= -ABS(R.clipsta);
91         
92         if(R.r.mode & R_ORTHO) {
93                 view[0]= view[1]= 0.0f;
94         }
95         else {
96                 
97                 if(R.r.mode & R_PANORAMA)
98                         x-= R.panodxp;
99                 
100                 /* move x and y to real viewplane coords */
101                 x= (x/(float)R.winx);
102                 view[0]= R.viewplane.xmin + x*(R.viewplane.xmax - R.viewplane.xmin);
103                 
104                 y= (y/(float)R.winy);
105                 view[1]= R.viewplane.ymin + y*(R.viewplane.ymax - R.viewplane.ymin);
106                 
107 //              if(R.flag & R_SEC_FIELD) {
108 //                      if(R.r.mode & R_ODDFIELD) view[1]= (y+R.ystart)*R.ycor;
109 //                      else view[1]= (y+R.ystart+1.0)*R.ycor;
110 //              }
111 //              else view[1]= (y+R.ystart+R.bluroffsy+0.5)*R.ycor;
112         
113                 if(R.r.mode & R_PANORAMA) {
114                         float u= view[0] + R.panodxv; float v= view[2];
115                         view[0]= R.panoco*u + R.panosi*v;
116                         view[2]= -R.panosi*u + R.panoco*v;
117                 }
118         }
119 }
120
121 void calc_renderco_ortho(float *co, float x, float y, int z)
122 {
123         /* x and y 3d coordinate can be derived from pixel coord and winmat */
124         float fx= 2.0f/(R.winx*R.winmat[0][0]);
125         float fy= 2.0f/(R.winy*R.winmat[1][1]);
126         float zco;
127         
128         co[0]= (x - 0.5f*R.winx)*fx - R.winmat[3][0]/R.winmat[0][0];
129         co[1]= (y - 0.5f*R.winy)*fy - R.winmat[3][1]/R.winmat[1][1];
130         
131         zco= ((float)z)/2147483647.0f;
132         co[2]= R.winmat[3][2]/( R.winmat[2][3]*zco - R.winmat[2][2] );
133 }
134
135 void calc_renderco_zbuf(float *co, float *view, int z)
136 {
137         float fac, zco;
138         
139         /* inverse of zbuf calc: zbuf = MAXZ*hoco_z/hoco_w */
140         zco= ((float)z)/2147483647.0f;
141         co[2]= R.winmat[3][2]/( R.winmat[2][3]*zco - R.winmat[2][2] );
142
143         fac= co[2]/view[2];
144         co[0]= fac*view[0];
145         co[1]= fac*view[1];
146 }
147
148 /* also used in zbuf.c and shadbuf.c */
149 int count_mask(unsigned short mask)
150 {
151         if(R.samples)
152                 return (R.samples->cmask[mask & 255]+R.samples->cmask[mask>>8]);
153         return 0;
154 }
155
156 static int calchalo_z(HaloRen *har, int zz)
157 {
158         
159         if(har->type & HA_ONLYSKY) {
160                 if(zz!=0x7FFFFFFF) zz= - 0x7FFFFF;
161         }
162         else {
163                 zz= (zz>>8);
164         }
165         return zz;
166 }
167
168
169
170 static void halo_pixelstruct(HaloRen *har, RenderLayer **rlpp, int totsample, int od, float dist, float xn, float yn, PixStr *ps)
171 {
172         float col[4], accol[4], fac;
173         int amount, amountm, zz, flarec, sample, fullsample, mask=0;
174         
175         fullsample= (totsample > 1);
176         amount= 0;
177         accol[0]=accol[1]=accol[2]=accol[3]= 0.0f;
178         flarec= har->flarec;
179         
180         while(ps) {
181                 amountm= count_mask(ps->mask);
182                 amount+= amountm;
183                 
184                 zz= calchalo_z(har, ps->z);
185                 if((zz> har->zs) || (har->mat->mode & MA_HALO_SOFT)) {
186                         if(shadeHaloFloat(har, col, zz, dist, xn, yn, flarec)) {
187                                 flarec= 0;
188
189                                 if(fullsample) {
190                                         for(sample=0; sample<totsample; sample++)
191                                                 if(ps->mask & (1 << sample))
192                                                         addalphaAddfacFloat(rlpp[sample]->rectf + od*4, col, har->add);
193                                 }
194                                 else {
195                                         fac= ((float)amountm)/(float)R.osa;
196                                         accol[0]+= fac*col[0];
197                                         accol[1]+= fac*col[1];
198                                         accol[2]+= fac*col[2];
199                                         accol[3]+= fac*col[3];
200                                 }
201                         }
202                 }
203                 
204                 mask |= ps->mask;
205                 ps= ps->next;
206         }
207
208         /* now do the sky sub-pixels */
209         amount= R.osa-amount;
210         if(amount) {
211                 if(shadeHaloFloat(har, col, 0x7FFFFF, dist, xn, yn, flarec)) {
212                         if(!fullsample) {
213                                 fac= ((float)amount)/(float)R.osa;
214                                 accol[0]+= fac*col[0];
215                                 accol[1]+= fac*col[1];
216                                 accol[2]+= fac*col[2];
217                                 accol[3]+= fac*col[3];
218                         }
219                 }
220         }
221
222         if(fullsample) {
223                 for(sample=0; sample<totsample; sample++)
224                         if(!(mask & (1 << sample)))
225                                 addalphaAddfacFloat(rlpp[sample]->rectf + od*4, col, har->add);
226         }
227         else {
228                 col[0]= accol[0];
229                 col[1]= accol[1];
230                 col[2]= accol[2];
231                 col[3]= accol[3];
232                 
233                 for(sample=0; sample<totsample; sample++)
234                         addalphaAddfacFloat(rlpp[sample]->rectf + od*4, col, har->add);
235         }
236 }
237
238 static void halo_tile(RenderPart *pa, RenderLayer *rl)
239 {
240         RenderLayer *rlpp[RE_MAX_OSA];
241         HaloRen *har;
242         rcti disprect= pa->disprect, testrect= pa->disprect;
243         float dist, xsq, ysq, xn, yn;
244         float col[4];
245         long *rd= NULL;
246         int a, *rz, zz, y, sample, totsample, od;
247         short minx, maxx, miny, maxy, x;
248         unsigned int lay= rl->lay;
249
250         /* we don't render halos in the cropped area, gives errors in flare counter */
251         if(pa->crop) {
252                 testrect.xmin+= pa->crop;
253                 testrect.xmax-= pa->crop;
254                 testrect.ymin+= pa->crop;
255                 testrect.ymax-= pa->crop;
256         }
257         
258         totsample= get_sample_layers(pa, rl, rlpp);
259
260         for(a=0; a<R.tothalo; a++) {
261                 har= R.sortedhalos[a];
262
263                 /* layer test, clip halo with y */
264                 if((har->lay & lay)==0);
265                 else if(testrect.ymin > har->maxy);
266                 else if(testrect.ymax < har->miny);
267                 else {
268                         
269                         minx= floor(har->xs-har->rad);
270                         maxx= ceil(har->xs+har->rad);
271                         
272                         if(testrect.xmin > maxx);
273                         else if(testrect.xmax < minx);
274                         else {
275                                 
276                                 minx= MAX2(minx, testrect.xmin);
277                                 maxx= MIN2(maxx, testrect.xmax);
278                         
279                                 miny= MAX2(har->miny, testrect.ymin);
280                                 maxy= MIN2(har->maxy, testrect.ymax);
281                         
282                                 for(y=miny; y<maxy; y++) {
283                                         int rectofs= (y-disprect.ymin)*pa->rectx + (minx - disprect.xmin);
284                                         rz= pa->rectz + rectofs;
285                                         od= rectofs;
286                                         
287                                         if(pa->rectdaps)
288                                                 rd= pa->rectdaps + rectofs;
289                                         
290                                         yn= (y-har->ys)*R.ycor;
291                                         ysq= yn*yn;
292                                         
293                                         for(x=minx; x<maxx; x++, rz++, od++) {
294                                                 xn= x- har->xs;
295                                                 xsq= xn*xn;
296                                                 dist= xsq+ysq;
297                                                 if(dist<har->radsq) {
298                                                         if(rd && *rd) {
299                                                                 halo_pixelstruct(har, rlpp, totsample, od, dist, xn, yn, (PixStr *)*rd);
300                                                         }
301                                                         else {
302                                                                 zz= calchalo_z(har, *rz);
303                                                                 if((zz> har->zs) || (har->mat->mode & MA_HALO_SOFT)) {
304                                                                         if(shadeHaloFloat(har, col, zz, dist, xn, yn, har->flarec)) {
305                                                                                 for(sample=0; sample<totsample; sample++)
306                                                                                         addalphaAddfacFloat(rlpp[sample]->rectf + od*4, col, har->add);
307                                                                         }
308                                                                 }
309                                                         }
310                                                 }
311                                                 if(rd) rd++;
312                                         }
313                                 }
314                         }
315                 }
316                 if(R.test_break() ) break; 
317         }
318 }
319
320 static void lamphalo_tile(RenderPart *pa, RenderLayer *rl)
321 {
322         ShadeInput shi;
323         float *pass= rl->rectf;
324         float fac;
325         long *rd= pa->rectdaps;
326         int x, y, *rz= pa->rectz;
327         
328         shade_input_initialize(&shi, pa, rl, 0); /* this zero's ShadeInput for us */
329         
330         for(y=pa->disprect.ymin; y<pa->disprect.ymax; y++) {
331                 for(x=pa->disprect.xmin; x<pa->disprect.xmax; x++, rz++, pass+=4) {
332                         
333                         calc_view_vector(shi.view, x, y);
334                         
335                         if(rd && *rd) {
336                                 PixStr *ps= (PixStr *)*rd;
337                                 int samp, totsamp= 0;
338                                 
339                                 while(ps) {
340                                         if(R.r.mode & R_ORTHO)
341                                                 calc_renderco_ortho(shi.co, (float)x, (float)y, ps->z);
342                                         else
343                                                 calc_renderco_zbuf(shi.co, shi.view, ps->z);
344                                         
345                                         totsamp+= samp= count_mask(ps->mask);
346                                         fac= ((float)samp)/(float)R.osa;
347                                         renderspothalo(&shi, pass, fac);
348                                         ps= ps->next;
349                                 }
350                                 if(totsamp<R.osa) {
351                                         fac= ((float)R.osa-totsamp)/(float)R.osa;
352                                         shi.co[2]= 0.0f;
353                                         renderspothalo(&shi, pass, fac);
354                                 }
355                         }
356                         else {
357                                 if(R.r.mode & R_ORTHO)
358                                         calc_renderco_ortho(shi.co, (float)x, (float)y, *rz);
359                                 else
360                                         calc_renderco_zbuf(shi.co, shi.view, *rz);
361                                 
362                                 renderspothalo(&shi, pass, 1.0f);
363                         }
364                         
365                         if(rd) rd++;
366                 }
367                 if(y&1)
368                         if(R.test_break()) break; 
369         }
370 }                               
371
372
373 /* ********************* MAINLOOPS ******************** */
374
375 /* osa version */
376 static void add_filt_passes(RenderLayer *rl, int curmask, int rectx, int offset, ShadeInput *shi, ShadeResult *shr)
377 {
378         RenderPass *rpass;
379
380         /* combined rgb */
381         add_filt_fmask(curmask, shr->combined, rl->rectf + 4*offset, rectx);
382         
383         for(rpass= rl->passes.first; rpass; rpass= rpass->next) {
384                 float *fp, *col= NULL;
385                 int pixsize= 3;
386                 
387                 switch(rpass->passtype) {
388                         case SCE_PASS_Z:
389                                 fp= rpass->rect + offset;
390                                 *fp= shr->z;
391                                 break;
392                         case SCE_PASS_RGBA:
393                                 col= shr->col;
394                                 pixsize= 4;
395                                 break;
396                         case SCE_PASS_DIFFUSE:
397                                 col= shr->diff;
398                                 break;
399                         case SCE_PASS_SPEC:
400                                 col= shr->spec;
401                                 break;
402                         case SCE_PASS_SHADOW:
403                                 col= shr->shad;
404                                 break;
405                         case SCE_PASS_AO:
406                                 col= shr->ao;
407                                 break;
408                         case SCE_PASS_REFLECT:
409                                 col= shr->refl;
410                                 break;
411                         case SCE_PASS_REFRACT:
412                                 col= shr->refr;
413                                 break;
414                         case SCE_PASS_RADIO:
415                                 col= shr->rad;
416                                 break;
417                         case SCE_PASS_NORMAL:
418                                 col= shr->nor;
419                                 break;
420                         case SCE_PASS_UV:
421                                 /* box filter only, gauss will screwup UV too much */
422                                 if(shi->totuv) {
423                                         float mult= (float)count_mask(curmask)/(float)R.osa;
424                                         fp= rpass->rect + 3*offset;
425                                         fp[0]+= mult*(0.5f + 0.5f*shi->uv[shi->actuv].uv[0]);
426                                         fp[1]+= mult*(0.5f + 0.5f*shi->uv[shi->actuv].uv[1]);
427                                         fp[2]+= mult;
428                                 }
429                                 break;
430                         case SCE_PASS_INDEXOB:
431                                 /* no filter */
432                                 if(shi->vlr) {
433                                         fp= rpass->rect + offset;
434                                         if(*fp==0.0f)
435                                                 *fp= (float)shi->obr->ob->index;
436                                 }
437                                 break;
438                         case SCE_PASS_MIST:
439                                 /*  */
440                                 col= &shr->mist;
441                                 pixsize= 1;
442                                 break;
443                         
444                         case SCE_PASS_VECTOR:
445                         {
446                                 /* add minimum speed in pixel, no filter */
447                                 fp= rpass->rect + 4*offset;
448                                 if( (ABS(shr->winspeed[0]) + ABS(shr->winspeed[1]))< (ABS(fp[0]) + ABS(fp[1])) ) {
449                                         fp[0]= shr->winspeed[0];
450                                         fp[1]= shr->winspeed[1];
451                                 }
452                                 if( (ABS(shr->winspeed[2]) + ABS(shr->winspeed[3]))< (ABS(fp[2]) + ABS(fp[3])) ) {
453                                         fp[2]= shr->winspeed[2];
454                                         fp[3]= shr->winspeed[3];
455                                 }
456                         }
457                                 break;
458                 }
459                 if(col) {
460                         fp= rpass->rect + pixsize*offset;
461                         add_filt_fmask_pixsize(curmask, col, fp, rectx, pixsize);
462                 }
463         }
464 }
465
466 /* non-osa version */
467 static void add_passes(RenderLayer *rl, int offset, ShadeInput *shi, ShadeResult *shr)
468 {
469         RenderPass *rpass;
470         float *fp;
471         
472         fp= rl->rectf + 4*offset;
473         QUATCOPY(fp, shr->combined);
474         
475         for(rpass= rl->passes.first; rpass; rpass= rpass->next) {
476                 float *col= NULL, uvcol[3];
477                 int a, pixsize= 3;
478                 
479                 switch(rpass->passtype) {
480                         case SCE_PASS_Z:
481                                 fp= rpass->rect + offset;
482                                 *fp= shr->z;
483                                 break;
484                         case SCE_PASS_RGBA:
485                                 col= shr->col;
486                                 pixsize= 4;
487                                 break;
488                         case SCE_PASS_DIFFUSE:
489                                 col= shr->diff;
490                                 break;
491                         case SCE_PASS_SPEC:
492                                 col= shr->spec;
493                                 break;
494                         case SCE_PASS_SHADOW:
495                                 col= shr->shad;
496                                 break;
497                         case SCE_PASS_AO:
498                                 col= shr->ao;
499                                 break;
500                         case SCE_PASS_REFLECT:
501                                 col= shr->refl;
502                                 break;
503                         case SCE_PASS_REFRACT:
504                                 col= shr->refr;
505                                 break;
506                         case SCE_PASS_RADIO:
507                                 col= shr->rad;
508                                 break;
509                         case SCE_PASS_NORMAL:
510                                 col= shr->nor;
511                                 break;
512                         case SCE_PASS_UV:
513                                 if(shi->totuv) {
514                                         uvcol[0]= 0.5f + 0.5f*shi->uv[shi->actuv].uv[0];
515                                         uvcol[1]= 0.5f + 0.5f*shi->uv[shi->actuv].uv[1];
516                                         uvcol[2]= 1.0f;
517                                         col= uvcol;
518                                 }
519                                 break;
520                         case SCE_PASS_VECTOR:
521                                 col= shr->winspeed;
522                                 pixsize= 4;
523                                 break;
524                         case SCE_PASS_INDEXOB:
525                                 if(shi->vlr) {
526                                         fp= rpass->rect + offset;
527                                         *fp= (float)shi->obr->ob->index;
528                                 }
529                                 break;
530                         case SCE_PASS_MIST:
531                                 fp= rpass->rect + offset;
532                                 *fp= shr->mist;
533                                 break;
534                 }
535                 if(col) {
536                         fp= rpass->rect + pixsize*offset;
537                         for(a=0; a<pixsize; a++)
538                                 fp[a]= col[a];
539                 }
540         }
541 }
542
543 int get_sample_layers(RenderPart *pa, RenderLayer *rl, RenderLayer **rlpp)
544 {
545         
546         if(pa->fullresult.first) {
547                 int sample, nr= BLI_findindex(&pa->result->layers, rl);
548                 
549                 for(sample=0; sample<R.osa; sample++) {
550                         RenderResult *rr= BLI_findlink(&pa->fullresult, sample);
551                 
552                         rlpp[sample]= BLI_findlink(&rr->layers, nr);
553                 }               
554                 return R.osa;
555         }
556         else {
557                 rlpp[0]= rl;
558                 return 1;
559         }
560 }
561
562
563 /* only do sky, is default in the solid layer (shade_tile) btw */
564 static void sky_tile(RenderPart *pa, RenderLayer *rl)
565 {
566         RenderLayer *rlpp[RE_MAX_OSA];
567         int x, y, od=0, totsample;
568         
569         if(R.r.alphamode!=R_ADDSKY)
570                 return;
571         
572         totsample= get_sample_layers(pa, rl, rlpp);
573         
574         for(y=pa->disprect.ymin; y<pa->disprect.ymax; y++) {
575                 for(x=pa->disprect.xmin; x<pa->disprect.xmax; x++, od+=4) {
576                         float col[4];
577                         int sample, done= 0;
578                         
579                         for(sample= 0; sample<totsample; sample++) {
580                                 float *pass= rlpp[sample]->rectf + od;
581                                 
582                                 if(pass[3]<1.0f) {
583                                         
584                                         if(done==0) {
585                                                 shadeSkyPixel(col, x, y);
586                                                 done= 1;
587                                         }
588                                         
589                                         if(pass[3]==0.0f) {
590                                                 QUATCOPY(pass, col);
591                                         }
592                                         else {
593                                                 addAlphaUnderFloat(pass, col);
594                                         }
595                                 }
596                         }                       
597                 }
598                 
599                 if(y&1)
600                         if(R.test_break()) break; 
601         }
602 }
603
604 static void shadeDA_tile(RenderPart *pa, RenderLayer *rl)
605 {
606         RenderResult *rr= pa->result;
607         ShadeSample ssamp;
608         long *rd, *rectdaps= pa->rectdaps;
609         int samp;
610         int x, y, seed, crop=0, offs=0, od;
611         
612         if(R.test_break()) return; 
613         
614         /* irregular shadowb buffer creation */
615         if(R.r.mode & R_SHADOW)
616                 ISB_create(pa, NULL);
617         
618         /* we set per pixel a fixed seed, for random AO and shadow samples */
619         seed= pa->rectx*pa->disprect.ymin;
620         
621         /* general shader info, passes */
622         shade_sample_initialize(&ssamp, pa, rl);
623
624         /* occlusion caching */
625         if(R.occlusiontree)
626                 cache_occ_samples(&R, pa, &ssamp);
627                 
628         /* filtered render, for now we assume only 1 filter size */
629         if(pa->crop) {
630                 crop= 1;
631                 rectdaps+= pa->rectx + 1;
632                 offs= pa->rectx + 1;
633         }
634         
635         /* scanline updates have to be 2 lines behind */
636         rr->renrect.ymin= 0;
637         rr->renrect.ymax= -2*crop;
638         rr->renlay= rl;
639                                 
640         for(y=pa->disprect.ymin+crop; y<pa->disprect.ymax-crop; y++, rr->renrect.ymax++) {
641                 rd= rectdaps;
642                 od= offs;
643                 
644                 for(x=pa->disprect.xmin+crop; x<pa->disprect.xmax-crop; x++, rd++, od++) {
645                         BLI_thread_srandom(pa->thread, seed++);
646                         
647                         if(*rd) {
648                                 if(shade_samples(&ssamp, (PixStr *)(*rd), x, y)) {
649                                         
650                                         /* multisample buffers or filtered mask filling? */
651                                         if(pa->fullresult.first) {
652                                                 int a;
653                                                 for(samp=0; samp<ssamp.tot; samp++) {
654                                                         int smask= ssamp.shi[samp].mask;
655                                                         for(a=0; a<R.osa; a++) {
656                                                                 int mask= 1<<a;
657                                                                 if(smask & mask)
658                                                                         add_passes(ssamp.rlpp[a], od, &ssamp.shi[samp], &ssamp.shr[samp]);
659                                                         }
660                                                 }
661                                         }
662                                         else {
663                                                 for(samp=0; samp<ssamp.tot; samp++)
664                                                         add_filt_passes(rl, ssamp.shi[samp].mask, pa->rectx, od, &ssamp.shi[samp], &ssamp.shr[samp]);
665                                         }
666                                 }
667                         }
668                 }
669                 
670                 rectdaps+= pa->rectx;
671                 offs+= pa->rectx;
672                 
673                 if(y&1) if(R.test_break()) break; 
674         }
675         
676         /* disable scanline updating */
677         rr->renlay= NULL;
678         
679         if(R.r.mode & R_SHADOW)
680                 ISB_free(pa);
681
682         if(R.occlusiontree)
683                 free_occ_samples(&R, pa);
684 }
685
686 /* ************* pixel struct ******** */
687
688
689 static PixStrMain *addpsmain(ListBase *lb)
690 {
691         PixStrMain *psm;
692         
693         psm= (PixStrMain *)MEM_mallocN(sizeof(PixStrMain),"pixstrMain");
694         BLI_addtail(lb, psm);
695         
696         psm->ps= (PixStr *)MEM_mallocN(4096*sizeof(PixStr),"pixstr");
697         psm->counter= 0;
698         
699         return psm;
700 }
701
702 static void freeps(ListBase *lb)
703 {
704         PixStrMain *psm, *psmnext;
705         
706         for(psm= lb->first; psm; psm= psmnext) {
707                 psmnext= psm->next;
708                 if(psm->ps)
709                         MEM_freeN(psm->ps);
710                 MEM_freeN(psm);
711         }
712         lb->first= lb->last= NULL;
713 }
714
715 static void addps(ListBase *lb, long *rd, int obi, int facenr, int z, int maskz, unsigned short mask)
716 {
717         PixStrMain *psm;
718         PixStr *ps, *last= NULL;
719         
720         if(*rd) {       
721                 ps= (PixStr *)(*rd);
722                 
723                 while(ps) {
724                         if( ps->obi == obi && ps->facenr == facenr ) {
725                                 ps->mask |= mask;
726                                 return;
727                         }
728                         last= ps;
729                         ps= ps->next;
730                 }
731         }
732         
733         /* make new PS (pixel struct) */
734         psm= lb->last;
735         
736         if(psm->counter==4095)
737                 psm= addpsmain(lb);
738         
739         ps= psm->ps + psm->counter++;
740         
741         if(last) last->next= ps;
742         else *rd= (long)ps;
743         
744         ps->next= NULL;
745         ps->obi= obi;
746         ps->facenr= facenr;
747         ps->z= z;
748         ps->maskz= maskz;
749         ps->mask = mask;
750         ps->shadfac= 0;
751 }
752
753 static void edge_enhance_add(RenderPart *pa, float *rectf, float *arect)
754 {
755         float addcol[4];
756         int pix;
757         
758         if(arect==NULL)
759                 return;
760         
761         for(pix= pa->rectx*pa->recty; pix>0; pix--, arect++, rectf+=4) {
762                 if(*arect != 0.0f) {
763                         addcol[0]= *arect * R.r.edgeR;
764                         addcol[1]= *arect * R.r.edgeG;
765                         addcol[2]= *arect * R.r.edgeB;
766                         addcol[3]= *arect;
767                         addAlphaOverFloat(rectf, addcol);
768                 }
769         }
770 }
771
772
773 static void convert_to_key_alpha(RenderPart *pa, float *rectf)
774 {
775         int y;
776         
777         for(y= pa->rectx*pa->recty; y>0; y--, rectf+=4) {
778                 if(rectf[3] >= 1.0f);
779                 else if(rectf[3] > 0.0f) {
780                         rectf[0] /= rectf[3];
781                         rectf[1] /= rectf[3];
782                         rectf[2] /= rectf[3];
783                 }
784         }
785 }
786
787 /* adds only alpha values */
788 void edge_enhance_tile(RenderPart *pa, float *rectf)    
789 {
790         /* use zbuffer to define edges, add it to the image */
791         int y, x, col, *rz, *rz1, *rz2, *rz3;
792         int zval1, zval2, zval3;
793         float *rf;
794         
795         /* shift values in zbuffer 4 to the right (anti overflows), for filter we need multiplying with 12 max */
796         rz= pa->rectz;
797         if(rz==NULL) return;
798         
799         for(y=0; y<pa->recty; y++)
800                 for(x=0; x<pa->rectx; x++, rz++) (*rz)>>= 4;
801         
802         rz1= pa->rectz;
803         rz2= rz1+pa->rectx;
804         rz3= rz2+pa->rectx;
805         
806         rf= rectf+pa->rectx+1;
807         
808         for(y=0; y<pa->recty-2; y++) {
809                 for(x=0; x<pa->rectx-2; x++, rz1++, rz2++, rz3++, rf++) {
810                         
811                         /* prevent overflow with sky z values */
812                         zval1=   rz1[0] + 2*rz1[1] +   rz1[2];
813                         zval2=  2*rz2[0]           + 2*rz2[2];
814                         zval3=   rz3[0] + 2*rz3[1] +   rz3[2];
815                         
816                         col= ( 4*rz2[1] - (zval1 + zval2 + zval3)/3 );
817                         if(col<0) col= -col;
818                         
819                         col >>= 5;
820                         if(col > (1<<16)) col= (1<<16);
821                         else col= (R.r.edgeint*col)>>8;
822                         
823                         if(col>0) {
824                                 float fcol;
825                                 
826                                 if(col>255) fcol= 1.0f;
827                                 else fcol= (float)col/255.0f;
828                                 
829                                 if(R.osa)
830                                         *rf+= fcol/(float)R.osa;
831                                 else
832                                         *rf= fcol;
833                         }
834                 }
835                 rz1+= 2;
836                 rz2+= 2;
837                 rz3+= 2;
838                 rf+= 2;
839         }
840         
841         /* shift back zbuf values, we might need it still */
842         rz= pa->rectz;
843         for(y=0; y<pa->recty; y++)
844                 for(x=0; x<pa->rectx; x++, rz++) (*rz)<<= 4;
845         
846 }
847
848 static void reset_sky_speed(RenderPart *pa, RenderLayer *rl)
849 {
850         /* for all pixels with max speed, set to zero */
851     RenderLayer *rlpp[RE_MAX_OSA];
852         float *fp;
853         int a, sample, totsample;
854         
855         totsample= get_sample_layers(pa, rl, rlpp);
856
857         for(sample= 0; sample<totsample; sample++) {
858                 fp= RE_RenderLayerGetPass(rlpp[sample], SCE_PASS_VECTOR);
859                 if(fp==NULL) break;
860
861                 for(a= 4*pa->rectx*pa->recty - 1; a>=0; a--)
862                         if(fp[a] == PASS_VECTOR_MAX) fp[a]= 0.0f;
863         }
864 }
865
866 static unsigned short *make_solid_mask(RenderPart *pa)
867
868         long *rd= pa->rectdaps;
869         unsigned short *solidmask, *sp;
870         int x;
871         
872         if(rd==NULL) return NULL;
873         
874         sp=solidmask= MEM_mallocN(sizeof(short)*pa->rectx*pa->recty, "solidmask");
875         
876         for(x=pa->rectx*pa->recty; x>0; x--, rd++, sp++) {
877                 if(*rd) {
878                         PixStr *ps= (PixStr *)*rd;
879                         
880                         *sp= ps->mask;
881                         for(ps= ps->next; ps; ps= ps->next)
882                                 *sp |= ps->mask;
883                 }
884                 else
885                         *sp= 0;
886         }
887                         
888         return solidmask;
889 }
890
891 static void addAlphaOverFloatMask(float *dest, float *source, unsigned short dmask, unsigned short smask)
892 {
893         unsigned short shared= dmask & smask;
894         float mul= 1.0 - source[3];
895         
896         if(shared) {    /* overlapping masks */
897                 
898                 /* masks differ, we make a mixture of 'add' and 'over' */
899                 if(shared!=dmask) {
900                         float shared_bits= (float)count_mask(shared);           /* alpha over */
901                         float tot_bits= (float)count_mask(smask|dmask);         /* alpha add */
902                         
903                         float add= (tot_bits - shared_bits)/tot_bits;           /* add level */
904                         mul= add + (1.0f-add)*mul;
905                 }
906         }
907         else if(dmask && smask) {
908                 /* works for premul only, of course */
909                 dest[0]+= source[0];
910                 dest[1]+= source[1];
911                 dest[2]+= source[2];
912                 dest[3]+= source[3];
913                 
914                 return;
915         }
916
917         dest[0]= (mul*dest[0]) + source[0];
918         dest[1]= (mul*dest[1]) + source[1];
919         dest[2]= (mul*dest[2]) + source[2];
920         dest[3]= (mul*dest[3]) + source[3];
921 }
922
923 typedef struct ZbufSolidData {
924         RenderLayer *rl;
925         ListBase *psmlist;
926         float *edgerect;
927 } ZbufSolidData;
928
929 void make_pixelstructs(RenderPart *pa, ZSpan *zspan, int sample, void *data)
930 {
931         ZbufSolidData *sdata= (ZbufSolidData*)data;
932         ListBase *lb= sdata->psmlist;
933         long *rd= pa->rectdaps;
934         int *ro= zspan->recto;
935         int *rp= zspan->rectp;
936         int *rz= zspan->rectz;
937         int *rm= zspan->rectmask;
938         int x, y;
939         int mask= 1<<sample;
940
941         for(y=0; y<pa->recty; y++) {
942                 for(x=0; x<pa->rectx; x++, rd++, rp++, ro++, rz++, rm++) {
943                         if(*rp) {
944                                 addps(lb, rd, *ro, *rp, *rz, (zspan->rectmask)? *rm: 0, mask);
945                         }
946                 }
947         }
948
949         if(sdata->rl->layflag & SCE_LAY_EDGE) 
950                 if(R.r.mode & R_EDGE) 
951                         edge_enhance_tile(pa, sdata->edgerect);
952 }
953
954 /* main call for shading Delta Accum, for OSA */
955 /* supposed to be fully threadable! */
956 void zbufshadeDA_tile(RenderPart *pa)
957 {
958         RenderResult *rr= pa->result;
959         RenderLayer *rl;
960         ListBase psmlist= {NULL, NULL};
961         float *edgerect= NULL;
962         
963         /* allocate the necessary buffers */
964                                 /* zbuffer inits these rects */
965         pa->recto= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "recto");
966         pa->rectp= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectp");
967         pa->rectz= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectz");
968         for(rl= rr->layers.first; rl; rl= rl->next) {
969                 if((rl->layflag & SCE_LAY_ZMASK) && (rl->layflag & SCE_LAY_NEG_ZMASK))
970                         pa->rectmask= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectmask");
971         
972                 /* initialize pixelstructs and edge buffer */
973                 addpsmain(&psmlist);
974                 pa->rectdaps= MEM_callocN(sizeof(long)*pa->rectx*pa->recty+4, "zbufDArectd");
975                 
976                 if(rl->layflag & SCE_LAY_EDGE) 
977                         if(R.r.mode & R_EDGE) 
978                                 edgerect= MEM_callocN(sizeof(float)*pa->rectx*pa->recty, "rectedge");
979                 
980                 /* always fill visibility */
981                 for(pa->sample=0; pa->sample<R.osa; pa->sample+=4) {
982                         ZbufSolidData sdata;
983
984                         sdata.rl= rl;
985                         sdata.psmlist= &psmlist;
986                         sdata.edgerect= edgerect;
987                         zbuffer_solid(pa, rl, make_pixelstructs, &sdata);
988                         if(R.test_break()) break; 
989                 }
990                 
991                 /* shades solid */
992                 if(rl->layflag & SCE_LAY_SOLID) 
993                         shadeDA_tile(pa, rl);
994                 
995                 /* lamphalo after solid, before ztra, looks nicest because ztra does own halo */
996                 if(R.flag & R_LAMPHALO)
997                         if(rl->layflag & SCE_LAY_HALO)
998                                 lamphalo_tile(pa, rl);
999                 
1000                 /* halo before ztra, because ztra fills in zbuffer now */
1001                 if(R.flag & R_HALO)
1002                         if(rl->layflag & SCE_LAY_HALO)
1003                                 halo_tile(pa, rl);
1004
1005                 /* transp layer */
1006                 if(R.flag & R_ZTRA || R.totstrand) {
1007                         if(rl->layflag & (SCE_LAY_ZTRA|SCE_LAY_STRAND)) {
1008                                 if(pa->fullresult.first) {
1009                                         zbuffer_transp_shade(pa, rl, rl->rectf, &psmlist);
1010                                 }
1011                                 else {
1012                                         unsigned short *ztramask, *solidmask= NULL; /* 16 bits, MAX_OSA */
1013                                         
1014                                         /* allocate, but not free here, for asynchronous display of this rect in main thread */
1015                                         rl->acolrect= MEM_callocN(4*sizeof(float)*pa->rectx*pa->recty, "alpha layer");
1016                                         
1017                                         /* swap for live updates, and it is used in zbuf.c!!! */
1018                                         SWAP(float *, rl->acolrect, rl->rectf);
1019                                         ztramask= zbuffer_transp_shade(pa, rl, rl->rectf, &psmlist);
1020                                         SWAP(float *, rl->acolrect, rl->rectf);
1021                                         
1022                                         /* zbuffer transp only returns ztramask if there's solid rendered */
1023                                         if(ztramask)
1024                                                 solidmask= make_solid_mask(pa);
1025
1026                                         if(ztramask && solidmask) {
1027                                                 unsigned short *sps= solidmask, *spz= ztramask;
1028                                                 unsigned short fullmask= (1<<R.osa)-1;
1029                                                 float *fcol= rl->rectf; float *acol= rl->acolrect;
1030                                                 int x;
1031                                                 
1032                                                 for(x=pa->rectx*pa->recty; x>0; x--, acol+=4, fcol+=4, sps++, spz++) {
1033                                                         if(*sps == fullmask)
1034                                                                 addAlphaOverFloat(fcol, acol);
1035                                                         else
1036                                                                 addAlphaOverFloatMask(fcol, acol, *sps, *spz);
1037                                                 }
1038                                         }
1039                                         else {
1040                                                 float *fcol= rl->rectf; float *acol= rl->acolrect;
1041                                                 int x;
1042                                                 for(x=pa->rectx*pa->recty; x>0; x--, acol+=4, fcol+=4) {
1043                                                         addAlphaOverFloat(fcol, acol);
1044                                                 }
1045                                         }
1046                                         if(solidmask) MEM_freeN(solidmask);
1047                                         if(ztramask) MEM_freeN(ztramask);
1048                                 }
1049                         }
1050                 }
1051
1052                 /* sky before edge */
1053                 if(rl->layflag & SCE_LAY_SKY)
1054                         sky_tile(pa, rl);
1055
1056                 /* extra layers */
1057                 if(rl->layflag & SCE_LAY_EDGE) 
1058                         if(R.r.mode & R_EDGE) 
1059                                 edge_enhance_add(pa, rl->rectf, edgerect);
1060                 
1061                 if(rl->passflag & SCE_PASS_VECTOR)
1062                         reset_sky_speed(pa, rl);
1063                 
1064                 /* de-premul alpha */
1065                 if(R.r.alphamode & R_ALPHAKEY)
1066                         convert_to_key_alpha(pa, rl->rectf);
1067                 
1068                 /* free stuff within loop! */
1069                 MEM_freeN(pa->rectdaps); pa->rectdaps= NULL;
1070                 freeps(&psmlist);
1071                 
1072                 if(edgerect) MEM_freeN(edgerect);
1073                 edgerect= NULL;
1074
1075                 if(pa->rectmask) {
1076                         MEM_freeN(pa->rectmask);
1077                         pa->rectmask= NULL;
1078                 }
1079         }
1080         
1081         /* free all */
1082         MEM_freeN(pa->recto); pa->recto= NULL;
1083         MEM_freeN(pa->rectp); pa->rectp= NULL;
1084         MEM_freeN(pa->rectz); pa->rectz= NULL;
1085         
1086         /* display active layer */
1087         rr->renrect.ymin=rr->renrect.ymax= 0;
1088         rr->renlay= render_get_active_layer(&R, rr);
1089 }
1090
1091
1092 /* ------------------------------------------------------------------------ */
1093
1094 /* non OSA case, full tile render */
1095 /* supposed to be fully threadable! */
1096 void zbufshade_tile(RenderPart *pa)
1097 {
1098         ShadeSample ssamp;
1099         RenderResult *rr= pa->result;
1100         RenderLayer *rl;
1101         PixStr ps;
1102         float *edgerect= NULL;
1103         
1104         /* fake pixel struct, to comply to osa render */
1105         ps.next= NULL;
1106         ps.mask= 0xFFFF;
1107         
1108         /* zbuffer code clears/inits rects */
1109         pa->recto= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "recto");
1110         pa->rectp= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectp");
1111         pa->rectz= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectz");
1112
1113         for(rl= rr->layers.first; rl; rl= rl->next) {
1114                 if((rl->layflag & SCE_LAY_ZMASK) && (rl->layflag & SCE_LAY_NEG_ZMASK))
1115                         pa->rectmask= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectmask");
1116
1117                 /* general shader info, passes */
1118                 shade_sample_initialize(&ssamp, pa, rl);
1119                 
1120                 zbuffer_solid(pa, rl, NULL, NULL);
1121                 
1122                 if(!R.test_break()) {   /* NOTE: this if() is not consistant */
1123                         
1124                         /* edges only for solid part, ztransp doesn't support it yet anti-aliased */
1125                         if(rl->layflag & SCE_LAY_EDGE) {
1126                                 if(R.r.mode & R_EDGE) {
1127                                         edgerect= MEM_callocN(sizeof(float)*pa->rectx*pa->recty, "rectedge");
1128                                         edge_enhance_tile(pa, edgerect);
1129                                 }
1130                         }
1131                         
1132                         /* initialize scanline updates for main thread */
1133                         rr->renrect.ymin= 0;
1134                         rr->renlay= rl;
1135                         
1136                         if(rl->layflag & SCE_LAY_SOLID) {
1137                                 float *fcol= rl->rectf;
1138                                 int *ro= pa->recto, *rp= pa->rectp, *rz= pa->rectz;
1139                                 int x, y, offs=0, seed;
1140                                 
1141                                 /* we set per pixel a fixed seed, for random AO and shadow samples */
1142                                 seed= pa->rectx*pa->disprect.ymin;
1143                                 
1144                                 /* irregular shadowb buffer creation */
1145                                 if(R.r.mode & R_SHADOW)
1146                                         ISB_create(pa, NULL);
1147
1148                                 if(R.occlusiontree)
1149                                         cache_occ_samples(&R, pa, &ssamp);
1150                                 
1151                                 for(y=pa->disprect.ymin; y<pa->disprect.ymax; y++, rr->renrect.ymax++) {
1152                                         for(x=pa->disprect.xmin; x<pa->disprect.xmax; x++, ro++, rz++, rp++, fcol+=4, offs++) {
1153                                                 /* per pixel fixed seed */
1154                                                 BLI_thread_srandom(pa->thread, seed++);
1155                                                 
1156                                                 if(*rp) {
1157                                                         ps.obi= *ro;
1158                                                         ps.facenr= *rp;
1159                                                         ps.z= *rz;
1160                                                         if(shade_samples(&ssamp, &ps, x, y)) {
1161                                                                 /* combined and passes */
1162                                                                 add_passes(rl, offs, ssamp.shi, ssamp.shr);
1163                                                         }
1164                                                 }
1165                                         }
1166                                         if(y&1)
1167                                                 if(R.test_break()) break; 
1168                                 }
1169                                 
1170                                 if(R.occlusiontree)
1171                                         free_occ_samples(&R, pa);
1172                                 
1173                                 if(R.r.mode & R_SHADOW)
1174                                         ISB_free(pa);
1175                         }
1176                         
1177                         /* disable scanline updating */
1178                         rr->renlay= NULL;
1179                 }
1180                 
1181                 /* lamphalo after solid, before ztra, looks nicest because ztra does own halo */
1182                 if(R.flag & R_LAMPHALO)
1183                         if(rl->layflag & SCE_LAY_HALO)
1184                                 lamphalo_tile(pa, rl);
1185                 
1186                 /* halo before ztra, because ztra fills in zbuffer now */
1187                 if(R.flag & R_HALO)
1188                         if(rl->layflag & SCE_LAY_HALO)
1189                                 halo_tile(pa, rl);
1190                 
1191                 if(R.flag & R_ZTRA || R.totstrand) {
1192                         if(rl->layflag & (SCE_LAY_ZTRA|SCE_LAY_STRAND)) {
1193                                 float *fcol, *acol;
1194                                 int x;
1195                                 
1196                                 /* allocate, but not free here, for asynchronous display of this rect in main thread */
1197                                 rl->acolrect= MEM_callocN(4*sizeof(float)*pa->rectx*pa->recty, "alpha layer");
1198                                 
1199                                 /* swap for live updates */
1200                                 SWAP(float *, rl->acolrect, rl->rectf);
1201                                 zbuffer_transp_shade(pa, rl, rl->rectf, NULL);
1202                                 SWAP(float *, rl->acolrect, rl->rectf);
1203                                 
1204                                 fcol= rl->rectf; acol= rl->acolrect;
1205                                 for(x=pa->rectx*pa->recty; x>0; x--, acol+=4, fcol+=4) {
1206                                         addAlphaOverFloat(fcol, acol);
1207                                 }
1208                         }
1209                 }
1210                 
1211                 /* sky before edge */
1212                 if(rl->layflag & SCE_LAY_SKY)
1213                         sky_tile(pa, rl);
1214                 
1215                 if(!R.test_break()) {
1216                         if(rl->layflag & SCE_LAY_EDGE) 
1217                                 if(R.r.mode & R_EDGE)
1218                                         edge_enhance_add(pa, rl->rectf, edgerect);
1219                 }
1220                 
1221                 if(rl->passflag & SCE_PASS_VECTOR)
1222                         reset_sky_speed(pa, rl);
1223                 
1224                 /* de-premul alpha */
1225                 if(R.r.alphamode & R_ALPHAKEY)
1226                         convert_to_key_alpha(pa, rl->rectf);
1227                 
1228                 if(edgerect) MEM_freeN(edgerect);
1229                 edgerect= NULL;
1230
1231                 if(pa->rectmask) {
1232                         MEM_freeN(pa->rectmask);
1233                         pa->rectmask= NULL;
1234                 }
1235         }
1236
1237         /* display active layer */
1238         rr->renrect.ymin=rr->renrect.ymax= 0;
1239         rr->renlay= render_get_active_layer(&R, rr);
1240         
1241         MEM_freeN(pa->recto); pa->recto= NULL;
1242         MEM_freeN(pa->rectp); pa->rectp= NULL;
1243         MEM_freeN(pa->rectz); pa->rectz= NULL;
1244 }
1245
1246 /* SSS preprocess tile render, fully threadable */
1247 typedef struct ZBufSSSHandle {
1248         RenderPart *pa;
1249         ListBase psmlist;
1250         int totps;
1251 } ZBufSSSHandle;
1252
1253 static void addps_sss(void *cb_handle, int obi, int facenr, int x, int y, int z)
1254 {
1255         ZBufSSSHandle *handle = cb_handle;
1256         RenderPart *pa= handle->pa;
1257
1258         /* extra border for filter gives double samples on part edges,
1259            don't use those */
1260         if(x<pa->crop || x>=pa->rectx-pa->crop)
1261                 return;
1262         if(y<pa->crop || y>=pa->recty-pa->crop)
1263                 return;
1264         
1265         if(pa->rectall) {
1266                 long *rs= pa->rectall + pa->rectx*y + x;
1267
1268                 addps(&handle->psmlist, rs, obi, facenr, z, 0, 0);
1269                 handle->totps++;
1270         }
1271         if(pa->rectz) {
1272                 int *rz= pa->rectz + pa->rectx*y + x;
1273                 int *rp= pa->rectp + pa->rectx*y + x;
1274                 int *ro= pa->recto + pa->rectx*y + x;
1275
1276                 if(z < *rz) {
1277                         if(*rp == 0)
1278                                 handle->totps++;
1279                         *rz= z;
1280                         *rp= facenr;
1281                         *ro= obi;
1282                 }
1283         }
1284         if(pa->rectbackz) {
1285                 int *rz= pa->rectbackz + pa->rectx*y + x;
1286                 int *rp= pa->rectbackp + pa->rectx*y + x;
1287                 int *ro= pa->rectbacko + pa->rectx*y + x;
1288
1289                 if(z >= *rz) {
1290                         if(*rp == 0)
1291                                 handle->totps++;
1292                         *rz= z;
1293                         *rp= facenr;
1294                         *ro= obi;
1295                 }
1296         }
1297 }
1298
1299 static void shade_sample_sss(ShadeSample *ssamp, Material *mat, ObjectInstanceRen *obi, VlakRen *vlr, int quad, float x, float y, float z, float *co, float *color, float *area)
1300 {
1301         ShadeInput *shi= ssamp->shi;
1302         ShadeResult shr;
1303         float texfac, orthoarea, nor[3], alpha;
1304
1305         /* cache for shadow */
1306         shi->samplenr= R.shadowsamplenr[shi->thread]++;
1307         
1308         if(quad) 
1309                 shade_input_set_triangle_i(shi, obi, vlr, 0, 2, 3);
1310         else
1311                 shade_input_set_triangle_i(shi, obi, vlr, 0, 1, 2);
1312
1313         /* center pixel */
1314         x += 0.5f;
1315         y += 0.5f;
1316
1317         /* we estimate the area here using shi->dxco and shi->dyco. we need to
1318            enabled shi->osatex these are filled. we compute two areas, one with
1319            the normal pointed at the camera and one with the original normal, and
1320            then clamp to avoid a too large contribution from a single pixel */
1321         shi->osatex= 1;
1322
1323         VECCOPY(nor, shi->facenor);
1324         calc_view_vector(shi->facenor, x, y);
1325         Normalize(shi->facenor);
1326         shade_input_set_viewco(shi, x, y, z);
1327         orthoarea= VecLength(shi->dxco)*VecLength(shi->dyco);
1328
1329         VECCOPY(shi->facenor, nor);
1330         shade_input_set_viewco(shi, x, y, z);
1331         *area= VecLength(shi->dxco)*VecLength(shi->dyco);
1332         *area= MIN2(*area, 2.0f*orthoarea);
1333
1334         shade_input_set_uv(shi);
1335         shade_input_set_normals(shi);
1336
1337         /* we don't want flipped normals, they screw up back scattering */
1338         if(shi->flippednor)
1339                 shade_input_flip_normals(shi);
1340
1341         /* not a pretty solution, but fixes common cases */
1342         if(shi->obr->ob && shi->obr->ob->transflag & OB_NEG_SCALE) {
1343                 VecMulf(shi->vn, -1.0f);
1344                 VecMulf(shi->vno, -1.0f);
1345         }
1346
1347         /* if nodetree, use the material that we are currently preprocessing
1348            instead of the node material */
1349         if(shi->mat->nodetree && shi->mat->use_nodes)
1350                 shi->mat= mat;
1351
1352         /* init material vars */
1353         // note, keep this synced with render_types.h
1354         memcpy(&shi->r, &shi->mat->r, 23*sizeof(float));
1355         shi->har= shi->mat->har;
1356         
1357         /* render */
1358         shade_input_set_shade_texco(shi);
1359         
1360         shade_samples_do_AO(ssamp);
1361         shade_material_loop(shi, &shr);
1362         
1363         VECCOPY(co, shi->co);
1364         VECCOPY(color, shr.combined);
1365
1366         /* texture blending */
1367         texfac= shi->mat->sss_texfac;
1368
1369         alpha= shr.col[3];
1370         *area *= alpha;
1371
1372         if(texfac == 0.0f) {
1373                 if(shr.col[0]!=0.0f) color[0] *= alpha/shr.col[0];
1374                 if(shr.col[1]!=0.0f) color[1] *= alpha/shr.col[1];
1375                 if(shr.col[2]!=0.0f) color[2] *= alpha/shr.col[2];
1376         }
1377         else if(texfac != 1.0f && (alpha > FLT_EPSILON)) {
1378                 if(shr.col[0]!=0.0f) color[0] *= alpha*pow(shr.col[0]/alpha, texfac)/shr.col[0];
1379                 if(shr.col[1]!=0.0f) color[1] *= alpha*pow(shr.col[1]/alpha, texfac)/shr.col[1];
1380                 if(shr.col[2]!=0.0f) color[2] *= alpha*pow(shr.col[2]/alpha, texfac)/shr.col[2];
1381         }
1382 }
1383
1384 static void zbufshade_sss_free(RenderPart *pa)
1385 {
1386 #if 0
1387         MEM_freeN(pa->rectall); pa->rectall= NULL;
1388         freeps(&handle.psmlist);
1389 #else
1390         MEM_freeN(pa->rectz); pa->rectz= NULL;
1391         MEM_freeN(pa->rectp); pa->rectp= NULL;
1392         MEM_freeN(pa->recto); pa->recto= NULL;
1393         MEM_freeN(pa->rectbackz); pa->rectbackz= NULL;
1394         MEM_freeN(pa->rectbackp); pa->rectbackp= NULL;
1395         MEM_freeN(pa->rectbacko); pa->rectbacko= NULL;
1396 #endif
1397 }
1398
1399 void zbufshade_sss_tile(RenderPart *pa)
1400 {
1401         Render *re= &R;
1402         ShadeSample ssamp;
1403         ZBufSSSHandle handle;
1404         RenderResult *rr= pa->result;
1405         RenderLayer *rl;
1406         VlakRen *vlr;
1407         Material *mat= re->sss_mat;
1408         float (*co)[3], (*color)[3], *area, *fcol;
1409         int x, y, seed, quad, totpoint, display = !(re->r.scemode & R_PREVIEWBUTS);
1410         int *ro, *rz, *rp, *rbo, *rbz, *rbp, lay;
1411 #if 0
1412         PixStr *ps;
1413         long *rs;
1414         int z;
1415 #endif
1416
1417         /* setup pixelstr list and buffer for zbuffering */
1418         handle.pa= pa;
1419         handle.totps= 0;
1420
1421 #if 0
1422         handle.psmlist.first= handle.psmlist.last= NULL;
1423         addpsmain(&handle.psmlist);
1424
1425         pa->rectall= MEM_callocN(sizeof(long)*pa->rectx*pa->recty+4, "rectall");
1426 #else
1427         pa->recto= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "recto");
1428         pa->rectp= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectp");
1429         pa->rectz= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectz");
1430         pa->rectbacko= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectbacko");
1431         pa->rectbackp= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectbackp");
1432         pa->rectbackz= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectbackz");
1433 #endif
1434
1435         /* setup shade sample with correct passes */
1436         memset(&ssamp, 0, sizeof(ssamp));
1437         shade_sample_initialize(&ssamp, pa, rr->layers.first);
1438         ssamp.tot= 1;
1439         
1440         for(rl=rr->layers.first; rl; rl=rl->next) {
1441                 ssamp.shi[0].lay |= rl->lay;
1442                 ssamp.shi[0].layflag |= rl->layflag;
1443                 ssamp.shi[0].passflag |= rl->passflag;
1444                 ssamp.shi[0].combinedflag |= ~rl->pass_xor;
1445         }
1446
1447         rl= rr->layers.first;
1448         ssamp.shi[0].passflag |= SCE_PASS_RGBA|SCE_PASS_COMBINED;
1449         ssamp.shi[0].combinedflag &= ~(SCE_PASS_SPEC);
1450         lay= ssamp.shi[0].lay;
1451
1452         /* create the pixelstrs to be used later */
1453         zbuffer_sss(pa, lay, &handle, addps_sss);
1454
1455         if(handle.totps==0) {
1456                 zbufshade_sss_free(pa);
1457                 return;
1458         }
1459         
1460         fcol= rl->rectf;
1461
1462         co= MEM_mallocN(sizeof(float)*3*handle.totps, "SSSCo");
1463         color= MEM_mallocN(sizeof(float)*3*handle.totps, "SSSColor");
1464         area= MEM_mallocN(sizeof(float)*handle.totps, "SSSArea");
1465
1466 #if 0
1467         /* create ISB (does not work currently!) */
1468         if(re->r.mode & R_SHADOW)
1469                 ISB_create(pa, NULL);
1470 #endif
1471
1472         if(display) {
1473                 /* initialize scanline updates for main thread */
1474                 rr->renrect.ymin= 0;
1475                 rr->renlay= rl;
1476         }
1477         
1478         seed= pa->rectx*pa->disprect.ymin;
1479 #if 0
1480         rs= pa->rectall;
1481 #else
1482         rz= pa->rectz;
1483         rp= pa->rectp;
1484         ro= pa->recto;
1485         rbz= pa->rectbackz;
1486         rbp= pa->rectbackp;
1487         rbo= pa->rectbacko;
1488 #endif
1489         totpoint= 0;
1490
1491         for(y=pa->disprect.ymin; y<pa->disprect.ymax; y++, rr->renrect.ymax++) {
1492                 for(x=pa->disprect.xmin; x<pa->disprect.xmax; x++, fcol+=4) {
1493                         /* per pixel fixed seed */
1494                         BLI_thread_srandom(pa->thread, seed++);
1495                         
1496 #if 0
1497                         if(rs) {
1498                                 /* for each sample in this pixel, shade it */
1499                                 for(ps=(PixStr*)*rs; ps; ps=ps->next) {
1500                                         ObjectInstanceRen *obi= &re->objectinstance[ps->obi];
1501                                         ObjectRen *obr= obi->obr;
1502                                         vlr= RE_findOrAddVlak(obr, (ps->facenr-1) & RE_QUAD_MASK);
1503                                         quad= (ps->facenr & RE_QUAD_OFFS);
1504                                         z= ps->z;
1505
1506                                         shade_sample_sss(&ssamp, mat, obi, vlr, quad, x, y, z,
1507                                                 co[totpoint], color[totpoint], &area[totpoint]);
1508
1509                                         totpoint++;
1510
1511                                         VECADD(fcol, fcol, color);
1512                                         fcol[3]= 1.0f;
1513                                 }
1514
1515                                 rs++;
1516                         }
1517 #else
1518                         if(rp) {
1519                                 if(*rp != 0) {
1520                                         ObjectInstanceRen *obi= &re->objectinstance[*ro];
1521                                         ObjectRen *obr= obi->obr;
1522
1523                                         /* shade front */
1524                                         vlr= RE_findOrAddVlak(obr, (*rp-1) & RE_QUAD_MASK);
1525                                         quad= ((*rp) & RE_QUAD_OFFS);
1526
1527                                         shade_sample_sss(&ssamp, mat, obi, vlr, quad, x, y, *rz,
1528                                                 co[totpoint], color[totpoint], &area[totpoint]);
1529                                         
1530                                         VECADD(fcol, fcol, color[totpoint]);
1531                                         fcol[3]= 1.0f;
1532                                         totpoint++;
1533                                 }
1534
1535                                 rp++; rz++; ro++;
1536                         }
1537
1538                         if(rbp) {
1539                                 if(*rbp != 0 && !(*rbp == *(rp-1) && *rbo == *(ro-1))) {
1540                                         ObjectInstanceRen *obi= &re->objectinstance[*rbo];
1541                                         ObjectRen *obr= obi->obr;
1542
1543                                         /* shade back */
1544                                         vlr= RE_findOrAddVlak(obr, (*rbp-1) & RE_QUAD_MASK);
1545                                         quad= ((*rbp) & RE_QUAD_OFFS);
1546
1547                                         shade_sample_sss(&ssamp, mat, obi, vlr, quad, x, y, *rbz,
1548                                                 co[totpoint], color[totpoint], &area[totpoint]);
1549                                         
1550                                         /* to indicate this is a back sample */
1551                                         area[totpoint]= -area[totpoint];
1552
1553                                         VECADD(fcol, fcol, color[totpoint]);
1554                                         fcol[3]= 1.0f;
1555                                         totpoint++;
1556                                 }
1557
1558                                 rbz++; rbp++; rbo++;
1559                         }
1560 #endif
1561                 }
1562
1563                 if(y&1)
1564                         if(re->test_break()) break; 
1565         }
1566
1567         /* note: after adding we do not free these arrays, sss keeps them */
1568         if(totpoint > 0) {
1569                 sss_add_points(re, co, color, area, totpoint);
1570         }
1571         else {
1572                 MEM_freeN(co);
1573                 MEM_freeN(color);
1574                 MEM_freeN(area);
1575         }
1576         
1577 #if 0
1578         if(re->r.mode & R_SHADOW)
1579                 ISB_free(pa);
1580 #endif
1581                 
1582         if(display) {
1583                 /* display active layer */
1584                 rr->renrect.ymin=rr->renrect.ymax= 0;
1585                 rr->renlay= render_get_active_layer(&R, rr);
1586         }
1587         
1588         zbufshade_sss_free(pa);
1589 }
1590
1591 /* ------------------------------------------------------------------------ */
1592
1593 static void renderhalo_post(RenderResult *rr, float *rectf, HaloRen *har)       /* postprocess version */
1594 {
1595         float dist, xsq, ysq, xn, yn, colf[4], *rectft, *rtf;
1596         float haloxs, haloys;
1597         int minx, maxx, miny, maxy, x, y;
1598
1599         /* calculate the disprect mapped coordinate for halo. note: rectx is disprect corrected */
1600         haloxs= har->xs - R.disprect.xmin;
1601         haloys= har->ys - R.disprect.ymin;
1602         
1603         har->miny= miny= haloys - har->rad/R.ycor;
1604         har->maxy= maxy= haloys + har->rad/R.ycor;
1605         
1606         if(maxy<0);
1607         else if(rr->recty<miny);
1608         else {
1609                 minx= floor(haloxs-har->rad);
1610                 maxx= ceil(haloxs+har->rad);
1611                         
1612                 if(maxx<0);
1613                 else if(rr->rectx<minx);
1614                 else {
1615                 
1616                         if(minx<0) minx= 0;
1617                         if(maxx>=rr->rectx) maxx= rr->rectx-1;
1618                         if(miny<0) miny= 0;
1619                         if(maxy>rr->recty) maxy= rr->recty;
1620         
1621                         rectft= rectf+ 4*rr->rectx*miny;
1622
1623                         for(y=miny; y<maxy; y++) {
1624         
1625                                 rtf= rectft+4*minx;
1626                                 
1627                                 yn= (y - haloys)*R.ycor;
1628                                 ysq= yn*yn;
1629                                 
1630                                 for(x=minx; x<=maxx; x++) {
1631                                         xn= x - haloxs;
1632                                         xsq= xn*xn;
1633                                         dist= xsq+ysq;
1634                                         if(dist<har->radsq) {
1635                                                 
1636                                                 if(shadeHaloFloat(har, colf, 0x7FFFFF, dist, xn, yn, har->flarec))
1637                                                         addalphaAddfacFloat(rtf, colf, har->add);
1638                                         }
1639                                         rtf+=4;
1640                                 }
1641         
1642                                 rectft+= 4*rr->rectx;
1643                                 
1644                                 if(R.test_break()) break; 
1645                         }
1646                 }
1647         }
1648
1649 /* ------------------------------------------------------------------------ */
1650
1651 static void renderflare(RenderResult *rr, float *rectf, HaloRen *har)
1652 {
1653         extern float hashvectf[];
1654         HaloRen fla;
1655         Material *ma;
1656         float *rc, rad, alfa, visifac, vec[3];
1657         int b, type;
1658         
1659         fla= *har;
1660         fla.linec= fla.ringc= fla.flarec= 0;
1661         
1662         rad= har->rad;
1663         alfa= har->alfa;
1664         
1665         visifac= R.ycor*(har->pixels);
1666         /* all radials added / r^3  == 1.0f! */
1667         visifac /= (har->rad*har->rad*har->rad);
1668         visifac*= visifac;
1669
1670         ma= har->mat;
1671         
1672         /* first halo: just do */
1673         
1674         har->rad= rad*ma->flaresize*visifac;
1675         har->radsq= har->rad*har->rad;
1676         har->zs= fla.zs= 0;
1677         
1678         har->alfa= alfa*visifac;
1679
1680         renderhalo_post(rr, rectf, har);
1681         
1682         /* next halo's: the flares */
1683         rc= hashvectf + ma->seed2;
1684         
1685         for(b=1; b<har->flarec; b++) {
1686                 
1687                 fla.r= fabs(rc[0]);
1688                 fla.g= fabs(rc[1]);
1689                 fla.b= fabs(rc[2]);
1690                 fla.alfa= ma->flareboost*fabs(alfa*visifac*rc[3]);
1691                 fla.hard= 20.0f + fabs(70*rc[7]);
1692                 fla.tex= 0;
1693                 
1694                 type= (int)(fabs(3.9*rc[6]));
1695
1696                 fla.rad= ma->subsize*sqrt(fabs(2.0f*har->rad*rc[4]));
1697                 
1698                 if(type==3) {
1699                         fla.rad*= 3.0f;
1700                         fla.rad+= R.rectx/10;
1701                 }
1702                 
1703                 fla.radsq= fla.rad*fla.rad;
1704                 
1705                 vec[0]= 1.4*rc[5]*(har->xs-R.winx/2);
1706                 vec[1]= 1.4*rc[5]*(har->ys-R.winy/2);
1707                 vec[2]= 32.0f*sqrt(vec[0]*vec[0] + vec[1]*vec[1] + 1.0f);
1708                 
1709                 fla.xs= R.winx/2 + vec[0] + (1.2+rc[8])*R.rectx*vec[0]/vec[2];
1710                 fla.ys= R.winy/2 + vec[1] + (1.2+rc[8])*R.rectx*vec[1]/vec[2];
1711
1712                 if(R.flag & R_SEC_FIELD) {
1713                         if(R.r.mode & R_ODDFIELD) fla.ys += 0.5;
1714                         else fla.ys -= 0.5;
1715                 }
1716                 if(type & 1) fla.type= HA_FLARECIRC;
1717                 else fla.type= 0;
1718                 renderhalo_post(rr, rectf, &fla);
1719
1720                 fla.alfa*= 0.5;
1721                 if(type & 2) fla.type= HA_FLARECIRC;
1722                 else fla.type= 0;
1723                 renderhalo_post(rr, rectf, &fla);
1724                 
1725                 rc+= 7;
1726         }
1727 }
1728
1729 /* needs recode... integrate this better! */
1730 void add_halo_flare(Render *re)
1731 {
1732         RenderResult *rr= re->result;
1733         RenderLayer *rl;
1734         HaloRen *har;
1735         int a, mode, do_draw=0;
1736         
1737         /* for now, we get the first renderlayer in list with halos set */
1738         for(rl= rr->layers.first; rl; rl= rl->next)
1739                 if(rl->layflag & SCE_LAY_HALO)
1740                         break;
1741
1742         if(rl==NULL || rl->rectf==NULL)
1743                 return;
1744         
1745         mode= R.r.mode;
1746         R.r.mode &= ~R_PANORAMA;
1747         
1748         project_renderdata(&R, projectverto, 0, 0, 0);
1749         
1750         for(a=0; a<R.tothalo; a++) {
1751                 har= R.sortedhalos[a];
1752                 
1753                 if(har->flarec) {
1754                         do_draw= 1;
1755                         renderflare(rr, rl->rectf, har);
1756                 }
1757         }
1758
1759         if(do_draw) {
1760                 /* weak... the display callback wants an active renderlayer pointer... */
1761                 rr->renlay= rl;
1762                 re->display_draw(rr, NULL);
1763         }
1764         
1765         R.r.mode= mode; 
1766 }
1767
1768 /* ************************* used for shaded view ************************ */
1769
1770 /* if *re, then initialize, otherwise execute */
1771 void RE_shade_external(Render *re, ShadeInput *shi, ShadeResult *shr)
1772 {
1773         static VlakRen vlr;
1774         static ObjectRen obr;
1775         static ObjectInstanceRen obi;
1776         
1777         /* init */
1778         if(re) {
1779                 R= *re;
1780                 
1781                 /* fake render face */
1782                 memset(&vlr, 0, sizeof(VlakRen));
1783                 memset(&obr, 0, sizeof(ObjectRen));
1784                 memset(&obi, 0, sizeof(ObjectInstanceRen));
1785                 obr.lay= -1;
1786                 obi.obr= &obr;
1787                 
1788                 return;
1789         }
1790         shi->vlr= &vlr;
1791         shi->obr= &obr;
1792         shi->obi= &obi;
1793         
1794         if(shi->mat->nodetree && shi->mat->use_nodes)
1795                 ntreeShaderExecTree(shi->mat->nodetree, shi, shr);
1796         else {
1797                 /* copy all relevant material vars, note, keep this synced with render_types.h */
1798                 memcpy(&shi->r, &shi->mat->r, 23*sizeof(float));
1799                 shi->har= shi->mat->har;
1800                 
1801                 shade_material_loop(shi, shr);
1802         }
1803 }
1804
1805 /* ************************* bake ************************ */
1806
1807 #define FTOCHAR(val) val<=0.0f?0: (val>=1.0f?255: (char)(255.0f*val))
1808
1809 typedef struct BakeShade {
1810         ShadeSample ssamp;
1811         ObjectInstanceRen *obi;
1812         VlakRen *vlr;
1813         
1814         ZSpan *zspan;
1815         Image *ima;
1816         ImBuf *ibuf;
1817         
1818         int rectx, recty, quad, type, vdone, ready;
1819
1820         float dir[3];
1821         Object *actob;
1822         
1823         unsigned int *rect;
1824         float *rect_float;
1825         
1826         int usemask;
1827         char *rect_mask; /* bake pixel mask */
1828
1829         float dxco[3], dyco[3];
1830 } BakeShade;
1831
1832 /* bake uses a char mask to know what has been baked */
1833 #define BAKE_MASK_NULL          0
1834 #define BAKE_MASK_MARGIN        1
1835 #define BAKE_MASK_BAKED         2
1836 static void bake_mask_filter_extend( char *mask, int width, int height )
1837 {
1838         char *row1, *row2, *row3;
1839         int rowlen, x, y;
1840         char *temprect;
1841         
1842         rowlen= width;
1843         
1844         /* make a copy, to prevent flooding */
1845         temprect= MEM_dupallocN(mask);
1846         
1847         for(y=1; y<=height; y++) {
1848                 /* setup rows */
1849                 row1= (char *)(temprect + (y-2)*rowlen);
1850                 row2= row1 + rowlen;
1851                 row3= row2 + rowlen;
1852                 if(y==1)
1853                         row1= row2;
1854                 else if(y==height)
1855                         row3= row2;
1856                 
1857                 for(x=0; x<rowlen; x++) {
1858                         if (mask[((y-1)*rowlen)+x]==0) {
1859                                 if (*row1 || *row2 || *row3 || *(row1+1) || *(row3+1) ) {
1860                                         mask[((y-1)*rowlen)+x] = BAKE_MASK_MARGIN;
1861                                 } else if((x!=rowlen-1) && (*(row1+2) || *(row2+2) || *(row3+2)) ) {
1862                                         mask[((y-1)*rowlen)+x] = BAKE_MASK_MARGIN;
1863                                 }
1864                         }
1865                         
1866                         if(x!=0) {
1867                                 row1++; row2++; row3++;
1868                         }
1869                 }
1870         }
1871         MEM_freeN(temprect);
1872 }
1873
1874 static void bake_mask_clear( ImBuf *ibuf, char *mask, char val )
1875 {
1876         int x,y;
1877         if (ibuf->rect_float) {
1878                 for(x=0; x<ibuf->x; x++) {
1879                         for(y=0; y<ibuf->y; y++) {
1880                                 if (mask[ibuf->x*y + x] == val) {
1881                                         float *col= ibuf->rect_float + 4*(ibuf->x*y + x);
1882                                         col[0] = col[1] = col[2] = col[3] = 0.0f;
1883                                 }
1884                         }
1885                 }
1886                 
1887         } else {
1888                 /* char buffer */
1889                 for(x=0; x<ibuf->x; x++) {
1890                         for(y=0; y<ibuf->y; y++) {
1891                                 if (mask[ibuf->x*y + x] == val) {
1892                                         char *col= (char *)(ibuf->rect + ibuf->x*y + x);
1893                                         col[0] = col[1] = col[2] = col[3] = 0;
1894                                 }
1895                         }
1896                 }
1897         }
1898 }
1899
1900 static void bake_set_shade_input(ObjectInstanceRen *obi, VlakRen *vlr, ShadeInput *shi, int quad, int isect, int x, int y, float u, float v)
1901 {
1902         if(isect) {
1903                 /* raytrace intersection with different u,v than scanconvert */
1904                 if(vlr->v4) {
1905                         if(quad)
1906                                 shade_input_set_triangle_i(shi, obi, vlr, 2, 1, 3);
1907                         else
1908                                 shade_input_set_triangle_i(shi, obi, vlr, 0, 1, 3);
1909                 }
1910                 else
1911                         shade_input_set_triangle_i(shi, obi, vlr, 0, 1, 2);
1912         }
1913         else {
1914                 /* regular scanconvert */
1915                 if(quad) 
1916                         shade_input_set_triangle_i(shi, obi, vlr, 0, 2, 3);
1917                 else
1918                         shade_input_set_triangle_i(shi, obi, vlr, 0, 1, 2);
1919         }
1920                 
1921         /* cache for shadow */
1922         shi->samplenr= R.shadowsamplenr[shi->thread]++;
1923
1924         shi->mask= 0xFFFF; /* all samples */
1925         
1926         shi->u= -u;
1927         shi->v= -v;
1928         shi->xs= x;
1929         shi->ys= y;
1930         
1931         shade_input_set_uv(shi);
1932         shade_input_set_normals(shi);
1933
1934         /* no normal flip */
1935         if(shi->flippednor)
1936                 shade_input_flip_normals(shi);
1937
1938         /* set up view vector to look right at the surface (note that the normal
1939          * is negated in the renderer so it does not need to be done here) */
1940         shi->view[0]= shi->vn[0];
1941         shi->view[1]= shi->vn[1];
1942         shi->view[2]= shi->vn[2];
1943 }
1944
1945 static void bake_shade(void *handle, Object *ob, ShadeInput *shi, int quad, int x, int y, float u, float v, float *tvn, float *ttang)
1946 {
1947         BakeShade *bs= handle;
1948         ShadeSample *ssamp= &bs->ssamp;
1949         ShadeResult shr;
1950         VlakRen *vlr= shi->vlr;
1951         
1952         /* init material vars */
1953         memcpy(&shi->r, &shi->mat->r, 23*sizeof(float));        // note, keep this synced with render_types.h
1954         shi->har= shi->mat->har;
1955         
1956         if(bs->type==RE_BAKE_AO) {
1957                 ambient_occlusion(shi);
1958
1959                 if(R.r.bake_flag & R_BAKE_NORMALIZE)
1960                         VECCOPY(shr.combined, shi->ao)
1961                 else
1962                         ambient_occlusion_to_diffuse(shi, shr.combined);
1963         }
1964         else {
1965                 shade_input_set_shade_texco(shi);
1966                 
1967                 if(!ELEM(bs->type, RE_BAKE_NORMALS, RE_BAKE_TEXTURE))
1968                         shade_samples_do_AO(ssamp);
1969                 
1970                 if(shi->mat->nodetree && shi->mat->use_nodes) {
1971                         ntreeShaderExecTree(shi->mat->nodetree, shi, &shr);
1972                         shi->mat= vlr->mat;             /* shi->mat is being set in nodetree */
1973                 }
1974                 else
1975                         shade_material_loop(shi, &shr);
1976                 
1977                 if(bs->type==RE_BAKE_NORMALS) {
1978                         float nor[3];
1979
1980                         VECCOPY(nor, shi->vn);
1981
1982                         if(R.r.bake_normal_space == R_BAKE_SPACE_CAMERA);
1983                         else if(R.r.bake_normal_space == R_BAKE_SPACE_TANGENT) {
1984                                 float mat[3][3], imat[3][3];
1985
1986                                 /* bitangent */
1987                                 if(tvn && ttang) {
1988                                         VECCOPY(mat[0], ttang);
1989                                         Crossf(mat[1], tvn, ttang);
1990                                         VECCOPY(mat[2], tvn);
1991                                 }
1992                                 else {
1993                                         VECCOPY(mat[0], shi->nmaptang);
1994                                         Crossf(mat[1], shi->vn, shi->nmaptang);
1995                                         VECCOPY(mat[2], shi->vn);
1996                                 }
1997
1998                                 Mat3Inv(imat, mat);
1999                                 Mat3MulVecfl(imat, nor);
2000                         }
2001                         else if(R.r.bake_normal_space == R_BAKE_SPACE_OBJECT)
2002                                 Mat4Mul3Vecfl(ob->imat, nor); /* ob->imat includes viewinv! */
2003                         else if(R.r.bake_normal_space == R_BAKE_SPACE_WORLD)
2004                                 Mat4Mul3Vecfl(R.viewinv, nor);
2005
2006                         Normalize(nor); /* in case object has scaling */
2007
2008                         shr.combined[0]= nor[0]/2.0f + 0.5f;
2009                         shr.combined[1]= 0.5f - nor[1]/2.0f;
2010                         shr.combined[2]= nor[2]/2.0f + 0.5f;
2011                 }
2012                 else if(bs->type==RE_BAKE_TEXTURE) {
2013                         shr.combined[0]= shi->r;
2014                         shr.combined[1]= shi->g;
2015                         shr.combined[2]= shi->b;
2016                         shr.alpha = shi->alpha;
2017                 }
2018         }
2019         
2020         if(bs->rect_float) {
2021                 float *col= bs->rect_float + 4*(bs->rectx*y + x);
2022                 VECCOPY(col, shr.combined);
2023                 if (bs->type==RE_BAKE_ALL || bs->type==RE_BAKE_TEXTURE) {
2024                         col[3]= shr.alpha;
2025                 } else {
2026                         col[3]= 1.0;
2027                 }
2028         }
2029         else {
2030                 char *col= (char *)(bs->rect + bs->rectx*y + x);
2031                 col[0]= FTOCHAR(shr.combined[0]);
2032                 col[1]= FTOCHAR(shr.combined[1]);
2033                 col[2]= FTOCHAR(shr.combined[2]);
2034                 
2035                 
2036                 if (bs->type==RE_BAKE_ALL || bs->type==RE_BAKE_TEXTURE) {
2037                         col[3]= FTOCHAR(shr.alpha);
2038                 } else {
2039                         col[3]= 255;
2040                 }
2041         }
2042         
2043         if (bs->rect_mask) {
2044                 bs->rect_mask[bs->rectx*y + x] = BAKE_MASK_BAKED;
2045         }
2046 }
2047
2048 static void bake_displacement(void *handle, ShadeInput *shi, float dist, int x, int y)
2049 {
2050         BakeShade *bs= handle;
2051         float disp;
2052         
2053         if(R.r.bake_flag & R_BAKE_NORMALIZE && R.r.bake_maxdist) {
2054                 disp = (dist+R.r.bake_maxdist) / (R.r.bake_maxdist*2); /* alter the range from [-bake_maxdist, bake_maxdist] to [0, 1]*/
2055         } else {
2056                 disp = 0.5 + dist; /* alter the range from [-0.5,0.5] to [0,1]*/
2057         }
2058         
2059         if(bs->rect_float) {
2060                 float *col= bs->rect_float + 4*(bs->rectx*y + x);
2061                 col[0] = col[1] = col[2] = disp;
2062                 col[3]= 1.0f;
2063         } else {        
2064                 char *col= (char *)(bs->rect + bs->rectx*y + x);
2065                 col[0]= FTOCHAR(disp);
2066                 col[1]= FTOCHAR(disp);
2067                 col[2]= FTOCHAR(disp);
2068                 col[3]= 255;
2069         }
2070         if (bs->rect_mask) {
2071                 bs->rect_mask[bs->rectx*y + x] = BAKE_MASK_BAKED;
2072         }
2073 }
2074
2075 static int bake_check_intersect(Isect *is, int ob, RayFace *face)
2076 {
2077         BakeShade *bs = (BakeShade*)is->userdata;
2078         
2079         /* no direction checking for now, doesn't always improve the result
2080          * (INPR(shi->facenor, bs->dir) > 0.0f); */
2081
2082         return (R.objectinstance[ob].obr->ob != bs->actob);
2083 }
2084
2085 static int bake_intersect_tree(RayTree* raytree, Isect* isect, float *start, float *dir, float sign, float *hitco, float *dist)
2086 {
2087         float maxdist;
2088         int hit;
2089
2090         /* might be useful to make a user setting for maxsize*/
2091         if(R.r.bake_maxdist > 0.0f)
2092                 maxdist= R.r.bake_maxdist;
2093         else
2094                 maxdist= RE_ray_tree_max_size(R.raytree) + R.r.bake_biasdist;
2095         
2096         VECADDFAC(isect->start, start, dir, -R.r.bake_biasdist);
2097
2098         isect->end[0] = isect->start[0] + dir[0]*maxdist*sign;
2099         isect->end[1] = isect->start[1] + dir[1]*maxdist*sign;
2100         isect->end[2] = isect->start[2] + dir[2]*maxdist*sign;
2101
2102         hit = RE_ray_tree_intersect_check(R.raytree, isect, bake_check_intersect);
2103         if(hit) {
2104                 hitco[0] = isect->start[0] + isect->labda*isect->vec[0];
2105                 hitco[1] = isect->start[1] + isect->labda*isect->vec[1];
2106                 hitco[2] = isect->start[2] + isect->labda*isect->vec[2];
2107
2108                 *dist= VecLenf(start, hitco);
2109         }
2110
2111         return hit;
2112 }
2113
2114 static void bake_set_vlr_dxyco(BakeShade *bs, float *uv1, float *uv2, float *uv3)
2115 {
2116         VlakRen *vlr= bs->vlr;
2117         float A, d1, d2, d3, *v1, *v2, *v3;
2118
2119         if(bs->quad) {
2120                 v1= vlr->v1->co;
2121                 v2= vlr->v3->co;
2122                 v3= vlr->v4->co;
2123         }
2124         else {
2125                 v1= vlr->v1->co;
2126                 v2= vlr->v2->co;
2127                 v3= vlr->v3->co;
2128         }
2129
2130         /* formula derived from barycentric coordinates:
2131          * (uvArea1*v1 + uvArea2*v2 + uvArea3*v3)/uvArea
2132          * then taking u and v partial derivatives to get dxco and dyco */
2133         A= (uv2[0] - uv1[0])*(uv3[1] - uv1[1]) - (uv3[0] - uv1[0])*(uv2[1] - uv1[1]);
2134
2135         if(fabs(A) > FLT_EPSILON) {
2136                 A= 0.5f/A;
2137
2138                 d1= uv2[1] - uv3[1];
2139                 d2= uv3[1] - uv1[1];
2140                 d3= uv1[1] - uv2[1];
2141                 bs->dxco[0]= (v1[0]*d1 + v2[0]*d2 + v3[0]*d3)*A;
2142                 bs->dxco[1]= (v1[1]*d1 + v2[1]*d2 + v3[1]*d3)*A;
2143                 bs->dxco[2]= (v1[2]*d1 + v2[2]*d2 + v3[2]*d3)*A;
2144
2145                 d1= uv3[0] - uv2[0];
2146                 d2= uv1[0] - uv3[0];
2147                 d3= uv2[0] - uv1[0];
2148                 bs->dyco[0]= (v1[0]*d1 + v2[0]*d2 + v3[0]*d3)*A;
2149                 bs->dyco[1]= (v1[1]*d1 + v2[1]*d2 + v3[1]*d3)*A;
2150                 bs->dyco[2]= (v1[2]*d1 + v2[2]*d2 + v3[2]*d3)*A;
2151         }
2152         else {
2153                 bs->dxco[0]= bs->dxco[1]= bs->dxco[2]= 0.0f;
2154                 bs->dyco[0]= bs->dyco[1]= bs->dyco[2]= 0.0f;
2155         }
2156
2157         if(bs->obi->flag & R_TRANSFORMED) {
2158                 Mat3MulVecfl(bs->obi->nmat, bs->dxco);
2159                 Mat3MulVecfl(bs->obi->nmat, bs->dyco);
2160         }
2161 }
2162
2163 static void do_bake_shade(void *handle, int x, int y, float u, float v)
2164 {
2165         BakeShade *bs= handle;
2166         VlakRen *vlr= bs->vlr;
2167         ObjectInstanceRen *obi= bs->obi;
2168         Object *ob= obi->obr->ob;
2169         float l, *v1, *v2, *v3, tvn[3], ttang[3];
2170         int quad;
2171         ShadeSample *ssamp= &bs->ssamp;
2172         ShadeInput *shi= ssamp->shi;
2173         
2174         /* fast threadsafe break test */
2175         if(R.test_break())
2176                 return;
2177         
2178         /* setup render coordinates */
2179         if(bs->quad) {
2180                 v1= vlr->v1->co;
2181                 v2= vlr->v3->co;
2182                 v3= vlr->v4->co;
2183         }
2184         else {
2185                 v1= vlr->v1->co;
2186                 v2= vlr->v2->co;
2187                 v3= vlr->v3->co;
2188         }
2189         
2190         /* renderco */
2191         l= 1.0f-u-v;
2192         
2193         shi->co[0]= l*v3[0]+u*v1[0]+v*v2[0];
2194         shi->co[1]= l*v3[1]+u*v1[1]+v*v2[1];
2195         shi->co[2]= l*v3[2]+u*v1[2]+v*v2[2];
2196         
2197         if(obi->flag & R_TRANSFORMED)
2198                 Mat4MulVecfl(obi->mat, shi->co);
2199         
2200         VECCOPY(shi->dxco, bs->dxco);
2201         VECCOPY(shi->dyco, bs->dyco);
2202
2203         quad= bs->quad;
2204         bake_set_shade_input(obi, vlr, shi, quad, 0, x, y, u, v);
2205
2206         if(bs->type==RE_BAKE_NORMALS && R.r.bake_normal_space==R_BAKE_SPACE_TANGENT) {
2207                 shade_input_set_shade_texco(shi);
2208                 VECCOPY(tvn, shi->vn);
2209                 VECCOPY(ttang, shi->nmaptang);
2210         }
2211
2212         /* if we are doing selected to active baking, find point on other face */
2213         if(bs->actob) {
2214                 Isect isec, minisec;
2215                 float co[3], minco[3], dist, mindist=0.0f;
2216                 int hit, sign, dir=1;
2217                 
2218                 /* intersect with ray going forward and backward*/
2219                 hit= 0;
2220                 memset(&minisec, 0, sizeof(minisec));
2221                 minco[0]= minco[1]= minco[2]= 0.0f;
2222                 
2223                 VECCOPY(bs->dir, shi->vn);
2224                 
2225                 for(sign=-1; sign<=1; sign+=2) {
2226                         memset(&isec, 0, sizeof(isec));
2227                         isec.mode= RE_RAY_MIRROR;
2228                         isec.faceorig= (RayFace*)vlr;
2229                         isec.oborig= RAY_OBJECT_SET(&R, obi);
2230                         isec.userdata= bs;
2231                         
2232                         if(bake_intersect_tree(R.raytree, &isec, shi->co, shi->vn, sign, co, &dist)) {
2233                                 if(!hit || VecLenf(shi->co, co) < VecLenf(shi->co, minco)) {
2234                                         minisec= isec;
2235                                         mindist= dist;
2236                                         VECCOPY(minco, co);
2237                                         hit= 1;
2238                                         dir = sign;
2239                                 }
2240                         }
2241                 }
2242
2243                 if (hit && bs->type==RE_BAKE_DISPLACEMENT) {;
2244                         bake_displacement(handle, shi, (dir==-1)? mindist:-mindist, x, y);
2245                         return;
2246                 }
2247
2248                 /* if hit, we shade from the new point, otherwise from point one starting face */
2249                 if(hit) {
2250                         vlr= (VlakRen*)minisec.face;
2251                         obi= RAY_OBJECT_GET(&R, minisec.ob);
2252                         quad= (minisec.isect == 2);
2253                         VECCOPY(shi->co, minco);
2254                         
2255                         u= -minisec.u;
2256                         v= -minisec.v;
2257                         bake_set_shade_input(obi, vlr, shi, quad, 1, x, y, u, v);
2258                 }
2259         }
2260
2261         if(bs->type==RE_BAKE_NORMALS && R.r.bake_normal_space==R_BAKE_SPACE_TANGENT)
2262                 bake_shade(handle, ob, shi, quad, x, y, u, v, tvn, ttang);
2263         else
2264                 bake_shade(handle, ob, shi, quad, x, y, u, v, 0, 0);
2265 }
2266
2267 static int get_next_bake_face(BakeShade *bs)
2268 {
2269         ObjectRen *obr;
2270         VlakRen *vlr;
2271         MTFace *tface;
2272         static int v= 0, vdone= 0;
2273         static ObjectInstanceRen *obi= NULL;
2274         
2275         if(bs==NULL) {
2276                 vlr= NULL;
2277                 v= vdone= 0;
2278                 obi= R.instancetable.first;
2279                 return 0;
2280         }
2281         
2282         BLI_lock_thread(LOCK_CUSTOM1);  
2283
2284         for(; obi; obi=obi->next, v=0) {
2285                 obr= obi->obr;
2286
2287                 for(; v<obr->totvlak; v++) {
2288                         vlr= RE_findOrAddVlak(obr, v);
2289
2290                         if((bs->actob && bs->actob == obr->ob) || (!bs->actob && (obr->ob->flag & SELECT))) {
2291                                 tface= RE_vlakren_get_tface(obr, vlr, obr->actmtface, NULL, 0);
2292
2293                                 if(tface && tface->tpage) {
2294                                         Image *ima= tface->tpage;
2295                                         ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL);
2296                                         float vec[4]= {0.0f, 0.0f, 0.0f, 0.0f};
2297                                         
2298                                         if(ibuf==NULL)
2299                                                 continue;
2300                                         
2301                                         if(ibuf->rect==NULL && ibuf->rect_float==NULL)
2302                                                 continue;
2303                                         
2304                                         if(ibuf->rect_float && !(ibuf->channels==0 || ibuf->channels==4))
2305                                                 continue;
2306                                         
2307                                         /* find the image for the first time? */
2308                                         if(ima->id.flag & LIB_DOIT) {
2309                                                 ima->id.flag &= ~LIB_DOIT;
2310                                                 
2311                                                 /* we either fill in float or char, this ensures things go fine */
2312                                                 if(ibuf->rect_float)
2313                                                         imb_freerectImBuf(ibuf);
2314                                                 /* clear image */
2315                                                 if(R.r.bake_flag & R_BAKE_CLEAR)
2316                                                         IMB_rectfill(ibuf, vec);
2317                                         
2318                                                 /* might be read by UI to set active image for display */
2319                                                 R.bakebuf= ima;
2320                                         }                               
2321                                         
2322                                         bs->obi= obi;
2323                                         bs->vlr= vlr;
2324                                         
2325                                         bs->vdone++;    /* only for error message if nothing was rendered */
2326                                         v++;
2327                                         
2328                                         BLI_unlock_thread(LOCK_CUSTOM1);
2329                                         return 1;
2330                                 }
2331                         }
2332                 }
2333         }
2334         
2335         BLI_unlock_thread(LOCK_CUSTOM1);
2336         return 0;
2337 }
2338
2339 /* already have tested for tface and ima and zspan */
2340 static void shade_tface(BakeShade *bs)
2341 {
2342         VlakRen *vlr= bs->vlr;
2343         ObjectInstanceRen *obi= bs->obi;
2344         ObjectRen *obr= obi->obr;
2345         MTFace *tface= RE_vlakren_get_tface(obr, vlr, obr->actmtface, NULL, 0);
2346         Image *ima= tface->tpage;
2347         float vec[4][2];
2348         int a, i1, i2, i3;
2349         
2350         /* check valid zspan */
2351         if(ima!=bs->ima) {
2352                 bs->ima= ima;
2353                 bs->ibuf= BKE_image_get_ibuf(ima, NULL);
2354                 /* note, these calls only free/fill contents of zspan struct, not zspan itself */
2355                 zbuf_free_span(bs->zspan);
2356                 zbuf_alloc_span(bs->zspan, bs->ibuf->x, bs->ibuf->y, R.clipcrop);
2357         }                               
2358         
2359         bs->rectx= bs->ibuf->x;
2360         bs->recty= bs->ibuf->y;
2361         bs->rect= bs->ibuf->rect;
2362         bs->rect_float= bs->ibuf->rect_float;
2363         bs->quad= 0;
2364         
2365         if (bs->usemask) {
2366                 if (bs->ibuf->userdata==NULL) {
2367                         BLI_lock_thread(LOCK_CUSTOM1);
2368                         if (bs->ibuf->userdata==NULL) { /* since the thread was locked, its possible another thread alloced the value */
2369                                 bs->ibuf->userdata = (void *)MEM_callocN(sizeof(char)*bs->rectx*bs->recty, "BakeMask");
2370                                 bs->rect_mask= (char *)bs->ibuf->userdata;
2371                         }
2372                         BLI_unlock_thread(LOCK_CUSTOM1);
2373                 } else {
2374                         bs->rect_mask= (char *)bs->ibuf->userdata;
2375                 }
2376         }
2377         
2378         /* get pixel level vertex coordinates */
2379         for(a=0; a<4; a++) {
2380                 vec[a][0]= tface->uv[a][0]*(float)bs->rectx - 0.5f;
2381                 vec[a][1]= tface->uv[a][1]*(float)bs->recty - 0.5f;
2382         }
2383         
2384         /* UV indices have to be corrected for possible quad->tria splits */
2385         i1= 0; i2= 1; i3= 2;
2386         vlr_set_uv_indices(vlr, &i1, &i2, &i3);
2387         bake_set_vlr_dxyco(bs, vec[i1], vec[i2], vec[i3]);
2388         zspan_scanconvert(bs->zspan, bs, vec[i1], vec[i2], vec[i3], do_bake_shade);
2389         
2390         if(vlr->v4) {
2391                 bs->quad= 1;
2392                 bake_set_vlr_dxyco(bs, vec[0], vec[2], vec[3]);
2393                 zspan_scanconvert(bs->zspan, bs, vec[0], vec[2], vec[3], do_bake_shade);
2394         }
2395 }
2396
2397 static void *do_bake_thread(void *bs_v)
2398 {
2399         BakeShade *bs= bs_v;
2400         
2401         while(get_next_bake_face(bs)) {
2402                 shade_tface(bs);
2403                 
2404                 /* fast threadsafe break test */
2405                 if(R.test_break())
2406                         break;
2407         }
2408         bs->ready= 1;
2409         
2410         return NULL;
2411 }
2412
2413 /* using object selection tags, the faces with UV maps get baked */
2414 /* render should have been setup */
2415 /* returns 0 if nothing was handled */
2416 int RE_bake_shade_all_selected(Render *re, int type, Object *actob)
2417 {
2418         BakeShade handles[BLENDER_MAX_THREADS];
2419         ListBase threads;
2420         Image *ima;
2421         int a, vdone=0, usemask=0;
2422         
2423         /* initialize render global */
2424         R= *re;
2425         R.bakebuf= NULL;
2426         
2427         /* initialize static vars */
2428         get_next_bake_face(NULL);
2429         
2430         /* do we need a mask? */
2431         if (re->r.bake_filter && (re->r.bake_flag & R_BAKE_CLEAR)==0)
2432                 usemask = 1;
2433         
2434         /* baker uses this flag to detect if image was initialized */
2435         for(ima= G.main->image.first; ima; ima= ima->id.next) {
2436                 ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL);
2437                 ima->id.flag |= LIB_DOIT;
2438                 if (ibuf)
2439                         ibuf->userdata = NULL; /* use for masking if needed */
2440         }
2441         
2442         BLI_init_threads(&threads, do_bake_thread, re->r.threads);
2443
2444         /* get the threads running */
2445         for(a=0; a<re->r.threads; a++) {
2446                 /* set defaults in handles */
2447                 memset(&handles[a], 0, sizeof(BakeShade));
2448                 
2449                 handles[a].ssamp.shi[0].lay= re->scene->lay;
2450                 handles[a].ssamp.shi[0].passflag= SCE_PASS_COMBINED;
2451                 handles[a].ssamp.shi[0].combinedflag= ~(SCE_PASS_SPEC);
2452                 handles[a].ssamp.shi[0].thread= a;
2453                 handles[a].ssamp.tot= 1;
2454                 
2455                 handles[a].type= type;
2456                 handles[a].actob= actob;
2457                 handles[a].zspan= MEM_callocN(sizeof(ZSpan), "zspan for bake");
2458                 
2459                 handles[a].usemask = usemask;
2460                 
2461                 BLI_insert_thread(&threads, &handles[a]);
2462         }
2463         
2464         /* wait for everything to be done */
2465         a= 0;
2466         while(a!=re->r.threads) {
2467                 
2468                 PIL_sleep_ms(50);
2469
2470                 for(a=0; a<re->r.threads; a++)
2471                         if(handles[a].ready==0)
2472                                 break;
2473         }
2474         
2475         /* filter and refresh images */
2476         for(ima= G.main->image.first; ima; ima= ima->id.next) {
2477                 if((ima->id.flag & LIB_DOIT)==0) {
2478                         ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL);
2479                         if (re->r.bake_filter) {
2480                                 if (usemask) {
2481                                         /* extend the mask +2 pixels from the image,
2482                                          * this is so colors dont blend in from outside */
2483                                         char *temprect;
2484                                         
2485                                         for(a=0; a<re->r.bake_filter; a++)
2486                                                 bake_mask_filter_extend((char *)ibuf->userdata, ibuf->x, ibuf->y);
2487                                         
2488                                         temprect = MEM_dupallocN(ibuf->userdata);
2489                                         
2490                                         /* expand twice to clear this many pixels, so they blend back in */
2491                                         bake_mask_filter_extend(temprect, ibuf->x, ibuf->y);
2492                                         bake_mask_filter_extend(temprect, ibuf->x, ibuf->y);
2493                                         
2494                                         /* clear all pixels in the margin*/
2495                                         bake_mask_clear(ibuf, temprect, BAKE_MASK_MARGIN);
2496                                         MEM_freeN(temprect);
2497                                 }
2498                                 
2499                                 for(a=0; a<re->r.bake_filter; a++) {
2500                                         /*the mask, ibuf->userdata - can be null, in this case only zero alpha is used */
2501                                         IMB_filter_extend(ibuf, (char *)ibuf->userdata);
2502                                 }
2503                                 
2504                                 if (ibuf->userdata) {
2505                                         MEM_freeN(ibuf->userdata);
2506                                         ibuf->userdata= NULL;
2507                                 }
2508                         }
2509                         ibuf->userflags |= IB_BITMAPDIRTY;
2510                         if (ibuf->rect_float) IMB_rect_from_float(ibuf);
2511                 }
2512         }
2513         
2514         /* calculate return value */
2515         for(a=0; a<re->r.threads; a++) {
2516                 vdone+= handles[a].vdone;
2517                 
2518                 zbuf_free_span(handles[a].zspan);
2519                 MEM_freeN(handles[a].zspan);
2520         }
2521         
2522         BLI_end_threads(&threads);
2523         return vdone;
2524 }
2525
2526 struct Image *RE_bake_shade_get_image(void)
2527 {
2528         return R.bakebuf;
2529 }
2530