Added switch in dilate/erode between old (Step) and new (Distance)
authorJeroen Bakker <j.bakker@atmind.nl>
Mon, 21 May 2012 10:20:30 +0000 (10:20 +0000)
committerJeroen Bakker <j.bakker@atmind.nl>
Mon, 21 May 2012 10:20:30 +0000 (10:20 +0000)
algorithm

Connected the Glare Fog Flow to use Fast Gaussian in stead of Bokeh blur

source/blender/compositor/nodes/COM_DilateErodeNode.cpp
source/blender/compositor/nodes/COM_GlareNode.cpp
source/blender/compositor/operations/COM_DilateErodeOperation.cpp
source/blender/compositor/operations/COM_DilateErodeOperation.h
source/blender/compositor/operations/COM_GlareBaseOperation.cpp
source/blender/editors/space_node/drawnode.c
source/blender/makesdna/DNA_node_types.h
source/blender/makesrna/intern/rna_nodetree.c

index 2118f5b8e47b46759e5ce81fca9deabcb6ca2638..55759ba410f6535f02c85477ff73338ab3c4036d 100644 (file)
@@ -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);
+               }
+       }
 }
index c65adc862b1b63abee356dfe1760fd107696d08b..e882c16814a07d2b055ed29366d0d8d951344690 100644 (file)
 #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);
index d9c0350eb09daa45c60351aa447ed9447fb1b825..0dc4ea84cb8ccf67987747a02c396968ce9f9da0 100644 (file)
@@ -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;
+}
index 102d1165bc86c87eb50093b0ec16c6f46f7f9f2e..7f01ea944948beed46c5492617c080cbfc62ca62 100644 (file)
@@ -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
index 6715d50bb95df77492c811c47e63feefedf10643..44f987b45e362bdbc2038811c82fc6f6c5676b60 100644 (file)
@@ -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);
+       }
 }
index d42393f3611981d5594ae7db231fae659f4ab776..ecdd30ce966ea026aabfa0c006db315cdd6ce46b 100644 (file)
@@ -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)
index 4bbd1e2097335e2577816607d3f87ece041726a7..6d3e57b603422ab703899abdf2bf1d6d94214a26 100644 (file)
@@ -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;
index 1f5ac24db92edb121f5e1aeac28cdeecd78c70c5..cc2ad912a11e63a565e3f045c572ce45dce373dd 100644 (file)
@@ -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)