diff options
-rw-r--r-- | source/blender/blenkernel/BKE_node.h | 1 | ||||
-rw-r--r-- | source/blender/blenkernel/BKE_utildefines.h | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/node.c | 1 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_node_types.h | 6 | ||||
-rw-r--r-- | source/blender/nodes/CMP_node.h | 1 | ||||
-rw-r--r-- | source/blender/nodes/intern/CMP_nodes/CMP_directionalblur.c | 143 | ||||
-rw-r--r-- | source/blender/src/drawnode.c | 69 |
7 files changed, 218 insertions, 5 deletions
diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h index b9df1e45bae..3fd9d00b208 100644 --- a/source/blender/blenkernel/BKE_node.h +++ b/source/blender/blenkernel/BKE_node.h @@ -306,6 +306,7 @@ void set_node_shader_lamp_loop(void (*lamp_loop_func)(struct ShadeInput *, str #define CMP_NODE_INVERT 251 #define CMP_NODE_NORMALIZE 252 #define CMP_NODE_CROP 253 +#define CMP_NODE_DBLUR 254 #define CMP_NODE_GLARE 301 #define CMP_NODE_TONEMAP 302 diff --git a/source/blender/blenkernel/BKE_utildefines.h b/source/blender/blenkernel/BKE_utildefines.h index f3f66190c31..d08f42375ac 100644 --- a/source/blender/blenkernel/BKE_utildefines.h +++ b/source/blender/blenkernel/BKE_utildefines.h @@ -101,6 +101,8 @@ #define ABS(a) ( (a)<0 ? (-(a)) : (a) ) +#define AVG2(x, y) ( 0.5 * ((x) + (y)) ) + #define VECCOPY(v1,v2) {*(v1)= *(v2); *(v1+1)= *(v2+1); *(v1+2)= *(v2+2);} #define VECCOPY2D(v1,v2) {*(v1)= *(v2); *(v1+1)= *(v2+1);} #define QUATCOPY(v1,v2) {*(v1)= *(v2); *(v1+1)= *(v2+1); *(v1+2)= *(v2+2); *(v1+3)= *(v2+3);} diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c index 4bcacae9fc5..9450b4353cf 100644 --- a/source/blender/blenkernel/intern/node.c +++ b/source/blender/blenkernel/intern/node.c @@ -2374,6 +2374,7 @@ static void registerCompositNodes(ListBase *ntypelist) nodeRegisterType(ntypelist, &cmp_node_filter); nodeRegisterType(ntypelist, &cmp_node_blur); + nodeRegisterType(ntypelist, &cmp_node_dblur); nodeRegisterType(ntypelist, &cmp_node_vecblur); nodeRegisterType(ntypelist, &cmp_node_dilateerode); nodeRegisterType(ntypelist, &cmp_node_defocus); diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h index b5084c41884..e010d8409fa 100644 --- a/source/blender/makesdna/DNA_node_types.h +++ b/source/blender/makesdna/DNA_node_types.h @@ -203,6 +203,12 @@ typedef struct NodeBlurData { int pad2; } NodeBlurData; +typedef struct NodeDBlurData { + float center_x, center_y, distance, angle, spin, zoom; + short iter; + char wrap, pad; +} NodeDBlurData; + typedef struct NodeHueSat { float hue, sat, val; } NodeHueSat; diff --git a/source/blender/nodes/CMP_node.h b/source/blender/nodes/CMP_node.h index 4b7e721ca57..d1e04065835 100644 --- a/source/blender/nodes/CMP_node.h +++ b/source/blender/nodes/CMP_node.h @@ -66,6 +66,7 @@ extern bNodeType cmp_node_normalize; extern bNodeType cmp_node_filter; extern bNodeType cmp_node_blur; +extern bNodeType cmp_node_dblur; extern bNodeType cmp_node_vecblur; extern bNodeType cmp_node_dilateerode; extern bNodeType cmp_node_defocus; diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_directionalblur.c b/source/blender/nodes/intern/CMP_nodes/CMP_directionalblur.c new file mode 100644 index 00000000000..27f535186db --- /dev/null +++ b/source/blender/nodes/intern/CMP_nodes/CMP_directionalblur.c @@ -0,0 +1,143 @@ +/** + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2006 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): Alfredo de Greef (eeshlo) + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include "../CMP_util.h" + +static bNodeSocketType cmp_node_dblur_in[]= { + { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.f, 0.f, 1.f}, + { -1, 0, "" } +}; + +static bNodeSocketType cmp_node_dblur_out[]= { + { SOCK_RGBA, 0, "Image", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, + { -1, 0, "" } +}; + +static CompBuf *dblur(bNode *node, CompBuf *img, int iterations, int wrap, + float center_x, float center_y, float dist, float angle, float spin, float zoom) +{ + if ((dist != 0.f) || (spin != 0.f) || (zoom != 0.f)) { + void (*getpix)(CompBuf*, float, float, float*) = wrap ? qd_getPixelLerpWrap : qd_getPixelLerp; + const float a= angle * (float)M_PI / 180.f; + const float itsc= 1.f / pow(2.f, (float)iterations); + float D; + float center_x_pix, center_y_pix; + float tx, ty; + float sc, rot; + CompBuf *tmp; + int i, j; + + tmp= dupalloc_compbuf(img); + + D= dist * sqrtf(img->x * img->x + img->y * img->y); + center_x_pix= center_x * img->x; + center_y_pix= center_y * img->y; + + tx= itsc * D * cos(a); + ty= -itsc * D * sin(a); + sc= itsc * zoom; + rot= itsc * spin * (float)M_PI / 180.f; + + /* blur the image */ + for(i= 0; i < iterations; ++i) { + const float cs= cos(rot), ss= sin(rot); + const float isc= 1.f / (1.f + sc); + unsigned int x, y; + float col[4]= {0,0,0,0}; + + for(y= 0; y < img->y; ++y) { + const float v= isc * (y - center_y_pix) + ty; + + for(x= 0; x < img->x; ++x) { + const float u= isc * (x - center_x_pix) + tx; + unsigned int p= (x + y * img->x) * img->type; + + getpix(tmp, cs * u + ss * v + center_x_pix, cs * v - ss * u + center_y_pix, col); + + /* mix img and transformed tmp */ + for(j= 0; j < 4; ++j) + img->rect[p + j]= AVG2(img->rect[p + j], col[j]); + } + } + + /* copy img to tmp */ + if(i != (iterations - 1)) + memcpy(tmp->rect, img->rect, sizeof(float) * img->x * img->y * img->type); + + /* double transformations */ + tx *= 2.f, ty *= 2.f; + sc *= 2.f, rot *= 2.f; + + if(node->exec & NODE_BREAK) break; + } + + free_compbuf(tmp); + } + + return img; +} + +static void node_composit_exec_dblur(void *data, bNode *node, bNodeStack **in, bNodeStack **out) +{ + NodeDBlurData *ndbd= node->storage; + CompBuf *new, *img= in[0]->data; + + if((img == NULL) || (out[0]->hasoutput == 0)) return; + + if (img->type != CB_RGBA) + new = typecheck_compbuf(img, CB_RGBA); + else + new = dupalloc_compbuf(img); + + out[0]->data= dblur(node, new, ndbd->iter, ndbd->wrap, ndbd->center_x, ndbd->center_y, ndbd->distance, ndbd->angle, ndbd->spin, ndbd->zoom); +} + +static void node_composit_init_dblur(bNode* node) +{ + NodeDBlurData *ndbd= MEM_callocN(sizeof(NodeDBlurData), "node dblur data"); + node->storage= ndbd; + ndbd->center_x= 0.5; + ndbd->center_y= 0.5; +} + +bNodeType cmp_node_dblur = { + /* *next,*prev */ NULL, NULL, + /* type code */ CMP_NODE_DBLUR, + /* name */ "Directional Blur", + /* width+range */ 150, 120, 200, + /* class+opts */ NODE_CLASS_OP_FILTER, NODE_OPTIONS, + /* input sock */ cmp_node_dblur_in, + /* output sock */ cmp_node_dblur_out, + /* storage */ "NodeDBlurData", + /* execfunc */ node_composit_exec_dblur, + /* butfunc */ NULL, + /* initfunc */ node_composit_init_dblur, + /* freestoragefunc */ node_free_standard_storage, + /* copystoragefunc */ node_copy_standard_storage, + /* id */ NULL +}; diff --git a/source/blender/src/drawnode.c b/source/blender/src/drawnode.c index cc65b10c8e7..f641efacdbd 100644 --- a/source/blender/src/drawnode.c +++ b/source/blender/src/drawnode.c @@ -1085,6 +1085,63 @@ static int node_composit_buts_blur(uiBlock *block, bNodeTree *ntree, bNode *node return 57; } +static int node_composit_buts_dblur(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr) +{ + if(block) { + NodeDBlurData *ndbd = node->storage; + short dy = butr->ymin + 171; + short dx = butr->xmax - butr->xmin; + short halfdx= (short)dx/2; + + uiBlockBeginAlign(block); + uiDefButS(block, NUM, B_NODE_EXEC+node->nr, "Iterations:", + butr->xmin, dy, dx, 19, + &ndbd->iter, 1, 32, 10, 0, "Amount of iterations"); + uiDefButC(block, TOG, B_NODE_EXEC+node->nr, "Wrap", + butr->xmin, dy-= 19, dx, 19, + &ndbd->wrap, 0, 0, 0, 0, "Wrap blur"); + uiBlockEndAlign(block); + + dy-= 9; + + uiDefBut(block, LABEL, B_NOP, "Center", butr->xmin, dy-= 19, dx, 19, NULL, 0.0f, 0.0f, 0, 0, ""); + + uiBlockBeginAlign(block); + uiDefButF(block, NUM, B_NODE_EXEC+node->nr, "X:", + butr->xmin, dy-= 19, halfdx, 19, + &ndbd->center_x, 0.0f, 1.0f, 10, 0, "X center in percents"); + uiDefButF(block, NUM, B_NODE_EXEC+node->nr, "Y:", + butr->xmin+halfdx, dy, halfdx, 19, + &ndbd->center_y, 0.0f, 1.0f, 10, 0, "Y center in percents"); + uiBlockEndAlign(block); + + dy-= 9; + + uiBlockBeginAlign(block); + uiDefButF(block, NUM, B_NODE_EXEC+node->nr, "Distance:", + butr->xmin, dy-= 19, dx, 19, + &ndbd->distance, -1.0f, 1.0f, 10, 0, "Amount of which the image moves"); + uiDefButF(block, NUM, B_NODE_EXEC+node->nr, "Angle:", + butr->xmin, dy-= 19, dx, 19, + &ndbd->angle, 0.0f, 360.0f, 1000, 0, "Angle in which the image will be moved"); + uiBlockEndAlign(block); + + dy-= 9; + + uiDefButF(block, NUM, B_NODE_EXEC+node->nr, "Spin:", + butr->xmin, dy-= 19, dx, 19, + &ndbd->spin, -360.0f, 360.0f, 1000, 0, "Angle that is used to spin the image"); + + dy-= 9; + + uiDefButF(block, NUM, B_NODE_EXEC+node->nr, "Zoom:", + butr->xmin, dy-= 19, dx, 19, + &ndbd->zoom, 0.0f, 100.0f, 100, 0, "Amount of which the image is zoomed"); + + } + return 190; +} + /* qdn: defocus node */ static int node_composit_buts_defocus(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr) { @@ -1334,7 +1391,6 @@ static int node_composit_buts_crop(uiBlock *block, bNodeTree *ntree, bNode *node { if(block) { NodeTwoXYs *ntxy= node->storage; - uiBut *bt; char elementheight = 19; short dx= (butr->xmax-butr->xmin)/2; short dy= butr->ymax - elementheight; @@ -1350,22 +1406,22 @@ static int node_composit_buts_crop(uiBlock *block, bNodeTree *ntree, bNode *node dy-=elementheight; /* x1 */ - bt=uiDefButS(block, NUM, B_NODE_EXEC+node->nr, "X1:", + uiDefButS(block, NUM, B_NODE_EXEC+node->nr, "X1:", butr->xmin, dy, dx, elementheight, &ntxy->x1, xymin, xymax, 0, 0, ""); /* y1 */ - bt=uiDefButS(block, NUM, B_NODE_EXEC+node->nr, "Y1:", + uiDefButS(block, NUM, B_NODE_EXEC+node->nr, "Y1:", butr->xmin+dx, dy, dx, elementheight, &ntxy->y1, xymin, xymax, 0, 0, ""); dy-=elementheight; /* x2 */ - bt=uiDefButS(block, NUM, B_NODE_EXEC+node->nr, "X2:", + uiDefButS(block, NUM, B_NODE_EXEC+node->nr, "X2:", butr->xmin, dy, dx, elementheight, &ntxy->x2, xymin, xymax, 0, 0, ""); /* y2 */ - bt=uiDefButS(block, NUM, B_NODE_EXEC+node->nr, "Y2:", + uiDefButS(block, NUM, B_NODE_EXEC+node->nr, "Y2:", butr->xmin+dx, dy, dx, elementheight, &ntxy->y2, xymin, xymax, 0, 0, ""); @@ -1808,6 +1864,9 @@ static void node_composit_set_butfunc(bNodeType *ntype) case CMP_NODE_BLUR: ntype->butfunc= node_composit_buts_blur; break; + case CMP_NODE_DBLUR: + ntype->butfunc= node_composit_buts_dblur; + break; /* qdn: defocus node */ case CMP_NODE_DEFOCUS: ntype->butfunc = node_composit_buts_defocus; |