/* called from within UI, saves both rendered result as a file-read result */ int RE_WriteRenderResult(ReportList *reports, RenderResult *rr, const char *filename, int compress) { RenderLayer *rl; RenderPass *rpass; void *exrhandle = IMB_exr_get_handle(); int success; BLI_make_existing_file(filename); /* composite result */ if (rr->rectf) { IMB_exr_add_channel(exrhandle, "Composite", "Combined.R", 4, 4 * rr->rectx, rr->rectf); IMB_exr_add_channel(exrhandle, "Composite", "Combined.G", 4, 4 * rr->rectx, rr->rectf + 1); IMB_exr_add_channel(exrhandle, "Composite", "Combined.B", 4, 4 * rr->rectx, rr->rectf + 2); IMB_exr_add_channel(exrhandle, "Composite", "Combined.A", 4, 4 * rr->rectx, rr->rectf + 3); } /* add layers/passes and assign channels */ for (rl = rr->layers.first; rl; rl = rl->next) { /* combined */ if (rl->rectf) { int a, xstride = 4; for (a = 0; a < xstride; a++) { IMB_exr_add_channel(exrhandle, rl->name, get_pass_name(SCE_PASS_COMBINED, a), xstride, xstride * rr->rectx, rl->rectf + a); } } /* passes are allocated in sync */ for (rpass = rl->passes.first; rpass; rpass = rpass->next) { int a, xstride = rpass->channels; for (a = 0; a < xstride; a++) { if (rpass->passtype) { IMB_exr_add_channel(exrhandle, rl->name, get_pass_name(rpass->passtype, a), xstride, xstride * rr->rectx, rpass->rect + a); } else { IMB_exr_add_channel(exrhandle, rl->name, make_pass_name(rpass, a), xstride, xstride * rr->rectx, rpass->rect + a); } } } } /* when the filename has no permissions, this can fail */ if (IMB_exr_begin_write(exrhandle, filename, rr->rectx, rr->recty, compress)) { IMB_exr_write_channels(exrhandle); success = TRUE; } else { /* TODO, get the error from openexr's exception */ BKE_report(reports, RPT_ERROR, "Error writing render result (see console)"); success = FALSE; } IMB_exr_close(exrhandle); return success; }
/* called for reading temp files, and for external engines */ int render_result_exr_file_read_path(RenderResult *rr, RenderLayer *rl_single, const char *filepath) { RenderLayer *rl; RenderPass *rpass; void *exrhandle = IMB_exr_get_handle(); int rectx, recty; if (IMB_exr_begin_read(exrhandle, filepath, &rectx, &recty) == 0) { printf("failed being read %s\n", filepath); IMB_exr_close(exrhandle); return 0; } if (rr == NULL || rectx != rr->rectx || recty != rr->recty) { if (rr) printf("error in reading render result: dimensions don't match\n"); else printf("error in reading render result: NULL result pointer\n"); IMB_exr_close(exrhandle); return 0; } for (rl = rr->layers.first; rl; rl = rl->next) { if (rl_single && rl_single != rl) continue; /* combined */ if (rl->rectf) { int a, xstride = 4; for (a = 0; a < xstride; a++) IMB_exr_set_channel(exrhandle, rl->name, get_pass_name(SCE_PASS_COMBINED, a), xstride, xstride * rectx, rl->rectf + a); } /* passes are allocated in sync */ for (rpass = rl->passes.first; rpass; rpass = rpass->next) { int a, xstride = rpass->channels; for (a = 0; a < xstride; a++) IMB_exr_set_channel(exrhandle, rl->name, get_pass_name(rpass->passtype, a), xstride, xstride * rectx, rpass->rect + a); BLI_strncpy(rpass->name, get_pass_name(rpass->passtype, -1), sizeof(rpass->name)); } } IMB_exr_read_channels(exrhandle); IMB_exr_close(exrhandle); return 1; }
bool IR_CP::perform(OptCtx & oc) { START_TIMER_AFTER(); ASSERT0(OC_is_cfg_valid(oc)); if (m_prop_kind == CP_PROP_CONST) { m_ru->checkValidAndRecompute(&oc, PASS_DOM, PASS_DU_REF, PASS_DU_CHAIN, PASS_UNDEF); } else { m_ru->checkValidAndRecompute(&oc, PASS_DOM, PASS_DU_REF, PASS_LIVE_EXPR, PASS_DU_CHAIN, PASS_UNDEF); } if (!OC_is_du_chain_valid(oc)) { END_TIMER_AFTER(get_pass_name()); return false; } bool change = false; IRBB * entry = m_ru->get_cfg()->get_entry(); ASSERT(entry, ("Not unique entry, invalid Region")); Graph domtree; m_cfg->get_dom_tree(domtree); List<Vertex*> lst; Vertex * root = domtree.get_vertex(BB_id(entry)); m_cfg->sortDomTreeInPreorder(root, lst); Vector<IR*> usevec; for (Vertex * v = lst.get_head(); v != NULL; v = lst.get_next()) { IRBB * bb = m_cfg->get_bb(VERTEX_id(v)); ASSERT0(bb); change |= doProp(bb, usevec); } if (change) { doFinalRefine(); OC_is_expr_tab_valid(oc) = false; OC_is_aa_valid(oc) = false; OC_is_du_chain_valid(oc) = true; //already update. OC_is_ref_valid(oc) = true; //already update. ASSERT0(m_ru->verifyMDRef() && m_du->verifyMDDUChain()); ASSERT0(verifySSAInfo(m_ru)); } END_TIMER_AFTER(get_pass_name()); return change; }
static void render_layer_add_pass(RenderResult *rr, RenderLayer *rl, int channels, int passtype) { const char *typestr = get_pass_name(passtype, 0); RenderPass *rpass = MEM_callocN(sizeof(RenderPass), typestr); int rectsize = rr->rectx * rr->recty * channels; BLI_addtail(&rl->passes, rpass); rpass->passtype = passtype; rpass->channels = channels; rpass->rectx = rl->rectx; rpass->recty = rl->recty; BLI_strncpy(rpass->name, get_pass_name(rpass->passtype, -1), sizeof(rpass->name)); if (rl->exrhandle) { int a; for (a = 0; a < channels; a++) IMB_exr_add_channel(rl->exrhandle, rl->name, get_pass_name(passtype, a), 0, 0, NULL); } else { float *rect; int x; rpass->rect = MEM_mapallocN(sizeof(float) * rectsize, typestr); if (passtype == SCE_PASS_VECTOR) { /* initialize to max speed */ rect = rpass->rect; for (x = rectsize - 1; x >= 0; x--) rect[x] = PASS_VECTOR_MAX; } else if (passtype == SCE_PASS_Z) { rect = rpass->rect; for (x = rectsize - 1; x >= 0; x--) rect[x] = 10e10; } } }
bool PRDF::perform(OptCTX & oc) { START_TIMER_AFTER(); m_ru->checkValidAndRecompute(&oc, PASS_RPO, PASS_UNDEF); List<IRBB*> * bbl = m_ru->get_bb_list(); if (bbl->get_elem_count() == 0) { return false; } List<IR const*> lst; C<IRBB*> * ct; for (bbl->get_head(&ct); ct != bbl->end(); ct = bbl->get_next(ct)) { IRBB * bb = ct->val(); ASSERT0(bb); computeLocal(bb, lst); } computeGlobal(); //dump(); END_TIMER_AFTER(get_pass_name()); return false; }
static void save_render_result_tile(RenderResult *rr, RenderResult *rrpart) { RenderLayer *rlp, *rl; RenderPass *rpassp; int offs, partx, party; BLI_lock_thread(LOCK_IMAGE); for (rlp = rrpart->layers.first; rlp; rlp = rlp->next) { rl = RE_GetRenderLayer(rr, rlp->name); /* should never happen but prevents crash if it does */ BLI_assert(rl); if (UNLIKELY(rl == NULL)) { continue; } if (rrpart->crop) { /* filters add pixel extra */ offs = (rrpart->crop + rrpart->crop * rrpart->rectx); } else { offs = 0; } /* combined */ if (rlp->rectf) { int a, xstride = 4; for (a = 0; a < xstride; a++) { IMB_exr_set_channel(rl->exrhandle, rlp->name, get_pass_name(SCE_PASS_COMBINED, a), xstride, xstride * rrpart->rectx, rlp->rectf + a + xstride * offs); } } /* passes are allocated in sync */ for (rpassp = rlp->passes.first; rpassp; rpassp = rpassp->next) { int a, xstride = rpassp->channels; for (a = 0; a < xstride; a++) { IMB_exr_set_channel(rl->exrhandle, rlp->name, get_pass_name(rpassp->passtype, a), xstride, xstride * rrpart->rectx, rpassp->rect + a + xstride * offs); } } } party = rrpart->tilerect.ymin + rrpart->crop; partx = rrpart->tilerect.xmin + rrpart->crop; for (rlp = rrpart->layers.first; rlp; rlp = rlp->next) { rl = RE_GetRenderLayer(rr, rlp->name); /* should never happen but prevents crash if it does */ BLI_assert(rl); if (UNLIKELY(rl == NULL)) { continue; } IMB_exrtile_write_channels(rl->exrhandle, partx, party, 0); } BLI_unlock_thread(LOCK_IMAGE); }