Skip to content

Commit

Permalink
Simplify MC C++ hashing logic
Browse files Browse the repository at this point in the history
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
  • Loading branch information
Jiali Duan authored and facebook-github-bot committed Nov 16, 2022
1 parent 8b82918 commit 1706eb8
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 40 deletions.
9 changes: 1 addition & 8 deletions pytorch3d/csrc/marching_cubes/marching_cubes_cpu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,6 @@ std::tuple<at::Tensor, at::Tensor, at::Tensor> MarchingCubesCpu(

// Create tensor accessors
auto vol_a = vol.accessor<float, 3>();
// vpair_to_edge maps a pair of vertex ids to its corresponding edge id
std::unordered_map<std::pair<int, int>, int64_t> vpair_to_edge;
// edge_id_to_v maps from an edge id to a vertex position
std::unordered_map<int64_t, Vertex> edge_id_to_v;
// uniq_edge_id: used to remove redundant edge ids
Expand All @@ -64,12 +62,7 @@ std::tuple<at::Tensor, at::Tensor, at::Tensor> 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]);

Expand Down
43 changes: 11 additions & 32 deletions pytorch3d/csrc/marching_cubes/marching_cubes_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -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<int, int> 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 <class T>
inline void hash_combine(size_t& s, const T& v) {
std::hash<T> h;
s ^= h(v) + 0x9e3779b9 + (s << 6) + (s >> 2);
}

// Function for hashing a pair of vertices
template <>
struct hash<std::pair<int, int>> {
size_t operator()(const std::pair<int, int>& p) const {
size_t res = 0;
hash_combine(res, p.first);
hash_combine(res, p.second);
return res;
}
};

} // namespace std

0 comments on commit 1706eb8

Please sign in to comment.