| 6 | |
| 7 | |
| 8 | class Mesh: |
| 9 | def __init__(self, |
| 10 | vertices, |
| 11 | faces, |
| 12 | vertex_attrs=None |
| 13 | ): |
| 14 | self.vertices = vertices.float() |
| 15 | self.faces = faces.int() |
| 16 | self.vertex_attrs = vertex_attrs |
| 17 | |
| 18 | @property |
| 19 | def device(self): |
| 20 | return self.vertices.device |
| 21 | |
| 22 | def to(self, device, non_blocking=False): |
| 23 | return Mesh( |
| 24 | self.vertices.to(device, non_blocking=non_blocking), |
| 25 | self.faces.to(device, non_blocking=non_blocking), |
| 26 | self.vertex_attrs.to(device, non_blocking=non_blocking) if self.vertex_attrs is not None else None, |
| 27 | ) |
| 28 | |
| 29 | def cuda(self, non_blocking=False): |
| 30 | return self.to('cuda', non_blocking=non_blocking) |
| 31 | |
| 32 | def cpu(self): |
| 33 | return self.to('cpu') |
| 34 | |
| 35 | def fill_holes(self, max_hole_perimeter=3e-2): |
| 36 | vertices = self.vertices.clone().cuda().contiguous() |
| 37 | faces = self.faces.clone().cuda().contiguous() |
| 38 | |
| 39 | mesh = cumesh.CuMesh() |
| 40 | mesh.init(vertices, faces) |
| 41 | mesh.get_edges() |
| 42 | mesh.get_boundary_info() |
| 43 | if mesh.num_boundaries == 0: |
| 44 | return |
| 45 | mesh.get_vertex_edge_adjacency() |
| 46 | mesh.get_vertex_boundary_adjacency() |
| 47 | mesh.get_manifold_boundary_adjacency() |
| 48 | mesh.read_manifold_boundary_adjacency() |
| 49 | mesh.get_boundary_connected_components() |
| 50 | mesh.get_boundary_loops() |
| 51 | if mesh.num_boundary_loops == 0: |
| 52 | return |
| 53 | mesh.fill_holes(max_hole_perimeter=max_hole_perimeter) |
| 54 | new_vertices, new_faces = mesh.read() |
| 55 | |
| 56 | self.vertices = new_vertices.to(self.device) |
| 57 | self.faces = new_faces.to(self.device) |
| 58 | |
| 59 | def remove_faces(self, face_mask: torch.Tensor): |
| 60 | vertices = self.vertices.clone().cuda().contiguous() |
| 61 | faces = self.faces.clone().cuda().contiguous() |
| 62 | |
| 63 | mesh = cumesh.CuMesh() |
| 64 | mesh.init(vertices, faces) |
| 65 | mesh.remove_faces(face_mask) |
no outgoing calls
no test coverage detected