From 1706eb8216248e54f68cad86f7ea4125c79a3ca4 Mon Sep 17 00:00:00 2001 From: Jiali Duan Date: Tue, 15 Nov 2022 19:42:04 -0800 Subject: [PATCH] Simplify MC C++ hashing logic Summary: To be consistent with CUDA hashing, the diff replaces boost hasher with a simplified hasher for storing unique global edge_ids. Reviewed By: kjchalup Differential Revision: D41140382 fbshipit-source-id: 2ce598e5edcf6369fe13bd15d1f5e014b252027b --- .../marching_cubes/marching_cubes_cpu.cpp | 9 +--- .../marching_cubes/marching_cubes_utils.h | 43 +++++-------------- 2 files changed, 12 insertions(+), 40 deletions(-) diff --git a/pytorch3d/csrc/marching_cubes/marching_cubes_cpu.cpp b/pytorch3d/csrc/marching_cubes/marching_cubes_cpu.cpp index 5b780dc0..5d68db50 100644 --- a/pytorch3d/csrc/marching_cubes/marching_cubes_cpu.cpp +++ b/pytorch3d/csrc/marching_cubes/marching_cubes_cpu.cpp @@ -36,8 +36,6 @@ std::tuple MarchingCubesCpu( // Create tensor accessors auto vol_a = vol.accessor(); - // vpair_to_edge maps a pair of vertex ids to its corresponding edge id - std::unordered_map, int64_t> vpair_to_edge; // edge_id_to_v maps from an edge id to a vertex position std::unordered_map edge_id_to_v; // uniq_edge_id: used to remove redundant edge ids @@ -64,12 +62,7 @@ std::tuple MarchingCubesCpu( const int e = _FACE_TABLE[cube.cubeindex][j]; interp_points[e] = cube.VertexInterp(isolevel, e, vol_a); - auto vpair = cube.GetVPairFromEdge(e, W, H); - if (!vpair_to_edge.count(vpair)) { - vpair_to_edge[vpair] = vpair_to_edge.size(); - } - - int64_t edge = vpair_to_edge[vpair]; + int64_t edge = cube.HashVpair(e, W, H, D); tri.push_back(edge); ps.push_back(interp_points[e]); diff --git a/pytorch3d/csrc/marching_cubes/marching_cubes_utils.h b/pytorch3d/csrc/marching_cubes/marching_cubes_utils.h index 48d93d39..486e0339 100644 --- a/pytorch3d/csrc/marching_cubes/marching_cubes_utils.h +++ b/pytorch3d/csrc/marching_cubes/marching_cubes_utils.h @@ -122,45 +122,24 @@ struct Cube { return p1 * (1 - ratio) + p2 * ratio; } - // Get a tuple of global vertex ID from a local edge ID - // Global vertex ID is calculated as (x + dx) + (y + dy) * W + (z + dz) * W * - // H - + // Hash an edge into a global edge_id. The function binds an + // edge with an integer to address floating point precision issue. + // // Args: - // edge: local edge ID in the cube - // W: width of x dimension - // H: height of y dimension + // v1_id: global id of vertex 1 + // v2_id: global id of vertex 2 + // W: width of the 3d grid + // H: height of the 3d grid + // D: depth of the 3d grid // // Returns: - // a pair of global vertex ID + // hashing for a pair of vertex ids // - std::pair GetVPairFromEdge(const int edge, int W, int H) { + int64_t HashVpair(const int edge, int W, int H, int D) { const int v1 = _EDGE_TO_VERTICES[edge][0]; const int v2 = _EDGE_TO_VERTICES[edge][1]; const int v1_id = p[v1].x + p[v1].y * W + p[v1].z * W * H; const int v2_id = p[v2].x + p[v2].y * W + p[v2].z * W * H; - return std::make_pair(v1_id, v2_id); + return (int64_t)v1_id * (W + W * H + W * H * D) + (int64_t)v2_id; } }; - -// helper functions for hashing -namespace std { -// Taken from boost library to combine several hash functions -template -inline void hash_combine(size_t& s, const T& v) { - std::hash h; - s ^= h(v) + 0x9e3779b9 + (s << 6) + (s >> 2); -} - -// Function for hashing a pair of vertices -template <> -struct hash> { - size_t operator()(const std::pair& p) const { - size_t res = 0; - hash_combine(res, p.first); - hash_combine(res, p.second); - return res; - } -}; - -} // namespace std