Merged changes in the trunk up to revision 39896.
[blender.git] / source / blender / render / intern / source / pipeline.c
index 49e5e7b989d4f76f28cf7de89bf3e28662c89ed9..6f1df7fa0b7b169b3f919fb9c878a39d7080f1fd 100644 (file)
@@ -50,6 +50,7 @@
 #include "BKE_animsys.h"       /* <------ should this be here?, needed for sequencer update */
 #include "BKE_global.h"
 #include "BKE_image.h"
+#include "BKE_library.h"
 #include "BKE_main.h"
 #include "BKE_node.h"
 #include "BKE_object.h"
@@ -75,6 +76,9 @@
 
 #include "RE_pipeline.h"
 
+#include "FRS_freestyle.h"
+#include "FRS_freestyle_config.h"
+
 /* internal */
 #include "render_types.h"
 #include "renderpipeline.h"
@@ -671,6 +675,7 @@ static RenderResult *new_render_result(Render *re, rcti *partrct, int crop, int
                rl->lay= (1<<20) -1;
                rl->layflag= 0x7FFF;    /* solid ztra halo strand */
                rl->passflag= SCE_PASS_COMBINED;
+               FRS_add_freestyle_config( srl );
                
                re->r.actlay= 0;
        }
@@ -1574,7 +1579,7 @@ static RenderPart *find_next_pano_slice(Render *re, int *minx, rctf *viewplane)
 
                R.panodxp= (re->winx - (best->disprect.xmin + best->disprect.xmax) )/2;
                R.panodxv= ((viewplane->xmax-viewplane->xmin)*R.panodxp)/(float)(re->winx);
-
+               
                /* shift viewplane */
                R.viewplane.xmin = viewplane->xmin + R.panodxv;
                R.viewplane.xmax = viewplane->xmax + R.panodxv;
@@ -1810,6 +1815,7 @@ void RE_TileProcessor(Render *re)
 /* ************  This part uses API, for rendering Blender scenes ********** */
 
 static int external_render_3d(Render *re, int do_all);
+static void add_freestyle(Render *re);
 
 static void do_render_3d(Render *re)
 {
@@ -1843,6 +1849,11 @@ static void do_render_3d(Render *re)
                if(!re->test_break(re->tbh))
                        add_halo_flare(re);
        
+       /* Freestyle  */
+       if( re->r.mode & R_EDGE_FRS && re->r.renderer==R_INTERN)
+               if(!re->test_break(re->tbh))
+                       add_freestyle(re);
+               
        /* free all render verts etc */
        RE_Database_Free(re);
        
@@ -2279,6 +2290,66 @@ static void render_composit_stats(void *UNUSED(arg), char *str)
 }
 
 
+/* invokes Freestyle stroke rendering */
+static void add_freestyle(Render *re)
+{
+       SceneRenderLayer *srl;
+       LinkData *link;
+
+       FRS_init_stroke_rendering(re);
+
+       for(srl= (SceneRenderLayer *)re->scene->r.layers.first; srl; srl= srl->next) {
+
+               link = (LinkData *)MEM_callocN(sizeof(LinkData), "LinkData to Freestyle render");
+               BLI_addtail(&re->freestyle_renders, link);
+
+               if( FRS_is_freestyle_enabled(srl) ) {
+                       link->data = (void *)FRS_do_stroke_rendering(re, srl);
+               }
+       }
+
+       FRS_finish_stroke_rendering(re);
+}
+
+/* merges the results of Freestyle stroke rendering into a given render result */
+static void composite_freestyle_renders(Render *re, int sample)
+{
+       Render *freestyle_render;
+       SceneRenderLayer *srl;
+       LinkData *link;
+
+       link = (LinkData *)re->freestyle_renders.first;
+       for(srl= (SceneRenderLayer *)re->scene->r.layers.first; srl; srl= srl->next) {
+               if( FRS_is_freestyle_enabled(srl) ) {
+                       freestyle_render = (Render *)link->data;
+                       read_render_result(freestyle_render, sample);
+                       FRS_composite_result(re, srl, freestyle_render);
+                       RE_FreeRenderResult(freestyle_render->result);
+                       freestyle_render->result = NULL;
+               }
+               link = link->next;
+       }
+}
+
+/* releases temporary scenes and renders for Freestyle stroke rendering */
+static void free_all_freestyle_renders(void)
+{
+       Render *re1, *freestyle_render;
+       LinkData *link;
+
+       for(re1= RenderGlobal.renderlist.first; re1; re1= re1->next) {
+               for (link = (LinkData *)re1->freestyle_renders.first; link; link = link->next) {
+                       if (link->data) {
+                               freestyle_render = (Render *)link->data;
+                               free_libblock(&G.main->scene, freestyle_render->scene);
+                               RE_FreeRender(freestyle_render);
+                       }
+               }
+               BLI_freelistN( &re1->freestyle_renders );
+       }
+}
+
+
 /* reads all buffers, calls optional composite, merges in first result->rectf */
 static void do_merge_fullsample(Render *re, bNodeTree *ntree)
 {
@@ -2316,8 +2387,10 @@ static void do_merge_fullsample(Render *re, bNodeTree *ntree)
                for(re1= RenderGlobal.renderlist.first; re1; re1= re1->next) {
                        if(re1->scene->id.flag & LIB_DOIT) {
                                if(re1->r.scemode & R_FULL_SAMPLE) {
-                                       if(sample)
+                                       if(sample) {
                                                read_render_result(re1, sample);
+                                               composite_freestyle_renders(re1, sample);
+                                       }
                                        ntreeCompositTagRender(re1->scene); /* ensure node gets exec to put buffers on stack */
                                }
                        }
@@ -2502,6 +2575,8 @@ static void do_render_composite_fields_blur_3d(Render *re)
                        do_merge_fullsample(re, NULL);
        }
 
+       free_all_freestyle_renders();
+
        /* weak... the display callback wants an active renderlayer pointer... */
        re->result->renlay= render_get_active_layer(re, re->result);
        re->display_draw(re->ddh, re->result, NULL);
@@ -2949,7 +3024,7 @@ void RE_BlenderFrame(Render *re, Main *bmain, Scene *scene, SceneRenderLayer *sr
                BLI_exec_cb(re->main, (ID *)scene, BLI_CB_EVT_RENDER_PRE);
 
                do_render_all_options(re);
-
+               
                if(write_still && !G.afbreek) {
                        if(BKE_imtype_is_movie(scene->r.imtype)) {
                                /* operator checks this but incase its called from elsewhere */
@@ -2971,6 +3046,15 @@ void RE_BlenderFrame(Render *re, Main *bmain, Scene *scene, SceneRenderLayer *sr
        G.rendering= 0;
 }
 
+void RE_RenderFreestyleStrokes(Render *re, Main *bmain, Scene *scene)
+{
+       re->result_ok= 0;
+       if(render_initialize_from_main(re, bmain, scene, NULL, NULL, scene->lay, 0, 0)) {
+               do_render_fields_blur_3d(re);
+       }
+       re->result_ok= 1;
+}
+
 static int do_write_image_or_movie(Render *re, Scene *scene, bMovieHandle *mh, const char *name_override)
 {
        char name[FILE_MAX];