docs: def pack(self, packer=default_packer) -> bytes:
          '''
              Args:
                  packer (str or lambda): The vertex attributes to pack.
  
              Returns:
                  bytes: The packed vertex data.
  
              Examples:
  
                  .. code-block:: python
  
                      import ModernGL
                      from ModernGL.ext import obj
  
                      model = obj.Obj.open('box.obj')
  
                      # default packer
                      data = model.pack()
  
                      # same as the default packer
                      data = model.pack('vx vy vz tx ty tz nx ny nz')
  
                      # pack vertices
                      data = model.pack('vx vy vz')
  
                      # pack vertices and texture coordinates (xy)
                      data = model.pack('vx vy vz tx ty')
  
                      # pack vertices and normals
                      data = model.pack('vx vy vz nx ny nz')
  
                      # pack vertices with padding
                      data = model.pack('vx vy vz 0.0')
          '''
  
          if isinstance(packer, str):
              nodes = packer.split()
              packer = eval(PACKER % (len(nodes), ', '.join(nodes)))
  
          result = bytearray()
  
          for v, t, n in self.face:
              vx, vy, vz = self.vert[v - 1]
              tx, ty, tz = self.text[t - 1] if t is not None else (0.0, 0.0, 0.0)
              nx, ny, nz = self.norm[n - 1] if n is not None else (0.0, 0.0, 0.0)
              result += packer(vx, vy, vz, tx, ty, tz, nx, ny, nz)
  
          return bytes(result)