diff options
Diffstat (limited to 'source/blender/nodes/composite/nodes/node_composite_image.c')
-rw-r--r-- | source/blender/nodes/composite/nodes/node_composite_image.c | 129 |
1 files changed, 87 insertions, 42 deletions
diff --git a/source/blender/nodes/composite/nodes/node_composite_image.c b/source/blender/nodes/composite/nodes/node_composite_image.c index 02bb16f644a..4467fb1f193 100644 --- a/source/blender/nodes/composite/nodes/node_composite_image.c +++ b/source/blender/nodes/composite/nodes/node_composite_image.c @@ -66,13 +66,17 @@ static bNodeSocketTemplate cmp_node_rlayers_out[]= { { -1, 0, "" } }; -static bNodeSocket *cmp_node_image_add_render_pass_output(bNodeTree *ntree, bNode *node, int UNUSED(pass), int rres_index) +static bNodeSocket *cmp_node_image_add_render_pass_output(bNodeTree *ntree, bNode *node, int pass, int rres_index) { bNodeSocket *sock; + NodeImageLayer *sockdata; sock = node_add_output_from_template(ntree, node, &cmp_node_rlayers_out[rres_index]); - /* for render pass outputs store the pass type index as a lookup key */ - sock->storage = SET_INT_IN_POINTER(rres_index); + /* extra socket info */ + sockdata = MEM_callocN(sizeof(NodeImageLayer), "node image layer"); + sock->storage = sockdata; + + sockdata->pass_flag = pass; return sock; } @@ -141,21 +145,37 @@ static void cmp_node_image_add_render_pass_outputs(bNodeTree *ntree, bNode *node cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_TRANSM_COLOR, RRES_OUT_TRANSM_COLOR); } -static void cmp_node_image_add_multilayer_outputs(bNodeTree *ntree, bNode *node, RenderLayer *rl) +static void cmp_node_image_add_multilayer_outputs(bNodeTree *ntree, bNode *node, ListBase *layers) { bNodeSocket *sock; + NodeImageLayer *sockdata; + RenderLayer *rl; RenderPass *rpass; - int index; - for (rpass=rl->passes.first, index=0; rpass; rpass=rpass->next, ++index) { - int type; - if (rpass->channels == 1) - type = SOCK_FLOAT; - else - type = SOCK_RGBA; - - sock = nodeAddSocket(ntree, node, SOCK_OUT, rpass->name, type); - /* for multilayer image use pass index directly as key */ - sock->storage = SET_INT_IN_POINTER(index); + int layer_index, pass_index; + char name[30]; /* EXR_TOT_MAXNAME-2 ('.' and channel char are appended) */ + int type; + + for (rl=layers->first, layer_index=0; rl; rl=rl->next, ++layer_index) { + for (rpass=rl->passes.first, pass_index=0; rpass; rpass=rpass->next, ++pass_index) { + /* reconstruct layer name from <render layer>.<render pass> strings */ + if (rl->name[0] != '\0') + BLI_snprintf(name, sizeof(name), "%s.%s", rl->name, rpass->name); + else + BLI_strncpy(name, rpass->name, sizeof(name)); + + if (rpass->channels == 1) + type = SOCK_FLOAT; + else + type = SOCK_RGBA; + + sock = nodeAddSocket(ntree, node, SOCK_OUT, name, type); + /* extra socket info */ + sockdata = MEM_callocN(sizeof(NodeImageLayer), "node image layer"); + sock->storage = sockdata; + + sockdata->layer_index = layer_index; + sockdata->pass_index = pass_index; + } } } @@ -169,16 +189,16 @@ static void cmp_node_image_create_outputs(bNodeTree *ntree, bNode *node) BKE_image_get_ibuf(ima, iuser); if (ima->rr) { - RenderLayer *rl= BLI_findlink(&ima->rr->layers, iuser->layer); - - if (rl) { - if (ima->type!=IMA_TYPE_MULTILAYER) + if (ima->type == IMA_TYPE_MULTILAYER) { + cmp_node_image_add_multilayer_outputs(ntree, node, &ima->rr->layers); + } + else { + RenderLayer *rl= BLI_findlink(&ima->rr->layers, iuser->layer); + if (rl) cmp_node_image_add_render_pass_outputs(ntree, node, rl->passflag); else - cmp_node_image_add_multilayer_outputs(ntree, node, rl); + cmp_node_image_add_render_pass_outputs(ntree, node, RRES_OUT_IMAGE|RRES_OUT_ALPHA); } - else - cmp_node_image_add_render_pass_outputs(ntree, node, RRES_OUT_IMAGE|RRES_OUT_ALPHA); } else cmp_node_image_add_render_pass_outputs(ntree, node, RRES_OUT_IMAGE|RRES_OUT_ALPHA|RRES_OUT_Z); @@ -261,6 +281,7 @@ static void cmp_node_image_verify_outputs(bNodeTree *ntree, bNode *node) */ for (oldsock=oldsocklist.first; oldsock; oldsock=oldsock_next) { oldsock_next = oldsock->next; + MEM_freeN(oldsock->storage); nodeRemoveSocket(ntree, node, oldsock); } } @@ -394,17 +415,21 @@ static CompBuf *node_composit_get_zimage(bNode *node, RenderData *rd) } /* check if layer is available, returns pass buffer */ -static CompBuf *compbuf_multilayer_get(RenderData *rd, RenderLayer *rl, Image *ima, ImageUser *iuser, int passindex) +static CompBuf *compbuf_multilayer_get(RenderData *rd, Image *ima, ImageUser *iuser, int layer_index, int pass_index) { - RenderPass *rpass = BLI_findlink(&rl->passes, passindex); - if (rpass) { - CompBuf *cbuf; - - iuser->pass = passindex; - BKE_image_multilayer_index(ima->rr, iuser); - cbuf = node_composit_get_image(rd, ima, iuser); - - return cbuf; + RenderLayer *rl = BLI_findlink(&ima->rr->layers, layer_index); + if (rl) { + RenderPass *rpass = BLI_findlink(&rl->passes, pass_index); + if (rpass) { + CompBuf *cbuf; + + iuser->layer = layer_index; + iuser->pass = pass_index; + BKE_image_multilayer_index(ima->rr, iuser); + cbuf = node_composit_get_image(rd, ima, iuser); + + return cbuf; + } } return NULL; } @@ -422,22 +447,20 @@ static void node_composit_exec_image(void *data, bNode *node, bNodeStack **UNUSE /* first set the right frame number in iuser */ BKE_image_user_frame_calc(iuser, rd->cfra, 0); - /* force a load, we assume iuser index will be set OK anyway */ - if (ima->type==IMA_TYPE_MULTILAYER) + if (ima->type==IMA_TYPE_MULTILAYER) { + /* force a load, we assume iuser index will be set OK anyway */ BKE_image_get_ibuf(ima, iuser); - if (ima->type==IMA_TYPE_MULTILAYER && ima->rr) { - RenderLayer *rl= BLI_findlink(&ima->rr->layers, iuser->layer); - - if (rl) { + if (ima->rr) { bNodeSocket *sock; + NodeImageLayer *sockdata; int out_index; CompBuf *combinedbuf= NULL, *firstbuf= NULL; for (sock=node->outputs.first, out_index=0; sock; sock=sock->next, ++out_index) { - int passindex = GET_INT_FROM_POINTER(sock->storage); + sockdata = sock->storage; if (out[out_index]->hasoutput) { - CompBuf *stackbuf = out[out_index]->data = compbuf_multilayer_get(rd, rl, ima, iuser, passindex); + CompBuf *stackbuf = out[out_index]->data = compbuf_multilayer_get(rd, ima, iuser, sockdata->layer_index, sockdata->pass_index); if (stackbuf) { /* preview policy: take first 'Combined' pass if available, * otherwise just use the first layer. @@ -446,7 +469,7 @@ static void node_composit_exec_image(void *data, bNode *node, bNodeStack **UNUSE firstbuf = stackbuf; } if (!combinedbuf && - (strcmp(sock->name, "Combined") == 0 || strcmp(sock->name, "Image") == 0)) + (strcmp(sock->name, "Combined") == 0 || strcmp(sock->name, "Image") == 0)) { combinedbuf = stackbuf; } @@ -520,6 +543,28 @@ static void node_composit_init_image(bNodeTree *ntree, bNode* node, bNodeTemplat cmp_node_image_verify_outputs(ntree, node); } +static void node_composit_free_image(bNode *node) +{ + bNodeSocket *sock; + + /* free extra socket info */ + for (sock=node->outputs.first; sock; sock=sock->next) + MEM_freeN(sock->storage); + + MEM_freeN(node->storage); +} + +static void node_composit_copy_image(bNode *orig_node, bNode *new_node) +{ + bNodeSocket *sock; + + new_node->storage= MEM_dupallocN(orig_node->storage); + + /* copy extra socket info */ + for (sock=orig_node->outputs.first; sock; sock=sock->next) + sock->new_sock->storage = MEM_dupallocN(sock->storage); +} + void register_node_type_cmp_image(bNodeTreeType *ttype) { static bNodeType ntype; @@ -527,7 +572,7 @@ void register_node_type_cmp_image(bNodeTreeType *ttype) node_type_base(ttype, &ntype, CMP_NODE_IMAGE, "Image", NODE_CLASS_INPUT, NODE_PREVIEW|NODE_OPTIONS); node_type_size(&ntype, 120, 80, 300); node_type_init(&ntype, node_composit_init_image); - node_type_storage(&ntype, "ImageUser", node_free_standard_storage, node_copy_standard_storage); + node_type_storage(&ntype, "ImageUser", node_composit_free_image, node_composit_copy_image); node_type_update(&ntype, cmp_node_image_update, NULL); node_type_exec(&ntype, node_composit_exec_image); |