From 5317dc716e3e0123570674e4637342cbd5d9559b Mon Sep 17 00:00:00 2001 From: Dalai Felinto Date: Wed, 9 Sep 2015 19:41:46 +0500 Subject: Fix T45839 : Regression - Multi-layer image issues when using non-standard names This was introduced in the fix for T44336 . The code is now what it should have been in the first place at the time of multiview commit. ImageUser->passtype is being removed in favour of bringing ImageUser->pass back. Reviewers: sergey Differential Revision: https://developer.blender.org/D1504 --- source/blender/blenkernel/intern/image.c | 105 ++++++++++++--------- source/blender/blenloader/intern/versioning_270.c | 1 - source/blender/compositor/nodes/COM_ImageNode.cpp | 15 +-- .../operations/COM_MultilayerImageOperation.cpp | 6 +- .../operations/COM_MultilayerImageOperation.h | 10 +- source/blender/editors/render/render_internal.c | 4 +- source/blender/editors/space_image/image_buttons.c | 63 +++++++------ source/blender/editors/space_image/space_image.c | 1 - source/blender/makesdna/DNA_image_types.h | 3 +- source/blender/makesrna/intern/rna_image.c | 5 + 10 files changed, 117 insertions(+), 96 deletions(-) (limited to 'source') diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c index ef760f2da26..36aeb97c3f0 100644 --- a/source/blender/blenkernel/intern/image.c +++ b/source/blender/blenkernel/intern/image.c @@ -2578,21 +2578,10 @@ static void image_init_imageuser(Image *ima, ImageUser *iuser) RenderResult *rr = ima->rr; iuser->multi_index = 0; - iuser->layer = iuser->view = 0; - iuser->passtype = SCE_PASS_COMBINED; - - if (rr) { - RenderLayer *rl = rr->layers.first; - - if (rl) { - RenderPass *rp = rl->passes.first; - - if (rp) - iuser->passtype = rp->passtype; - } + iuser->layer = iuser->pass = iuser->view = 0; + if (rr) BKE_image_multilayer_index(rr, iuser); - } } void BKE_image_init_imageuser(Image *ima, ImageUser *iuser) @@ -2740,6 +2729,52 @@ void BKE_image_signal(Image *ima, ImageUser *iuser, int signal) } } +#define PASSTYPE_UNSET -1 +/* return renderpass for a given pass index and active view */ +/* fallback to available if there are missing passes for active view */ +static RenderPass *image_render_pass_get(RenderLayer *rl, const int pass, const int view, int *r_passindex) +{ + RenderPass *rpass_ret = NULL; + RenderPass *rpass; + + int rp_index = 0; + int rp_passtype = PASSTYPE_UNSET; + + for (rpass = rl->passes.first; rpass; rpass = rpass->next, rp_index++) { + if (rp_index == pass) { + rpass_ret = rpass; + if (view == 0) { + /* no multiview or left eye */ + break; + } + else { + rp_passtype = rpass->passtype; + } + } + /* multiview */ + else if ((rp_passtype != PASSTYPE_UNSET) && + (rpass->passtype == rp_passtype) && + (rpass->view_id == view)) + { + rpass_ret = rpass; + break; + } + } + + /* fallback to the first pass in the layer */ + if (rpass_ret == NULL) { + rp_index = 0; + rpass_ret = rl->passes.first; + } + + if (r_passindex) { + *r_passindex = (rpass == rpass_ret ? rp_index : pass); + } + + return rpass_ret; +} +#undef PASSTYPE_UNSET + /* if layer or pass changes, we need an index for the imbufs list */ /* note it is called for rendered results, but it doesnt use the index! */ /* and because rendered results use fake layer/passes, don't correct for wrong indices here */ @@ -2759,27 +2794,16 @@ RenderPass *BKE_image_multilayer_index(RenderResult *rr, ImageUser *iuser) if (RE_HasFakeLayer(rr)) rl_index += 1; for (rl = rr->layers.first; rl; rl = rl->next, rl_index++) { - for (rpass = rl->passes.first; rpass; rpass = rpass->next, index++) { - if (iuser->layer == rl_index && - iuser->passtype == rpass->passtype && - rv_index == rpass->view_id) - { - break; - } - } - if (rpass) + if (iuser->layer == rl_index) { + int rp_index; + rpass = image_render_pass_get(rl, iuser->pass, rv_index, &rp_index); + iuser->multi_index = index + rp_index; break; + } + else { + index += BLI_listbase_count(&rl->passes); + } } - iuser->multi_index = (rpass ? index : 0); - } - - if (rpass == NULL) { - rl = rr->layers.first; - if (rl) - rpass = rl->passes.first; - - if (rpass && iuser) - iuser->passtype = rpass->passtype; } return rpass; @@ -3613,7 +3637,7 @@ static ImBuf *image_get_render_result(Image *ima, ImageUser *iuser, void **r_loc float *rectf, *rectz; unsigned int *rect; float dither; - int channels, layer, passtype; + int channels, layer, pass; ImBuf *ibuf; int from_render = (ima->render_slot == ima->last_render_slot); int actview; @@ -3630,7 +3654,7 @@ static ImBuf *image_get_render_result(Image *ima, ImageUser *iuser, void **r_loc channels = 4; layer = iuser->layer; - passtype = iuser->passtype; + pass = iuser->pass; actview = iuser->view; if ((ima->flag & IMA_IS_STEREO) && (iuser->flag & IMA_SHOW_STEREO)) @@ -3693,19 +3717,10 @@ static ImBuf *image_get_render_result(Image *ima, ImageUser *iuser, void **r_loc else if (rres.layers.first) { RenderLayer *rl = BLI_findlink(&rres.layers, layer - (rres.have_combined ? 1 : 0)); if (rl) { - RenderPass *rpass; - - for (rpass = rl->passes.first; rpass; rpass = rpass->next) { - if (passtype == rpass->passtype && - actview == rpass->view_id) - { - break; - } - } - + RenderPass *rpass = image_render_pass_get(rl, pass, actview, NULL); if (rpass) { rectf = rpass->rect; - if (passtype == SCE_PASS_COMBINED) { + if (pass == 0) { if (rectf == NULL) { /* Happens when Save Buffers is enabled. * Use display buffer stored in the render layer. diff --git a/source/blender/blenloader/intern/versioning_270.c b/source/blender/blenloader/intern/versioning_270.c index 6af6a7aff4f..5518b1513f4 100644 --- a/source/blender/blenloader/intern/versioning_270.c +++ b/source/blender/blenloader/intern/versioning_270.c @@ -767,7 +767,6 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main) { SpaceImage *sima = (SpaceImage *) sl; sima->iuser.flag |= IMA_SHOW_STEREO; - sima->iuser.passtype = SCE_PASS_COMBINED; break; } } diff --git a/source/blender/compositor/nodes/COM_ImageNode.cpp b/source/blender/compositor/nodes/COM_ImageNode.cpp index 572e63a2ced..facd422c217 100644 --- a/source/blender/compositor/nodes/COM_ImageNode.cpp +++ b/source/blender/compositor/nodes/COM_ImageNode.cpp @@ -40,19 +40,19 @@ ImageNode::ImageNode(bNode *editorNode) : Node(editorNode) } NodeOperation *ImageNode::doMultilayerCheck(NodeConverter &converter, RenderLayer *rl, Image *image, ImageUser *user, - int framenumber, int outputsocketIndex, int passtype, int view, DataType datatype) const + int framenumber, int outputsocketIndex, int passindex, int view, DataType datatype) const { NodeOutput *outputSocket = this->getOutputSocket(outputsocketIndex); MultilayerBaseOperation *operation = NULL; switch (datatype) { case COM_DT_VALUE: - operation = new MultilayerValueOperation(passtype, view); + operation = new MultilayerValueOperation(passindex, view); break; case COM_DT_VECTOR: - operation = new MultilayerVectorOperation(passtype, view); + operation = new MultilayerVectorOperation(passindex, view); break; case COM_DT_COLOR: - operation = new MultilayerColorOperation(passtype, view); + operation = new MultilayerColorOperation(passindex, view); break; default: break; @@ -124,20 +124,21 @@ void ImageNode::convertToOperations(NodeConverter &converter, const CompositorCo } if (rpass) { + int passindex = BLI_findindex(&rl->passes, rpass); switch (rpass->channels) { case 1: operation = doMultilayerCheck(converter, rl, image, imageuser, framenumber, index, - rpass->passtype, view, COM_DT_VALUE); + passindex, view, COM_DT_VALUE); break; /* using image operations for both 3 and 4 channels (RGB and RGBA respectively) */ /* XXX any way to detect actual vector images? */ case 3: operation = doMultilayerCheck(converter, rl, image, imageuser, framenumber, index, - rpass->passtype, view, COM_DT_VECTOR); + passindex, view, COM_DT_VECTOR); break; case 4: operation = doMultilayerCheck(converter, rl, image, imageuser, framenumber, index, - rpass->passtype, view, COM_DT_COLOR); + passindex, view, COM_DT_COLOR); break; default: /* dummy operation is added below */ diff --git a/source/blender/compositor/operations/COM_MultilayerImageOperation.cpp b/source/blender/compositor/operations/COM_MultilayerImageOperation.cpp index 00be3b1cdde..b57dd4e32c3 100644 --- a/source/blender/compositor/operations/COM_MultilayerImageOperation.cpp +++ b/source/blender/compositor/operations/COM_MultilayerImageOperation.cpp @@ -27,9 +27,9 @@ extern "C" { # include "IMB_imbuf_types.h" } -MultilayerBaseOperation::MultilayerBaseOperation(int passtype, int view) : BaseImageOperation() +MultilayerBaseOperation::MultilayerBaseOperation(int passindex, int view) : BaseImageOperation() { - this->m_passtype = passtype; + this->m_passId = passindex; this->m_view = view; } @@ -39,7 +39,7 @@ ImBuf *MultilayerBaseOperation::getImBuf() int view = this->m_imageUser->view; this->m_imageUser->view = this->m_view; - this->m_imageUser->passtype = this->m_passtype; + this->m_imageUser->pass = this->m_passId; if (BKE_image_multilayer_index(this->m_image->rr, this->m_imageUser)) { ImBuf *ibuf = BaseImageOperation::getImBuf(); diff --git a/source/blender/compositor/operations/COM_MultilayerImageOperation.h b/source/blender/compositor/operations/COM_MultilayerImageOperation.h index 2e140577d74..46a9319c373 100644 --- a/source/blender/compositor/operations/COM_MultilayerImageOperation.h +++ b/source/blender/compositor/operations/COM_MultilayerImageOperation.h @@ -29,7 +29,7 @@ class MultilayerBaseOperation : public BaseImageOperation { private: - int m_passtype; + int m_passId; int m_view; RenderLayer *m_renderlayer; protected: @@ -38,13 +38,13 @@ public: /** * Constructor */ - MultilayerBaseOperation(int passtype, int view); + MultilayerBaseOperation(int passindex, int view); void setRenderLayer(RenderLayer *renderlayer) { this->m_renderlayer = renderlayer; } }; class MultilayerColorOperation : public MultilayerBaseOperation { public: - MultilayerColorOperation(int passtype, int view) : MultilayerBaseOperation(passtype, view) { + MultilayerColorOperation(int passindex, int view) : MultilayerBaseOperation(passindex, view) { this->addOutputSocket(COM_DT_COLOR); } void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); @@ -52,7 +52,7 @@ public: class MultilayerValueOperation : public MultilayerBaseOperation { public: - MultilayerValueOperation(int passtype, int view) : MultilayerBaseOperation(passtype, view) { + MultilayerValueOperation(int passindex, int view) : MultilayerBaseOperation(passindex, view) { this->addOutputSocket(COM_DT_VALUE); } void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); @@ -60,7 +60,7 @@ public: class MultilayerVectorOperation : public MultilayerBaseOperation { public: - MultilayerVectorOperation(int passtype, int view) : MultilayerBaseOperation(passtype, view) { + MultilayerVectorOperation(int passindex, int view) : MultilayerBaseOperation(passindex, view) { this->addOutputSocket(COM_DT_VECTOR); } void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); diff --git a/source/blender/editors/render/render_internal.c b/source/blender/editors/render/render_internal.c index 755b8dd303d..10de2d667ea 100644 --- a/source/blender/editors/render/render_internal.c +++ b/source/blender/editors/render/render_internal.c @@ -190,7 +190,7 @@ static void image_buffer_rect_update(RenderJob *rj, RenderResult *rr, ImBuf *ibu * - sergey - */ /* TODO(sergey): Need to check has_combined here? */ - if (iuser->passtype == SCE_PASS_COMBINED) { + if (iuser->pass == 0) { RenderView *rv; size_t view_id = BKE_scene_multiview_view_id_get(&scene->r, viewname); rv = RE_RenderViewGetById(rr, view_id); @@ -525,6 +525,7 @@ static void render_image_update_pass_and_layer(RenderJob *rj, RenderResult *rr, } } + iuser->pass = sima->iuser.pass; iuser->layer = sima->iuser.layer; RE_ReleaseResult(rj->re); @@ -898,7 +899,6 @@ static int screen_render_invoke(bContext *C, wmOperator *op, const wmEvent *even rj->write_still = is_write_still && !is_animation; rj->iuser.scene = scene; rj->iuser.ok = 1; - rj->iuser.passtype = SCE_PASS_COMBINED; rj->reports = op->reports; rj->orig_layer = 0; rj->last_layer = 0; diff --git a/source/blender/editors/space_image/image_buttons.c b/source/blender/editors/space_image/image_buttons.c index 579860726c6..3af210f376b 100644 --- a/source/blender/editors/space_image/image_buttons.c +++ b/source/blender/editors/space_image/image_buttons.c @@ -418,7 +418,7 @@ static void ui_imageuser_pass_menu(bContext *UNUSED(C), uiLayout *layout, void * uiItemS(layout); - nr = (rl ? BLI_listbase_count(&rl->passes) : 0) - 1; + nr = 0; fake_name = ui_imageuser_pass_fake_name(rl); if (fake_name) { @@ -427,7 +427,8 @@ static void ui_imageuser_pass_menu(bContext *UNUSED(C), uiLayout *layout, void * } /* rendered results don't have a Combined pass */ - for (rpass = rl ? rl->passes.last : NULL; rpass; rpass = rpass->prev, nr--) { + /* multiview: the ordering must be ascending, so the left-most pass is always the one picked */ + for (rpass = rl ? rl->passes.first : NULL; rpass; rpass = rpass->next, nr++) { /* just show one pass of each kind */ if (passflag & rpass->passtype) @@ -436,18 +437,17 @@ static void ui_imageuser_pass_menu(bContext *UNUSED(C), uiLayout *layout, void * passflag |= rpass->passtype; final: - uiDefButI(block, UI_BTYPE_BUT_MENU, B_NOP, IFACE_(rpass->internal_name), 0, 0, - UI_UNIT_X * 5, UI_UNIT_X, &iuser->passtype, (float) rpass->passtype, 0.0, 0, -1, ""); + uiDefButS(block, UI_BTYPE_BUT_MENU, B_NOP, IFACE_(rpass->internal_name), 0, 0, + UI_UNIT_X * 5, UI_UNIT_X, &iuser->pass, (float) nr, 0.0, 0, -1, ""); } if (fake_name) { fake_name = NULL; rpass = &rpass_fake; + nr = 0; goto final; } - BLI_assert(nr == -1); - BKE_image_release_renderresult(scene, image); } @@ -550,7 +550,6 @@ static void image_multi_incpass_cb(bContext *C, void *rr_v, void *iuser_v) ImageUser *iuser = iuser_v; RenderLayer *rl; RenderPass *rp; - RenderPass *next = NULL; int layer = iuser->layer; if (RE_HasFakeLayer(rr)) @@ -559,20 +558,20 @@ static void image_multi_incpass_cb(bContext *C, void *rr_v, void *iuser_v) rl = BLI_findlink(&rr->layers, layer); if (rl) { - for (rp = rl->passes.first; rp; rp = rp->next) { - if (rp->passtype == iuser->passtype) { - next = rp->next; - if (next != NULL && next->passtype == rp->passtype) - next = next->next; + RenderPass *rpass = BLI_findlink(&rl->passes, iuser->pass); + int rp_index = iuser->pass + 1; + + if (rpass == NULL) + return; + + for (rp = rpass->next; rp; rp = rp->next, rp_index++) { + if (rp->passtype != rpass->passtype) { + iuser->pass = rp_index; + BKE_image_multilayer_index(rr, iuser); + WM_event_add_notifier(C, NC_IMAGE | ND_DRAW, NULL); break; } } - - if (next != NULL && iuser->passtype != next->passtype) { - iuser->passtype = next->passtype; - BKE_image_multilayer_index(rr, iuser); - WM_event_add_notifier(C, NC_IMAGE | ND_DRAW, NULL); - } } } static void image_multi_decpass_cb(bContext *C, void *rr_v, void *iuser_v) @@ -581,29 +580,31 @@ static void image_multi_decpass_cb(bContext *C, void *rr_v, void *iuser_v) ImageUser *iuser = iuser_v; RenderLayer *rl; RenderPass *rp; - RenderPass *prev = NULL; int layer = iuser->layer; + if (iuser->pass == 0) + return; + if (RE_HasFakeLayer(rr)) layer -= 1; rl = BLI_findlink(&rr->layers, layer); if (rl) { - for (rp = rl->passes.last; rp; rp = rp->prev) { - if (rp->passtype == iuser->passtype) { - prev = rp->prev; - if (prev != NULL && prev->passtype == rp->passtype) - prev = prev->prev; + RenderPass *rpass = BLI_findlink(&rl->passes, iuser->pass); + int rp_index = 0; + + if (rpass == NULL) + return; + + for (rp = rl->passes.first; rp; rp = rp->next, rp_index++) { + if (rp->passtype == rpass->passtype) { + iuser->pass = rp_index - 1; + BKE_image_multilayer_index(rr, iuser); + WM_event_add_notifier(C, NC_IMAGE | ND_DRAW, NULL); break; } } - - if (prev != NULL && iuser->passtype != prev->passtype) { - iuser->passtype = prev->passtype; - BKE_image_multilayer_index(rr, iuser); - WM_event_add_notifier(C, NC_IMAGE | ND_DRAW, NULL); - } } } @@ -692,7 +693,7 @@ static void uiblock_layer_pass_buttons(uiLayout *layout, Image *image, RenderRes /* pass */ fake_name = ui_imageuser_pass_fake_name(rl); - rpass = (rl ? RE_pass_find_by_type(rl, iuser->passtype, ((RenderView *)rr->views.first)->name) : NULL); + rpass = (rl ? BLI_findlink(&rl->passes, iuser->pass - (fake_name ? 1 : 0)) : NULL); display_name = rpass ? rpass->internal_name : (fake_name ? fake_name : ""); but = uiDefMenuBut(block, ui_imageuser_pass_menu, rnd_pt, IFACE_(display_name), diff --git a/source/blender/editors/space_image/space_image.c b/source/blender/editors/space_image/space_image.c index 928e064b730..98a0752f64d 100644 --- a/source/blender/editors/space_image/space_image.c +++ b/source/blender/editors/space_image/space_image.c @@ -157,7 +157,6 @@ static SpaceLink *image_new(const bContext *UNUSED(C)) simage->iuser.fie_ima = 2; simage->iuser.frames = 100; simage->iuser.flag = IMA_SHOW_STEREO; - simage->iuser.passtype = SCE_PASS_COMBINED; scopes_new(&simage->scopes); simage->sample_line_hist.height = 100; diff --git a/source/blender/makesdna/DNA_image_types.h b/source/blender/makesdna/DNA_image_types.h index 6088dccd4e9..56a8842a8d2 100644 --- a/source/blender/makesdna/DNA_image_types.h +++ b/source/blender/makesdna/DNA_image_types.h @@ -55,7 +55,8 @@ typedef struct ImageUser { char ok; char multiview_eye; /* multiview current eye - for internal use of drawing routines */ - int passtype; + short pass; + short pad; short multi_index, view, layer; /* listbase indices, for menu browsing or retrieve buffer */ short flag; diff --git a/source/blender/makesrna/intern/rna_image.c b/source/blender/makesrna/intern/rna_image.c index 0d0b440ec08..561f5c9dd26 100644 --- a/source/blender/makesrna/intern/rna_image.c +++ b/source/blender/makesrna/intern/rna_image.c @@ -539,6 +539,11 @@ static void rna_def_imageuser(BlenderRNA *brna) RNA_def_property_clear_flag(prop, PROP_EDITABLE); /* image_multi_cb */ RNA_def_property_ui_text(prop, "Layer", "Layer in multilayer image"); + prop = RNA_def_property(srna, "multilayer_pass", PROP_INT, PROP_UNSIGNED); + RNA_def_property_int_sdna(prop, NULL, "pass"); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); /* image_multi_cb */ + RNA_def_property_ui_text(prop, "Pass", "Pass in multilayer image"); + prop = RNA_def_property(srna, "multilayer_view", PROP_INT, PROP_UNSIGNED); RNA_def_property_int_sdna(prop, NULL, "view"); RNA_def_property_clear_flag(prop, PROP_EDITABLE); /* image_multi_cb */ -- cgit v1.2.3