* Added new dilate/erode function

This commit is contained in:
2012-05-31 10:38:11 +00:00
parent 722ce85ff6
commit a9c4f76a6a
6 changed files with 175 additions and 8 deletions

View File

@@ -35,7 +35,7 @@ void DilateErodeNode::convertToOperations(ExecutionSystem *graph, CompositorCont
{
bNode *editorNode = this->getbNode();
if (editorNode->custom1 == CMP_NODE_DILATEERODE_DISTANCE) {
if (editorNode->custom1 == CMP_NODE_DILATEERODE_DISTANCE_THRESH) {
DilateErodeDistanceOperation *operation = new DilateErodeDistanceOperation();
operation->setDistance(editorNode->custom2);
operation->setInset(editorNode->custom3);
@@ -52,8 +52,22 @@ void DilateErodeNode::convertToOperations(ExecutionSystem *graph, CompositorCont
this->getOutputSocket(0)->relinkConnections(operation->getOutputSocket(0));
}
graph->addOperation(operation);
}
else {
} else if (editorNode->custom1 == CMP_NODE_DILATEERODE_DISTANCE) {
if (editorNode->custom2 > 0) {
DilateDistanceOperation * operation = new DilateDistanceOperation();
operation->setDistance(editorNode->custom2);
this->getInputSocket(0)->relinkConnections(operation->getInputSocket(0), 0, graph);
this->getOutputSocket(0)->relinkConnections(operation->getOutputSocket(0));
graph->addOperation(operation);
}
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);
}
} else {
if (editorNode->custom2 > 0) {
DilateStepOperation * operation = new DilateStepOperation();
operation->setIterations(editorNode->custom2);

View File

@@ -23,6 +23,7 @@
#include "COM_DilateErodeOperation.h"
#include "BLI_math.h"
// DilateErode Distance Threshold
DilateErodeDistanceOperation::DilateErodeDistanceOperation(): NodeOperation()
{
this->addInputSocket(COM_DT_VALUE);
@@ -158,6 +159,115 @@ bool DilateErodeDistanceOperation::determineDependingAreaOfInterest(rcti *input,
return NodeOperation::determineDependingAreaOfInterest(&newInput, readOperation, output);
}
// Dilate Distance
DilateDistanceOperation::DilateDistanceOperation(): NodeOperation()
{
this->addInputSocket(COM_DT_VALUE);
this->addOutputSocket(COM_DT_VALUE);
this->setComplex(true);
this->inputProgram = NULL;
this->distance = 0.0f;
}
void DilateDistanceOperation::initExecution()
{
this->inputProgram = this->getInputSocketReader(0);
this->scope = distance;
if (scope < 3) {
scope = 3;
}
}
void *DilateDistanceOperation::initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers)
{
void *buffer = inputProgram->initializeTileData(NULL, memoryBuffers);
return buffer;
}
void DilateDistanceOperation::executePixel(float *color, int x, int y, MemoryBuffer *inputBuffers[], void *data)
{
const float distance = this->distance;
float mindist = distance * distance;
MemoryBuffer *inputBuffer = (MemoryBuffer*)data;
float *buffer = inputBuffer->getBuffer();
rcti *rect = inputBuffer->getRect();
const int minx = max(x - scope, rect->xmin);
const int miny = max(y - scope, rect->ymin);
const int maxx = min(x + scope, rect->xmax);
const int maxy = min(y + scope, rect->ymax);
const int bufferWidth = rect->xmax-rect->xmin;
int offset;
float value = 0.0f;
for (int yi = miny ; yi<maxy;yi++) {
offset = ((yi-rect->ymin)*bufferWidth+(minx-rect->xmin))*4;
for (int xi = minx ; xi<maxx;xi++) {
const float dx = xi-x;
const float dy = yi-y;
const float dis = dx*dx+dy*dy;
if (dis <= mindist) {
value = max(buffer[offset], value);
}
offset +=4;
}
}
color[0] = value;
}
void DilateDistanceOperation::deinitExecution()
{
this->inputProgram = NULL;
}
bool DilateDistanceOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output)
{
rcti newInput;
newInput.xmax = input->xmax + scope;
newInput.xmin = input->xmin - scope;
newInput.ymax = input->ymax + scope;
newInput.ymin = input->ymin - scope;
return NodeOperation::determineDependingAreaOfInterest(&newInput, readOperation, output);
}
// Erode Distance
ErodeDistanceOperation::ErodeDistanceOperation() : DilateDistanceOperation()
{
}
void ErodeDistanceOperation::executePixel(float *color, int x, int y, MemoryBuffer *inputBuffers[], void *data)
{
const float distance = this->distance;
float mindist = distance * distance;
MemoryBuffer *inputBuffer = (MemoryBuffer*)data;
float *buffer = inputBuffer->getBuffer();
rcti *rect = inputBuffer->getRect();
const int minx = max(x - scope, rect->xmin);
const int miny = max(y - scope, rect->ymin);
const int maxx = min(x + scope, rect->xmax);
const int maxy = min(y + scope, rect->ymax);
const int bufferWidth = rect->xmax-rect->xmin;
int offset;
float value = 1.0f;
for (int yi = miny ; yi<maxy;yi++) {
offset = ((yi-rect->ymin)*bufferWidth+(minx-rect->xmin))*4;
for (int xi = minx ; xi<maxx;xi++) {
const float dx = xi-x;
const float dy = yi-y;
const float dis = dx*dx+dy*dy;
if (dis <= mindist) {
value = min(buffer[offset], value);
}
offset +=4;
}
}
color[0] = value;
}
// Dilate step
DilateStepOperation::DilateStepOperation(): NodeOperation()
{

View File

@@ -68,6 +68,47 @@ public:
};
class DilateDistanceOperation : public NodeOperation {
private:
/**
* Cached reference to the inputProgram
*/
SocketReader * inputProgram;
protected:
float distance;
int scope;
public:
DilateDistanceOperation();
/**
* 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 setDistance(float distance) {this->distance = distance;}
bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output);
};
class ErodeDistanceOperation : public DilateDistanceOperation {
public:
ErodeDistanceOperation();
/**
* the inner loop of this program
*/
void executePixel(float *color, int x, int y, MemoryBuffer *inputBuffers[], void *data);
};
class DilateStepOperation : public NodeOperation {
protected:
/**

View File

@@ -1641,7 +1641,7 @@ static void node_composit_buts_dilateerode(uiLayout *layout, bContext *UNUSED(C)
{
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) {
if (RNA_enum_get(ptr, "type") == CMP_NODE_DILATEERODE_DISTANCE_THRESH) {
uiItemR(layout, ptr, "edge", 0, NULL, ICON_NONE);
}
}

View File

@@ -350,8 +350,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
#define CMP_NODE_DILATEERODE_STEP 0
#define CMP_NODE_DILATEERODE_DISTANCE_THRESH 1
#define CMP_NODE_DILATEERODE_DISTANCE 2
typedef struct NodeFrame {
short flag;

View File

@@ -1994,8 +1994,9 @@ 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", ""},
{CMP_NODE_DILATEERODE_STEP, "STEP", 0, "Step", ""},
{CMP_NODE_DILATEERODE_DISTANCE_THRESH, "THRESHOLD", 0, "Threshold", ""},
{CMP_NODE_DILATEERODE_DISTANCE, "DISTANCE", 0, "Distance", ""},
{0, NULL, 0, NULL, NULL}
};