* Added new dilate/erode function
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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()
|
||||
{
|
||||
|
||||
@@ -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:
|
||||
/**
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user