Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/intern
diff options
context:
space:
mode:
authorGeraldine Chua <chua.gsk@gmail.com>2018-06-06 18:51:56 +0300
committerGeraldine Chua <chua.gsk@gmail.com>2018-06-06 18:51:56 +0300
commit998d1b091a90454cdc65ed8ea8101f28984298e4 (patch)
treeb918094732d30eb771fa0725f5cc5138f974b7bc /intern
parente1db45c41a9acb9dadbb40183e1037d441a15035 (diff)
Added sparse grid lookup to mesh volume generator.
Also made some minor operator additions/changes.
Diffstat (limited to 'intern')
-rw-r--r--intern/cycles/render/mesh_volume.cpp122
-rw-r--r--intern/cycles/util/util_math_float4.h20
-rw-r--r--intern/cycles/util/util_math_int4.h17
-rw-r--r--intern/cycles/util/util_sparse_grid.h13
4 files changed, 124 insertions, 48 deletions
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/util_sparse_grid.h
index 910d4f4e1fb..91ed75e23f8 100644
--- a/intern/cycles/util/util_sparse_grid.h
+++ b/intern/cycles/util/util_sparse_grid.h
@@ -38,16 +38,11 @@
CCL_NAMESPACE_BEGIN
-/* For some type4 textures (e.g. color), they may still be
- * considered active even if at least one of their values
- * is beneath the threshold. Thus, we require a custom
- * function using ORs instead of ANDs.
- */
namespace {
inline bool gt(float a, float b) { return a > b; }
inline bool gt(uchar a, uchar b) { return a > b; }
inline bool gt(half a, half b) { return a > b; }
- inline bool gt(float4 a, float4 b) { return a.x > b.x || a.y > b.y || a.z > b.z || a.w > b.w; }
+ inline bool gt(float4 a, float4 b) { return any(b < a); }
inline bool gt(uchar4 a, uchar4 b) { return a.x > b.x || a.y > b.y || a.z > b.z || a.w > b.w; }
inline bool gt(half4 a, half4 b) { return a.x > b.x || a.y > b.y || a.z > b.z || a.w > b.w; }
}
@@ -68,6 +63,12 @@ const inline int compute_index(const size_t x, const size_t y, const size_t z,
return x + width * (y + z * height);
}
+const inline int compute_index(const size_t x, const size_t y, const size_t z,
+ const int3 resolution)
+{
+ return compute_index(x, y, z, resolution.x, resolution.y, resolution.z);
+}
+
const inline int3 compute_coordinates(const size_t index, const size_t width,
const size_t height, const size_t depth)
{