[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [48523] trunk/blender/source/blender/ compositor: Optimized the area of interest of the lensdistortion node.

Jeroen Bakker j.bakker at atmind.nl
Tue Jul 3 11:05:20 CEST 2012


Revision: 48523
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=48523
Author:   jbakker
Date:     2012-07-03 09:05:19 +0000 (Tue, 03 Jul 2012)
Log Message:
-----------
Optimized the area of interest of the lensdistortion node.
This will have faster feedback to the user, as lensdistortion is mostly
a node that is located at the end of a composite

Modified Paths:
--------------
    trunk/blender/source/blender/compositor/nodes/COM_LensDistortionNode.cpp
    trunk/blender/source/blender/compositor/operations/COM_ScreenLensDistortionOperation.cpp
    trunk/blender/source/blender/compositor/operations/COM_ScreenLensDistortionOperation.h

Modified: trunk/blender/source/blender/compositor/nodes/COM_LensDistortionNode.cpp
===================================================================
--- trunk/blender/source/blender/compositor/nodes/COM_LensDistortionNode.cpp	2012-07-03 09:02:41 UTC (rev 48522)
+++ trunk/blender/source/blender/compositor/nodes/COM_LensDistortionNode.cpp	2012-07-03 09:05:19 UTC (rev 48523)
@@ -48,13 +48,21 @@
 	}
 	else {
 		ScreenLensDistortionOperation *operation = new ScreenLensDistortionOperation();
+		operation->setData(data);
+		if (!(this->getInputSocket(1)->isConnected() || this->getInputSocket(2)->isConnected())) 
+		{
+			// no nodes connected to the distortion and dispersion. We can precalculate some values
+			float distortion = ((const bNodeSocketValueFloat *)this->getInputSocket(1)->getbNodeSocket()->default_value)->value;
+			float dispersion = ((const bNodeSocketValueFloat *)this->getInputSocket(2)->getbNodeSocket()->default_value)->value;
+			operation->setDistortionAndDispersion(distortion, dispersion);
+		}
 
 		this->getInputSocket(0)->relinkConnections(operation->getInputSocket(0), 0, graph);
 		this->getInputSocket(1)->relinkConnections(operation->getInputSocket(1), 1, graph);
 		this->getInputSocket(2)->relinkConnections(operation->getInputSocket(2), 2, graph);
+
 		this->getOutputSocket(0)->relinkConnections(operation->getOutputSocket(0));
 
-		operation->setData(data);
 		graph->addOperation(operation);
 	}
 

Modified: trunk/blender/source/blender/compositor/operations/COM_ScreenLensDistortionOperation.cpp
===================================================================
--- trunk/blender/source/blender/compositor/operations/COM_ScreenLensDistortionOperation.cpp	2012-07-03 09:02:41 UTC (rev 48522)
+++ trunk/blender/source/blender/compositor/operations/COM_ScreenLensDistortionOperation.cpp	2012-07-03 09:05:19 UTC (rev 48523)
@@ -42,6 +42,10 @@
 void ScreenLensDistortionOperation::initExecution()
 {
 	this->m_inputProgram = this->getInputSocketReader(0);
+	this->initMutex();
+	this->m_cx = 0.5f * (float)getWidth();
+	this->m_cy = 0.5f * (float)getHeight();
+	
 }
 
 void *ScreenLensDistortionOperation::initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers)
@@ -139,52 +143,192 @@
 
 void ScreenLensDistortionOperation::deinitExecution()
 {
+	this->deinitMutex();
 	this->m_inputProgram = NULL;
 }
 
