c++ marching cubes fix

Summary:
Fixes https://github.com/facebookresearch/pytorch3d/issues/1641. The bug was caused by the mistaken downcasting of an int64_t into int, causing issues only on inputs large enough to have hashes that escaped the bounds of an int32.

Also added a test case for this issue.

Reviewed By: bottler

Differential Revision: D53505370

fbshipit-source-id: 0fdd0efc6d259cc3b0263e7ff3a4ab2c648ec521
This commit is contained in:
Ada Martin 2024-02-08 11:13:15 -08:00 committed by Facebook GitHub Bot
parent d0d9cae9cd
commit c292c71c1a
2 changed files with 14 additions and 2 deletions

View File

@ -71,8 +71,8 @@ std::tuple<at::Tensor, at::Tensor, at::Tensor> MarchingCubesCpu(
if ((j + 1) % 3 == 0 && ps[0] != ps[1] && ps[1] != ps[2] && if ((j + 1) % 3 == 0 && ps[0] != ps[1] && ps[1] != ps[2] &&
ps[2] != ps[0]) { ps[2] != ps[0]) {
for (int k = 0; k < 3; k++) { for (int k = 0; k < 3; k++) {
int v = tri[k]; int64_t v = tri.at(k);
edge_id_to_v[tri.at(k)] = ps.at(k); edge_id_to_v[v] = ps.at(k);
if (!uniq_edge_id.count(v)) { if (!uniq_edge_id.count(v)) {
uniq_edge_id[v] = verts.size(); uniq_edge_id[v] = verts.size();
verts.push_back(edge_id_to_v[v]); verts.push_back(edge_id_to_v[v]);

View File

@ -854,6 +854,18 @@ class TestMarchingCubes(TestCaseMixin, unittest.TestCase):
self.assertClose(verts2[0], expected_verts) self.assertClose(verts2[0], expected_verts)
self.assertClose(faces2[0], expected_faces) self.assertClose(faces2[0], expected_faces)
def test_single_large_ellipsoid(self):
if USE_SCIKIT:
from skimage.draw import ellipsoid
ellip_base = ellipsoid(50, 60, 16, levelset=True)
volume = torch.Tensor(ellip_base).unsqueeze(0).cpu()
verts, faces = marching_cubes_naive(volume, 0)
verts2, faces2 = marching_cubes(volume, 0)
self.assertClose(verts[0], verts2[0], atol=1e-6)
self.assertClose(faces[0], faces2[0], atol=1e-6)
def test_cube_surface_area(self): def test_cube_surface_area(self):
if USE_SCIKIT: if USE_SCIKIT:
from skimage.measure import marching_cubes_classic, mesh_surface_area from skimage.measure import marching_cubes_classic, mesh_surface_area