[Bf-blender-cvs] [998d1b091a9] soc-2018-cycles-volumes: Added sparse grid lookup to mesh volume generator.

Geraldine Chua noreply at git.blender.org
Thu Jun 7 17:18:57 CEST 2018


Commit: 998d1b091a90454cdc65ed8ea8101f28984298e4
Author: Geraldine Chua
Date:   Wed Jun 6 23:51:56 2018 +0800
Branches: soc-2018-cycles-volumes
https://developer.blender.org/rB998d1b091a90454cdc65ed8ea8101f28984298e4

Added sparse grid lookup to mesh volume generator.

Also made some minor operator additions/changes.

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

M	intern/cycles/render/mesh_volume.cpp
M	intern/cycles/util/util_math_float4.h
M	intern/cycles/util/util_math_int4.h
M	intern/cycles/util/util_sparse_grid.h

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

diff --git a/intern/cycles/render/mesh_volume.cpp b/intern/cycles/render/mesh_volume.cpp
index d1c49b456ff..8a55b89abcc 100644
--- a/intern/cycles/render/mesh_volume.cpp
+++ b/intern/cycles/render/mesh_volume.cpp
@@ -21,27 +21,11 @@
 #include "util/util_foreach.h"
 #include "util/util_logging.h"
 #include "util/util_progress.h"
+#include "util/util_sparse_grid.h"
 #include "util/util_types.h"
 
 CCL_NAMESPACE_BEGIN
 
