diff options
author | Brecht Van Lommel <brechtvanlommel@gmail.com> | 2017-11-08 02:20:59 +0300 |
---|---|---|
committer | Brecht Van Lommel <brechtvanlommel@gmail.com> | 2017-11-08 02:20:59 +0300 |
commit | 7b1d7074817dac9d0f088e8e7e5b336bae662c36 (patch) | |
tree | 4ebd67459d2fc160d3a6c76a2509cefc68f4e89c /source/blender/render | |
parent | 1b18e158025a488e1ba2446ad93c2eb563c11611 (diff) | |
parent | a0478ebe379c8384376586e2880ebc813a6afef7 (diff) |
Merge branch 'master' into blender2.8
Diffstat (limited to 'source/blender/render')
-rw-r--r-- | source/blender/render/extern/include/RE_pipeline.h | 5 | ||||
-rw-r--r-- | source/blender/render/intern/include/render_result.h | 1 | ||||
-rw-r--r-- | source/blender/render/intern/source/pipeline.c | 64 | ||||
-rw-r--r-- | source/blender/render/intern/source/render_result.c | 183 |
4 files changed, 147 insertions, 106 deletions
diff --git a/source/blender/render/extern/include/RE_pipeline.h b/source/blender/render/extern/include/RE_pipeline.h index c19c332c677..243aff8ae54 100644 --- a/source/blender/render/extern/include/RE_pipeline.h +++ b/source/blender/render/extern/include/RE_pipeline.h @@ -316,7 +316,7 @@ void RE_PreviewRender(struct Render *re, struct Main *bmain, struct Scene *scene bool RE_ReadRenderResult(struct Scene *scene, struct Scene *scenode); bool RE_WriteRenderResult( struct ReportList *reports, RenderResult *rr, const char *filename, - struct ImageFormatData *imf, const bool multiview, const char *view); + struct ImageFormatData *imf, const char *view, const int layer); struct RenderResult *RE_MultilayerConvert( void *exrhandle, const char *colorspace, bool predivide, int rectx, int recty); @@ -348,6 +348,7 @@ void RE_zbuf_accumulate_vecblur( int RE_seq_render_active(struct Scene *scene, struct RenderData *rd); bool RE_layers_have_name(struct RenderResult *result); +bool RE_passes_have_name(struct RenderLayer *rl); struct RenderPass *RE_pass_find_by_name(volatile struct RenderLayer *rl, const char *name, const char *viewname); struct RenderPass *RE_pass_find_by_type(volatile struct RenderLayer *rl, int passtype, const char *viewname); @@ -393,7 +394,7 @@ void RE_updateRenderInstances(Render *re, int flag); /******* defined in render_result.c *********/ -bool RE_HasFakeLayer(RenderResult *res); +bool RE_HasCombinedLayer(RenderResult *res); bool RE_RenderResult_is_stereo(RenderResult *res); struct RenderView *RE_RenderViewGetById(struct RenderResult *res, const int view_id); struct RenderView *RE_RenderViewGetByName(struct RenderResult *res, const char *viewname); diff --git a/source/blender/render/intern/include/render_result.h b/source/blender/render/intern/include/render_result.h index 4057d8c1052..8d293c938c7 100644 --- a/source/blender/render/intern/include/render_result.h +++ b/source/blender/render/intern/include/render_result.h @@ -115,6 +115,7 @@ void render_result_rect_get_pixels(struct RenderResult *rr, void render_result_views_shallowcopy(struct RenderResult *dst, struct RenderResult *src); void render_result_views_shallowdelete(struct RenderResult *rr); +bool render_result_has_views(struct RenderResult *rr); #endif /* __RENDER_RESULT_H__ */ diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c index 7a8f0d3ada7..f351a990dba 100644 --- a/source/blender/render/intern/source/pipeline.c +++ b/source/blender/render/intern/source/pipeline.c @@ -385,6 +385,7 @@ void RE_AcquireResultImageViews(Render *re, RenderResult *rr) render_result_views_shallowcopy(rr, re->result); rv = rr->views.first; + rr->have_combined = (rv->rectf != NULL); /* active layer */ rl = render_get_active_layer(re, re->result); @@ -403,7 +404,6 @@ void RE_AcquireResultImageViews(Render *re, RenderResult *rr) } } - rr->have_combined = (rv->rectf != NULL); rr->layers = re->result->layers; rr->xof = re->disprect.xmin; rr->yof = re->disprect.ymin; @@ -442,11 +442,14 @@ void RE_AcquireResultImage(Render *re, RenderResult *rr, const int view_id) /* actview view */ rv = RE_RenderViewGetById(re->result, view_id); + rr->have_combined = (rv->rectf != NULL); rr->rectf = rv->rectf; rr->rectz = rv->rectz; rr->rect32 = rv->rect32; + rr->have_combined = (rv->rectf != NULL); + /* active layer */ rl = render_get_active_layer(re, re->result); @@ -458,7 +461,6 @@ void RE_AcquireResultImage(Render *re, RenderResult *rr, const int view_id) rr->rectz = RE_RenderLayerGetPass(rl, RE_PASSNAME_Z, rv->name); } - rr->have_combined = (rv->rectf != NULL); rr->layers = re->result->layers; rr->views = re->result->views; @@ -3333,19 +3335,18 @@ void RE_RenderFreestyleExternal(Render *re) bool RE_WriteRenderViewsImage(ReportList *reports, RenderResult *rr, Scene *scene, const bool stamp, char *name) { - bool is_mono; bool ok = true; RenderData *rd = &scene->r; if (!rr) return false; - is_mono = BLI_listbase_count_ex(&rr->views, 2) < 2; + bool is_mono = BLI_listbase_count_ex(&rr->views, 2) < 2; + bool is_exr_rr = ELEM(rd->im_format.imtype, R_IMF_IMTYPE_OPENEXR, R_IMF_IMTYPE_MULTILAYER); - if (ELEM(rd->im_format.imtype, R_IMF_IMTYPE_OPENEXR, R_IMF_IMTYPE_MULTILAYER) && - rd->im_format.views_format == R_IMF_VIEWS_MULTIVIEW) + if (rd->im_format.views_format == R_IMF_VIEWS_MULTIVIEW && is_exr_rr) { - ok = RE_WriteRenderResult(reports, rr, name, &rd->im_format, true, NULL); + ok = RE_WriteRenderResult(reports, rr, name, &rd->im_format, NULL, -1); render_print_save_message(reports, name, ok, errno); } @@ -3363,33 +3364,34 @@ bool RE_WriteRenderViewsImage(ReportList *reports, RenderResult *rr, Scene *scen BKE_scene_multiview_view_filepath_get(&scene->r, filepath, rv->name, name); } - if (rd->im_format.imtype == R_IMF_IMTYPE_MULTILAYER) { - ok = RE_WriteRenderResult(reports, rr, name, &rd->im_format, false, rv->name); + if (is_exr_rr) { + ok = RE_WriteRenderResult(reports, rr, name, &rd->im_format, rv->name, -1); render_print_save_message(reports, name, ok, errno); - } - else { - ImBuf *ibuf = render_result_rect_to_ibuf(rr, rd, view_id); - - IMB_colormanagement_imbuf_for_write(ibuf, true, false, &scene->view_settings, - &scene->display_settings, &rd->im_format); - - ok = render_imbuf_write_stamp_test(reports, scene, rr, ibuf, name, &rd->im_format, stamp); /* optional preview images for exr */ - if (ok && rd->im_format.imtype == R_IMF_IMTYPE_OPENEXR && (rd->im_format.flag & R_IMF_FLAG_PREVIEW_JPG)) { + if (ok && (rd->im_format.flag & R_IMF_FLAG_PREVIEW_JPG)) { ImageFormatData imf = rd->im_format; imf.imtype = R_IMF_IMTYPE_JPEG90; if (BLI_testextensie(name, ".exr")) name[strlen(name) - 4] = 0; BKE_image_path_ensure_ext_from_imformat(name, &imf); - ibuf->planes = 24; - IMB_colormanagement_imbuf_for_write(ibuf, true, false, &scene->view_settings, - &scene->display_settings, &imf); + ImBuf *ibuf = render_result_rect_to_ibuf(rr, rd, view_id); + ibuf->planes = 24; ok = render_imbuf_write_stamp_test(reports, scene, rr, ibuf, name, &imf, stamp); + + IMB_freeImBuf(ibuf); } + } + else { + ImBuf *ibuf = render_result_rect_to_ibuf(rr, rd, view_id); + + IMB_colormanagement_imbuf_for_write(ibuf, true, false, &scene->view_settings, + &scene->display_settings, &rd->im_format); + + ok = render_imbuf_write_stamp_test(reports, scene, rr, ibuf, name, &rd->im_format, stamp); /* imbuf knows which rects are not part of ibuf */ IMB_freeImBuf(ibuf); @@ -3400,7 +3402,7 @@ bool RE_WriteRenderViewsImage(ReportList *reports, RenderResult *rr, Scene *scen BLI_assert(scene->r.im_format.views_format == R_IMF_VIEWS_STEREO_3D); if (rd->im_format.imtype == R_IMF_IMTYPE_MULTILAYER) { - printf("Stereo 3D not support for MultiLayer image: %s\n", name); + printf("Stereo 3D not supported for MultiLayer image: %s\n", name); } else { ImBuf *ibuf_arr[3] = {NULL}; @@ -3420,7 +3422,7 @@ bool RE_WriteRenderViewsImage(ReportList *reports, RenderResult *rr, Scene *scen ok = render_imbuf_write_stamp_test(reports, scene, rr, ibuf_arr[2], name, &rd->im_format, stamp); /* optional preview images for exr */ - if (ok && rd->im_format.imtype == R_IMF_IMTYPE_OPENEXR && + if (ok && is_exr_rr && (rd->im_format.flag & R_IMF_FLAG_PREVIEW_JPG)) { ImageFormatData imf = rd->im_format; @@ -3432,9 +3434,6 @@ bool RE_WriteRenderViewsImage(ReportList *reports, RenderResult *rr, Scene *scen BKE_image_path_ensure_ext_from_imformat(name, &imf); ibuf_arr[2]->planes = 24; - IMB_colormanagement_imbuf_for_write(ibuf_arr[2], true, false, &scene->view_settings, - &scene->display_settings, &imf); - ok = render_imbuf_write_stamp_test(reports, scene, rr, ibuf_arr[2], name, &rd->im_format, stamp); } @@ -4049,7 +4048,7 @@ bool RE_WriteEnvmapResult(struct ReportList *reports, Scene *scene, EnvMap *env, } } -/* used in the interface to decide whether to show layers */ +/* Used in the interface to decide whether to show layers or passes. */ bool RE_layers_have_name(struct RenderResult *rr) { switch (BLI_listbase_count_ex(&rr->layers, 2)) { @@ -4063,6 +4062,17 @@ bool RE_layers_have_name(struct RenderResult *rr) return false; } +bool RE_passes_have_name(struct RenderLayer *rl) +{ + for (RenderPass *rp = rl->passes.first; rp; rp = rp->next) { + if (!STREQ(rp->name, "Combined")) { + return true; + } + } + + return false; +} + RenderPass *RE_pass_find_by_name(volatile RenderLayer *rl, const char *name, const char *viewname) { RenderPass *rp = NULL; diff --git a/source/blender/render/intern/source/render_result.c b/source/blender/render/intern/source/render_result.c index aa0c7357302..631503bdad5 100644 --- a/source/blender/render/intern/source/render_result.c +++ b/source/blender/render/intern/source/render_result.c @@ -585,7 +585,7 @@ static void *ml_addlayer_cb(void *base, const char *str) rl = MEM_callocN(sizeof(RenderLayer), "new render layer"); BLI_addtail(&rr->layers, rl); - + BLI_strncpy(rl->name, str, EXR_LAY_MAXNAME); return rl; } @@ -756,6 +756,12 @@ void render_result_views_new(RenderResult *rr, RenderData *rd) } } +bool render_result_has_views(RenderResult *rr) +{ + RenderView *rv = rr->views.first; + return (rv && (rv->next || rv->name[0])); +} + /*********************************** Merge ***********************************/ static void do_merge_tile(RenderResult *rr, RenderResult *rrpart, float *target, float *tile, int pixsize) @@ -820,101 +826,124 @@ void render_result_merge(RenderResult *rr, RenderResult *rrpart) } } -/* called from within UI and render pipeline, saves both rendered result as a file-read result - * if multiview is true saves all views in a multiview exr - * else if view is not NULL saves single view - * else saves stereo3d - */ -bool RE_WriteRenderResult(ReportList *reports, RenderResult *rr, const char *filename, ImageFormatData *imf, const bool multiview, const char *view) +/* Called from the UI and render pipeline, to save multilayer and multiview + * images, optionally isolating a specific, view, layer or RGBA/Z pass. */ +bool RE_WriteRenderResult(ReportList *reports, RenderResult *rr, const char *filename, ImageFormatData *imf, const char *view, int layer) { - RenderLayer *rl; - RenderPass *rpass; - RenderView *rview; void *exrhandle = IMB_exr_get_handle(); - bool success; - int a, nr; - const char *chan_view = NULL; - int compress = (imf ? imf->exr_codec : 0); - size_t width, height; - - const bool is_mono = view && !multiview; - const bool use_half_float = (imf != NULL) ? (imf->depth == R_IMF_CHAN_DEPTH_16) : false; - - width = rr->rectx; - height = rr->recty; + const bool half_float = (imf && imf->depth == R_IMF_CHAN_DEPTH_16); + const bool multi_layer = !(imf && imf->imtype == R_IMF_IMTYPE_OPENEXR); + const bool write_z = !multi_layer && (imf && (imf->flag & R_IMF_FLAG_ZBUF)); - if (imf && imf->imtype == R_IMF_IMTYPE_OPENEXR && multiview) { - /* single layer OpenEXR */ - const char *RGBAZ[] = {"R", "G", "B", "A", "Z"}; - for (nr = 0, rview = rr->views.first; rview; rview = rview->next, nr++) { - IMB_exr_add_view(exrhandle, rview->name); + /* Write first layer if not multilayer and no layer was specified. */ + if (!multi_layer && layer == -1) { + layer = 0; + } - if (rview->rectf) { - for (a = 0; a < 4; a++) { - IMB_exr_add_channel(exrhandle, "", RGBAZ[a], - rview->name, 4, 4 * width, rview->rectf + a, - use_half_float); - } - if (rview->rectz) { - /* Z pass is always stored as float. */ - IMB_exr_add_channel(exrhandle, "", RGBAZ[4], - rview->name, 1, width, rview->rectz, - false); - } + /* First add views since IMB_exr_add_channel checks number of views. */ + if (render_result_has_views(rr)) { + for (RenderView *rview = rr->views.first; rview; rview = rview->next) { + if (!view || STREQ(view, rview->name)) { + IMB_exr_add_view(exrhandle, rview->name); } } } - else { - for (nr = 0, rview = rr->views.first; rview; rview = rview->next, nr++) { - if (is_mono) { - if (!STREQ(view, rview->name)) { + + /* Compositing result. */ + if (rr->have_combined) { + for (RenderView *rview = rr->views.first; rview; rview = rview->next) { + if (!rview->rectf) { + continue; + } + + const char *viewname = rview->name; + if (view) { + if (!STREQ(view, viewname)) { continue; } - chan_view = ""; - } - else { - /* if rendered only one view, we treat as a a non-view render */ - chan_view = rview->name; + else { + viewname = ""; + } } - IMB_exr_add_view(exrhandle, rview->name); + /* Skip compositing if only a single other layer is requested. */ + if (!multi_layer && layer != 0) { + continue; + } - if (rview->rectf) { + for (int a = 0; a < 4; a++) { char passname[EXR_PASS_MAXNAME]; - for (a = 0; a < 4; a++) { - set_pass_name(passname, RE_PASSNAME_COMBINED, a, "RGBA"); - IMB_exr_add_channel(exrhandle, RE_PASSNAME_COMBINED, passname, - chan_view, 4, 4 * width, rview->rectf + a, - use_half_float); + char layname[EXR_PASS_MAXNAME]; + const char *chan_id = "RGBA"; + + if (multi_layer) { + set_pass_name(passname, "Combined", a, chan_id); + BLI_strncpy(layname, "Composite", sizeof(layname)); } + else { + passname[0] = chan_id[a]; + passname[1] = '\0'; + layname[0] = '\0'; + } + + IMB_exr_add_channel(exrhandle, layname, passname, viewname, + 4, 4 * rr->rectx, rview->rectf + a, half_float); + } + + if (write_z && rview->rectz) { + const char *layname = (multi_layer)? "Composite": ""; + IMB_exr_add_channel(exrhandle, layname, "Z", viewname, + 1, rr->rectx, rview->rectz, false); } } + } - /* add layers/passes and assign channels */ - for (rl = rr->layers.first; rl; rl = rl->next) { + /* Other render layers. */ + int nr = (rr->have_combined)? 1: 0; + for (RenderLayer *rl = rr->layers.first; rl; rl = rl->next, nr++) { + /* Skip other render layers if requested. */ + if (!multi_layer && nr != layer) { + continue; + } - /* passes are allocated in sync */ - for (rpass = rl->passes.first; rpass; rpass = rpass->next) { - const int xstride = rpass->channels; - char passname[EXR_PASS_MAXNAME]; + for (RenderPass *rp = rl->passes.first; rp; rp = rp->next) { + /* Skip non-RGBA and Z passes if not using multi layer. */ + if (!multi_layer && !(STREQ(rp->name, RE_PASSNAME_COMBINED) || + STREQ(rp->name, "") || + (STREQ(rp->name, RE_PASSNAME_Z) && write_z))) { + continue; + } - if (is_mono) { - if (!STREQ(view, rpass->view)) { - continue; - } - chan_view = ""; + /* Skip pass if it does not match the requested view(s). */ + const char *viewname = rp->view; + if (view) { + if (!STREQ(view, viewname)) { + continue; } else { - /* if rendered only one view, we treat as a a non-view render */ - chan_view = (nr > 1 ? rpass->view :""); + viewname = ""; } + } - for (a = 0; a < xstride; a++) { - set_pass_name(passname, rpass->name, a, rpass->chan_id); - IMB_exr_add_channel(exrhandle, rl->name, passname, chan_view, - xstride, xstride * width, rpass->rect + a, - STREQ(rpass->name, RE_PASSNAME_Z) ? false : use_half_float); + for (int a = 0; a < rp->channels; a++) { + /* Save Combined as RGBA if single layer save. */ + char passname[EXR_PASS_MAXNAME]; + char layname[EXR_PASS_MAXNAME]; + + if (multi_layer) { + set_pass_name(passname, rp->name, a, rp->chan_id); + BLI_strncpy(layname, rl->name, sizeof(layname)); + } + else { + passname[0] = rp->chan_id[a]; + passname[1] = '\0'; + layname[0] = '\0'; } + + /* Add channel. */ + IMB_exr_add_channel(exrhandle, layname, passname, viewname, + rp->channels, rp->channels * rr->rectx, rp->rect + a, + STREQ(rp->name, RE_PASSNAME_Z) ? false : half_float); } } } @@ -923,14 +952,14 @@ bool RE_WriteRenderResult(ReportList *reports, RenderResult *rr, const char *fil BLI_make_existing_file(filename); - if (IMB_exr_begin_write(exrhandle, filename, width, height, compress, rr->stamp_data)) { + int compress = (imf ? imf->exr_codec : 0); + bool success = IMB_exr_begin_write(exrhandle, filename, rr->rectx, rr->recty, compress, rr->stamp_data); + if (success) { IMB_exr_write_channels(exrhandle); - success = true; } else { /* TODO, get the error from openexr's exception */ BKE_reportf(reports, RPT_ERROR, "Error writing render result, %s (see console)", strerror(errno)); - success = false; } IMB_exr_close(exrhandle); @@ -1245,7 +1274,7 @@ void render_result_exr_file_cache_write(Render *re) 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, NULL, true, NULL); + RE_WriteRenderResult(NULL, rr, str, NULL, NULL, -1); } /* For cache, makes exact copy of render result */ @@ -1370,7 +1399,7 @@ void render_result_rect_get_pixels(RenderResult *rr, unsigned int *rect, int rec /*************************** multiview functions *****************************/ -bool RE_HasFakeLayer(RenderResult *res) +bool RE_HasCombinedLayer(RenderResult *res) { RenderView *rv; |