code: def _compute_vertex_normals(face_normals, faces, vertices):
      if face_normals.shape[1:] != (3,):
          raise ValueError(
              "Expected (F, 3) array of face normals, got"
              f" {face_normals.shape}."
          )
      if faces.shape[1:] != (3,):
          raise ValueError(
              "Expected (F, 3) array of face vertex indices, got"
              f" {faces.shape}."
          )
      if vertices.shape[1:] != (3,):
          raise ValueError(
              "Expected (N, 3) array of vertices, got"
              f" {vertices.shape}."
          )
  
      vertex_normals = np.zeros_like(vertices)
      n_corners_in_triangle = 3
      face_normals_repeated_on_corners = np.repeat(
          face_normals, n_corners_in_triangle, axis=0
      )
      # NOTE: The next line is equivalent to
      #
      #   vertex_normals[self._faces.ravel()] += face_normals_repeated_on_corners
      #
      # except that it accumulates the values from the right hand side at
      # repeated indices on the left hand side, instead of overwritting them,
      # like in the above.
      np.add.at(
          vertex_normals,
          faces.ravel(),
          face_normals_repeated_on_corners,
      )
  
      norms = np.sqrt((vertex_normals**2).sum(axis=1))
      nonzero_norms = norms > 0
      vertex_normals[nonzero_norms] /= norms[nonzero_norms][:, None]
  
      return vertex_normals
  
imports: import numpy
label_desc: Use image node_id 4 for calling a global function with example usage: _compute_vertex_normals(face_normals, faces, vertices) and returns: vertex_normals