feather option for dilate/erode node - needed for alpha masks so we can (blur in...
authorCampbell Barton <ideasman42@gmail.com>
Sat, 16 Jun 2012 13:46:20 +0000 (13:46 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Sat, 16 Jun 2012 13:46:20 +0000 (13:46 +0000)
16 files changed:
source/blender/blenkernel/intern/node.c
source/blender/compositor/CMakeLists.txt
source/blender/compositor/nodes/COM_DilateErodeNode.cpp
source/blender/compositor/nodes/COM_DilateErodeNode.h
source/blender/compositor/operations/COM_BlurBaseOperation.cpp
source/blender/compositor/operations/COM_BlurBaseOperation.h
source/blender/compositor/operations/COM_FastGaussianBlurOperation.cpp
source/blender/compositor/operations/COM_GaussianAlphaXBlurOperation.cpp [new file with mode: 0644]
source/blender/compositor/operations/COM_GaussianAlphaXBlurOperation.h [new file with mode: 0644]
source/blender/compositor/operations/COM_GaussianAlphaYBlurOperation.cpp [new file with mode: 0644]
source/blender/compositor/operations/COM_GaussianAlphaYBlurOperation.h [new file with mode: 0644]
source/blender/compositor/operations/COM_GaussianBokehBlurOperation.cpp
source/blender/compositor/operations/COM_GaussianXBlurOperation.cpp
source/blender/compositor/operations/COM_GaussianYBlurOperation.cpp
source/blender/makesdna/DNA_node_types.h
source/blender/makesrna/intern/rna_nodetree.c

index bd3690e..a5e081d 100644 (file)
@@ -2098,4 +2098,3 @@ void clear_scene_in_nodes(Main *bmain, Scene *sce)
                }
        }
 }
-
index fbe391a..d0093c5 100644 (file)
@@ -288,6 +288,10 @@ set(SRC
        nodes/COM_BokehBlurNode.h
        nodes/COM_DirectionalBlurNode.cpp
        nodes/COM_DirectionalBlurNode.h
+       operations/COM_GaussianAlphaXBlurOperation.cpp
+       operations/COM_GaussianAlphaXBlurOperation.h
+       operations/COM_GaussianAlphaYBlurOperation.cpp
+       operations/COM_GaussianAlphaYBlurOperation.h
        operations/COM_GaussianXBlurOperation.cpp
        operations/COM_GaussianXBlurOperation.h
        operations/COM_GaussianYBlurOperation.cpp
index 6ee5b2a..6584120 100644 (file)
@@ -25,6 +25,8 @@
 #include "COM_ExecutionSystem.h"
 #include "COM_DilateErodeOperation.h"
 #include "COM_AntiAliasOperation.h"
+#include "COM_GaussianAlphaXBlurOperation.h"
+#include "COM_GaussianAlphaYBlurOperation.h"
 #include "BLI_math.h"
 
 DilateErodeNode::DilateErodeNode(bNode *editorNode) : Node(editorNode)
@@ -70,6 +72,53 @@ void DilateErodeNode::convertToOperations(ExecutionSystem *graph, CompositorCont
                        graph->addOperation(operation);
                }
        }
