svn merge ^/trunk/blender -r49061:49063
This commit is contained in:
@@ -25,9 +25,13 @@
|
||||
#include "DNA_node_types.h"
|
||||
#include "COM_GaussianXBlurOperation.h"
|
||||
#include "COM_GaussianYBlurOperation.h"
|
||||
#include "COM_GaussianAlphaXBlurOperation.h"
|
||||
#include "COM_GaussianAlphaYBlurOperation.h"
|
||||
#include "COM_ExecutionSystem.h"
|
||||
#include "COM_GaussianBokehBlurOperation.h"
|
||||
#include "COM_FastGaussianBlurOperation.h"
|
||||
#include "COM_MathBaseOperation.h"
|
||||
#include "COM_SetValueOperation.h"
|
||||
|
||||
BlurNode::BlurNode(bNode *editorNode) : Node(editorNode)
|
||||
{
|
||||
@@ -56,6 +60,42 @@ void BlurNode::convertToOperations(ExecutionSystem *graph, CompositorContext *co
|
||||
graph->addOperation(operationfgb);
|
||||
addPreviewOperation(graph, operationfgb->getOutputSocket());
|
||||
}
|
||||
else if (editorNode->custom1 & CMP_NODEFLAG_BLUR_REFERENCE) {
|
||||
MathAddOperation *clamp = new MathAddOperation();
|
||||
SetValueOperation *zero = new SetValueOperation();
|
||||
addLink(graph, zero->getOutputSocket(), clamp->getInputSocket(1));
|
||||
this->getInputSocket(1)->relinkConnections(clamp->getInputSocket(0), 1, graph);
|
||||
zero->setValue(0.0f);
|
||||
clamp->setUseClamp(true);
|
||||
graph->addOperation(clamp);
|
||||
graph->addOperation(zero);
|
||||
|
||||
GaussianAlphaXBlurOperation *operationx = new GaussianAlphaXBlurOperation();
|
||||
operationx->setData(data);
|
||||
operationx->setbNode(editorNode);
|
||||
operationx->setQuality(quality);
|
||||
operationx->setSize(1.0f);
|
||||
addLink(graph, clamp->getOutputSocket(), operationx->getInputSocket(0));
|
||||
graph->addOperation(operationx);
|
||||
|
||||
GaussianYBlurOperation *operationy = new GaussianYBlurOperation();
|
||||
operationy->setData(data);
|
||||
operationy->setbNode(editorNode);
|
||||
operationy->setQuality(quality);
|
||||
operationy->setSize(1.0f);
|
||||
addLink(graph, operationx->getOutputSocket(), operationy->getInputSocket(0));
|
||||
graph->addOperation(operationy);
|
||||
|
||||
GaussianBlurReferenceOperation *operation = new GaussianBlurReferenceOperation();
|
||||
operation->setData(data);
|
||||
operation->setbNode(editorNode);
|
||||
operation->setQuality(quality);
|
||||
this->getInputSocket(0)->relinkConnections(operation->getInputSocket(0), 0, graph);
|
||||
addLink(graph, operationy->getOutputSocket(), operation->getInputSocket(1));
|
||||
graph->addOperation(operation);
|
||||
this->getOutputSocket(0)->relinkConnections(operation->getOutputSocket());
|
||||
addPreviewOperation(graph, operation->getOutputSocket());
|
||||
}
|
||||
else if (!data->bokeh) {
|
||||
GaussianXBlurOperation *operationx = new GaussianXBlurOperation();
|
||||
operationx->setData(data);
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
|
||||
#include "COM_GaussianBokehBlurOperation.h"
|
||||
#include "BLI_math.h"
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
extern "C" {
|
||||
#include "RE_pipeline.h"
|
||||
}
|
||||
@@ -198,25 +198,20 @@ bool GaussianBokehBlurOperation::determineDependingAreaOfInterest(rcti *input, R
|
||||
}
|
||||
|
||||
// reference image
|
||||
GaussianBokehBlurReferenceOperation::GaussianBokehBlurReferenceOperation() : NodeOperation()
|
||||
GaussianBlurReferenceOperation::GaussianBlurReferenceOperation() : BlurBaseOperation(COM_DT_COLOR)
|
||||
{
|
||||
this->addInputSocket(COM_DT_COLOR);
|
||||
this->addInputSocket(COM_DT_VALUE);
|
||||
this->addOutputSocket(COM_DT_COLOR);
|
||||
this->setComplex(true);
|
||||
this->m_gausstab = NULL;
|
||||
this->m_inputImage = NULL;
|
||||
this->m_inputSize = NULL;
|
||||
this->m_maintabs = NULL;
|
||||
}
|
||||
|
||||
void *GaussianBokehBlurReferenceOperation::initializeTileData(rcti *rect)
|
||||
void *GaussianBlurReferenceOperation::initializeTileData(rcti *rect)
|
||||
{
|
||||
void *buffer = getInputOperation(0)->initializeTileData(NULL);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
void GaussianBokehBlurReferenceOperation::initExecution()
|
||||
void GaussianBlurReferenceOperation::initExecution()
|
||||
{
|
||||
BlurBaseOperation::initExecution();
|
||||
// setup gaustab
|
||||
this->m_data->image_in_width = this->getWidth();
|
||||
this->m_data->image_in_height = this->getHeight();
|
||||
@@ -237,100 +232,106 @@ void GaussianBokehBlurReferenceOperation::initExecution()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* horizontal */
|
||||
m_radx = (float)this->m_data->sizex;
|
||||
int imgx = getWidth()/2;
|
||||
if (m_radx > imgx)
|
||||
m_radx = imgx;
|
||||
else if (m_radx < 1)
|
||||
m_radx = 1;
|
||||
m_radxf = (float)m_radx;
|
||||
|
||||
/* vertical */
|
||||
m_rady = (float)this->m_data->sizey;
|
||||
int imgy = getHeight()/2;
|
||||
if (m_rady > imgy)
|
||||
m_rady = imgy;
|
||||
else if (m_rady < 1)
|
||||
m_rady = 1;
|
||||
m_radyf = (float)m_rady;
|
||||
updateGauss();
|
||||
this->m_inputImage = this->getInputSocketReader(0);
|
||||
this->m_inputSize = this->getInputSocketReader(1);
|
||||
}
|
||||
|
||||
void GaussianBokehBlurReferenceOperation::updateGauss()
|
||||
void GaussianBlurReferenceOperation::updateGauss()
|
||||
{
|
||||
int n;
|
||||
float *dgauss;
|
||||
float *ddgauss;
|
||||
int j, i;
|
||||
|
||||
n = (2 * radx + 1) * (2 * rady + 1);
|
||||
|
||||
/* create a full filter image */
|
||||
ddgauss = new float[n];
|
||||
dgauss = ddgauss;
|
||||
for (j = -rady; j <= rady; j++) {
|
||||
for (i = -radx; i <= radx; i++, dgauss++) {
|
||||
float fj = (float)j / radyf;
|
||||
float fi = (float)i / radxf;
|
||||
float dist = sqrt(fj * fj + fi * fi);
|
||||
*dgauss = RE_filter_value(this->m_data->filtertype, dist);
|
||||
}
|
||||
}
|
||||
this->m_gausstab = ddgauss;
|
||||
int i;
|
||||
int x = MAX2(m_radx, m_rady);
|
||||
this->m_maintabs = (float**)MEM_mallocN(x * sizeof(float *), "gauss array");
|
||||
for (i = 0; i < x; i++)
|
||||
m_maintabs[i] = make_gausstab(i + 1);
|
||||
}
|
||||
|
||||
void GaussianBokehBlurReferenceOperation::executePixel(float *color, int x, int y, void *data)
|
||||
void GaussianBlurReferenceOperation::executePixel(float *color, int x, int y, void *data)
|
||||
{
|
||||
float tempColor[4];
|
||||
MemoryBuffer *memorybuffer = (MemoryBuffer*)data;
|
||||
float *buffer = memorybuffer->getBuffer();
|
||||
float *gausstabx, *gausstabcenty;
|
||||
float *gausstaby, *gausstabcentx;
|
||||
int i, j;
|
||||
float *src;
|
||||
register float sum, val;
|
||||
float rval, gval, bval, aval;
|
||||
int imgx = getWidth();
|
||||
int imgy = getHeight();
|
||||
float tempSize[4];
|
||||
tempColor[0] = 0;
|
||||
tempColor[1] = 0;
|
||||
tempColor[2] = 0;
|
||||
tempColor[3] = 0;
|
||||
float multiplier_accum = 0;
|
||||
MemoryBuffer *inputBuffer = (MemoryBuffer *)data;
|
||||
float *buffer = inputBuffer->getBuffer();
|
||||
int bufferwidth = inputBuffer->getWidth();
|
||||
int bufferstartx = inputBuffer->getRect()->xmin;
|
||||
int bufferstarty = inputBuffer->getRect()->ymin;
|
||||
this->m_inputSize->read(tempSize, x, y, data);
|
||||
float size = tempSize[0];
|
||||
CLAMP(size, 0.0f, 1.0f);
|
||||
float sizeX = ceil(this->m_data->sizex * size);
|
||||
float sizeY = ceil(this->m_data->sizey * size);
|
||||
float refSize = tempSize[0];
|
||||
int refradx = (int)(refSize * m_radxf);
|
||||
int refrady = (int)(refSize * m_radyf);
|
||||
if (refradx > m_radx) refradx = m_radx;
|
||||
else if (refradx < 1) refradx = 1;
|
||||
if (refrady > m_rady) refrady = m_rady;
|
||||
else if (refrady < 1) refrady = 1;
|
||||
|
||||
if (sizeX <= 0.5f && sizeY <= 0.5f) {
|
||||
this->m_inputImage->read(color, x, y, data);
|
||||
return;
|
||||
}
|
||||
|
||||
int miny = y - sizeY;
|
||||
int maxy = y + sizeY;
|
||||
int minx = x - sizeX;
|
||||
int maxx = x + sizeX;
|
||||
miny = max(miny, inputBuffer->getRect()->ymin);
|
||||
minx = max(minx, inputBuffer->getRect()->xmin);
|
||||
maxy = min(maxy, inputBuffer->getRect()->ymax);
|
||||
maxx = min(maxx, inputBuffer->getRect()->xmax);
|
||||
if (refradx == 1 && refrady == 1) {
|
||||
memorybuffer->readNoCheck(color, x, y);
|
||||
} else {
|
||||
int minxr = x - refradx < 0 ? -x : -refradx;
|
||||
int maxxr = x + refradx > imgx ? imgx - x : refradx;
|
||||
int minyr = y - refrady < 0 ? -y : -refrady;
|
||||
int maxyr = y + refrady > imgy ? imgy - y : refrady;
|
||||
|
||||
int step = QualityStepHelper::getStep();
|
||||
int offsetadd = QualityStepHelper::getOffsetAdd();
|
||||
for (int ny = miny; ny < maxy; ny += step) {
|
||||
int u = ny - y;
|
||||
float uf = ((u/sizeY)*radyf)+radyf;
|
||||
int indexu = uf * (radx*2+1);
|
||||
int bufferindex = ((minx - bufferstartx) * 4) + ((ny - bufferstarty) * 4 * bufferwidth);
|
||||
for (int nx = minx; nx < maxx; nx += step) {
|
||||
int v = nx - x;
|
||||
float vf = ((v/sizeX)*radxf)+radxf;
|
||||
int index = indexu + vf;
|
||||
const float multiplier = this->m_gausstab[index];
|
||||
madd_v4_v4fl(tempColor, &buffer[bufferindex], multiplier);
|
||||
multiplier_accum += multiplier;
|
||||
index += step;
|
||||
bufferindex += offsetadd;
|
||||
float *srcd = buffer + COM_NUMBER_OF_CHANNELS * ( (y + minyr) * imgx + x + minxr);
|
||||
|
||||
gausstabx = m_maintabs[refradx - 1];
|
||||
gausstabcentx = gausstabx + refradx;
|
||||
gausstaby = m_maintabs[refrady - 1];
|
||||
gausstabcenty = gausstaby + refrady;
|
||||
|
||||
sum = gval = rval = bval = aval = 0.0f;
|
||||
for (i = minyr; i < maxyr; i++, srcd += COM_NUMBER_OF_CHANNELS * imgx) {
|
||||
src = srcd;
|
||||
for (j = minxr; j < maxxr; j++, src += COM_NUMBER_OF_CHANNELS) {
|
||||
|
||||
val = gausstabcenty[i] * gausstabcentx[j];
|
||||
sum += val;
|
||||
rval += val * src[0];
|
||||
gval += val * src[1];
|
||||
bval += val * src[2];
|
||||
aval += val * src[3];
|
||||
}
|
||||
}
|
||||
sum = 1.0f / sum;
|
||||
color[0] = rval * sum;
|
||||
color[1] = gval * sum;
|
||||
color[2] = bval * sum;
|
||||
color[3] = aval * sum;
|
||||
}
|
||||
|
||||
mul_v4_v4fl(color, tempColor, 1.0f / multiplier_accum);
|
||||
}
|
||||
|
||||
void GaussianBokehBlurReferenceOperation::deinitExecution()
|
||||
void GaussianBlurReferenceOperation::deinitExecution()
|
||||
{
|
||||
delete [] this->m_gausstab;
|
||||
this->m_gausstab = NULL;
|
||||
this->m_inputImage = NULL;
|
||||
this->m_inputSize = NULL;
|
||||
|
||||
int x, i;
|
||||
x = MAX2(m_radx, m_rady);
|
||||
for (i = 0; i < x; i++)
|
||||
delete []m_maintabs[i];
|
||||
MEM_freeN(m_maintabs);
|
||||
BlurBaseOperation::deinitExecution();
|
||||
}
|
||||
|
||||
bool GaussianBokehBlurReferenceOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output)
|
||||
bool GaussianBlurReferenceOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output)
|
||||
{
|
||||
rcti newInput;
|
||||
NodeOperation *operation = this->getInputOperation(1);
|
||||
|
||||
@@ -49,22 +49,18 @@ public:
|
||||
bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output);
|
||||
};
|
||||
|
||||
class GaussianBokehBlurReferenceOperation : public NodeOperation, public QualityStepHelper {
|
||||
class GaussianBlurReferenceOperation : public BlurBaseOperation {
|
||||
private:
|
||||
SocketReader * m_inputImage;
|
||||
SocketReader * m_inputSize;
|
||||
float *m_gausstab;
|
||||
NodeBlurData *m_data;
|
||||
float **m_maintabs;
|
||||
|
||||
void updateGauss();
|
||||
int m_radx;
|
||||
int m_rady;
|
||||
float m_radxf;
|
||||
float m_radyf;
|
||||
|
||||
static const int radxf = 256.0f;
|
||||
static const int radyf = 256.0f;
|
||||
static const int radx = 256;
|
||||
static const int rady = 256;
|
||||
|
||||
public:
|
||||
GaussianBokehBlurReferenceOperation();
|
||||
GaussianBlurReferenceOperation();
|
||||
void initExecution();
|
||||
void *initializeTileData(rcti *rect);
|
||||
/**
|
||||
@@ -78,8 +74,6 @@ public:
|
||||
void deinitExecution();
|
||||
|
||||
bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output);
|
||||
|
||||
void setData(NodeBlurData *data) { this->m_data = data; }
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1533,12 +1533,19 @@ static void node_composit_buts_renderlayers(uiLayout *layout, bContext *C, Point
|
||||
static void node_composit_buts_blur(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
|
||||
{
|
||||
uiLayout *col, *row;
|
||||
int reference;
|
||||
int filter;
|
||||
|
||||
col = uiLayoutColumn(layout, FALSE);
|
||||
|
||||
filter = RNA_enum_get(ptr, "filter_type");
|
||||
reference = RNA_boolean_get(ptr, "use_reference");
|
||||
|
||||
uiItemR(col, ptr, "filter_type", 0, "", ICON_NONE);
|
||||
if (RNA_enum_get(ptr, "filter_type") != R_FILTER_FAST_GAUSS) {
|
||||
uiItemR(col, ptr, "use_bokeh", 0, NULL, ICON_NONE);
|
||||
if (filter != R_FILTER_FAST_GAUSS) {
|
||||
uiItemR(col, ptr, "use_reference", 0, NULL, ICON_NONE);
|
||||
if (!reference) {
|
||||
uiItemR(col, ptr, "use_bokeh", 0, NULL, ICON_NONE);
|
||||
}
|
||||
uiItemR(col, ptr, "use_gamma_correction", 0, NULL, ICON_NONE);
|
||||
}
|
||||
|
||||
|
||||
@@ -374,6 +374,10 @@ enum {
|
||||
CMP_NODEFLAG_MASK_NO_FEATHER = (1 << 1)
|
||||
};
|
||||
|
||||
enum {
|
||||
CMP_NODEFLAG_BLUR_REFERENCE = (1 << 0),
|
||||
};
|
||||
|
||||
typedef struct NodeFrame {
|
||||
short flag;
|
||||
short label_size;
|
||||
|
||||
@@ -1731,6 +1731,11 @@ static void def_cmp_blur(StructRNA *srna)
|
||||
{0, NULL, 0, NULL, NULL}
|
||||
};
|
||||
|
||||
prop = RNA_def_property(srna, "use_reference", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "custom1", CMP_NODEFLAG_BLUR_REFERENCE);
|
||||
RNA_def_property_ui_text(prop, "Reference", "Use size socket as a reference 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);
|
||||
@@ -1789,7 +1794,6 @@ static void def_cmp_blur(StructRNA *srna)
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "gamma", 1);
|
||||
RNA_def_property_ui_text(prop, "Gamma", "Apply filter on gamma corrected values");
|
||||
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
|
||||
|
||||
}
|
||||
|
||||
static void def_cmp_filter(StructRNA *srna)
|
||||
|
||||
Reference in New Issue
Block a user