diff options
author | Sergey Sharybin <sergey.vfx@gmail.com> | 2015-12-09 17:31:39 +0300 |
---|---|---|
committer | Sergey Sharybin <sergey.vfx@gmail.com> | 2016-01-14 14:13:55 +0300 |
commit | cc55f97da9cca7a27f2313b7405d3aad277029d7 (patch) | |
tree | 0dd6047408ec255772dac4a9b79a6e50edcc1990 | |
parent | 73feae6f5dd81a81e0321db80e55c15c3518b7a0 (diff) |
Compositor: Add option to extend image bounds when blurring
It is handy when doing some roto work and it's required to blur some
mask or overaly before alpha-overing it on top of the footage.
Quite straightforward option with the only limitation that variable
size blur is not supported.
Reviewers: campbellbarton
Subscribers: hype, sebastian_k
Differential Revision: https://developer.blender.org/D1663
9 files changed, 68 insertions, 6 deletions
diff --git a/source/blender/compositor/nodes/COM_BlurNode.cpp b/source/blender/compositor/nodes/COM_BlurNode.cpp index f3d0c33d3b3..6fbfc24a6b6 100644 --- a/source/blender/compositor/nodes/COM_BlurNode.cpp +++ b/source/blender/compositor/nodes/COM_BlurNode.cpp @@ -46,13 +46,15 @@ void BlurNode::convertToOperations(NodeConverter &converter, const CompositorCon bool connectedSizeSocket = inputSizeSocket->isLinked(); const float size = this->getInputSocket(1)->getEditorValueFloat(); - + const bool extend_bounds = (editorNode->custom1 & CMP_NODEFLAG_BLUR_EXTEND_BOUNDS) != 0; + CompositorQuality quality = context.getQuality(); NodeOperation *input_operation = NULL, *output_operation = NULL; if (data->filtertype == R_FILTER_FAST_GAUSS) { FastGaussianBlurOperation *operationfgb = new FastGaussianBlurOperation(); operationfgb->setData(data); + operationfgb->setExtendBounds(extend_bounds); converter.addOperation(operationfgb); converter.mapInputSocket(getInputSocket(1), operationfgb->getInputSocket(1)); @@ -77,6 +79,7 @@ void BlurNode::convertToOperations(NodeConverter &converter, const CompositorCon operationx->setSize(1.0f); operationx->setFalloff(PROP_SMOOTH); operationx->setSubtract(false); + operationx->setExtendBounds(extend_bounds); converter.addOperation(operationx); converter.addLink(clamp->getOutputSocket(), operationx->getInputSocket(0)); @@ -87,14 +90,16 @@ void BlurNode::convertToOperations(NodeConverter &converter, const CompositorCon operationy->setSize(1.0f); operationy->setFalloff(PROP_SMOOTH); operationy->setSubtract(false); - + operationy->setExtendBounds(extend_bounds); + converter.addOperation(operationy); converter.addLink(operationx->getOutputSocket(), operationy->getInputSocket(0)); GaussianBlurReferenceOperation *operation = new GaussianBlurReferenceOperation(); operation->setData(data); operation->setQuality(quality); - + operation->setExtendBounds(extend_bounds); + converter.addOperation(operation); converter.addLink(operationy->getOutputSocket(), operation->getInputSocket(1)); @@ -106,7 +111,8 @@ void BlurNode::convertToOperations(NodeConverter &converter, const CompositorCon operationx->setData(data); operationx->setQuality(quality); operationx->checkOpenCL(); - + operationx->setExtendBounds(extend_bounds); + converter.addOperation(operationx); converter.mapInputSocket(getInputSocket(1), operationx->getInputSocket(1)); @@ -114,6 +120,7 @@ void BlurNode::convertToOperations(NodeConverter &converter, const CompositorCon operationy->setData(data); operationy->setQuality(quality); operationy->checkOpenCL(); + operationy->setExtendBounds(extend_bounds); converter.addOperation(operationy); converter.mapInputSocket(getInputSocket(1), operationy->getInputSocket(1)); @@ -131,7 +138,8 @@ void BlurNode::convertToOperations(NodeConverter &converter, const CompositorCon GaussianBokehBlurOperation *operation = new GaussianBokehBlurOperation(); operation->setData(data); operation->setQuality(quality); - + operation->setExtendBounds(extend_bounds); + converter.addOperation(operation); converter.mapInputSocket(getInputSocket(1), operation->getInputSocket(1)); diff --git a/source/blender/compositor/nodes/COM_BokehBlurNode.cpp b/source/blender/compositor/nodes/COM_BokehBlurNode.cpp index 7ab05e438ec..91c26eecb73 100644 --- a/source/blender/compositor/nodes/COM_BokehBlurNode.cpp +++ b/source/blender/compositor/nodes/COM_BokehBlurNode.cpp @@ -41,6 +41,7 @@ void BokehBlurNode::convertToOperations(NodeConverter &converter, const Composit NodeInput *inputSizeSocket = this->getInputSocket(2); bool connectedSizeSocket = inputSizeSocket->isLinked(); + const bool extend_bounds = (b_node->custom1 & CMP_NODEFLAG_BLUR_EXTEND_BOUNDS) != 0; if ((b_node->custom1 & CMP_NODEFLAG_BLUR_VARIABLE_SIZE) && connectedSizeSocket) { VariableSizeBokehBlurOperation *operation = new VariableSizeBokehBlurOperation(); @@ -58,6 +59,7 @@ void BokehBlurNode::convertToOperations(NodeConverter &converter, const Composit else { BokehBlurOperation *operation = new BokehBlurOperation(); operation->setQuality(context.getQuality()); + operation->setExtendBounds(extend_bounds); converter.addOperation(operation); converter.mapInputSocket(getInputSocket(0), operation->getInputSocket(0)); diff --git a/source/blender/compositor/operations/COM_BlurBaseOperation.cpp b/source/blender/compositor/operations/COM_BlurBaseOperation.cpp index dc5f80e55f3..2003d6e7b69 100644 --- a/source/blender/compositor/operations/COM_BlurBaseOperation.cpp +++ b/source/blender/compositor/operations/COM_BlurBaseOperation.cpp @@ -39,6 +39,7 @@ BlurBaseOperation::BlurBaseOperation(DataType data_type) : NodeOperation() memset(&m_data, 0, sizeof(NodeBlurData)); this->m_size = 1.0f; this->m_sizeavailable = false; + this->m_extend_bounds = false; } void BlurBaseOperation::initExecution() { @@ -174,3 +175,14 @@ void BlurBaseOperation::updateSize() this->m_sizeavailable = true; } } + +void BlurBaseOperation::determineResolution(unsigned int resolution[2], + unsigned int preferredResolution[2]) +{ + NodeOperation::determineResolution(resolution, + preferredResolution); + if (this->m_extend_bounds) { + resolution[0] += 2 * this->m_size * m_data.sizex; + resolution[1] += 2 * this->m_size * m_data.sizey; + } +} diff --git a/source/blender/compositor/operations/COM_BlurBaseOperation.h b/source/blender/compositor/operations/COM_BlurBaseOperation.h index f9f37479c56..84cdcfeeba8 100644 --- a/source/blender/compositor/operations/COM_BlurBaseOperation.h +++ b/source/blender/compositor/operations/COM_BlurBaseOperation.h @@ -55,6 +55,8 @@ protected: float m_size; bool m_sizeavailable; + bool m_extend_bounds; + public: /** * Initialize the execution @@ -69,5 +71,10 @@ public: void setData(const NodeBlurData *data); void setSize(float size) { this->m_size = size; this->m_sizeavailable = true; } + + void setExtendBounds(bool extend_bounds) { this->m_extend_bounds = extend_bounds; } + + void determineResolution(unsigned int resolution[2], + unsigned int preferredResolution[2]); }; #endif diff --git a/source/blender/compositor/operations/COM_BokehBlurOperation.cpp b/source/blender/compositor/operations/COM_BokehBlurOperation.cpp index 189483708b5..5ed36635f81 100644 --- a/source/blender/compositor/operations/COM_BokehBlurOperation.cpp +++ b/source/blender/compositor/operations/COM_BokehBlurOperation.cpp @@ -43,6 +43,8 @@ BokehBlurOperation::BokehBlurOperation() : NodeOperation() this->m_inputProgram = NULL; this->m_inputBokehProgram = NULL; this->m_inputBoundingBoxReader = NULL; + + this->m_extend_bounds = false; } void *BokehBlurOperation::initializeTileData(rcti * /*rect*/) @@ -226,3 +228,15 @@ void BokehBlurOperation::updateSize() this->m_sizeavailable = true; } } + +void BokehBlurOperation::determineResolution(unsigned int resolution[2], + unsigned int preferredResolution[2]) +{ + NodeOperation::determineResolution(resolution, + preferredResolution); + if (this->m_extend_bounds) { + const float max_dim = max(resolution[0], resolution[1]); + resolution[0] += 2 * this->m_size * max_dim / 100.0f; + resolution[1] += 2 * this->m_size * max_dim / 100.0f; + } +} diff --git a/source/blender/compositor/operations/COM_BokehBlurOperation.h b/source/blender/compositor/operations/COM_BokehBlurOperation.h index d2944825583..ed967d0fdb9 100644 --- a/source/blender/compositor/operations/COM_BokehBlurOperation.h +++ b/source/blender/compositor/operations/COM_BokehBlurOperation.h @@ -37,6 +37,7 @@ private: float m_bokehMidX; float m_bokehMidY; float m_bokehDimension; + bool m_extend_bounds; public: BokehBlurOperation(); @@ -64,5 +65,10 @@ public: MemoryBuffer *outputMemoryBuffer, cl_mem clOutputBuffer, MemoryBuffer **inputMemoryBuffers, list<cl_mem> *clMemToCleanUp, list<cl_kernel> *clKernelsToCleanUp); + + void setExtendBounds(bool extend_bounds) { this->m_extend_bounds = extend_bounds; } + + void determineResolution(unsigned int resolution[2], + unsigned int preferredResolution[2]); }; #endif diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index 50e31ffca64..e97d1d2771f 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -1374,6 +1374,7 @@ static void node_composit_buts_blur(uiLayout *layout, bContext *UNUSED(C), Point uiItemR(col, ptr, "size_x", 0, IFACE_("X"), ICON_NONE); uiItemR(col, ptr, "size_y", 0, IFACE_("Y"), ICON_NONE); } + uiItemR(col, ptr, "use_extended_bounds", 0, NULL, ICON_NONE); } static void node_composit_buts_dblur(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) @@ -2207,6 +2208,7 @@ static void node_composit_buts_bokehblur(uiLayout *layout, bContext *UNUSED(C), uiItemR(layout, ptr, "use_variable_size", 0, NULL, ICON_NONE); // uiItemR(layout, ptr, "f_stop", 0, NULL, ICON_NONE); // UNUSED uiItemR(layout, ptr, "blur_max", 0, NULL, ICON_NONE); + uiItemR(layout, ptr, "use_extended_bounds", 0, NULL, ICON_NONE); } static void node_composit_backdrop_viewer(SpaceNode *snode, ImBuf *backdrop, bNode *node, int x, int y) diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h index 7aec437b62b..3b35320c803 100644 --- a/source/blender/makesdna/DNA_node_types.h +++ b/source/blender/makesdna/DNA_node_types.h @@ -503,7 +503,8 @@ enum { }; enum { - CMP_NODEFLAG_BLUR_VARIABLE_SIZE = (1 << 0) + CMP_NODEFLAG_BLUR_VARIABLE_SIZE = (1 << 0), + CMP_NODEFLAG_BLUR_EXTEND_BOUNDS = (1 << 1), }; typedef struct NodeFrame { diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index 0bec03c5ce1..798f3cb9af3 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -4376,6 +4376,11 @@ static void def_cmp_blur(StructRNA *srna) RNA_def_property_ui_text(prop, "Variable Size", "Support variable blur per-pixel when using an image for size input"); RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); + prop = RNA_def_property(srna, "use_extended_bounds", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "custom1", CMP_NODEFLAG_BLUR_EXTEND_BOUNDS); + RNA_def_property_ui_text(prop, "Extend Bounds", "Extend bounds of the input image to fully fit blurred image"); + RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); + RNA_def_struct_sdna_from(srna, "NodeBlurData", "storage"); prop = RNA_def_property(srna, "size_x", PROP_INT, PROP_NONE); @@ -6098,6 +6103,11 @@ static void def_cmp_bokehblur(StructRNA *srna) "Support variable blur per-pixel when using an image for size input"); RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); + prop = RNA_def_property(srna, "use_extended_bounds", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "custom1", CMP_NODEFLAG_BLUR_EXTEND_BOUNDS); + RNA_def_property_ui_text(prop, "Extend Bounds", "Extend bounds of the input image to fully fit blurred image"); + RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); + #if 0 prop = RNA_def_property(srna, "f_stop", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "custom3"); |