Spaces:
Running
on
Zero
Running
on
Zero
| # Copyright (c) Meta Platforms, Inc. and affiliates. | |
| from collections import namedtuple | |
| from typing import Tuple, Optional, Union | |
| import numpy as np | |
| import torch | |
| from pytorch3d.structures import Meshes | |
| from pytorch3d.renderer.mesh.textures import TexturesVertex | |
| from utils3d.numpy import ( | |
| depth_edge, | |
| normals_edge, | |
| points_to_normals, | |
| image_uv, | |
| image_mesh, | |
| ) | |
| np.acos = np.arccos # sam3d_objects-3dfy version of numpy doesn't have acos | |
| MeshAndTexture = namedtuple( | |
| "mesh_and_texture", ["faces", "vertices", "vertex_colors", "vertex_uvs"] | |
| ) | |
| def mesh_from_pointmap( | |
| pointmap: np.ndarray, | |
| image: np.ndarray, | |
| mask: Optional[np.ndarray] = None, | |
| depth: Optional[np.ndarray] = None, | |
| filter_edges: bool = True, | |
| depth_edge_rtol: float = 0.03, | |
| depth_edge_tol: float = 5, | |
| ) -> MeshAndTexture: | |
| """ | |
| Create a mesh from pointmap and image. | |
| Returns: | |
| faces, vertices, vertex_colors, vertex_uvs: Mesh components | |
| """ | |
| assert pointmap.ndim == 3, pointmap.shape | |
| assert pointmap.shape[-1] == 3, pointmap.shape | |
| assert image.ndim == 3, image.shape | |
| assert image.shape[-1] == 3, image.shape | |
| if mask is None: | |
| mask = np.ones_like(pointmap[..., 2], dtype=np.float32) > 0 | |
| if depth is None: | |
| depth = pointmap[..., 2] | |
| height, width = image.shape[:2] | |
| normals, normals_mask = points_to_normals(pointmap, mask=mask) | |
| if filter_edges: | |
| mask = mask & ~( | |
| depth_edge(depth, rtol=depth_edge_rtol, mask=mask) | |
| & normals_edge(normals, tol=depth_edge_tol, mask=normals_mask) | |
| ) | |
| faces, vertices, vertex_colors, vertex_uvs = image_mesh( | |
| pointmap, | |
| image.astype(np.float32), | |
| image_uv(width=width, height=height), | |
| mask=mask, | |
| tri=True, | |
| ) | |
| vertices, vertex_uvs = vertices * [1, 1, 1], vertex_uvs * [1, -1] + [0, 1] | |
| return MeshAndTexture(faces, vertices, vertex_colors, vertex_uvs) | |
| def create_textured_mesh( | |
| verts: torch.Tensor, | |
| faces: torch.Tensor, | |
| vert_colors: torch.Tensor, | |
| ) -> Meshes: | |
| tex = TexturesVertex(verts_features=[vert_colors]) | |
| mesh = Meshes(verts=[verts], faces=[faces], textures=tex) | |
| return mesh | |