+       else if (editorNode->custom1 == CMP_NODE_DILATEERODE_DISTANCE_FEATHER) {
+               /* this uses a modified gaussian blur function otherwise its far too slow */
+               if (editorNode->custom2 > 0) {
+
+                       CompositorQuality quality = context->getQuality();
+
+                       /* initialize node data */
+                       NodeBlurData *data = (NodeBlurData *)&this->alpha_blur;
+                       memset(data, 0, sizeof(*data));
+                       data->sizex = data->sizey = editorNode->custom2;
+                       data->filtertype = R_FILTER_GAUSS;
+
+                       GaussianAlphaXBlurOperation *operationx = new GaussianAlphaXBlurOperation();
+                       operationx->setData(data);
+                       operationx->setQuality(quality);
+                       this->getInputSocket(0)->relinkConnections(operationx->getInputSocket(0), 0, graph);
+                       this->getInputSocket(1)->relinkConnections(operationx->getInputSocket(1), 1, graph);
+                       graph->addOperation(operationx);
+                       GaussianAlphaYBlurOperation *operationy = new GaussianAlphaYBlurOperation();
+                       operationy->setData(data);
+                       operationy->setQuality(quality);
+                       this->getOutputSocket(0)->relinkConnections(operationy->getOutputSocket());
+                       graph->addOperation(operationy);
+                       addLink(graph, operationx->getOutputSocket(), operationy->getInputSocket(0));
+                       addLink(graph, operationx->getInputSocket(1)->getConnection()->getFromSocket(), operationy->getInputSocket(1));
+                       addPreviewOperation(graph, operationy->getOutputSocket());
+
+                       /* TODO? */
+                       /* see gaussian blue node for original usage */
+#if 0
+                       if (!connectedSizeSocket) {
+                               operationx->setSize(size);
+                               operationy->setSize(size);
+                       }
+#else
+                       operationx->setSize(1.0f);
+                       operationy->setSize(1.0f);
+#endif
+               }
+               else {
+                       ErodeDistanceOperation *operation = new ErodeDistanceOperation();
+                       operation->setDistance(-editorNode->custom2);
+                       this->getInputSocket(0)->relinkConnections(operation->getInputSocket(0), 0, graph);
+                       this->getOutputSocket(0)->relinkConnections(operation->getOutputSocket(0));
+                       graph->addOperation(operation);
+               }
+       }
        else {
                if (editorNode->custom2 > 0) {
                        DilateStepOperation *operation = new DilateStepOperation();
index fa4e368..ac374d7 100644 (file)
@@ -30,6 +30,7 @@
  * @ingroup Node
  */
 class DilateErodeNode : public Node {
+       NodeBlurData alpha_blur; /* only used for blurring alpha, since the dilate/erode node doesnt have this */
 public:
        DilateErodeNode(bNode *editorNode);
        void convertToOperations(ExecutionSystem *graph, CompositorContext *context);
index bb915fe..0e7676d 100644 (file)
@@ -27,11 +27,11 @@ extern "C" {
        #include "RE_pipeline.h"
 }
 
-BlurBaseOperation::BlurBaseOperation() : NodeOperation()
+BlurBaseOperation::BlurBaseOperation(DataType data_type=COM_DT_COLOR) : NodeOperation()
 {
-       this->addInputSocket(COM_DT_COLOR);
+       this->addInputSocket(data_type);
        this->addInputSocket(COM_DT_VALUE);
-       this->addOutputSocket(COM_DT_COLOR);
+       this->addOutputSocket(data_type);
        this->setComplex(true);
        this->inputProgram = NULL;
        this->data = NULL;
@@ -89,6 +89,24 @@ float *BlurBaseOperation::make_gausstab(int rad)
        return gausstab;
 }
 
+/* normalized distance from the current (inverted so 1.0 is close and 0.0 is far) */
+float *BlurBaseOperation::make_dist_fac_inverse(int rad)
+{
+       float *dist_fac_invert, val;
+       int i, n;
+
+       n = 2 * rad + 1;
+
+       dist_fac_invert = new float[n];
+
+       for (i = -rad; i <= rad; i++) {
+               val = 1.0f - fabsf(((float)i / (float)rad));
+               dist_fac_invert[i + rad] = val;
+       }
+
+       return dist_fac_invert;
+}
+
 void BlurBaseOperation::deinitExecution()
 {
        this->inputProgram = NULL;
index 84fc243..33c07ab 100644 (file)
@@ -35,8 +35,9 @@ protected:
        SocketReader *inputProgram;
        SocketReader *inputSize;
        NodeBlurData *data;
-       BlurBaseOperation();
+       BlurBaseOperation(DataType data_type);
        float *make_gausstab(int rad);
+       float *make_dist_fac_inverse(int rad);
        float size;
        bool deleteData;
        bool sizeavailable;
index 48cfbeb..7491b0f 100644 (file)
@@ -26,7 +26,7 @@
 #include "MEM_guardedalloc.h"
 #include "BLI_utildefines.h"
 
-FastGaussianBlurOperation::FastGaussianBlurOperation() : BlurBaseOperation()
+FastGaussianBlurOperation::FastGaussianBlurOperation() : BlurBaseOperation(COM_DT_COLOR)
 {
        this->iirgaus = NULL;
 }
diff --git a/source/blender/compositor/operations/COM_GaussianAlphaXBlurOperation.cpp b/source/blender/compositor/operations/COM_GaussianAlphaXBlurOperation.cpp
new file mode 100644 (file)
index 0000000..5b042ae
--- /dev/null
@@ -0,0 +1,186 @@
+/*
+ * Copyright 2011, Blender Foundation.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor: 
+ *             Jeroen Bakker 
+ *             Monique Dewanchand
+ *             Campbell Barton
+ */
+
+#include "COM_GaussianAlphaXBlurOperation.h"
+#include "BLI_math.h"
+
+extern "C" {
+       #include "RE_pipeline.h"
+}
+
+GaussianAlphaXBlurOperation::GaussianAlphaXBlurOperation() : BlurBaseOperation(COM_DT_VALUE)
+{
+       this->gausstab = NULL;
+       this->rad = 0;
+}
+
+void *GaussianAlphaXBlurOperation::initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers)
+{
+       if (!this->sizeavailable) {
+               updateGauss(memoryBuffers);
+       }
+       void *buffer = getInputOperation(0)->initializeTileData(NULL, memoryBuffers);
+       return buffer;
+}
+
+void GaussianAlphaXBlurOperation::initExecution()
+{
+       BlurBaseOperation::initExecution();
+
+       if (this->sizeavailable) {
+               float rad = size * this->data->sizex;
+               if (rad < 1)
+                       rad = 1;
+
+               this->rad = rad;
+               this->gausstab = BlurBaseOperation::make_gausstab(rad);
+               this->distbuf_inv = BlurBaseOperation::make_dist_fac_inverse(rad);
+       }
+}
+
+void GaussianAlphaXBlurOperation::updateGauss(MemoryBuffer **memoryBuffers)
+{
+       if (this->gausstab == NULL) {
+               updateSize(memoryBuffers);
+               float rad = size * this->data->sizex;
+               if (rad < 1)
+                       rad = 1;
+
+               this->rad = rad;
+               this->gausstab = BlurBaseOperation::make_gausstab(rad); 
+       }
+
+       if (this->distbuf_inv == NULL) {
+               updateSize(memoryBuffers);
+               float rad = size * this->data->sizex;
+               if (rad < 1)
+                       rad = 1;
+
+               this->rad = rad;
+               this->distbuf_inv = BlurBaseOperation::make_dist_fac_inverse(rad);
+       }
+}
+
+void GaussianAlphaXBlurOperation::executePixel(float *color, int x, int y, MemoryBuffer *inputBuffers[], void *data)
+{
+       MemoryBuffer *inputBuffer = (MemoryBuffer *)data;
+       float *buffer = inputBuffer->getBuffer();
+       int bufferwidth = inputBuffer->getWidth();
+       int bufferstartx = inputBuffer->getRect()->xmin;
+       int bufferstarty = inputBuffer->getRect()->ymin;
+
+       int miny = y;
+       int maxy = y;
+       int minx = x - this->rad;
+       int maxx = x + this->rad;
+       miny = max(miny, inputBuffer->getRect()->ymin);
+       minx = max(minx, inputBuffer->getRect()->xmin);
+       maxy = min(maxy, inputBuffer->getRect()->ymax);
+       maxx = min(maxx, inputBuffer->getRect()->xmax);
+
+       /* *** this is the main part which is different to 'GaussianXBlurOperation'  *** */
+       int step = getStep();
+       int offsetadd = getOffsetAdd();
+       int bufferindex = ((minx - bufferstartx) * 4) + ((miny - bufferstarty) * 4 * bufferwidth);
+
+       /* gauss */
+       float tempColor = 0.0f;
+       float overallmultiplyer = 0.0f;
+
+       /* dilate */
+       float value_max = buffer[(x * 4) + (y * 4 * bufferwidth)]; /* init with the current color to avoid unneeded lookups */
+       float distfacinv_max = 1.0f; /* 0 to 1 */
+
+       for (int nx = minx; nx < maxx; nx += step) {
+               const int index = (nx - x) + this->rad;
+               float value = buffer[bufferindex];
+               float multiplyer;
+
+               /* gauss */
+               {
+                       multiplyer = gausstab[index];
+                       tempColor += value * multiplyer;
+                       overallmultiplyer += multiplyer;
+               }
+
+               /* dilate - find most extreme color */
+               if (value > value_max) {
+#if 0
+                       multiplyer = 1.0f - ((fabsf(x - nx)) / (float)this->rad);
+#else
+                       multiplyer = distbuf_inv[index];
+#endif
+                       value *= multiplyer;
+                       if ((value > value_max) == TRUE) {
+                               value_max = value;
+                               distfacinv_max = multiplyer;
+                       }
+               }
+
+               bufferindex += offsetadd;
+       }
+
+       /* blend between the max value and gauss blue - gives nice feather */
+       const float value_gauss = tempColor / overallmultiplyer;
+       const float value_final = (value_max * distfacinv_max) + (value_gauss * (1.0f - distfacinv_max));
+       color[0] = value_final;
+}
+
+void GaussianAlphaXBlurOperation::deinitExecution()
+{
+       BlurBaseOperation::deinitExecution();
+       delete [] this->gausstab;
+       this->gausstab = NULL;
+       delete [] this->distbuf_inv;
+       this->distbuf_inv = NULL;
+}
+
+bool GaussianAlphaXBlurOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output)
+{
+       rcti newInput;
+       rcti sizeInput;
+       sizeInput.xmin = 0;
+       sizeInput.ymin = 0;
+       sizeInput.xmax = 5;
+       sizeInput.ymax = 5;
+       
+       NodeOperation *operation = this->getInputOperation(1);
+       if (operation->determineDependingAreaOfInterest(&sizeInput, readOperation, output)) {
+               return true;
+       }
+       else {
+               if (this->sizeavailable && this->gausstab != NULL) {
+                       newInput.xmax = input->xmax + rad;
+                       newInput.xmin = input->xmin - rad;
+                       newInput.ymax = input->ymax;
+                       newInput.ymin = input->ymin;
+               }
+               else {
+                       newInput.xmax = this->getWidth();
+                       newInput.xmin = 0;
+                       newInput.ymax = this->getHeight();
+                       newInput.ymin = 0;
+               }
+               return NodeOperation::determineDependingAreaOfInterest(&newInput, readOperation, output);
+       }
+}
diff --git a/source/blender/compositor/operations/COM_GaussianAlphaXBlurOperation.h b/source/blender/compositor/operations/COM_GaussianAlphaXBlurOperation.h
new file mode 100644 (file)
index 0000000..2b5e4d3
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2011, Blender Foundation.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor: 
+ *             Jeroen Bakker 
+ *             Monique Dewanchand
+ *             Campbell Barton
+ */
+
+#ifndef _COM_GaussianAlphaXBlurOperation_h
+#define _COM_GaussianAlphaXBlurOperation_h
+#include "COM_NodeOperation.h"
+#include "COM_BlurBaseOperation.h"
+
+class GaussianAlphaXBlurOperation : public BlurBaseOperation {
+private:
+       float *gausstab;
+       float *distbuf_inv;
+       int rad;
+       void updateGauss(MemoryBuffer **memoryBuffers);
+public:
+       GaussianAlphaXBlurOperation();
+
+       /**
+        * @brief the inner loop of this program
+        */
+       void executePixel(float *color, int x, int y, MemoryBuffer * inputBuffers[], void *data);
+       
+       /**
+        * @brief initialize the execution
+        */
+       void initExecution();
+
+       /**
+        * @brief Deinitialize the execution
+        */
+       void deinitExecution();
+       
+       void *initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers);
+       bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output);
+};
+#endif
diff --git a/source/blender/compositor/operations/COM_GaussianAlphaYBlurOperation.cpp b/source/blender/compositor/operations/COM_GaussianAlphaYBlurOperation.cpp
new file mode 100644 (file)
index 0000000..73dabda
--- /dev/null
@@ -0,0 +1,183 @@
+/*
+ * Copyright 2011, Blender Foundation.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor: 
+ *             Jeroen Bakker 
+ *             Monique Dewanchand
+ *             Campbell Barton
+ */
+
+#include "COM_GaussianAlphaYBlurOperation.h"
+#include "BLI_math.h"
+
+extern "C" {
+       #include "RE_pipeline.h"
+}
+
+GaussianAlphaYBlurOperation::GaussianAlphaYBlurOperation() : BlurBaseOperation(COM_DT_VALUE)
+{
+       this->gausstab = NULL;
+       this->rad = 0;
+}
+
+void *GaussianAlphaYBlurOperation::initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers)
+{
+       if (!this->sizeavailable) {
+               updateGauss(memoryBuffers);
+       }
+       void *buffer = getInputOperation(0)->initializeTileData(NULL, memoryBuffers);
+       return buffer;
+}
+
+void GaussianAlphaYBlurOperation::initExecution()
+{
+       if (this->sizeavailable) {
+               float rad = size * this->data->sizey;
+               if (rad < 1)
+                       rad = 1;
+
+               this->rad = rad;
+               this->gausstab = BlurBaseOperation::make_gausstab(rad);
+               this->distbuf_inv = BlurBaseOperation::make_dist_fac_inverse(rad);
+       }
+}
+
+void GaussianAlphaYBlurOperation::updateGauss(MemoryBuffer **memoryBuffers)
+{
+       if (this->gausstab == NULL) {
+               updateSize(memoryBuffers);
+               float rad = size * this->data->sizey;
+               if (rad < 1)
+                       rad = 1;
+               
+               this->rad = rad;
+               this->gausstab = BlurBaseOperation::make_gausstab(rad);
+       }
+
+       if (this->distbuf_inv == NULL) {
+               updateSize(memoryBuffers);
+               float rad = size * this->data->sizex;
+               if (rad < 1)
+                       rad = 1;
+
+               this->rad = rad;
+               this->distbuf_inv = BlurBaseOperation::make_dist_fac_inverse(rad);
+       }
+}
+
+void GaussianAlphaYBlurOperation::executePixel(float *color, int x, int y, MemoryBuffer *inputBuffers[], void *data)
+{
+       MemoryBuffer *inputBuffer = (MemoryBuffer *)data;
+       float *buffer = inputBuffer->getBuffer();
+       int bufferwidth = inputBuffer->getWidth();
+       int bufferstartx = inputBuffer->getRect()->xmin;
+       int bufferstarty = inputBuffer->getRect()->ymin;
+
+       int miny = y - this->rad;
+       int maxy = y + this->rad;
+       int minx = x;
+       int maxx = x;
+       miny = max(miny, inputBuffer->getRect()->ymin);
+       minx = max(minx, inputBuffer->getRect()->xmin);
+       maxy = min(maxy, inputBuffer->getRect()->ymax);
+       maxx = min(maxx, inputBuffer->getRect()->xmax);
+
+       /* *** this is the main part which is different to 'GaussianYBlurOperation'  *** */
+       int step = getStep();
+
+       /* gauss */
+       float tempColor = 0.0f;
+       float overallmultiplyer = 0.0f;
+
+       /* dilate */
+       float value_max = buffer[(x * 4) + (y * 4 * bufferwidth)]; /* init with the current color to avoid unneeded lookups */
+       float distfacinv_max = 1.0f; /* 0 to 1 */
+
+       for (int ny = miny; ny < maxy; ny += step) {
+               int bufferindex = ((minx - bufferstartx) * 4) + ((ny - bufferstarty) * 4 * bufferwidth);
+
+               const int index = (ny - y) + this->rad;
+               float value = buffer[bufferindex];
+               float multiplyer;
+
+               /* gauss */
+               {
+                       multiplyer = gausstab[index];
+                       tempColor += value * multiplyer;
+                       overallmultiplyer += multiplyer;
+               }
+
+               /* dilate - find most extreme color */
+               if (value > value_max) {
+#if 0
+                       multiplyer = 1.0f - ((fabsf(y - ny)) / (float)this->rad);
+#else
+                       multiplyer = distbuf_inv[index];
+#endif
+                       value *= multiplyer;
+                       if (value > value_max) {
+                               value_max = value;
+                               distfacinv_max = multiplyer;
+                       }
+               }
+
+       }
+
+       /* blend between the max value and gauss blue - gives nice feather */
+       const float value_gauss = tempColor / overallmultiplyer;
+       const float value_final = (value_max * distfacinv_max) + (value_gauss * (1.0f - distfacinv_max));
+       color[0] = value_final;
+}
+
+void GaussianAlphaYBlurOperation::deinitExecution()
+{
+       BlurBaseOperation::deinitExecution();
+       delete [] this->gausstab;
+       this->gausstab = NULL;
+       delete [] this->distbuf_inv;
+       this->distbuf_inv = NULL;
+}
+
+bool GaussianAlphaYBlurOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output)
+{
+       rcti newInput;
+       rcti sizeInput;
+       sizeInput.xmin = 0;
+       sizeInput.ymin = 0;
+       sizeInput.xmax = 5;
+       sizeInput.ymax = 5;
+       
+       NodeOperation *operation = this->getInputOperation(1);
+       if (operation->determineDependingAreaOfInterest(&sizeInput, readOperation, output)) {
+               return true;
+       }
+       else {
+               if (this->sizeavailable && this->gausstab != NULL) {
+                       newInput.xmax = input->xmax;
+                       newInput.xmin = input->xmin;
+                       newInput.ymax = input->ymax + rad;
+                       newInput.ymin = input->ymin - rad;
+               }
+               else {
+                       newInput.xmax = this->getWidth();
+                       newInput.xmin = 0;
+                       newInput.ymax = this->getHeight();
+                       newInput.ymin = 0;
+               }
+               return NodeOperation::determineDependingAreaOfInterest(&newInput, readOperation, output);
+       }
+}
diff --git a/source/blender/compositor/operations/COM_GaussianAlphaYBlurOperation.h b/source/blender/compositor/operations/COM_GaussianAlphaYBlurOperation.h
new file mode 100644 (file)
index 0000000..830f9b3
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2011, Blender Foundation.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor: 
+ *             Jeroen Bakker 
+ *             Monique Dewanchand
+ *             Campbell Barton
+ */
+
+#ifndef _COM_GaussianAlphaYBlurOperation_h
+#define _COM_GaussianAlphaYBlurOperation_h
+#include "COM_NodeOperation.h"
+#include "COM_BlurBaseOperation.h"
+
+class GaussianAlphaYBlurOperation : public BlurBaseOperation {
+private:
+       float *gausstab;
+       float *distbuf_inv;
+       int rad;
+       void updateGauss(MemoryBuffer **memoryBuffers);
+public:
+       GaussianAlphaYBlurOperation();
+       
+       /**
+        * the inner loop of this program
+        */
+       void executePixel(float *color, int x, int y, MemoryBuffer * inputBuffers[], void *data);
+       
+       /**
+        * @brief initialize the execution
+        */
+       void initExecution();
+
+       /**
+        * Deinitialize the execution
+        */
+       void deinitExecution();
+       
+       void *initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers);
+       bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output);
+};
+#endif
index b38ed28..208d482 100644 (file)
@@ -27,7 +27,7 @@ extern "C" {
        #include "RE_pipeline.h"
 }
 
