From 354a1808ff57cb75461c697b282eac98c9082ea9 Mon Sep 17 00:00:00 2001 From: Jeremy Reizenstein Date: Mon, 21 Jun 2021 06:05:03 -0700 Subject: [PATCH] Fix save_ply with noncontiguous faces Summary: As noted in #710, save_ply was failing with some values of the faces tensor. It was assuming the faces were contiguous in using view() to change them. Here we avoid doing that. Reviewed By: patricklabatut Differential Revision: D29159655 fbshipit-source-id: 47214a7ce915bab8d81f109c2b97cde464fd57d8 --- pytorch3d/io/ply_io.py | 11 ++++++++--- tests/test_io_ply.py | 5 +++++ 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/pytorch3d/io/ply_io.py b/pytorch3d/io/ply_io.py index 85ae1aa3..3e28ba5d 100644 --- a/pytorch3d/io/ply_io.py +++ b/pytorch3d/io/ply_io.py @@ -1154,9 +1154,14 @@ def _save_ply( if ascii: np.savetxt(f, faces_array, "3 %d %d %d") else: - # rows are 13 bytes: a one-byte 3 followed by three four-byte face indices. - faces_uints = np.full((len(faces_array), 13), 3, dtype=np.uint8) - faces_uints[:, 1:] = faces_array.astype(np.uint32).view(np.uint8) + faces_recs = np.zeros( + len(faces_array), + dtype=[("count", np.uint8), ("vertex_indices", np.uint32, 3)], + ) + faces_recs["count"] = 3 + faces_recs["vertex_indices"] = faces_array + faces_uints = faces_recs.view(np.uint8) + if isinstance(f, BytesIO): f.write(faces_uints.tobytes()) else: diff --git a/tests/test_io_ply.py b/tests/test_io_ply.py index 192170c8..e6a24362 100644 --- a/tests/test_io_ply.py +++ b/tests/test_io_ply.py @@ -353,6 +353,11 @@ class TestMeshPlyIO(TestCaseMixin, unittest.TestCase): save_ply(file, verts=verts, faces=faces, verts_normals=normals) file.close() + def test_contiguity_unimportant(self): + verts = torch.rand(32, 3) + self._test_save_load(verts, torch.randint(30, size=(10, 3))) + self._test_save_load(verts, torch.randint(30, size=(3, 10)).T) + def test_empty_save_load(self): # Vertices + empty faces verts = torch.tensor([[0.1, 0.2, 0.3]])