[Bf-blender-cvs] [51efa8a] master: Fix T38529, Blur node size 0 doesn't work.

Lukas Tönne noreply at git.blender.org
Thu Feb 13 11:57:12 CET 2014


Commit: 51efa8a1f53f230b72210289483dae66f01de51a
Author: Lukas Tönne
Date:   Thu Feb 13 11:46:15 2014 +0100
https://developer.blender.org/rB51efa8a1f53f230b72210289483dae66f01de51a

Fix T38529, Blur node size 0 doesn't work.

The blur operations were clamping the filter size to 1, which prevents
no-op blur nodes. Further any value < 1 would also be ignored and in
many combinations the filter scale setting ("Size") would only work in
integer steps.

Now most blur settings will work with smooth Size value scaling as well,
meaning you can choose a reasonably large filter size (e.g. 10) and then
use the Size factor to scale the actual blur radius smoothly.

Note that non-integer filter sizes also depend on the filter type
selected in the Blur node, e.g. "Flat" filtering will still ignore
smooth filter sizes. Gaussian filters work best for this purpose.

===================================================================

M	source/blender/compositor/operations/COM_BlurBaseOperation.cpp
M	source/blender/compositor/operations/COM_BlurBaseOperation.h
M	source/blender/compositor/operations/COM_GaussianAlphaXBlurOperation.cpp
M	source/blender/compositor/operations/COM_GaussianAlphaXBlurOperation.h
M	source/blender/compositor/operations/COM_GaussianAlphaYBlurOperation.cpp
M	source/blender/compositor/operations/COM_GaussianAlphaYBlurOperation.h
M	source/blender/compositor/operations/COM_GaussianBokehBlurOperation.cpp
M	source/blender/compositor/operations/COM_GaussianBokehBlurOperation.h
M	source/blender/compositor/operations/COM_GaussianXBlurOperation.cpp
M	source/blender/compositor/operations/COM_GaussianXBlurOperation.h
M	source/blender/compositor/operations/COM_GaussianYBlurOperation.cpp
M	source/blender/compositor/operations/COM_GaussianYBlurOperation.h

===================================================================

diff --git a/source/blender/compositor/operations/COM_BlurBaseOperation.cpp b/source/blender/compositor/operations/COM_BlurBaseOperation.cpp
index c8d53b6..d13fea9 100644
--- a/source/blender/compositor/operations/COM_BlurBaseOperation.cpp
+++ b/source/blender/compositor/operations/COM_BlurBaseOperation.cpp
@@ -68,20 +68,21 @@ void BlurBaseOperation::initExecution()
 
 }
 
