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
diff options
context:
space:
mode:
-rw-r--r--source/blender/blenkernel/BKE_node.h1
-rw-r--r--source/blender/blenkernel/intern/node.c1
-rw-r--r--source/blender/makesdna/DNA_node_types.h5
-rw-r--r--source/blender/nodes/CMP_node.h1
-rw-r--r--source/blender/nodes/intern/CMP_nodes/CMP_bilateralblur.c273
-rw-r--r--source/blender/src/drawnode.c27
6 files changed, 308 insertions, 0 deletions
diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h
index 3fd9d00b208..2008b18b5ed 100644
--- a/source/blender/blenkernel/BKE_node.h
+++ b/source/blender/blenkernel/BKE_node.h
@@ -307,6 +307,7 @@ void set_node_shader_lamp_loop(void (*lamp_loop_func)(struct ShadeInput *, str
#define CMP_NODE_NORMALIZE 252
#define CMP_NODE_CROP 253
#define CMP_NODE_DBLUR 254
+#define CMP_NODE_BILATERALBLUR 255
#define CMP_NODE_GLARE 301
#define CMP_NODE_TONEMAP 302
diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c
index 9450b4353cf..ce14165a499 100644
--- a/source/blender/blenkernel/intern/node.c
+++ b/source/blender/blenkernel/intern/node.c
@@ -2375,6 +2375,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_bilateralblur);
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 e010d8409fa..ceab9a1c9c1 100644
--- a/source/blender/makesdna/DNA_node_types.h
+++ b/source/blender/makesdna/DNA_node_types.h
@@ -209,6 +209,11 @@ typedef struct NodeDBlurData {
char wrap, pad;
} NodeDBlurData;
+typedef struct NodeBilateralBlurData {
+ float sigma_color, sigma_space;
+ short iter, pad;
+} NodeBilateralBlurData;
+
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 d1e04065835..3e62ea9970f 100644
--- a/source/blender/nodes/CMP_node.h
+++ b/source/blender/nodes/CMP_node.h
@@ -67,6 +67,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_bilateralblur;
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_bilateralblur.c b/source/blender/nodes/intern/CMP_nodes/CMP_bilateralblur.c
new file mode 100644
index 00000000000..81592becf4b
--- /dev/null
+++ b/source/blender/nodes/intern/CMP_nodes/CMP_bilateralblur.c
@@ -0,0 +1,273 @@
+/**
+ *
+ *
+ * ***** 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): Vilem Novak
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+#include "../CMP_util.h"
+
+/* **************** BILATERALBLUR ******************** */
+static bNodeSocketType cmp_node_bilateralblur_in[]= {
+ { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f},
+ { SOCK_RGBA, 1, "Determinator", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f},
+ { -1, 0, "" }
+};
+
+static bNodeSocketType cmp_node_bilateralblur_out[]= {
+ { SOCK_RGBA, 0, "Image", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
+ { -1, 0, "" }
+};
+
+#define INIT_C3\
+ mean0 = 1; mean1[0] = src[0];mean1[1] = src[1];mean1[2] = src[2];mean1[3] = src[3];
+
+/* finds color distances */
+#define COLOR_DISTANCE_C3(c1, c2)\
+ ((c1[0] - c2[0])*(c1[0] - c2[0]) + \
+ (c1[1] - c2[1])*(c1[1] - c2[1]) + \
+ (c1[2] - c2[2])*(c1[2] - c2[2]) + \
+ (c1[3] - c2[3])*(c1[3] - c2[3]))
+
+/* this is the main kernel function for comparing color distances
+ and adding them weighted to the final color */
+#define KERNEL_ELEMENT_C3(k)\
+ temp_color = src + deltas[k];\
+ ref_color = ref + deltas[k];\
+ w = weight_tab[k] + COLOR_DISTANCE_C3(ref, ref_color )*i2sigma_color;\
+ w = 1./(w*w + 1); \
+ mean0 += w;\
+ mean1[0] += temp_color[0]*w; \
+ mean1[1] += temp_color[1]*w; \
+ mean1[2] += temp_color[2]*w; \
+ mean1[3] += temp_color[3]*w;
+
+/* write blurred values to image */
+#define UPDATE_OUTPUT_C3\
+ mean0 = 1./mean0;\
+ dest[x*pix + 0] = mean1[0]*mean0; \
+ dest[x*pix + 1] = mean1[1]*mean0; \
+ dest[x*pix + 2] = mean1[2]*mean0; \
+ dest[x*pix + 3] = mean1[3]*mean0;
+
+/* initializes deltas for fast access to neighbour pixels */
+#define INIT_3X3_DELTAS( deltas, step, nch ) \
+ ((deltas)[0] = (nch), (deltas)[1] = -(step) + (nch), \
+ (deltas)[2] = -(step), (deltas)[3] = -(step) - (nch), \
+ (deltas)[4] = -(nch), (deltas)[5] = (step) - (nch), \
+ (deltas)[6] = (step), (deltas)[7] = (step) + (nch));
+
+
+/* code of this node was heavily inspired by the smooth function of opencv library.
+The main change is an optional image input */
+static void node_composit_exec_bilateralblur(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
+{
+ NodeBilateralBlurData *nbbd= node->storage;
+ CompBuf *new, *source, *img= in[0]->data , *refimg= in[1]->data;
+ double mean0, w, i2sigma_color, i2sigma_space;
+ double mean1[4];
+ double weight_tab[8];
+ float *src, *dest, *ref, *temp_color, *ref_color;
+ float sigma_color, sigma_space;
+ int imgx, imgy, x, y, pix, i, step;
+ int deltas[8];
+ short found_determinator= 0;
+
+ if(img == NULL || out[0]->hasoutput == 0)
+ return;
+
+ if(img->type != CB_RGBA) {
+ img= typecheck_compbuf(in[0]->data, CB_RGBA);
+ }
+
+ imgx= img->x;
+ imgy= img->y;
+ pix= img->type;
+ step= pix * imgx;
+
+ if(refimg) {
+ refimg= img;
+ if(refimg->x == imgx && refimg->y == imgy) {
+ if(refimg->type == CB_VEC2 || refimg->type == CB_VEC3) {
+ refimg= typecheck_compbuf(in[1]->data, CB_RGBA);
+ found_determinator= 1;
+ }
+ }
+ }
+ else {
+ refimg= img;
+ }
+
+ /* allocs */
+ source= dupalloc_compbuf(img);
+ new= alloc_compbuf(imgx, imgy, pix, 1);
+
+ /* accept image offsets from other nodes */
+ new->xof= img->xof;
+ new->yof= img->yof;
+
+ /* bilateral code properties */
+ sigma_color= nbbd->sigma_color;
+ sigma_space= nbbd->sigma_space;
+
+ i2sigma_color= 1. / (sigma_color * sigma_color);
+ i2sigma_space= 1. / (sigma_space * sigma_space);
+
+ INIT_3X3_DELTAS(deltas, step, pix);
+
+ weight_tab[0] = weight_tab[2] = weight_tab[4] = weight_tab[6] = i2sigma_space;
+ weight_tab[1] = weight_tab[3] = weight_tab[5] = weight_tab[7] = i2sigma_space * 2;
+
+ /* iterations */
+ for(i= 0; i < nbbd->iter; i++) {
+ src= source->rect;
+ ref= refimg->rect;
+ dest= new->rect;
+ /*goes through image, there are more loops for 1st/last line and all other lines*/
+ /*kernel element accumulates surrounding colors, which are then written with the update_output function*/
+ for(x= 0; x < imgx; x++, src+= pix, ref+= pix) {
+ INIT_C3;
+
+ KERNEL_ELEMENT_C3(6);
+
+ if(x > 0) {
+ KERNEL_ELEMENT_C3(5);
+ KERNEL_ELEMENT_C3(4);
+ }
+
+ if(x < imgx - 1) {
+ KERNEL_ELEMENT_C3(7);
+ KERNEL_ELEMENT_C3(0);
+ }
+
+ UPDATE_OUTPUT_C3;
+ }
+
+ dest+= step;
+
+ for(y= 1; y < imgy - 1; y++, dest+= step, src+= pix, ref+= pix) {
+ x= 0;
+
+ INIT_C3;
+
+ KERNEL_ELEMENT_C3(0);
+ KERNEL_ELEMENT_C3(1);
+ KERNEL_ELEMENT_C3(2);
+ KERNEL_ELEMENT_C3(6);
+ KERNEL_ELEMENT_C3(7);
+
+ UPDATE_OUTPUT_C3;
+
+ src+= pix;
+ ref+= pix;
+
+ for(x= 1; x < imgx - 1; x++, src+= pix, ref+= pix) {
+ INIT_C3;
+
+ KERNEL_ELEMENT_C3(0);
+ KERNEL_ELEMENT_C3(1);
+ KERNEL_ELEMENT_C3(2);
+ KERNEL_ELEMENT_C3(3);
+ KERNEL_ELEMENT_C3(4);
+ KERNEL_ELEMENT_C3(5);
+ KERNEL_ELEMENT_C3(6);
+ KERNEL_ELEMENT_C3(7);
+
+ UPDATE_OUTPUT_C3;
+ }
+
+ INIT_C3;
+
+ KERNEL_ELEMENT_C3(2);
+ KERNEL_ELEMENT_C3(3);
+ KERNEL_ELEMENT_C3(4);
+ KERNEL_ELEMENT_C3(5);
+ KERNEL_ELEMENT_C3(6);
+
+ UPDATE_OUTPUT_C3;
+ }
+
+ for(x= 0; x < imgx; x++, src+= pix, ref+= pix) {
+ INIT_C3;
+
+ KERNEL_ELEMENT_C3(2);
+
+ if(x > 0) {
+ KERNEL_ELEMENT_C3(3);
+ KERNEL_ELEMENT_C3(4);
+ }
+ if(x < imgx - 1) {
+ KERNEL_ELEMENT_C3(1);
+ KERNEL_ELEMENT_C3(0);
+ }
+
+ UPDATE_OUTPUT_C3;
+ }
+
+ if(node->exec & NODE_BREAK) break;
+
+ SWAP(CompBuf, *source, *new);
+ }
+
+ if(node->exec & NODE_BREAK)
+ free_compbuf(source);
+
+ if(img != in[0]->data)
+ free_compbuf(img);
+
+ if(found_determinator == 1) {
+ if(refimg != in[1]->data)
+ free_compbuf(refimg);
+ }
+
+ out[0]->data= source;
+
+ free_compbuf(new);
+}
+
+static void node_composit_init_bilateralblur(bNode* node)
+{
+ NodeBilateralBlurData *nbbd= MEM_callocN(sizeof(NodeBilateralBlurData), "node bilateral blur data");
+ node->storage= nbbd;
+ nbbd->sigma_color= 0.3;
+ nbbd->sigma_space= 5.0;
+}
+
+bNodeType cmp_node_bilateralblur= {
+ /* *next,*prev */ NULL, NULL,
+ /* type code */ CMP_NODE_BILATERALBLUR,
+ /* name */ "Bilateral Blur",
+ /* width+range */ 150, 120, 200,
+ /* class+opts */ NODE_CLASS_OP_FILTER, NODE_OPTIONS,
+ /* input sock */ cmp_node_bilateralblur_in,
+ /* output sock */ cmp_node_bilateralblur_out,
+ /* storage */ "NodeBilateralBlurData",
+ /* execfunc */ node_composit_exec_bilateralblur,
+ /* butfunc */ NULL,
+ /* initfunc */ node_composit_init_bilateralblur,
+ /* 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 f641efacdbd..491ecb6e741 100644
--- a/source/blender/src/drawnode.c
+++ b/source/blender/src/drawnode.c
@@ -1142,6 +1142,30 @@ static int node_composit_buts_dblur(uiBlock *block, bNodeTree *ntree, bNode *nod
return 190;
}
+static int node_composit_buts_bilateralblur(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr)
+{
+ if(block) {
+ NodeBilateralBlurData *nbbd= node->storage;
+ short dy= butr->ymin+38;
+ short dx= (butr->xmax-butr->xmin);
+
+ uiBlockBeginAlign(block);
+ uiDefButS(block, NUM, B_NODE_EXEC+node->nr, "Iterations:",
+ butr->xmin, dy, dx, 19,
+ &nbbd->iter, 1, 128, 0, 0, "Amount of iterations");
+ dy-=19;
+ uiDefButF(block, NUM, B_NODE_EXEC+node->nr, "Color Sigma:",
+ butr->xmin, dy, dx, 19,
+ &nbbd->sigma_color,0.01, 3, 10, 0, "Sigma value used to modify color");
+ dy-=19;
+ uiDefButF(block, NUM, B_NODE_EXEC+node->nr, "Space Sigma:",
+ butr->xmin, dy, dx, 19,
+ &nbbd->sigma_space ,0.01, 30, 10, 0, "Sigma value used to modify space");
+
+ }
+ return 57;
+}
+
/* qdn: defocus node */
static int node_composit_buts_defocus(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr)
{
@@ -1867,6 +1891,9 @@ static void node_composit_set_butfunc(bNodeType *ntype)
case CMP_NODE_DBLUR:
ntype->butfunc= node_composit_buts_dblur;
break;
+ case CMP_NODE_BILATERALBLUR:
+ ntype->butfunc= node_composit_buts_bilateralblur;
+ break;
/* qdn: defocus node */
case CMP_NODE_DEFOCUS:
ntype->butfunc = node_composit_buts_defocus;