code: def project_verts(verts, P, eps: float = 1e-1):  # pragma: no cover
      """
      Copied from meshrcnn codebase:
      https://github.com/facebookresearch/meshrcnn/blob/main/shapenet/utils/coords.py#L159
  
      Project vertices using a 4x4 transformation matrix.
  
      Args:
          verts: FloatTensor of shape (N, V, 3) giving a batch of vertex positions or of
              shape (V, 3) giving a single set of vertex positions.
          P: FloatTensor of shape (N, 4, 4) giving projection matrices or of shape (4, 4)
              giving a single projection matrix.
  
      Returns:
          verts_out: FloatTensor of shape (N, V, 3) giving vertex positions (x, y, z)
              where verts_out[i] is the result of transforming verts[i] by P[i].
      """
      # Handle unbatched inputs
      singleton = False
      if verts.dim() == 2:
          assert P.dim() == 2
          singleton = True
          verts, P = verts[None], P[None]
  
      N, V = verts.shape[0], verts.shape[1]
      dtype, device = verts.dtype, verts.device
  
      # Add an extra row of ones to the world-space coordinates of verts before
      # multiplying by the projection matrix. We could avoid this allocation by
      # instead multiplying by a 4x3 submatrix of the projection matrix, then
      # adding the remaining 4x1 vector. Not sure whether there will be much
      # performance difference between the two.
      ones = torch.ones(N, V, 1, dtype=dtype, device=device)
      verts_hom = torch.cat([verts, ones], dim=2)
      verts_cam_hom = torch.bmm(verts_hom, P.transpose(1, 2))
  
      # Avoid division by zero by clamping the absolute value
      w = verts_cam_hom[:, :, 3:]
      w_sign = w.sign()
      w_sign[w == 0] = 1
      w = w_sign * w.abs().clamp(min=eps)
  
      verts_proj = verts_cam_hom[:, :, :3] / w
  
      if singleton:
          return verts_proj[0]
      return verts_proj
  
imports: import math
  from typing import Dict, List
  import numpy
  import torch
  from pytorch3d.common.datatypes import Device
  from pytorch3d.datasets.utils import collate_batched_meshes
  from pytorch3d.ops import cubify
  from pytorch3d.renderer import HardPhongShader, MeshRasterizer, MeshRenderer, PointLights, RasterizationSettings, TexturesVertex
  from pytorch3d.renderer.cameras import CamerasBase
  from pytorch3d.transforms import Transform3d
label_desc: Use image node_id 8 for calling a global function with example usage: project_verts(verts, P, eps) and returns: verts_proj, verts_proj