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
This commit is contained in:
Jeroen Bakker 2012-05-21 10:20:30 +00:00
parent 14e4ad9302
commit 998a850f9f
8 changed files with 273 additions and 32 deletions

@ -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);
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);
bNode *editorNode = this->getbNode();
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));
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);
}
}
}

@ -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);

@ -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;
}

@ -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

@ -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);
}
}

@ -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)

@ -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;

@ -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)