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:
-rw-r--r--source/blender/blenkernel/BKE_node.h1
-rw-r--r--source/blender/blenkernel/intern/node.c1
-rw-r--r--source/blender/compositor/CMakeLists.txt11
-rw-r--r--source/blender/compositor/intern/COM_Converter.cpp4
-rw-r--r--source/blender/compositor/nodes/COM_KeyingNode.cpp227
-rw-r--r--source/blender/compositor/nodes/COM_KeyingNode.h42
-rw-r--r--source/blender/compositor/operations/COM_KeyingBlurOperation.cpp88
-rw-r--r--source/blender/compositor/operations/COM_KeyingBlurOperation.h48
-rw-r--r--source/blender/compositor/operations/COM_KeyingClipOperation.cpp123
-rw-r--r--source/blender/compositor/operations/COM_KeyingClipOperation.h59
-rw-r--r--source/blender/compositor/operations/COM_KeyingDespillOperation.cpp89
-rw-r--r--source/blender/compositor/operations/COM_KeyingDespillOperation.h49
-rw-r--r--source/blender/compositor/operations/COM_KeyingOperation.cpp115
-rw-r--r--source/blender/compositor/operations/COM_KeyingOperation.h56
-rw-r--r--source/blender/editors/space_clip/clip_dopesheet_ops.c17
-rw-r--r--source/blender/editors/space_node/drawnode.c18
-rw-r--r--source/blender/makesdna/DNA_node_types.h10
-rw-r--r--source/blender/makesrna/intern/rna_nodetree.c98
-rw-r--r--source/blender/makesrna/intern/rna_nodetree_types.h1
-rw-r--r--source/blender/nodes/CMakeLists.txt1
-rw-r--r--source/blender/nodes/NOD_composite.h1
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_keying.c94
22 files changed, 1134 insertions, 19 deletions
diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h
index bf708fc550d..c856d407f05 100644
--- a/source/blender/blenkernel/BKE_node.h
+++ b/source/blender/blenkernel/BKE_node.h
@@ -659,6 +659,7 @@ void ntreeGPUMaterialNodes(struct bNodeTree *ntree, struct GPUMaterial *mat);
#define CMP_NODE_OUTPUT_MULTI_FILE__DEPRECATED 267 /* DEPRECATED multi file node has been merged into regular CMP_NODE_OUTPUT_FILE */
#define CMP_NODE_MASK 268
#define CMP_NODE_KEYINGSCREEN 269
+#define CMP_NODE_KEYING 270
#define CMP_NODE_GLARE 301
#define CMP_NODE_TONEMAP 302
diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c
index 20c9344a870..bd3690e2174 100644
--- a/source/blender/blenkernel/intern/node.c
+++ b/source/blender/blenkernel/intern/node.c
@@ -1901,6 +1901,7 @@ static void registerCompositNodes(bNodeTreeType *ttype)
register_node_type_cmp_luma_matte(ttype);
register_node_type_cmp_doubleedgemask(ttype);
register_node_type_cmp_keyingscreen(ttype);
+ register_node_type_cmp_keying(ttype);
register_node_type_cmp_translate(ttype);
register_node_type_cmp_rotate(ttype);
diff --git a/source/blender/compositor/CMakeLists.txt b/source/blender/compositor/CMakeLists.txt
index cfaf11c4400..fbe391a554d 100644
--- a/source/blender/compositor/CMakeLists.txt
+++ b/source/blender/compositor/CMakeLists.txt
@@ -330,6 +330,17 @@ set(SRC
operations/COM_KeyingScreenOperation.cpp
operations/COM_KeyingScreenOperation.h
+ nodes/COM_KeyingNode.cpp
+ nodes/COM_KeyingNode.h
+ operations/COM_KeyingOperation.cpp
+ operations/COM_KeyingOperation.h
+ operations/COM_KeyingBlurOperation.cpp
+ operations/COM_KeyingBlurOperation.h
+ operations/COM_KeyingDespillOperation.cpp
+ operations/COM_KeyingDespillOperation.h
+ operations/COM_KeyingClipOperation.cpp
+ operations/COM_KeyingClipOperation.h
+
operations/COM_ColorSpillOperation.cpp
operations/COM_ColorSpillOperation.h
operations/COM_RenderLayersBaseProg.cpp
diff --git a/source/blender/compositor/intern/COM_Converter.cpp b/source/blender/compositor/intern/COM_Converter.cpp
index 082e2fe5d04..9731555039c 100644
--- a/source/blender/compositor/intern/COM_Converter.cpp
+++ b/source/blender/compositor/intern/COM_Converter.cpp
@@ -113,6 +113,7 @@
#include "COM_CropNode.h"
#include "COM_MaskNode.h"
#include "COM_KeyingScreenNode.h"
+#include "COM_KeyingNode.h"
Node *Converter::convert(bNode *bNode)
{
@@ -355,6 +356,9 @@ case CMP_NODE_OUTPUT_FILE:
case CMP_NODE_KEYINGSCREEN:
node = new KeyingScreenNode(bNode);
break;
+ case CMP_NODE_KEYING:
+ node = new KeyingNode(bNode);
+ break;
/* not inplemented yet */
default:
node = new MuteNode(bNode);
diff --git a/source/blender/compositor/nodes/COM_KeyingNode.cpp b/source/blender/compositor/nodes/COM_KeyingNode.cpp
new file mode 100644
index 00000000000..74af25b8e5f
--- /dev/null
+++ b/source/blender/compositor/nodes/COM_KeyingNode.cpp
@@ -0,0 +1,227 @@
+/*
+ * Copyright 2012, Blender Foundation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor:
+ * Jeroen Bakker
+ * Monique Dewanchand
+ * Sergey Sharybin
+ */
+
+#include "COM_KeyingNode.h"
+
+#include "COM_ExecutionSystem.h"
+
+#include "COM_KeyingOperation.h"
+#include "COM_KeyingBlurOperation.h"
+#include "COM_KeyingDespillOperation.h"
+#include "COM_KeyingClipOperation.h"
+
+#include "COM_SeparateChannelOperation.h"
+#include "COM_CombineChannelsOperation.h"
+#include "COM_ConvertRGBToYCCOperation.h"
+#include "COM_ConvertYCCToRGBOperation.h"
+#include "COM_GaussianBokehBlurOperation.h"
+#include "COM_SetValueOperation.h"
+
+#include "COM_DilateErodeOperation.h"
+
+#include "COM_SetAlphaOperation.h"
+
+KeyingNode::KeyingNode(bNode *editorNode): Node(editorNode)
+{
+}
+
+OutputSocket *KeyingNode::setupPreBlur(ExecutionSystem *graph, InputSocket *inputImage, int size, OutputSocket **originalImage)
+{
+ ConvertRGBToYCCOperation *convertRGBToYCCOperation = new ConvertRGBToYCCOperation();
+ convertRGBToYCCOperation->setMode(0); /* ITU 601 */
+
+ inputImage->relinkConnections(convertRGBToYCCOperation->getInputSocket(0), 0, graph);
+ graph->addOperation(convertRGBToYCCOperation);
+
+ CombineChannelsOperation *combineOperation = new CombineChannelsOperation();
+ graph->addOperation(combineOperation);
+
+ for (int channel = 0; channel < 4; channel++) {
+ SeparateChannelOperation *separateOperation = new SeparateChannelOperation();
+ separateOperation->setChannel(channel);
+ addLink(graph, convertRGBToYCCOperation->getOutputSocket(0), separateOperation->getInputSocket(0));
+ graph->addOperation(separateOperation);
+
+ if (channel == 0 || channel == 3) {
+ addLink(graph, separateOperation->getOutputSocket(0), combineOperation->getInputSocket(channel));
+ }
+ else {
+ KeyingBlurOperation *blurOperation = new KeyingBlurOperation();
+
+ blurOperation->setSize(size);
+
+ addLink(graph, separateOperation->getOutputSocket(0), blurOperation->getInputSocket(0));
+ addLink(graph, blurOperation->getOutputSocket(0), combineOperation->getInputSocket(channel));
+ graph->addOperation(blurOperation);
+ }
+ }
+
+ ConvertYCCToRGBOperation *convertYCCToRGBOperation = new ConvertYCCToRGBOperation();
+ convertYCCToRGBOperation->setMode(0); /* ITU 601 */
+ addLink(graph, combineOperation->getOutputSocket(0), convertYCCToRGBOperation->getInputSocket(0));
+ graph->addOperation(convertYCCToRGBOperation);
+
+ *originalImage = convertRGBToYCCOperation->getInputSocket(0)->getConnection()->getFromSocket();
+
+ return convertYCCToRGBOperation->getOutputSocket(0);
+}
+
+OutputSocket *KeyingNode::setupPostBlur(ExecutionSystem *graph, OutputSocket *postBLurInput, int size)
+{
+ KeyingBlurOperation *blurOperation = new KeyingBlurOperation();
+
+ blurOperation->setSize(size);
+
+ addLink(graph, postBLurInput, blurOperation->getInputSocket(0));
+
+ graph->addOperation(blurOperation);
+
+ return blurOperation->getOutputSocket();
+}
+
+OutputSocket *KeyingNode::setupDilateErode(ExecutionSystem *graph, OutputSocket *dilateErodeInput, int distance)
+{
+ DilateStepOperation *dilateErodeOperation;
+
+ if (distance > 0) {
+ dilateErodeOperation = new DilateStepOperation();
+ dilateErodeOperation->setIterations(distance);
+ }
+ else {
+ dilateErodeOperation = new ErodeStepOperation();
+ dilateErodeOperation->setIterations(-distance);
+ }
+
+ addLink(graph, dilateErodeInput, dilateErodeOperation->getInputSocket(0));
+
+ graph->addOperation(dilateErodeOperation);
+
+ return dilateErodeOperation->getOutputSocket(0);
+}
+
+OutputSocket *KeyingNode::setupDespill(ExecutionSystem *graph, OutputSocket *despillInput, OutputSocket *inputScreen, float factor)
+{
+ KeyingDespillOperation *despillOperation = new KeyingDespillOperation();
+
+ despillOperation->setDespillFactor(factor);
+
+ addLink(graph, despillInput, despillOperation->getInputSocket(0));
+ addLink(graph, inputScreen, despillOperation->getInputSocket(1));
+
+ graph->addOperation(despillOperation);
+
+ return despillOperation->getOutputSocket(0);
+}
+
+OutputSocket *KeyingNode::setupClip(ExecutionSystem *graph, OutputSocket *clipInput, int kernelRadius, float kernelTolerance,
+ float clipBlack, float clipWhite, bool edgeMatte)
+{
+ KeyingClipOperation *clipOperation = new KeyingClipOperation();
+
+ clipOperation->setKernelRadius(kernelRadius);
+ clipOperation->setKernelTolerance(kernelTolerance);
+
+ clipOperation->setClipBlack(clipBlack);
+ clipOperation->setClipWhite(clipWhite);
+ clipOperation->setIsEdgeMatte(edgeMatte);
+
+ addLink(graph, clipInput, clipOperation->getInputSocket(0));
+
+ graph->addOperation(clipOperation);
+
+ return clipOperation->getOutputSocket(0);
+}
+
+void KeyingNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context)
+{
+ InputSocket *inputImage = this->getInputSocket(0);
+ InputSocket *inputScreen = this->getInputSocket(1);
+ OutputSocket *outputImage = this->getOutputSocket(0);
+ OutputSocket *outputMatte = this->getOutputSocket(1);
+ OutputSocket *outputEdges = this->getOutputSocket(2);
+ OutputSocket *postprocessedMatte, *postprocessedImage, *originalImage, *edgesMatte;
+
+ bNode *editorNode = this->getbNode();
+ NodeKeyingData *keying_data = (NodeKeyingData *) editorNode->storage;
+
+ /* keying operation */
+ KeyingOperation *keyingOperation = new KeyingOperation();
+
+ keyingOperation->setScreenBalance(keying_data->screen_balance);
+
+ inputScreen->relinkConnections(keyingOperation->getInputSocket(1), 1, graph);
+
+ if (keying_data->blur_pre) {
+ /* chroma preblur operation for input of keying operation */
+ OutputSocket *preBluredImage = setupPreBlur(graph, inputImage, keying_data->blur_pre, &originalImage);
+ addLink(graph, preBluredImage, keyingOperation->getInputSocket(0));
+ }
+ else {
+ inputImage->relinkConnections(keyingOperation->getInputSocket(0), 0, graph);
+ originalImage = keyingOperation->getInputSocket(0)->getConnection()->getFromSocket();
+ }
+
+ graph->addOperation(keyingOperation);
+
+ postprocessedMatte = keyingOperation->getOutputSocket();
+
+ if (keying_data->clip_black > 0.0f || keying_data->clip_white< 1.0f) {
+ postprocessedMatte = setupClip(graph, postprocessedMatte,
+ keying_data->edge_kernel_radius, keying_data->edge_kernel_tolerance,
+ keying_data->clip_black, keying_data->clip_white, false);
+ }
+
+ edgesMatte = setupClip(graph, postprocessedMatte,
+ keying_data->edge_kernel_radius, keying_data->edge_kernel_tolerance,
+ keying_data->clip_black, keying_data->clip_white, true);
+
+ /* apply blur on matte if needed */
+ if (keying_data->blur_post)
+ postprocessedMatte = setupPostBlur(graph, postprocessedMatte, keying_data->blur_post);
+
+ /* matte dilate/erode */
+ if (keying_data->dilate_distance != 0) {
+ postprocessedMatte = setupDilateErode(graph, postprocessedMatte, keying_data->dilate_distance);
+ }
+
+ /* set alpha channel to output image */
+ SetAlphaOperation *alphaOperation = new SetAlphaOperation();
+ addLink(graph, originalImage, alphaOperation->getInputSocket(0));
+ addLink(graph, postprocessedMatte, alphaOperation->getInputSocket(1));
+
+ postprocessedImage = alphaOperation->getOutputSocket();
+
+ /* despill output image */
+ if (keying_data->despill_factor > 0.0f) {
+ postprocessedImage = setupDespill(graph, postprocessedImage,
+ keyingOperation->getInputSocket(1)->getConnection()->getFromSocket(),
+ keying_data->despill_factor);
+ }
+
+ /* connect result to output sockets */
+ outputImage->relinkConnections(postprocessedImage);
+ outputMatte->relinkConnections(postprocessedMatte);
+ outputEdges->relinkConnections(edgesMatte);
+
+ graph->addOperation(alphaOperation);
+}
diff --git a/source/blender/compositor/nodes/COM_KeyingNode.h b/source/blender/compositor/nodes/COM_KeyingNode.h
new file mode 100644
index 00000000000..cc1d447c66e
--- /dev/null
+++ b/source/blender/compositor/nodes/COM_KeyingNode.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2012, Blender Foundation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor:
+ * Jeroen Bakker
+ * Monique Dewanchand
+ * Sergey Sharybin
+ */
+
+#include "COM_Node.h"
+
+/**
+ * @brief KeyingNode
+ * @ingroup Node
+ */
+class KeyingNode : public Node {
+protected:
+ OutputSocket *setupPreBlur(ExecutionSystem *graph, InputSocket *inputImage, int size, OutputSocket **originalImage);
+ OutputSocket *setupPostBlur(ExecutionSystem *graph, OutputSocket *postBLurInput, int size);
+ OutputSocket *setupDilateErode(ExecutionSystem *graph, OutputSocket *dilateErodeInput, int distance);
+ OutputSocket *setupDespill(ExecutionSystem *graph, OutputSocket *despillInput, OutputSocket *inputSrceen, float factor);
+ OutputSocket *setupClip(ExecutionSystem *graph, OutputSocket *clipInput, int kernelRadius, float kernelTolerance,
+ float clipBlack, float clipWhite, bool edgeMatte);
+public:
+ KeyingNode(bNode *editorNode);
+ void convertToOperations(ExecutionSystem *graph, CompositorContext *context);
+
+};
diff --git a/source/blender/compositor/operations/COM_KeyingBlurOperation.cpp b/source/blender/compositor/operations/COM_KeyingBlurOperation.cpp
new file mode 100644
index 00000000000..3ed3921e0c1
--- /dev/null
+++ b/source/blender/compositor/operations/COM_KeyingBlurOperation.cpp
@@ -0,0 +1,88 @@
+/*
+ * Copyright 2012, Blender Foundation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor:
+ * Jeroen Bakker
+ * Monique Dewanchand
+ * Sergey Sharybin
+ */
+
+#include "COM_KeyingBlurOperation.h"
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_listbase.h"
+#include "BLI_math.h"
+
+KeyingBlurOperation::KeyingBlurOperation(): NodeOperation()
+{
+ this->addInputSocket(COM_DT_VALUE);
+ this->addOutputSocket(COM_DT_VALUE);
+
+ this->size = 0.0f;
+
+ this->setComplex(true);
+}
+
+void *KeyingBlurOperation::initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers)
+{
+ void *buffer = getInputOperation(0)->initializeTileData(rect, memoryBuffers);
+
+ return buffer;
+}
+
+void KeyingBlurOperation::executePixel(float *color, int x, int y, MemoryBuffer *inputBuffers[], void *data)
+{
+ MemoryBuffer *inputBuffer = (MemoryBuffer*)data;
+ float *buffer = inputBuffer->getBuffer();
+
+ int bufferWidth = inputBuffer->getWidth();
+ int bufferHeight = inputBuffer->getHeight();
+
+ int i, j, count = 0;
+
+ float average = 0.0f;
+
+ for (i = -this->size + 1; i < this->size; i++) {
+ for (j = -this->size + 1; j < this->size; j++) {
+ int cx = x + j, cy = y + i;
+
+ if (cx >= 0 && cx < bufferWidth && cy >= 0 && cy < bufferHeight) {
+ int bufferIndex = (cy * bufferWidth + cx) * 4;
+
+ average += buffer[bufferIndex];
+ count++;
+ }
+ }
+ }
+
+ average /= (float) count;
+
+ color[0] = average;
+}
+
+bool KeyingBlurOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output)
+{
+ rcti newInput;
+
+ newInput.xmin = 0;
+ newInput.ymin = 0;
+ newInput.xmax = this->getWidth();
+ newInput.ymax = this->getHeight();
+
+ return NodeOperation::determineDependingAreaOfInterest(&newInput, readOperation, output);
+}
diff --git a/source/blender/compositor/operations/COM_KeyingBlurOperation.h b/source/blender/compositor/operations/COM_KeyingBlurOperation.h
new file mode 100644
index 00000000000..8d7834c7265
--- /dev/null
+++ b/source/blender/compositor/operations/COM_KeyingBlurOperation.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2012, Blender Foundation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor:
+ * Jeroen Bakker
+ * Monique Dewanchand
+ * Sergey Sharybin
+ */
+
+#ifndef _COM_KeyingBlurOperation_h
+#define _COM_KeyingBlurOperation_h
+
+#include "COM_NodeOperation.h"
+
+/**
+ * Class with implementation of bluring for keying node
+ */
+class KeyingBlurOperation : public NodeOperation {
+protected:
+ int size;
+
+public:
+ KeyingBlurOperation();
+
+ void setSize(float value) {this->size = value;}
+
+ void *initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers);
+
+ void executePixel(float *color, int x, int y, MemoryBuffer *inputBuffers[], void *data);
+
+ bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output);
+};
+
+#endif
diff --git a/source/blender/compositor/operations/COM_KeyingClipOperation.cpp b/source/blender/compositor/operations/COM_KeyingClipOperation.cpp
new file mode 100644
index 00000000000..09b5b7a523c
--- /dev/null
+++ b/source/blender/compositor/operations/COM_KeyingClipOperation.cpp
@@ -0,0 +1,123 @@
+/*
+ * Copyright 2012, Blender Foundation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor:
+ * Jeroen Bakker
+ * Monique Dewanchand
+ * Sergey Sharybin
+ */
+
+#include "COM_KeyingClipOperation.h"
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_listbase.h"
+#include "BLI_math.h"
+
+KeyingClipOperation::KeyingClipOperation(): NodeOperation()
+{
+ this->addInputSocket(COM_DT_VALUE);
+ this->addOutputSocket(COM_DT_VALUE);
+
+ this->kernelRadius = 3;
+ this->kernelTolerance = 0.1f;
+
+ this->clipBlack = 0.0f;
+ this->clipWhite = 1.0f;
+
+ this->isEdgeMatte = false;
+
+ this->setComplex(true);
+}
+
+void *KeyingClipOperation::initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers)
+{
+ void *buffer = getInputOperation(0)->initializeTileData(rect, memoryBuffers);
+
+ return buffer;
+}
+
+void KeyingClipOperation::executePixel(float *color, int x, int y, MemoryBuffer *inputBuffers[], void *data)
+{
+ const int delta = this->kernelRadius;
+ const float tolerance = this->kernelTolerance;
+
+ MemoryBuffer *inputBuffer = (MemoryBuffer*)data;
+ float *buffer = inputBuffer->getBuffer();
+
+ int bufferWidth = inputBuffer->getWidth();
+ int bufferHeight = inputBuffer->getHeight();
+
+ int i, j, count = 0, totalCount = 0;
+
+ float value = buffer[(y * bufferWidth + x) * 4];
+
+ bool ok = false;
+
+ for (i = -delta + 1; i < delta; i++) {
+ for (j = -delta + 1; j < delta; j++) {
+ int cx = x + j, cy = y + i;
+
+ if (i == 0 && j == 0)
+ continue;
+
+ if (cx >= 0 && cx < bufferWidth && cy >= 0 && cy < bufferHeight) {
+ int bufferIndex = (cy * bufferWidth + cx) * 4;
+ float currentValue = buffer[bufferIndex];
+
+ if (fabsf(currentValue - value) < tolerance) {
+ count++;
+ }
+
+ totalCount++;
+ }
+ }
+ }
+
+ ok = count >= (float) totalCount * 0.9f;
+
+ if (this->isEdgeMatte) {
+ if (ok)
+ color[0] = 0.0f;
+ else
+ color[0] = 1.0f;
+ }
+ else {
+ color[0] = value;
+
+ if (ok) {
+ if (color[0] < this->clipBlack)
+ color[0] = 0.0f;
+ else if (color[0] >= this->clipWhite)
+ color[0] = 1.0f;
+ else
+ color[0] = (color[0] - this->clipBlack) / (this->clipWhite - this->clipBlack);
+ }
+ }
+}
+
+bool KeyingClipOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output)
+{
+ rcti newInput;
+
+ newInput.xmin = 0;
+ newInput.ymin = 0;
+ newInput.xmax = this->getWidth();
+ newInput.ymax = this->getHeight();
+
+ return NodeOperation::determineDependingAreaOfInterest(&newInput, readOperation, output);
+}
diff --git a/source/blender/compositor/operations/COM_KeyingClipOperation.h b/source/blender/compositor/operations/COM_KeyingClipOperation.h
new file mode 100644
index 00000000000..9c7b23b0160
--- /dev/null
+++ b/source/blender/compositor/operations/COM_KeyingClipOperation.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2012, Blender Foundation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor:
+ * Jeroen Bakker
+ * Monique Dewanchand
+ * Sergey Sharybin
+ */
+
+#ifndef _COM_KeyingClipOperation_h
+#define _COM_KeyingClipOperation_h
+
+#include "COM_NodeOperation.h"
+
+/**
+ * Class with implementation of black/white clipping for keying node
+ */
+class KeyingClipOperation : public NodeOperation {
+protected:
+ float clipBlack;
+ float clipWhite;
+
+ int kernelRadius;
+ float kernelTolerance;
+
+ bool isEdgeMatte;
+public:
+ KeyingClipOperation();
+
+ void setClipBlack(float value) {this->clipBlack = value;}
+ void setClipWhite(float value) {this->clipWhite = value;}
+
+ void setKernelRadius(int value) {this->kernelRadius = value;}
+ void setKernelTolerance(float value) {this->kernelTolerance = value;}
+
+ void setIsEdgeMatte(bool value) {this->isEdgeMatte = value;}
+
+ void *initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers);
+
+ void executePixel(float *color, int x, int y, MemoryBuffer *inputBuffers[], void *data);
+
+ bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output);
+};
+
+#endif
diff --git a/source/blender/compositor/operations/COM_KeyingDespillOperation.cpp b/source/blender/compositor/operations/COM_KeyingDespillOperation.cpp
new file mode 100644
index 00000000000..b7fd2772729
--- /dev/null
+++ b/source/blender/compositor/operations/COM_KeyingDespillOperation.cpp
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2012, Blender Foundation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor:
+ * Jeroen Bakker
+ * Monique Dewanchand
+ * Sergey Sharybin
+ */
+
+#include "COM_KeyingDespillOperation.h"
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_listbase.h"
+#include "BLI_math.h"
+
+static int get_pixel_primary_channel(float *pixel)
+{
+ float max_value = MAX3(pixel[0], pixel[1], pixel[2]);
+
+ if (max_value == pixel[0])
+ return 0;
+ else if (max_value == pixel[1])
+ return 1;
+
+ return 2;
+}
+
+KeyingDespillOperation::KeyingDespillOperation(): NodeOperation()
+{
+ this->addInputSocket(COM_DT_COLOR);
+ this->addInputSocket(COM_DT_COLOR);
+ this->addOutputSocket(COM_DT_COLOR);
+
+ this->despillFactor = 0.5f;
+
+ this->pixelReader = NULL;
+ this->screenReader = NULL;
+}
+
+void KeyingDespillOperation::initExecution()
+{
+ this->pixelReader = this->getInputSocketReader(0);
+ this->screenReader = this->getInputSocketReader(1);
+}
+
+void KeyingDespillOperation::deinitExecution()
+{
+ this->pixelReader = NULL;
+ this->screenReader = NULL;
+}
+
+void KeyingDespillOperation::executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[])
+{
+ float pixelColor[4];
+ float screenColor[4];
+
+ this->pixelReader->read(pixelColor, x, y, sampler, inputBuffers);
+ this->screenReader->read(screenColor, x, y, sampler, inputBuffers);
+
+ int screen_primary_channel = get_pixel_primary_channel(screenColor);
+ float average_value, amount;
+
+ average_value = (pixelColor[0] + pixelColor[1] + pixelColor[2] - pixelColor[screen_primary_channel]) / 2.0f;
+ amount = pixelColor[screen_primary_channel] - average_value;
+
+ color[0] = pixelColor[0];
+ color[1] = pixelColor[1];
+ color[2] = pixelColor[2];
+ color[3] = pixelColor[3];
+
+ if (this->despillFactor * amount > 0) {
+ color[screen_primary_channel] = pixelColor[screen_primary_channel] - this->despillFactor * amount;
+ }
+}
diff --git a/source/blender/compositor/operations/COM_KeyingDespillOperation.h b/source/blender/compositor/operations/COM_KeyingDespillOperation.h
new file mode 100644
index 00000000000..92a1415a1f0
--- /dev/null
+++ b/source/blender/compositor/operations/COM_KeyingDespillOperation.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2012, Blender Foundation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor:
+ * Jeroen Bakker
+ * Monique Dewanchand
+ * Sergey Sharybin
+ */
+
+#ifndef _COM_KeyingDespillOperation_h
+#define _COM_KeyingDespillOperation_h
+
+#include "COM_NodeOperation.h"
+
+/**
+ * Class with implementation of keying despill node
+ */
+class KeyingDespillOperation : public NodeOperation {
+protected:
+ SocketReader *pixelReader;
+ SocketReader *screenReader;
+ float despillFactor;
+
+public:
+ KeyingDespillOperation();
+
+ void initExecution();
+ void deinitExecution();
+
+ void setDespillFactor(float value) {this->despillFactor = value;}
+
+ void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]);
+};
+
+#endif
diff --git a/source/blender/compositor/operations/COM_KeyingOperation.cpp b/source/blender/compositor/operations/COM_KeyingOperation.cpp
new file mode 100644
index 00000000000..fba4dc65faf
--- /dev/null
+++ b/source/blender/compositor/operations/COM_KeyingOperation.cpp
@@ -0,0 +1,115 @@
+/*
+ * Copyright 2012, Blender Foundation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor:
+ * Jeroen Bakker
+ * Monique Dewanchand
+ * Sergey Sharybin
+ */
+
+#include "COM_KeyingOperation.h"
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_listbase.h"
+#include "BLI_math.h"
+
+static int get_pixel_primary_channel(float pixelColor[4])
+{
+ float max_value = MAX3(pixelColor[0], pixelColor[1], pixelColor[2]);
+
+ if (max_value == pixelColor[0])
+ return 0;
+ else if (max_value == pixelColor[1])
+ return 1;
+
+ return 2;
+}
+
+static float get_pixel_saturation(float pixelColor[4], float screen_balance, int primary_channel)
+{
+ int other_1 = (primary_channel + 1) % 3;
+ int other_2 = (primary_channel + 2) % 3;
+
+ float min = MIN2(pixelColor[other_1], pixelColor[other_2]);
+ float max = MAX2(pixelColor[other_1], pixelColor[other_2]);
+ float val = screen_balance * min + (1.0f - screen_balance) * max;
+
+ return (pixelColor[primary_channel] - val) * fabsf(1.0f - val);
+}
+
+KeyingOperation::KeyingOperation(): NodeOperation()
+{
+ this->addInputSocket(COM_DT_COLOR);
+ this->addInputSocket(COM_DT_COLOR);
+ this->addOutputSocket(COM_DT_VALUE);
+
+ this->screenBalance = 0.5f;
+
+ this->pixelReader = NULL;
+ this->screenReader = NULL;
+}
+
+void KeyingOperation::initExecution()
+{
+ this->pixelReader = this->getInputSocketReader(0);
+ this->screenReader = this->getInputSocketReader(1);
+}
+
+void KeyingOperation::deinitExecution()
+{
+ this->pixelReader = NULL;
+ this->screenReader = NULL;
+}
+
+void KeyingOperation::executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[])
+{
+ float pixelColor[4];
+ float screenColor[4];
+
+ this->pixelReader->read(pixelColor, x, y, sampler, inputBuffers);
+ this->screenReader->read(screenColor, x, y, sampler, inputBuffers);
+
+ int primary_channel = get_pixel_primary_channel(screenColor);
+
+ float saturation = get_pixel_saturation(pixelColor, this->screenBalance, primary_channel);
+ float screen_saturation = get_pixel_saturation(screenColor, this->screenBalance, primary_channel);
+
+ if (saturation < 0) {
+ color[0] = 1.0f;
+ }
+ else if (saturation >= screen_saturation) {
+ color[0] = 0.0f;
+ }
+ else {
+ float distance = 1.0f - saturation / screen_saturation;
+
+ color[0] = distance;
+ }
+}
+
+bool KeyingOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output)
+{
+ rcti newInput;
+
+ newInput.xmin = 0;
+ newInput.ymin = 0;
+ newInput.xmax = this->getWidth();
+ newInput.ymax = this->getHeight();
+
+ return NodeOperation::determineDependingAreaOfInterest(&newInput, readOperation, output);
+}
diff --git a/source/blender/compositor/operations/COM_KeyingOperation.h b/source/blender/compositor/operations/COM_KeyingOperation.h
new file mode 100644
index 00000000000..0fc13407d14
--- /dev/null
+++ b/source/blender/compositor/operations/COM_KeyingOperation.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2012, Blender Foundation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor:
+ * Jeroen Bakker
+ * Monique Dewanchand
+ * Sergey Sharybin
+ */
+
+
+#ifndef _COM_KeyingOperation_h
+#define _COM_KeyingOperation_h
+
+#include <string.h>
+
+#include "COM_NodeOperation.h"
+
+#include "BLI_listbase.h"
+
+/**
+ * Class with implementation of keying node
+ */
+class KeyingOperation : public NodeOperation {
+protected:
+ SocketReader *pixelReader;
+ SocketReader *screenReader;
+ float screenBalance;
+
+public:
+ KeyingOperation();
+
+ void initExecution();
+ void deinitExecution();
+
+ void setScreenBalance(float value) {this->screenBalance = value;}
+
+ void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]);
+
+ bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output);
+};
+
+#endif
diff --git a/source/blender/editors/space_clip/clip_dopesheet_ops.c b/source/blender/editors/space_clip/clip_dopesheet_ops.c
index 744c7ba46fd..6576d2aeb01 100644
--- a/source/blender/editors/space_clip/clip_dopesheet_ops.c
+++ b/source/blender/editors/space_clip/clip_dopesheet_ops.c
@@ -59,6 +59,23 @@
#include "clip_intern.h" // own include
+#if 0
+static int ED_space_clip_dopesheet_poll(bContext *C)
+{
+ SpaceClip *sc = CTX_wm_space_clip(C);
+
+ if (sc && sc->clip) {
+ if (sc->view == SC_VIEW_DOPESHEET) {
+ ARegion *ar = CTX_wm_region(C);
+
+ return ar->regiontype == RGN_TYPE_PREVIEW;
+ }
+ }
+
+ return FALSE;
+}
+#endif
+
/********************** select channel operator *********************/
static int dopesheet_select_channel_poll(bContext *C)
diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c
index a42bf062b12..033bfd165c2 100644
--- a/source/blender/editors/space_node/drawnode.c
+++ b/source/blender/editors/space_node/drawnode.c
@@ -2443,6 +2443,21 @@ static void node_composit_buts_keyingscreen(uiLayout *layout, bContext *C, Point
}
}
+static void node_composit_buts_keying(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+{
+ /* bNode *node= ptr->data; */ /* UNUSED */
+
+ uiItemR(layout, ptr, "blur_pre", 0, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "screen_balance", 0, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "despill_factor", 0, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "edge_kernel_radius", 0, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "edge_kernel_tolerance", 0, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "clip_black", 0, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "clip_white", 0, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "dilate_distance", 0, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "blur_post", 0, NULL, ICON_NONE);
+}
+
/* only once called */
static void node_composit_set_butfunc(bNodeType *ntype)
{
@@ -2638,6 +2653,9 @@ static void node_composit_set_butfunc(bNodeType *ntype)
case CMP_NODE_KEYINGSCREEN:
ntype->uifunc = node_composit_buts_keyingscreen;
break;
+ case CMP_NODE_KEYING:
+ ntype->uifunc = node_composit_buts_keying;
+ break;
default:
ntype->uifunc = NULL;
}
diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h
index a81d3f5b6cd..a10d610c6d4 100644
--- a/source/blender/makesdna/DNA_node_types.h
+++ b/source/blender/makesdna/DNA_node_types.h
@@ -632,6 +632,16 @@ typedef struct NodeKeyingScreenData {
char tracking_object[64];
} NodeKeyingScreenData;
+typedef struct NodeKeyingData {
+ float screen_balance;
+ float despill_factor;
+ int edge_kernel_radius;
+ float edge_kernel_tolerance;
+ float clip_black, clip_white;
+ int dilate_distance;
+ int blur_pre, blur_post;
+} NodeKeyingData;
+
/* frame node flags */
#define NODE_FRAME_SHRINK 1 /* keep the bounding box minimal */
#define NODE_FRAME_RESIZEABLE 2 /* test flag, if frame can be resized by user */
diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c
index b43fca26748..509e20949c2 100644
--- a/source/blender/makesrna/intern/rna_nodetree.c
+++ b/source/blender/makesrna/intern/rna_nodetree.c
@@ -3101,25 +3101,6 @@ static void def_cmp_mask(StructRNA *srna)
RNA_def_property_ui_text(prop, "Mask", "");
}
-static void def_cmp_keyingscreen(StructRNA *srna)
-{
- PropertyRNA *prop;
-
- prop = RNA_def_property(srna, "clip", PROP_POINTER, PROP_NONE);
- RNA_def_property_pointer_sdna(prop, NULL, "id");
- RNA_def_property_struct_type(prop, "MovieClip");
- RNA_def_property_flag(prop, PROP_EDITABLE);
- RNA_def_property_ui_text(prop, "Movie Clip", "");
- RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_update");
-
- RNA_def_struct_sdna_from(srna, "NodeKeyingScreenData", "storage");
-
- prop = RNA_def_property(srna, "tracking_object", PROP_STRING, PROP_NONE);
- RNA_def_property_string_sdna(prop, NULL, "tracking_object");
- RNA_def_property_ui_text(prop, "Tracking Object", "");
- RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_update");
-}
-
static void dev_cmd_transform(StructRNA *srna)
{
PropertyRNA *prop;
@@ -3526,6 +3507,85 @@ static void def_cmp_viewer(StructRNA *srna)
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
}
+static void def_cmp_keyingscreen(StructRNA *srna)
+{
+ PropertyRNA *prop;
+
+ prop = RNA_def_property(srna, "clip", PROP_POINTER, PROP_NONE);
+ RNA_def_property_pointer_sdna(prop, NULL, "id");
+ RNA_def_property_struct_type(prop, "MovieClip");
+ RNA_def_property_flag(prop, PROP_EDITABLE);
+ RNA_def_property_ui_text(prop, "Movie Clip", "");
+ RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_update");
+
+ RNA_def_struct_sdna_from(srna, "NodeKeyingScreenData", "storage");
+
+ prop = RNA_def_property(srna, "tracking_object", PROP_STRING, PROP_NONE);
+ RNA_def_property_string_sdna(prop, NULL, "tracking_object");
+ RNA_def_property_ui_text(prop, "Tracking Object", "");
+ RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_update");
+}
+
+static void def_cmp_keying(StructRNA *srna)
+{
+ PropertyRNA *prop;
+
+ RNA_def_struct_sdna_from(srna, "NodeKeyingData", "storage");
+
+ prop = RNA_def_property(srna, "screen_balance", PROP_FLOAT, PROP_FACTOR);
+ RNA_def_property_float_sdna(prop, NULL, "screen_balance");
+ RNA_def_property_range(prop, 0.0f, 1.0f);
+ RNA_def_property_ui_text(prop, "Screen Balance", "Balance between two non-primary channels primary channel is comparing against");
+ RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_update");
+
+ prop = RNA_def_property(srna, "despill_factor", PROP_FLOAT, PROP_FACTOR);
+ RNA_def_property_float_sdna(prop, NULL, "despill_factor");
+ RNA_def_property_range(prop, 0.0f, 1.0f);
+ RNA_def_property_ui_text(prop, "Despill", "Factor of despilling screen color from image");
+ RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_update");
+
+ prop = RNA_def_property(srna, "clip_black", PROP_FLOAT, PROP_FACTOR);
+ RNA_def_property_float_sdna(prop, NULL, "clip_black");
+ RNA_def_property_range(prop, 0.0f, 1.0f);
+ RNA_def_property_ui_text(prop, "Clip Black", "Value of on-scaled matte pixel which considers as fully background pixel");
+ RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_update");
+
+ prop = RNA_def_property(srna, "clip_white", PROP_FLOAT, PROP_FACTOR);
+ RNA_def_property_float_sdna(prop, NULL, "clip_white");
+ RNA_def_property_range(prop, 0.0f, 1.0f);
+ RNA_def_property_ui_text(prop, "Clip White", "Value of on-scaled matte pixel which considers as fully foreground pixel");
+ RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_update");
+
+ prop = RNA_def_property(srna, "blur_pre", PROP_INT, PROP_NONE);
+ RNA_def_property_int_sdna(prop, NULL, "blur_pre");
+ RNA_def_property_range(prop, 0, 2048);
+ RNA_def_property_ui_text(prop, "Pre Blur", "Chroma pre-blur size which applies before running keyer");
+ RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_update");
+
+ prop = RNA_def_property(srna, "blur_post", PROP_INT, PROP_NONE);
+ RNA_def_property_int_sdna(prop, NULL, "blur_post");
+ RNA_def_property_range(prop, 0, 2048);
+ RNA_def_property_ui_text(prop, "Post Blur", "Matte blur size which applies after clipping and dilate/eroding");
+ RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_update");
+
+ prop = RNA_def_property(srna, "dilate_distance", PROP_INT, PROP_NONE);
+ RNA_def_property_int_sdna(prop, NULL, "dilate_distance");
+ RNA_def_property_range(prop, -100, 100);
+ RNA_def_property_ui_text(prop, "Dilate/Erode", "Matte dilate/erode side");
+ RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_update");
+
+ prop = RNA_def_property(srna, "edge_kernel_radius", PROP_INT, PROP_NONE);
+ RNA_def_property_int_sdna(prop, NULL, "edge_kernel_radius");
+ RNA_def_property_range(prop, -100, 100);
+ RNA_def_property_ui_text(prop, "Edge Kernel Radius", "Radius of kernel used to detect whether pixel belongs to edge");
+ RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_update");
+
+ prop = RNA_def_property(srna, "edge_kernel_tolerance", PROP_FLOAT, PROP_FACTOR);
+ RNA_def_property_float_sdna(prop, NULL, "edge_kernel_tolerance");
+ RNA_def_property_range(prop, 0.0f, 1.0f);
+ RNA_def_property_ui_text(prop, "Edge Kernel Tolerance", "Tolerance to pixels inside kernel which are treating as belonging to the same plane");
+ RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_update");
+}
/* -- Texture Nodes --------------------------------------------------------- */
diff --git a/source/blender/makesrna/intern/rna_nodetree_types.h b/source/blender/makesrna/intern/rna_nodetree_types.h
index 98170cc4d67..62c3051727d 100644
--- a/source/blender/makesrna/intern/rna_nodetree_types.h
+++ b/source/blender/makesrna/intern/rna_nodetree_types.h
@@ -169,6 +169,7 @@ DefNode( CompositorNode, CMP_NODE_SWITCH, def_cmp_switch, "SWITC
DefNode( CompositorNode, CMP_NODE_COLORCORRECTION,def_cmp_colorcorrection,"COLORCORRECTION",ColorCorrection, "ColorCorrection", "" )
DefNode( CompositorNode, CMP_NODE_MASK, def_cmp_mask, "MASK", Mask, "Mask", "" )
DefNode( CompositorNode, CMP_NODE_KEYINGSCREEN, def_cmp_keyingscreen, "KEYINGSCREEN", KeyingScreen, "KeyingScreen", "" )
+DefNode( CompositorNode, CMP_NODE_KEYING, def_cmp_keying, "KEYING", Keying, "Keying", "" )
DefNode( TextureNode, TEX_NODE_OUTPUT, def_tex_output, "OUTPUT", Output, "Output", "" )
DefNode( TextureNode, TEX_NODE_CHECKER, 0, "CHECKER", Checker, "Checker", "" )
diff --git a/source/blender/nodes/CMakeLists.txt b/source/blender/nodes/CMakeLists.txt
index 7b0feab2bc1..2415c7842a7 100644
--- a/source/blender/nodes/CMakeLists.txt
+++ b/source/blender/nodes/CMakeLists.txt
@@ -77,6 +77,7 @@ set(SRC
composite/nodes/node_composite_image.c
composite/nodes/node_composite_invert.c
composite/nodes/node_composite_keyingscreen.c
+ composite/nodes/node_composite_keying.c
composite/nodes/node_composite_lensdist.c
composite/nodes/node_composite_levels.c
composite/nodes/node_composite_lummaMatte.c
diff --git a/source/blender/nodes/NOD_composite.h b/source/blender/nodes/NOD_composite.h
index fd4918a32b5..33d6327ece1 100644
--- a/source/blender/nodes/NOD_composite.h
+++ b/source/blender/nodes/NOD_composite.h
@@ -106,6 +106,7 @@ void register_node_type_cmp_color_spill(struct bNodeTreeType *ttype);
void register_node_type_cmp_luma_matte(struct bNodeTreeType *ttype);
void register_node_type_cmp_doubleedgemask(struct bNodeTreeType *ttype);
void register_node_type_cmp_keyingscreen(struct bNodeTreeType *ttype);
+void register_node_type_cmp_keying(struct bNodeTreeType *ttype);
void register_node_type_cmp_translate(struct bNodeTreeType *ttype);
void register_node_type_cmp_rotate(struct bNodeTreeType *ttype);
diff --git a/source/blender/nodes/composite/nodes/node_composite_keying.c b/source/blender/nodes/composite/nodes/node_composite_keying.c
new file mode 100644
index 00000000000..e5bf3b7ae62
--- /dev/null
+++ b/source/blender/nodes/composite/nodes/node_composite_keying.c
@@ -0,0 +1,94 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2011 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Blender Foundation,
+ * Sergey Sharybin
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/nodes/composite/nodes/node_composite_keying.c
+ * \ingroup cmpnodes
+ */
+
+#include "BLF_translation.h"
+
+#include "DNA_movieclip_types.h"
+
+#include "BKE_movieclip.h"
+
+#include "BLI_listbase.h"
+#include "BLI_math_base.h"
+#include "BLI_math_color.h"
+#include "BLI_voronoi.h"
+
+#include "node_composite_util.h"
+
+/* **************** Translate ******************** */
+
+static bNodeSocketTemplate cmp_node_keying_in[] = {
+ { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f},
+ { SOCK_RGBA, 1, "Key Color", 1.0f, 1.0f, 1.0f, 1.0f},
+ { -1, 0, "" }
+};
+
+static bNodeSocketTemplate cmp_node_keying_out[] = {
+ { SOCK_RGBA, 0, "Image"},
+ { SOCK_FLOAT, 0, "Matte"},
+ { SOCK_FLOAT, 0, "Edges"},
+ { -1, 0, "" }
+};
+
+static void exec(void *UNUSED(data), bNode *UNUSED(node), bNodeStack **UNUSED(in), bNodeStack **UNUSED(out))
+{
+}
+
+static void node_composit_init_keying(bNodeTree *UNUSED(ntree), bNode* node, bNodeTemplate *UNUSED(ntemp))
+{
+ NodeKeyingData *data;
+
+ data = MEM_callocN(sizeof(NodeKeyingData), "node keying data");
+
+ data->screen_balance = 0.5f;
+ data->despill_factor = 1.0f;
+ data->edge_kernel_radius = 3;
+ data->edge_kernel_tolerance = 0.1f;
+ data->clip_white = 1.0f;
+ data->clip_black = 0.0f;
+ data->clip_white = 1.0f;
+
+ node->storage = data;
+}
+
+void register_node_type_cmp_keying(bNodeTreeType *ttype)
+{
+ static bNodeType ntype;
+
+ node_type_base(ttype, &ntype, CMP_NODE_KEYING, "Keying", NODE_CLASS_MATTE, NODE_OPTIONS);
+ node_type_socket_templates(&ntype, cmp_node_keying_in, cmp_node_keying_out);
+ node_type_size(&ntype, 140, 100, 320);
+ node_type_init(&ntype, node_composit_init_keying);
+ node_type_storage(&ntype, "NodeKeyingData", node_free_standard_storage, node_copy_standard_storage);
+ node_type_exec(&ntype, exec);
+
+ nodeRegisterType(ttype, &ntype);
+}