-float *BlurBaseOperation::make_gausstab(int rad)
+float *BlurBaseOperation::make_gausstab(float rad, int size)
 {
 	float *gausstab, sum, val;
 	int i, n;
 
-	n = 2 * rad + 1;
+	n = 2 * size + 1;
 
 	gausstab = (float *)MEM_mallocN(sizeof(float) * n, __func__);
 
 	sum = 0.0f;
-	for (i = -rad; i <= rad; i++) {
-		val = RE_filter_value(this->m_data->filtertype, (float)i / (float)rad);
+	float fac = (rad > 0.0f ? 1.0f/rad : 0.0f);
+	for (i = -size; i <= size; i++) {
+		val = RE_filter_value(this->m_data->filtertype, (float)i * fac);
 		sum += val;
-		gausstab[i + rad] = val;
+		gausstab[i + size] = val;
 	}
 
 	sum = 1.0f / sum;
@@ -93,17 +94,18 @@ float *BlurBaseOperation::make_gausstab(int rad)
 
 /* normalized distance from the current (inverted so 1.0 is close and 0.0 is far)
  * 'ease' is applied after, looks nicer */
-float *BlurBaseOperation::make_dist_fac_inverse(int rad, int falloff)
+float *BlurBaseOperation::make_dist_fac_inverse(float rad, int size, int falloff)
 {
 	float *dist_fac_invert, val;
 	int i, n;
 
-	n = 2 * rad + 1;
+	n = 2 * size + 1;
 
 	dist_fac_invert = (float *)MEM_mallocN(sizeof(float) * n, __func__);
 
-	for (i = -rad; i <= rad; i++) {
-		val = 1.0f - fabsf(((float)i / (float)rad));
+	float fac = (rad > 0.0f ? 1.0f/rad : 0.0f);
+	for (i = -size; i <= size; i++) {
+		val = 1.0f - fabsf((float)i * fac);
 
 		/* keep in sync with proportional_falloff_curve_only_items */
 		switch (falloff) {
@@ -132,7 +134,7 @@ float *BlurBaseOperation::make_dist_fac_inverse(int rad, int falloff)
 				/* nothing */
 				break;
 		}
-		dist_fac_invert[i + rad] = val;
+		dist_fac_invert[i + size] = val;
 	}
 
 	return dist_fac_invert;
diff --git a/source/blender/compositor/operations/COM_BlurBaseOperation.h b/source/blender/compositor/operations/COM_BlurBaseOperation.h
index a868f0b..c5d89b1 100644
--- a/source/blender/compositor/operations/COM_BlurBaseOperation.h
+++ b/source/blender/compositor/operations/COM_BlurBaseOperation.h
@@ -33,8 +33,8 @@ private:
 protected:
 
 	BlurBaseOperation(DataType data_type);
-	float *make_gausstab(int rad);
-	float *make_dist_fac_inverse(int rad, int falloff);
+	float *make_gausstab(float rad, int size);
+	float *make_dist_fac_inverse(float rad, int size, int falloff);
 
 	void updateSize();
 
diff --git a/source/blender/compositor/operations/COM_GaussianAlphaXBlurOperation.cpp b/source/blender/compositor/operations/COM_GaussianAlphaXBlurOperation.cpp
index f4c73c3..4ae0b4e 100644
--- a/source/blender/compositor/operations/COM_GaussianAlphaXBlurOperation.cpp
+++ b/source/blender/compositor/operations/COM_GaussianAlphaXBlurOperation.cpp
@@ -32,7 +32,7 @@ extern "C" {
 GaussianAlphaXBlurOperation::GaussianAlphaXBlurOperation() : BlurBaseOperation(COM_DT_VALUE)
 {
 	this->m_gausstab = NULL;
-	this->m_rad = 0;
+	this->m_filtersize = 0;
 	this->m_falloff = -1;  /* intentionally invalid, so we can detect uninitialized values */
 }
 
@@ -54,12 +54,11 @@ void GaussianAlphaXBlurOperation::initExecution()
 	initMutex();
 
 	if (this->m_sizeavailable) {
-		float rad = this->m_size * this->m_data->sizex;
-		CLAMP(rad, 1.0f, MAX_GAUSSTAB_RADIUS);
-
-		this->m_rad = rad;
-		this->m_gausstab = BlurBaseOperation::make_gausstab(rad);
-		this->m_distbuf_inv = BlurBaseOperation::make_dist_fac_inverse(rad, this->m_falloff);
+		float rad = max_ff(m_size * m_data->sizex, 0.0f);
+		m_filtersize = min_ii(ceil(rad), MAX_GAUSSTAB_RADIUS);
+		
+		m_gausstab = BlurBaseOperation::make_gausstab(rad, m_filtersize);
+		m_distbuf_inv = BlurBaseOperation::make_dist_fac_inverse(rad, m_filtersize, m_falloff);
 	}
 }
 
@@ -67,20 +66,18 @@ void GaussianAlphaXBlurOperation::updateGauss()
 {
 	if (this->m_gausstab == NULL) {
 		updateSize();
-		float rad = this->m_size * this->m_data->sizex;
-		CLAMP(rad, 1.0f, MAX_GAUSSTAB_RADIUS);
-
-		this->m_rad = rad;
-		this->m_gausstab = BlurBaseOperation::make_gausstab(rad);
+		float rad = max_ff(m_size * m_data->sizex, 0.0f);
+		m_filtersize = min_ii(ceil(rad), MAX_GAUSSTAB_RADIUS);
+		
+		m_gausstab = BlurBaseOperation::make_gausstab(rad, m_filtersize);
 	}
 
 	if (this->m_distbuf_inv == NULL) {
 		updateSize();
-		float rad = this->m_size * this->m_data->sizex;
-		CLAMP(rad, 1.0f, MAX_GAUSSTAB_RADIUS);
-
-		this->m_rad = rad;
-		this->m_distbuf_inv = BlurBaseOperation::make_dist_fac_inverse(rad, this->m_falloff);
+		float rad = max_ff(m_size * m_data->sizex, 0.0f);
+		m_filtersize = min_ii(ceil(rad), MAX_GAUSSTAB_RADIUS);
+		
+		m_distbuf_inv = BlurBaseOperation::make_dist_fac_inverse(rad, m_filtersize, m_falloff);
 	}
 }
 
@@ -98,18 +95,15 @@ void GaussianAlphaXBlurOperation::executePixel(float output[4], int x, int y, vo
 	int bufferstartx = inputBuffer->getRect()->xmin;
 	int bufferstarty = inputBuffer->getRect()->ymin;
 
-	int miny = y;
-	int minx = x - this->m_rad;
-	int maxx = x + this->m_rad;  // UNUSED
-	miny = max(miny, inputBuffer->getRect()->ymin);
-	minx = max(minx, inputBuffer->getRect()->xmin);
-	maxx = min(maxx, inputBuffer->getRect()->xmax -1);
-
+	rcti &rect = *inputBuffer->getRect();
+	int xmin = max_ii(x - m_filtersize,     rect.xmin);
+	int xmax = min_ii(x + m_filtersize + 1, rect.xmax);
+	int ymin = max_ii(y,                    rect.ymin);
 
 	/* *** this is the main part which is different to 'GaussianXBlurOperation'  *** */
 	int step = getStep();
 	int offsetadd = getOffsetAdd();
-	int bufferindex = ((minx - bufferstartx) * 4) + ((miny - bufferstarty) * 4 * bufferwidth);
+	int bufferindex = ((xmin - bufferstartx) * 4) + ((ymin - bufferstarty) * 4 * bufferwidth);
 
 	/* gauss */
 	float alpha_accum = 0.0f;
@@ -119,8 +113,8 @@ void GaussianAlphaXBlurOperation::executePixel(float output[4], int x, int y, vo
 	float value_max = finv_test(buffer[(x * 4) + (y * 4 * bufferwidth)], do_invert); /* init with the current color to avoid unneeded lookups */
 	float distfacinv_max = 1.0f; /* 0 to 1 */
 
-	for (int nx = minx; nx <= maxx; nx += step) {
-		const int index = (nx - x) + this->m_rad;
+	for (int nx = xmin; nx < xmax; nx += step) {
+		const int index = (nx - x) + this->m_filtersize;
 		float value = finv_test(buffer[bufferindex], do_invert);
 		float multiplier;
 
@@ -178,8 +172,8 @@ bool GaussianAlphaXBlurOperation::determineDependingAreaOfInterest(rcti *input,
 #endif
 	{
 		if (this->m_sizeavailable && this->m_gausstab != NULL) {
-			newInput.xmax = input->xmax + this->m_rad + 1;
-			newInput.xmin = input->xmin - this->m_rad - 1;
+			newInput.xmax = input->xmax + this->m_filtersize + 1;
+			newInput.xmin = input->xmin - this->m_filtersize - 1;
 			newInput.ymax = input->ymax;
 			newInput.ymin = input->ymin;
 		}
diff --git a/source/blender/compositor/operations/COM_GaussianAlphaXBlurOperation.h b/source/blender/compositor/operations/COM_GaussianAlphaXBlurOperation.h
index 21e80c5..0d61e96 100644
--- a/source/blender/compositor/operations/COM_GaussianAlphaXBlurOperation.h
+++ b/source/blender/compositor/operations/COM_GaussianAlphaXBlurOperation.h
@@ -32,7 +32,7 @@ private:
 	float *m_distbuf_inv;
 	int m_falloff;  /* falloff for distbuf_inv */
 	bool m_do_subtract;
-	int m_rad;
+	int m_filtersize;
 	void updateGauss();
 public:
 	GaussianAlphaXBlurOperation();
diff --git a/source/blender/compositor/operations/COM_GaussianAlphaYBlurOperation.cpp b/source/blender/compositor/operations/COM_GaussianAlphaYBlurOperation.cpp
index 4866fb9..fb407bf 100644
--- a/source/blender/compositor/operations/COM_GaussianAlphaYBlurOperation.cpp
+++ b/source/blender/compositor/operations/COM_GaussianAlphaYBlurOperation.cpp
@@ -32,7 +32,7 @@ extern "C" {
 GaussianAlphaYBlurOperation::GaussianAlphaYBlurOperation() : BlurBaseOperation(COM_DT_VALUE)
 {
 	this->m_gausstab = NULL;
-	this->m_rad = 0;
+	this->m_filtersize = 0;
 	this->m_falloff = -1;  /* intentionally invalid, so we can detect uninitialized values */
 }
 
@@ -54,12 +54,11 @@ void GaussianAlphaYBlurOperation::initExecution()
 	initMutex();
 
 	if (this->m_sizeavailable) {
-		float rad = this->m_size * this->m_data->sizey;
-		CLAMP(rad, 1.0f, MAX_GAUSSTAB_RADIUS);
-
-		this->m_rad = rad;
-		this->m_gausstab = BlurBaseOperation::make_gausstab(rad);
-		this->m_distbuf_inv = BlurBaseOperation::make_dist_fac_inverse(rad, this->m_falloff);
+		float rad = max_ff(m_size * m_data->sizey, 0.0f);
+		m_filtersize = min_ii(ceil(rad), MAX_GAUSSTAB_RADIUS);
+		
+		m_gausstab = BlurBaseOperation::make_gausstab(rad, m_filtersize);
+		m_distbuf_inv = BlurBaseOperation::make_dist_fac_inverse(rad, m_filtersize, m_falloff);
 	}
 }
 
@@ -67,20 +66,18 @@ void GaussianAlphaYBlurOperation::updateGauss()
 {
 	if (this->m_gausstab == NULL) {
 		updateSize();
-		float rad = this->m_size * this->m_data->sizey;
-		CLAMP(rad, 1.0f, MAX_GAUSSTAB_RADIUS);
-
-		this->m_rad = rad;
-		this->m_gausstab = BlurBaseOperation::make_gausstab(rad);
+		float rad = max_ff(m_size * m_data->sizey, 0.0f);
+		m_filtersize = min_ii(ceil(rad), MAX_GAUSSTAB_RADIUS);
+		
+		m_gausstab = BlurBaseOperation::make_gausstab(rad, m_filtersize);
 	}
 
 	if (this->m_distbuf_inv == NULL) {
 		updateSize();
-		float rad = this->m_size * this->m_data->sizex;
-		CLAMP(rad, 1.0f, MAX_GAUSSTAB_RADIUS);
-
-		this->m_rad = rad;
-		this->m_distbuf_inv = BlurBaseOperation::make_dist_fac_inverse(rad, this->m_falloff);
+		float rad = max_ff(m_size * m_data->sizey, 0.0f);
+		m_filtersize = min_ii(ceil(rad), MAX_GAUSSTAB_RADIUS);
+		
+		m_distbuf_inv = BlurBaseOperation::make_dist_fac_inverse(rad, m_filtersize, m_falloff);
 	}
 }
 
@@ -98,12 +95,10 @@ void GaussianAlphaYBlurOperation::executePixel(float output[4], int x, int y, vo
 	int bufferstartx = inputBuffer->getRect()->xmin;
 	int bufferstarty = inputBuffer->getRect()->ymin;
 
-	int miny = y - this->m_rad;
-	int maxy = y + this->m_rad;
-	int minx = x;
-	miny = max(miny, inputBuffer->getRect()->ymin);
-	minx = max(minx, inputBuffer->getRect()->xmin);
-	maxy = min(maxy, inputBuffer->getR

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list