[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [47991] trunk/blender/source/blender/ compositor: support for negative feather dilate/erode

Campbell Barton ideasman42 at gmail.com
Sat Jun 16 16:40:24 CEST 2012


Revision: 47991
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=47991
Author:   campbellbarton
Date:     2012-06-16 14:40:16 +0000 (Sat, 16 Jun 2012)
Log Message:
-----------
support for negative feather dilate/erode

Modified Paths:
--------------
    trunk/blender/source/blender/compositor/nodes/COM_DilateErodeNode.cpp
    trunk/blender/source/blender/compositor/operations/COM_GaussianAlphaXBlurOperation.cpp
    trunk/blender/source/blender/compositor/operations/COM_GaussianAlphaXBlurOperation.h
    trunk/blender/source/blender/compositor/operations/COM_GaussianAlphaYBlurOperation.cpp
    trunk/blender/source/blender/compositor/operations/COM_GaussianAlphaYBlurOperation.h

Modified: trunk/blender/source/blender/compositor/nodes/COM_DilateErodeNode.cpp
===================================================================
--- trunk/blender/source/blender/compositor/nodes/COM_DilateErodeNode.cpp	2012-06-16 14:11:30 UTC (rev 47990)
+++ trunk/blender/source/blender/compositor/nodes/COM_DilateErodeNode.cpp	2012-06-16 14:40:16 UTC (rev 47991)
@@ -74,50 +74,49 @@
 	}
 	else if (editorNode->custom1 == CMP_NODE_DILATEERODE_DISTANCE_FEATHER) {
 		/* this uses a modified gaussian blur function otherwise its far too slow */
-		if (editorNode->custom2 > 0) {
+		CompositorQuality quality = context->getQuality();
 
-			CompositorQuality quality = context->getQuality();
+		/* initialize node data */
+		NodeBlurData *data = (NodeBlurData *)&this->alpha_blur;
+		memset(data, 0, sizeof(*data));
+		data->filtertype = R_FILTER_GAUSS;
 
-			/* initialize node data */
-			NodeBlurData *data = (NodeBlurData *)&this->alpha_blur;
-			memset(data, 0, sizeof(*data));
+		if (editorNode->custom2 > 0) {
 			data->sizex = data->sizey = editorNode->custom2;
-			data->filtertype = R_FILTER_GAUSS;
+		}
+		else {
+			data->sizex = data->sizey = -editorNode->custom2;
 
-			GaussianAlphaXBlurOperation *operationx = new GaussianAlphaXBlurOperation();
-			operationx->setData(data);
-			operationx->setQuality(quality);
-			this->getInputSocket(0)->relinkConnections(operationx->getInputSocket(0), 0, graph);
-			// this->getInputSocket(1)->relinkConnections(operationx->getInputSocket(1), 1, graph); // no size input yet
-			graph->addOperation(operationx);
-			GaussianAlphaYBlurOperation *operationy = new GaussianAlphaYBlurOperation();
-			operationy->setData(data);
-			operationy->setQuality(quality);
-			this->getOutputSocket(0)->relinkConnections(operationy->getOutputSocket());
-			graph->addOperation(operationy);
-			addLink(graph, operationx->getOutputSocket(), operationy->getInputSocket(0));
-			// addLink(graph, operationx->getInputSocket(1)->getConnection()->getFromSocket(), operationy->getInputSocket(1)); // no size input yet
-			addPreviewOperation(graph, operationy->getOutputSocket());
+		}
 
-			/* TODO? */
-			/* see gaussian blue node for original usage */
+		GaussianAlphaXBlurOperation *operationx = new GaussianAlphaXBlurOperation();
+		operationx->setData(data);
+		operationx->setQuality(quality);
+		this->getInputSocket(0)->relinkConnections(operationx->getInputSocket(0), 0, graph);
+		// this->getInputSocket(1)->relinkConnections(operationx->getInputSocket(1), 1, graph); // no size input yet
+		graph->addOperation(operationx);
+		GaussianAlphaYBlurOperation *operationy = new GaussianAlphaYBlurOperation();
+		operationy->setData(data);
+		operationy->setQuality(quality);
+		this->getOutputSocket(0)->relinkConnections(operationy->getOutputSocket());
+		graph->addOperation(operationy);
+		addLink(graph, operationx->getOutputSocket(), operationy->getInputSocket(0));
+		// addLink(graph, operationx->getInputSocket(1)->getConnection()->getFromSocket(), operationy->getInputSocket(1)); // no size input yet
+		addPreviewOperation(graph, operationy->getOutputSocket());
+
+		/* TODO? */
+		/* see gaussian blue node for original usage */
 #if 0
-			if (!connectedSizeSocket) {
-				operationx->setSize(size);
-				operationy->setSize(size);
-			}
+		if (!connectedSizeSocket) {
+			operationx->setSize(size);
+			operationy->setSize(size);
+		}
 #else
-			operationx->setSize(1.0f);
-			operationy->setSize(1.0f);
+		operationx->setSize(1.0f);
+		operationy->setSize(1.0f);
 #endif
-		}
-		else {
-			ErodeDistanceOperation *operation = new ErodeDistanceOperation();
-			operation->setDistance(-editorNode->custom2);
-			this->getInputSocket(0)->relinkConnections(operation->getInputSocket(0), 0, graph);
-			this->getOutputSocket(0)->relinkConnections(operation->getOutputSocket(0));
-			graph->addOperation(operation);
-		}
+		operationx->setSubtract(editorNode->custom2 < 0);
+		operationy->setSubtract(editorNode->custom2 < 0);
 	}
 	else {
 		if (editorNode->custom2 > 0) {

Modified: trunk/blender/source/blender/compositor/operations/COM_GaussianAlphaXBlurOperation.cpp
===================================================================
--- trunk/blender/source/blender/compositor/operations/COM_GaussianAlphaXBlurOperation.cpp	2012-06-16 14:11:30 UTC (rev 47990)
+++ trunk/blender/source/blender/compositor/operations/COM_GaussianAlphaXBlurOperation.cpp	2012-06-16 14:40:16 UTC (rev 47991)
@@ -81,8 +81,14 @@
 	}
 }
 
