[Bf-blender-cvs] [c6f7f3b] fracture_modifier: memory optimization for smoke compressibility fix, dont use recursion but a queue to avoid potential stack overflows, thanks to angavrilov for this optimization

Martin Felke noreply at git.blender.org
Sat Jul 23 16:40:05 CEST 2016


Commit: c6f7f3bc385bb1f5e29f6230519938fcb49a9f8a
Author: Martin Felke
Date:   Sat Jul 23 16:39:25 2016 +0200
Branches: fracture_modifier
https://developer.blender.org/rBc6f7f3bc385bb1f5e29f6230519938fcb49a9f8a

memory optimization for smoke compressibility fix, dont use recursion but a queue to avoid potential stack overflows, thanks to angavrilov for this optimization

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

M	intern/smoke/intern/FLUID_3D.cpp
M	intern/smoke/intern/FLUID_3D.h

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

diff --git a/intern/smoke/intern/FLUID_3D.cpp b/intern/smoke/intern/FLUID_3D.cpp
index f80a96f..8a27818 100644
--- a/intern/smoke/intern/FLUID_3D.cpp
+++ b/intern/smoke/intern/FLUID_3D.cpp
@@ -1294,29 +1294,42 @@ void FLUID_3D::setObstacleBoundaries(float *_pressure, int zBegin, int zEnd)
 	}	// z-loop
 }
 
-void FLUID_3D::replaceComponentRec(int *buffer, size_t limit, size_t pos, int from, int to)
+void FLUID_3D::floodFillComponent(int *buffer, size_t *queue, size_t limit, size_t pos, int from, int to)
 {
-	/* Recursively replace 'from' with 'to' in the grid. Rely on (from != 0 && edges == 0) to stop. */
+	/* Flood 'from' cells with 'to' in the grid. Rely on (from != 0 && from != to && edges == 0) to stop. */
 	int offsets[] = { -1, +1, -_xRes, +_xRes, -_slabSize, +_slabSize };
+	size_t qend = 0;
 
 	buffer[pos] = to;
+	queue[qend++] = pos;
 
-	for (int i = 0; i < 6; i++) {
-		size_t next = pos + offsets[i];
+	for (size_t qidx = 0; qidx < qend; qidx++)
+	{
+		pos = queue[qidx];
+
+		for (int i = 0; i < 6; i++)
+		{
+			size_t next = pos + offsets[i];
 
-		if (next < limit && buffer[next] == from)
-			replaceComponentRec(buffer, limit, next, from, to);
+			if (next < limit && buffer[next] == from)
+			{
+				buffer[next] = to;
+				queue[qend++] = next;
+			}
+		}
 	}
 }
 
-void FLUID_3D::mergeComponents(int *buffer, size_t cur, size_t other)
+void FLUID_3D::mergeComponents(int *buffer, size_t *queue, size_t cur, size_t other)
 {
 	/* Replace higher value with lower. */
-	if (buffer[other] < buffer[cur]) {
-		replaceComponentRec(buffer, cur, cur, buffer[cur], buffer[other]);
+	if (buffer[other] < buffer[cur])
+	{
+		floodFillComponent(buffer, queue, cur, cur, buffer[cur], buffer[other]);
 	}
-	else if (buffer[cur] < buffer[other]) {
-		replaceComponentRec(buffer, cur, other, buffer[other], buffer[cur]);
+	else if (buffer[cur] < buffer[other])
+	{
+		floodFillComponent(buffer, queue, cur, other, buffer[other], buffer[cur]);
 	}
 }
 
@@ -1328,6 +1341,8 @@ void FLUID_3D::fixObstacleCompression(float *divergence)
 	/* Find compartments completely separated by obstacles.
 	 * Edge of the domain is automatically component 0. */
 	int *component = new int[_totalCells];
+	size_t *queue = new size_t[_totalCells];
+
 	memset(component, 0, sizeof(int) * _totalCells);
 
 	int next_id = 1;
@@ -1352,11 +1367,11 @@ void FLUID_3D::fixObstacleCompression(float *divergence)
 					}
 
 					if (!_obstacles[index - 1])
-						mergeComponents(component, index, index - 1);
+						mergeComponents(component, queue, index, index - 1);
 					if (!_obstacles[index - _xRes])
-						mergeComponents(component, index, index - _xRes);
+						mergeComponents(component, queue, index, index - _xRes);
 					if (!_obstacles[index - _slabSize])
-						mergeComponents(component, index, index - _slabSize);
+						mergeComponents(component, queue, index, index - _slabSize);
 
 					if (component[index] == next_id)
 						next_id++;
@@ -1365,6 +1380,8 @@ void FLUID_3D::fixObstacleCompression(float *divergence)
 		}
 	}
 
+	delete[] queue;
+
 	/* Compute average divergence within each component. */
 	float *total_divergence = new float[next_id];
 	int *component_size = new int[next_id];
diff --git a/intern/smoke/intern/FLUID_3D.h b/intern/smoke/intern/FLUID_3D.h
index 5335183..fe20c10 100644
--- a/intern/smoke/intern/FLUID_3D.h
+++ b/intern/smoke/intern/FLUID_3D.h
@@ -204,8 +204,8 @@ struct FLUID_3D
 		void advectMacCormackEnd1(int zBegin, int zEnd);
 		void advectMacCormackEnd2(int zBegin, int zEnd);
 
-		void replaceComponentRec(int *components, size_t limit, size_t pos, int from, int to);
-		void mergeComponents(int *components, size_t cur, size_t other);
+		void floodFillComponent(int *components, size_t *queue, size_t limit, size_t start, int from, int to);
+		void mergeComponents(int *components, size_t *queue, size_t cur, size_t other);
 
 		/* burning */
 		float *_burning_rate; // RNA pointer




More information about the Bf-blender-cvs mailing list