Fix T74417: Freestyle render removes image texture users
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.
This commit is contained in:
parent
366cb3a059
commit
ba8d819c9b
Notes:
blender-bot
2023-02-14 05:44:22 +01:00
Referenced by issue #74417, Freestyle render removes texture image user
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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*/)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 (rv = re->result->views.first; rv; rv = rv->next) {
|
||||
RE_SetActiveRenderView(re, rv->name);
|
||||
add_freestyle(re, 1);
|
||||
for (RenderView *rv = re->result->views.first; rv; rv = rv->next) {
|
||||
RE_SetActiveRenderView(re, rv->name);
|
||||
|
||||
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
|
||||
|
|
Loading…
Reference in New Issue