code: def _get_verts(header: _PlyHeader, elements: dict) -> _VertsData:
      """
      Get the vertex locations, colors and normals from a parsed ply file.
  
      Args:
          header, elements: as returned from load_ply_raw.
  
      Returns:
          _VertsData object
      """
  
      vertex = elements.get("vertex", None)
      if vertex is None:
          raise ValueError("The ply file has no vertex element.")
      if not isinstance(vertex, list):
          raise ValueError("Invalid vertices in file.")
      vertex_head = next(
          head for head in header.elements if head.name == "vertex"
      )
  
      column_idxs = _get_verts_column_indices(vertex_head)
  
      # Case of no vertices
      if vertex_head.count == 0:
          verts = torch.zeros((0, 3), dtype=torch.float32)
          if column_idxs.color_idxs is None:
              return _VertsData(verts=verts)
          return _VertsData(
              verts=verts,
              verts_colors=torch.zeros((0, 3), dtype=torch.float32),
          )
  
      # Simple case where the only data is the vertices themselves
      if (
          len(vertex) == 1
          and isinstance(vertex[0], np.ndarray)
          and vertex[0].ndim == 2
          and vertex[0].shape[1] == 3
      ):
          return _VertsData(
              verts=_make_tensor(vertex[0], cols=3, dtype=torch.float32)
          )
  
      vertex_colors = None
      vertex_normals = None
      vertex_texture_uvs = None
  
      if len(vertex) == 1:
          # This is the case where the whole vertex element has one type,
          # so it was read as a single array and we can index straight into it.
          verts = torch.tensor(
              vertex[0][:, column_idxs.point_idxs], dtype=torch.float32
          )
          if column_idxs.color_idxs is not None:
              vertex_colors = column_idxs.color_scale * torch.tensor(
                  vertex[0][:, column_idxs.color_idxs],
                  dtype=torch.float32,
              )
          if column_idxs.normal_idxs is not None:
              vertex_normals = torch.tensor(
                  vertex[0][:, column_idxs.normal_idxs],
                  dtype=torch.float32,
              )
          if column_idxs.texture_uv_idxs is not None:
              vertex_texture_uvs = torch.tensor(
                  vertex[0][:, column_idxs.texture_uv_idxs],
                  dtype=torch.float32,
              )
      else:
          # The vertex element is heterogeneous. It was read as several arrays,
          # part by part, where a part is a set of properties with the same type.
          # For each property (=column in the file), we store in
          # prop_to_partnum_col its partnum (i.e. the index of what part it is
          # in) and its column number (its index within its part).
          prop_to_partnum_col = [
              (partnum, col)
              for partnum, array in enumerate(vertex)
              for col in range(array.shape[1])
          ]
          verts = torch.empty(
              size=(vertex_head.count, 3), dtype=torch.float32
          )
          for axis in range(3):
              partnum, col = prop_to_partnum_col[
                  column_idxs.point_idxs[axis]
              ]
              verts.numpy()[:, axis] = vertex[partnum][:, col]
              # Note that in the previous line, we made the assignment
              # as numpy arrays by casting verts. If we took the (more
              # obvious) method of converting the right hand side to
              # torch, then we might have an extra data copy because
              # torch wants contiguity. The code would be like:
              #   if not vertex[partnum].flags["C_CONTIGUOUS"]:
              #      vertex[partnum] = np.ascontiguousarray(vertex[partnum])
              #   verts[:, axis] = torch.tensor((vertex[partnum][:, col]))
          if column_idxs.color_idxs is not None:
              vertex_colors = torch.empty(
                  size=(vertex_head.count, 3), dtype=torch.float32
              )
              for color in range(3):
                  partnum, col = prop_to_partnum_col[
                      column_idxs.color_idxs[color]
                  ]
                  vertex_colors.numpy()[:, color] = vertex[partnum][
                      :, col
                  ]
              vertex_colors *= column_idxs.color_scale
          if column_idxs.normal_idxs is not None:
              vertex_normals = torch.empty(
                  size=(vertex_head.count, 3), dtype=torch.float32
              )
              for axis in range(3):
                  partnum, col = prop_to_partnum_col[
                      column_idxs.normal_idxs[axis]
                  ]
                  vertex_normals.numpy()[:, axis] = vertex[partnum][
                      :, col
                  ]
          if column_idxs.texture_uv_idxs is not None:
              vertex_texture_uvs = torch.empty(
                  size=(vertex_head.count, 2),
                  dtype=torch.float32,
              )
              for axis in range(2):
                  partnum, col = prop_to_partnum_col[
                      column_idxs.texture_uv_idxs[axis]
                  ]
                  vertex_texture_uvs.numpy()[:, axis] = vertex[partnum][
                      :, col
                  ]
      return _VertsData(
          verts=verts,
          verts_colors=vertex_colors,
          verts_normals=vertex_normals,
          verts_texture_uvs=vertex_texture_uvs,
      )
  
imports: import itertools
  import os
  import struct
  import sys
  import warnings
  from collections import namedtuple
  from dataclasses import asdict, dataclass
  from io import BytesIO, TextIOBase
  from typing import List, Optional, Tuple
  import numpy
  import torch
  from iopath.common.file_io import PathManager
  from pytorch3d.io.utils import _check_faces_indices, _make_tensor, _open_file, _read_image, PathOrStr
  from pytorch3d.renderer import TexturesUV, TexturesVertex
  from pytorch3d.structures import Meshes, Pointclouds
  from .pluggable_formats import endswith, MeshFormatInterpreter, PointcloudFormatInterpreter
label_desc: Use image node_id 14 for calling a global function with example usage: _get_verts(header, elements) and returns: _VertsData, _VertsData, _VertsData, _VertsData