svn merge ^/trunk/blender -r49061:49063

This commit is contained in:
Campbell Barton
2012-07-19 11:35:45 +00:00
6 changed files with 153 additions and 103 deletions

View File

@@ -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);

View File

@@ -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);

View File

@@ -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

View File

@@ -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);
}

View File

@@ -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;

View File

@@ -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)