-void ScreenLensDistortionOperation::determineUV(float result[2], float x, float y) const
+void ScreenLensDistortionOperation::determineUV(float result[4], float x, float y, float distortion, float dispersion) 
 {
+	if (!this->m_valuesAvailable) {
+		updateVariables(distortion, dispersion);
+	}
+	determineUV(result, x, y);
+}
+
+void ScreenLensDistortionOperation::determineUV(float result[4], float x, float y) const
+{
+	const float height = this->getHeight();
+	const float width = this->getWidth();
+	
+	float d, t, ln[6] = {0, 0, 0, 0, 0, 0};
 	const float v = this->m_sc * ((y + 0.5f) - this->m_cy) / this->m_cy;
 	const float u = this->m_sc * ((x + 0.5f) - this->m_cx) / this->m_cx;
-	const float t = ABS(MIN3(this->m_kr, this->m_kg, this->m_kb) * 4);
-	float d = 1.f / (1.f + sqrtf(t));
-	result[0] = (u * d + 0.5f) * getWidth() - 0.5f;
-	result[1] = (v * d + 0.5f) * getHeight() - 0.5f;
+	const float uv_dot = u * u + v * v;
+
+	if ((t = 1.f - this->m_kr4 * uv_dot) >= 0.f) {
+		d = 1.f / (1.f + sqrtf(t));
+		ln[0] = (u * d + 0.5f) * width - 0.5f, ln[1] = (v * d + 0.5f) * height - 0.5f;
+	}
+	if ((t = 1.f - this->m_kg4 * uv_dot) >= 0.f) {
+		d = 1.f / (1.f + sqrtf(t));
+		ln[2] = (u * d + 0.5f) * width - 0.5f, ln[3] = (v * d + 0.5f) * height - 0.5f;
+	}
+	if ((t = 1.f - this->m_kb4 * uv_dot) >= 0.f) {
+		d = 1.f / (1.f + sqrtf(t));
+		ln[4] = (u * d + 0.5f) * width - 0.5f, ln[5] = (v * d + 0.5f) * height - 0.5f;
+	}
+
+	float jit = this->m_data->jit;
+	float z;
+	{
+		// RG
+		const int dx = ln[2] - ln[0], dy = ln[3] - ln[1];
+		const float dsf = sqrtf((float)dx * dx + dy * dy) + 1.f;
+		const int ds = (int)(jit ? ((dsf < 4.f) ? 2.f : sqrtf(dsf)) : dsf);
+		const float sd = 1.f / (float)ds;
+
+		z = ds;
+		const float tz = ((float)z + (1.0f)) * sd;
+		t = 1.0f - (this->m_kr4 + tz * this->m_drg) * uv_dot;
+		d = 1.0f / (1.f + sqrtf(t));
+		const float nx = (u * d + 0.5f) * width - 0.5f;
+		const float ny = (v * d + 0.5f) * height - 0.5f;
+		result[0] = nx;
+		result[1] = ny;
+	}
+	{
+		// GB
+		const int dx = ln[4] - ln[2], dy = ln[5] - ln[3];
+		const float dsf = sqrtf((float)dx * dx + dy * dy) + 1.f;
+		const int ds = (int)(jit ? ((dsf < 4.f) ? 2.f : sqrtf(dsf)) : dsf);
+		const float sd = 1.f / (float)ds;
+
+		z = ds;
+		const float tz = ((float)z + (1.0f)) * sd;
+		t = 1.f - (this->m_kg4 + tz * this->m_dgb) * uv_dot;
+		d = 1.f / (1.f + sqrtf(t));
+		const float nx = (u * d + 0.5f) * width - 0.5f;
+		const float ny = (v * d + 0.5f) * height - 0.5f;
+		result[2] = nx;
+		result[3] = ny;
+	}
 }
 
 bool ScreenLensDistortionOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output)
 {
+	rcti newInputValue;
+	newInputValue.xmin = 0;
+	newInputValue.ymin = 0;
+	newInputValue.xmax = 2;
+	newInputValue.ymax = 2;
+	
+	NodeOperation *operation = getInputOperation(1);
+	if (operation->determineDependingAreaOfInterest(&newInputValue, readOperation, output) ) {
+		return true;
+	}
+
+	operation = getInputOperation(2);
+	if (operation->determineDependingAreaOfInterest(&newInputValue, readOperation, output) ) {
+		return true;
+	}
+
+#define MARGIN 64
+
+#define UPDATE_INPUT \
+		newInput.xmin = MIN3(newInput.xmin, coords[0], coords[2]); \
+		newInput.ymin = MIN3(newInput.ymin, coords[1], coords[3]); \
+		newInput.xmax = MAX3(newInput.xmax, coords[0], coords[2]); \
+		newInput.ymax = MAX3(newInput.ymax, coords[1], coords[3]);
+	
 	rcti newInput;
-	newInput.xmin = 0;
-	newInput.ymin = 0;
-	newInput.ymax = this->m_inputProgram->getHeight();
-	newInput.xmax = this->m_inputProgram->getWidth();
-	return NodeOperation::determineDependingAreaOfInterest(&newInput, readOperation, output);
+	float margin;
+	float coords[4];
+	if (m_valuesAvailable) {
+		determineUV(coords, input->xmin, input->ymin);
+		newInput.xmin = coords[0];
+		newInput.ymin = coords[1];
+		newInput.xmax = coords[0];
+		newInput.ymax = coords[1];
+		UPDATE_INPUT;
+		determineUV(coords, input->xmin, input->ymax);
+		UPDATE_INPUT;
+		determineUV(coords, input->xmax, input->ymax);
+		UPDATE_INPUT;
+		determineUV(coords, input->xmax, input->ymin);
+		UPDATE_INPUT;
+		margin = (ABS(this->m_distortion)+this->m_dispersion)*MARGIN;
+	} 
+	else 
+	{
+		determineUV(coords, input->xmin, input->ymin, 1.0f, 1.0f);
+		newInput.xmin = coords[0];
+		newInput.ymin = coords[1];
+		newInput.xmax = coords[0];
+		newInput.ymax = coords[1];
+		UPDATE_INPUT;
+		determineUV(coords, input->xmin, input->ymin, -1.0f, 1.0f);
+		UPDATE_INPUT;
+		
+		determineUV(coords, input->xmin, input->ymax, -1.0f, 1.0f);
+		UPDATE_INPUT;
+		determineUV(coords, input->xmin, input->ymax, 1.0f, 1.0f);
+		UPDATE_INPUT;
+		
+		determineUV(coords, input->xmax, input->ymax, -1.0f, 1.0f);
+		UPDATE_INPUT;
+		determineUV(coords, input->xmax, input->ymax, 1.0f, 1.0f);
+		UPDATE_INPUT;
+		
+		determineUV(coords, input->xmax, input->ymin, -1.0f, 1.0f);
+		UPDATE_INPUT;
+		determineUV(coords, input->xmax, input->ymin, 1.0f, 1.0f);
+		UPDATE_INPUT;
+		margin=MARGIN;
+	}
+
+#undef UPDATE_INPUT
+	newInput.xmin -= margin;
+	newInput.ymin -= margin;
+	newInput.xmax += margin;
+	newInput.ymax += margin;
+
+	operation = getInputOperation(0);
+	if (operation->determineDependingAreaOfInterest(&newInput, readOperation, output) ) {
+		return true;
+	}
+	return false;
 }
 
