| import torch | |
| def face_normals_packed(meshes): | |
| verts = meshes.verts_packed() | |
| faces = meshes.faces_packed() | |
| face_verts = verts[faces] | |
| normals = torch.cross( | |
| face_verts[:, 1] - face_verts[:, 0], | |
| face_verts[:, 2] - face_verts[:, 0], | |
| dim=1, | |
| ) | |
| return normals / normals.norm(dim=1, keepdim=True).clamp_min(1e-12) | |
| def vertex_normals_packed(meshes): | |
| verts = meshes.verts_packed() | |
| faces = meshes.faces_packed() | |
| face_normals = face_normals_packed(meshes) | |
| normals = torch.zeros_like(verts) | |
| normals.index_add_(0, faces[:, 0], face_normals) | |
| normals.index_add_(0, faces[:, 1], face_normals) | |
| normals.index_add_(0, faces[:, 2], face_normals) | |
| return normals / normals.norm(dim=1, keepdim=True).clamp_min(1e-12) | |