+BLI_INLINE float finv_test(const float f, const bool test)
+{
+	return (LIKELY(test == false)) ? f : 1.0f - f;
+}
+
 void GaussianAlphaXBlurOperation::executePixel(float *color, int x, int y, MemoryBuffer *inputBuffers[], void *data)
 {
+	const bool do_invert = this->do_subtract;
 	MemoryBuffer *inputBuffer = (MemoryBuffer *)data;
 	float *buffer = inputBuffer->getBuffer();
 	int bufferwidth = inputBuffer->getWidth();
@@ -108,12 +114,12 @@
 	float overallmultiplyer = 0.0f;
 
 	/* dilate */
-	float value_max = buffer[(x * 4) + (y * 4 * bufferwidth)]; /* init with the current color to avoid unneeded lookups */
+	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->rad;
-		float value = buffer[bufferindex];
+		float value = finv_test(buffer[bufferindex], do_invert);
 		float multiplyer;
 
 		/* gauss */
@@ -131,7 +137,7 @@
 			multiplyer = distbuf_inv[index];
 #endif
 			value *= multiplyer;
-			if ((value > value_max) == TRUE) {
+			if (value > value_max) {
 				value_max = value;
 				distfacinv_max = multiplyer;
 			}
@@ -143,7 +149,7 @@
 	/* blend between the max value and gauss blue - gives nice feather */
 	const float value_gauss = tempColor / overallmultiplyer;
 	const float value_final = (value_max * distfacinv_max) + (value_gauss * (1.0f - distfacinv_max));
-	color[0] = value_final;
+	color[0] = finv_test(value_final, do_invert);
 }
 
 void GaussianAlphaXBlurOperation::deinitExecution()
@@ -164,7 +170,7 @@
 	sizeInput.ymin = 0;
 	sizeInput.xmax = 5;
 	sizeInput.ymax = 5;
-	
+
 	NodeOperation *operation = this->getInputOperation(1);
 	if (operation->determineDependingAreaOfInterest(&sizeInput, readOperation, output)) {
 		return true;

Modified: trunk/blender/source/blender/compositor/operations/COM_GaussianAlphaXBlurOperation.h
===================================================================
--- trunk/blender/source/blender/compositor/operations/COM_GaussianAlphaXBlurOperation.h	2012-06-16 14:11:30 UTC (rev 47990)
+++ trunk/blender/source/blender/compositor/operations/COM_GaussianAlphaXBlurOperation.h	2012-06-16 14:40:16 UTC (rev 47991)
@@ -30,6 +30,7 @@
 private:
 	float *gausstab;
 	float *distbuf_inv;
+	bool do_subtract;
 	int rad;
 	void updateGauss(MemoryBuffer **memoryBuffers);
 public:
@@ -52,5 +53,10 @@
 	
 	void *initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers);
 	bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output);
