Three features;
[blender-staging.git] / source / blender / render / intern / source / pipeline.c
1 /**  
2  *
3  * ***** BEGIN GPL LICENSE BLOCK *****
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version. 
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software Foundation,
17  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18  *
19  * The Original Code is Copyright (C) 2006 Blender Foundation.
20  * All rights reserved.
21  *
22  * The Original Code is: all of this file.
23  *
24  * Contributor(s): none yet.
25  *
26  * ***** END GPL LICENSE BLOCK *****
27  */
28
29 #include <math.h>
30 #include <limits.h>
31 #include <string.h>
32 #include <stdlib.h>
33
34 #include "DNA_group_types.h"
35 #include "DNA_object_types.h"
36 #include "DNA_scene_types.h"
37
38 #include "BKE_global.h"
39 #include "BKE_image.h"
40 #include "BKE_node.h"
41 #include "BKE_scene.h"
42 #include "BKE_writeavi.h"       /* <------ should be replaced once with generic movie module */
43
44 #include "MEM_guardedalloc.h"
45
46 #include "BLI_arithb.h"
47 #include "BLI_blenlib.h"
48 #include "BLI_threads.h"
49
50 #include "PIL_time.h"
51 #include "IMB_imbuf.h"
52 #include "IMB_imbuf_types.h"
53
54 #include "RE_pipeline.h"
55 #include "radio.h"
56
57 #include "BSE_sequence.h"  /* <----------------- bad!!! */
58
59 /* internal */
60 #include "render_types.h"
61 #include "renderpipeline.h"
62 #include "renderdatabase.h"
63 #include "rendercore.h"
64 #include "envmap.h"
65 #include "initrender.h"
66 #include "shadbuf.h"
67 #include "zbuf.h"
68
69 #include "SDL_thread.h"
70 #include "SDL_mutex.h"
71
72 /* render flow
73
74 1) Initialize state
75 - state data, tables
76 - movie/image file init
77 - everything that doesn't change during animation
78
79 2) Initialize data
80 - camera, world, matrices
81 - make render verts, faces, halos, strands
82 - everything can change per frame/field
83
84 3) Render Processor
85 - multiple layers
86 - tiles, rect, baking
87 - layers/tiles optionally to disk or directly in Render Result
88
89 4) Composit Render Result
90 - also read external files etc
91
92 5) Image Files
93 - save file or append in movie
94
95 */
96
97
98 /* ********* globals ******** */
99
100 /* here we store all renders */
101 static struct ListBase RenderList= {NULL, NULL};
102
103 /* hardcopy of current render, used while rendering for speed */
104 Render R;
105
106 /* ********* alloc and free ******** */
107
108
109 static SDL_mutex *malloc_lock= NULL;
110
111 void *RE_mallocN(int len, char *name)
112 {
113         void *mem;
114         if(malloc_lock) SDL_mutexP(malloc_lock);
115         mem= MEM_mallocN(len, name);
116         if(malloc_lock) SDL_mutexV(malloc_lock);
117         return mem;
118 }
119 void *RE_callocN(int len, char *name)
120 {
121         void *mem;
122         if(malloc_lock) SDL_mutexP(malloc_lock);
123         mem= MEM_callocN(len, name);
124         if(malloc_lock) SDL_mutexV(malloc_lock);
125         return mem;
126 }
127 void RE_freeN(void *poin)
128 {
129         if(malloc_lock) SDL_mutexP(malloc_lock);
130         MEM_freeN(poin);
131         if(malloc_lock) SDL_mutexV(malloc_lock);
132 }
133
134 /* ********************** */
135
136
137 /* default callbacks, set in each new render */
138 static void result_nothing(RenderResult *rr) {}
139 static void result_rcti_nothing(RenderResult *rr, rcti *rect) {}
140 static void stats_nothing(RenderStats *rs) {}
141 static void int_nothing(int val) {}
142 static int void_nothing(void) {return 0;}
143 static void print_error(const char *str) {printf("ERROR: %s\n", str);}
144
145 static void free_render_result(RenderResult *res)
146 {
147         if(res==NULL) return;
148
149         while(res->layers.first) {
150                 RenderLayer *rl= res->layers.first;
151                 if(rl->rectf) RE_freeN(rl->rectf);
152                 if(rl->rectz) RE_freeN(rl->rectz);
153                 if(rl->rectvec) RE_freeN(rl->rectvec);
154                 BLI_remlink(&res->layers, rl);
155                 RE_freeN(rl);
156         }
157         
158         if(res->rect32)
159                 RE_freeN(res->rect32);
160         if(res->rectz)
161                 RE_freeN(res->rectz);
162         if(res->rectf)
163                 RE_freeN(res->rectf);
164         
165         RE_freeN(res);
166 }
167
168 /* called by main render as well for parts */
169 /* will read info from Render *re to define layers */
170 /* called in threads */
171 /* winrct is coordinate rect of entire image, partrct the part within */
172 static RenderResult *new_render_result(Render *re, rcti *partrct, int crop)
173 {
174         RenderResult *rr;
175         RenderLayer *rl;
176         SceneRenderLayer *srl;
177         int rectx, recty;
178         
179         rectx= partrct->xmax - partrct->xmin;
180         recty= partrct->ymax - partrct->ymin;
181         
182         if(rectx<=0 || recty<=0)
183                 return NULL;
184         
185         rr= RE_callocN(sizeof(RenderResult), "new render result");
186         rr->rectx= rectx;
187         rr->recty= recty;
188         /* crop is one or two extra pixels rendered for filtering, is used for merging and display too */
189         rr->crop= crop;
190         
191         /* tilerect is relative coordinates within render disprect. do not subtract crop yet */
192         rr->tilerect.xmin= partrct->xmin - re->disprect.xmin;
193         rr->tilerect.xmax= partrct->xmax - re->disprect.xmax;
194         rr->tilerect.ymin= partrct->ymin - re->disprect.ymin;
195         rr->tilerect.ymax= partrct->ymax - re->disprect.ymax;
196         
197         /* check renderdata for amount of layers */
198         for(srl= re->r.layers.first; srl; srl= srl->next) {
199                 rl= RE_callocN(sizeof(RenderLayer), "new render layer");
200                 BLI_addtail(&rr->layers, rl);
201                 
202                 strcpy(rl->name, srl->name);
203                 rl->lay= srl->lay;
204                 rl->layflag= srl->layflag;
205                 rl->passflag= srl->passflag;
206                 
207                 rl->rectf= RE_callocN(rectx*recty*sizeof(float)*4, "layer float rgba");
208                 if(srl->passflag  & SCE_PASS_Z)
209                         rl->rectz= RE_callocN(rectx*recty*sizeof(float), "layer float Z");
210                 if(srl->passflag  & SCE_PASS_VECTOR)
211                         rl->rectvec= RE_callocN(rectx*recty*sizeof(float)*2, "layer float Vector");
212                 
213         }
214         /* previewrender and envmap don't do layers, so we make a default one */
215         if(rr->layers.first==NULL) {
216                 rl= RE_callocN(sizeof(RenderLayer), "new render layer");
217                 BLI_addtail(&rr->layers, rl);
218                 
219                 rl->rectf= RE_callocN(rectx*recty*sizeof(float)*4, "prev/env float rgba");
220                 rl->rectz= RE_callocN(rectx*recty*sizeof(float), "prev/env float Z");
221                 
222                 /* note, this has to be in sync with scene.c */
223                 rl->lay= (1<<20) -1;
224                 rl->layflag= 0x7FFF;    /* solid ztra halo strand */
225                 rl->passflag= SCE_PASS_COMBINED|SCE_PASS_Z;
226                 
227         }
228         
229         return rr;
230 }
231
232 static int render_result_needs_vector(RenderResult *rr)
233 {
234         RenderLayer *rl;
235         
236         for(rl= rr->layers.first; rl; rl= rl->next)
237                 if(rl->passflag & SCE_PASS_VECTOR)
238                         return 1;
239         return 0;
240 }
241
242 static void do_merge_tile(RenderResult *rr, RenderResult *rrpart, float *target, float *tile, int pixsize)
243 {
244         int y, ofs, copylen, tilex, tiley;
245         
246         copylen= tilex= rrpart->rectx;
247         tiley= rrpart->recty;
248         
249         if(rrpart->crop) {      /* filters add pixel extra */
250                 tile+= pixsize*(rrpart->crop + rrpart->crop*tilex);
251                 
252                 copylen= tilex - 2*rrpart->crop;
253                 tiley -= 2*rrpart->crop;
254                 
255                 ofs= (rrpart->tilerect.ymin + rrpart->crop)*rr->rectx + (rrpart->tilerect.xmin+rrpart->crop);
256                 target+= pixsize*ofs;
257         }
258         else {
259                 ofs= (rrpart->tilerect.ymin*rr->rectx + rrpart->tilerect.xmin);
260                 target+= pixsize*ofs;
261         }
262
263         copylen *= sizeof(float)*pixsize;
264         tilex *= pixsize;
265         ofs= pixsize*rr->rectx;
266
267         for(y=0; y<tiley; y++) {
268                 memcpy(target, tile, copylen);
269                 target+= ofs;
270                 tile+= tilex;
271         }
272 }
273
274 /* used when rendering to a full buffer, or when reading the exr part-layer-pass file */
275 /* no test happens here if it fits... we also assume layers are in sync */
276 /* is used within threads */
277 static void merge_render_result(RenderResult *rr, RenderResult *rrpart)
278 {
279         RenderLayer *rl, *rlp;
280         
281         for(rl= rr->layers.first, rlp= rrpart->layers.first; rl && rlp; rl= rl->next, rlp= rlp->next) {
282                 
283                 /* combined */
284                 if(rl->rectf && rlp->rectf)
285                         do_merge_tile(rr, rrpart, rl->rectf, rlp->rectf, 4);
286                 /* z */
287                 if(rl->rectz && rlp->rectz)
288                         do_merge_tile(rr, rrpart, rl->rectz, rlp->rectz, 1);
289                 /* vector */
290                 if(rl->rectvec && rlp->rectvec)
291                         do_merge_tile(rr, rrpart, rl->rectvec, rlp->rectvec, 2);
292         }
293 }
294
295
296 /* *************************************************** */
297
298 Render *RE_GetRender(const char *name)
299 {
300         Render *re;
301         
302         /* search for existing renders */
303         for(re= RenderList.first; re; re= re->next) {
304                 if(strncmp(re->name, name, RE_MAXNAME)==0) {
305                         break;
306                 }
307         }
308         return re;
309 }
310
311 /* if you want to know exactly what has been done */
312 RenderResult *RE_GetResult(Render *re)
313 {
314         if(re)
315                 return re->result;
316         return NULL;
317 }
318
319 /* fill provided result struct with what's currently active or done */
320 void RE_GetResultImage(Render *re, RenderResult *rr)
321 {
322         memset(rr, 0, sizeof(RenderResult));
323
324         if(re && re->result) {
325                 RenderLayer *rl;
326                 
327                 rr->rectx= re->result->rectx;
328                 rr->recty= re->result->recty;
329                 
330                 rr->rectf= re->result->rectf;
331                 rr->rectz= re->result->rectz;
332                 rr->rect32= re->result->rect32;
333                 
334                 /* active layer */
335                 rl= BLI_findlink(&re->result->layers, re->r.actlay);
336                 if(rl) {
337                         if(rr->rectf==NULL)
338                                 rr->rectf= rl->rectf;
339                         if(rr->rectz==NULL)
340                                 rr->rectz= rl->rectz;   
341                 }
342         }
343 }
344
345 #define FTOCHAR(val) val<=0.0f?0: (val>=1.0f?255: (char)(255.0f*val))
346 /* caller is responsible for allocating rect in correct size! */
347 void RE_ResultGet32(Render *re, unsigned int *rect)
348 {
349         RenderResult rres;
350         
351         RE_GetResultImage(re, &rres);
352         if(rres.rect32) 
353                 memcpy(rect, rres.rect32, sizeof(int)*rres.rectx*rres.recty);
354         else if(rres.rectf) {
355                 float *fp= rres.rectf;
356                 int tot= rres.rectx*rres.recty;
357                 char *cp= (char *)rect;
358                 
359                 for(;tot>0; tot--, cp+=4, fp+=4) {
360                         cp[0] = FTOCHAR(fp[0]);
361                         cp[1] = FTOCHAR(fp[1]);
362                         cp[2] = FTOCHAR(fp[2]);
363                         cp[3] = FTOCHAR(fp[3]);
364                 }
365         }
366         else
367                 /* else fill with black */
368                 memset(rect, 0, sizeof(int)*re->rectx*re->recty);
369 }
370
371
372 RenderStats *RE_GetStats(Render *re)
373 {
374         return &re->i;
375 }
376
377 Render *RE_NewRender(const char *name)
378 {
379         Render *re;
380         
381         /* only one render per name exists */
382         re= RE_GetRender(name);
383         if(re) {
384                 BLI_remlink(&RenderList, re);
385                 RE_FreeRender(re);
386         }
387         
388         /* new render data struct */
389         re= RE_callocN(sizeof(Render), "new render");
390         BLI_addtail(&RenderList, re);
391         strncpy(re->name, name, RE_MAXNAME);
392         
393         /* set default empty callbacks */
394         re->display_init= result_nothing;
395         re->display_clear= result_nothing;
396         re->display_draw= result_rcti_nothing;
397         re->timecursor= int_nothing;
398         re->test_break= void_nothing;
399         re->test_return= void_nothing;
400         re->error= print_error; 
401         re->stats_draw= stats_nothing;
402         
403         /* init some variables */
404         re->ycor= 1.0f;
405         
406         return re;
407 }
408
409 /* only call this while you know it will remove the link too */
410 void RE_FreeRender(Render *re)
411 {
412         
413         free_renderdata_tables(re);
414         free_sample_tables(re);
415         
416         free_render_result(re->result);
417         
418         BLI_remlink(&RenderList, re);
419         RE_freeN(re);
420 }
421
422 /* exit blender */
423 void RE_FreeAllRender(void)
424 {
425         while(RenderList.first) {
426                 RE_FreeRender(RenderList.first);
427         }
428 }
429
430 /* ********* initialize state ******** */
431
432
433 /* what doesn't change during entire render sequence */
434 /* disprect is optional, if NULL it assumes full window render */
435 void RE_InitState(Render *re, RenderData *rd, int winx, int winy, rcti *disprect)
436 {
437         re->ok= TRUE;   /* maybe flag */
438         
439         re->i.starttime= PIL_check_seconds_timer();
440         re->r= *rd;             /* hardcopy */
441         
442         re->winx= winx;
443         re->winy= winy;
444         if(disprect) {
445                 re->disprect= *disprect;
446                 re->rectx= disprect->xmax-disprect->xmin;
447                 re->recty= disprect->ymax-disprect->ymin;
448         }
449         else {
450                 re->disprect.xmin= re->disprect.xmax= 0;
451                 re->disprect.xmax= winx;
452                 re->disprect.ymax= winy;
453                 re->rectx= winx;
454                 re->recty= winy;
455         }
456         
457         if(re->rectx < 2 || re->recty < 2) {
458                 re->error("Image too small");
459                 re->ok= 0;
460         }
461         else {
462                 /* check state variables, osa? */
463                 if(re->r.mode & (R_OSA|R_MBLUR)) {
464                         re->osa= re->r.osa;
465                         if(re->osa>16) re->osa= 16;
466                 }
467                 else re->osa= 0;
468                 
469                 /* always call, checks for gamma, gamma tables and jitter too */
470                 make_sample_tables(re); 
471                 
472                 /* initialize render result */
473                 free_render_result(re->result);
474                 re->result= new_render_result(re, &re->disprect, 0);
475
476         }
477 }
478
479 void RE_SetDispRect (struct Render *re, rcti *disprect)
480 {
481         re->disprect= *disprect;
482         re->rectx= disprect->xmax-disprect->xmin;
483         re->recty= disprect->ymax-disprect->ymin;
484         
485         /* initialize render result */
486         free_render_result(re->result);
487         re->result= new_render_result(re, &re->disprect, 0);
488 }
489
490 void RE_SetWindow(Render *re, rctf *viewplane, float clipsta, float clipend)
491 {
492         /* re->ok flag? */
493         
494         re->viewplane= *viewplane;
495         re->clipsta= clipsta;
496         re->clipend= clipend;
497
498         i_window(re->viewplane.xmin, re->viewplane.xmax, re->viewplane.ymin, re->viewplane.ymax, re->clipsta, re->clipend, re->winmat);
499 }
500
501 void RE_SetOrtho(Render *re, rctf *viewplane, float clipsta, float clipend)
502 {
503         /* re->ok flag? */
504         
505         re->viewplane= *viewplane;
506         re->clipsta= clipsta;
507         re->clipend= clipend;
508         re->r.mode |= R_ORTHO;
509
510         i_ortho(re->viewplane.xmin, re->viewplane.xmax, re->viewplane.ymin, re->viewplane.ymax, re->clipsta, re->clipend, re->winmat);
511 }
512
513 void RE_SetView(Render *re, float mat[][4])
514 {
515         /* re->ok flag? */
516         Mat4CpyMat4(re->viewmat, mat);
517         Mat4Invert(re->viewinv, re->viewmat);
518 }
519
520 /* image and movie output has to move to either imbuf or kernel */
521
522 void RE_display_init_cb(Render *re, void (*f)(RenderResult *rr))
523 {
524         re->display_init= f;
525 }
526 void RE_display_clear_cb(Render *re, void (*f)(RenderResult *rr))
527 {
528         re->display_clear= f;
529 }
530 void RE_display_draw_cb(Render *re, void (*f)(RenderResult *rr, rcti *rect))
531 {
532         re->display_draw= f;
533 }
534
535 void RE_stats_draw_cb(Render *re, void (*f)(RenderStats *rs))
536 {
537         re->stats_draw= f;
538 }
539 void RE_timecursor_cb(Render *re, void (*f)(int))
540 {
541         re->timecursor= f;
542 }
543
544 void RE_test_break_cb(Render *re, int (*f)(void))
545 {
546         re->test_break= f;
547 }
548 void RE_test_return_cb(Render *re, int (*f)(void))
549 {
550         re->test_return= f;
551 }
552 void RE_error_cb(Render *re, void (*f)(const char *str))
553 {
554         re->error= f;
555 }
556
557
558 /* ********* add object data (later) ******** */
559
560 /* object is considered fully prepared on correct time etc */
561 /* includes lights */
562 void RE_AddObject(Render *re, Object *ob)
563 {
564         
565 }
566
567 /* *************************************** */
568
569 static int do_part_thread(void *pa_v)
570 {
571         RenderPart *pa= pa_v;
572         
573         /* need to return nicely all parts on esc */
574         if(R.test_break()==0) {
575                 
576                 pa->result= new_render_result(&R, &pa->disprect, pa->crop);
577                 
578                 if(R.osa)
579                         zbufshadeDA_tile(pa);
580                 else
581                         zbufshade_tile(pa);
582                 
583                 /* merge too on break! */       
584                 merge_render_result(R.result, pa->result);
585         }
586         
587         pa->ready= 1;
588         
589         return 0;
590 }
591
592 /* returns with render result filled, not threaded */
593 static void render_tile_processor(Render *re)
594 {
595         RenderPart *pa;
596         
597         if(re->test_break())
598                 return;
599         
600         re->i.lastframetime= PIL_check_seconds_timer()- re->i.starttime;
601         re->stats_draw(&re->i);
602         re->i.starttime= PIL_check_seconds_timer();
603  
604         if(re->result==NULL)
605                 return;
606         
607         initparts(re);
608         
609         /* assuming no new data gets added to dbase... */
610         R= *re;
611         
612         for(pa= re->parts.first; pa; pa= pa->next) {
613                 do_part_thread(pa);
614                 
615                 if(pa->result) {
616                         if(!re->test_break()) {
617                                 re->display_draw(pa->result, NULL);
618                                 re->i.partsdone++;
619                         }
620                         free_render_result(pa->result);
621                         pa->result= NULL;
622                 }               
623                 if(re->test_break())
624                         break;
625         }
626         
627         re->i.lastframetime= PIL_check_seconds_timer()- re->i.starttime;
628         re->stats_draw(&re->i);
629
630         freeparts(re);
631 }
632
633 static RenderPart *find_nicest_part(Render *re)
634 {
635         RenderPart *pa, *best= NULL;
636         int centx=re->winx/2, centy=re->winy/2, tot=1;
637         int mindist, distx, disty;
638         
639         /* find center of rendered parts, image center counts for 1 too */
640         for(pa= re->parts.first; pa; pa= pa->next) {
641                 if(pa->ready) {
642                         centx+= (pa->disprect.xmin+pa->disprect.xmax)/2;
643                         centy+= (pa->disprect.ymin+pa->disprect.ymax)/2;
644                         tot++;
645                 }
646         }
647         centx/=tot;
648         centy/=tot;
649         
650         /* closest of the non-rendering parts */
651         mindist= re->winx*re->winy;
652         for(pa= re->parts.first; pa; pa= pa->next) {
653                 if(pa->ready==0 && pa->nr==0) {
654                         distx= centx - (pa->disprect.xmin+pa->disprect.xmax)/2;
655                         disty= centy - (pa->disprect.ymin+pa->disprect.ymax)/2;
656                         distx= (int)sqrt(distx*distx + disty*disty);
657                         if(distx<mindist) {
658                                 best= pa;
659                                 mindist= distx;
660                         }
661                 }
662         }
663         return best;
664 }
665
666 static void threaded_tile_processor(Render *re)
667 {
668         ListBase threads;
669         RenderPart *pa;
670         int maxthreads, rendering=1, counter= 1, hasdrawn, drawtimer=0;
671         
672         if(re->result==NULL)
673                 return;
674         if(re->test_break())
675                 return;
676         
677         if(re->r.mode & R_THREADS) maxthreads= 2;
678         else maxthreads= 1;
679         
680         initparts(re);
681         BLI_init_threads(&threads, do_part_thread, maxthreads);
682         
683         /* assuming no new data gets added to dbase... */
684         R= *re;
685         
686         malloc_lock = SDL_CreateMutex();
687         
688         while(rendering) {
689                 
690                 /* I noted that test_break() in a thread doesn't make ghost send ESC */
691                 if(BLI_available_threads(&threads) && !re->test_break()) {
692                         pa= find_nicest_part(re);
693                         if(pa) {
694                                 pa->nr= counter++;      /* for nicest part, and for stats */
695                                 pa->thread= BLI_available_thread_index(&threads);       /* sample index */
696                                 BLI_insert_thread(&threads, pa);
697                         }
698                 }
699                 else {
700                         PIL_sleep_ms(50);
701                         drawtimer++;
702                 }
703                 
704                 /* check for ready ones to display, and if we need to continue */
705                 hasdrawn= 0;
706                 rendering= 0;
707                 for(pa= re->parts.first; pa; pa= pa->next) {
708                         if(pa->ready) {
709                                 if(pa->result) {
710                                         BLI_remove_thread(&threads, pa);
711                                         re->display_draw(pa->result, NULL);
712                                         free_render_result(pa->result);
713                                         pa->result= NULL;
714                                         re->i.partsdone++;
715                                         hasdrawn= 1;
716                                 }
717                         }
718                         else {
719                                 rendering= 1;
720                                 if(pa->nr && pa->result && drawtimer>20) {
721                                         re->display_draw(pa->result, &pa->result->renrect);
722                                         hasdrawn= 1;
723                                 }
724                         }
725                 }
726                 
727                 if(hasdrawn)
728                         drawtimer= 0;
729                 
730                 /* on break, wait for all slots to get freed */
731                 if(re->test_break() && BLI_available_threads(&threads)==maxthreads)
732                         rendering= 0;
733                 
734         }
735         
736         if(malloc_lock) SDL_DestroyMutex(malloc_lock); malloc_lock= NULL;
737         
738         BLI_end_threads(&threads);
739         freeparts(re);
740 }
741
742 void RE_TileProcessor(Render *re)
743 {
744         if(1) 
745                 threaded_tile_processor(re);
746         else
747                 render_tile_processor(re);      
748 }
749
750
751 /* ************  This part uses API, for rendering Blender scenes ********** */
752
753 void render_one_frame(Render *re)
754 {
755         
756 //      re->cfra= cfra; /* <- unused! */
757         
758         /* make render verts/faces/halos/lamps */
759         if(render_result_needs_vector(re->result))
760                 RE_Database_FromScene_Vectors(re, re->scene);
761         else
762            RE_Database_FromScene(re, re->scene, 1);
763         
764         RE_TileProcessor(re);
765         
766         /* free all render verts etc */
767         RE_Database_Free(re);
768 }
769
770 /* accumulates osa frames */
771 static void do_render_blurred(Render *re, float frame)
772 {
773         
774 }
775
776 /* interleaves 2 frames */
777 static void do_render_fields(Render *re)
778 {
779         
780 }
781
782 static void do_render_final(Render *re, Scene *scene)
783 {
784         /* we set start time here, for main Blender loops */
785         re->i.starttime= PIL_check_seconds_timer();
786
787         if(re->r.scemode & R_DOSEQ) {
788                 re->result->rect32= MEM_callocN(sizeof(int)*re->rectx*re->recty, "rectot");
789                 if(!re->test_break()) 
790                         do_render_seq(re->result);
791         }
792         else {
793                 /* first check if theres nodetree with render result */
794                 int do_render= ntreeCompositNeedsRender(scene->nodetree);
795                 /* but.. do we use nodes? */
796                 if(scene->use_nodes==0) do_render= 1;
797                 
798                 re->scene= scene;
799                 
800                 if(do_render) {
801                         /* now use renderdata and camera to set viewplane */
802                         RE_SetCamera(re, re->scene->camera);
803                         
804                         if(re->r.mode & R_FIELDS)
805                                 do_render_fields(re);
806                         else if(re->r.mode & R_MBLUR)
807                                 do_render_blurred(re, re->scene->r.cfra);
808                         else
809                                 render_one_frame(re);
810                 }
811                 
812                 ntreeCompositTagRender(scene->nodetree);
813                 ntreeCompositTagAnimated(scene->nodetree);
814                 
815                 if(re->r.scemode & R_DOCOMP)
816                         ntreeCompositExecTree(scene->nodetree, &re->r, 0);
817         }
818         
819
820         re->i.lastframetime= PIL_check_seconds_timer()- re->i.starttime;
821         re->stats_draw(&re->i);
822         
823         re->display_draw(re->result, NULL);
824         
825 }
826
827
828 static int is_rendering_allowed(Render *re)
829 {
830         
831         /* forbidden combinations */
832         if(re->r.mode & R_PANORAMA) {
833                 if(re->r.mode & R_BORDER) {
834                         re->error("No border supported for Panorama");
835                         return 0;
836                 }
837                 if(re->r.yparts>1) {
838                         re->error("No Y-Parts supported for Panorama");
839                         return 0;
840                 }
841                 if(re->r.mode & R_ORTHO) {
842                         re->error("No Ortho render possible for Panorama");
843                         return 0;
844                 }
845         }
846         
847         if(re->r.mode & R_BORDER) {
848                 if(re->r.border.xmax <= re->r.border.xmin || 
849                    re->r.border.ymax <= re->r.border.ymin) {
850                         re->error("No border area selected.");
851                         return 0;
852                 }
853         }
854         
855         if(re->r.xparts*re->r.yparts>=2 && (re->r.mode & R_MOVIECROP) && (re->r.mode & R_BORDER)) {
856                 re->error("Combination of border, crop and parts not allowed");
857                 return 0;
858         }
859         
860         if(re->r.xparts*re->r.yparts>64) {
861                 re->error("No more than 64 parts supported");
862                 return 0;
863         }
864         
865         if(re->r.yparts>1 && (re->r.mode & R_PANORAMA)) {
866                 re->error("No Y-Parts supported for Panorama");
867                 return 0;
868         }
869         
870         /* check valid camera */
871         if(re->scene->camera==NULL)
872                 re->scene->camera= scene_find_camera(re->scene);
873         if(re->scene->camera==NULL) {
874                 re->error("No camera");
875                 return 0;
876         }
877         
878         
879         return 1;
880 }
881
882 /* evaluating scene options for general Blender render */
883 static int render_initialize_from_scene(Render *re, Scene *scene)
884 {
885         int winx, winy;
886         rcti disprect;
887         
888         /* r.xsch and r.ysch has the actual view window size
889                 r.border is the clipping rect */
890         
891         /* calculate actual render result and display size */
892         winx= (scene->r.size*scene->r.xsch)/100;
893         winy= (scene->r.size*scene->r.ysch)/100;
894         //      if(scene->r.mode & R_PANORAMA)
895         //              winx*= scene->r.xparts;
896         
897         /* only in movie case we render smaller part */
898         if(scene->r.mode & R_BORDER) {
899                 disprect.xmin= scene->r.border.xmin*winx;
900                 disprect.xmax= scene->r.border.xmax*winx;
901                 
902                 disprect.ymin= scene->r.border.ymin*winy;
903                 disprect.ymax= scene->r.border.ymax*winy;
904         }
905         else {
906                 disprect.xmin= disprect.ymin= 0;
907                 disprect.xmax= winx;
908                 disprect.ymax= winy;
909         }
910         
911         RE_InitState(re, &scene->r, winx, winy, &disprect);
912         
913         re->scene= scene;
914         if(!is_rendering_allowed(re))
915                 return 0;
916         
917         re->display_init(re->result);
918         re->display_clear(re->result);
919         
920         return 1;
921 }
922
923 /* general Blender frame render call */
924 /* should return 1 when all is OK, otherwise it throws up errors */
925 void RE_BlenderFrame(Render *re, Scene *scene, int frame)
926 {
927         /* ugly global still... is to prevent renderwin events and signal subsurfs etc to make full resol */
928         /* is also set by caller renderwin.c */
929         G.rendering= 1;
930         
931         if(render_initialize_from_scene(re, scene)) {
932                 do_render_final(re, scene);
933         }
934 }
935
936
937 /* saves images to disk */
938 void RE_BlenderAnim(Render *re, Scene *scene, int sfra, int efra)
939 {
940         bMovieHandle *mh= BKE_get_movie_handle(scene->r.imtype);
941         int cfrao= scene->r.cfra;
942         char name[FILE_MAXDIR+FILE_MAXFILE];
943         
944         /* ugly global still... is to prevent renderwin events and signal subsurfs etc to make full resol */
945         /* is also set by caller renderwin.c */
946         G.rendering= 1;
947         
948         if(!render_initialize_from_scene(re, scene))
949            return;
950         
951         /* confusing... scene->r or re->r? make a decision once! */
952         if(BKE_imtype_is_movie(scene->r.imtype))
953                 mh->start_movie(&scene->r, re->rectx, re->recty);
954         
955         for(scene->r.cfra= sfra; scene->r.cfra<=efra; scene->r.cfra++) {
956                 re->r.cfra= scene->r.cfra;      /* weak.... */
957                 
958                 do_render_final(re, scene);
959                 
960                 /* write image or movie */
961                 if(re->test_break()==0) {
962                         RenderResult rres;
963                         
964                         RE_GetResultImage(re, &rres);
965
966                         /* write movie or image */
967                         if(BKE_imtype_is_movie(scene->r.imtype)) {
968                                 /* note; the way it gets 32 bits rects is weak... */
969                                 int dofree=0;
970                                 if(rres.rect32==NULL) {
971                                         rres.rect32= MEM_mallocN(sizeof(int)*rres.rectx*rres.recty, "temp 32 bits rect");
972                                         dofree= 1;
973                                 }
974                                 RE_ResultGet32(re, rres.rect32);
975                                 mh->append_movie(scene->r.cfra, rres.rect32, rres.rectx, rres.recty);
976                                 if(dofree) MEM_freeN(rres.rect32);
977                                 printf("Append frame %d", scene->r.cfra);
978                         }
979                         else {
980                                 ImBuf *ibuf= IMB_allocImBuf(rres.rectx, rres.recty, scene->r.planes, 0, 0);
981                                 int ok;
982                                 
983                                 BKE_makepicstring(name, (scene->r.cfra));
984                                 ibuf->rect= rres.rect32;                /* if not exists, BKE_write_ibuf makes one */
985                                 ibuf->rect_float= rres.rectf;
986                                 ibuf->zbuf_float= rres.rectz;
987                                 ok= BKE_write_ibuf(ibuf, name, scene->r.imtype, scene->r.subimtype, scene->r.quality);
988                                 IMB_freeImBuf(ibuf);    /* imbuf knows which rects are not part of ibuf */
989
990                                 if(ok==0) {
991                                         printf("Render error: cannot save %s\n", name);
992                                         break;
993                                 }
994                                 else printf("Saved: %s", name);
995                         }
996                         
997                         BLI_timestr(re->i.lastframetime, name);
998                         printf(" Time: %s\n", name);
999                         fflush(stdout); /* needed for renderd !! (not anymore... (ton)) */
1000                 }
1001                 
1002                 if(G.afbreek==1) break;
1003         }
1004         
1005         /* end movie */
1006         if(BKE_imtype_is_movie(scene->r.imtype))
1007                 mh->end_movie();
1008
1009         scene->r.cfra= cfrao;
1010 }
1011
1012
1013