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:
authorCampbell Barton <ideasman42@gmail.com>2012-06-16 18:40:16 +0400
committerCampbell Barton <ideasman42@gmail.com>2012-06-16 18:40:16 +0400
commit6fc277c410d5ee4d13562e4b8b260bc0929f30f5 (patch)
tree5c7af757a8ae2c4d55fed565ef058843fef05209 /source
parente946fa443b5aab057bfe5f40f8bb4f346c84331e (diff)
support for negative feather dilate/erode
Diffstat (limited to 'source')
-rw-r--r--source/blender/compositor/nodes/COM_DilateErodeNode.cpp71
-rw-r--r--source/blender/compositor/operations/COM_GaussianAlphaXBlurOperation.cpp16
-rw-r--r--source/blender/compositor/operations/COM_GaussianAlphaXBlurOperation.h6
-rw-r--r--source/blender/compositor/operations/COM_GaussianAlphaYBlurOperation.cpp12
-rw-r--r--source/blender/compositor/operations/COM_GaussianAlphaYBlurOperation.h6
5 files changed, 67 insertions, 44 deletions
diff --git a/source/blender/compositor/nodes/COM_DilateErodeNode.cpp b/source/blender/compositor/nodes/COM_DilateErodeNode.cpp
index 326e0ad0c60..fbec1522e27 100644
--- a/source/blender/compositor/nodes/COM_DilateErodeNode.cpp
+++ b/source/blender/compositor/nodes/COM_DilateErodeNode.cpp
@@ -74,50 +74,49 @@ void DilateErodeNode::convertToOperations(ExecutionSystem *graph, CompositorCont
}
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();
- CompositorQuality quality = context->getQuality();
+ /* initialize node data */
+ NodeBlurData *data = (NodeBlurData *)&this->alpha_blur;
+ memset(data, 0, sizeof(*data));
+ data->filtertype = R_FILTER_GAUSS;
- /* initialize node data */
- NodeBlurData *data = (NodeBlurData *)&this->alpha_blur;
- memset(data, 0, sizeof(*data));
+ if (editorNode->custom2 > 0) {
data->sizex = data->sizey = editorNode->custom2;
- data->filtertype = R_FILTER_GAUSS;
+ }
+ else {
+ data->sizex = data->sizey = -editorNode->custom2;
- 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); // no size input yet
- 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)); // no size input yet
- addPreviewOperation(graph, operationy->getOutputSocket());
+ }
+
+ 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); // no size input yet
+ 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)); // no size input yet
+ addPreviewOperation(graph, operationy->getOutputSocket());
- /* TODO? */
- /* see gaussian blue node for original usage */
+ /* TODO? */
+ /* see gaussian blue node for original usage */
#if 0
- if (!connectedSizeSocket) {
- operationx->setSize(size);
- operationy->setSize(size);
- }
+ if (!connectedSizeSocket) {
+ operationx->setSize(size);
+ operationy->setSize(size);
+ }
#else
- operationx->setSize(1.0f);
- operationy->setSize(1.0f);
+ 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);
- }
+ operationx->setSubtract(editorNode->custom2 < 0);
+ operationy->setSubtract(editorNode->custom2 < 0);
}
else {
if (editorNode->custom2 > 0) {
diff --git a/source/blender/compositor/operations/COM_GaussianAlphaXBlurOperation.cpp b/source/blender/compositor/operations/COM_GaussianAlphaXBlurOperation.cpp
index 4a3fa7d5c12..5c6e0e4adac 100644
--- a/source/blender/compositor/operations/COM_GaussianAlphaXBlurOperation.cpp
+++ b/source/blender/compositor/operations/COM_GaussianAlphaXBlurOperation.cpp
@@ -81,8 +81,14 @@ void GaussianAlphaXBlurOperation::updateGauss(MemoryBuffer **memoryBuffers)
}
}
+BLI_INLINE float finv_test(const float f, const bool test)
+{
+ return (LIKELY(test == false)) ? f : 1.0f - f;
+}
+
void GaussianAlphaXBlurOperation::executePixel(float *color, int x, int y, MemoryBuffer *inputBuffers[], void *data)
{
+ const bool do_invert = this->do_subtract;
MemoryBuffer *inputBuffer = (MemoryBuffer *)data;
float *buffer = inputBuffer->getBuffer();
int bufferwidth = inputBuffer->getWidth();
@@ -108,12 +114,12 @@ void GaussianAlphaXBlurOperation::executePixel(float *color, int x, int y, Memor
float overallmultiplyer = 0.0f;
/* dilate */
- float value_max = buffer[(x * 4) + (y * 4 * bufferwidth)]; /* init with the current color to avoid unneeded lookups */
+ float value_max = finv_test(buffer[(x * 4) + (y * 4 * bufferwidth)], do_invert); /* 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 value = finv_test(buffer[bufferindex], do_invert);
float multiplyer;
/* gauss */
@@ -131,7 +137,7 @@ void GaussianAlphaXBlurOperation::executePixel(float *color, int x, int y, Memor
multiplyer = distbuf_inv[index];
#endif
value *= multiplyer;
- if ((value > value_max) == TRUE) {
+ if (value > value_max) {
value_max = value;
distfacinv_max = multiplyer;
}
@@ -143,7 +149,7 @@ void GaussianAlphaXBlurOperation::executePixel(float *color, int x, int y, Memor
/* 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;
+ color[0] = finv_test(value_final, do_invert);
}
void GaussianAlphaXBlurOperation::deinitExecution()
@@ -164,7 +170,7 @@ bool GaussianAlphaXBlurOperation::determineDependingAreaOfInterest(rcti *input,
sizeInput.ymin = 0;
sizeInput.xmax = 5;
sizeInput.ymax = 5;
-
+
NodeOperation *operation = this->getInputOperation(1);
if (operation->determineDependingAreaOfInterest(&sizeInput, readOperation, output)) {
return true;
diff --git a/source/blender/compositor/operations/COM_GaussianAlphaXBlurOperation.h b/source/blender/compositor/operations/COM_GaussianAlphaXBlurOperation.h
index 2b5e4d33673..3268e51be01 100644
--- a/source/blender/compositor/operations/COM_GaussianAlphaXBlurOperation.h
+++ b/source/blender/compositor/operations/COM_GaussianAlphaXBlurOperation.h
@@ -30,6 +30,7 @@ class GaussianAlphaXBlurOperation : public BlurBaseOperation {
private:
float *gausstab;
float *distbuf_inv;
+ bool do_subtract;
int rad;
void updateGauss(MemoryBuffer **memoryBuffers);
public:
@@ -52,5 +53,10 @@ public:
void *initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers);
bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output);
+
+ /**
+ * Set subtract for Dilate/Erode functionality
+ */
+ void setSubtract(bool subtract) { this->do_subtract = subtract; }
};
#endif
diff --git a/source/blender/compositor/operations/COM_GaussianAlphaYBlurOperation.cpp b/source/blender/compositor/operations/COM_GaussianAlphaYBlurOperation.cpp
index f84f4e3b094..40f74ad4485 100644
--- a/source/blender/compositor/operations/COM_GaussianAlphaYBlurOperation.cpp
+++ b/source/blender/compositor/operations/COM_GaussianAlphaYBlurOperation.cpp
@@ -79,8 +79,14 @@ void GaussianAlphaYBlurOperation::updateGauss(MemoryBuffer **memoryBuffers)
}
}
+BLI_INLINE float finv_test(const float f, const bool test)
+{
+ return (LIKELY(test == false)) ? f : 1.0f - f;
+}
+
void GaussianAlphaYBlurOperation::executePixel(float *color, int x, int y, MemoryBuffer *inputBuffers[], void *data)
{
+ const bool do_invert = this->do_subtract;
MemoryBuffer *inputBuffer = (MemoryBuffer *)data;
float *buffer = inputBuffer->getBuffer();
int bufferwidth = inputBuffer->getWidth();
@@ -104,14 +110,14 @@ void GaussianAlphaYBlurOperation::executePixel(float *color, int x, int y, Memor
float overallmultiplyer = 0.0f;
/* dilate */
- float value_max = buffer[(x * 4) + (y * 4 * bufferwidth)]; /* init with the current color to avoid unneeded lookups */
+ float value_max = finv_test(buffer[(x * 4) + (y * 4 * bufferwidth)], do_invert); /* 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 value = finv_test(buffer[bufferindex], do_invert);
float multiplyer;
/* gauss */
@@ -140,7 +146,7 @@ void GaussianAlphaYBlurOperation::executePixel(float *color, int x, int y, Memor
/* 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;
+ color[0] = finv_test(value_final, do_invert);
}
void GaussianAlphaYBlurOperation::deinitExecution()
diff --git a/source/blender/compositor/operations/COM_GaussianAlphaYBlurOperation.h b/source/blender/compositor/operations/COM_GaussianAlphaYBlurOperation.h
index 830f9b35c30..0ffc264ba98 100644
--- a/source/blender/compositor/operations/COM_GaussianAlphaYBlurOperation.h
+++ b/source/blender/compositor/operations/COM_GaussianAlphaYBlurOperation.h
@@ -30,6 +30,7 @@ class GaussianAlphaYBlurOperation : public BlurBaseOperation {
private:
float *gausstab;
float *distbuf_inv;
+ bool do_subtract;
int rad;
void updateGauss(MemoryBuffer **memoryBuffers);
public:
@@ -52,5 +53,10 @@ public:
void *initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers);
bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output);
+
+ /**
+ * Set subtract for Dilate/Erode functionality
+ */
+ void setSubtract(bool subtract) { this->do_subtract = subtract; }
};
#endif