be1f659d7e6cae437c42667698a6eef7f116b84a
[blender.git] / source / blender / render / intern / source / initrender.c
1 /**
2  * $Id$
3  *
4  * ***** BEGIN GPL/BL DUAL 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. The Blender
10  * Foundation also sells licenses for use in proprietary software under
11  * the Blender License.  See http://www.blender.org/BL/ for information
12  * about this.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software Foundation,
21  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22  *
23  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
24  * All rights reserved.
25  *
26  * The Original Code is: all of this file.
27  *
28  * Contributor(s): none yet.
29  *
30  * ***** END GPL/BL DUAL LICENSE BLOCK *****
31  */
32
33
34 /* Global includes */
35
36 #include <math.h>
37 #include <stdlib.h>
38 #include <string.h>
39 #include <stdio.h>
40
41 #ifdef HAVE_CONFIG_H
42 #include <config.h>
43 #endif
44
45 #ifdef WIN32
46 #include "BLI_winstuff.h"
47 #endif
48
49 #include "blendef.h"
50 #include "MEM_guardedalloc.h"
51
52 #include "PIL_time.h"
53
54 #include "BLI_arithb.h"
55 #include "BLI_blenlib.h"
56 #include "BLI_rand.h"
57
58 #include "MTC_matrixops.h"
59
60 #include "DNA_image_types.h"
61 #include "DNA_camera_types.h"
62 #include "DNA_lamp_types.h"
63 #include "DNA_scene_types.h"
64 #include "DNA_object_types.h"
65
66 #include "BKE_utildefines.h"
67 #include "BKE_global.h"
68 #include "BKE_material.h"
69 #include "BKE_object.h"
70 #include "BKE_image.h"
71 #include "BKE_ipo.h"
72 #include "BKE_key.h"
73 #include "BKE_ika.h"
74 #include "BKE_action.h"
75 #include "BKE_writeavi.h"
76 #include "BKE_scene.h"
77
78 #include "BIF_toolbox.h"
79 #include "BIF_writeavicodec.h"
80 #include "BIF_writemovie.h"             /* start_movie(), append_movie(), end_movie() */
81
82 #include "BSE_drawview.h"
83 #include "BSE_sequence.h"
84
85 #ifdef WITH_QUICKTIME
86 #include "quicktime_export.h"
87 #endif
88
89 /* this module */
90 #include "render.h"
91 #include "render_intern.h"
92
93 #include "RE_callbacks.h"
94 #include "zbuf.h"
95 #include "rendercore.h" /* part handler for the old renderer, shading functions */
96 #include "renderPreAndPost.h"
97 #include "vanillaRenderPipe.h"
98 #include "renderHelp.h"
99 #include "jitter.h"
100
101 /* Own includes */
102 #include "initrender.h"
103
104 /* yafray: include for yafray export/render */
105 #include "YafRay_Api.h"
106
107 /* Some crud :/ */
108 #define ELEM3(a, b, c, d)       ( ELEM(a, b, c) || (a)==(d) )
109
110
111 /* from render.c */
112 extern float fmask[256], centLut[16], *fmask1[9], *fmask2[9];
113 extern unsigned short *mask1[9], *mask2[9], *igamtab2;
114 extern char cmask[256], *centmask;
115
116 Material defmaterial;
117 short pa; /* pa is global part, for print */
118 short allparts[65][4];
119 int qscount;
120
121 /* ********************* *********************** */
122
123
124 void init_def_material(void)
125 {
126         Material *ma;
127
128         ma= &defmaterial;
129         
130         init_material(&defmaterial);
131
132         init_render_material(ma);
133 }
134
135 void RE_init_render_data(void)
136 {
137         memset(&R, 0, sizeof(RE_Render));
138         memset(&O, 0, sizeof(Osa));
139         O.dxwin[0]= 1.0;
140         O.dywin[1]= 1.0;
141         
142         R.blove= (VertRen **)MEM_callocN(sizeof(void *)*(TABLEINITSIZE),"Blove");
143         R.blovl= (VlakRen **)MEM_callocN(sizeof(void *)*(TABLEINITSIZE),"Blovl");
144         R.bloha= (HaloRen **)MEM_callocN(sizeof(void *)*(TABLEINITSIZE),"Bloha");
145         R.la= (LampRen **)MEM_mallocN(LAMPINITSIZE*sizeof(void *),"renderlamparray");
146
147         init_def_material();
148 }
149
150 void RE_free_render_data()
151 {
152         MEM_freeN(R.blove);
153         R.blove= 0;
154         MEM_freeN(R.blovl);
155         R.blovl= 0;
156         MEM_freeN(R.bloha);
157         R.bloha= 0;
158         MEM_freeN(R.la);
159         R.la= 0;
160         if(R.rectot) MEM_freeN(R.rectot);
161         if(R.rectz) MEM_freeN(R.rectz);
162         if(R.rectspare) MEM_freeN(R.rectspare);
163         R.rectot= 0;
164         R.rectz= 0;
165         R.rectspare= 0;
166
167         end_render_material(&defmaterial);
168 }
169
170 /* ****************** GAMMA, MASKS and LUTS **************** */
171
172 float  calc_weight(float *weight, int i, int j)
173 {
174         float x, y, dist, totw= 0.0, fac;
175         int a;
176
177         fac= R.r.gauss*R.r.gauss;
178         fac*= fac;
179
180         for(a=0; a<R.osa; a++) {
181                 x= jit[a][0] + i;
182                 y= jit[a][1] + j;
183                 dist= sqrt(x*x+y*y);
184
185                 weight[a]= 0.0;
186
187                 /* gaussian weighting */
188                 if(R.r.mode & R_GAUSS) {
189                         if(dist<R.r.gauss) {
190                                 x = dist*R.r.gauss;
191                                 weight[a]= (1.0/exp(x*x) - 1.0/exp(fac));
192                         }
193                 }
194                 else {
195                         if(i==0 && j==0) weight[a]= 1.0;
196                 }
197
198                 totw+= weight[a];
199
200         }
201         return totw;
202 }
203
204 void RE_init_filt_mask(void)
205 {
206         static int firsttime=1;
207         static int lastosa=0;
208         static int lastgauss=0;
209         static float lastgamma= 0.0;
210         float gamma, igamma, flweight[32];
211         float weight[32], totw, val, *fpx1, *fpx2, *fpy1, *fpy2, *m3, *m4;
212         int i, j, a;
213         unsigned short *m1, *m2, shweight[32];
214
215         if(firsttime) {
216                 firsttime= 0;
217                 
218                 for(a=0; a<9;a++) {
219                         mask1[a]= MEM_mallocN(256*sizeof(short), "initfilt");
220                         mask2[a]= MEM_mallocN(256*sizeof(short), "initfilt");
221                         fmask1[a]= MEM_mallocN(256*sizeof(float), "initfilt");
222                         fmask2[a]= MEM_mallocN(256*sizeof(float), "initfilt");
223                 }
224                 for(a=0; a<256; a++) {
225                         cmask[a]= 0;
226                         if(a &   1) cmask[a]++;
227                         if(a &   2) cmask[a]++;
228                         if(a &   4) cmask[a]++;
229                         if(a &   8) cmask[a]++;
230                         if(a &  16) cmask[a]++;
231                         if(a &  32) cmask[a]++;
232                         if(a &  64) cmask[a]++;
233                         if(a & 128) cmask[a]++;
234                 }
235                 centmask= MEM_mallocN(65536, "Initfilt3");
236                 for(a=0; a<16; a++) {
237                         centLut[a]= -0.45+((float)a)/16.0;
238                 }
239
240                 gamtab= MEM_mallocN(65536*sizeof(short), "initGaus2");
241                 igamtab1= MEM_mallocN(256*sizeof(short), "initGaus2");
242                 igamtab2= MEM_mallocN(65536*sizeof(short), "initGaus2");
243                 
244                 return; // this case is called on startup
245         }
246
247         if(R.r.alphamode==R_ALPHAKEY) gamma= 1.0;       /* gamma correction of alpha is nasty */
248
249         if(R.r.mode & R_GAMMA) gamma= 2.0;
250         else gamma= 1.0;
251         igamma= 1.0/gamma;
252
253         if(gamma!= lastgamma) {
254                 lastgamma= gamma;
255
256                 /* gamtab: in short, out short */
257                 for(a=0; a<65536; a++) {
258                         val= a;
259                         val/= 65535.0;
260
261                         if(gamma==2.0) val= sqrt(val);
262                         else if(gamma!=1.0) val= pow(val, igamma);
263
264                         gamtab[a]= (65535.99*val);
265                 }
266                 /* inverse gamtab1 : in byte, out short */
267                 for(a=1; a<=256; a++) {
268                         if(gamma==2.0) igamtab1[a-1]= a*a-1;
269                         else if(gamma==1.0) igamtab1[a-1]= 256*a-1;
270                         else {
271                                 val= a/256.0;
272                                 igamtab1[a-1]= (65535.0*pow(val, gamma)) -1 ;
273                         }
274                 }
275
276                 /* inverse gamtab2 : in short, out short */
277                 for(a=0; a<65536; a++) {
278                         val= a;
279                         val/= 65535.0;
280                         if(gamma==2.0) val= val*val;
281                         else val= pow(val, gamma);
282
283                         igamtab2[a]= 65535.0*val;
284                 }
285         }
286
287         if(R.osa && (lastosa!=R.osa || lastgauss != (R.r.mode & R_GAUSS)) ) {
288                 lastosa= R.osa;
289                 lastgauss= R.r.mode & R_GAUSS;
290                         
291                 val= 1.0/((float)R.osa);
292                 for(a=0; a<256; a++) {
293                         fmask[a]= ((float)cmask[a])*val;
294                 }
295
296                 for(a=0; a<9;a++) {
297                         memset(mask1[a], 0, 256*2);
298                         memset(mask2[a], 0, 256*2);
299                         memset(fmask1[a], 0, 256*4);
300                         memset(fmask2[a], 0, 256*4);
301                 }
302
303                 /* calculate totw */
304                 totw= 0.0;
305                 for(j= -1; j<2; j++) {
306                         for(i= -1; i<2; i++) {
307                                 totw+= calc_weight(weight, i, j);
308                         }
309                 }
310
311                 for(j= -1; j<2; j++) {
312                         for(i= -1; i<2; i++) {
313                                 /* calculate using jit, with offset the weights */
314
315                                 memset(weight, 0, sizeof(weight));
316                                 calc_weight(weight, i, j);
317
318                                 for(a=0; a<16; a++) shweight[a]= weight[a]*(65535.0/totw);
319                                 for(a=0; a<16; a++) flweight[a]= weight[a]*(1.0/totw);
320
321                                 m1= mask1[ 3*(j+1)+i+1 ];
322                                 m2= mask2[ 3*(j+1)+i+1 ];
323                                 m3= fmask1[ 3*(j+1)+i+1 ];
324                                 m4= fmask2[ 3*(j+1)+i+1 ];
325
326                                 for(a=0; a<256; a++) {
327                                         if(a &   1) {
328                                                 m1[a]+= shweight[0];
329                                                 m2[a]+= shweight[8];
330                                                 m3[a]+= flweight[0];
331                                                 m4[a]+= flweight[8];
332                                         }
333                                         if(a &   2) {
334                                                 m1[a]+= shweight[1];
335                                                 m2[a]+= shweight[9];
336                                                 m3[a]+= flweight[1];
337                                                 m4[a]+= flweight[9];
338                                         }
339                                         if(a &   4) {
340                                                 m1[a]+= shweight[2];
341                                                 m2[a]+= shweight[10];
342                                                 m3[a]+= flweight[2];
343                                                 m4[a]+= flweight[10];
344                                         }
345                                         if(a &   8) {
346                                                 m1[a]+= shweight[3];
347                                                 m2[a]+= shweight[11];
348                                                 m3[a]+= flweight[3];
349                                                 m4[a]+= flweight[11];
350                                         }
351                                         if(a &  16) {
352                                                 m1[a]+= shweight[4];
353                                                 m2[a]+= shweight[12];
354                                                 m3[a]+= flweight[4];
355                                                 m4[a]+= flweight[12];
356                                         }
357                                         if(a &  32) {
358                                                 m1[a]+= shweight[5];
359                                                 m2[a]+= shweight[13];
360                                                 m3[a]+= flweight[5];
361                                                 m4[a]+= flweight[13];
362                                         }
363                                         if(a &  64) {
364                                                 m1[a]+= shweight[6];
365                                                 m2[a]+= shweight[14];
366                                                 m3[a]+= flweight[6];
367                                                 m4[a]+= flweight[14];
368                                         }
369                                         if(a & 128) {
370                                                 m1[a]+= shweight[7];
371                                                 m2[a]+= shweight[15];
372                                                 m3[a]+= flweight[7];
373                                                 m4[a]+= flweight[15];
374                                         }
375                                 }
376                         }
377                 }
378
379                 /* centmask: the correct subpixel offset per mask */
380
381                 fpx1= MEM_mallocN(256*sizeof(float), "initgauss4");
382                 fpx2= MEM_mallocN(256*sizeof(float), "initgauss4");
383                 fpy1= MEM_mallocN(256*sizeof(float), "initgauss4");
384                 fpy2= MEM_mallocN(256*sizeof(float), "initgauss4");
385                 for(a=0; a<256; a++) {
386                         fpx1[a]= fpx2[a]= 0.0;
387                         fpy1[a]= fpy2[a]= 0.0;
388                         if(a & 1) {
389                                 fpx1[a]+= jit[0][0];
390                                 fpy1[a]+= jit[0][1];
391                                 fpx2[a]+= jit[8][0];
392                                 fpy2[a]+= jit[8][1];
393                         }
394                         if(a & 2) {
395                                 fpx1[a]+= jit[1][0];
396                                 fpy1[a]+= jit[1][1];
397                                 fpx2[a]+= jit[9][0];
398                                 fpy2[a]+= jit[9][1];
399                         }
400                         if(a & 4) {
401                                 fpx1[a]+= jit[2][0];
402                                 fpy1[a]+= jit[2][1];
403                                 fpx2[a]+= jit[10][0];
404                                 fpy2[a]+= jit[10][1];
405                         }
406                         if(a & 8) {
407                                 fpx1[a]+= jit[3][0];
408                                 fpy1[a]+= jit[3][1];
409                                 fpx2[a]+= jit[11][0];
410                                 fpy2[a]+= jit[11][1];
411                         }
412                         if(a & 16) {
413                                 fpx1[a]+= jit[4][0];
414                                 fpy1[a]+= jit[4][1];
415                                 fpx2[a]+= jit[12][0];
416                                 fpy2[a]+= jit[12][1];
417                         }
418                         if(a & 32) {
419                                 fpx1[a]+= jit[5][0];
420                                 fpy1[a]+= jit[5][1];
421                                 fpx2[a]+= jit[13][0];
422                                 fpy2[a]+= jit[13][1];
423                         }
424                         if(a & 64) {
425                                 fpx1[a]+= jit[6][0];
426                                 fpy1[a]+= jit[6][1];
427                                 fpx2[a]+= jit[14][0];
428                                 fpy2[a]+= jit[14][1];
429                         }
430                         if(a & 128) {
431                                 fpx1[a]+= jit[7][0];
432                                 fpy1[a]+= jit[7][1];
433                                 fpx2[a]+= jit[15][0];
434                                 fpy2[a]+= jit[15][1];
435                         }
436                 }
437
438                 for(a= (1<<R.osa)-1; a>0; a--) {
439                         val= count_mask(a);
440                         i= 8+(15.9*(fpy1[a & 255]+fpy2[a>>8])/val);
441                         CLAMP(i, 0, 15);
442                         j= 8+(15.9*(fpx1[a & 255]+fpx2[a>>8])/val);
443                         CLAMP(j, 0, 15);
444                         i= j + (i<<4);
445                         centmask[a]= i;
446                 }
447
448                 MEM_freeN(fpx1);
449                 MEM_freeN(fpx2);
450                 MEM_freeN(fpy1);
451                 MEM_freeN(fpy2);
452         }
453 }
454
455 void RE_free_filt_mask()
456 {
457         int a;
458
459         for(a=0; a<9; a++) {
460                 MEM_freeN(mask1[a]);
461                 MEM_freeN(mask2[a]);
462                 MEM_freeN(fmask1[a]);
463                 MEM_freeN(fmask2[a]);
464         }
465         MEM_freeN(gamtab);
466         MEM_freeN(igamtab1);
467         MEM_freeN(igamtab2);
468
469         MEM_freeN(centmask);
470 }
471
472 /* add stuff */
473
474
475 void defaultlamp()
476 {
477         LampRen *lar;
478
479         lar= (LampRen *)MEM_callocN(sizeof(LampRen),"lampren");
480         R.la[R.totlamp++]=lar;
481
482         lar->type= LA_SUN;
483         lar->vec[0]= -R.viewmat[2][0];
484         lar->vec[1]= -R.viewmat[2][1];
485         lar->vec[2]= -R.viewmat[2][2];
486         Normalise(lar->vec);
487         lar->r= 1.0;
488         lar->g= 1.0;
489         lar->b= 1.0;
490         lar->lay= 65535;
491 }
492
493
494 /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
495
496 void RE_make_existing_file(char *name)
497 {
498         char di[FILE_MAXDIR], fi[FILE_MAXFILE];
499
500         strcpy(di, name);
501         BLI_splitdirstring(di, fi);
502
503         /* test exist */
504         if (BLI_exists(di) == 0) {
505                 BLI_recurdir_fileops(di);
506         }
507 }
508
509
510 /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
511
512 void RE_setwindowclip(int mode, int jmode)
513 {
514         extern float bluroffsx, bluroffsy;      // rendercore.c... hackish (ton)
515         Camera *cam=0;
516         float lens, minx, miny, maxx, maxy;
517         float xd, yd, afmx, afmy;
518
519         if(G.scene->camera==0) return;
520
521         afmx= R.afmx;
522         afmy= R.afmy;
523
524         if(mode) {
525
526                 if(G.scene->camera->type==OB_LAMP) {
527                         /* fac= cos( PI*((float)(256- la->spsi))/512.0 ); */
528
529                         /* phi= acos(fac); */
530                         /* lens= 16.0*fac/sin(phi); */
531                         lens= 35.0;
532                         R.near= 0.1;
533                         R.far= 1000.0;
534                 }
535                 else if(G.scene->camera->type==OB_CAMERA) {
536                         cam= G.scene->camera->data;
537
538                         lens= cam->lens;
539                         R.near= cam->clipsta;
540                         R.far= cam->clipend;
541                 }
542                 else {
543                         lens= 16.0;
544                 }
545
546                 if( (R.r.xasp*afmx) >= (R.r.yasp*afmy) ) {
547                         R.viewfac= (afmx*lens)/16.0;
548                 }
549                 else {
550                         R.viewfac= R.ycor*(afmy*lens)/16.0;
551                 }
552                 if(R.r.mode & R_ORTHO) {
553                         R.near*= 100.0; 
554                         R.viewfac*= 100.0;
555                 }
556
557                 R.pixsize= R.near/R.viewfac;
558
559         }
560
561         /* revision / simplification of subpixel offsets:
562            - the matrix will go without offset from start (e.g. -100) to end (e.g. +99).
563            - filling in with zbuffer will set offset of 0.5. to make sure clipped faces fill in too
564            - in shadepixel() again that 0.5 offset is corrected
565         */
566         minx= R.xstart; 
567         miny= R.ycor*(R.ystart); 
568         maxx= R.xend; 
569         maxy= R.ycor*(R.yend); 
570            
571         if(R.flag & R_SEC_FIELD) {
572                 if(R.r.mode & R_ODDFIELD) {
573                         miny-= .5*R.ycor;
574                         maxy-= .5*R.ycor;
575                 }
576                 else {
577                         miny+= .5*R.ycor;
578                         maxy+= .5*R.ycor;
579                 }
580         }
581
582         xd= yd= 0.0;
583         if(jmode!= -1) {
584                 bluroffsx= xd= jit[jmode % R.osa][0];
585                 bluroffsy= yd= R.ycor*jit[jmode % R.osa][1];
586         }
587         else bluroffsx=bluroffsy= 0.0;
588
589         minx= R.pixsize*(minx+xd);
590         maxx= R.pixsize*(maxx+xd);
591         miny= R.pixsize*(miny+yd);
592         maxy= R.pixsize*(maxy+yd);
593
594         if(R.r.mode & R_ORTHO) {
595                 i_window(minx, maxx, miny, maxy, R.near, 100.0*R.far, R.winmat);
596         }
597         else i_window(minx, maxx, miny, maxy, R.near, R.far, R.winmat);
598
599 }
600
601
602 /* ~~~~~~~~~~~~~~~~ PARTS ~~~~~~~~~~~~~~~~~~~~~~ */
603
604 #define PART_EMPTY      -2
605
606 void initparts()
607 {
608         short nr, xd, yd, xpart, ypart, xparts, yparts;
609         short a, xminb, xmaxb, yminb, ymaxb;
610
611         if(R.r.mode & R_BORDER) {
612                 xminb= R.r.border.xmin*R.rectx;
613                 xmaxb= R.r.border.xmax*R.rectx;
614
615                 yminb= R.r.border.ymin*R.recty;
616                 ymaxb= R.r.border.ymax*R.recty;
617
618                 if(xminb<0) xminb= 0;
619                 if(xmaxb>R.rectx) xmaxb= R.rectx;
620                 if(yminb<0) yminb= 0;
621                 if(ymaxb>R.recty) ymaxb= R.recty;
622         }
623         else {
624                 xminb=yminb= 0;
625                 xmaxb= R.rectx;
626                 ymaxb= R.recty;
627         }
628
629         xparts= R.r.xparts;     /* for border */
630         yparts= R.r.yparts;
631
632         for(nr=0;nr<xparts*yparts;nr++)
633                 allparts[nr][0]= PART_EMPTY;    /* clear array */
634
635         xpart= R.rectx/xparts;
636         ypart= R.recty/yparts;
637
638         /* if border: test if amount of parts can be fewer */
639         if(R.r.mode & R_BORDER) {
640                 a= (xmaxb-xminb-1)/xpart+1; /* amount of parts in border */
641                 if(a<xparts) xparts= a;
642                 a= (ymaxb-yminb-1)/ypart+1; /* amount of parts in border */
643                 if(a<yparts) yparts= a;
644
645                 xpart= (xmaxb-xminb)/xparts;
646                 ypart= (ymaxb-yminb)/yparts;
647         }
648
649         for(nr=0; nr<xparts*yparts; nr++) {
650
651                 if(R.r.mode & R_PANORAMA) {
652                         allparts[nr][0]= 0;
653                         allparts[nr][1]= 0;
654                         allparts[nr][2]= R.rectx;
655                         allparts[nr][3]= R.recty;
656                 }
657                 else {
658                         xd= (nr % xparts);
659                         yd= (nr-xd)/xparts;
660
661                         allparts[nr][0]= xminb+ xd*xpart;
662                         allparts[nr][1]= yminb+ yd*ypart;
663                         if(xd<R.r.xparts-1) allparts[nr][2]= allparts[nr][0]+xpart;
664                         else allparts[nr][2]= xmaxb;
665                         if(yd<R.r.yparts-1) allparts[nr][3]= allparts[nr][1]+ypart;
666                         else allparts[nr][3]= ymaxb;
667
668                         if(allparts[nr][2]-allparts[nr][0]<=0) allparts[nr][0]= PART_EMPTY;
669                         if(allparts[nr][3]-allparts[nr][1]<=0) allparts[nr][0]= PART_EMPTY;
670                         
671                         /* gauss needs 1 pixel extra to work */
672                         if(xparts*yparts>1 && (R.r.mode & R_GAUSS)) {
673                                 allparts[nr][0]-= 1;
674                                 allparts[nr][1]-= 1;
675                                 allparts[nr][2]+= 1;
676                                 allparts[nr][3]+= 1;
677                         }
678                 }
679         }
680         
681 }
682
683 /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
684 short setpart(short nr) /* return 0 if incorrect part */
685 {
686
687         if(allparts[nr][0]== PART_EMPTY) return 0;
688
689         R.xstart= allparts[nr][0]-R.afmx;
690         R.ystart= allparts[nr][1]-R.afmy;
691         R.xend= allparts[nr][2]-R.afmx;
692         R.yend= allparts[nr][3]-R.afmy;
693         R.rectx= R.xend-R.xstart;
694         R.recty= R.yend-R.ystart;
695
696         return 1;
697 }
698
699 /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
700 void addparttorect(short nr, Part *part)
701 {
702         unsigned int *rt, *rp;
703         int y, heigth, len, copylen;
704
705         /* the right offset in rectot */
706
707         rp= part->rect;
708         copylen=len= (allparts[nr][2]-allparts[nr][0]);
709         heigth= (allparts[nr][3]-allparts[nr][1]);
710         
711         if(R.r.mode & R_GAUSS) {
712                 rp+= 1+len;
713                 copylen= len-2;
714                 heigth -= 2;
715                 rt= R.rectot+ (allparts[nr][1] + 1)*R.rectx+ (allparts[nr][0]+1);
716         }
717         else rt= R.rectot+ allparts[nr][1]*R.rectx+ allparts[nr][0];
718
719
720         for(y=0; y<heigth; y++) {
721                 memcpy(rt, rp, 4*copylen);
722                 rt+= R.rectx;
723                 rp+= len;
724         }
725 }
726
727
728 /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
729
730  
731 void add_to_blurbuf(int blur)
732 {
733         static unsigned int *blurrect= 0;
734         int tot, gamval;
735         short facr, facb;
736         char *rtr, *rtb;
737
738         if(blur<0) {
739                 if(blurrect) {
740                         if(R.rectot) MEM_freeN(R.rectot);
741                         R.rectot= blurrect;
742                         blurrect= 0;
743                 }
744         }
745         else if(blur==R.osa-1) {
746                 /* first time */
747                 blurrect= MEM_mallocN(R.rectx*R.recty*sizeof(int), "rectblur");
748                 if(R.rectot) memcpy(blurrect, R.rectot, R.rectx*R.recty*4);
749         }
750         else if(blurrect) {
751                 /* accumulate */
752
753                 facr= 256/(R.osa-blur);
754                 facb= 256-facr;
755
756                 if(R.rectot) {
757                         rtr= (char *)R.rectot;
758                         rtb= (char *)blurrect;
759                         tot= R.rectx*R.recty;
760                         while(tot--) {
761                                 if( *((unsigned int *)rtb) != *((unsigned int *)rtr) ) {
762
763                                         if(R.r.mode & R_GAMMA) {
764                                                 gamval= (facr* igamtab2[ rtr[0]<<8 ] + facb* igamtab2[ rtb[0]<<8 ])>>8;
765                                                 rtb[0]= gamtab[ gamval ]>>8;
766                                                 gamval= (facr* igamtab2[ rtr[1]<<8 ] + facb* igamtab2[ rtb[1]<<8 ])>>8;
767                                                 rtb[1]= gamtab[ gamval ]>>8;
768                                                 gamval= (facr* igamtab2[ rtr[2]<<8 ] + facb* igamtab2[ rtb[2]<<8 ])>>8;
769                                                 rtb[2]= gamtab[ gamval ]>>8;
770                                                 gamval= (facr* igamtab2[ rtr[3]<<8 ] + facb* igamtab2[ rtb[3]<<8 ])>>8;
771                                                 rtb[3]= gamtab[ gamval ]>>8;
772                                         }
773                                         else {
774                                                 rtb[0]= (facr*rtr[0] + facb*rtb[0])>>8;
775                                                 rtb[1]= (facr*rtr[1] + facb*rtb[1])>>8;
776                                                 rtb[2]= (facr*rtr[2] + facb*rtb[2])>>8;
777                                                 rtb[3]= (facr*rtr[3] + facb*rtb[3])>>8;
778                                         }
779                                 }
780                                 rtr+= 4;
781                                 rtb+= 4;
782                         }
783                 }
784                 if(blur==0) {
785                         /* last time */
786                         if(R.rectot) MEM_freeN(R.rectot);
787                         R.rectot= blurrect;
788                         blurrect= 0;
789                 }
790         }
791 }
792
793
794 /* yafray: main yafray render/export call */
795 void yafrayRender()
796 {
797         R.flag |= R_RENDERING;  /* !!! */
798
799         if (R.rectz) MEM_freeN(R.rectz);
800         R.rectz = 0;
801
802         // switch must be done before prepareScene()
803         if (!R.r.YFexportxml)
804                 YAF_switchFile();
805         else
806                 YAF_switchPlugin();
807
808         printf("Starting scene conversion.\n");
809         prepareScene();
810         printf("Scene conversion done.\n");
811
812         YAF_exportScene();
813         finalizeScene();
814 }
815
816
817 /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
818 void render() {
819         /* yafray: render, see above */
820         if (R.r.renderer==R_YAFRAY)
821                 yafrayRender();
822         else
823                 oldRenderLoop();
824 }
825
826
827 void oldRenderLoop(void)  /* here the PART and FIELD loops */
828 {
829         Part *part;
830         unsigned int *rt, *rt1, *rt2;
831         int len, y;
832         short blur, a,fields,fi,parts;  /* pa is a global because of print */
833
834         if (R.rectz) MEM_freeN(R.rectz);
835         R.rectz = 0;
836
837         /* FIELD LOOP */
838         fields= 1;
839         parts= R.r.xparts*R.r.yparts;
840
841         if(R.r.mode & R_FIELDS) {
842                 fields= 2;
843                 R.rectf1= R.rectf2= 0;  /* field rects */
844                 R.r.ysch/= 2;
845                 R.afmy/= 2;
846                 R.r.yasp*= 2;
847                 R.ycor= ( (float)R.r.yasp)/( (float)R.r.xasp);
848
849         }
850
851         
852         for(fi=0; fi<fields; fi++) {
853
854                 /* INIT */
855                 BLI_srand( 2*(G.scene->r.cfra)+fi);
856                         
857                 R.flag|= R_RENDERING;
858                 if(fi==1) R.flag |= R_SEC_FIELD;
859         
860                 /* MOTIONBLUR loop */
861                 if(R.r.mode & R_MBLUR) blur= R.osa;
862                 else blur= 1;
863                 while(blur--) {
864
865                         /* WINDOW */
866                         R.rectx= R.r.xsch;
867                         R.recty= R.r.ysch;
868                         R.xstart= -R.afmx;
869                         R.ystart= -R.afmy;
870                         R.xend= R.xstart+R.rectx-1;
871                         R.yend= R.ystart+R.recty-1;
872
873
874                         if(R.r.mode & R_MBLUR) set_mblur_offs(R.osa-blur);
875
876                         initparts(); /* always do, because of border */
877                         setpart(0);
878
879                         RE_local_init_render_display();
880                         RE_local_clear_render_display(R.win);
881                         RE_local_timecursor((G.scene->r.cfra));
882
883                         prepareScene();
884
885                         /* PARTS */
886                         R.parts.first= R.parts.last= 0;
887                         for(pa=0; pa<parts; pa++) {
888
889                                 if(RE_local_test_break()) break;
890
891                                 if(pa) {        /* because case pa==0 has been done */
892                                         if(setpart(pa)==0) break;
893                                 }
894
895                                 if(R.r.mode & R_MBLUR) RE_setwindowclip(0, blur);
896                                 else RE_setwindowclip(0,-1);
897
898                                 if(R.r.mode & R_PANORAMA) setPanoRot(pa);
899
900                                 /* HOMOGENIC COORDINATES AND ZBUF AND CLIP OPTIMISATION (per part) */
901                                 /* There may be some interference with z-coordinate    */
902                                 /* calculation here?                                   */
903
904                                 doClipping(RE_projectverto);
905                                 if(RE_local_test_break()) break;
906
907
908                                 /* rectot is for result and integer face indices */
909                                 R.rectot= (unsigned int *)MEM_callocN(sizeof(int)*R.rectx*R.recty, "rectot");
910                                 
911                                 if(R.r.mode & R_MBLUR) {
912                                         RE_local_printrenderinfo(0.0, R.osa - blur);
913                                         if(G.background && blur<R.osa) printf("\n"); // newline for percentage print
914                                 }
915                                 else RE_local_printrenderinfo(0.0, -1);
916
917                                 if(R.r.mode & R_UNIFIED) {
918                                         zBufShadeAdvanced();
919                                 }
920                                 else {
921                                         R.rectz =  (unsigned int *)MEM_mallocN(sizeof(int)*R.rectx*R.recty, "rectz");
922
923                                         if(R.r.mode & R_OSA) zbufshadeDA();
924                                         else zbufshade();
925                                 }
926                                 
927                                 /* exception */
928                                 if( (R.r.mode & R_BORDER) && (R.r.mode & R_MOVIECROP));
929                                 else {
930                                         /* HANDLE PART OR BORDER */
931                                         if(parts>1 || (R.r.mode & R_BORDER)) {
932
933                                                 part= MEM_callocN(sizeof(Part), "part");
934                                                 BLI_addtail(&R.parts, part);
935                                                 part->rect= R.rectot;
936                                                 R.rectot= NULL;
937
938                                                 if (R.rectz) {
939                                                         MEM_freeN(R.rectz);
940                                                         R.rectz= NULL;
941                                                 }
942                                         }
943                                 }
944
945                                 if(RE_local_test_break()) break;
946                         }
947
948                         /* JOIN PARTS OR INSERT BORDER */
949
950                         /* exception: crop */
951                         if( (R.r.mode & R_BORDER) && (R.r.mode & R_MOVIECROP)) ;
952                         else {
953                                 R.rectx= R.r.xsch;
954                                 R.recty= R.r.ysch;
955
956                                 if(R.r.mode & R_PANORAMA) R.rectx*= R.r.xparts;
957
958                                 if(parts>1 || (R.r.mode & R_BORDER)) {
959                                         if(R.rectot) MEM_freeN(R.rectot);
960                                         
961                                         R.rectot=(unsigned int *)MEM_callocN(sizeof(int)*R.rectx*R.recty, "rectot");
962                                         
963                                         part= R.parts.first;
964                                         for(pa=0; pa<parts; pa++) {
965                                                 if(allparts[pa][0]== PART_EMPTY) break;
966                                                 if(part==0) break;
967                                                 
968                                                 if(R.r.mode & R_PANORAMA) {
969                                                         if(pa) {
970                                                                 allparts[pa][0] += pa*R.r.xsch;
971                                                                 allparts[pa][2] += pa*R.r.xsch;
972                                                         }
973                                                 }
974                                                 addparttorect(pa, part);
975                                                 
976                                                 part= part->next;
977                                         }
978                                         
979                                         part= R.parts.first;
980                                         while(part) {
981                                                 MEM_freeN(part->rect);
982                                                 part= part->next;
983                                         }
984                                         BLI_freelistN(&R.parts);
985                                 }
986                         }
987
988                         if( (R.flag & R_HALO)) {
989                                 if(RE_local_test_break()==0) add_halo_flare();
990                         }
991
992                         if(R.r.mode & R_MBLUR) {
993                                 add_to_blurbuf(blur);
994                         }
995
996                         /* END (blur loop) */
997                         finalizeScene();
998
999                         if(RE_local_test_break()) break;
1000                 }
1001
1002                 /* definite free */
1003                 add_to_blurbuf(-1);
1004
1005                 /* HANDLE FIELD */
1006                 if(R.r.mode & R_FIELDS) {
1007                         if(R.flag & R_SEC_FIELD) R.rectf2= R.rectot;
1008                         else R.rectf1= R.rectot;
1009                         R.rectot= 0;
1010                 }
1011
1012                 if(RE_local_test_break()) break;
1013         }
1014
1015         /* JOIN FIELDS */
1016         if(R.r.mode & R_FIELDS) {
1017                 R.r.ysch*= 2;
1018                 R.afmy*= 2;
1019                 R.recty*= 2;
1020                 R.r.yasp/=2;
1021
1022                 if(R.rectot) MEM_freeN(R.rectot);       /* happens when a render has been stopped */
1023                 R.rectot=(unsigned int *)MEM_callocN(sizeof(int)*R.rectx*R.recty, "rectot");
1024
1025                 if(RE_local_test_break()==0) {
1026                         rt= R.rectot;
1027
1028                         if(R.r.mode & R_ODDFIELD) {
1029                                 rt2= R.rectf1;
1030                                 rt1= R.rectf2;
1031                         }
1032                         else {
1033                                 rt1= R.rectf1;
1034                                 rt2= R.rectf2;
1035                         }
1036
1037                         len= 4*R.rectx;
1038
1039                         for(a=0; a<R.recty; a+=2) {
1040                                 memcpy(rt, rt1, len);
1041                                 rt+= R.rectx;
1042                                 rt1+= R.rectx;
1043                                 memcpy(rt, rt2, len);
1044                                 rt+= R.rectx;
1045                                 rt2+= R.rectx;
1046                         }
1047                 }
1048         }
1049
1050         /* R.rectx= R.r.xsch; */
1051         /* if(R.r.mode & R_PANORAMA) R.rectx*= R.r.xparts; */
1052         /* R.recty= R.r.ysch; */
1053
1054         /* if border: still do skybuf */
1055         if(R.r.mode & R_BORDER) {
1056                 if( (R.r.mode & R_MOVIECROP)==0) {
1057                         if(R.r.bufflag & 1) {
1058                                 R.xstart= -R.afmx;
1059                                 R.ystart= -R.afmy;
1060                                 rt= R.rectot;
1061                                 for(y=0; y<R.recty; y++, rt+= R.rectx) scanlinesky((char *)rt, y);
1062                         }
1063                 }
1064         }
1065
1066         set_mblur_offs(0);
1067
1068         /* FREE */
1069
1070         /* zbuf test */
1071
1072         /* don't free R.rectz, only when its size is not the same as R.rectot */
1073
1074         if (R.rectz && parts == 1 && (R.r.mode & R_FIELDS) == 0);
1075         else {
1076                 if(R.rectz) MEM_freeN(R.rectz);
1077                 R.rectz= 0;
1078         }
1079
1080         if(R.rectf1) MEM_freeN(R.rectf1);
1081         R.rectf1= 0;
1082         if(R.rectf2) MEM_freeN(R.rectf2);
1083         R.rectf2= 0;
1084 }
1085
1086
1087
1088 /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
1089 extern unsigned short usegamtab;
1090 void RE_initrender(struct View3D *ogl_render_view3d)
1091 {
1092         double start_time;
1093         Image *bima;
1094         char name[256];
1095         
1096         /* scene data to R */
1097         R.r= G.scene->r;
1098         R.r.postigamma= 1.0/R.r.postgamma;
1099         
1100         /* WINDOW size (sch='scherm' dutch for screen...) */
1101         R.r.xsch= (R.r.size*R.r.xsch)/100;
1102         R.r.ysch= (R.r.size*R.r.ysch)/100;
1103         
1104         R.afmx= R.r.xsch/2;
1105         R.afmy= R.r.ysch/2;
1106         
1107         /* to be sure: when a premature return (rectx can differ from xsch) */
1108         R.rectx= R.r.xsch;
1109         R.recty= R.r.ysch;
1110         
1111         /* IS RENDERING ALLOWED? */
1112         
1113         /* forbidden combination */
1114         if((R.r.mode & R_BORDER) && (R.r.mode & R_PANORAMA)) {
1115                 error("No border supported for Panorama");
1116                 G.afbreek= 1;
1117                 return;
1118         }
1119         
1120         if(R.r.xparts*R.r.yparts>=2 && (R.r.mode & R_MOVIECROP) && (R.r.mode & R_BORDER)) {
1121                 error("Combination of border, crop and parts not allowed");
1122                 G.afbreek= 1;
1123                 return;
1124         }
1125         
1126         if(R.r.xparts*R.r.yparts>64) {
1127                 error("No more than 64 parts supported");
1128                 G.afbreek= 1;
1129                 return;
1130         }
1131         
1132         if(R.r.yparts>1 && (R.r.mode & R_PANORAMA)) {
1133                 error("No Y-Parts supported for Panorama");
1134                 G.afbreek= 1;
1135                 return;
1136         }
1137         
1138         
1139         /* TEST BACKBUF */
1140         /* If an image is specified for use as backdrop, that image is loaded    */
1141         /* here.                                                                 */
1142         if((R.r.bufflag & 1) && (G.scene->r.scemode & R_OGL)==0) {
1143                 if(R.r.alphamode == R_ADDSKY) {
1144                         strcpy(name, R.r.backbuf);
1145                         BLI_convertstringcode(name, G.sce, G.scene->r.cfra);
1146                         
1147                         if(R.backbuf) {
1148                                 R.backbuf->id.us--;
1149                                 bima= R.backbuf;
1150                         }
1151                         else bima= 0;
1152                         
1153                         R.backbuf= add_image(name);
1154                         
1155                         if(bima && bima->id.us<1) {
1156                                 free_image_buffers(bima);
1157                         }
1158                         if(R.backbuf==0) {
1159                                 // error() doesnt work with render window open
1160                                 //error("No backbuf there!");
1161                                 printf("Error: No backbuf %s\n", name);
1162                         }
1163                 }
1164         }
1165         
1166         usegamtab= 0; /* see also further */
1167         
1168         if(R.r.mode & (R_OSA|R_MBLUR)) {
1169                 R.osa= R.r.osa;
1170                 if(R.osa>16) R.osa= 16;
1171                 
1172                 init_render_jit(R.osa);
1173                 
1174                 /* this value sometimes is reset temporally, for example in transp zbuf */
1175                 if(R.r.mode & R_GAMMA) {
1176                         if((R.r.mode & R_OSA)) usegamtab= 1;
1177                 }
1178         }
1179         else R.osa= 0;
1180         
1181         /* always call, it does gamma tables used by alphaunder, but call after R.osa and jit was set */
1182         RE_init_filt_mask();
1183         
1184         /* when rendered without camera object */
1185         /* it has to done here because of envmaps */
1186         R.near= 0.1;
1187         R.far= 1000.0;
1188         
1189         
1190         if(R.afmx<1 || R.afmy<1) {
1191                 error("Image too small");
1192                 return;
1193         }
1194         R.ycor= ( (float)R.r.yasp)/( (float)R.r.xasp);
1195         
1196         start_time= PIL_check_seconds_timer();
1197         
1198         if(R.r.scemode & R_DOSEQ) {
1199                 R.rectx= R.r.xsch;
1200                 R.recty= R.r.ysch;
1201                 if(R.r.mode & R_PANORAMA) {
1202                         R.rectx*= R.r.xparts;
1203                 }
1204                 
1205                 if(R.rectot) MEM_freeN(R.rectot);
1206                 R.rectot= (unsigned int *)MEM_callocN(sizeof(int)*R.rectx*R.recty, "rectot");
1207                 
1208                 RE_local_timecursor((G.scene->r.cfra));
1209                 
1210                 if(RE_local_test_break()==0) do_render_seq();
1211                 
1212                 /* display */
1213                 if(R.rectot) RE_local_render_display(0, R.recty-1,
1214                                                                                          R.rectx, R.recty,
1215                                                                                          R.rectot);
1216         }
1217         else if(R.r.scemode & R_OGL) {
1218                 R.rectx= R.r.xsch;
1219                 R.recty= R.r.ysch;
1220                 
1221                 if(R.rectot) MEM_freeN(R.rectot);
1222                 R.rectot= (unsigned int *)MEM_callocN(sizeof(int)*R.rectx*R.recty, "rectot");
1223                 
1224                 RE_local_init_render_display();
1225                 drawview3d_render(ogl_render_view3d);
1226         }
1227         else {
1228                 if(G.scene->camera==0) {
1229                         G.scene->camera= scene_find_camera(G.scene);
1230                 }
1231                 
1232                 if(G.scene->camera==0) {
1233                         error("No camera");
1234                         /* needed because R.rectx and R.recty can be unmatching R.rectot */
1235                         if(R.rectot) MEM_freeN(R.rectot);
1236                         R.rectot= NULL;
1237                         
1238                         G.afbreek=1;
1239                         return;
1240                 }
1241                 else {
1242                         
1243                         if(G.scene->camera->type==OB_CAMERA) {
1244                                 Camera *cam= G.scene->camera->data;
1245                                 if(cam->type==CAM_ORTHO) R.r.mode |= R_ORTHO;
1246                         }
1247                         
1248                         render(); /* returns with complete rect xsch-ysch */
1249                 }
1250         }
1251         
1252         /* display again: fields/seq/parts/pano etc */
1253         if(R.rectot) {
1254                 RE_local_init_render_display();
1255                 RE_local_render_display(0, R.recty-1,
1256                         R.rectx, R.recty,
1257                         R.rectot);
1258         }
1259         else RE_local_clear_render_display(R.win);
1260         
1261         if ((G.scene->r.scemode & R_OGL)==0) /* header gets scrabled if renderwindow holds OGL context */       
1262                 RE_local_printrenderinfo((PIL_check_seconds_timer() - start_time), -1);
1263         
1264         /* restore variables */
1265         //R.osatex= 0;
1266         //R.vlr= 0;     
1267         ///* at cubemap */
1268         
1269         /* these flags remain on, until reset in caller to render (renderwin.c) */
1270         R.flag &= (R_RENDERING|R_ANIMRENDER);
1271 }
1272
1273 void RE_animrender(struct View3D *ogl_render_view3d)
1274 {
1275         int cfrao;
1276         char name[256];
1277
1278         if(G.scene==0) return;
1279
1280         /* scenedata to R: (for backbuf, R.rectx etc) */
1281         R.r= G.scene->r;
1282
1283         /* START ANIMLOOP, everywhere NOT the cfra from R.r is gebruikt: because of rest blender */
1284         cfrao= (G.scene->r.cfra);
1285
1286         if(G.scene->r.scemode & R_OGL) R.r.mode &= ~R_PANORAMA;
1287         
1288         // these calculations apply for
1289         // all movie formats
1290         R.rectx= (R.r.size*R.r.xsch)/100;
1291         R.recty= (R.r.size*R.r.ysch)/100;
1292         if(R.r.mode & R_PANORAMA) {
1293                 R.rectx*= R.r.xparts;
1294                 R.recty*= R.r.yparts;
1295         }
1296         if(R.r.mode & R_MOVIECROP) {
1297                 initparts();
1298                 setpart(0);             // this will adjust r.rectx
1299         }
1300
1301         if (0) {
1302 #ifdef __sgi
1303         } else if (R.r.imtype==R_MOVIE) {
1304                 start_movie();
1305 #endif
1306 #if defined(_WIN32) && !defined(FREE_WINDOWS)
1307         } else if (R.r.imtype == R_AVICODEC) {
1308                 start_avi_codec();
1309 #endif
1310 #if WITH_QUICKTIME
1311         } else if (R.r.imtype == R_QUICKTIME) {
1312                 start_qt();
1313 #endif
1314         } else if ELEM4(R.r.imtype, R_AVIRAW, R_AVIJPEG, R_MOVIE, R_AVICODEC) {
1315                 if ELEM(R.r.imtype, R_MOVIE, R_AVICODEC) {
1316                         printf("Selected movie format not supported on this platform,\nusing RAW AVI instead\n");
1317                 }
1318                 start_avi();
1319         }
1320
1321         for((G.scene->r.cfra)=(G.scene->r.sfra); (G.scene->r.cfra)<=(G.scene->r.efra); (G.scene->r.cfra)++) {
1322                 double starttime= PIL_check_seconds_timer();
1323
1324                 R.flag |= R_ANIMRENDER; // unused now (ton)
1325
1326                 RE_initrender(ogl_render_view3d);
1327                 
1328                 /* WRITE IMAGE */
1329                 if(RE_local_test_break()==0) {
1330
1331                         if (0) {
1332 #ifdef __sgi
1333                         } else if (R.r.imtype == R_MOVIE) {
1334                                 append_movie((G.scene->r.cfra));
1335 #endif
1336 #if defined(_WIN32) && !defined(FREE_WINDOWS)
1337                         } else if (R.r.imtype == R_AVICODEC) {
1338                                 append_avi_codec((G.scene->r.cfra));
1339 #endif
1340 #ifdef WITH_QUICKTIME
1341                         } else if (R.r.imtype == R_QUICKTIME) {
1342                                 append_qt((G.scene->r.cfra));
1343 #endif
1344                         } else if ELEM4(R.r.imtype, R_AVIRAW, R_AVIJPEG, R_MOVIE, R_AVICODEC) {
1345                                 append_avi((G.scene->r.cfra));
1346                         } else {
1347                                 makepicstring(name, (G.scene->r.cfra));
1348                                 schrijfplaatje(name);
1349                                 if(RE_local_test_break()==0) printf("Saved: %s", name);
1350                         }
1351
1352                         timestr(PIL_check_seconds_timer()-starttime, name);
1353                         printf(" Time: %s\n", name);
1354                         fflush(stdout); /* needed for renderd !! */
1355                 }
1356
1357                 if(G.afbreek==1) break;
1358
1359         }
1360
1361         (G.scene->r.cfra)= cfrao;
1362
1363         /* restore time */
1364         if(R.r.mode & (R_FIELDS|R_MBLUR)) {
1365                 do_all_ipos();
1366                 do_all_keys();
1367                 do_all_actions();
1368                 do_all_ikas();
1369         }
1370
1371         if (0) {
1372 #ifdef __sgi    
1373         } else if (R.r.imtype==R_MOVIE) {
1374                 end_movie();
1375 #endif
1376 #if defined(_WIN32) && !defined(FREE_WINDOWS)
1377         } else if (R.r.imtype == R_AVICODEC) {
1378                 end_avi_codec();
1379 #endif
1380 #ifdef WITH_QUICKTIME
1381         } else if (R.r.imtype == R_QUICKTIME) {
1382                 end_qt();
1383 #endif
1384         } else if ELEM4(R.r.imtype, R_AVIRAW, R_AVIJPEG, R_MOVIE, R_AVICODEC) {
1385                 end_avi();
1386         }
1387 }
1388
1389 /* *************************************************** */
1390 /* ******************* Screendumps ******************** */
1391 /* moved to the windowControl thing */