Fix #35561: freestyle + read full sample layers = crash.
authorTamito Kajiyama <rd6t-kjym@asahi-net.or.jp>
Tue, 11 Jun 2013 02:32:01 +0000 (02:32 +0000)
committerTamito Kajiyama <rd6t-kjym@asahi-net.or.jp>
Tue, 11 Jun 2013 02:32:01 +0000 (02:32 +0000)
Now add_freestyle() in pipeline.c takes a second argument to enable/disable
stroke rendering.  When stroke rendering is disabled, the function allocates
data structures but does not perform stroke rendering.  The allocated data
structures (mostly left unpopulated with data elements) are intended to allow
for the Read Full Sample Layers (Shift-R) command in the compositor.

source/blender/freestyle/FRS_freestyle.h
source/blender/freestyle/intern/application/Controller.cpp
source/blender/freestyle/intern/application/Controller.h
source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp
source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.h
source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp
source/blender/render/extern/include/RE_pipeline.h
source/blender/render/intern/source/pipeline.c

index b10a73277bfd96784bc497898061d511ef68a61f..7be51b37f7a47462999deae90ef2547ccf49de5d 100644 (file)
@@ -45,7 +45,7 @@ void FRS_set_context(struct bContext *C);
 void FRS_read_file(struct bContext *C);
 int FRS_is_freestyle_enabled(struct SceneRenderLayer *srl);
 void FRS_init_stroke_rendering(struct Render *re);
-struct Render *FRS_do_stroke_rendering(struct Render *re, struct SceneRenderLayer *srl);
+struct Render *FRS_do_stroke_rendering(struct Render *re, struct SceneRenderLayer *srl, int render);
 void FRS_finish_stroke_rendering(struct Render *re);
 void FRS_composite_result(struct Render *re, struct SceneRenderLayer *srl, struct Render *freestyle_render);
 void FRS_exit(void);
index 436cdbfe6b5a3b1b2e903153f6a3d38ea5587326..dbf3fa8349eae413f32e8ebefc8a56c130674332 100644 (file)
@@ -833,17 +833,18 @@ void Controller::ResetRenderCount()
        _render_count = 0;
 }
 
-Render *Controller::RenderStrokes(Render *re)
+Render *Controller::RenderStrokes(Render *re, bool render)
 {
        _Chrono.start();
        BlenderStrokeRenderer *blenderRenderer = new BlenderStrokeRenderer(re, ++_render_count);
-       _Canvas->Render(blenderRenderer);
+       if (render)
+               _Canvas->Render(blenderRenderer);
        real d = _Chrono.stop();
        if (G.debug & G_DEBUG_FREESTYLE) {
                cout << "Temporary scene generation: " << d << endl;
        }
        _Chrono.start();
-       Render *freestyle_render = blenderRenderer->RenderScene(re);
+       Render *freestyle_render = blenderRenderer->RenderScene(re, render);
        d = _Chrono.stop();
        if (G.debug & G_DEBUG_FREESTYLE) {
                cout << "Stroke rendering  : " << d << endl;
index 3315fe7e20be9ed6347dc318ea63f0c93eb8505a..c8eaaf5486b7ee5cbc7cb2ad2940d4cff7cdddfb 100644 (file)
@@ -86,7 +86,7 @@ public:
        void toggleEdgeTesselationNature(Nature::EdgeNature iNature);
        void DrawStrokes();
        void ResetRenderCount();
-       Render *RenderStrokes(Render *re);
+       Render *RenderStrokes(Render *re, bool render);
        void SwapStyleModules(unsigned i1, unsigned i2);
        void InsertStyleModule(unsigned index, const char *iFileName);
        void InsertStyleModule(unsigned index, const char *iName, struct Text *iText);
index 294da904497f453823794238f792929cf6d7c680..096447de214cd16ab287bd9280d4799b95696c06 100644 (file)
@@ -476,7 +476,7 @@ Object *BlenderStrokeRenderer::NewMesh() const
        return ob;
 }
 
-Render *BlenderStrokeRenderer::RenderScene(Render *re)
+Render *BlenderStrokeRenderer::RenderScene(Render *re, bool render)
 {
        Camera *camera = (Camera *)freestyle_scene->camera->data;
        if (camera->clipend < _z)
@@ -489,7 +489,7 @@ Render *BlenderStrokeRenderer::RenderScene(Render *re)
 
        Render *freestyle_render = RE_NewRender(freestyle_scene->id.name);
 
-       RE_RenderFreestyleStrokes(freestyle_render, freestyle_bmain, freestyle_scene);
+       RE_RenderFreestyleStrokes(freestyle_render, freestyle_bmain, freestyle_scene, render);
 
        return freestyle_render;
 }
index 4d34f70f689544cc4d03aa195cc3e560bfc71d0e..ae0e6bed3b2afb4741ed97b5cef0f70d06c89da9 100644 (file)
@@ -51,7 +51,7 @@ public:
 
        Object *NewMesh() const;
 
-       Render *RenderScene(Render *re);
+       Render *RenderScene(Render *re, bool render);
 
 protected:
        Main *freestyle_bmain;
index d5002d6fa39333246ac62d43fe688cc998d2391f..8cb44d05b842fc169e72ab37296c618f9c506cf8 100644 (file)
@@ -580,12 +580,15 @@ void FRS_init_stroke_rendering(Render *re)
        controller->ResetRenderCount();
 }
 
