static void save_render_result_tile(RenderResult *rr, RenderResult *rrpart, const char *viewname) { 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; } /* passes are allocated in sync */ for (rpassp = rlp->passes.first; rpassp; rpassp = rpassp->next) { const int xstride = rpassp->channels; int a; char passname[EXR_PASS_MAXNAME]; for (a = 0; a < xstride; a++) { set_pass_name(passname, rpassp->passtype, a, rpassp->view); IMB_exr_set_channel(rl->exrhandle, rlp->name, passname, 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, viewname); } BLI_unlock_thread(LOCK_IMAGE); }
/* is used within threads */ void render_result_merge(RenderResult *rr, RenderResult *rrpart) { RenderLayer *rl, *rlp; RenderPass *rpass, *rpassp; for (rl = rr->layers.first; rl; rl = rl->next) { rlp = RE_GetRenderLayer(rrpart, rl->name); if (rlp) { /* passes are allocated in sync */ for (rpass = rl->passes.first, rpassp = rlp->passes.first; rpass && rpassp; rpass = rpass->next) { /* renderresult have all passes, renderpart only the active view's passes */ if (strcmp(rpassp->name, rpass->name) != 0) continue; do_merge_tile(rr, rrpart, rpass->rect, rpassp->rect, rpass->channels); /* manually get next render pass */ rpassp = rpassp->next; } } } }
void RenderLayersProg::initExecution() { Scene *scene = this->getScene(); Render *re = (scene) ? RE_GetSceneRender(scene) : NULL; RenderResult *rr = NULL; if (re) { rr = RE_AcquireResultRead(re); } if (rr) { ViewLayer *view_layer = (ViewLayer *)BLI_findlink(&scene->view_layers, getLayerId()); if (view_layer) { RenderLayer *rl = RE_GetRenderLayer(rr, view_layer->name); if (rl) { this->m_inputBuffer = RE_RenderLayerGetPass( rl, this->m_passName.c_str(), this->m_viewName); } } } if (re) { RE_ReleaseResult(re); re = NULL; } }
void RenderLayersProg::determineResolution(unsigned int resolution[2], unsigned int /*preferredResolution*/[2]) { Scene *sce = this->getScene(); Render *re = (sce) ? RE_GetSceneRender(sce) : NULL; RenderResult *rr = NULL; resolution[0] = 0; resolution[1] = 0; if (re) { rr = RE_AcquireResultRead(re); } if (rr) { ViewLayer *view_layer = (ViewLayer *)BLI_findlink(&sce->view_layers, getLayerId()); if (view_layer) { RenderLayer *rl = RE_GetRenderLayer(rr, view_layer->name); if (rl) { resolution[0] = rl->rectx; resolution[1] = rl->recty; } } } if (re) { RE_ReleaseResult(re); } }
void RenderLayersBaseProg::initExecution() { Scene *scene = this->getScene(); Render *re = (scene) ? RE_GetRender(scene->id.name) : NULL; RenderResult *rr = NULL; if (re) rr = RE_AcquireResultRead(re); if (rr) { SceneRenderLayer *srl = (SceneRenderLayer *)BLI_findlink(&scene->r.layers, getLayerId()); if (srl) { RenderLayer *rl = RE_GetRenderLayer(rr, srl->name); if (rl && rl->rectf) { this->m_inputBuffer = RE_RenderLayerGetPass(rl, this->m_renderpass); if (this->m_inputBuffer == NULL && this->m_renderpass == SCE_PASS_COMBINED) { this->m_inputBuffer = rl->rectf; } } } } if (re) { RE_ReleaseResult(re); re = NULL; } }
void RenderLayersBaseProg::determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2]) { Scene *sce = this->getScene(); Render *re = (sce) ? RE_GetRender(sce->id.name) : NULL; RenderResult *rr = NULL; resolution[0] = 0; resolution[1] = 0; if (re) rr = RE_AcquireResultRead(re); if (rr) { SceneRenderLayer *srl = (SceneRenderLayer *)BLI_findlink(&sce->r.layers, getLayerId()); if (srl) { RenderLayer *rl = RE_GetRenderLayer(rr, srl->name); if (rl && rl->rectf) { resolution[0] = rl->rectx; resolution[1] = rl->recty; } } } if (re) RE_ReleaseResult(re); }
static void node_composit_exec_rlayers(void *data, bNode *node, bNodeStack **UNUSED(in), bNodeStack **out) { Scene *sce= (Scene *)node->id; Render *re= (sce)? RE_GetRender(sce->id.name): NULL; RenderData *rd= data; RenderResult *rr= NULL; if(re) rr= RE_AcquireResultRead(re); if(rr) { SceneRenderLayer *srl= BLI_findlink(&sce->r.layers, node->custom1); if(srl) { RenderLayer *rl= RE_GetRenderLayer(rr, srl->name); if(rl && rl->rectf) { CompBuf *stackbuf; /* we put render rect on stack, cbuf knows rect is from other ibuf when freed! */ if(rd->scemode & R_COMP_CROP) stackbuf= get_cropped_compbuf(&rd->disprect, rl->rectf, rr->rectx, rr->recty, CB_RGBA); else { stackbuf= alloc_compbuf(rr->rectx, rr->recty, CB_RGBA, 0); stackbuf->rect= rl->rectf; } if(stackbuf==NULL) { printf("Error; Preview Panel in UV Window returns zero sized image\n"); } else { stackbuf->xof= rr->xof; stackbuf->yof= rr->yof; /* put on stack */ out[RRES_OUT_IMAGE]->data= stackbuf; if(out[RRES_OUT_ALPHA]->hasoutput) out[RRES_OUT_ALPHA]->data= valbuf_from_rgbabuf(stackbuf, CHAN_A); node_composit_rlayers_out(rd, rl, out, rr->rectx, rr->recty); generate_preview(data, node, stackbuf); } } } } if(re) RE_ReleaseResult(re); }
/* if scemode is R_SINGLE_LAYER, at end of rendering, merge the both render results */ void render_result_single_layer_end(Render *re) { SceneRenderLayer *srl; RenderLayer *rlpush; RenderLayer *rl; int nr; if (re->result == NULL) { printf("pop render result error; no current result!\n"); return; } if (!re->pushedresult) return; if (re->pushedresult->rectx == re->result->rectx && re->pushedresult->recty == re->result->recty) { /* find which layer in re->pushedresult should be replaced */ rl = re->result->layers.first; /* render result should be empty after this */ BLI_remlink(&re->result->layers, rl); /* reconstruct render result layers */ for (nr = 0, srl = re->r.layers.first; srl; srl = srl->next, nr++) { if (nr == re->r.actlay) { BLI_addtail(&re->result->layers, rl); } else { rlpush = RE_GetRenderLayer(re->pushedresult, srl->name); if (rlpush) { BLI_remlink(&re->pushedresult->layers, rlpush); BLI_addtail(&re->result->layers, rlpush); } } } } RE_FreeRenderResult(re->pushedresult); re->pushedresult = NULL; }
/* is used within threads */ void render_result_merge(RenderResult *rr, RenderResult *rrpart) { RenderLayer *rl, *rlp; RenderPass *rpass, *rpassp; for (rl = rr->layers.first; rl; rl = rl->next) { rlp = RE_GetRenderLayer(rrpart, rl->name); if (rlp) { /* combined */ if (rl->rectf && rlp->rectf) do_merge_tile(rr, rrpart, rl->rectf, rlp->rectf, 4); /* passes are allocated in sync */ for (rpass = rl->passes.first, rpassp = rlp->passes.first; rpass && rpassp; rpass = rpass->next, rpassp = rpassp->next) { do_merge_tile(rr, rrpart, rpass->rect, rpassp->rect, rpass->channels); } } } }
void RenderLayersNode::testRenderLink(NodeConverter &converter, const CompositorContext &context, Render *re) const { Scene *scene = (Scene *)this->getbNode()->id; const short layerId = this->getbNode()->custom1; RenderResult *rr = RE_AcquireResultRead(re); if (rr == NULL) { missingRenderLink(converter); return; } SceneRenderLayer *srl = (SceneRenderLayer *)BLI_findlink(&scene->r.layers, layerId); if (srl == NULL) { missingRenderLink(converter); return; } RenderLayer *rl = RE_GetRenderLayer(rr, srl->name); if (rl == NULL) { missingRenderLink(converter); return; } const int num_outputs = this->getNumberOfOutputSockets(); for (int i = 0; i < num_outputs; i++) { NodeOutput *output = this->getOutputSocket(i); NodeImageLayer *storage = (NodeImageLayer *)output->getbNodeSocket()->storage; RenderPass *rpass = (RenderPass *)BLI_findstring( &rl->passes, storage->pass_name, offsetof(RenderPass, name)); if (rpass == NULL) { missingSocketLink(converter, output); continue; } RenderLayersProg *operation; bool is_preview; if (STREQ(rpass->name, RE_PASSNAME_COMBINED) && STREQ(output->getbNodeSocket()->name, "Alpha")) { operation = new RenderLayersAlphaProg(rpass->name, COM_DT_VALUE, rpass->channels); is_preview = false; } else if (STREQ(rpass->name, RE_PASSNAME_Z)) { operation = new RenderLayersDepthProg(rpass->name, COM_DT_VALUE, rpass->channels); is_preview = false; } else { DataType type; switch (rpass->channels) { case 4: type = COM_DT_COLOR; break; case 3: type = COM_DT_VECTOR; break; case 1: type = COM_DT_VALUE; break; default: BLI_assert(!"Unexpected number of channels for pass"); type = COM_DT_VALUE; break; } operation = new RenderLayersProg(rpass->name, type, rpass->channels); is_preview = STREQ(output->getbNodeSocket()->name, "Image"); } testSocketLink(converter, context, output, operation, scene, layerId, is_preview); } }