forked from bartvdbraak/blender
3 very simple new composite nodes that I wanted for working with here. Hope the code is ok,
they work ok in testing here and get done what I need, any checks or fixes are welcome. * Separate RGBA: Separates an input RGBA image into its R, G, B and A channels * Separate HSVA: Separates an input RGBA image into H, S, V and A channels * Set Alpha: Takes an input RGBA image and an alpha value channel and combines them into a single RGBA image channel. You can also set the alpha for the entire image with the number field when there's no input alpha channel. TODO: Allow input alpha channel with no input image, in order to output a solid colour, with alpha.
This commit is contained in:
parent
7592c09c2b
commit
90fa460d2a
@ -185,7 +185,7 @@ void nodeShaderSynchronizeID(struct bNode *node, int copyto);
|
||||
/* switch material render loop */
|
||||
void set_node_shader_lamp_loop(void (*lamp_loop_func)(struct ShadeInput *, struct ShadeResult *));
|
||||
|
||||
/* ************** COMPOSIT NODES *************** */
|
||||
/* ************** COMPOSITE NODES *************** */
|
||||
|
||||
/* note: types are needed to restore callbacks, don't change values */
|
||||
#define CMP_NODE_VIEWER 201
|
||||
@ -203,6 +203,9 @@ void set_node_shader_lamp_loop(void (*lamp_loop_func)(struct ShadeInput *, str
|
||||
#define CMP_NODE_MAP_VALUE 213
|
||||
#define CMP_NODE_TIME 214
|
||||
#define CMP_NODE_VECBLUR 215
|
||||
#define CMP_NODE_SEPRGBA 216
|
||||
#define CMP_NODE_SEPHSVA 217
|
||||
#define CMP_NODE_SETALPHA 218
|
||||
|
||||
#define CMP_NODE_IMAGE 220
|
||||
#define CMP_NODE_R_RESULT 221
|
||||
|
@ -75,6 +75,12 @@ typedef struct CompBuf {
|
||||
#define CB_VEC2 2
|
||||
#define CB_VAL 1
|
||||
|
||||
/* defines for RGBA channels */
|
||||
#define CHAN_R 0
|
||||
#define CHAN_G 1
|
||||
#define CHAN_B 2
|
||||
#define CHAN_A 3
|
||||
|
||||
static CompBuf *alloc_compbuf(int sizex, int sizey, int type, int alloc)
|
||||
{
|
||||
CompBuf *cbuf= MEM_callocT(sizeof(CompBuf), "compbuf");
|
||||
@ -442,7 +448,7 @@ static void composit3_pixel_processor(bNode *node, CompBuf *out, CompBuf *src1_b
|
||||
}
|
||||
}
|
||||
|
||||
/* */
|
||||
/* ok to delete this and use the generalised version below? */
|
||||
static CompBuf *alphabuf_from_rgbabuf(CompBuf *cbuf)
|
||||
{
|
||||
CompBuf *valbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_VAL, 1);
|
||||
@ -457,6 +463,25 @@ static CompBuf *alphabuf_from_rgbabuf(CompBuf *cbuf)
|
||||
return valbuf;
|
||||
}
|
||||
|
||||
static CompBuf *valbuf_from_rgbabuf(CompBuf *cbuf, int channel)
|
||||
{
|
||||
CompBuf *valbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_VAL, 1);
|
||||
float *valf, *rectf;
|
||||
int tot;
|
||||
|
||||
valf= valbuf->rect;
|
||||
|
||||
/* defaults to returning alpha channel */
|
||||
if ((channel < CHAN_R) && (channel > CHAN_A)) channel = CHAN_A;
|
||||
|
||||
rectf= cbuf->rect + channel;
|
||||
|
||||
for(tot= cbuf->x*cbuf->y; tot>0; tot--, valf++, rectf+=4)
|
||||
*valf= *rectf;
|
||||
|
||||
return valbuf;
|
||||
}
|
||||
|
||||
static void generate_preview(bNode *node, CompBuf *stackbuf)
|
||||
{
|
||||
bNodePreview *preview= node->preview;
|
||||
@ -888,7 +913,7 @@ static void node_composit_exec_image(void *data, bNode *node, bNodeStack **in, b
|
||||
|
||||
if(stackbuf) {
|
||||
if(out[1]->hasoutput)
|
||||
out[1]->data= alphabuf_from_rgbabuf(stackbuf);
|
||||
out[1]->data= valbuf_from_rgbabuf(stackbuf, CHAN_A);
|
||||
|
||||
if(out[2]->hasoutput)
|
||||
out[2]->data= node_composit_get_zimage(node, data);
|
||||
@ -995,7 +1020,7 @@ static void node_composit_exec_rresult(void *data, bNode *node, bNodeStack **in,
|
||||
out[RRES_OUT_IMAGE]->data= stackbuf;
|
||||
|
||||
if(out[RRES_OUT_ALPHA]->hasoutput)
|
||||
out[RRES_OUT_ALPHA]->data= alphabuf_from_rgbabuf(stackbuf);
|
||||
out[RRES_OUT_ALPHA]->data= valbuf_from_rgbabuf(stackbuf, CHAN_A);
|
||||
if(out[RRES_OUT_Z]->hasoutput)
|
||||
out[RRES_OUT_Z]->data= compbuf_from_pass(rd, rl, rr->rectx, rr->recty, SCE_PASS_Z);
|
||||
if(out[RRES_OUT_VEC]->hasoutput)
|
||||
@ -1505,7 +1530,7 @@ static void node_composit_exec_valtorgb(void *data, bNode *node, bNodeStack **in
|
||||
out[0]->data= stackbuf;
|
||||
|
||||
if(out[1]->hasoutput)
|
||||
out[1]->data= alphabuf_from_rgbabuf(stackbuf);
|
||||
out[1]->data= valbuf_from_rgbabuf(stackbuf, CHAN_A);
|
||||
|
||||
}
|
||||
}
|
||||
@ -1546,7 +1571,7 @@ static void node_composit_exec_rgbtobw(void *data, bNode *node, bNodeStack **in,
|
||||
|
||||
/* input no image? then only color operation */
|
||||
if(in[0]->data==NULL) {
|
||||
out[0]->vec[0]= in[0]->vec[0]*0.35f + in[0]->vec[1]*0.45f + in[0]->vec[2]*0.2f;
|
||||
do_rgbtobw(node, out[0], in[0]);
|
||||
}
|
||||
else {
|
||||
/* make output size of input image */
|
||||
@ -1571,6 +1596,188 @@ static bNodeType cmp_node_rgbtobw= {
|
||||
|
||||
};
|
||||
|
||||
/* **************** SEPARATE RGBA ******************** */
|
||||
static bNodeSocketType cmp_node_seprgba_in[]= {
|
||||
{ SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f},
|
||||
{ -1, 0, "" }
|
||||
};
|
||||
static bNodeSocketType cmp_node_seprgba_out[]= {
|
||||
{ SOCK_VALUE, 0, "R", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
|
||||
{ SOCK_VALUE, 0, "G", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
|
||||
{ SOCK_VALUE, 0, "B", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
|
||||
{ SOCK_VALUE, 0, "A", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
|
||||
{ -1, 0, "" }
|
||||
};
|
||||
|
||||
static void node_composit_exec_seprgba(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
|
||||
{
|
||||
/* stack order out: bw channels */
|
||||
/* stack order in: col */
|
||||
|
||||
/* input no image? then only color operation */
|
||||
if(in[0]->data==NULL) {
|
||||
out[0]->vec[0] = in[0]->vec[0];
|
||||
out[1]->vec[0] = in[0]->vec[1];
|
||||
out[2]->vec[0] = in[0]->vec[2];
|
||||
out[3]->vec[0] = in[0]->vec[3];
|
||||
}
|
||||
else {
|
||||
/* make output size of input image */
|
||||
CompBuf *cbuf= in[0]->data;
|
||||
|
||||
/* don't do any pixel processing, just copy the stack directly (faster, I presume) */
|
||||
if(out[0]->hasoutput)
|
||||
out[0]->data= valbuf_from_rgbabuf(cbuf, CHAN_R);
|
||||
if(out[1]->hasoutput)
|
||||
out[1]->data= valbuf_from_rgbabuf(cbuf, CHAN_G);
|
||||
if(out[2]->hasoutput)
|
||||
out[2]->data= valbuf_from_rgbabuf(cbuf, CHAN_B);
|
||||
if(out[3]->hasoutput)
|
||||
out[3]->data= valbuf_from_rgbabuf(cbuf, CHAN_A);
|
||||
}
|
||||
}
|
||||
|
||||
static bNodeType cmp_node_seprgba= {
|
||||
/* type code */ CMP_NODE_SEPRGBA,
|
||||
/* name */ "Separate RGBA",
|
||||
/* width+range */ 80, 40, 140,
|
||||
/* class+opts */ NODE_CLASS_OPERATOR, 0,
|
||||
/* input sock */ cmp_node_seprgba_in,
|
||||
/* output sock */ cmp_node_seprgba_out,
|
||||
/* storage */ "",
|
||||
/* execfunc */ node_composit_exec_seprgba
|
||||
|
||||
};
|
||||
|
||||
/* **************** SEPARATE HSVA ******************** */
|
||||
static bNodeSocketType cmp_node_sephsva_in[]= {
|
||||
{ SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f},
|
||||
{ -1, 0, "" }
|
||||
};
|
||||
static bNodeSocketType cmp_node_sephsva_out[]= {
|
||||
{ SOCK_VALUE, 0, "H", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
|
||||
{ SOCK_VALUE, 0, "S", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
|
||||
{ SOCK_VALUE, 0, "V", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
|
||||
{ SOCK_VALUE, 0, "A", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
|
||||
{ -1, 0, "" }
|
||||
};
|
||||
|
||||
static void do_sephsva(bNode *node, float *out, float *in)
|
||||
{
|
||||
float h, s, v;
|
||||
|
||||
rgb_to_hsv(in[0], in[1], in[2], &h, &s, &v);
|
||||
|
||||
out[0]= h;
|
||||
out[1]= s;
|
||||
out[2]= v;
|
||||
out[3]= in[3];
|
||||
}
|
||||
|
||||
static void node_composit_exec_sephsva(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
|
||||
{
|
||||
/* stack order out: bw channels */
|
||||
/* stack order in: col */
|
||||
|
||||
/* input no image? then only color operation */
|
||||
if(in[0]->data==NULL) {
|
||||
float h, s, v;
|
||||
|
||||
rgb_to_hsv(in[0]->vec[0], in[0]->vec[1], in[0]->vec[2], &h, &s, &v);
|
||||
|
||||
out[0]->vec[0] = h;
|
||||
out[1]->vec[0] = s;
|
||||
out[2]->vec[0] = v;
|
||||
out[3]->vec[0] = in[0]->vec[3];
|
||||
}
|
||||
else if ((out[0]->hasoutput) || (out[1]->hasoutput) || (out[2]->hasoutput) || (out[3]->hasoutput)) {
|
||||
/* make output size of input image */
|
||||
CompBuf *cbuf= in[0]->data;
|
||||
|
||||
CompBuf *stackbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_RGBA, 1); // allocs
|
||||
|
||||
/* convert the RGB stackbuf to an HSV representation */
|
||||
composit1_pixel_processor(node, stackbuf, in[0]->data, NULL, do_sephsva);
|
||||
|
||||
/* separate each of those channels */
|
||||
if(out[0]->hasoutput)
|
||||
out[0]->data= valbuf_from_rgbabuf(stackbuf, CHAN_R);
|
||||
if(out[1]->hasoutput)
|
||||
out[1]->data= valbuf_from_rgbabuf(stackbuf, CHAN_G);
|
||||
if(out[2]->hasoutput)
|
||||
out[2]->data= valbuf_from_rgbabuf(stackbuf, CHAN_B);
|
||||
if(out[3]->hasoutput)
|
||||
out[3]->data= valbuf_from_rgbabuf(stackbuf, CHAN_A);
|
||||
|
||||
free_compbuf(stackbuf);
|
||||
}
|
||||
}
|
||||
|
||||
static bNodeType cmp_node_sephsva= {
|
||||
/* type code */ CMP_NODE_SEPHSVA,
|
||||
/* name */ "Separate HSVA",
|
||||
/* width+range */ 80, 40, 140,
|
||||
/* class+opts */ NODE_CLASS_OPERATOR, 0,
|
||||
/* input sock */ cmp_node_sephsva_in,
|
||||
/* output sock */ cmp_node_sephsva_out,
|
||||
/* storage */ "",
|
||||
/* execfunc */ node_composit_exec_sephsva
|
||||
|
||||
};
|
||||
|
||||
/* **************** SET ALPHA ******************** */
|
||||
static bNodeSocketType cmp_node_setalpha_in[]= {
|
||||
{ SOCK_RGBA, 1, "Image", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
|
||||
{ SOCK_VALUE, 1, "Alpha", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
|
||||
{ -1, 0, "" }
|
||||
};
|
||||
static bNodeSocketType cmp_node_setalpha_out[]= {
|
||||
{ SOCK_RGBA, 0, "Image", 0.0f, 0.0f, 1.0f, 1.0f, -1.0f, 1.0f},
|
||||
{ -1, 0, "" }
|
||||
};
|
||||
|
||||
static void node_composit_exec_setalpha(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
|
||||
{
|
||||
/* stack order out: RGBA image */
|
||||
/* stack order in: col, alpha */
|
||||
|
||||
/* input no image? then only color operation */
|
||||
if(in[0]->data==NULL) {
|
||||
out[0]->vec[0] = in[0]->vec[0];
|
||||
out[0]->vec[1] = in[0]->vec[1];
|
||||
out[0]->vec[2] = in[0]->vec[2];
|
||||
out[0]->vec[3] = in[1]->vec[0];
|
||||
}
|
||||
else {
|
||||
/* make output size of input image */
|
||||
CompBuf *cbuf= in[0]->data;
|
||||
CompBuf *stackbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_RGBA, 1); // allocs
|
||||
|
||||
if(in[1]->vec[0]==1.0f) {
|
||||
/* pass on image */
|
||||
composit1_pixel_processor(node, stackbuf, in[0]->data, in[0]->vec, do_copy_rgb);
|
||||
}
|
||||
else {
|
||||
/* send an compbuf or a value to set as alpha - composit2_pixel_processor handles choosing the right one */
|
||||
composit2_pixel_processor(node, stackbuf, in[0]->data, in[0]->vec, in[1]->data, in[1]->vec, do_copy_a_rgba);
|
||||
}
|
||||
|
||||
out[0]->data= stackbuf;
|
||||
}
|
||||
}
|
||||
|
||||
static bNodeType cmp_node_setalpha= {
|
||||
/* type code */ CMP_NODE_SETALPHA,
|
||||
/* name */ "Set Alpha",
|
||||
/* width+range */ 120, 40, 140,
|
||||
/* class+opts */ NODE_CLASS_OPERATOR, NODE_OPTIONS,
|
||||
/* input sock */ cmp_node_setalpha_in,
|
||||
/* output sock */ cmp_node_setalpha_out,
|
||||
/* storage */ "",
|
||||
/* execfunc */ node_composit_exec_setalpha
|
||||
|
||||
};
|
||||
|
||||
/* **************** ALPHAOVER ******************** */
|
||||
static bNodeSocketType cmp_node_alphaover_in[]= {
|
||||
{ SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f},
|
||||
@ -2363,6 +2570,9 @@ bNodeType *node_all_composit[]= {
|
||||
&cmp_node_blur,
|
||||
&cmp_node_vecblur,
|
||||
&cmp_node_map_value,
|
||||
&cmp_node_seprgba,
|
||||
&cmp_node_sephsva,
|
||||
&cmp_node_setalpha,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
@ -1254,7 +1254,7 @@ static void node_add_menu(SpaceNode *snode)
|
||||
}
|
||||
else if(snode->treetype==NTREE_COMPOSIT) {
|
||||
/* compo menu, still hardcoded defines... solve */
|
||||
event= pupmenu("Add Node%t|Render Result %x221|Composite %x222|Viewer%x201|Image %x220|RGB Curves%x209|AlphaOver %x210|Blur %x211|Vector Blur %x215|Filter %x212|Value %x203|Color %x202|Mix %x204|ColorRamp %x205|Color to BW %x206|Map Value %x213|Time %x214|Normal %x207");
|
||||
event= pupmenu("Add Node%t|Render Result %x221|Composite %x222|Viewer%x201|Image %x220|RGB Curves%x209|AlphaOver %x210|Blur %x211|Vector Blur %x215|Filter %x212|Value %x203|Color %x202|Mix %x204|ColorRamp %x205|Color to BW %x206|Map Value %x213|Time %x214|Normal %x207||Separate RGBA %x216|Separate HSVA %x217|Set Alpha %x218");
|
||||
if(event<1) return;
|
||||
}
|
||||
else return;
|
||||
|
Loading…
Reference in New Issue
Block a user