<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 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