code: def write_ply(
      filename, field_list, field_names, triangular_faces=None
  ):
      """
      Write ".ply" files
      Parameters
      ----------
      filename : string
          the name of the file to which the data is saved. A '.ply' extension will be appended to the
          file name if it does no already have one.
      field_list : list, tuple, numpy array
          the fields to be saved in the ply file. Either a numpy array, a list of numpy arrays or a
          tuple of numpy arrays. Each 1D numpy array and each column of 2D numpy arrays are considered
          as one field.
      field_names : list
          the name of each fields as a list of strings. Has to be the same length as the number of
          fields.
      Examples
      --------
      >>> points = np.random.rand(10, 3)
      >>> write_ply('example1.ply', points, ['x', 'y', 'z'])
      >>> values = np.random.randint(2, size=10)
      >>> write_ply('example2.ply', [points, values], ['x', 'y', 'z', 'values'])
      >>> colors = np.random.randint(255, size=(10,3), dtype=np.uint8)
      >>> field_names = ['x', 'y', 'z', 'red', 'green', 'blue', values']
      >>> write_ply('example3.ply', [points, colors, values], field_names)
      """
  
      # Format list input to the right form
      field_list = (
          list(field_list)
          if (type(field_list) == list or type(field_list) == tuple)
          else list((field_list,))
      )
      for i, field in enumerate(field_list):
          if field.ndim < 2:
              field_list[i] = field.reshape(-1, 1)
          if field.ndim > 2:
              log.info("fields have more than 2 dimensions")
              return False
  
      # check all fields have the same number of data
      n_points = [field.shape[0] for field in field_list]
      if not np.all(np.equal(n_points, n_points[0])):
          log.info("wrong field dimensions")
          return False
  
      # Check if field_names and field_list have same nb of column
      n_fields = np.sum([field.shape[1] for field in field_list])
      if n_fields != len(field_names):
          log.info("wrong number of field names")
          return False
  
      # Add extension if not there
      if not filename.endswith(".ply"):
          filename += ".ply"
  
      # open in text mode to write the header
      with open(filename, "w") as plyfile:
          # First magical word
          header = ["ply"]
  
          # Encoding format
          header.append(
              "format binary_" + sys.byteorder + "_endian 1.0"
          )
  
          # Points properties description
          header.extend(header_properties(field_list, field_names))
  
          # Add faces if needded
          if triangular_faces is not None:
              header.append(
                  "element face {:d}".format(triangular_faces.shape[0])
              )
              header.append("property list uchar int vertex_indices")
  
          # End of header
          header.append("end_header")
  
          # Write all lines
          for line in header:
              plyfile.write("%s\n" % line)
  
      # open in binary/append to use tofile
      with open(filename, "ab") as plyfile:
          # Create a structured array
          i = 0
          type_list = []
          for fields in field_list:
              for field in fields.T:
                  type_list += [(field_names[i], field.dtype.str)]
                  i += 1
          data = np.empty(field_list[0].shape[0], dtype=type_list)
          i = 0
          for fields in field_list:
              for field in fields.T:
                  data[field_names[i]] = field
                  i += 1
  
          data.tofile(plyfile)
  
          if triangular_faces is not None:
              triangular_faces = triangular_faces.astype(np.int32)
              type_list = [("k", "uint8")] + [
                  (str(ind), "int32") for ind in range(3)
              ]
              data = np.empty(
                  triangular_faces.shape[0], dtype=type_list
              )
              data["k"] = np.full(
                  (triangular_faces.shape[0],), 3, dtype=np.uint8
              )
              data["0"] = triangular_faces[:, 0]
              data["1"] = triangular_faces[:, 1]
              data["2"] = triangular_faces[:, 2]
              data.tofile(plyfile)
  
      return True
  
file_path: torch-points3d/torch_points3d/modules/KPConv/plyutils.py
imports: import numpy
  import sys
  import logging
label_desc: Use image node_id 5 for calling a global function with example usage: write_ply(filename, field_list, field_names, triangular_faces) and returns: True, False, False, False