From c292c71c1adb0712c12cf4fa67a7a84ad9b44e5c Mon Sep 17 00:00:00 2001 From: Ada Martin Date: Thu, 8 Feb 2024 11:13:15 -0800 Subject: [PATCH] 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 --- pytorch3d/csrc/marching_cubes/marching_cubes_cpu.cpp | 4 ++-- tests/test_marching_cubes.py | 12 ++++++++++++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/pytorch3d/csrc/marching_cubes/marching_cubes_cpu.cpp b/pytorch3d/csrc/marching_cubes/marching_cubes_cpu.cpp index 5d68db50..fa128e71 100644 --- a/pytorch3d/csrc/marching_cubes/marching_cubes_cpu.cpp +++ b/pytorch3d/csrc/marching_cubes/marching_cubes_cpu.cpp @@ -71,8 +71,8 @@ std::tuple MarchingCubesCpu( if ((j + 1) % 3 == 0 && ps[0] != ps[1] && ps[1] != ps[2] && ps[2] != ps[0]) { for (int k = 0; k < 3; k++) { - int v = tri[k]; - edge_id_to_v[tri.at(k)] = ps.at(k); + int64_t v = tri.at(k); + edge_id_to_v[v] = ps.at(k); if (!uniq_edge_id.count(v)) { uniq_edge_id[v] = verts.size(); verts.push_back(edge_id_to_v[v]); diff --git a/tests/test_marching_cubes.py b/tests/test_marching_cubes.py index 116a18cb..324ef8d0 100644 --- a/tests/test_marching_cubes.py +++ b/tests/test_marching_cubes.py @@ -854,6 +854,18 @@ class TestMarchingCubes(TestCaseMixin, unittest.TestCase): self.assertClose(verts2[0], expected_verts) 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): if USE_SCIKIT: from skimage.measure import marching_cubes_classic, mesh_surface_area