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:
Diffstat (limited to 'source/blender/compositor/nodes')
-rw-r--r--source/blender/compositor/nodes/COM_KeyingNode.cpp227
-rw-r--r--source/blender/compositor/nodes/COM_KeyingNode.h42
2 files changed, 269 insertions, 0 deletions
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);
+
+};