diff options
author | Stefan Werner <stefan.werner@tangent-animation.com> | 2018-07-28 19:14:05 +0300 |
---|---|---|
committer | Brecht Van Lommel <brechtvanlommel@gmail.com> | 2018-07-28 20:23:35 +0300 |
commit | b747524144c54c2c71d550de6331d96afc4cb711 (patch) | |
tree | 55cc4f6040fde7a94f0f091d6897d56a5f982d7c /intern/cycles/render | |
parent | bcefb202a2278188c0c780a6e4a3603d4d727c91 (diff) |
Cycles: speed up mesh volume bounds construction.
Patch by Stefan, with minor tweaks by Brecht.
Diffstat (limited to 'intern/cycles/render')
-rw-r--r-- | intern/cycles/render/mesh_volume.cpp | 91 |
1 files changed, 26 insertions, 65 deletions
diff --git a/intern/cycles/render/mesh_volume.cpp b/intern/cycles/render/mesh_volume.cpp index d1c49b456ff..3ee4124ba0f 100644 --- a/intern/cycles/render/mesh_volume.cpp +++ b/intern/cycles/render/mesh_volume.cpp @@ -87,23 +87,31 @@ const float3 quads_normals[6] = { make_float3(0.0f, 0.0f, 1.0f), }; -static void create_quad(int3 corners[8], vector<int3> &vertices, vector<QuadData> &quads, int face_index) +static int add_vertex(int3 v, vector<int3> &vertices, int3 res, unordered_map<size_t, int> &used_verts) { - size_t vertex_offset = vertices.size(); + size_t vert_key = v.x + v.y * (res.x+1) + v.z * (res.x+1)*(res.y+1); + unordered_map<size_t, int>::iterator it = used_verts.find(vert_key); + if(it != used_verts.end()) { + return it->second; + } + + int vertex_offset = vertices.size(); + used_verts[vert_key] = vertex_offset; + vertices.push_back(v); + return vertex_offset; +} + +static void create_quad(int3 corners[8], vector<int3> &vertices, vector<QuadData> &quads, int3 res, unordered_map<size_t, int> &used_verts, int face_index) +{ QuadData quad; - quad.v0 = vertex_offset + 0; - quad.v1 = vertex_offset + 1; - quad.v2 = vertex_offset + 2; - quad.v3 = vertex_offset + 3; + quad.v0 = add_vertex(corners[quads_indices[face_index][0]], vertices, res, used_verts); + quad.v1 = add_vertex(corners[quads_indices[face_index][1]], vertices, res, used_verts); + quad.v2 = add_vertex(corners[quads_indices[face_index][2]], vertices, res, used_verts); + quad.v3 = add_vertex(corners[quads_indices[face_index][3]], vertices, res, used_verts); quad.normal = quads_normals[face_index]; quads.push_back(quad); - - vertices.push_back(corners[quads_indices[face_index][0]]); - vertices.push_back(corners[quads_indices[face_index][1]]); - vertices.push_back(corners[quads_indices[face_index][2]]); - vertices.push_back(corners[quads_indices[face_index][3]]); } struct VolumeParams { @@ -159,9 +167,6 @@ private: void generate_vertices_and_quads(vector<int3> &vertices_is, vector<QuadData> &quads); - void deduplicate_vertices(vector<int3> &vertices, - vector<QuadData> &quads); - void convert_object_space(const vector<int3> &vertices, vector<float3> &out_vertices); @@ -234,8 +239,6 @@ void VolumeMeshBuilder::create_mesh(vector<float3> &vertices, generate_vertices_and_quads(vertices_is, quads); - deduplicate_vertices(vertices_is, quads); - convert_object_space(vertices_is, vertices); convert_quads_to_tris(quads, indices, face_normals); @@ -245,10 +248,7 @@ void VolumeMeshBuilder::generate_vertices_and_quads( vector<ccl::int3> &vertices_is, vector<QuadData> &quads) { - /* Overallocation, we could count the number of quads and vertices to create - * in a pre-pass if memory becomes an issue. */ - vertices_is.reserve(number_of_nodes*8); - quads.reserve(number_of_nodes*6); + unordered_map<size_t, int> used_verts; for(int z = 0; z < res.z; ++z) { for(int y = 0; y < res.y; ++y) { @@ -283,77 +283,38 @@ void VolumeMeshBuilder::generate_vertices_and_quads( voxel_index = compute_voxel_index(res, x - 1, y, z); if(voxel_index == -1 || grid[voxel_index] == 0) { - create_quad(corners, vertices_is, quads, QUAD_X_MIN); + create_quad(corners, vertices_is, quads, res, used_verts, QUAD_X_MIN); } voxel_index = compute_voxel_index(res, x + 1, y, z); if(voxel_index == -1 || grid[voxel_index] == 0) { - create_quad(corners, vertices_is, quads, QUAD_X_MAX); + create_quad(corners, vertices_is, quads, res, used_verts, QUAD_X_MAX); } voxel_index = compute_voxel_index(res, x, y - 1, z); if(voxel_index == -1 || grid[voxel_index] == 0) { - create_quad(corners, vertices_is, quads, QUAD_Y_MIN); + create_quad(corners, vertices_is, quads, res, used_verts, QUAD_Y_MIN); } voxel_index = compute_voxel_index(res, x, y + 1, z); if(voxel_index == -1 || grid[voxel_index] == 0) { - create_quad(corners, vertices_is, quads, QUAD_Y_MAX); + create_quad(corners, vertices_is, quads, res, used_verts, QUAD_Y_MAX); } voxel_index = compute_voxel_index(res, x, y, z - 1); if(voxel_index == -1 || grid[voxel_index] == 0) { - create_quad(corners, vertices_is, quads, QUAD_Z_MIN); + create_quad(corners, vertices_is, quads, res, used_verts, QUAD_Z_MIN); } voxel_index = compute_voxel_index(res, x, y, z + 1); if(voxel_index == -1 || grid[voxel_index] == 0) { - create_quad(corners, vertices_is, quads, QUAD_Z_MAX); + create_quad(corners, vertices_is, quads, res, used_verts, QUAD_Z_MAX); } } } } } -void VolumeMeshBuilder::deduplicate_vertices(vector<int3> &vertices, - vector<QuadData> &quads) -{ - vector<int3> sorted_vertices = vertices; - std::sort(sorted_vertices.begin(), sorted_vertices.end()); - vector<int3>::iterator it = std::unique(sorted_vertices.begin(), sorted_vertices.end()); - sorted_vertices.resize(std::distance(sorted_vertices.begin(), it)); - - vector<QuadData> new_quads = quads; - - for(size_t i = 0; i < vertices.size(); ++i) { - for(size_t j = 0; j < sorted_vertices.size(); ++j) { - if(vertices[i] != sorted_vertices[j]) { - continue; - } - - for(int k = 0; k < quads.size(); ++k) { - if(quads[k].v0 == i) { - new_quads[k].v0 = j; - } - else if(quads[k].v1 == i) { - new_quads[k].v1 = j; - } - else if(quads[k].v2 == i) { - new_quads[k].v2 = j; - } - else if(quads[k].v3 == i) { - new_quads[k].v3 = j; - } - } - - break; - } - } - - vertices = sorted_vertices; - quads = new_quads; -} - void VolumeMeshBuilder::convert_object_space(const vector<int3> &vertices, vector<float3> &out_vertices) { |