def test_mesh_normal_consistency(self): """ Test Mesh Normal Consistency for random meshes. """ meshes = TestMeshNormalConsistency.init_meshes(5, 100, 300) out1 = mesh_normal_consistency(meshes) out2 = TestMeshNormalConsistency.mesh_normal_consistency_naive(meshes) self.assertTrue(torch.allclose(out1, out2))
def test_no_intersection(self): """ Test Mesh Normal Consistency for a mesh known to have no intersecting faces. """ verts = torch.rand(1, 6, 3) faces = torch.arange(6).reshape(1, 2, 3) meshes = Meshes(verts=verts, faces=faces) out = mesh_normal_consistency(meshes) self.assertEqual(out.item(), 0)
def loss(): mesh_normal_consistency(meshes) torch.cuda.synchronize()
def test_mesh_normal_consistency_simple(self): r""" Mesh 1: v3 /\ / \ e4 / f1 \ e3 / \ v2 /___e2___\ v1 \ / \ / e1 \ f0 / e0 \ / \/ v0 """ device = torch.device("cuda:0") # mesh1 shown above verts1 = torch.rand((4, 3), dtype=torch.float32, device=device) faces1 = torch.tensor([[0, 1, 2], [2, 1, 3]], dtype=torch.int64, device=device) # mesh2 is a cuboid with 8 verts, 12 faces and 18 edges verts2 = torch.tensor( [ [0, 0, 0], [0, 0, 1], [0, 1, 0], [0, 1, 1], [1, 0, 0], [1, 0, 1], [1, 1, 0], [1, 1, 1], ], dtype=torch.float32, device=device, ) faces2 = torch.tensor( [ [0, 1, 2], [1, 3, 2], # left face: 0, 1 [2, 3, 6], [3, 7, 6], # bottom face: 2, 3 [0, 2, 6], [0, 6, 4], # front face: 4, 5 [0, 5, 1], [0, 4, 5], # up face: 6, 7 [6, 7, 5], [6, 5, 4], # right face: 8, 9 [1, 7, 3], [1, 5, 7], # back face: 10, 11 ], dtype=torch.int64, device=device, ) # mesh3 is like mesh1 but with another face added to e2 verts3 = torch.rand((5, 3), dtype=torch.float32, device=device) faces3 = torch.tensor([[0, 1, 2], [2, 1, 3], [2, 1, 4]], dtype=torch.int64, device=device) meshes = Meshes(verts=[verts1, verts2, verts3], faces=[faces1, faces2, faces3]) # mesh1: normal consistency computation n0 = (verts1[1] - verts1[2]).cross(verts1[3] - verts1[2]) n1 = (verts1[1] - verts1[2]).cross(verts1[0] - verts1[2]) loss1 = 1.0 - torch.cosine_similarity(n0.view(1, 3), -(n1.view(1, 3))) # mesh2: normal consistency computation # In the cube mesh, 6 edges are shared with coplanar faces (loss=0), # 12 edges are shared by perpendicular faces (loss=1) loss2 = 12.0 / 18 # mesh3 n0 = (verts3[1] - verts3[2]).cross(verts3[3] - verts3[2]) n1 = (verts3[1] - verts3[2]).cross(verts3[0] - verts3[2]) n2 = (verts3[1] - verts3[2]).cross(verts3[4] - verts3[2]) loss3 = (3.0 - torch.cosine_similarity(n0.view(1, 3), -(n1.view(1, 3))) - torch.cosine_similarity(n0.view(1, 3), -(n2.view(1, 3))) - torch.cosine_similarity(n1.view(1, 3), -(n2.view(1, 3)))) loss3 /= 3.0 loss = (loss1 + loss2 + loss3) / 3.0 out = mesh_normal_consistency(meshes) self.assertTrue(torch.allclose(out, loss))