diff options
Diffstat (limited to 'source/blender')
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 |