Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorJuho Vepsalainen <bebraw@gmail.com>2007-12-27 17:19:11 +0300
committerJuho Vepsalainen <bebraw@gmail.com>2007-12-27 17:19:11 +0300
commit8ddc48d32f011b0c5af5c191a94188e3f29c3776 (patch)
tree5d1c3195bbdb7badf7964ca1d1419b78a8050393 /source
parent28805c626fffdc70736e26dccb2ef37816c4bc76 (diff)
Directional Blur Node
Directional Blur node allows the users to do various blur operations on the input image. It essentially offers three different kind of ways of blurring in one node. It is possible to blur using a certain direction, spin and zoom. These three ways can be used in conjunction. The node contains following controls: *Iterations, Wrap *Center: X, Y *Distance, Angle *Spin *Zoom Iterations is used to determine the smoothness of the result. The more iterations, the smoother result. Low values are good for preview. Wrap means that the image is wrapped as if it was tiled on both x and y directions. To see better what this means, try it with spin for instance. Center values (X and Y) determine the location which is used as a pivot point for the operations. It is center (0.5) of the image by default. Distance and angle are used to adjust directional blur. The result can be described as a sweep that varies based on given distance (bigger distance, longer sweep) and angle. Angle is given in degrees. Spin produces rotating blur based on given angle. Yet again it is in degrees. Also negative values work. Zoom causes the image to be zoomed towards set center point (Center values). Thanks to Alfredo de Greef (eeshlo) for contribution. Possible development ideas: *Make an algorithm to extend image in case spin is used. Extend would temporarily change the size of the canvas of the input image. Canvas would be filled based on colors on the edges of the input image. After the blur operation has been done, the image would be cropped back to normal size. The advantage of this would be nicer result of spin (no problems with image size) on a computational cost. *Make values animatable. This is something that is better solved on more general level. ("everything is animatable" paradigm) *Provide an option to calculate automatic value for iterations. A good value that produces a smooth result could be calculated based on direction deltas. This would be useful in conjuction of animatable values.
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenkernel/BKE_node.h1
-rw-r--r--source/blender/blenkernel/BKE_utildefines.h2
-rw-r--r--source/blender/blenkernel/intern/node.c1
-rw-r--r--source/blender/makesdna/DNA_node_types.h6
-rw-r--r--source/blender/nodes/CMP_node.h1
-rw-r--r--source/blender/nodes/intern/CMP_nodes/CMP_directionalblur.c143
-rw-r--r--source/blender/src/drawnode.c69
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;