[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [46299] branches/tile/source/blender/ compositor: Tile Branche
Monique Dewanchand
m.dewanchand at atmind.nl
Fri May 4 23:23:28 CEST 2012
Revision: 46299
http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=46299
Author: mdewanchand
Date: 2012-05-04 21:23:27 +0000 (Fri, 04 May 2012)
Log Message:
-----------
Tile Branche
[#31242] Fast Gaussian blur results in a black screen
Modified Paths:
--------------
branches/tile/source/blender/compositor/CMakeLists.txt
branches/tile/source/blender/compositor/nodes/COM_BlurNode.cpp
Added Paths:
-----------
branches/tile/source/blender/compositor/operations/COM_FastGaussianBlurOperation.cpp
branches/tile/source/blender/compositor/operations/COM_FastGaussianBlurOperation.h
Modified: branches/tile/source/blender/compositor/CMakeLists.txt
===================================================================
--- branches/tile/source/blender/compositor/CMakeLists.txt 2012-05-04 18:06:52 UTC (rev 46298)
+++ branches/tile/source/blender/compositor/CMakeLists.txt 2012-05-04 21:23:27 UTC (rev 46299)
@@ -305,6 +305,8 @@
operations/COM_BokehBlurOperation.h
operations/COM_VariableSizeBokehBlurOperation.cpp
operations/COM_VariableSizeBokehBlurOperation.h
+ operations/COM_FastGaussianBlurOperation.cpp
+ operations/COM_FastGaussianBlurOperation.h
operations/COM_BlurBaseOperation.cpp
operations/COM_BlurBaseOperation.h
operations/COM_DirectionalBlurOperation.cpp
Modified: branches/tile/source/blender/compositor/nodes/COM_BlurNode.cpp
===================================================================
--- branches/tile/source/blender/compositor/nodes/COM_BlurNode.cpp 2012-05-04 18:06:52 UTC (rev 46298)
+++ branches/tile/source/blender/compositor/nodes/COM_BlurNode.cpp 2012-05-04 21:23:27 UTC (rev 46299)
@@ -27,6 +27,7 @@
#include "COM_GaussianYBlurOperation.h"
#include "COM_ExecutionSystem.h"
#include "COM_GaussianBokehBlurOperation.h"
+#include "COM_FastGaussianBlurOperation.h"
BlurNode::BlurNode(bNode *editorNode): Node(editorNode) {
}
@@ -41,8 +42,14 @@
if (data->filtertype == R_FILTER_MITCH || data->filtertype == R_FILTER_CATROM) {
quality = COM_QUALITY_HIGH;
}
-
- if (!data->bokeh) {
+ if (data->filtertype == R_FILTER_FAST_GAUSS) {
+ FastGaussianBlurOperation *operationfgb = new FastGaussianBlurOperation();
+ operationfgb->setdata(data);
+ operationfgb->setSize(size);
+ this->getInputSocket(0)->relinkConnections(operationfgb->getInputSocket(0), true, 0, graph);
+ this->getOutputSocket(0)->relinkConnections(operationfgb->getOutputSocket(0));
+ graph->addOperation(operationfgb);
+ }else if (!data->bokeh) {
GaussianXBlurOperation *operationx = new GaussianXBlurOperation();
operationx->setData(data);
operationx->setQuality(quality);
Added: branches/tile/source/blender/compositor/operations/COM_FastGaussianBlurOperation.cpp
===================================================================
--- branches/tile/source/blender/compositor/operations/COM_FastGaussianBlurOperation.cpp (rev 0)
+++ branches/tile/source/blender/compositor/operations/COM_FastGaussianBlurOperation.cpp 2012-05-04 21:23:27 UTC (rev 46299)
@@ -0,0 +1,192 @@
+/*
+ * Copyright 2011, 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
+ */
+
+#include "COM_FastGaussianBlurOperation.h"
+#include "MEM_guardedalloc.h"
+#include "BLI_utildefines.h"
+
+FastGaussianBlurOperation::FastGaussianBlurOperation(): NodeOperation(){
+ this->inputOperation = NULL;
+ this->addInputSocket(COM_DT_COLOR);
+ this->addOutputSocket(COM_DT_COLOR);
+ this->setComplex(true);
+ this->data = NULL;
+}
+
+void FastGaussianBlurOperation::initExecution(){
+ this->inputOperation = this->getInputSocketReader(0);
+ sx = data->sizex * this->size/2.0f;
+ sy = data->sizey * this->size/2.0f;
+}
+
+void FastGaussianBlurOperation::deinitExecution(){
+ this->inputOperation = NULL;
+ this->data = NULL;
+}
+
+void FastGaussianBlurOperation::executePixel(float *color,int x, int y, MemoryBuffer *inputBuffers[], void *data) {
+ MemoryBuffer *newData = (MemoryBuffer*)data;
+
+ newData->read(color, x, y);
+
+}
+
+bool FastGaussianBlurOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output){
+ rcti newInput;
+
+ newInput.xmax = input->xmax + (sx);
+ newInput.xmin = input->xmin - (sx);
+ newInput.ymax = input->ymax + (sy);
+ newInput.ymin = input->ymin - (sy);
+
+ return NodeOperation::determineDependingAreaOfInterest(&newInput, readOperation, output);
+}
+
+void* FastGaussianBlurOperation::initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers){
+ MemoryBuffer *newBuf = (MemoryBuffer*)this->inputOperation->initializeTileData(rect, memoryBuffers);
+ MemoryBuffer *copy = newBuf->duplicate();
+
+ int c;
+ if ((sx == sy) && (sx > 0.f)) {
+ for (c=0; c<COM_NUMBER_OF_CHANNELS; ++c)
+ IIR_gauss(copy, sx, c, 3);
+ }
+ else {
+ if (sx > 0.f) {
+ for (c=0; c<COM_NUMBER_OF_CHANNELS; ++c)
+ IIR_gauss(copy, sx, c, 1);
+ }
+ if (sy > 0.f) {
+ for (c=0; c<COM_NUMBER_OF_CHANNELS; ++c)
+ IIR_gauss(copy, sy, c, 2);
+ }
+ }
+ return copy;
+}
+
+void FastGaussianBlurOperation::deinitializeTileData(rcti *rect, MemoryBuffer **memoryBuffers, void *data){
+ MemoryBuffer *newData = (MemoryBuffer*)data;
+ delete newData;
+}
+
+void FastGaussianBlurOperation::IIR_gauss(MemoryBuffer *src, float sigma, int chan, int xy) {
+ double q, q2, sc, cf[4], tsM[9], tsu[3], tsv[3];
+ double *X, *Y, *W;
+ int i, x, y, sz;
+ float *buffer = src->getBuffer();
+
+ // <0.5 not valid, though can have a possibly useful sort of sharpening effect
+ if (sigma < 0.5f) return;
+
+ if ((xy < 1) || (xy > 3)) xy = 3;
+
+ // XXX The YVV macro defined below explicitly expects sources of at least 3x3 pixels,
+ // so just skiping blur along faulty direction if src's def is below that limit!
+ if (src->getWidth() < 3) xy &= ~(int) 1;
+ if (src->getHeight() < 3) xy &= ~(int) 2;
+ if (xy < 1) return;
+
+ // see "Recursive Gabor Filtering" by Young/VanVliet
+ // all factors here in double.prec. Required, because for single.prec it seems to blow up if sigma > ~200
+ if (sigma >= 3.556f)
+ q = 0.9804f*(sigma - 3.556f) + 2.5091f;
+ else // sigma >= 0.5
+ q = (0.0561f*sigma + 0.5784f)*sigma - 0.2568f;
+ q2 = q*q;
+ sc = (1.1668 + q)*(3.203729649 + (2.21566 + q)*q);
+ // no gabor filtering here, so no complex multiplies, just the regular coefs.
+ // all negated here, so as not to have to recalc Triggs/Sdika matrix
+ cf[1] = q*(5.788961737 + (6.76492 + 3.0*q)*q)/ sc;
+ cf[2] = -q2*(3.38246 + 3.0*q)/sc;
+ // 0 & 3 unchanged
+ cf[3] = q2*q/sc;
+ cf[0] = 1.0 - cf[1] - cf[2] - cf[3];
+
+ // Triggs/Sdika border corrections,
+ // it seems to work, not entirely sure if it is actually totally correct,
+ // Besides J.M.Geusebroek's anigauss.c (see http://www.science.uva.nl/~mark),
+ // found one other implementation by Cristoph Lampert,
+ // but neither seem to be quite the same, result seems to be ok so far anyway.
+ // Extra scale factor here to not have to do it in filter,
+ // though maybe this had something to with the precision errors
+ sc = cf[0]/((1.0 + cf[1] - cf[2] + cf[3])*(1.0 - cf[1] - cf[2] - cf[3])*(1.0 + cf[2] + (cf[1] - cf[3])*cf[3]));
+ tsM[0] = sc*(-cf[3]*cf[1] + 1.0 - cf[3]*cf[3] - cf[2]);
+ tsM[1] = sc*((cf[3] + cf[1])*(cf[2] + cf[3]*cf[1]));
+ tsM[2] = sc*(cf[3]*(cf[1] + cf[3]*cf[2]));
+ tsM[3] = sc*(cf[1] + cf[3]*cf[2]);
+ tsM[4] = sc*(-(cf[2] - 1.0)*(cf[2] + cf[3]*cf[1]));
+ tsM[5] = sc*(-(cf[3]*cf[1] + cf[3]*cf[3] + cf[2] - 1.0)*cf[3]);
+ tsM[6] = sc*(cf[3]*cf[1] + cf[2] + cf[1]*cf[1] - cf[2]*cf[2]);
+ tsM[7] = sc*(cf[1]*cf[2] + cf[3]*cf[2]*cf[2] - cf[1]*cf[3]*cf[3] - cf[3]*cf[3]*cf[3] - cf[3]*cf[2] + cf[3]);
+ tsM[8] = sc*(cf[3]*(cf[1] + cf[3]*cf[2]));
+
+#define YVV(L) \
+{ \
+W[0] = cf[0]*X[0] + cf[1]*X[0] + cf[2]*X[0] + cf[3]*X[0]; \
+W[1] = cf[0]*X[1] + cf[1]*W[0] + cf[2]*X[0] + cf[3]*X[0]; \
+W[2] = cf[0]*X[2] + cf[1]*W[1] + cf[2]*W[0] + cf[3]*X[0]; \
+for (i=3; i<L; i++) \
+W[i] = cf[0]*X[i] + cf[1]*W[i-1] + cf[2]*W[i-2] + cf[3]*W[i-3]; \
+tsu[0] = W[L-1] - X[L-1]; \
+tsu[1] = W[L-2] - X[L-1]; \
+tsu[2] = W[L-3] - X[L-1]; \
+tsv[0] = tsM[0]*tsu[0] + tsM[1]*tsu[1] + tsM[2]*tsu[2] + X[L-1]; \
+tsv[1] = tsM[3]*tsu[0] + tsM[4]*tsu[1] + tsM[5]*tsu[2] + X[L-1]; \
+tsv[2] = tsM[6]*tsu[0] + tsM[7]*tsu[1] + tsM[8]*tsu[2] + X[L-1]; \
+Y[L-1] = cf[0]*W[L-1] + cf[1]*tsv[0] + cf[2]*tsv[1] + cf[3]*tsv[2]; \
+Y[L-2] = cf[0]*W[L-2] + cf[1]*Y[L-1] + cf[2]*tsv[0] + cf[3]*tsv[1]; \
+Y[L-3] = cf[0]*W[L-3] + cf[1]*Y[L-2] + cf[2]*Y[L-1] + cf[3]*tsv[0]; \
+for (i=L-4; i>=0; i--) \
+Y[i] = cf[0]*W[i] + cf[1]*Y[i+1] + cf[2]*Y[i+2] + cf[3]*Y[i+3]; \
+}
+
+ // intermediate buffers
+ sz = MAX2(src->getWidth(), src->getHeight());
+ X = (double*)MEM_callocN(sz*sizeof(double), "IIR_gauss X buf");
+ Y = (double*)MEM_callocN(sz*sizeof(double), "IIR_gauss Y buf");
+ W = (double*)MEM_callocN(sz*sizeof(double), "IIR_gauss W buf");
+ if (xy & 1) { // H
+ for (y=0; y<src->getHeight(); ++y) {
+ const int yx = y*src->getWidth();
+ for (x=0; x<src->getWidth(); ++x)
+ X[x] = buffer[(x + yx)*COM_NUMBER_OF_CHANNELS + chan];
+ YVV(src->getWidth());
+ for (x=0; x<src->getWidth(); ++x)
+ buffer[(x + yx)*COM_NUMBER_OF_CHANNELS + chan] = Y[x];
+ }
+ }
+ if (xy & 2) { // V
+ for (x=0; x<src->getWidth(); ++x) {
+ for (y=0; y<src->getHeight(); ++y)
+ X[y] = buffer[(x + y*src->getWidth())*COM_NUMBER_OF_CHANNELS + chan];
+ YVV(src->getHeight());
+ for (y=0; y<src->getHeight(); ++y)
+ buffer[(x + y*src->getWidth())*COM_NUMBER_OF_CHANNELS + chan] = Y[y];
+ }
+ }
+
+ MEM_freeN(X);
+ MEM_freeN(W);
+ MEM_freeN(Y);
+#undef YVV
+
+}
Added: branches/tile/source/blender/compositor/operations/COM_FastGaussianBlurOperation.h
===================================================================
--- branches/tile/source/blender/compositor/operations/COM_FastGaussianBlurOperation.h (rev 0)
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list