+void ScreenLensDistortionOperation::updateVariables(float distortion, float dispersion)
+{
+	this->m_kg = MAX2(MIN2(distortion, 1.f), -0.999f);
+	// smaller dispersion range for somewhat more control
+	const float d = 0.25f * MAX2(MIN2(dispersion, 1.f), 0.f);
+	this->m_kr = MAX2(MIN2((this->m_kg + d), 1.0f), -0.999f);
+	this->m_kb = MAX2(MIN2((this->m_kg - d), 1.0f), -0.999f);
+	this->m_maxk = MAX3(this->m_kr, this->m_kg, this->m_kb);
+	this->m_sc = (this->m_data->fit && (this->m_maxk > 0.f)) ? (1.f / (1.f + 2.f * this->m_maxk)) : (1.f / (1.f + this->m_maxk));
+	this->m_drg = 4.f * (this->m_kg - this->m_kr);
+	this->m_dgb = 4.f * (this->m_kb - this->m_kg);
+
+	this->m_kr4 = this->m_kr * 4.0f;
+	this->m_kg4 = this->m_kg * 4.0f;
+	this->m_kb4 = this->m_kb * 4.0f;	
+}
+
 void ScreenLensDistortionOperation::updateDispersionAndDistortion(MemoryBuffer **inputBuffers)
 {
+	if (this->m_valuesAvailable) return;
+	
+	this->lockMutex();
 	if (!this->m_valuesAvailable) {
 		float result[4];
 		this->getInputSocketReader(1)->read(result, 0, 0, COM_PS_NEAREST, inputBuffers);
 		this->m_distortion = result[0];
 		this->getInputSocketReader(2)->read(result, 0, 0, COM_PS_NEAREST, inputBuffers);
 		this->m_dispersion = result[0];
-		this->m_kg = MAX2(MIN2(this->m_distortion, 1.f), -0.999f);
-		// smaller dispersion range for somewhat more control
-		const float d = 0.25f * MAX2(MIN2(this->m_dispersion, 1.f), 0.f);
-		this->m_kr = MAX2(MIN2((this->m_kg + d), 1.0f), -0.999f);
-		this->m_kb = MAX2(MIN2((this->m_kg - d), 1.0f), -0.999f);
-		this->m_maxk = MAX3(this->m_kr, this->m_kg, this->m_kb);
-		this->m_sc = (this->m_data->fit && (this->m_maxk > 0.f)) ? (1.f / (1.f + 2.f * this->m_maxk)) : (1.f / (1.f + this->m_maxk));
-		this->m_drg = 4.f * (this->m_kg - this->m_kr);
-		this->m_dgb = 4.f * (this->m_kb - this->m_kg);
-	
-		this->m_kr4 = this->m_kr * 4.0f;
-		this->m_kg4 = this->m_kg * 4.0f;
-		this->m_kb4 = this->m_kb * 4.0f;
-		this->m_cx = 0.5f * (float)getWidth();
-		this->m_cy = 0.5f * (float)getHeight();
+		updateVariables(this->m_distortion, this->m_dispersion);
 		this->m_valuesAvailable = true;
 	}
+	this->unlockMutex();
 }

Modified: trunk/blender/source/blender/compositor/operations/COM_ScreenLensDistortionOperation.h
===================================================================
--- trunk/blender/source/blender/compositor/operations/COM_ScreenLensDistortionOperation.h	2012-07-03 09:02:41 UTC (rev 48522)
+++ trunk/blender/source/blender/compositor/operations/COM_ScreenLensDistortionOperation.h	2012-07-03 09:05:19 UTC (rev 48523)
@@ -66,9 +66,23 @@
 	
 	bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output);
 
+	/**
+	 * @brief Set the distortion and dispersion and precalc some values
+	 * @param distortion
+	 * @param dispersion
+	 */

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list