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)