-GaussianBokehBlurOperation::GaussianBokehBlurOperation() : BlurBaseOperation()
+GaussianBokehBlurOperation::GaussianBokehBlurOperation() : BlurBaseOperation(COM_DT_COLOR)
 {
        this->gausstab = NULL;
 }
index 09a2a70..8f68957 100644 (file)
@@ -27,7 +27,7 @@ extern "C" {
        #include "RE_pipeline.h"
 }
 
-GaussianXBlurOperation::GaussianXBlurOperation() : BlurBaseOperation()
+GaussianXBlurOperation::GaussianXBlurOperation() : BlurBaseOperation(COM_DT_COLOR)
 {
        this->gausstab = NULL;
        this->rad = 0;
index ace8171..d2cf5d1 100644 (file)
@@ -27,7 +27,7 @@ extern "C" {
        #include "RE_pipeline.h"
 }
 
-GaussianYBlurOperation::GaussianYBlurOperation() : BlurBaseOperation()
+GaussianYBlurOperation::GaussianYBlurOperation() : BlurBaseOperation(COM_DT_COLOR)
 {
        this->gausstab = NULL;
        this->rad = 0;
index a10d610..9bc002b 100644 (file)
@@ -361,6 +361,7 @@ typedef struct bNodeSocketValueRGBA {
 #define CMP_NODE_DILATEERODE_STEP            0
 #define CMP_NODE_DILATEERODE_DISTANCE_THRESH 1
 #define CMP_NODE_DILATEERODE_DISTANCE        2
+#define CMP_NODE_DILATEERODE_DISTANCE_FEATHER 3
 
 typedef struct NodeFrame {
        short flag;
index 683a49a..906f9cf 100644 (file)
@@ -2049,10 +2049,11 @@ static void def_cmp_dilate_erode(StructRNA *srna)
        PropertyRNA *prop;
 
        static EnumPropertyItem type_items[] = {
-               {CMP_NODE_DILATEERODE_STEP,            "STEP",      0, "Step",      ""},
+           {CMP_NODE_DILATEERODE_STEP,            "STEP",      0, "Step",      ""},
            {CMP_NODE_DILATEERODE_DISTANCE_THRESH, "THRESHOLD", 0, "Threshold", ""},
            {CMP_NODE_DILATEERODE_DISTANCE,        "DISTANCE",  0, "Distance",  ""},
-               {0, NULL, 0, NULL, NULL}
+           {CMP_NODE_DILATEERODE_DISTANCE_FEATHER,"FEATHER",  0,  "Feather",  ""},
+           {0, NULL, 0, NULL, NULL}
        };
        
        prop = RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE);