Three-in-one commit:
[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 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                 BLI_remlink(&res->layers, rl);
154                 RE_freeN(rl);
155         }
156         
157         if(res->rect32)
158                 RE_freeN(res->rect32);
159         if(res->rectz)
160                 RE_freeN(res->rectz);
161         if(res->rectf)
162                 RE_freeN(res->rectf);
163         
164         RE_freeN(res);
165 }
166
167 /* called by main render as well for parts */
168 /* will read info from Render *re to define layers */
169 /* called in threads */
170 /* winrct is coordinate rect of entire image, partrct the part within */
171 static RenderResult *new_render_result(Render *re, rcti *partrct, int crop)
172 {
173         RenderResult *rr;
174         RenderLayer *rl;
175         SceneRenderLayer *srl;
176         int rectx, recty;
177         
178         rectx= partrct->xmax - partrct->xmin;
179         recty= partrct->ymax - partrct->ymin;
180         
181         if(rectx<=0 || recty<=0)
182                 return NULL;
183         
184         rr= RE_callocN(sizeof(RenderResult), "new render result");
185         rr->rectx= rectx;
186         rr->recty= recty;
187         /* crop is one or two extra pixels rendered for filtering, is used for merging and display too */
188         rr->crop= crop;
189         
190         /* tilerect is relative coordinates within render disprect. do not subtract crop yet */
191         rr->tilerect.xmin= partrct->xmin - re->disprect.xmin;
192         rr->tilerect.xmax= partrct->xmax - re->disprect.xmax;
193         rr->tilerect.ymin= partrct->ymin - re->disprect.ymin;
194         rr->tilerect.ymax= partrct->ymax - re->disprect.ymax;
195         
196         /* copy, so display callbacks can find out too */
197         rr->actlay= re->r.actlay;
198         
199         /* check renderdata for amount of layers */
200         for(srl= re->r.layers.first; srl; srl= srl->next) {
201                 rl= RE_callocN(sizeof(RenderLayer), "new render layer");
202                 BLI_addtail(&rr->layers, rl);
203                 
204                 strcpy(rl->name, srl->name);
205                 rl->lay= srl->lay;
206                 rl->layflag= srl->layflag;
207                 rl->passflag= srl->passflag;
208                 
209                 rl->rectf= RE_callocN(rectx*recty*sizeof(float)*4, "layer float rgba");
210                 if(srl->passflag  & SCE_PASS_Z)
211                         rl->rectz= RE_callocN(rectx*recty*sizeof(float), "layer float Z");
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
233 /* used when rendering to a full buffer, or when reading the exr part-layer-pass file */
234 /* no test happens here if it fits... we also assume layers are in sync */
235 /* is used within threads */
236 static void merge_render_result(RenderResult *rr, RenderResult *rrpart)
237 {
238         RenderLayer *rl, *rlp;
239         float *rf, *rfp;
240         float *rz, *rzp;
241         int y, height, len, copylen;
242         
243         for(rl= rr->layers.first, rlp= rrpart->layers.first; rl && rlp; rl= rl->next, rlp= rlp->next) {
244                 
245                 /* first combined and z pass */
246                 if(rl->rectf && rlp->rectf) {
247                         int ofs;
248                         
249                         rzp= rlp->rectz;
250                         rfp= rlp->rectf;
251                         
252                         copylen=len= rrpart->rectx;
253                         height= rrpart->recty;
254                         
255                         if(rrpart->crop) {      /* filters add pixel extra */
256                                 
257                                 if(rzp) rzp+= rrpart->crop + rrpart->crop*len;
258                                 if(rfp) rfp+= 4*(rrpart->crop + rrpart->crop*len);
259                                 
260                                 copylen= len-2*rrpart->crop;
261                                 height -= 2*rrpart->crop;
262                                 
263                                 ofs= (rrpart->tilerect.ymin + rrpart->crop)*rr->rectx + (rrpart->tilerect.xmin+rrpart->crop);
264                                 rz= rl->rectz+ ofs;
265                                 rf= rl->rectf+ 4*ofs;
266                         }
267                         else {
268                                 ofs= (rrpart->tilerect.ymin*rr->rectx + rrpart->tilerect.xmin);
269                                 rz= rl->rectz+ ofs;
270                                 rf= rl->rectf+ 4*ofs;
271                         }
272
273                         for(y=0; y<height; y++) {
274                                 if(rzp) {
275                                         memcpy(rz, rzp, 4*copylen);
276                                         rz+= rr->rectx;
277                                         rzp+= len;
278                                 }
279                                 if(rfp) {
280                                         memcpy(rf, rfp, 16*copylen);
281                                         rf+= 4*rr->rectx;
282                                         rfp+= 4*len;
283                                 }
284                         }
285                 }
286         }
287 }
288
289
290 /* *************************************************** */
291
292 Render *RE_GetRender(const char *name)
293 {
294         Render *re;
295         
296         /* search for existing renders */
297         for(re= RenderList.first; re; re= re->next) {
298                 if(strncmp(re->name, name, RE_MAXNAME)==0) {
299                         break;
300                 }
301         }
302         return re;
303 }
304
305 /* if you want to know exactly what has been done */
306 RenderResult *RE_GetResult(Render *re)
307 {
308         if(re)
309                 return re->result;
310         return NULL;
311 }
312
313 /* fill provided result struct with what's currently active or done */
314 void RE_GetResultImage(Render *re, RenderResult *rr)
315 {
316         memset(rr, sizeof(RenderResult), 0);
317
318         if(re && re->result) {
319                 RenderLayer *rl;
320                 
321                 rr->rectx= re->result->rectx;
322                 rr->recty= re->result->recty;
323                 
324                 rr->rectf= re->result->rectf;
325                 rr->rectz= re->result->rectz;
326                 rr->rect32= re->result->rect32;
327                 
328                 /* active layer */
329                 rl= BLI_findlink(&re->result->layers, re->r.actlay);
330                 if(rl) {
331                         if(rr->rectf==NULL)
332                                 rr->rectf= rl->rectf;
333                         if(rr->rectz==NULL)
334                                 rr->rectz= rl->rectz;   
335                 }
336         }
337 }
338
339 #define FTOCHAR(val) val<=0.0f?0: (val>=1.0f?255: (char)(255.0f*val))
340 /* caller is responsible for allocating rect in correct size! */
341 void RE_ResultGet32(Render *re, unsigned int *rect)
342 {
343         RenderResult rres;
344         
345         RE_GetResultImage(re, &rres);
346         if(rres.rect32) 
347                 memcpy(rect, rres.rect32, sizeof(int)*rres.rectx*rres.recty);
348         else if(rres.rectf) {
349                 float *fp= rres.rectf;
350                 int tot= rres.rectx*rres.recty;
351                 char *cp= (char *)rect;
352                 
353                 for(;tot>0; tot--, cp+=4, fp+=4) {
354                         cp[0] = FTOCHAR(fp[0]);
355                         cp[1] = FTOCHAR(fp[1]);
356                         cp[2] = FTOCHAR(fp[2]);
357                         cp[3] = FTOCHAR(fp[3]);
358                 }
359         }
360         else
361                 /* else fill with black */
362                 memset(rect, sizeof(int)*re->rectx*re->recty, 0);
363 }
364
365
366 RenderStats *RE_GetStats(Render *re)
367 {
368         return &re->i;
369 }
370
371 Render *RE_NewRender(const char *name)
372 {
373         Render *re;
374         
375         /* only one render per name exists */
376         re= RE_GetRender(name);
377         if(re) {
378                 BLI_remlink(&RenderList, re);
379                 RE_FreeRender(re);
380         }
381         
382         /* new render data struct */
383         re= RE_callocN(sizeof(Render), "new render");
384         BLI_addtail(&RenderList, re);
385         strncpy(re->name, name, RE_MAXNAME);
386         
387         /* set default empty callbacks */
388         re->display_init= result_nothing;
389         re->display_clear= result_nothing;
390         re->display_draw= result_rcti_nothing;
391         re->timecursor= int_nothing;
392         re->test_break= void_nothing;
393         re->test_return= void_nothing;
394         re->error= print_error; 
395         re->stats_draw= stats_nothing;
396         
397         /* init some variables */
398         re->ycor= 1.0f;
399         
400         return re;
401 }
402
403 /* only call this while you know it will remove the link too */
404 void RE_FreeRender(Render *re)
405 {
406         
407         free_renderdata_tables(re);
408         free_sample_tables(re);
409         
410         free_render_result(re->result);
411         
412         BLI_remlink(&RenderList, re);
413         RE_freeN(re);
414 }
415
416 /* exit blender */
417 void RE_FreeAllRender(void)
418 {
419         while(RenderList.first) {
420                 RE_FreeRender(RenderList.first);
421         }
422 }
423
424 /* ********* initialize state ******** */
425
426
427 /* what doesn't change during entire render sequence */
428 /* disprect is optional, if NULL it assumes full window render */
429 void RE_InitState(Render *re, RenderData *rd, int winx, int winy, rcti *disprect)
430 {
431         re->ok= TRUE;   /* maybe flag */
432         
433         re->i.starttime= PIL_check_seconds_timer();
434         re->r= *rd;             /* hardcopy */
435         
436         re->winx= winx;
437         re->winy= winy;
438         if(disprect) {
439                 re->disprect= *disprect;
440                 re->rectx= disprect->xmax-disprect->xmin;
441                 re->recty= disprect->ymax-disprect->ymin;
442         }
443         else {
444                 re->disprect.xmin= re->disprect.xmax= 0;
445                 re->disprect.xmax= winx;
446                 re->disprect.ymax= winy;
447                 re->rectx= winx;
448                 re->recty= winy;
449         }
450         
451         if(re->rectx < 2 || re->recty < 2) {
452                 re->error("Image too small");
453                 re->ok= 0;
454         }
455         else {
456                 /* check state variables, osa? */
457                 if(re->r.mode & (R_OSA|R_MBLUR)) {
458                         re->osa= re->r.osa;
459                         if(re->osa>16) re->osa= 16;
460                 }
461                 else re->osa= 0;
462                 
463                 /* always call, checks for gamma, gamma tables and jitter too */
464                 make_sample_tables(re); 
465                 
466                 /* initialize render result */
467                 free_render_result(re->result);
468                 re->result= new_render_result(re, &re->disprect, 0);
469
470         }
471 }
472
473 void RE_SetDispRect (struct Render *re, rcti *disprect)
474 {
475         re->disprect= *disprect;
476         re->rectx= disprect->xmax-disprect->xmin;
477         re->recty= disprect->ymax-disprect->ymin;
478         
479         /* initialize render result */
480         free_render_result(re->result);
481         re->result= new_render_result(re, &re->disprect, 0);
482 }
483
484 void RE_SetWindow(Render *re, rctf *viewplane, float clipsta, float clipend)
485 {
486         /* re->ok flag? */
487         
488         re->viewplane= *viewplane;
489         re->clipsta= clipsta;
490         re->clipend= clipend;
491
492         i_window(re->viewplane.xmin, re->viewplane.xmax, re->viewplane.ymin, re->viewplane.ymax, re->clipsta, re->clipend, re->winmat);
493 }
494
495 void RE_SetOrtho(Render *re, rctf *viewplane, float clipsta, float clipend)
496 {
497         /* re->ok flag? */
498         
499         re->viewplane= *viewplane;
500         re->clipsta= clipsta;
501         re->clipend= clipend;
502         re->r.mode |= R_ORTHO;
503
504         i_ortho(re->viewplane.xmin, re->viewplane.xmax, re->viewplane.ymin, re->viewplane.ymax, re->clipsta, re->clipend, re->winmat);
505 }
506
507 void RE_SetView(Render *re, float mat[][4])
508 {
509         /* re->ok flag? */
510         Mat4CpyMat4(re->viewmat, mat);
511         Mat4Invert(re->viewinv, re->viewmat);
512 }
513
514 /* image and movie output has to move to either imbuf or kernel */
515
516 void RE_display_init_cb(Render *re, void (*f)(RenderResult *rr))
517 {
518         re->display_init= f;
519 }
520 void RE_display_clear_cb(Render *re, void (*f)(RenderResult *rr))
521 {
522         re->display_clear= f;
523 }
524 void RE_display_draw_cb(Render *re, void (*f)(RenderResult *rr, rcti *rect))
525 {
526         re->display_draw= f;
527 }
528
529 void RE_stats_draw_cb(Render *re, void (*f)(RenderStats *rs))
530 {
531         re->stats_draw= f;
532 }
533 void RE_timecursor_cb(Render *re, void (*f)(int))
534 {
535         re->timecursor= f;
536 }
537
538 void RE_test_break_cb(Render *re, int (*f)(void))
539 {
540         re->test_break= f;
541 }
542 void RE_test_return_cb(Render *re, int (*f)(void))
543 {
544         re->test_return= f;
545 }
546 void RE_error_cb(Render *re, void (*f)(const char *str))
547 {
548         re->error= f;
549 }
550
551
552 /* ********* add object data (later) ******** */
553
554 /* object is considered fully prepared on correct time etc */
555 /* includes lights */
556 void RE_AddObject(Render *re, Object *ob)
557 {
558         
559 }
560
561 /* *************************************** */
562
563 static int do_part_thread(void *pa_v)
564 {
565         RenderPart *pa= pa_v;
566         
567         /* need to return nicely all parts on esc */
568         if(R.test_break()==0) {
569                 
570                 pa->result= new_render_result(&R, &pa->disprect, pa->crop);
571                 
572                 if(R.osa)
573                         zbufshadeDA_tile(pa);
574                 else
575                         zbufshade_tile(pa);
576                         
577                 if(!R.test_break())
578                         merge_render_result(R.result, pa->result);
579         }
580         
581         pa->ready= 1;
582         
583         return 0;
584 }
585
586 /* returns with render result filled, not threaded */
587 static void render_tile_processor(Render *re)
588 {
589         RenderPart *pa;
590         
591         if(re->test_break())
592                 return;
593         
594         re->i.lastframetime= PIL_check_seconds_timer()- re->i.starttime;
595         re->stats_draw(&re->i);
596         re->i.starttime= PIL_check_seconds_timer();
597  
598         if(re->result==NULL)
599                 return;
600         
601         initparts(re);
602         
603         /* assuming no new data gets added to dbase... */
604         R= *re;
605         
606         for(pa= re->parts.first; pa; pa= pa->next) {
607                 do_part_thread(pa);
608                 
609                 if(pa->result) {
610                         if(!re->test_break()) {
611                                 re->display_draw(pa->result, NULL);
612                                 re->i.partsdone++;
613                         }
614                         free_render_result(pa->result);
615                         pa->result= NULL;
616                 }               
617                 if(re->test_break())
618                         break;
619         }
620         
621         re->i.lastframetime= PIL_check_seconds_timer()- re->i.starttime;
622         re->stats_draw(&re->i);
623
624         freeparts(re);
625 }
626
627 static RenderPart *find_nicest_part(Render *re)
628 {
629         RenderPart *pa, *best= NULL;
630         int centx=re->winx/2, centy=re->winy/2, tot=1;
631         int mindist, distx, disty;
632         
633         /* find center of rendered parts, image center counts for 1 too */
634         for(pa= re->parts.first; pa; pa= pa->next) {
635                 if(pa->ready) {
636                         centx+= (pa->disprect.xmin+pa->disprect.xmax)/2;
637                         centy+= (pa->disprect.ymin+pa->disprect.ymax)/2;
638                         tot++;
639                 }
640         }
641         centx/=tot;
642         centy/=tot;
643         
644         /* closest of the non-rendering parts */
645         mindist= re->winx*re->winy;
646         for(pa= re->parts.first; pa; pa= pa->next) {
647                 if(pa->ready==0 && pa->nr==0) {
648                         distx= centx - (pa->disprect.xmin+pa->disprect.xmax)/2;
649                         disty= centy - (pa->disprect.ymin+pa->disprect.ymax)/2;
650                         distx= (int)sqrt(distx*distx + disty*disty);
651                         if(distx<mindist) {
652                                 best= pa;
653                                 mindist= distx;
654                         }
655                 }
656         }
657         return best;
658 }
659
660 static void threaded_tile_processor(Render *re)
661 {
662         ListBase threads;
663         RenderPart *pa;
664         int maxthreads=2, rendering=1, counter= 1;
665         
666         if(re->result==NULL)
667                 return;
668         if(re->test_break())
669                 return;
670         
671         initparts(re);
672         BLI_init_threads(&threads, do_part_thread, maxthreads);
673         
674         /* assuming no new data gets added to dbase... */
675         R= *re;
676         
677         malloc_lock = SDL_CreateMutex();
678         
679         while(rendering) {
680                 
681                 /* I noted that test_break() in a thread doesn't make ghost send ESC */
682                 if(BLI_available_threads(&threads) && !re->test_break()) {
683                         pa= find_nicest_part(re);
684                         if(pa) {
685                                 pa->nr= counter++;      /* for nicest part, and for stats */
686                                 pa->thread= BLI_available_thread_index(&threads);       /* sample index */
687                                 BLI_insert_thread(&threads, pa);
688                         }
689                 }
690                 else
691                         PIL_sleep_ms(50);
692                 
693                 /* check for ready ones to display, and if we need to continue */
694                 rendering= 0;
695                 for(pa= re->parts.first; pa; pa= pa->next) {
696                         if(pa->ready) {
697                                 if(pa->result) {
698                                         BLI_remove_thread(&threads, pa);
699                                         re->display_draw(pa->result, NULL);
700                                         free_render_result(pa->result);
701                                         pa->result= NULL;
702                                         re->i.partsdone++;
703                                 }
704                         }
705                         else rendering= 1;
706                 }
707                 
708                 /* on break, wait for all slots to get freed */
709                 if(re->test_break() && BLI_available_threads(&threads)==maxthreads)
710                         rendering= 0;
711                 
712         }
713         
714         if(malloc_lock) SDL_DestroyMutex(malloc_lock); malloc_lock= NULL;
715         
716         BLI_end_threads(&threads);
717         freeparts(re);
718 }
719
720 void RE_TileProcessor(Render *re)
721 {
722         if(re->r.mode & R_THREADS) 
723                 threaded_tile_processor(re);
724         else
725                 render_tile_processor(re);      
726 }
727
728
729 /* ************  This part uses API, for rendering Blender scenes ********** */
730
731 void render_one_frame(Render *re)
732 {
733         
734 //      re->cfra= cfra; /* <- unused! */
735         
736         /* make render verts/faces/halos/lamps */
737         RE_Database_FromScene(re, re->scene, 1);
738
739         RE_TileProcessor(re);
740         
741         /* free all render verts etc */
742         RE_Database_Free(re);
743 }
744
745 /* accumulates osa frames */
746 static void do_render_blurred(Render *re, float frame)
747 {
748         
749 }
750
751 /* interleaves 2 frames */
752 static void do_render_fields(Render *re)
753 {
754         
755 }
756
757 static void do_render_final(Render *re, Scene *scene)
758 {
759         /* we set start time here, for main Blender loops */
760         re->i.starttime= PIL_check_seconds_timer();
761
762         if(re->r.scemode & R_DOSEQ) {
763                 re->result->rect32= MEM_callocN(sizeof(int)*re->rectx*re->recty, "rectot");
764                 if(!re->test_break()) 
765                         do_render_seq(re->result);
766         }
767         else {
768                 /* first check if theres nodetree with render result */
769                 int do_render= ntreeCompositNeedsRender(scene->nodetree);
770                 /* but.. do we use nodes? */
771                 if(scene->use_nodes==0) do_render= 1;
772                 
773                 re->scene= scene;
774                 
775                 if(do_render) {
776                         /* now use renderdata and camera to set viewplane */
777                         RE_SetCamera(re, re->scene->camera);
778                         
779                         if(re->r.mode & R_FIELDS)
780                                 do_render_fields(re);
781                         else if(re->r.mode & R_MBLUR)
782                                 do_render_blurred(re, re->scene->r.cfra);
783                         else
784                                 render_one_frame(re);
785                 }
786                 
787                 ntreeCompositTagRender(scene->nodetree);
788                 ntreeCompositTagAnimated(scene->nodetree);
789                 
790                 if(re->r.scemode & R_DOCOMP)
791                         ntreeCompositExecTree(scene->nodetree, &re->r, 0);
792         }
793         
794
795         re->i.lastframetime= PIL_check_seconds_timer()- re->i.starttime;
796         re->stats_draw(&re->i);
797         
798         re->display_draw(re->result, NULL);
799         
800 }
801
802
803 static int is_rendering_allowed(Render *re)
804 {
805         
806         /* forbidden combinations */
807         if(re->r.mode & R_PANORAMA) {
808                 if(re->r.mode & R_BORDER) {
809                         re->error("No border supported for Panorama");
810                         return 0;
811                 }
812                 if(re->r.yparts>1) {
813                         re->error("No Y-Parts supported for Panorama");
814                         return 0;
815                 }
816                 if(re->r.mode & R_ORTHO) {
817                         re->error("No Ortho render possible for Panorama");
818                         return 0;
819                 }
820         }
821         
822         if(re->r.mode & R_BORDER) {
823                 if(re->r.border.xmax <= re->r.border.xmin || 
824                    re->r.border.ymax <= re->r.border.ymin) {
825                         re->error("No border area selected.");
826                         return 0;
827                 }
828         }
829         
830         if(re->r.xparts*re->r.yparts>=2 && (re->r.mode & R_MOVIECROP) && (re->r.mode & R_BORDER)) {
831                 re->error("Combination of border, crop and parts not allowed");
832                 return 0;
833         }
834         
835         if(re->r.xparts*re->r.yparts>64) {
836                 re->error("No more than 64 parts supported");
837                 return 0;
838         }
839         
840         if(re->r.yparts>1 && (re->r.mode & R_PANORAMA)) {
841                 re->error("No Y-Parts supported for Panorama");
842                 return 0;
843         }
844         
845         /* check valid camera */
846         if(re->scene->camera==NULL)
847                 re->scene->camera= scene_find_camera(re->scene);
848         if(re->scene->camera==NULL) {
849                 re->error("No camera");
850                 return 0;
851         }
852         
853         
854         return 1;
855 }
856
857 /* evaluating scene options for general Blender render */
858 static int render_initialize_from_scene(Render *re, Scene *scene)
859 {
860         int winx, winy;
861         rcti disprect;
862         
863         /* r.xsch and r.ysch has the actual view window size
864                 r.border is the clipping rect */
865         
866         /* calculate actual render result and display size */
867         winx= (scene->r.size*scene->r.xsch)/100;
868         winy= (scene->r.size*scene->r.ysch)/100;
869         //      if(scene->r.mode & R_PANORAMA)
870         //              winx*= scene->r.xparts;
871         
872         /* only in movie case we render smaller part */
873         if(scene->r.mode & R_BORDER) {
874                 disprect.xmin= scene->r.border.xmin*winx;
875                 disprect.xmax= scene->r.border.xmax*winx;
876                 
877                 disprect.ymin= scene->r.border.ymin*winy;
878                 disprect.ymax= scene->r.border.ymax*winy;
879         }
880         else {
881                 disprect.xmin= disprect.ymin= 0;
882                 disprect.xmax= winx;
883                 disprect.ymax= winy;
884         }
885         
886         RE_InitState(re, &scene->r, winx, winy, &disprect);
887         
888         re->scene= scene;
889         if(!is_rendering_allowed(re))
890                 return 0;
891         
892         re->display_init(re->result);
893         re->display_clear(re->result);
894         
895         return 1;
896 }
897
898 /* general Blender frame render call */
899 /* should return 1 when all is OK, otherwise it throws up errors */
900 void RE_BlenderFrame(Render *re, Scene *scene, int frame)
901 {
902         /* ugly global still... is to prevent renderwin events and signal subsurfs etc to make full resol */
903         /* is also set by caller renderwin.c */
904         G.rendering= 1;
905         
906         if(render_initialize_from_scene(re, scene)) {
907                 do_render_final(re, scene);
908         }
909 }
910
911
912 /* saves images to disk */
913 void RE_BlenderAnim(Render *re, Scene *scene, int sfra, int efra)
914 {
915         bMovieHandle *mh= BKE_get_movie_handle(scene->r.imtype);
916         int cfrao= scene->r.cfra;
917         char name[FILE_MAXDIR+FILE_MAXFILE];
918         
919         /* ugly global still... is to prevent renderwin events and signal subsurfs etc to make full resol */
920         /* is also set by caller renderwin.c */
921         G.rendering= 1;
922         
923         if(!render_initialize_from_scene(re, scene))
924            return;
925         
926         /* confusing... scene->r or re->r? make a decision once! */
927         if(BKE_imtype_is_movie(scene->r.imtype))
928                 mh->start_movie(&scene->r, re->rectx, re->recty);
929         
930         for(scene->r.cfra= sfra; scene->r.cfra<=efra; scene->r.cfra++) {
931                 re->r.cfra= scene->r.cfra;      /* weak.... */
932                 
933                 do_render_final(re, scene);
934                 
935                 /* write image or movie */
936                 if(re->test_break()==0) {
937                         RenderResult rres;
938                         
939                         RE_GetResultImage(re, &rres);
940
941                         /* write movie or image */
942                         if(BKE_imtype_is_movie(scene->r.imtype)) {
943                                 /* note; the way it gets 32 bits rects is weak... */
944                                 int dofree=0;
945                                 if(rres.rect32==NULL) {
946                                         rres.rect32= MEM_mallocN(sizeof(int)*rres.rectx*rres.recty, "temp 32 bits rect");
947                                         dofree= 1;
948                                 }
949                                 RE_ResultGet32(re, rres.rect32);
950                                 mh->append_movie(scene->r.cfra, rres.rect32, rres.rectx, rres.recty);
951                                 if(dofree) MEM_freeN(rres.rect32);
952                                 printf("Append frame %d", scene->r.cfra);
953                         }
954                         else {
955                                 ImBuf *ibuf= IMB_allocImBuf(rres.rectx, rres.recty, scene->r.planes, 0, 0);
956                                 int ok;
957                                 
958                                 BKE_makepicstring(name, (scene->r.cfra));
959                                 ibuf->rect= rres.rect32;                /* if not exists, BKE_write_ibuf makes one */
960                                 ibuf->rect_float= rres.rectf;
961                                 ibuf->zbuf_float= rres.rectz;
962                                 ok= BKE_write_ibuf(ibuf, name, scene->r.imtype, scene->r.subimtype, scene->r.quality);
963                                 IMB_freeImBuf(ibuf);    /* imbuf knows which rects are not part of ibuf */
964
965                                 if(ok==0) {
966                                         printf("Render error: cannot save %s\n", name);
967                                         break;
968                                 }
969                                 else printf("Saved: %s", name);
970                         }
971                         
972                         BLI_timestr(re->i.lastframetime, name);
973                         printf(" Time: %s\n", name);
974                         fflush(stdout); /* needed for renderd !! (not anymore... (ton)) */
975                 }
976                 
977                 if(G.afbreek==1) break;
978         }
979         
980         /* end movie */
981         if(BKE_imtype_is_movie(scene->r.imtype))
982                 mh->end_movie();
983
984         scene->r.cfra= cfrao;
985 }
986
987
988