diff options
-rw-r--r-- | source/blender/blenkernel/intern/node.c | 2 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_nodetree.c | 6 | ||||
-rw-r--r-- | source/blender/nodes/composite/node_composite_tree.c | 24 | ||||
-rw-r--r-- | source/blender/nodes/composite/nodes/node_composite_image.c | 338 |
4 files changed, 263 insertions, 107 deletions
diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c index b50969d0107..2fb3f81b147 100644 --- a/source/blender/blenkernel/intern/node.c +++ b/source/blender/blenkernel/intern/node.c @@ -1616,6 +1616,7 @@ int nodeUpdateID(bNodeTree *ntree, ID *id) for (node= ntree->nodes.first; node; node= node->next) { if (node->id==id) { change = TRUE; + node->update |= NODE_UPDATE_ID; ntreetype->update_node(ntree, node); /* clear update flag */ node->update = 0; @@ -1626,6 +1627,7 @@ int nodeUpdateID(bNodeTree *ntree, ID *id) for (node= ntree->nodes.first; node; node= node->next) { if (node->id==id) { change = TRUE; + node->update |= NODE_UPDATE_ID; if (node->typeinfo->updatefunc) node->typeinfo->updatefunc(ntree, node); /* clear update flag */ diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index 9d5a6049144..f5bded42a1c 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -357,7 +357,7 @@ static void rna_Node_update(Main *bmain, Scene *scene, PointerRNA *ptr) node_update(bmain, scene, ntree, node); } -static void rna_Node_image_update(Main *bmain, Scene *scene, PointerRNA *ptr) +static void rna_Node_tex_image_update(Main *bmain, Scene *scene, PointerRNA *ptr) { bNodeTree *ntree = (bNodeTree*)ptr->id.data; bNode *node = (bNode*)ptr->data; @@ -1299,7 +1299,7 @@ static void def_sh_tex_environment(StructRNA *srna) RNA_def_property_struct_type(prop, "Image"); RNA_def_property_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text(prop, "Image", ""); - RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_image_update"); + RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_tex_image_update"); RNA_def_struct_sdna_from(srna, "NodeTexEnvironment", "storage"); def_sh_tex(srna); @@ -1333,7 +1333,7 @@ static void def_sh_tex_image(StructRNA *srna) RNA_def_property_struct_type(prop, "Image"); RNA_def_property_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text(prop, "Image", ""); - RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_image_update"); + RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_tex_image_update"); RNA_def_struct_sdna_from(srna, "NodeTexImage", "storage"); def_sh_tex(srna); diff --git a/source/blender/nodes/composite/node_composite_tree.c b/source/blender/nodes/composite/node_composite_tree.c index 7bd0d03322d..049b5dd8178 100644 --- a/source/blender/nodes/composite/node_composite_tree.c +++ b/source/blender/nodes/composite/node_composite_tree.c @@ -757,26 +757,14 @@ void ntreeCompositForceHidden(bNodeTree *ntree, Scene *curscene) if (srl) force_hidden_passes(node, srl->passflag); } + /* XXX this stuff is called all the time, don't want that. + * Updates should only happen when actually necessary. + */ + #if 0 else if ( node->type==CMP_NODE_IMAGE) { - Image *ima= (Image *)node->id; - if (ima) { - if (ima->rr) { - ImageUser *iuser= node->storage; - RenderLayer *rl= BLI_findlink(&ima->rr->layers, iuser->layer); - if (rl) - force_hidden_passes(node, rl->passflag); - else - force_hidden_passes(node, RRES_OUT_IMAGE|RRES_OUT_ALPHA); - } - else if (ima->type!=IMA_TYPE_MULTILAYER) { /* if ->rr not yet read we keep inputs */ - force_hidden_passes(node, RRES_OUT_IMAGE|RRES_OUT_ALPHA|RRES_OUT_Z); - } - else - force_hidden_passes(node, RRES_OUT_IMAGE|RRES_OUT_ALPHA); - } - else - force_hidden_passes(node, RRES_OUT_IMAGE|RRES_OUT_ALPHA); + nodeUpdate(ntree, node); } + #endif } } diff --git a/source/blender/nodes/composite/nodes/node_composite_image.c b/source/blender/nodes/composite/nodes/node_composite_image.c index 44efbc6f9db..323767b64b1 100644 --- a/source/blender/nodes/composite/nodes/node_composite_image.c +++ b/source/blender/nodes/composite/nodes/node_composite_image.c @@ -32,7 +32,6 @@ #include "node_composite_util.h" - /* **************** IMAGE (and RenderResult, multilayer image) ******************** */ static bNodeSocketTemplate cmp_node_rlayers_out[]= { @@ -67,6 +66,212 @@ 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) +{ + bNodeSocket *sock; + + 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); + + return sock; +} + +static void cmp_node_image_add_render_pass_outputs(bNodeTree *ntree, bNode *node, int passflag) +{ + if (passflag & SCE_PASS_COMBINED) { + cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_COMBINED, RRES_OUT_IMAGE); + cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_COMBINED, RRES_OUT_ALPHA); + } + + if (passflag & SCE_PASS_Z) + cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_Z, RRES_OUT_Z); + if (passflag & SCE_PASS_NORMAL) + cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_NORMAL, RRES_OUT_NORMAL); + if (passflag & SCE_PASS_VECTOR) + cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_VECTOR, RRES_OUT_VEC); + if (passflag & SCE_PASS_UV) + cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_UV, RRES_OUT_UV); + if (passflag & SCE_PASS_RGBA) + cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_RGBA, RRES_OUT_RGBA); + if (passflag & SCE_PASS_DIFFUSE) + cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_DIFFUSE, RRES_OUT_DIFF); + if (passflag & SCE_PASS_SPEC) + cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_SPEC, RRES_OUT_SPEC); + if (passflag & SCE_PASS_SHADOW) + cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_SHADOW, RRES_OUT_SHADOW); + if (passflag & SCE_PASS_AO) + cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_AO, RRES_OUT_AO); + if (passflag & SCE_PASS_REFLECT) + cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_REFLECT, RRES_OUT_REFLECT); + if (passflag & SCE_PASS_REFRACT) + cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_REFRACT, RRES_OUT_REFRACT); + if (passflag & SCE_PASS_INDIRECT) + cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_INDIRECT, RRES_OUT_INDIRECT); + if (passflag & SCE_PASS_INDEXOB) + cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_INDEXOB, RRES_OUT_INDEXOB); + if (passflag & SCE_PASS_INDEXMA) + cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_INDEXMA, RRES_OUT_INDEXMA); + if (passflag & SCE_PASS_MIST) + cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_MIST, RRES_OUT_MIST); + if (passflag & SCE_PASS_EMIT) + cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_EMIT, RRES_OUT_EMIT); + if (passflag & SCE_PASS_ENVIRONMENT) + cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_ENVIRONMENT, RRES_OUT_ENV); + + if (passflag & SCE_PASS_DIFFUSE_DIRECT) + cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_DIFFUSE_DIRECT, RRES_OUT_DIFF_DIRECT); + if (passflag & SCE_PASS_DIFFUSE_INDIRECT) + cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_DIFFUSE_INDIRECT, RRES_OUT_DIFF_INDIRECT); + if (passflag & SCE_PASS_DIFFUSE_COLOR) + cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_DIFFUSE_COLOR, RRES_OUT_DIFF_COLOR); + + if (passflag & SCE_PASS_GLOSSY_DIRECT) + cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_GLOSSY_DIRECT, RRES_OUT_GLOSSY_DIRECT); + if (passflag & SCE_PASS_GLOSSY_INDIRECT) + cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_GLOSSY_INDIRECT, RRES_OUT_GLOSSY_INDIRECT); + if (passflag & SCE_PASS_GLOSSY_COLOR) + cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_GLOSSY_COLOR, RRES_OUT_GLOSSY_COLOR); + + if (passflag & SCE_PASS_TRANSM_DIRECT) + cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_TRANSM_DIRECT, RRES_OUT_TRANSM_DIRECT); + if (passflag & SCE_PASS_TRANSM_INDIRECT) + cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_TRANSM_INDIRECT, RRES_OUT_TRANSM_INDIRECT); + if (passflag & SCE_PASS_TRANSM_COLOR) + 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) +{ + bNodeSocket *sock; + 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); + } +} + +static void cmp_node_image_create_outputs(bNodeTree *ntree, bNode *node) +{ + Image *ima= (Image *)node->id; + if (ima) { + ImageUser *iuser= node->storage; + + /* make sure ima->type is correct */ + 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) + cmp_node_image_add_render_pass_outputs(ntree, node, rl->passflag); + else + cmp_node_image_add_multilayer_outputs(ntree, node, rl); + } + 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); + } + else + cmp_node_image_add_render_pass_outputs(ntree, node, RRES_OUT_IMAGE|RRES_OUT_ALPHA); +} + +static bNodeSocket *cmp_node_image_output_find_match(bNode *UNUSED(node), bNodeSocket *newsock, ListBase *oldsocklist) +{ + bNodeSocket *sock; + + for (sock=oldsocklist->first; sock; sock=sock->next) + if (strcmp(sock->name, newsock->name)==0) + return sock; + return NULL; +} + +static bNodeSocket *cmp_node_image_output_relink(bNode *node, bNodeSocket *oldsock, int oldindex) +{ + bNodeSocket *sock; + + /* first try to find matching socket name */ + for (sock=node->outputs.first; sock; sock=sock->next) + if (strcmp(sock->name, oldsock->name)==0) + return sock; + + /* no matching name, simply link to same index */ + return BLI_findlink(&node->outputs, oldindex); +} + +static void cmp_node_image_sync_output(bNode *UNUSED(node), bNodeSocket *UNUSED(newsock), bNodeSocket *UNUSED(oldsock)) +{ + /* pass */ +} + +/* XXX make this into a generic socket verification function for dynamic socket replacement (multilayer, groups, static templates) */ +static void cmp_node_image_verify_outputs(bNodeTree *ntree, bNode *node) +{ + bNodeSocket *newsock, *oldsock, *oldsock_next; + ListBase oldsocklist; + int oldindex; + bNodeLink *link; + + /* store current nodes in oldsocklist, then clear socket list */ + oldsocklist = node->outputs; + node->outputs.first = node->outputs.last = NULL; + + /* XXX make callback */ + cmp_node_image_create_outputs(ntree, node); + /* flag all new sockets as dynamic, to prevent removal by socket verification function */ + for (newsock=node->outputs.first; newsock; newsock=newsock->next) + newsock->flag |= SOCK_DYNAMIC; + + for (newsock=node->outputs.first; newsock; newsock=newsock->next) { + /* XXX make callback */ + oldsock = cmp_node_image_output_find_match(node, newsock, &oldsocklist); + if (oldsock) { + /* XXX make callback */ + cmp_node_image_sync_output(node, newsock, oldsock); + } + } + + /* move links to new socket */ + for (oldsock=oldsocklist.first, oldindex=0; oldsock; oldsock=oldsock->next, ++oldindex) { + newsock = cmp_node_image_output_relink(node, oldsock, oldindex); + + if (newsock) { + for (link=ntree->links.first; link; link=link->next) { + if (link->fromsock == oldsock) + link->fromsock = newsock; + } + } + } + + /* delete old sockets + * XXX oldsock is not actually in the node->outputs list any more, + * but the nodeRemoveSocket function works anyway. In future this + * should become part of the core code, so can take care of this behavior. + */ + for (oldsock=oldsocklist.first; oldsock; oldsock=oldsock_next) { + oldsock_next = oldsock->next; + nodeRemoveSocket(ntree, node, oldsock); + } +} + +static void cmp_node_image_update(bNodeTree *ntree, bNode *node) +{ + /* avoid unnecessary updates, only changes to the image/image user data are of interest */ + if (node->update & NODE_UPDATE_ID) + cmp_node_image_verify_outputs(ntree, node); +} + /* float buffer from the image with matching color management */ float *node_composit_get_float_buffer(RenderData *rd, ImBuf *ibuf, int *alloc) { @@ -189,85 +394,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 passtype) +static CompBuf *compbuf_multilayer_get(RenderData *rd, RenderLayer *rl, Image *ima, ImageUser *iuser, int passindex) { - RenderPass *rpass; - short index; - - for (index=0, rpass= rl->passes.first; rpass; rpass= rpass->next, index++) - if (rpass->passtype==passtype) - break; - + RenderPass *rpass = BLI_findlink(&rl->passes, passindex); if (rpass) { CompBuf *cbuf; - iuser->pass= index; + iuser->pass = passindex; BKE_image_multilayer_index(ima->rr, iuser); - cbuf= node_composit_get_image(rd, ima, iuser); + cbuf = node_composit_get_image(rd, ima, iuser); return cbuf; } return NULL; } -static void outputs_multilayer_get(RenderData *rd, RenderLayer *rl, bNodeStack **out, Image *ima, ImageUser *iuser) -{ - if (out[RRES_OUT_Z]->hasoutput) - out[RRES_OUT_Z]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_Z); - if (out[RRES_OUT_VEC]->hasoutput) - out[RRES_OUT_VEC]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_VECTOR); - if (out[RRES_OUT_NORMAL]->hasoutput) - out[RRES_OUT_NORMAL]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_NORMAL); - if (out[RRES_OUT_UV]->hasoutput) - out[RRES_OUT_UV]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_UV); - - if (out[RRES_OUT_RGBA]->hasoutput) - out[RRES_OUT_RGBA]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_RGBA); - if (out[RRES_OUT_DIFF]->hasoutput) - out[RRES_OUT_DIFF]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_DIFFUSE); - if (out[RRES_OUT_SPEC]->hasoutput) - out[RRES_OUT_SPEC]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_SPEC); - if (out[RRES_OUT_SHADOW]->hasoutput) - out[RRES_OUT_SHADOW]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_SHADOW); - if (out[RRES_OUT_AO]->hasoutput) - out[RRES_OUT_AO]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_AO); - if (out[RRES_OUT_REFLECT]->hasoutput) - out[RRES_OUT_REFLECT]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_REFLECT); - if (out[RRES_OUT_REFRACT]->hasoutput) - out[RRES_OUT_REFRACT]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_REFRACT); - if (out[RRES_OUT_INDIRECT]->hasoutput) - out[RRES_OUT_INDIRECT]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_INDIRECT); - if (out[RRES_OUT_INDEXOB]->hasoutput) - out[RRES_OUT_INDEXOB]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_INDEXOB); - if (out[RRES_OUT_INDEXMA]->hasoutput) - out[RRES_OUT_INDEXMA]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_INDEXMA); - if (out[RRES_OUT_MIST]->hasoutput) - out[RRES_OUT_MIST]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_MIST); - if (out[RRES_OUT_EMIT]->hasoutput) - out[RRES_OUT_EMIT]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_EMIT); - if (out[RRES_OUT_ENV]->hasoutput) - out[RRES_OUT_ENV]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_ENVIRONMENT); - if (out[RRES_OUT_DIFF_DIRECT]->hasoutput) - out[RRES_OUT_DIFF_DIRECT]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_DIFFUSE_DIRECT); - if (out[RRES_OUT_DIFF_INDIRECT]->hasoutput) - out[RRES_OUT_DIFF_INDIRECT]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_DIFFUSE_INDIRECT); - if (out[RRES_OUT_DIFF_COLOR]->hasoutput) - out[RRES_OUT_DIFF_COLOR]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_DIFFUSE_COLOR); - if (out[RRES_OUT_GLOSSY_DIRECT]->hasoutput) - out[RRES_OUT_GLOSSY_DIRECT]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_GLOSSY_DIRECT); - if (out[RRES_OUT_GLOSSY_INDIRECT]->hasoutput) - out[RRES_OUT_GLOSSY_INDIRECT]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_GLOSSY_INDIRECT); - if (out[RRES_OUT_GLOSSY_COLOR]->hasoutput) - out[RRES_OUT_GLOSSY_COLOR]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_GLOSSY_COLOR); - if (out[RRES_OUT_TRANSM_DIRECT]->hasoutput) - out[RRES_OUT_TRANSM_DIRECT]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_TRANSM_DIRECT); - if (out[RRES_OUT_TRANSM_INDIRECT]->hasoutput) - out[RRES_OUT_TRANSM_INDIRECT]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_TRANSM_INDIRECT); - if (out[RRES_OUT_TRANSM_COLOR]->hasoutput) - out[RRES_OUT_TRANSM_COLOR]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_TRANSM_COLOR); -} - - static void node_composit_exec_image(void *data, bNode *node, bNodeStack **UNUSED(in), bNodeStack **out) { @@ -277,7 +418,6 @@ static void node_composit_exec_image(void *data, bNode *node, bNodeStack **UNUSE RenderData *rd= data; Image *ima= (Image *)node->id; ImageUser *iuser= (ImageUser *)node->storage; - CompBuf *stackbuf= NULL; /* first set the right frame number in iuser */ BKE_image_user_calc_frame(iuser, rd->cfra, 0); @@ -290,15 +430,36 @@ static void node_composit_exec_image(void *data, bNode *node, bNodeStack **UNUSE RenderLayer *rl= BLI_findlink(&ima->rr->layers, iuser->layer); if (rl) { - out[0]->data= stackbuf= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_COMBINED); + bNodeSocket *sock; + int out_index; + CompBuf *combinedbuf= NULL, *firstbuf= NULL; - /* go over all layers */ - outputs_multilayer_get(rd, rl, out, ima, iuser); + for (sock=node->outputs.first, out_index=0; sock; sock=sock->next, ++out_index) { + int passindex = GET_INT_FROM_POINTER(sock->storage); + if (out[out_index]->hasoutput) { + CompBuf *stackbuf = out[out_index]->data = compbuf_multilayer_get(rd, rl, ima, iuser, passindex); + if (stackbuf) { + /* preview policy: take first 'Combined' pass if available, + * otherwise just use the first layer. + */ + if (!firstbuf) + firstbuf = stackbuf; + if (!combinedbuf && + (strcmp(sock->name, "Combined")==0 || strcmp(sock->name, "Image")==0)) + combinedbuf = stackbuf; + } + } + } + + /* preview */ + if (combinedbuf) + generate_preview(data, node, combinedbuf); + else if (firstbuf) + generate_preview(data, node, firstbuf); } } else { - stackbuf= node_composit_get_image(rd, ima, iuser); - + CompBuf *stackbuf = node_composit_get_image(rd, ima, iuser); if (stackbuf) { /*respect image premul option*/ if (stackbuf->type==CB_RGBA && ima->flag & IMA_DO_PREMUL) { @@ -324,23 +485,23 @@ static void node_composit_exec_image(void *data, bNode *node, bNodeStack **UNUSE /* put image on stack */ out[0]->data= stackbuf; - + + /* alpha output */ + if (out[1]->hasoutput) + out[1]->data= valbuf_from_rgbabuf(stackbuf, CHAN_A); + + /* Z output */ if (out[2]->hasoutput) out[2]->data= node_composit_get_zimage(node, rd); + + /* preview */ + generate_preview(data, node, stackbuf); } } - - /* alpha and preview for both types */ - if (stackbuf) { - if (out[1]->hasoutput) - out[1]->data= valbuf_from_rgbabuf(stackbuf, CHAN_A); - - generate_preview(data, node, stackbuf); - } } } -static void node_composit_init_image(bNodeTree *UNUSED(ntree), bNode* node, bNodeTemplate *UNUSED(ntemp)) +static void node_composit_init_image(bNodeTree *ntree, bNode* node, bNodeTemplate *UNUSED(ntemp)) { ImageUser *iuser= MEM_callocN(sizeof(ImageUser), "node image user"); node->storage= iuser; @@ -348,6 +509,9 @@ static void node_composit_init_image(bNodeTree *UNUSED(ntree), bNode* node, bNod iuser->sfra= 1; iuser->fie_ima= 2; iuser->ok= 1; + + /* setup initial outputs */ + cmp_node_image_verify_outputs(ntree, node); } void register_node_type_cmp_image(bNodeTreeType *ttype) @@ -355,10 +519,10 @@ void register_node_type_cmp_image(bNodeTreeType *ttype) static bNodeType ntype; node_type_base(ttype, &ntype, CMP_NODE_IMAGE, "Image", NODE_CLASS_INPUT, NODE_PREVIEW|NODE_OPTIONS); - node_type_socket_templates(&ntype, NULL, cmp_node_rlayers_out); 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_update(&ntype, cmp_node_image_update, NULL); node_type_exec(&ntype, node_composit_exec_image); nodeRegisterType(ttype, &ntype); @@ -449,6 +613,8 @@ static void node_composit_rlayers_out(RenderData *rd, RenderLayer *rl, bNodeStac out[RRES_OUT_TRANSM_COLOR]->data= compbuf_from_pass(rd, rl, rectx, recty, SCE_PASS_TRANSM_COLOR); } + + static void node_composit_exec_rlayers(void *data, bNode *node, bNodeStack **UNUSED(in), bNodeStack **out) { Scene *sce= (Scene *)node->id; |