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:
authorJeroen Bakker <j.bakker@atmind.nl>2012-07-19 15:05:18 +0400
committerJeroen Bakker <j.bakker@atmind.nl>2012-07-19 15:05:18 +0400
commita56f4fee38e17d05964941a5edc2850c217309d7 (patch)
treee4430faf6ff15aa037f6d8fb1ede5f0afac6a376 /source
parent9c8edae7d4ef799b19f6487feb21ce7fbcf5ee07 (diff)
Fix for
* [#32040] size-input of a blur-node is uniform for the whole picture * [#32062] Blur node Size input is not working with * [#32140] Blur Node using a greyscale input as size multiplier fails to work Node now has a new option (new compositor cannot detect if the connected part is a single value, or an image connected). With this option the use of a reference image to multiply the size of the blur per pixel can be enabled/disabled. Regards, Jeroen - At Mind -
Diffstat (limited to 'source')
-rw-r--r--source/blender/compositor/nodes/COM_BlurNode.cpp40
-rw-r--r--source/blender/compositor/operations/COM_GaussianBokehBlurOperation.cpp173
-rw-r--r--source/blender/compositor/operations/COM_GaussianBokehBlurOperation.h20
-rw-r--r--source/blender/editors/space_node/drawnode.c13
-rw-r--r--source/blender/makesdna/DNA_node_types.h4
-rw-r--r--source/blender/makesrna/intern/rna_nodetree.c6
6 files changed, 153 insertions, 103 deletions
diff --git a/source/blender/compositor/nodes/COM_BlurNode.cpp b/source/blender/compositor/nodes/COM_BlurNode.cpp
index 5447652c238..9b945887ec2 100644
--- a/source/blender/compositor/nodes/COM_BlurNode.cpp
+++ b/source/blender/compositor/nodes/COM_BlurNode.cpp
@@ -25,9 +25,13 @@
#include "DNA_node_types.h"
#include "COM_GaussianXBlurOperation.h"
#include "COM_GaussianYBlurOperation.h"
+#include "COM_GaussianAlphaXBlurOperation.h"
+#include "COM_GaussianAlphaYBlurOperation.h"
#include "COM_ExecutionSystem.h"
#include "COM_GaussianBokehBlurOperation.h"
#include "COM_FastGaussianBlurOperation.h"
+#include "COM_MathBaseOperation.h"
+#include "COM_SetValueOperation.h"
BlurNode::BlurNode(bNode *editorNode) : Node(editorNode)
{
@@ -56,6 +60,42 @@ void BlurNode::convertToOperations(ExecutionSystem *graph, CompositorContext *co
graph->addOperation(operationfgb);
addPreviewOperation(graph, operationfgb->getOutputSocket());
}
+ else if (editorNode->custom1 & CMP_NODEFLAG_BLUR_REFERENCE) {
+ MathAddOperation *clamp = new MathAddOperation();
+ SetValueOperation *zero = new SetValueOperation();
+ addLink(graph, zero->getOutputSocket(), clamp->getInputSocket(1));
+ this->getInputSocket(1)->relinkConnections(clamp->getInputSocket(0), 1, graph);
+ zero->setValue(0.0f);
+ clamp->setUseClamp(true);
+ graph->addOperation(clamp);
+ graph->addOperation(zero);
+
+ GaussianAlphaXBlurOperation *operationx = new GaussianAlphaXBlurOperation();
+ operationx->setData(data);
+ operationx->setbNode(editorNode);
+ operationx->setQuality(quality);
+ operationx->setSize(1.0f);
+ addLink(graph, clamp->getOutputSocket(), operationx->getInputSocket(0));
+ graph->addOperation(operationx);
+
+ GaussianYBlurOperation *operationy = new GaussianYBlurOperation();
+ operationy->setData(data);
+ operationy->setbNode(editorNode);
+ operationy->setQuality(quality);
+ operationy->setSize(1.0f);
+ addLink(graph, operationx->getOutputSocket(), operationy->getInputSocket(0));
+ graph->addOperation(operationy);
+
+ GaussianBlurReferenceOperation *operation = new GaussianBlurReferenceOperation();
+ operation->setData(data);
+ operation->setbNode(editorNode);
+ operation->setQuality(quality);
+ this->getInputSocket(0)->relinkConnections(operation->getInputSocket(0), 0, graph);
+ addLink(graph, operationy->getOutputSocket(), operation->getInputSocket(1));
+ graph->addOperation(operation);
+ this->getOutputSocket(0)->relinkConnections(operation->getOutputSocket());
+ addPreviewOperation(graph, operation->getOutputSocket());
+ }
else if (!data->bokeh) {
GaussianXBlurOperation *operationx = new GaussianXBlurOperation();
operationx->setData(data);
diff --git a/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.cpp b/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.cpp
index 93cc39849a2..fd70d0d329a 100644
--- a/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.cpp
+++ b/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.cpp
@@ -22,7 +22,7 @@
#include "COM_GaussianBokehBlurOperation.h"
#include "BLI_math.h"
-
+#include "MEM_guardedalloc.h"
extern "C" {
#include "RE_pipeline.h"
}
@@ -198,25 +198,20 @@ bool GaussianBokehBlurOperation::determineDependingAreaOfInterest(rcti *input, R
}
// reference image
-GaussianBokehBlurReferenceOperation::GaussianBokehBlurReferenceOperation() : NodeOperation()
+GaussianBlurReferenceOperation::GaussianBlurReferenceOperation() : BlurBaseOperation(COM_DT_COLOR)
{
- this->addInputSocket(COM_DT_COLOR);
- this->addInputSocket(COM_DT_VALUE);
- this->addOutputSocket(COM_DT_COLOR);
- this->setComplex(true);
- this->m_gausstab = NULL;
- this->m_inputImage = NULL;
- this->m_inputSize = NULL;
+ this->m_maintabs = NULL;
}
-void *GaussianBokehBlurReferenceOperation::initializeTileData(rcti *rect)
+void *GaussianBlurReferenceOperation::initializeTileData(rcti *rect)
{
void *buffer = getInputOperation(0)->initializeTileData(NULL);
return buffer;
}
-void GaussianBokehBlurReferenceOperation::initExecution()
+void GaussianBlurReferenceOperation::initExecution()
{
+ BlurBaseOperation::initExecution();
// setup gaustab
this->m_data->image_in_width = this->getWidth();
this->m_data->image_in_height = this->getHeight();
@@ -237,100 +232,106 @@ void GaussianBokehBlurReferenceOperation::initExecution()
}
}
+
+ /* horizontal */
+ m_radx = (float)this->m_data->sizex;
+ int imgx = getWidth()/2;
+ if (m_radx > imgx)
+ m_radx = imgx;
+ else if (m_radx < 1)
+ m_radx = 1;
+ m_radxf = (float)m_radx;
+
+ /* vertical */
+ m_rady = (float)this->m_data->sizey;
+ int imgy = getHeight()/2;
+ if (m_rady > imgy)
+ m_rady = imgy;
+ else if (m_rady < 1)
+ m_rady = 1;
+ m_radyf = (float)m_rady;
updateGauss();
- this->m_inputImage = this->getInputSocketReader(0);
- this->m_inputSize = this->getInputSocketReader(1);
}
-void GaussianBokehBlurReferenceOperation::updateGauss()
+void GaussianBlurReferenceOperation::updateGauss()
{
- int n;
- float *dgauss;
- float *ddgauss;
- int j, i;
-
- n = (2 * radx + 1) * (2 * rady + 1);
-
- /* create a full filter image */
- ddgauss = new float[n];
- dgauss = ddgauss;
- for (j = -rady; j <= rady; j++) {
- for (i = -radx; i <= radx; i++, dgauss++) {
- float fj = (float)j / radyf;
- float fi = (float)i / radxf;
- float dist = sqrt(fj * fj + fi * fi);
- *dgauss = RE_filter_value(this->m_data->filtertype, dist);
- }
- }
- this->m_gausstab = ddgauss;
+ int i;
+ int x = MAX2(m_radx, m_rady);
+ this->m_maintabs = (float**)MEM_mallocN(x * sizeof(float *), "gauss array");
+ for (i = 0; i < x; i++)
+ m_maintabs[i] = make_gausstab(i + 1);
}
-void GaussianBokehBlurReferenceOperation::executePixel(float *color, int x, int y, void *data)
+void GaussianBlurReferenceOperation::executePixel(float *color, int x, int y, void *data)
{
- float tempColor[4];
+ MemoryBuffer *memorybuffer = (MemoryBuffer*)data;
+ float *buffer = memorybuffer->getBuffer();
+ float *gausstabx, *gausstabcenty;
+ float *gausstaby, *gausstabcentx;
+ int i, j;
+ float *src;
+ register float sum, val;
+ float rval, gval, bval, aval;
+ int imgx = getWidth();
+ int imgy = getHeight();
float tempSize[4];
- tempColor[0] = 0;
- tempColor[1] = 0;
- tempColor[2] = 0;
- tempColor[3] = 0;
- float multiplier_accum = 0;
- MemoryBuffer *inputBuffer = (MemoryBuffer *)data;
- float *buffer = inputBuffer->getBuffer();
- int bufferwidth = inputBuffer->getWidth();
- int bufferstartx = inputBuffer->getRect()->xmin;
- int bufferstarty = inputBuffer->getRect()->ymin;
this->m_inputSize->read(tempSize, x, y, data);
- float size = tempSize[0];
- CLAMP(size, 0.0f, 1.0f);
- float sizeX = ceil(this->m_data->sizex * size);
- float sizeY = ceil(this->m_data->sizey * size);
+ float refSize = tempSize[0];
+ int refradx = (int)(refSize * m_radxf);
+ int refrady = (int)(refSize * m_radyf);
+ if (refradx > m_radx) refradx = m_radx;
+ else if (refradx < 1) refradx = 1;
+ if (refrady > m_rady) refrady = m_rady;
+ else if (refrady < 1) refrady = 1;
- if (sizeX <= 0.5f && sizeY <= 0.5f) {
- this->m_inputImage->read(color, x, y, data);
- return;
- }
-
- int miny = y - sizeY;
- int maxy = y + sizeY;
- int minx = x - sizeX;
- int maxx = x + sizeX;
- miny = max(miny, inputBuffer->getRect()->ymin);
- minx = max(minx, inputBuffer->getRect()->xmin);
- maxy = min(maxy, inputBuffer->getRect()->ymax);
- maxx = min(maxx, inputBuffer->getRect()->xmax);
+ if (refradx == 1 && refrady == 1) {
+ memorybuffer->readNoCheck(color, x, y);
+ } else {
+ int minxr = x - refradx < 0 ? -x : -refradx;
+ int maxxr = x + refradx > imgx ? imgx - x : refradx;
+ int minyr = y - refrady < 0 ? -y : -refrady;
+ int maxyr = y + refrady > imgy ? imgy - y : refrady;
- int step = QualityStepHelper::getStep();
- int offsetadd = QualityStepHelper::getOffsetAdd();
- for (int ny = miny; ny < maxy; ny += step) {
- int u = ny - y;
- float uf = ((u/sizeY)*radyf)+radyf;
- int indexu = uf * (radx*2+1);
- int bufferindex = ((minx - bufferstartx) * 4) + ((ny - bufferstarty) * 4 * bufferwidth);
- for (int nx = minx; nx < maxx; nx += step) {
- int v = nx - x;
- float vf = ((v/sizeX)*radxf)+radxf;
- int index = indexu + vf;
- const float multiplier = this->m_gausstab[index];
- madd_v4_v4fl(tempColor, &buffer[bufferindex], multiplier);
- multiplier_accum += multiplier;
- index += step;
- bufferindex += offsetadd;
+ float *srcd = buffer + COM_NUMBER_OF_CHANNELS * ( (y + minyr) * imgx + x + minxr);
+
+ gausstabx = m_maintabs[refradx - 1];
+ gausstabcentx = gausstabx + refradx;
+ gausstaby = m_maintabs[refrady - 1];
+ gausstabcenty = gausstaby + refrady;
+
+ sum = gval = rval = bval = aval = 0.0f;
+ for (i = minyr; i < maxyr; i++, srcd += COM_NUMBER_OF_CHANNELS * imgx) {
+ src = srcd;
+ for (j = minxr; j < maxxr; j++, src += COM_NUMBER_OF_CHANNELS) {
+
+ val = gausstabcenty[i] * gausstabcentx[j];
+ sum += val;
+ rval += val * src[0];
+ gval += val * src[1];
+ bval += val * src[2];
+ aval += val * src[3];
+ }
}
+ sum = 1.0f / sum;
+ color[0] = rval * sum;
+ color[1] = gval * sum;
+ color[2] = bval * sum;
+ color[3] = aval * sum;
}
- mul_v4_v4fl(color, tempColor, 1.0f / multiplier_accum);
}
-void GaussianBokehBlurReferenceOperation::deinitExecution()
+void GaussianBlurReferenceOperation::deinitExecution()
{
- delete [] this->m_gausstab;
- this->m_gausstab = NULL;
- this->m_inputImage = NULL;
- this->m_inputSize = NULL;
-
+ int x, i;
+ x = MAX2(m_radx, m_rady);
+ for (i = 0; i < x; i++)
+ delete []m_maintabs[i];
+ MEM_freeN(m_maintabs);
+ BlurBaseOperation::deinitExecution();
}
-bool GaussianBokehBlurReferenceOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output)
+bool GaussianBlurReferenceOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output)
{
rcti newInput;
NodeOperation *operation = this->getInputOperation(1);
diff --git a/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.h b/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.h
index 1a134c20e63..45140855464 100644
--- a/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.h
+++ b/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.h
@@ -49,22 +49,18 @@ public:
bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output);
};
-class GaussianBokehBlurReferenceOperation : public NodeOperation, public QualityStepHelper {
+class GaussianBlurReferenceOperation : public BlurBaseOperation {
private:
- SocketReader * m_inputImage;
- SocketReader * m_inputSize;
- float *m_gausstab;
- NodeBlurData *m_data;
+ float **m_maintabs;
void updateGauss();
+ int m_radx;
+ int m_rady;
+ float m_radxf;
+ float m_radyf;
- static const int radxf = 256.0f;
- static const int radyf = 256.0f;
- static const int radx = 256;
- static const int rady = 256;
-
public:
- GaussianBokehBlurReferenceOperation();
+ GaussianBlurReferenceOperation();
void initExecution();
void *initializeTileData(rcti *rect);
/**
@@ -78,8 +74,6 @@ public:
void deinitExecution();
bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output);
-
- void setData(NodeBlurData *data) { this->m_data = data; }
};
#endif
diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c
index 87a07407ee6..134b2d6fd99 100644
--- a/source/blender/editors/space_node/drawnode.c
+++ b/source/blender/editors/space_node/drawnode.c
@@ -1528,12 +1528,19 @@ static void node_composit_buts_renderlayers(uiLayout *layout, bContext *C, Point
static void node_composit_buts_blur(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
uiLayout *col, *row;
+ int reference;
+ int filter;
col = uiLayoutColumn(layout, FALSE);
-
+ filter = RNA_enum_get(ptr, "filter_type");
+ reference = RNA_boolean_get(ptr, "use_reference");
+
uiItemR(col, ptr, "filter_type", 0, "", ICON_NONE);
- if (RNA_enum_get(ptr, "filter_type") != R_FILTER_FAST_GAUSS) {
- uiItemR(col, ptr, "use_bokeh", 0, NULL, ICON_NONE);
+ if (filter != R_FILTER_FAST_GAUSS) {
+ uiItemR(col, ptr, "use_reference", 0, NULL, ICON_NONE);
+ if (!reference) {
+ uiItemR(col, ptr, "use_bokeh", 0, NULL, ICON_NONE);
+ }
uiItemR(col, ptr, "use_gamma_correction", 0, NULL, ICON_NONE);
}
diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h
index 1e2f6eabce6..a7f854f603c 100644
--- a/source/blender/makesdna/DNA_node_types.h
+++ b/source/blender/makesdna/DNA_node_types.h
@@ -374,6 +374,10 @@ enum {
CMP_NODEFLAG_MASK_NO_FEATHER = (1 << 1)
};
+enum {
+ CMP_NODEFLAG_BLUR_REFERENCE = (1 << 0),
+};
+
typedef struct NodeFrame {
short flag;
short label_size;
diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c
index a72059063fd..055c8dcbebb 100644
--- a/source/blender/makesrna/intern/rna_nodetree.c
+++ b/source/blender/makesrna/intern/rna_nodetree.c
@@ -1713,6 +1713,11 @@ static void def_cmp_blur(StructRNA *srna)
{0, NULL, 0, NULL, NULL}
};
+ prop = RNA_def_property(srna, "use_reference", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "custom1", CMP_NODEFLAG_BLUR_REFERENCE);
+ RNA_def_property_ui_text(prop, "Reference", "Use size socket as a reference image");
+ RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
+
RNA_def_struct_sdna_from(srna, "NodeBlurData", "storage");
prop = RNA_def_property(srna, "size_x", PROP_INT, PROP_NONE);
@@ -1771,7 +1776,6 @@ static void def_cmp_blur(StructRNA *srna)
RNA_def_property_boolean_sdna(prop, NULL, "gamma", 1);
RNA_def_property_ui_text(prop, "Gamma", "Apply filter on gamma corrected values");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-
}
static void def_cmp_filter(StructRNA *srna)