Fix T74417: Freestyle render removes image texture users
authorBrecht Van Lommel <brecht@blender.org>
Thu, 26 Mar 2020 00:14:08 +0000 (01:14 +0100)
committerBrecht Van Lommel <brecht@blender.org>
Thu, 26 Mar 2020 00:29:20 +0000 (01:29 +0100)
This simplifies freestyle render pipeline integration so we don't have to do
much manual ID user management at all. The complexity here was legacy from
Blender Internal.

Based on fix provided by Sybren A. St├╝vl.

source/blender/freestyle/FRS_freestyle.h
source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp
source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp
source/blender/render/intern/include/render_types.h
source/blender/render/intern/source/pipeline.c

index dc8a0c7907297517662bbd82ba8f5b7f2513213e..876f40b211f33fbe7c8d5ab65309eddd44c3af82 100644 (file)
@@ -48,9 +48,7 @@ void FRS_set_context(struct bContext *C);
 int FRS_is_freestyle_enabled(struct ViewLayer *view_layer);
 void FRS_init_stroke_renderer(struct Render *re);
 void FRS_begin_stroke_rendering(struct Render *re);
-struct Render *FRS_do_stroke_rendering(struct Render *re,
-                                       struct ViewLayer *view_layer,
-                                       int render);
+void FRS_do_stroke_rendering(struct Render *re, struct ViewLayer *view_layer);
 void FRS_end_stroke_rendering(struct Render *re);
 void FRS_free_view_map_cache(void);
 void FRS_composite_result(struct Render *re,
index c88d5f24b5d74a9028c6b9f41b9c3a39ba73bc44..a61bad7cf8a103e2b236478bdb964b7a9f051391 100644 (file)
@@ -32,19 +32,19 @@ extern "C" {
 
 #include "DNA_camera_types.h"
 #include "DNA_collection_types.h"
-#include "DNA_listBase.h"
 #include "DNA_linestyle_types.h"
+#include "DNA_listBase.h"
 #include "DNA_material_types.h"
-#include "DNA_meshdata_types.h"
 #include "DNA_mesh_types.h"
+#include "DNA_meshdata_types.h"
 #include "DNA_object_types.h"
-#include "DNA_screen_types.h"
 #include "DNA_scene_types.h"
+#include "DNA_screen_types.h"
 
 #include "BKE_collection.h"
 #include "BKE_customdata.h"
-#include "BKE_idprop.h"
 #include "BKE_global.h"
+#include "BKE_idprop.h"
 #include "BKE_layer.h"
 #include "BKE_lib_id.h" /* free_libblock */
 #include "BKE_material.h"
@@ -76,7 +76,16 @@ const char *BlenderStrokeRenderer::uvNames[] = {"along_stroke", "along_stroke_ti
 
 BlenderStrokeRenderer::BlenderStrokeRenderer(Render *re, int render_count) : StrokeRenderer()
 {
-  freestyle_bmain = re->freestyle_bmain;
+  freestyle_bmain = BKE_main_new();
+
+  /* We use the same window manager for freestyle bmain as
+   * real bmain uses. This is needed because freestyle's
+   * bmain could be used to tag scenes for update, which
+   * implies call of ED_render_scene_update in some cases
+   * and that function requires proper window manager
+   * to present (sergey)
+   */
+  freestyle_bmain->wm = re->main->wm;
 
   // for stroke mesh generation
   _width = re->winx;
@@ -170,50 +179,18 @@ BlenderStrokeRenderer::BlenderStrokeRenderer(Render *re, int render_count) : Str
 
 BlenderStrokeRenderer::~BlenderStrokeRenderer()
 {
-  // The freestyle_scene object is not released here.  Instead,
-  // the scene is released in free_all_freestyle_renders() in
-  // source/blender/render/intern/source/pipeline.c, after the
-  // compositor has finished.
-
-  // release objects and data blocks
-  Base *base_next = NULL;
-  ViewLayer *view_layer = (ViewLayer *)freestyle_scene->view_layers.first;
-  for (Base *b = (Base *)view_layer->object_bases.first; b; b = base_next) {
-    base_next = b->next;
-    Object *ob = b->object;
-    char *name = ob->id.name;
-#if 0
-    if (G.debug & G_DEBUG_FREESTYLE) {
-      cout << "removing " << name[0] << name[1] << ":" << (name + 2) << endl;
-    }
-#endif
-    switch (ob->type) {
-      case OB_CAMERA:
-        freestyle_scene->camera = NULL;
-        ATTR_FALLTHROUGH;
-      case OB_MESH:
-        BKE_scene_collections_object_remove(freestyle_bmain, freestyle_scene, ob, true);
-        break;
-      default:
-        cerr << "Warning: unexpected object in the scene: " << name[0] << name[1] << ":"
-             << (name + 2) << endl;
-    }
-  }
-
-  // release materials
-  Link *lnk = (Link *)freestyle_bmain->materials.first;
-
-  while (lnk) {
-    Material *ma = (Material *)lnk;
-    lnk = lnk->next;
-    BKE_id_free(freestyle_bmain, ma);
-  }
-
   BLI_ghash_free(_nodetree_hash, NULL, NULL);
 
   DEG_graph_free(freestyle_depsgraph);
 
   FreeStrokeGroups();
+
+  /* detach the window manager from freestyle bmain (see comments
+   * in add_freestyle() for more detail)
+   */
+  BLI_listbase_clear(&freestyle_bmain->wm);
+
+  BKE_main_free(freestyle_bmain);
 }
 
 float BlenderStrokeRenderer::get_stroke_vertex_z(void) const
index 0877107a2404fccf58a2bc326275c7cceab055fa..0f4263162a66105d7be10554f95d7ad3ed766a6f 100644 (file)
@@ -637,14 +637,8 @@ void FRS_begin_stroke_rendering(Render *re)
   init_camera(re);
 }
 
-Render *FRS_do_stroke_rendering(Render *re, ViewLayer *view_layer, int render)
+void FRS_do_stroke_rendering(Render *re, ViewLayer *view_layer)
 {
-  Render *freestyle_render = NULL;
-
-  if (!render) {
-    return controller->RenderStrokes(re, false);
-  }
-
   RenderMonitor monitor(re);
   controller->setRenderMonitor(&monitor);
   controller->setViewMapCache(
@@ -685,6 +679,7 @@ Render *FRS_do_stroke_rendering(Render *re, ViewLayer *view_layer, int render)
       re->i.infostr = NULL;
       g_freestyle.scene = DEG_get_evaluated_scene(depsgraph);
       int strokeCount = controller->DrawStrokes();
+      Render *freestyle_render = NULL;
       if (strokeCount > 0) {
         freestyle_render = controller->RenderStrokes(re, true);
       }
@@ -694,15 +689,12 @@ Render *FRS_do_stroke_rendering(Render *re, ViewLayer *view_layer, int render)
       // composite result
       if (freestyle_render) {
         FRS_composite_result(re, view_layer, freestyle_render);
-        RE_FreeRenderResult(freestyle_render->result);
-        freestyle_render->result = NULL;
+        RE_FreeRender(freestyle_render);
       }
     }
   }
 
   DEG_graph_free(depsgraph);
-
-  return freestyle_render;
 }
 
 void FRS_end_stroke_rendering(Render * /*re*/)
index 1318e2498bb2b4da6263b28d5cae4139a9e136ef..3ae4b9c0b900c9f81490c13fc7c5197f740ad24f 100644 (file)
@@ -123,11 +123,6 @@ struct Render {
   Depsgraph *pipeline_depsgraph;
   Scene *pipeline_scene_eval;
 
-#ifdef WITH_FREESTYLE
-  struct Main *freestyle_bmain;
-  ListBase freestyle_renders;
-#endif
-
   /* callbacks */
   void (*display_init)(void *handle, RenderResult *rr);
   void *dih;
index 14a9ebcff5d290b756c0f664aaa56b33cc7eeaec..87568402df3af092672a4d6f10af504a10ea0894 100644 (file)
@@ -1149,14 +1149,6 @@ void RE_AddObject(Render *UNUSED(re), Object *UNUSED(ob))
 }
 #endif
 
-/* *************************************** */
-
-#ifdef WITH_FREESTYLE
-static void init_freestyle(Render *re);
-static void add_freestyle(Render *re, int render);
-static void free_all_freestyle_renders(void);
-#endif
-
 /* ************  This part uses API, for rendering Blender scenes ********** */
 
 static void do_render_3d(Render *re)
@@ -1365,87 +1357,6 @@ static void render_composit_stats(void *arg, const char *str)
   re->stats_draw(re->sdh, &i);
 }
 
-#ifdef WITH_FREESTYLE
-/* init Freestyle renderer */
-static void init_freestyle(Render *re)
-{
-  re->freestyle_bmain = BKE_main_new();
-
-  /* We use the same window manager for freestyle bmain as
-   * real bmain uses. This is needed because freestyle's
-   * bmain could be used to tag scenes for update, which
-   * implies call of ED_render_scene_update in some cases
-   * and that function requires proper window manager
-   * to present (sergey)
-   */
-  re->freestyle_bmain->wm = re->main->wm;
-
-  FRS_init_stroke_renderer(re);
-}
-
-/* invokes Freestyle stroke rendering */
-static void add_freestyle(Render *re, int render)
-{
-  ViewLayer *view_layer, *active_view_layer;
-  LinkData *link;
-  Render *r;
-
-  active_view_layer = BLI_findlink(&re->view_layers, re->active_view_layer);
-
-  FRS_begin_stroke_rendering(re);
-
-  for (view_layer = (ViewLayer *)re->view_layers.first; view_layer;
-       view_layer = view_layer->next) {
-    link = (LinkData *)MEM_callocN(sizeof(LinkData), "LinkData to Freestyle render");
-    BLI_addtail(&re->freestyle_renders, link);
-
-    if ((re->r.scemode & R_SINGLE_LAYER) && view_layer != active_view_layer) {
-      continue;
-    }
-    if (FRS_is_freestyle_enabled(view_layer)) {
-      r = FRS_do_stroke_rendering(re, view_layer, render);
-      link->data = (void *)r;
-    }
-  }
-
-  FRS_end_stroke_rendering(re);
-}
-
-/* releases temporary scenes and renders for Freestyle stroke rendering */
-static void free_all_freestyle_renders(void)
-{
-  Render *re1;
-  LinkData *link;
-
-  for (re1 = RenderGlobal.renderlist.first; re1; re1 = re1->next) {
-    for (link = (LinkData *)re1->freestyle_renders.first; link; link = link->next) {
-      Render *freestyle_render = (Render *)link->data;
-
-      if (freestyle_render) {
-        Scene *freestyle_scene = freestyle_render->scene;
-        RE_FreeRender(freestyle_render);
-
-        if (freestyle_scene) {
-          BKE_libblock_unlink(re1->freestyle_bmain, freestyle_scene, false, false);
-          BKE_id_free(re1->freestyle_bmain, freestyle_scene);
-        }
-      }
-    }
-    BLI_freelistN(&re1->freestyle_renders);
-
-    if (re1->freestyle_bmain) {
-      /* detach the window manager from freestyle bmain (see comments
-       * in add_freestyle() for more detail)
-       */
-      BLI_listbase_clear(&re1->freestyle_bmain->wm);
-
-      BKE_main_free(re1->freestyle_bmain);
-      re1->freestyle_bmain = NULL;
-    }
-  }
-}
-#endif
-
 /* returns fully composited render-result on given time step (in RenderData) */
 static void do_render_composite(Render *re)
 {
@@ -1531,10 +1442,6 @@ static void do_render_composite(Render *re)
     }
   }
 
