code: def _write_normals(
      normals: torch.Tensor,
      faces_normals_idx: torch.Tensor,
      float_str: str,
  ) -> str:
      if faces_normals_idx.dim() != 2 or faces_normals_idx.size(1) != 3:
          message = "'faces_normals_idx' should either be empty or of shape (num_faces, 3)."
          raise ValueError(message)
  
      if normals.dim() != 2 or normals.size(1) != 3:
          message = "'normals' should either be empty or of shape (num_verts, 3)."
          raise ValueError(message)
  
      normals, faces_normals_idx = (
          normals.cpu(),
          faces_normals_idx.cpu(),
      )
  
      lines = []
      V, D = normals.shape
      for i in range(V):
          normal = [float_str % normals[i, j] for j in range(D)]
          lines.append("vn %s\n" % " ".join(normal))
      return "".join(lines)
  
imports: import os
  import warnings
  from collections import namedtuple
  from pathlib import Path
  from typing import List, Optional
  import numpy
  import torch
  from iopath.common.file_io import PathManager
  from PIL import Image
  from pytorch3d.common.datatypes import Device
  from pytorch3d.io.mtl_io import load_mtl, make_mesh_texture_atlas
  from pytorch3d.io.utils import _check_faces_indices, _make_tensor, _open_file, PathOrStr
  from pytorch3d.renderer import TexturesAtlas, TexturesUV
  from pytorch3d.structures import join_meshes_as_batch, Meshes
  from .pluggable_formats import endswith, MeshFormatInterpreter
label_desc: Use image node_id 10 for calling a global function with example usage: _write_normals(normals, faces_normals_idx, float_str) and returns: str