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:
parent
37a79f4727
commit
f4498e62a7
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue