[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [13020] trunk/blender/source/blender: Directional Blur Node

Juho Vepsalainen bebraw at gmail.com
Thu Dec 27 15:19:11 CET 2007


Revision: 13020
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=13020
Author:   bebraw
Date:     2007-12-27 15:19:11 +0100 (Thu, 27 Dec 2007)

Log Message:
-----------
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.

Modified Paths:
--------------
    trunk/blender/source/blender/blenkernel/BKE_node.h
    trunk/blender/source/blender/blenkernel/BKE_utildefines.h
    trunk/blender/source/blender/blenkernel/intern/node.c
    trunk/blender/source/blender/makesdna/DNA_node_types.h
    trunk/blender/source/blender/nodes/CMP_node.h
    trunk/blender/source/blender/src/drawnode.c

Added Paths:
-----------
    trunk/blender/source/blender/nodes/intern/CMP_nodes/CMP_directionalblur.c

Modified: trunk/blender/source/blender/blenkernel/BKE_node.h
===================================================================
--- trunk/blender/source/blender/blenkernel/BKE_node.h	2007-12-27 13:35:14 UTC (rev 13019)
+++ trunk/blender/source/blender/blenkernel/BKE_node.h	2007-12-27 14:19:11 UTC (rev 13020)
@@ -306,6 +306,7 @@
 #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

Modified: trunk/blender/source/blender/blenkernel/BKE_utildefines.h
===================================================================
--- trunk/blender/source/blender/blenkernel/BKE_utildefines.h	2007-12-27 13:35:14 UTC (rev 13019)
+++ trunk/blender/source/blender/blenkernel/BKE_utildefines.h	2007-12-27 14:19:11 UTC (rev 13020)
@@ -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);}

Modified: trunk/blender/source/blender/blenkernel/intern/node.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/node.c	2007-12-27 13:35:14 UTC (rev 13019)
+++ trunk/blender/source/blender/blenkernel/intern/node.c	2007-12-27 14:19:11 UTC (rev 13020)
@@ -2374,6 +2374,7 @@
 	
 	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);

Modified: trunk/blender/source/blender/makesdna/DNA_node_types.h
===================================================================
--- trunk/blender/source/blender/makesdna/DNA_node_types.h	2007-12-27 13:35:14 UTC (rev 13019)
+++ trunk/blender/source/blender/makesdna/DNA_node_types.h	2007-12-27 14:19:11 UTC (rev 13020)
@@ -203,6 +203,12 @@
 	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;

Modified: trunk/blender/source/blender/nodes/CMP_node.h
===================================================================
--- trunk/blender/source/blender/nodes/CMP_node.h	2007-12-27 13:35:14 UTC (rev 13019)
+++ trunk/blender/source/blender/nodes/CMP_node.h	2007-12-27 14:19:11 UTC (rev 13020)
@@ -66,6 +66,7 @@
 
 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;

Added: trunk/blender/source/blender/nodes/intern/CMP_nodes/CMP_directionalblur.c
===================================================================
--- trunk/blender/source/blender/nodes/intern/CMP_nodes/CMP_directionalblur.c	                        (rev 0)
+++ trunk/blender/source/blender/nodes/intern/CMP_nodes/CMP_directionalblur.c	2007-12-27 14:19:11 UTC (rev 13020)
@@ -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
+};

Modified: trunk/blender/source/blender/src/drawnode.c
===================================================================
--- trunk/blender/source/blender/src/drawnode.c	2007-12-27 13:35:14 UTC (rev 13019)
+++ trunk/blender/source/blender/src/drawnode.c	2007-12-27 14:19:11 UTC (rev 13020)
@@ -1085,6 +1085,63 @@
 	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 @@
 {
 	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 @@
 		dy-=elementheight;
 
 		/* x1 */
-		bt=uiDefButS(block, NUM, B_NODE_EXEC+node->nr, "X1:",
+		uiDefButS(block, NUM, B_NODE_EXEC+node->nr, "X1:",

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list