diff options
author | Jeroen Bakker <j.bakker@atmind.nl> | 2012-05-21 14:20:30 +0400 |
---|---|---|
committer | Jeroen Bakker <j.bakker@atmind.nl> | 2012-05-21 14:20:30 +0400 |
commit | 998a850f9f2747065ffe379097907232a85cd2d5 (patch) | |
tree | a4b86c8a1f10e1c39e7557edad82d2a55574ea62 | |
parent | 14e4ad930209a3b861b5b514fbd23b39a7d16e94 (diff) |
Added switch in dilate/erode between old (Step) and new (Distance)
algorithm
Connected the Glare Fog Flow to use Fast Gaussian in stead of Bokeh blur
8 files changed, 272 insertions, 31 deletions
diff --git a/source/blender/compositor/nodes/COM_DilateErodeNode.cpp b/source/blender/compositor/nodes/COM_DilateErodeNode.cpp index 2118f5b8e47..55759ba410f 100644 --- a/source/blender/compositor/nodes/COM_DilateErodeNode.cpp +++ b/source/blender/compositor/nodes/COM_DilateErodeNode.cpp @@ -33,16 +33,37 @@ DilateErodeNode::DilateErodeNode(bNode *editorNode): Node(editorNode) void DilateErodeNode::convertToOperations(ExecutionSystem *graph, CompositorContext * context) { + bNode *editorNode = this->getbNode(); - DilateErodeOperation *operation = new DilateErodeOperation(); - operation->setDistance(editorNode->custom2); - operation->setInset(2.0f); + if (editorNode->custom1 == CMP_NODE_DILATEERODE_DISTANCE) { + DilateErodeDistanceOperation *operation = new DilateErodeDistanceOperation(); + operation->setDistance(editorNode->custom2); + operation->setInset(editorNode->custom3); + + this->getInputSocket(0)->relinkConnections(operation->getInputSocket(0)); - this->getInputSocket(0)->relinkConnections(operation->getInputSocket(0)); - - AntiAliasOperation * antiAlias = new AntiAliasOperation(); - addLink(graph, operation->getOutputSocket(), antiAlias->getInputSocket(0)); - this->getOutputSocket(0)->relinkConnections(antiAlias->getOutputSocket(0)); - graph->addOperation(operation); - graph->addOperation(antiAlias); + if (editorNode->custom3 < 2.0f) { + AntiAliasOperation * antiAlias = new AntiAliasOperation(); + addLink(graph, operation->getOutputSocket(), antiAlias->getInputSocket(0)); + this->getOutputSocket(0)->relinkConnections(antiAlias->getOutputSocket(0)); + graph->addOperation(antiAlias); + } else { + this->getOutputSocket(0)->relinkConnections(operation->getOutputSocket(0)); + } + graph->addOperation(operation); + } else { + if (editorNode->custom2 > 0) { + DilateStepOperation * operation = new DilateStepOperation(); + operation->setIterations(editorNode->custom2); + this->getInputSocket(0)->relinkConnections(operation->getInputSocket(0)); + this->getOutputSocket(0)->relinkConnections(operation->getOutputSocket(0)); + graph->addOperation(operation); + } else { + ErodeStepOperation * operation = new ErodeStepOperation(); + operation->setIterations(-editorNode->custom2); + this->getInputSocket(0)->relinkConnections(operation->getInputSocket(0)); + this->getOutputSocket(0)->relinkConnections(operation->getOutputSocket(0)); + graph->addOperation(operation); + } + } } diff --git a/source/blender/compositor/nodes/COM_GlareNode.cpp b/source/blender/compositor/nodes/COM_GlareNode.cpp index c65adc862b1..e882c16814a 100644 --- a/source/blender/compositor/nodes/COM_GlareNode.cpp +++ b/source/blender/compositor/nodes/COM_GlareNode.cpp @@ -23,12 +23,12 @@ #include "COM_GlareNode.h" #include "DNA_node_types.h" #include "COM_FogGlowImageOperation.h" -#include "COM_BokehBlurOperation.h" #include "COM_GlareThresholdOperation.h" #include "COM_GlareSimpleStarOperation.h" #include "COM_GlareStreaksOperation.h" #include "COM_SetValueOperation.h" #include "COM_MixBlendOperation.h" +#include "COM_FastGaussianBlurOperation.h" GlareNode::GlareNode(bNode *editorNode): Node(editorNode) { @@ -70,29 +70,31 @@ void GlareNode::convertToOperations(ExecutionSystem *system, CompositorContext * case 1: // fog glow { GlareThresholdOperation *thresholdOperation = new GlareThresholdOperation(); - FogGlowImageOperation * kerneloperation = new FogGlowImageOperation(); - BokehBlurOperation * bluroperation = new BokehBlurOperation(); + FastGaussianBlurOperation* bluroperation = new FastGaussianBlurOperation(); SetValueOperation * valueoperation = new SetValueOperation(); SetValueOperation * mixvalueoperation = new SetValueOperation(); MixBlendOperation * mixoperation = new MixBlendOperation(); mixoperation->setResolutionInputSocketIndex(1); this->getInputSocket(0)->relinkConnections(thresholdOperation->getInputSocket(0), true, 0, system); addLink(system, thresholdOperation->getOutputSocket(), bluroperation->getInputSocket(0)); - addLink(system, kerneloperation->getOutputSocket(), bluroperation->getInputSocket(1)); - addLink(system, valueoperation->getOutputSocket(), bluroperation->getInputSocket(2)); + addLink(system, valueoperation->getOutputSocket(), bluroperation->getInputSocket(1)); addLink(system, mixvalueoperation->getOutputSocket(), mixoperation->getInputSocket(0)); addLink(system, bluroperation->getOutputSocket(), mixoperation->getInputSocket(2)); addLink(system, thresholdOperation->getInputSocket(0)->getConnection()->getFromSocket(), mixoperation->getInputSocket(1)); thresholdOperation->setThreshold(glare->threshold); - bluroperation->setSize(0.003f*glare->size); + NodeBlurData * data = new NodeBlurData(); + data->relative = 0; + data->sizex = glare->size; + data->sizey = glare->size; + bluroperation->setData(data); + bluroperation->deleteDataWhenFinished(); bluroperation->setQuality(context->getQuality()); valueoperation->setValue(1.0f); mixvalueoperation->setValue(0.5f+glare->mix*0.5f); this->getOutputSocket()->relinkConnections(mixoperation->getOutputSocket()); system->addOperation(bluroperation); - system->addOperation(kerneloperation); system->addOperation(thresholdOperation); system->addOperation(mixvalueoperation); system->addOperation(valueoperation); diff --git a/source/blender/compositor/operations/COM_DilateErodeOperation.cpp b/source/blender/compositor/operations/COM_DilateErodeOperation.cpp index d9c0350eb09..0dc4ea84cb8 100644 --- a/source/blender/compositor/operations/COM_DilateErodeOperation.cpp +++ b/source/blender/compositor/operations/COM_DilateErodeOperation.cpp @@ -23,7 +23,7 @@ #include "COM_DilateErodeOperation.h" #include "BLI_math.h" -DilateErodeOperation::DilateErodeOperation(): NodeOperation() +DilateErodeDistanceOperation::DilateErodeDistanceOperation(): NodeOperation() { this->addInputSocket(COM_DT_VALUE); this->addOutputSocket(COM_DT_VALUE); @@ -33,7 +33,7 @@ DilateErodeOperation::DilateErodeOperation(): NodeOperation() this->_switch = 0.5f; this->distance = 0.0f; } -void DilateErodeOperation::initExecution() +void DilateErodeDistanceOperation::initExecution() { this->inputProgram = this->getInputSocketReader(0); if (this->distance < 0.0f) { @@ -52,13 +52,13 @@ void DilateErodeOperation::initExecution() } } -void *DilateErodeOperation::initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers) +void *DilateErodeDistanceOperation::initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers) { void *buffer = inputProgram->initializeTileData(NULL, memoryBuffers); return buffer; } -void DilateErodeOperation::executePixel(float *color, int x, int y, MemoryBuffer *inputBuffers[], void *data) +void DilateErodeDistanceOperation::executePixel(float *color, int x, int y, MemoryBuffer *inputBuffers[], void *data) { float inputValue[4]; const float sw = this->_switch; @@ -141,12 +141,12 @@ void DilateErodeOperation::executePixel(float *color, int x, int y, MemoryBuffer } } -void DilateErodeOperation::deinitExecution() +void DilateErodeDistanceOperation::deinitExecution() { this->inputProgram = NULL; } -bool DilateErodeOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output) +bool DilateErodeDistanceOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output) { rcti newInput; @@ -157,3 +157,151 @@ bool DilateErodeOperation::determineDependingAreaOfInterest(rcti *input, ReadBuf return NodeOperation::determineDependingAreaOfInterest(&newInput, readOperation, output); } + +// Dilate step +DilateStepOperation::DilateStepOperation(): NodeOperation() +{ + this->addInputSocket(COM_DT_VALUE); + this->addOutputSocket(COM_DT_VALUE); + this->setComplex(true); + this->inputProgram = NULL; +} +void DilateStepOperation::initExecution() +{ + this->inputProgram = this->getInputSocketReader(0); + this->cached_buffer = NULL; + this->initMutex(); +} + +void *DilateStepOperation::initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers) +{ + if (this->cached_buffer != NULL) { + return this->cached_buffer; + } + BLI_mutex_lock(getMutex()); + if (this->cached_buffer == NULL) { + MemoryBuffer *buffer = (MemoryBuffer*)inputProgram->initializeTileData(NULL, memoryBuffers); + float *rectf = buffer->convertToValueBuffer(); + int x, y, i; + float *p; + int bwidth = buffer->getWidth(); + int bheight = buffer->getHeight(); + for (i = 0 ; i < this->iterations ; i ++) { + for (y=0; y < bheight; y++) { + for (x=0; x < bwidth-1; x++) { + p = rectf + (bwidth*y + x); + *p = MAX2(*p, *(p + 1)); + } + } + + for (y=0; y < bheight; y++) { + for (x=bwidth-1; x >= 1; x--) { + p = rectf + (bwidth*y + x); + *p = MAX2(*p, *(p - 1)); + } + } + + for (x=0; x < bwidth; x++) { + for (y=0; y < bheight-1; y++) { + p = rectf + (bwidth*y + x); + *p = MAX2(*p, *(p + bwidth)); + } + } + + for (x=0; x < bwidth; x++) { + for (y=bheight-1; y >= 1; y--) { + p = rectf + (bwidth*y + x); + *p = MAX2(*p, *(p - bwidth)); + } + } + } + this->cached_buffer = rectf; + } + BLI_mutex_unlock(getMutex()); + return this->cached_buffer; +} + + +void DilateStepOperation::executePixel(float *color, int x, int y, MemoryBuffer *inputBuffers[], void *data) +{ + color[0] = this->cached_buffer[y*this->getWidth()+x]; +} + +void DilateStepOperation::deinitExecution() +{ + this->inputProgram = NULL; + this->deinitMutex(); + if (this->cached_buffer) { + delete cached_buffer; + this->cached_buffer = NULL; + } +} + +bool DilateStepOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output) +{ + if (this->cached_buffer) { + return false; + } else { + rcti newInput; + + newInput.xmax = getWidth(); + newInput.xmin = 0; + newInput.ymax = getHeight(); + newInput.ymin = 0; + + return NodeOperation::determineDependingAreaOfInterest(&newInput, readOperation, output); + } +} + +// Erode step +ErodeStepOperation::ErodeStepOperation(): DilateStepOperation() +{ +} + +void *ErodeStepOperation::initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers) +{ + if (this->cached_buffer != NULL) { + return this->cached_buffer; + } + BLI_mutex_lock(getMutex()); + if (this->cached_buffer == NULL) { + MemoryBuffer *buffer = (MemoryBuffer*)inputProgram->initializeTileData(NULL, memoryBuffers); + float *rectf = buffer->convertToValueBuffer(); + int x, y, i; + float *p; + int bwidth = buffer->getWidth(); + int bheight = buffer->getHeight(); + for (i = 0 ; i < this->iterations ; i ++) { + for (y=0; y < bheight; y++) { + for (x=0; x < bwidth-1; x++) { + p = rectf + (bwidth*y + x); + *p = MIN2(*p, *(p + 1)); + } + } + + for (y=0; y < bheight; y++) { + for (x=bwidth-1; x >= 1; x--) { + p = rectf + (bwidth*y + x); + *p = MIN2(*p, *(p - 1)); + } + } + + for (x=0; x < bwidth; x++) { + for (y=0; y < bheight-1; y++) { + p = rectf + (bwidth*y + x); + *p = MIN2(*p, *(p + bwidth)); + } + } + + for (x=0; x < bwidth; x++) { + for (y=bheight-1; y >= 1; y--) { + p = rectf + (bwidth*y + x); + *p = MIN2(*p, *(p - bwidth)); + } + } + } + this->cached_buffer = rectf; + } + BLI_mutex_unlock(getMutex()); + return this->cached_buffer; +} diff --git a/source/blender/compositor/operations/COM_DilateErodeOperation.h b/source/blender/compositor/operations/COM_DilateErodeOperation.h index 102d1165bc8..7f01ea94494 100644 --- a/source/blender/compositor/operations/COM_DilateErodeOperation.h +++ b/source/blender/compositor/operations/COM_DilateErodeOperation.h @@ -25,7 +25,7 @@ #include "COM_NodeOperation.h" -class DilateErodeOperation : public NodeOperation { +class DilateErodeDistanceOperation : public NodeOperation { private: /** * Cached reference to the inputProgram @@ -42,7 +42,7 @@ private: */ int scope; public: - DilateErodeOperation(); + DilateErodeDistanceOperation(); /** * the inner loop of this program @@ -67,4 +67,46 @@ public: bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output); }; + +class DilateStepOperation : public NodeOperation { +protected: + /** + * Cached reference to the inputProgram + */ + SocketReader * inputProgram; + + int iterations; + + float *cached_buffer; +public: + DilateStepOperation(); + + /** + * the inner loop of this program + */ + void executePixel(float *color, int x, int y, MemoryBuffer *inputBuffers[], void *data); + + /** + * Initialize the execution + */ + void initExecution(); + + void *initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers); + /** + * Deinitialize the execution + */ + void deinitExecution(); + + void setIterations(int iterations) {this->iterations = iterations;} + + bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output); +}; + +class ErodeStepOperation : public DilateStepOperation { +public: + ErodeStepOperation(); + + void *initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers); +}; + #endif diff --git a/source/blender/compositor/operations/COM_GlareBaseOperation.cpp b/source/blender/compositor/operations/COM_GlareBaseOperation.cpp index 6715d50bb95..44f987b45e3 100644 --- a/source/blender/compositor/operations/COM_GlareBaseOperation.cpp +++ b/source/blender/compositor/operations/COM_GlareBaseOperation.cpp @@ -72,10 +72,14 @@ void *GlareBaseOperation::initializeTileData(rcti *rect, MemoryBuffer **memoryBu bool GlareBaseOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output) { - rcti newInput; - newInput.xmax = this->getWidth(); - newInput.xmin = 0; - newInput.ymax = this->getHeight(); - newInput.ymin = 0; - return NodeOperation::determineDependingAreaOfInterest(&newInput, readOperation, output); + if (this->cachedInstance != NULL) { + return false; + } else { + rcti newInput; + 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/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index d42393f3611..ecdd30ce966 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -1582,7 +1582,11 @@ static void node_composit_buts_hue_sat(uiLayout *layout, bContext *UNUSED(C), Po static void node_composit_buts_dilateerode(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) { + uiItemR(layout, ptr, "type", 0, NULL, ICON_NONE); uiItemR(layout, ptr, "distance", 0, NULL, ICON_NONE); + if (RNA_enum_get(ptr, "type") == CMP_NODE_DILATEERODE_DISTANCE) { + uiItemR(layout, ptr, "edge", 0, NULL, ICON_NONE); + } } static void node_composit_buts_diff_matte(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h index 4bbd1e20973..6d3e57b6034 100644 --- a/source/blender/makesdna/DNA_node_types.h +++ b/source/blender/makesdna/DNA_node_types.h @@ -345,6 +345,9 @@ typedef struct bNodeSocketValueRGBA { #define CMP_NODE_LENSFLARE_CIRCLE 4 #define CMP_NODE_LENSFLARE_STREAKS 8 +#define CMP_NODE_DILATEERODE_STEP 0 +#define CMP_NODE_DILATEERODE_DISTANCE 1 + /* this one has been replaced with ImageUser, keep it for do_versions() */ typedef struct NodeImageAnim { int frames, sfra, nr; diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index 1f5ac24db92..cc2ad912a11 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -1962,12 +1962,29 @@ static void def_cmp_output_file(StructRNA *srna) static void def_cmp_dilate_erode(StructRNA *srna) { PropertyRNA *prop; + + static EnumPropertyItem type_items[] = { + {CMP_NODE_DILATEERODE_STEP, "STEP", 0, "Step", ""}, + {CMP_NODE_DILATEERODE_DISTANCE, "DISTANCE", 0, "Distance", ""}, + {0, NULL, 0, NULL, NULL}}; + + prop = RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "custom1"); + RNA_def_property_enum_items(prop, type_items); + RNA_def_property_ui_text(prop, "Distance", "Distance to grow/shrink (number of iterations)"); + RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_update"); prop = RNA_def_property(srna, "distance", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "custom2"); RNA_def_property_range(prop, -100, 100); RNA_def_property_ui_text(prop, "Distance", "Distance to grow/shrink (number of iterations)"); RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_update"); + + prop = RNA_def_property(srna, "edge", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "custom3"); + RNA_def_property_range(prop, -100, 100); + RNA_def_property_ui_text(prop, "Edge", "Edge to inset"); + RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_update"); } static void def_cmp_scale(StructRNA *srna) |