diff options
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); +} |