diff options
-rw-r--r-- | source/blender/blenkernel/BKE_mask.h | 3 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/mask.c | 45 | ||||
-rw-r--r-- | source/blender/compositor/CMakeLists.txt | 5 | ||||
-rw-r--r-- | source/blender/compositor/intern/COM_Converter.cpp | 4 | ||||
-rw-r--r-- | source/blender/compositor/nodes/COM_MaskNode.cpp | 65 | ||||
-rw-r--r-- | source/blender/compositor/nodes/COM_MaskNode.h | 38 | ||||
-rw-r--r-- | source/blender/compositor/operations/COM_MaskOperation.cpp | 110 | ||||
-rw-r--r-- | source/blender/compositor/operations/COM_MaskOperation.h | 66 | ||||
-rw-r--r-- | source/blender/nodes/CMakeLists.txt | 1 | ||||
-rw-r--r-- | source/blender/nodes/composite/nodes/node_composite_mask.c | 40 |
10 files changed, 337 insertions, 40 deletions
diff --git a/source/blender/blenkernel/BKE_mask.h b/source/blender/blenkernel/BKE_mask.h index e09aa9d8355..21be180b05f 100644 --- a/source/blender/blenkernel/BKE_mask.h +++ b/source/blender/blenkernel/BKE_mask.h @@ -110,6 +110,9 @@ struct MaskObjectShape *BKE_mask_object_shape_varify_frame(struct MaskObject *ma void BKE_mask_object_shape_unlink(struct MaskObject *maskobj, struct MaskObjectShape *maskobj_shape); void BKE_mask_object_shape_sort(struct MaskObject *maskobj); +/* rasterization */ +void BKE_mask_rasterize(struct Mask *mask, int width, int height, float *buffer); + #define MASKPOINT_ISSEL(p) ( ((p)->bezt.f1 | (p)->bezt.f2 | (p)->bezt.f2) & SELECT) #define MASKPOINT_SEL(p) { (p)->bezt.f1 |= SELECT; (p)->bezt.f2 |= SELECT; (p)->bezt.f3 |= SELECT; } (void)0 #define MASKPOINT_DESEL(p) { (p)->bezt.f1 &= ~SELECT; (p)->bezt.f2 &= ~SELECT; (p)->bezt.f3 &= ~SELECT; } (void)0 diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c index 56bf90499e5..ea2acc4dbd3 100644 --- a/source/blender/blenkernel/intern/mask.c +++ b/source/blender/blenkernel/intern/mask.c @@ -55,6 +55,8 @@ #include "BKE_movieclip.h" #include "BKE_utildefines.h" +#include "raskter.h" + /* mask objects */ MaskObject *BKE_mask_object_new(Mask *mask, const char *name) @@ -1271,3 +1273,46 @@ void BKE_mask_object_shape_sort(MaskObject *maskobj) { BLI_sortlist(&maskobj->splines_shapes, mask_object_shape_sort_cb); } + +/* rasterization */ +void BKE_mask_rasterize(Mask *mask, int width, int height, float *buffer) +{ + MaskObject *maskobj; + + for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) { + MaskSpline *spline; + + for (spline = maskobj->splines.first; spline; spline = spline->next) { + float *diff_points; + int tot_diff_point; + + diff_points = BKE_mask_spline_differentiate(spline, &tot_diff_point); + + /* TODO, make this optional! */ + if (width != height) { + float *fp; + int i; + float asp; + + if (width < height) { + fp = &diff_points[0]; + asp = (float)width / (float)height; + } + else { + fp = &diff_points[1]; + asp = (float)height / (float)width; + } + + for (i = 0; i < tot_diff_point; i++, fp += 2) { + (*fp) = (((*fp) - 0.5f) / asp) + 0.5f; + } + } + + if (tot_diff_point) { + PLX_raskterize(diff_points, tot_diff_point, buffer, width, height); + + MEM_freeN(diff_points); + } + } + } +} diff --git a/source/blender/compositor/CMakeLists.txt b/source/blender/compositor/CMakeLists.txt index 3230c0ec33d..5e778d4d03b 100644 --- a/source/blender/compositor/CMakeLists.txt +++ b/source/blender/compositor/CMakeLists.txt @@ -134,6 +134,8 @@ set(SRC nodes/COM_MovieClipNode.h nodes/COM_OutputFileNode.cpp nodes/COM_OutputFileNode.h + nodes/COM_MaskNode.cpp + nodes/COM_MaskNode.h # output nodes nodes/COM_CompositorNode.cpp @@ -603,6 +605,9 @@ operations/COM_ConvertDepthToRadiusOperation.cpp operations/COM_AntiAliasOperation.cpp operations/COM_AntiAliasOperation.h + + operations/COM_MaskOperation.cpp + operations/COM_MaskOperation.h ) blender_add_lib(bf_compositor "${SRC}" "${INC}" "${INC_SYS}") diff --git a/source/blender/compositor/intern/COM_Converter.cpp b/source/blender/compositor/intern/COM_Converter.cpp index 3cb297801ca..dc6409e7b86 100644 --- a/source/blender/compositor/intern/COM_Converter.cpp +++ b/source/blender/compositor/intern/COM_Converter.cpp @@ -111,6 +111,7 @@ #include "COM_DefocusNode.h" #include "COM_DoubleEdgeMaskNode.h" #include "COM_CropNode.h" +#include "COM_MaskNode.h" Node *Converter::convert(bNode *bNode) { @@ -347,6 +348,9 @@ case CMP_NODE_OUTPUT_FILE: case CMP_NODE_CROP: node = new CropNode(bNode); break; + case CMP_NODE_MASK: + node = new MaskNode(bNode); + break; /* not inplemented yet */ default: node = new MuteNode(bNode); diff --git a/source/blender/compositor/nodes/COM_MaskNode.cpp b/source/blender/compositor/nodes/COM_MaskNode.cpp new file mode 100644 index 00000000000..991c3f75e05 --- /dev/null +++ b/source/blender/compositor/nodes/COM_MaskNode.cpp @@ -0,0 +1,65 @@ +/* + * 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_MaskNode.h" +#include "COM_ExecutionSystem.h" +#include "COM_MaskOperation.h" + +extern "C" { + #include "DNA_mask_types.h" +} + +MaskNode::MaskNode(bNode *editorNode): Node(editorNode) +{ +} + +void MaskNode::convertToOperations(ExecutionSystem *graph, CompositorContext * context) +{ + const RenderData *data = &context->getScene()->r; + + InputSocket *inputImage = this->getInputSocket(0); + OutputSocket *outputMask = this->getOutputSocket(0); + + bNode *editorNode = this->getbNode(); + Mask *mask = (Mask *)editorNode->id; + + // always connect the output image + MaskOperation *operation = new MaskOperation(); + + if (inputImage->isConnected()) { + inputImage->relinkConnections(operation->getInputSocket(0), 0, graph); + } + else { + operation->setMaskWidth(data->xsch * data->size / 100.0f); + operation->setMaskHeight(data->ysch * data->size / 100.0f); + } + + if (outputMask->isConnected()) { + outputMask->relinkConnections(operation->getOutputSocket()); + } + + operation->setMask(mask); + operation->setFramenumber(context->getFramenumber()); + + graph->addOperation(operation); +} diff --git a/source/blender/compositor/nodes/COM_MaskNode.h b/source/blender/compositor/nodes/COM_MaskNode.h new file mode 100644 index 00000000000..9d2ea1889d9 --- /dev/null +++ b/source/blender/compositor/nodes/COM_MaskNode.h @@ -0,0 +1,38 @@ +/* + * 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 MaskNode + * @ingroup Node + */ +class MaskNode : public Node { + + +public: + MaskNode(bNode *editorNode); + void convertToOperations(ExecutionSystem *graph, CompositorContext *context); + +}; diff --git a/source/blender/compositor/operations/COM_MaskOperation.cpp b/source/blender/compositor/operations/COM_MaskOperation.cpp new file mode 100644 index 00000000000..7c71e884e5c --- /dev/null +++ b/source/blender/compositor/operations/COM_MaskOperation.cpp @@ -0,0 +1,110 @@ +/* + * 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_MaskOperation.h" + +#include "MEM_guardedalloc.h" + +#include "BLI_listbase.h" +#include "BLI_math.h" + +#include "DNA_scene_types.h" + +extern "C" { + #include "BKE_mask.h" +} + +MaskOperation::MaskOperation(): NodeOperation() +{ + this->addInputSocket(COM_DT_COLOR); + this->addOutputSocket(COM_DT_COLOR); + this->mask = NULL; + this->maskWidth = 0; + this->maskHeight = 0; + this->framenumber = 0; + this->rasterizedMask = NULL; + setComplex(true); +} + +void MaskOperation::initExecution() +{ + initMutex(); + this->rasterizedMask = NULL; +} + +void MaskOperation::deinitExecution() +{ + if (this->rasterizedMask) { + MEM_freeN(rasterizedMask); + this->rasterizedMask = NULL; + } +} + +void *MaskOperation::initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers) +{ + if (this->rasterizedMask) + return this->rasterizedMask; + + BLI_mutex_lock(getMutex()); + if (this->rasterizedMask == NULL) { + int width = this->getWidth(); + int height = this->getHeight(); + + this->rasterizedMask = (float *)MEM_callocN(sizeof(float) * width * height, "rasterized mask"); + BKE_mask_rasterize(mask, width, height, this->rasterizedMask); + } + BLI_mutex_unlock(getMutex()); + + return this->rasterizedMask; +} + +void MaskOperation::determineResolution(unsigned int resolution[], unsigned int preferredResolution[]) +{ + if (maskWidth == 0 || maskHeight == 0) { + NodeOperation::determineResolution(resolution, preferredResolution); + } + else { + unsigned int nr[2]; + + nr[0] = maskWidth; + nr[1] = maskHeight; + + NodeOperation::determineResolution(resolution, nr); + + resolution[0] = maskWidth; + resolution[1] = maskHeight; + } +} + +void MaskOperation::executePixel(float *color, int x, int y, MemoryBuffer *inputBuffers[], void *data) +{ + float *buffer = (float*) data; + int index = (y * this->getWidth() + x); + + color[0] = buffer[index]; + color[1] = buffer[index]; + color[2] = buffer[index]; + color[3] = 1.0f; +} + + diff --git a/source/blender/compositor/operations/COM_MaskOperation.h b/source/blender/compositor/operations/COM_MaskOperation.h new file mode 100644 index 00000000000..9f2c7f53f56 --- /dev/null +++ b/source/blender/compositor/operations/COM_MaskOperation.h @@ -0,0 +1,66 @@ +/* + * 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_MaskOperation_h +#define _COM_MaskOperation_h + +#include "COM_NodeOperation.h" +#include "DNA_scene_types.h" +#include "DNA_mask_types.h" +#include "BLI_listbase.h" +#include "IMB_imbuf_types.h" + +/** + * Class with implementation of mask rasterization + */ +class MaskOperation : public NodeOperation { +protected: + Mask *mask; + int maskWidth; + int maskHeight; + int framenumber; + float *rasterizedMask; + + /** + * Determine the output resolution. The resolution is retrieved from the Renderer + */ + void determineResolution(unsigned int resolution[], unsigned int preferredResolution[]); + +public: + MaskOperation(); + + void initExecution(); + void deinitExecution(); + + void *initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers); + + void setMask(Mask *mask) {this->mask = mask;} + void setMaskWidth(int width) {this->maskWidth = width;} + void setMaskHeight(int height) {this->maskHeight = height;} + void setFramenumber(int framenumber) {this->framenumber = framenumber;} + + void executePixel(float *color, int x, int y, MemoryBuffer *inputBuffers[], void *data); +}; + +#endif diff --git a/source/blender/nodes/CMakeLists.txt b/source/blender/nodes/CMakeLists.txt index 358abb08ba4..5e36f90f217 100644 --- a/source/blender/nodes/CMakeLists.txt +++ b/source/blender/nodes/CMakeLists.txt @@ -35,7 +35,6 @@ set(INC ../makesrna ../render/extern/include ../../../intern/guardedalloc - ../../../intern/raskter ../compositor ) diff --git a/source/blender/nodes/composite/nodes/node_composite_mask.c b/source/blender/nodes/composite/nodes/node_composite_mask.c index 93d1edd76e8..c90c7918660 100644 --- a/source/blender/nodes/composite/nodes/node_composite_mask.c +++ b/source/blender/nodes/composite/nodes/node_composite_mask.c @@ -36,8 +36,6 @@ #include "BKE_mask.h" -// XXX: ... -#include "../../../../intern/raskter/raskter.h" #include "node_composite_util.h" /* **************** Translate ******************** */ @@ -58,7 +56,6 @@ static void exec(void *data, bNode *node, bNodeStack **in, bNodeStack **out) Mask *mask = (Mask *)node->id; CompBuf *stackbuf; RenderData *rd = data; - MaskObject *maskobj = mask->maskobjs.first; float *res; int sx, sy; @@ -84,42 +81,7 @@ static void exec(void *data, bNode *node, bNodeStack **in, bNodeStack **out) stackbuf = alloc_compbuf(sx, sy, CB_VAL, TRUE); res = stackbuf->rect; - for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) { - MaskSpline *spline; - - for (spline = maskobj->splines.first; spline; spline = spline->next) { - float *diff_points; - int tot_diff_point; - - diff_points = BKE_mask_spline_differentiate(spline, &tot_diff_point); - - /* TODO, make this optional! */ - if (sx != sy) { - float *fp; - int i; - float asp; - - if (sx < sy) { - fp = &diff_points[0]; - asp = (float)sx / (float)sy; - } - else { - fp = &diff_points[1]; - asp = (float)sy / (float)sx; - } - - for (i = 0; i < tot_diff_point; i++, fp += 2) { - (*fp) = (((*fp) - 0.5f) / asp) + 0.5f; - } - } - - if (tot_diff_point) { - PLX_raskterize(diff_points, tot_diff_point, res, sx, sy); - - MEM_freeN(diff_points); - } - } - } + BKE_mask_rasterize(mask, sx, sy, res); /* pass on output and free */ out[0]->data = stackbuf; |