diff options
-rw-r--r-- | release/scripts/startup/bl_ui/properties_render.py | 4 | ||||
-rw-r--r-- | release/scripts/startup/bl_ui/space_image.py | 2 | ||||
-rw-r--r-- | release/scripts/startup/bl_ui/space_userpref.py | 2 | ||||
-rw-r--r-- | source/blender/editors/space_image/image_intern.h | 2 | ||||
-rw-r--r-- | source/blender/editors/space_image/image_ops.c | 32 | ||||
-rw-r--r-- | source/blender/editors/space_image/space_image.c | 3 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_scene_types.h | 1 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_userdef_types.h | 2 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_scene.c | 8 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_userdef.c | 4 | ||||
-rw-r--r-- | source/blender/render/intern/include/render_result.h | 7 | ||||
-rw-r--r-- | source/blender/render/intern/source/external_engine.c | 6 | ||||
-rw-r--r-- | source/blender/render/intern/source/pipeline.c | 19 | ||||
-rw-r--r-- | source/blender/render/intern/source/render_result.c | 70 |
14 files changed, 149 insertions, 13 deletions
diff --git a/release/scripts/startup/bl_ui/properties_render.py b/release/scripts/startup/bl_ui/properties_render.py index ce375eca894..42cb6086c35 100644 --- a/release/scripts/startup/bl_ui/properties_render.py +++ b/release/scripts/startup/bl_ui/properties_render.py @@ -396,7 +396,9 @@ class RENDER_PT_output(RenderButtonsPanel, Panel): col.prop(rd, "use_overwrite") col.prop(rd, "use_placeholder") - split.prop(rd, "use_file_extension") + col = split.column() + col.prop(rd, "use_file_extension") + col.prop(rd, "use_render_cache") layout.template_image_settings(image_settings, color_management=False) diff --git a/release/scripts/startup/bl_ui/space_image.py b/release/scripts/startup/bl_ui/space_image.py index f19e77eff8e..97c89df0693 100644 --- a/release/scripts/startup/bl_ui/space_image.py +++ b/release/scripts/startup/bl_ui/space_image.py @@ -154,6 +154,8 @@ class IMAGE_MT_image(Menu): show_render = sima.show_render + layout.operator("image.read_renderlayers") + if ima: if not show_render: layout.operator("image.replace") diff --git a/release/scripts/startup/bl_ui/space_userpref.py b/release/scripts/startup/bl_ui/space_userpref.py index 31ca972726e..cba6f065a6f 100644 --- a/release/scripts/startup/bl_ui/space_userpref.py +++ b/release/scripts/startup/bl_ui/space_userpref.py @@ -865,6 +865,7 @@ class USERPREF_PT_file(Panel): sub.label(text="Scripts:") sub.label(text="Sounds:") sub.label(text="Temp:") + sub.label(text="Render Cache:") sub.label(text="I18n Branches:") sub.label(text="Image Editor:") sub.label(text="Animation Player:") @@ -876,6 +877,7 @@ class USERPREF_PT_file(Panel): sub.prop(paths, "script_directory", text="") sub.prop(paths, "sound_directory", text="") sub.prop(paths, "temporary_directory", text="") + sub.prop(paths, "render_cache_directory", text="") sub.prop(paths, "i18n_branches_directory", text="") sub.prop(paths, "image_editor", text="") subsplit = sub.split(percentage=0.3) diff --git a/source/blender/editors/space_image/image_intern.h b/source/blender/editors/space_image/image_intern.h index 4d391874f9b..8e556378803 100644 --- a/source/blender/editors/space_image/image_intern.h +++ b/source/blender/editors/space_image/image_intern.h @@ -90,6 +90,8 @@ void IMAGE_OT_curves_point_set(struct wmOperatorType *ot); void IMAGE_OT_change_frame(struct wmOperatorType *ot); +void IMAGE_OT_read_renderlayers(struct wmOperatorType *ot); + /* image_panels.c */ struct ImageUser *ntree_get_active_iuser(struct bNodeTree *ntree); void image_buttons_register(struct ARegionType *art); diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c index cc769f13b82..7c021cf6645 100644 --- a/source/blender/editors/space_image/image_ops.c +++ b/source/blender/editors/space_image/image_ops.c @@ -2997,3 +2997,35 @@ void IMAGE_OT_change_frame(wmOperatorType *ot) /* rna */ RNA_def_int(ot->srna, "frame", 0, MINAFRAME, MAXFRAME, "Frame", "", MINAFRAME, MAXFRAME); } + +/* Reload cached render results... */ +/* goes over all scenes, reads render layers */ +static int image_read_renderlayers_exec(bContext *C, wmOperator *UNUSED(op)) +{ + Scene *scene = CTX_data_scene(C); + SpaceImage *sima = CTX_wm_space_image(C); + Image *ima; + + ima = BKE_image_verify_viewer(IMA_TYPE_R_RESULT, "Render Result"); + if (sima->image == NULL) { + ED_space_image_set(sima, scene, NULL, ima); + } + + RE_ReadRenderResult(scene, scene); + + WM_event_add_notifier(C, NC_IMAGE | NA_EDITED, ima); + return OPERATOR_FINISHED; +} + +void IMAGE_OT_read_renderlayers(wmOperatorType *ot) +{ + ot->name = "Read Render Layers"; + ot->idname = "IMAGE_OT_read_renderlayers"; + ot->description = "Read all the current scene's render layers from cache, as needed"; + + ot->poll = space_image_main_area_poll; + ot->exec = image_read_renderlayers_exec; + + /* flags */ + ot->flag = 0; +} diff --git a/source/blender/editors/space_image/space_image.c b/source/blender/editors/space_image/space_image.c index d1868951987..0fb93ad27ee 100644 --- a/source/blender/editors/space_image/space_image.c +++ b/source/blender/editors/space_image/space_image.c @@ -255,6 +255,8 @@ static void image_operatortypes(void) WM_operatortype_append(IMAGE_OT_toolshelf); WM_operatortype_append(IMAGE_OT_change_frame); + + WM_operatortype_append(IMAGE_OT_read_renderlayers); } static void image_keymap(struct wmKeyConfig *keyconf) @@ -266,6 +268,7 @@ static void image_keymap(struct wmKeyConfig *keyconf) WM_keymap_add_item(keymap, "IMAGE_OT_new", NKEY, KM_PRESS, KM_ALT, 0); WM_keymap_add_item(keymap, "IMAGE_OT_open", OKEY, KM_PRESS, KM_ALT, 0); WM_keymap_add_item(keymap, "IMAGE_OT_reload", RKEY, KM_PRESS, KM_ALT, 0); + WM_keymap_add_item(keymap, "IMAGE_OT_read_renderlayers", RKEY, KM_PRESS, KM_CTRL, 0); WM_keymap_add_item(keymap, "IMAGE_OT_save", SKEY, KM_PRESS, KM_ALT, 0); WM_keymap_add_item(keymap, "IMAGE_OT_save_as", F3KEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "IMAGE_OT_properties", NKEY, KM_PRESS, 0, 0); diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index c95cdb5c1f8..6b1cad120a7 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -1377,6 +1377,7 @@ typedef struct Scene { /* #define R_RECURS_PROTECTION 0x20000 */ #define R_TEXNODE_PREVIEW 0x40000 #define R_VIEWPORT_PREVIEW 0x80000 +#define R_EXR_CACHE_FILE 0x100000 /* r->stamp */ #define R_STAMP_TIME 0x0001 diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h index 987985f0ba7..cb2341b0b7f 100644 --- a/source/blender/makesdna/DNA_userdef_types.h +++ b/source/blender/makesdna/DNA_userdef_types.h @@ -422,6 +422,8 @@ typedef struct UserDef { char tempdir[768]; /* FILE_MAXDIR length */ char fontdir[768]; char renderdir[1024]; /* FILE_MAX length */ + /* EXR cache path */ + char render_cachedir[768]; /* 768 = FILE_MAXDIR */ char textudir[768]; char pythondir[768]; char sounddir[768]; diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index bcdb469dd85..bce7d0062f2 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -4811,6 +4811,14 @@ static void rna_def_scene_render_data(BlenderRNA *brna) "and length of frame numbers"); RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL); + /* Render result EXR cache. */ + prop = RNA_def_property(srna, "use_render_cache", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "scemode", R_EXR_CACHE_FILE); + RNA_def_property_ui_text(prop, "Cache Result", + "Save render cache to EXR files (useful for heavy compositing, " + "Note: affects indirectly rendered scenes)"); + RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL); + /* Bake */ prop = RNA_def_property(srna, "bake_type", PROP_ENUM, PROP_NONE); diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c index f69e768670e..f4974266f60 100644 --- a/source/blender/makesrna/intern/rna_userdef.c +++ b/source/blender/makesrna/intern/rna_userdef.c @@ -4272,6 +4272,10 @@ static void rna_def_userdef_filepaths(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Temporary Directory", "The directory for storing temporary save files"); RNA_def_property_update(prop, 0, "rna_userdef_temp_update"); + prop = RNA_def_property(srna, "render_cache_directory", PROP_STRING, PROP_DIRPATH); + RNA_def_property_string_sdna(prop, NULL, "render_cachedir"); + RNA_def_property_ui_text(prop, "Render Cache Path", "Where to cache raw render results"); + prop = RNA_def_property(srna, "image_editor", PROP_STRING, PROP_FILEPATH); RNA_def_property_string_sdna(prop, NULL, "image_editor"); RNA_def_property_ui_text(prop, "Image Editor", "Path to an image editor"); diff --git a/source/blender/render/intern/include/render_result.h b/source/blender/render/intern/include/render_result.h index 457f1377e9b..90ff69dbfbe 100644 --- a/source/blender/render/intern/include/render_result.h +++ b/source/blender/render/intern/include/render_result.h @@ -81,9 +81,14 @@ void render_result_exr_file_end(struct Render *re); void render_result_exr_file_merge(struct RenderResult *rr, struct RenderResult *rrpart); void render_result_exr_file_path(struct Scene *scene, const char *layname, int sample, char *filepath); -int render_result_exr_file_read(struct Render *re, int sample); +int render_result_exr_file_read_sample(struct Render *re, int sample); int render_result_exr_file_read_path(struct RenderResult *rr, struct RenderLayer *rl_single, const char *filepath); +/* EXR cache */ + +void render_result_exr_file_cache_write(struct Render *re); +bool render_result_exr_file_cache_read(struct Render *re); + /* Combined Pixel Rect */ struct ImBuf *render_result_rect_to_ibuf(struct RenderResult *rr, struct RenderData *rd); diff --git a/source/blender/render/intern/source/external_engine.c b/source/blender/render/intern/source/external_engine.c index 1df701c48eb..95ff68dadb3 100644 --- a/source/blender/render/intern/source/external_engine.c +++ b/source/blender/render/intern/source/external_engine.c @@ -664,6 +664,12 @@ int RE_engine_render(Render *re, int do_all) BLI_rw_mutex_unlock(&re->resultmutex); } + if (re->r.scemode & R_EXR_CACHE_FILE) { + BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE); + render_result_exr_file_cache_write(re); + BLI_rw_mutex_unlock(&re->resultmutex); + } + RE_parts_free(re); if (BKE_reports_contain(re->reports, RPT_ERROR)) diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c index bdd911df33b..9f27021d23e 100644 --- a/source/blender/render/intern/source/pipeline.c +++ b/source/blender/render/intern/source/pipeline.c @@ -1229,7 +1229,13 @@ static void threaded_tile_processor(Render *re) render_result_exr_file_end(re); BLI_rw_mutex_unlock(&re->resultmutex); } - + + if (re->r.scemode & R_EXR_CACHE_FILE) { + BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE); + render_result_exr_file_cache_write(re); + BLI_rw_mutex_unlock(&re->resultmutex); + } + /* unset threadsafety */ g_break = 0; @@ -1662,7 +1668,10 @@ static void render_scene(Render *re, Scene *sce, int cfra) /* initial setup */ RE_InitState(resc, re, &sce->r, NULL, winx, winy, &re->disprect); - + + /* We still want to use 'rendercache' setting from org (main) scene... */ + resc->r.scemode = (resc->r.scemode & ~R_EXR_CACHE_FILE) | (re->r.scemode & R_EXR_CACHE_FILE); + /* still unsure entity this... */ resc->main = re->main; resc->scene = sce; @@ -1967,7 +1976,7 @@ static void composite_freestyle_renders(Render *re, int sample) /* may be NULL in case of empty render layer */ if (freestyle_render) { - render_result_exr_file_read(freestyle_render, sample); + render_result_exr_file_read_sample(freestyle_render, sample); FRS_composite_result(re, srl, freestyle_render); RE_FreeRenderResult(freestyle_render->result); freestyle_render->result = NULL; @@ -2041,7 +2050,7 @@ static void do_merge_fullsample(Render *re, bNodeTree *ntree) if (re1 && (re1->r.scemode & R_FULL_SAMPLE)) { if (sample) { BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE); - render_result_exr_file_read(re1, sample); + render_result_exr_file_read_sample(re1, sample); #ifdef WITH_FREESTYLE if (re1->r.mode & R_EDGE_FRS) composite_freestyle_renders(re1, sample); @@ -3108,7 +3117,7 @@ bool RE_ReadRenderResult(Scene *scene, Scene *scenode) re->scene_color_manage = BKE_scene_check_color_management_enabled(scene); BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE); - success = render_result_exr_file_read(re, 0); + success = render_result_exr_file_cache_read(re); BLI_rw_mutex_unlock(&re->resultmutex); return success; diff --git a/source/blender/render/intern/source/render_result.c b/source/blender/render/intern/source/render_result.c index dd867852bdb..d8410fbe257 100644 --- a/source/blender/render/intern/source/render_result.c +++ b/source/blender/render/intern/source/render_result.c @@ -37,6 +37,7 @@ #include "BLI_utildefines.h" #include "BLI_listbase.h" +#include "BLI_md5.h" #include "BLI_path_util.h" #include "BLI_rect.h" #include "BLI_string.h" @@ -1012,7 +1013,7 @@ void render_result_exr_file_end(Render *re) render_result_free_list(&re->fullresult, re->result); re->result = NULL; - render_result_exr_file_read(re, 0); + render_result_exr_file_read_sample(re, 0); } /* save part into exr file */ @@ -1038,25 +1039,23 @@ void render_result_exr_file_path(Scene *scene, const char *layname, int sample, BLI_make_file_string("/", filepath, BLI_temp_dir_session(), name); } -/* only for temp buffer files, makes exact copy of render result */ -int render_result_exr_file_read(Render *re, int sample) +/* only for temp buffer, makes exact copy of render result */ +int render_result_exr_file_read_sample(Render *re, int sample) { RenderLayer *rl; - char str[FILE_MAX]; + char str[FILE_MAXFILE + MAX_ID_NAME + MAX_ID_NAME + 100] = ""; bool success = true; RE_FreeRenderResult(re->result); re->result = render_result_new(re, &re->disprect, 0, RR_USE_MEM, RR_ALL_LAYERS); for (rl = re->result->layers.first; rl; rl = rl->next) { - render_result_exr_file_path(re->scene, rl->name, sample, str); printf("read exr tmp file: %s\n", str); if (!render_result_exr_file_read_path(re->result, rl, str)) { printf("cannot read: %s\n", str); success = false; - } } @@ -1115,6 +1114,65 @@ int render_result_exr_file_read_path(RenderResult *rr, RenderLayer *rl_single, c return 1; } +static void render_result_exr_file_cache_path(Scene *sce, const char *root, char *r_path) +{ + char filename_full[FILE_MAX + MAX_ID_NAME + 100], filename[FILE_MAXFILE], dirname[FILE_MAXDIR]; + char path_digest[16] = {0}; + char path_hexdigest[33]; + + /* If root is relative, use either current .blend file dir, or temp one if not saved. */ + if (G.main->name[0]) { + BLI_split_dirfile(G.main->name, dirname, filename, sizeof(dirname), sizeof(filename)); + BLI_replace_extension(filename, sizeof(filename), ""); /* strip '.blend' */ + md5_buffer(G.main->name, strlen(G.main->name), path_digest); + } + else { + BLI_strncpy(dirname, BLI_temp_dir_base(), sizeof(dirname)); + BLI_strncpy(filename, "UNSAVED", sizeof(filename)); + } + md5_to_hexdigest(path_digest, path_hexdigest); + + /* Default to *non-volatile* tmp dir. */ + if (*root == '\0') { + root = BLI_temp_dir_base(); + } + + BLI_snprintf(filename_full, sizeof(filename_full), "cached_RR_%s_%s_%s.exr", + filename, sce->id.name + 2, path_hexdigest); + BLI_make_file_string(dirname, r_path, root, filename_full); +} + +void render_result_exr_file_cache_write(Render *re) +{ + RenderResult *rr = re->result; + char str[FILE_MAXFILE + FILE_MAXFILE + MAX_ID_NAME + 100]; + char *root = U.render_cachedir; + + render_result_exr_file_cache_path(re->scene, root, str); + printf("Caching exr file, %dx%d, %s\n", rr->rectx, rr->recty, str); + RE_WriteRenderResult(NULL, rr, str, 0); +} + +/* For cache, makes exact copy of render result */ +bool render_result_exr_file_cache_read(Render *re) +{ + char str[FILE_MAXFILE + MAX_ID_NAME + MAX_ID_NAME + 100] = ""; + char *root = U.render_cachedir; + + RE_FreeRenderResult(re->result); + re->result = render_result_new(re, &re->disprect, 0, RR_USE_MEM, RR_ALL_LAYERS); + + /* First try cache. */ + render_result_exr_file_cache_path(re->scene, root, str); + + printf("read exr cache file: %s\n", str); + if (!render_result_exr_file_read_path(re->result, NULL, str)) { + printf("cannot read: %s\n", str); + return false; + } + return true; +} + /*************************** Combined Pixel Rect *****************************/ ImBuf *render_result_rect_to_ibuf(RenderResult *rr, RenderData *rd) |