+
+	/**
+	 * Set subtract for Dilate/Erode functionality
+	 */
+	void setSubtract(bool subtract) { this->do_subtract = subtract; }
 };
 #endif

Modified: trunk/blender/source/blender/compositor/operations/COM_GaussianAlphaYBlurOperation.cpp
===================================================================
--- trunk/blender/source/blender/compositor/operations/COM_GaussianAlphaYBlurOperation.cpp	2012-06-16 14:11:30 UTC (rev 47990)
+++ trunk/blender/source/blender/compositor/operations/COM_GaussianAlphaYBlurOperation.cpp	2012-06-16 14:40:16 UTC (rev 47991)
@@ -79,8 +79,14 @@
 	}
 }
 
+BLI_INLINE float finv_test(const float f, const bool test)
+{
+	return (LIKELY(test == false)) ? f : 1.0f - f;
+}
+
 void GaussianAlphaYBlurOperation::executePixel(float *color, int x, int y, MemoryBuffer *inputBuffers[], void *data)
 {
+	const bool do_invert = this->do_subtract;
 	MemoryBuffer *inputBuffer = (MemoryBuffer *)data;
 	float *buffer = inputBuffer->getBuffer();
 	int bufferwidth = inputBuffer->getWidth();
@@ -104,14 +110,14 @@
 	float overallmultiplyer = 0.0f;
 
 	/* dilate */
-	float value_max = buffer[(x * 4) + (y * 4 * bufferwidth)]; /* init with the current color to avoid unneeded lookups */
+	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 ny = miny; ny < maxy; ny += step) {
 		int bufferindex = ((minx - bufferstartx) * 4) + ((ny - bufferstarty) * 4 * bufferwidth);
 
 		const int index = (ny - y) + this->rad;
-		float value = buffer[bufferindex];
+		float value = finv_test(buffer[bufferindex], do_invert);
 		float multiplyer;
 
 		/* gauss */
@@ -140,7 +146,7 @@
 	/* blend between the max value and gauss blue - gives nice feather */
 	const float value_gauss = tempColor / overallmultiplyer;
 	const float value_final = (value_max * distfacinv_max) + (value_gauss * (1.0f - distfacinv_max));
-	color[0] = value_final;
+	color[0] = finv_test(value_final, do_invert);
 }
 
 void GaussianAlphaYBlurOperation::deinitExecution()

Modified: trunk/blender/source/blender/compositor/operations/COM_GaussianAlphaYBlurOperation.h
===================================================================
--- trunk/blender/source/blender/compositor/operations/COM_GaussianAlphaYBlurOperation.h	2012-06-16 14:11:30 UTC (rev 47990)
+++ trunk/blender/source/blender/compositor/operations/COM_GaussianAlphaYBlurOperation.h	2012-06-16 14:40:16 UTC (rev 47991)
@@ -30,6 +30,7 @@
 private:
 	float *gausstab;
 	float *distbuf_inv;
+	bool do_subtract;
 	int rad;
 	void updateGauss(MemoryBuffer **memoryBuffers);
 public:
@@ -52,5 +53,10 @@
 	
 	void *initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers);
 	bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output);
+
+	/**
+	 * Set subtract for Dilate/Erode functionality
+	 */
+	void setSubtract(bool subtract) { this->do_subtract = subtract; }
 };
 #endif




More information about the Bf-blender-cvs mailing list