-#ifdef WITH_FREESTYLE
-  free_all_freestyle_renders();
-#endif
-
   /* weak... the display callback wants an active renderlayer pointer... */
   if (re->result != NULL) {
     re->result->renlay = render_get_active_layer(re, re->result);
@@ -2181,15 +2088,30 @@ void RE_RenderFreestyleStrokes(Render *re, Main *bmain, Scene *scene, int render
 
 void RE_RenderFreestyleExternal(Render *re)
 {
-  if (!re->test_break(re->tbh)) {
-    RenderView *rv;
+  if (re->test_break(re->tbh)) {
+    return;
+  }
 
-    init_freestyle(re);
+  FRS_init_stroke_renderer(re);
+
+  for (RenderView *rv = re->result->views.first; rv; rv = rv->next) {
+    RE_SetActiveRenderView(re, rv->name);
 
-    for (rv = re->result->views.first; rv; rv = rv->next) {
-      RE_SetActiveRenderView(re, rv->name);
-      add_freestyle(re, 1);
+    ViewLayer *active_view_layer = BLI_findlink(&re->view_layers, re->active_view_layer);
+    FRS_begin_stroke_rendering(re);
+
+    for (ViewLayer *view_layer = (ViewLayer *)re->view_layers.first; view_layer;
+         view_layer = view_layer->next) {
+      if ((re->r.scemode & R_SINGLE_LAYER) && view_layer != active_view_layer) {
+        continue;
+      }
+
+      if (FRS_is_freestyle_enabled(view_layer)) {
+        FRS_do_stroke_rendering(re, view_layer);
+      }
     }
+
+    FRS_end_stroke_rendering(re);
   }
 }
 #endif