docs: def read_objfile(fname):
      """Takes .obj filename and returns dict of object properties for each object in file."""
      verts = defaultdict(list)
      obj_props = []
      with open(fname) as f:
          lines = f.read().splitlines()
  
      for line in lines:
          if line:
              split_line = line.strip().split(' ', 1)
              if len(split_line) < 2:
                  continue
  
              prefix, value = split_line[0], split_line[1]
              if prefix == 'o':
                  obj_props.append({})
                  obj = obj_props[-1]
                  obj['f'] = []
                  obj[prefix] = value
              # For files without an 'o' statement
              elif prefix == 'v' and len(obj_props) < 1:
                  obj_props.append({})
                  obj = obj_props[-1]
                  obj['f'] = []
                  obj['o'] = fname
              if obj_props:
                  if prefix[0] == 'v':
                      verts[prefix].append([float(val) for val in value.split(' ')])
                  elif prefix == 'f':
                      obj[prefix].append(parse_mixed_delim_str(value))
                  else:
                      obj[prefix] = value
  
  
      # Reindex vertices to be in face index order, then remove face indices.
      verts = {key: np.array(value) for key, value in iteritems(verts)}
      for obj in obj_props:
          obj['f'] = tuple(np.array(verts) if verts[0] else tuple() for verts in zip(*obj['f']))
          for idx, vertname in enumerate(['v' ,'vt', 'vn']):
              if vertname in verts:
                  obj[vertname] = verts[vertname][obj['f'][idx].flatten() - 1, :]
              else:
                  obj[vertname] = tuple()
          del obj['f']
  
      geoms = {obj['o']:obj for obj in obj_props}
  
      return geoms