Dynamic output sockets for the image input node. This is needed to enable the node to read arbitrary multilayer exr files. Output sockets of this node are now generated dynamically when the image is updated. The image buffer has to be loaded to detect multilayer files on update.

This commit is contained in:
Lukas Toenne 2012-04-16 13:49:33 +00:00
parent 37a79f4727
commit f4498e62a7
4 changed files with 263 additions and 107 deletions

View File

@ -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 */

View File

@ -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);

View File

@ -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
}
}

View File

@ -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;