diff options
author | Sergey Sharybin <sergey.vfx@gmail.com> | 2012-06-14 16:18:42 +0400 |
---|---|---|
committer | Sergey Sharybin <sergey.vfx@gmail.com> | 2012-06-14 16:18:42 +0400 |
commit | d56e77ada59050d02a03b44e9d5a7b122683615f (patch) | |
tree | 0c8fbdad67b170eb7c2d9abb360657ee05181c1e /source/blender/compositor | |
parent | e2cda811ac2b8bd054afe2d7e0a0c760de96080c (diff) |
Keying Screen node from tomato branch
Merge Keying Screen node developed in tomato branch into trunk.
This node is aimed to make dealing with non-even greenscreens better
by generating gradiented image which could be used a input for keyer
nodes.
Based on building voronoi diagram using motion tracking markers as
sites position and average pattern color as color for that site.
Pretty straignforward node, some documentation is there
http://wiki.blender.org/index.php/User:Nazg-gul/Keying#Screen_color
Diffstat (limited to 'source/blender/compositor')
6 files changed, 403 insertions, 0 deletions
diff --git a/source/blender/compositor/CMakeLists.txt b/source/blender/compositor/CMakeLists.txt index aa428c2b8d0..cfaf11c4400 100644 --- a/source/blender/compositor/CMakeLists.txt +++ b/source/blender/compositor/CMakeLists.txt @@ -323,6 +323,13 @@ set(SRC operations/COM_DoubleEdgeMaskOperation.cpp operations/COM_DoubleEdgeMaskOperation.h + + + nodes/COM_KeyingScreenNode.cpp + nodes/COM_KeyingScreenNode.h + operations/COM_KeyingScreenOperation.cpp + operations/COM_KeyingScreenOperation.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 f4bb89969ff..082e2fe5d04 100644 --- a/source/blender/compositor/intern/COM_Converter.cpp +++ b/source/blender/compositor/intern/COM_Converter.cpp @@ -112,6 +112,7 @@ #include "COM_DoubleEdgeMaskNode.h" #include "COM_CropNode.h" #include "COM_MaskNode.h" +#include "COM_KeyingScreenNode.h" Node *Converter::convert(bNode *bNode) { @@ -351,6 +352,9 @@ case CMP_NODE_OUTPUT_FILE: case CMP_NODE_MASK: node = new MaskNode(bNode); break; + case CMP_NODE_KEYINGSCREEN: + node = new KeyingScreenNode(bNode); + break; /* not inplemented yet */ default: node = new MuteNode(bNode); diff --git a/source/blender/compositor/nodes/COM_KeyingScreenNode.cpp b/source/blender/compositor/nodes/COM_KeyingScreenNode.cpp new file mode 100644 index 00000000000..ad58adae48b --- /dev/null +++ b/source/blender/compositor/nodes/COM_KeyingScreenNode.cpp @@ -0,0 +1,57 @@ +/* + * 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_KeyingScreenNode.h" +#include "COM_ExecutionSystem.h" +#include "COM_KeyingScreenOperation.h" + +extern "C" { + #include "DNA_movieclip_types.h" +} + +KeyingScreenNode::KeyingScreenNode(bNode *editorNode): Node(editorNode) +{ +} + +void KeyingScreenNode::convertToOperations(ExecutionSystem *graph, CompositorContext * context) +{ + OutputSocket *outputScreen = this->getOutputSocket(0); + + bNode *editorNode = this->getbNode(); + MovieClip *clip = (MovieClip *) editorNode->id; + + NodeKeyingScreenData *keyingscreen_data = (NodeKeyingScreenData *) editorNode->storage; + + // always connect the output image + KeyingScreenOperation *operation = new KeyingScreenOperation(); + + if (outputScreen->isConnected()) { + outputScreen->relinkConnections(operation->getOutputSocket()); + } + + operation->setMovieClip(clip); + operation->setTrackingObject(keyingscreen_data->tracking_object); + operation->setFramenumber(context->getFramenumber()); + + graph->addOperation(operation); +} diff --git a/source/blender/compositor/nodes/COM_KeyingScreenNode.h b/source/blender/compositor/nodes/COM_KeyingScreenNode.h new file mode 100644 index 00000000000..7c87219ef6e --- /dev/null +++ b/source/blender/compositor/nodes/COM_KeyingScreenNode.h @@ -0,0 +1,36 @@ +/* + * 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" +#include "DNA_node_types.h" + +/** + * @brief KeyingScreenNode + * @ingroup Node + */ +class KeyingScreenNode : public Node { +public: + KeyingScreenNode(bNode *editorNode); + void convertToOperations(ExecutionSystem *graph, CompositorContext *context); + +}; diff --git a/source/blender/compositor/operations/COM_KeyingScreenOperation.cpp b/source/blender/compositor/operations/COM_KeyingScreenOperation.cpp new file mode 100644 index 00000000000..757afe7b394 --- /dev/null +++ b/source/blender/compositor/operations/COM_KeyingScreenOperation.cpp @@ -0,0 +1,220 @@ +/* + * 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_KeyingScreenOperation.h" + +#include "MEM_guardedalloc.h" + +#include "BLI_listbase.h" +#include "BLI_math.h" +#include "BLI_math_color.h" + +#include "DNA_scene_types.h" + +extern "C" { + #include "BKE_movieclip.h" + #include "BKE_tracking.h" + + #include "IMB_imbuf.h" + #include "IMB_imbuf_types.h" +} + +KeyingScreenOperation::KeyingScreenOperation(): NodeOperation() +{ + this->addOutputSocket(COM_DT_COLOR); + this->movieClip = NULL; + this->framenumber = 0; + this->trackingObject[0] = 0; + setComplex(true); +} + +void KeyingScreenOperation::initExecution() +{ + initMutex(); + this->cachedTriangulation = NULL; +} + +void KeyingScreenOperation::deinitExecution() +{ + if (this->cachedTriangulation) { + TriangulationData *triangulation = cachedTriangulation; + + if (triangulation->triangulated_points) + MEM_freeN(triangulation->triangulated_points); + + if (triangulation->triangles) + MEM_freeN(triangulation->triangles); + + MEM_freeN(this->cachedTriangulation); + + this->cachedTriangulation = NULL; + } +} + +KeyingScreenOperation::TriangulationData *KeyingScreenOperation::buildVoronoiTriangulation() +{ + MovieClipUser user = {0}; + TriangulationData *triangulation; + MovieTracking *tracking = &movieClip->tracking; + MovieTrackingTrack *track; + VoronoiSite *sites; + ImBuf *ibuf; + ListBase *tracksbase; + ListBase edges = {NULL, NULL}; + int sites_total; + int i; + int width = this->getWidth(); + int height = this->getHeight(); + + if (this->trackingObject[0]) { + MovieTrackingObject *object = BKE_tracking_named_object(tracking, this->trackingObject); + + if (!object) + return NULL; + + tracksbase = BKE_tracking_object_tracks(tracking, object); + } + else + tracksbase = BKE_tracking_get_tracks(tracking); + + sites_total = BLI_countlist(tracksbase); + + if (!sites_total) + return NULL; + + BKE_movieclip_user_set_frame(&user, framenumber); + ibuf = BKE_movieclip_get_ibuf(movieClip, &user); + + if (!ibuf) + return NULL; + + triangulation = (TriangulationData *) MEM_callocN(sizeof(TriangulationData), "keying screen triangulation data"); + + sites = (VoronoiSite *) MEM_callocN(sizeof(VoronoiSite) * sites_total, "keyingscreen voronoi sites"); + track = (MovieTrackingTrack *) tracksbase->first; + i = 0; + while (track) { + VoronoiSite *site = &sites[i]; + MovieTrackingMarker *marker = BKE_tracking_get_marker(track, framenumber); + ImBuf *pattern_ibuf = BKE_tracking_get_pattern_imbuf(ibuf, track, marker, TRUE, FALSE); + int j; + + zero_v3(site->color); + for (j = 0; j < pattern_ibuf->x * pattern_ibuf->y; j++) { + if (pattern_ibuf->rect_float) { + add_v3_v3(site->color, &pattern_ibuf->rect_float[4 * j]); + } + else { + unsigned char *rrgb = (unsigned char *)pattern_ibuf->rect; + + site->color[0] += srgb_to_linearrgb((float)rrgb[4 * j + 0] / 255.0f); + site->color[1] += srgb_to_linearrgb((float)rrgb[4 * j + 1] / 255.0f); + site->color[2] += srgb_to_linearrgb((float)rrgb[4 * j + 2] / 255.0f); + } + } + + mul_v3_fl(site->color, 1.0f / (pattern_ibuf->x * pattern_ibuf->y)); + IMB_freeImBuf(pattern_ibuf); + + site->co[0] = marker->pos[0] * width; + site->co[1] = marker->pos[1] * height; + + track = track->next; + i++; + } + + IMB_freeImBuf(ibuf); + + BLI_voronoi_compute(sites, sites_total, width, height, &edges); + + BLI_voronoi_triangulate(sites, sites_total, &edges, width, height, + &triangulation->triangulated_points, &triangulation->triangulated_points_total, + &triangulation->triangles, &triangulation->triangles_total); + + MEM_freeN(sites); + BLI_freelistN(&edges); + + return triangulation; +} + +void *KeyingScreenOperation::initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers) +{ + if (this->movieClip == NULL) + return NULL; + + if (this->cachedTriangulation) + return this->cachedTriangulation; + + lockMutex(); + if (this->cachedTriangulation == NULL) { + this->cachedTriangulation = buildVoronoiTriangulation(); + } + unlockMutex(); + + return this->cachedTriangulation; +} + +void KeyingScreenOperation::determineResolution(unsigned int resolution[], unsigned int preferredResolution[]) +{ + resolution[0] = 0; + resolution[1] = 0; + + if (this->movieClip) { + MovieClipUser user = {0}; + int width, height; + + BKE_movieclip_user_set_frame(&user, framenumber); + BKE_movieclip_get_size(this->movieClip, &user, &width, &height); + + resolution[0] = width; + resolution[1] = height; + } +} + +void KeyingScreenOperation::executePixel(float *color, int x, int y, MemoryBuffer *inputBuffers[], void *data) +{ + color[0] = 0.0f; + color[1] = 0.0f; + color[2] = 0.0f; + color[3] = 1.0f; + + if (this->movieClip && data) { + TriangulationData *triangulation = (TriangulationData *) data; + int i; + for (i = 0; i < triangulation->triangles_total; i++) { + int *triangle = triangulation->triangles[i]; + VoronoiTriangulationPoint *a = &triangulation->triangulated_points[triangle[0]], + *b = &triangulation->triangulated_points[triangle[1]], + *c = &triangulation->triangulated_points[triangle[2]]; + float co[2] = {(float) x, (float) y}, w[3]; + + if (barycentric_coords_v2(a->co, b->co, c->co, co, w)) { + if (barycentric_inside_triangle_v2(w)) { + color[0] += a->color[0] * w[0] + b->color[0] * w[1] + c->color[0] * w[2]; + color[1] += a->color[1] * w[0] + b->color[1] * w[1] + c->color[1] * w[2]; + color[2] += a->color[2] * w[0] + b->color[2] * w[1] + c->color[2] * w[2]; + } + } + } + } +} diff --git a/source/blender/compositor/operations/COM_KeyingScreenOperation.h b/source/blender/compositor/operations/COM_KeyingScreenOperation.h new file mode 100644 index 00000000000..9d3f44f6be2 --- /dev/null +++ b/source/blender/compositor/operations/COM_KeyingScreenOperation.h @@ -0,0 +1,79 @@ +/* + * 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_KeyingScreenOperation_h +#define _COM_KeyingScreenOperation_h + +#include <string.h> + +#include "COM_NodeOperation.h" + +#include "DNA_scene_types.h" +#include "DNA_movieclip_types.h" + +#include "BLI_listbase.h" + +extern "C" { + #include "BLI_voronoi.h" +} + +/** + * Class with implementation of green screen gradient rasterization + */ +class KeyingScreenOperation : public NodeOperation { +protected: + typedef struct TriangulationData { + VoronoiTriangulationPoint *triangulated_points; + int (*triangles)[3]; + int triangulated_points_total, triangles_total; + } TriangulationData; + + MovieClip *movieClip; + int framenumber; + TriangulationData *cachedTriangulation; + char trackingObject[64]; + + /** + * Determine the output resolution. The resolution is retrieved from the Renderer + */ + void determineResolution(unsigned int resolution[], unsigned int preferredResolution[]); + + TriangulationData *buildVoronoiTriangulation(); + + public: + KeyingScreenOperation(); + + void initExecution(); + void deinitExecution(); + + void *initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers); + + void setMovieClip(MovieClip *clip) {this->movieClip = clip;} + void setTrackingObject(char *object) {strncpy(this->trackingObject, object, sizeof(this->trackingObject));} + void setFramenumber(int framenumber) {this->framenumber = framenumber;} + + void executePixel(float *color, int x, int y, MemoryBuffer *inputBuffers[], void *data); +}; + +#endif |