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
This commit is contained in:
parent
73feae6f5d
commit
cc55f97da9
|
@ -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));
|
||||
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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");
|
||||
|
|
Loading…
Reference in New Issue