from lib.kits.basic import * def compute_mesh_volume( verts: Union[torch.Tensor, np.ndarray], faces: Union[torch.Tensor, np.ndarray], ) -> torch.Tensor: ''' Computes the volume of a mesh object through triangles. References: 1. https://github.com/muelea/shapy/blob/a5daa70ce619cbd2a218cebbe63ae3a4c0b771fd/mesh-mesh-intersection/body_measurements/body_measurements.py#L201-L215 2. https://stackoverflow.com/questions/1406029/how-to-calculate-the-volume-of-a-3d-mesh-object-the-surface-of-which-is-made-up ### Args - verts: `torch.Tensor` or `np.ndarray`, shape = ((...B,) V, C=3) - faces: `torch.Tensor` or `np.ndarray`, shape = (T, K=3) where T = #triangles ### Returns - volume: `torch.Tensor`, shape = (...B,) or (,), in m^3. ''' faces = to_numpy(faces) # Get triangles' xyz. batch_shape = verts.shape[:-2] V = verts.shape[-2] verts = verts.reshape(-1, V, 3) # (B', V, C=3) tris = verts[:, faces] # (B', T, K=3, C=3) tris = tris.reshape(*batch_shape, -1, 3, 3) # (..., T, K=3, C=3) x = tris[..., 0] # (..., T, K=3) y = tris[..., 1] # (..., T, K=3) z = tris[..., 2] # (..., T, K=3) volume = ( -x[..., 2] * y[..., 1] * z[..., 0] + x[..., 1] * y[..., 2] * z[..., 0] + x[..., 2] * y[..., 0] * z[..., 1] - x[..., 0] * y[..., 2] * z[..., 1] - x[..., 1] * y[..., 0] * z[..., 2] + x[..., 0] * y[..., 1] * z[..., 2] ).sum(dim=-1).abs() / 6.0 return volume