Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeroen Bakker <j.bakker@atmind.nl>2012-05-31 14:38:11 +0400
committerJeroen Bakker <j.bakker@atmind.nl>2012-05-31 14:38:11 +0400
commita9c4f76a6a96bcffc8d94e2da5e636d4304da345 (patch)
tree38f0d2593d5a5f704fb890cde3b8ba030bfb015d /source/blender/compositor
parent722ce85ff6876ab85b7e934724e89fe24241f670 (diff)
* Added new dilate/erode function
Diffstat (limited to 'source/blender/compositor')
-rw-r--r--source/blender/compositor/nodes/COM_DilateErodeNode.cpp20
-rw-r--r--source/blender/compositor/operations/COM_DilateErodeOperation.cpp110
-rw-r--r--source/blender/compositor/operations/COM_DilateErodeOperation.h41
3 files changed, 168 insertions, 3 deletions
diff --git a/source/blender/compositor/nodes/COM_DilateErodeNode.cpp b/source/blender/compositor/nodes/COM_DilateErodeNode.cpp
index cc96f672ebd..b722e40a875 100644
--- a/source/blender/compositor/nodes/COM_DilateErodeNode.cpp
+++ b/source/blender/compositor/nodes/COM_DilateErodeNode.cpp
@@ -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);
diff --git a/source/blender/compositor/operations/COM_DilateErodeOperation.cpp b/source/blender/compositor/operations/COM_DilateErodeOperation.cpp
index a73f76030ab..7bc49fa695c 100644
--- a/source/blender/compositor/operations/COM_DilateErodeOperation.cpp
+++ b/source/blender/compositor/operations/COM_DilateErodeOperation.cpp
@@ -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()
{
diff --git a/source/blender/compositor/operations/COM_DilateErodeOperation.h b/source/blender/compositor/operations/COM_DilateErodeOperation.h
index 7f01ea94494..71bbab74a4b 100644
--- a/source/blender/compositor/operations/COM_DilateErodeOperation.h
+++ b/source/blender/compositor/operations/COM_DilateErodeOperation.h
@@ -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:
/**