-Render *FRS_do_stroke_rendering(Render *re, SceneRenderLayer *srl)
+Render *FRS_do_stroke_rendering(Render *re, SceneRenderLayer *srl, int render)
 {
        Main bmain = {0};
        Render *freestyle_render = NULL;
        Text *text, *next_text;
 
+       if (!render)
+               return controller->RenderStrokes(re, false);
+
        RenderMonitor monitor(re);
        controller->setRenderMonitor(&monitor);
 
@@ -619,7 +622,7 @@ Render *FRS_do_stroke_rendering(Render *re, SceneRenderLayer *srl)
                re->i.infostr = NULL;
                freestyle_scene = re->scene;
                controller->DrawStrokes();
-               freestyle_render = controller->RenderStrokes(re);
+               freestyle_render = controller->RenderStrokes(re, true);
                controller->CloseFile();
                freestyle_scene = NULL;
 
index 52d42cd20a408eceb5da74a3deb88ceed5d6e71a..118d0036464741bdc7ebb61ce65b4563629a2bab 100644 (file)
@@ -226,7 +226,7 @@ void RE_TileProcessor(struct Render *re);
 void RE_BlenderFrame(struct Render *re, struct Main *bmain, struct Scene *scene, struct SceneRenderLayer *srl, struct Object *camera_override, unsigned int lay, int frame, const short write_still);
 void RE_BlenderAnim(struct Render *re, struct Main *bmain, struct Scene *scene, struct Object *camera_override, unsigned int lay, int sfra, int efra, int tfra);
 #ifdef WITH_FREESTYLE
-void RE_RenderFreestyleStrokes(struct Render *re, struct Main *bmain, struct Scene *scene);
+void RE_RenderFreestyleStrokes(struct Render *re, struct Main *bmain, struct Scene *scene, int render);
 #endif
 
 /* error reporting */
index c8f8f844e5f52a3f97d3d902b5363caa2b9e0efb..068df215edbb2d0ca7965c6bde43fc24b725a27e 100644 (file)
@@ -1081,7 +1081,7 @@ static void threaded_tile_processor(Render *re)
 }
 
 #ifdef WITH_FREESTYLE
-static void add_freestyle(Render *re);
+static void add_freestyle(Render *re, int render);
 static void free_all_freestyle_renders(void);
 #endif
 
@@ -1097,7 +1097,7 @@ void RE_TileProcessor(Render *re)
        /* Freestyle */
        if (re->r.mode & R_EDGE_FRS) {
                if (!re->test_break(re->tbh)) {
-                       add_freestyle(re);
+                       add_freestyle(re, 1);
        
                        free_all_freestyle_renders();
                        
@@ -1150,7 +1150,7 @@ static void do_render_3d(Render *re)
        /* Freestyle */
        if (re->r.mode & R_EDGE_FRS)
                if (!re->test_break(re->tbh))
-                       add_freestyle(re);
+                       add_freestyle(re, 1);
 #endif
        
        /* do left-over 3d post effects (flares) */
@@ -1633,7 +1633,7 @@ static void render_composit_stats(void *UNUSED(arg), char *str)
 
 #ifdef WITH_FREESTYLE
 /* invokes Freestyle stroke rendering */
-static void add_freestyle(Render *re)
+static void add_freestyle(Render *re, int render)
 {
        SceneRenderLayer *srl, *actsrl;
        LinkData *link;
@@ -1659,7 +1659,7 @@ static void add_freestyle(Render *re)
                if ((re->r.scemode & R_SINGLE_LAYER) && srl != actsrl)
                        continue;
                if (FRS_is_freestyle_enabled(srl)) {
-                       link->data = (void *)FRS_do_stroke_rendering(re, srl);
+                       link->data = (void *)FRS_do_stroke_rendering(re, srl, render);
                }
        }
 
@@ -1853,6 +1853,11 @@ void RE_MergeFullSample(Render *re, Main *bmain, Scene *sce, bNodeTree *ntree)
        for (scene = re->main->scene.first; scene; scene = scene->id.next)
                scene->id.flag |= LIB_DOIT;
        
+#ifdef WITH_FREESTYLE
+       for (scene = re->freestyle_bmain.scene.first; scene; scene = scene->id.next)
+               scene->id.flag &= ~LIB_DOIT;
+#endif
+
        for (node = ntree->nodes.first; node; node = node->next) {
                if (node->type == CMP_NODE_R_LAYERS) {
                        Scene *nodescene = (Scene *)node->id;
@@ -1876,7 +1881,16 @@ void RE_MergeFullSample(Render *re, Main *bmain, Scene *sce, bNodeTree *ntree)
        re->display_init(re->dih, re->result);
        re->display_clear(re->dch, re->result);
        
+#ifdef WITH_FREESTYLE
+       if (re->r.mode & R_EDGE_FRS)
+               add_freestyle(re, 0);
+#endif
+
        do_merge_fullsample(re, ntree);
+
+#ifdef WITH_FREESTYLE
+       free_all_freestyle_renders();
+#endif
 }
 
 /* returns fully composited render-result on given time step (in RenderData) */
@@ -2445,11 +2459,12 @@ void RE_BlenderFrame(Render *re, Main *bmain, Scene *scene, SceneRenderLayer *sr
 }
 
 #ifdef WITH_FREESTYLE
-void RE_RenderFreestyleStrokes(Render *re, Main *bmain, Scene *scene)
+void RE_RenderFreestyleStrokes(Render *re, Main *bmain, Scene *scene, int render)
 {
        re->result_ok= 0;
        if (render_initialize_from_main(re, bmain, scene, NULL, NULL, scene->lay, 0, 0)) {
-               do_render_fields_blur_3d(re);
+               if (render)
+                       do_render_fields_blur_3d(re);
        }
        re->result_ok = 1;
 }