-static size_t compute_voxel_index(const int3 &resolution, size_t x, size_t y, size_t z)
-{
-	if(x == -1 || x >= resolution.x) {
-		return -1;
-	}
-
-	if(y == -1 || y >= resolution.y) {
-		return -1;
-	}
-
-	if(z == -1 || z >= resolution.z) {
-		return -1;
-	}
-
-	return x + y*resolution.x + z*resolution.x*resolution.y;
-}
-
 struct QuadData {
 	int v0, v1, v2, v3;
 
@@ -200,7 +184,7 @@ void VolumeMeshBuilder::add_node(int x, int y, int z)
 
 	assert((index_x >= 0) && (index_y >= 0) && (index_z >= 0));
 
-	const size_t index = compute_voxel_index(res, index_x, index_y, index_z);
+	const size_t index = compute_index(index_x, index_y, index_z, res);
 
 	/* We already have a node here. */
 	if(grid[index] == 1) {
@@ -253,7 +237,7 @@ void VolumeMeshBuilder::generate_vertices_and_quads(
 	for(int z = 0; z < res.z; ++z) {
 		for(int y = 0; y < res.y; ++y) {
 			for(int x = 0; x < res.x; ++x) {
-				size_t voxel_index = compute_voxel_index(res, x, y, z);
+				size_t voxel_index = compute_index(x, y, z, res);
 				if(grid[voxel_index] == 0) {
 					continue;
 				}
@@ -281,32 +265,32 @@ void VolumeMeshBuilder::generate_vertices_and_quads(
 				 * an inactive node.
 				 */
 
-				voxel_index = compute_voxel_index(res, x - 1, y, z);
+				voxel_index = compute_index(x - 1, y, z, res);
 				if(voxel_index == -1 || grid[voxel_index] == 0) {
 					create_quad(corners, vertices_is, quads, QUAD_X_MIN);
 				}
 
-				voxel_index = compute_voxel_index(res, x + 1, y, z);
+				voxel_index = compute_index(x + 1, y, z, res);
 				if(voxel_index == -1 || grid[voxel_index] == 0) {
 					create_quad(corners, vertices_is, quads, QUAD_X_MAX);
 				}
 
-				voxel_index = compute_voxel_index(res, x, y - 1, z);
+				voxel_index = compute_index(x, y - 1, z, res);
 				if(voxel_index == -1 || grid[voxel_index] == 0) {
 					create_quad(corners, vertices_is, quads, QUAD_Y_MIN);
 				}
 
-				voxel_index = compute_voxel_index(res, x, y + 1, z);
+				voxel_index = compute_index(x, y + 1, z, res);
 				if(voxel_index == -1 || grid[voxel_index] == 0) {
 					create_quad(corners, vertices_is, quads, QUAD_Y_MAX);
 				}
 
-				voxel_index = compute_voxel_index(res, x, y, z - 1);
+				voxel_index = compute_index(x, y, z - 1, res);
 				if(voxel_index == -1 || grid[voxel_index] == 0) {
 					create_quad(corners, vertices_is, quads, QUAD_Z_MIN);
 				}
 
-				voxel_index = compute_voxel_index(res, x, y, z + 1);
+				voxel_index = compute_index(x, y, z + 1, res);
 				if(voxel_index == -1 || grid[voxel_index] == 0) {
 					create_quad(corners, vertices_is, quads, QUAD_Z_MAX);
 				}
@@ -394,7 +378,8 @@ void VolumeMeshBuilder::convert_quads_to_tris(const vector<QuadData> &quads,
 /* ************************************************************************** */
 
 struct VoxelAttributeGrid {
-	float *data;
+	void *data;
+	int *offsets = NULL;
 	int channels;
 };
 
@@ -418,9 +403,18 @@ void MeshManager::create_volume_mesh(Scene *scene,
 
 		VoxelAttribute *voxel = attr.data_voxel();
 		device_memory *image_memory = scene->image_manager->image_memory(voxel->slot);
-		int3 resolution = make_int3(image_memory->data_width,
-                                    image_memory->data_height,
-		                            image_memory->data_depth);
+		device_memory *offsets = image_memory->offsets;
+		int3 resolution;
+		if(offsets) {
+			resolution = make_int3(offsets->data_width * TILE_SIZE,
+			                       offsets->data_height * TILE_SIZE,
+			                       offsets->data_depth * TILE_SIZE);
+		}
+		else{
+			resolution = make_int3(image_memory->data_width,
+                                   image_memory->data_height,
+		                           image_memory->data_depth);
+		}
 
 		if(volume_params.resolution == make_int3(0, 0, 0)) {
 			volume_params.resolution = resolution;
@@ -431,8 +425,11 @@ void MeshManager::create_volume_mesh(Scene *scene,
 		}
 
 		VoxelAttributeGrid voxel_grid;
-		voxel_grid.data = static_cast<float*>(image_memory->host_pointer);
+		voxel_grid.data = image_memory->host_pointer;
 		voxel_grid.channels = image_memory->data_elements;
+		if(offsets) {
+			voxel_grid.offsets = static_cast<int*>(offsets->host_pointer);
+		}
 		voxel_grids.push_back(voxel_grid);
 	}
 
@@ -472,6 +469,9 @@ void MeshManager::create_volume_mesh(Scene *scene,
 	float3 cell_size = make_float3(1.0f/resolution.x,
 	                               1.0f/resolution.y,
 	                               1.0f/resolution.z);
+	const int3 tile_res = make_int3(compute_tile_resolution(resolution.x),
+	                                compute_tile_resolution(resolution.y),
+	                                compute_tile_resolution(resolution.z));
 
 	if(attr) {
 		const Transform *tfm = attr->data_transform();
@@ -488,19 +488,57 @@ void MeshManager::create_volume_mesh(Scene *scene,
 	VolumeMeshBuilder builder(&volume_params);
 	const float isovalue = mesh->volume_isovalue;
 
-	for(int z = 0; z < resolution.z; ++z) {
-		for(int y = 0; y < resolution.y; ++y) {
-			for(int x = 0; x < resolution.x; ++x) {
-				size_t voxel_index = compute_voxel_index(resolution, x, y, z);
-
-				for(size_t i = 0; i < voxel_grids.size(); ++i) {
-					const VoxelAttributeGrid &voxel_grid = voxel_grids[i];
-					const int channels = voxel_grid.channels;
-
-					for(int c = 0; c < channels; c++) {
-						if(voxel_grid.data[voxel_index * channels + c] >= isovalue) {
+	for(size_t i = 0; i < voxel_grids.size(); ++i) {
+		const VoxelAttributeGrid &voxel_grid = voxel_grids[i];
+		const int channels = voxel_grid.channels;
+
+		if(channels > 1 && voxel_grid.offsets) {
+			SparseTile<float4> *data = (SparseTile<float4>*)voxel_grid.data;
+			for(int z = 0; z < resolution.z; ++z) {
+				for(int y = 0; y < resolution.y; ++y) {
+					for(int x = 0; x < resolution.x; ++x) {
+						float4 val = get_value<float4>(data,
+						                               voxel_grid.offsets,
+						                               x, y, z,
+						                               tile_res.x,
+						                               tile_res.y,
+						                               tile_res.z);
+						if(any(isovalue < val)) {
+							builder.add_node_with_padding(x, y, z);
+						}
+					}
+				}
+			}
+		}
+		else if(voxel_grid.offsets) {
+			SparseTile<float> *data = (SparseTile<float>*)voxel_grid.data;
+			for(int z = 0; z < resolution.z; ++z) {
+				for(int y = 0; y < resolution.y; ++y) {
+					for(int x = 0; x < resolution.x; ++x) {
+						float val = get_value<float>(data,
+						                             voxel_grid.offsets,
+						                             x, y, z,
+						                             tile_res.x,
+						                             tile_res.y,
+						                             tile_res.z);
+						if(val >= isovalue) {
 							builder.add_node_with_padding(x, y, z);
-							break;
+						}
+					}
+				}
+			}
+		}
+		else {
+			float *data = (float*)(voxel_grid.data);
+			for(int z = 0; z < resolution.z; ++z) {
+				for(int y = 0; y < resolution.y; ++y) {
+					for(int x = 0; x < resolution.x; ++x) {
+						size_t voxel_index = compute_index(x, y, z, resolution) * channels;
+						for(int c = 0 ; c < channels; ++c) {
+							if(data[voxel_index + c] >= isovalue) {
+								builder.add_node_with_padding(x, y, z);
+								break;
+							}
 						}
 					}
 				}
diff --git a/intern/cycles/util/util_math_float4.h b/intern/cycles/util/util_math_float4.h
index aa7e56fefe9..123104b6ba5 100644
--- a/intern/cycles/util/util_math_float4.h
+++ b/intern/cycles/util/util_math_float4.h
@@ -41,6 +41,8 @@ ccl_device_inline float4 operator*=(float4& a, const float4& b);
 ccl_device_inline float4 operator/=(float4& a, float f);
 
 ccl_device_inline int4 operator<(const float4& a, const float4& b);
+ccl_device_inline int4 operator<(const float4& a, const float& b);
+ccl_device_inline int4 operator<(const float& a, const float4& b);
 ccl_device_inline int4 operator>=(const float4& a, const float4& b);
 ccl_device_inline int4 operator<=(const float4& a, const float4& b);
 ccl_device_inline bool operator==(const float4& a, const float4& b);
@@ -182,6 +184,24 @@ ccl_device_inline int4 operator<(const float4& a, const float4& b)
 #endif
 }
 
+ccl_device_inline int4 operator<(const float4& a, const float& b)
+{
+#ifdef __KERNEL_SSE__
+	return a < make_float4(b);
+#else
+	return make_int4(a.x < b, a.y < b, a.z < b, a.w < b);
+#endif
+}
+
+ccl_device_inline int4 operator<(const float& a, const float4& b)
+{
+#ifdef __KERNEL_SSE__
+	return make_float4(a) < b;
+#else
+	return make_int4(a < b.x, a < b.y, a < b.z, a < b.w);
+#endif
+}
+
 ccl_device_inline int4 operator>=(const float4& a, const float4& b)
 {
 #ifdef __KERNEL_SSE__
diff --git a/intern/cycles/util/util_math_int4.h b/intern/cycles/util/util_math_int4.h
index 502e77cee72..ea73733a7f1 100644
--- a/intern/cycles/util/util_math_int4.h
+++ b/intern/cycles/util/util_math_int4.h
@@ -40,6 +40,11 @@ ccl_device_inline int4 clamp(const int4& a, const int4& mn, const int4& mx);
 ccl_device_inline int4 select(const int4& mask, const int4& a, const int4& b);
 #endif  /* __KERNEL_GPU__ */
 
+#ifndef __KERNEL_OPENCL__
+ccl_device_inline bool any(const int4& a);
+ccl_device_inline bool all(const int4& a);
+#endif  /* __KERNEL_OPENCL__ */
+
 /*******************************************************************************
  * Definition.
  */
@@ -132,6 +137,18 @@ ccl_device_inline int4 load_int4(const int *v)
 }
 #endif  /* __KERNEL_GPU__ */
 
+#ifndef __KERNEL_OPENCL__
+ccl_device_inline bool any(const int4& a)
+{
+	return a.x || a.y || a.z || a.w;
+}
+
+ccl_device_inline bool all(const int4& a)
+{
+	return a.x && a.y && a.z && a.w;
+}
+#endif  /* __KERNEL_OPENCL__ */
+
 CCL_NAMESPACE_END
 
 #endif /* __UTIL_MATH_INT4_H__ */
diff --git a/intern/cycles/util/util_sparse_grid.h b/intern/cycles/util/ut

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list