in pytorch3d/io/obj_io.py [0:0]
def _parse_obj(f, data_dir: str):
"""
Load a mesh from a file-like object. See load_obj function for more details
about the return values.
"""
verts, normals, verts_uvs = [], [], []
faces_verts_idx, faces_normals_idx, faces_textures_idx = [], [], []
faces_materials_idx = []
material_names = []
mtl_path = None
lines = [line.strip() for line in f]
# startswith expects each line to be a string. If the file is read in as
# bytes then first decode to strings.
if lines and isinstance(lines[0], bytes):
lines = [el.decode("utf-8") for el in lines]
materials_idx = -1
for line in lines:
tokens = line.strip().split()
if line.startswith("mtllib"):
if len(tokens) < 2:
raise ValueError("material file name is not specified")
# NOTE: only allow one .mtl file per .obj.
# Definitions for multiple materials can be included
# in this one .mtl file.
mtl_path = line[len(tokens[0]) :].strip() # Take the remainder of the line
mtl_path = os.path.join(data_dir, mtl_path)
elif len(tokens) and tokens[0] == "usemtl":
material_name = tokens[1]
# materials are often repeated for different parts
# of a mesh.
if material_name not in material_names:
material_names.append(material_name)
materials_idx = len(material_names) - 1
else:
materials_idx = material_names.index(material_name)
elif line.startswith("v "): # Line is a vertex.
vert = [float(x) for x in tokens[1:4]]
if len(vert) != 3:
msg = "Vertex %s does not have 3 values. Line: %s"
raise ValueError(msg % (str(vert), str(line)))
verts.append(vert)
elif line.startswith("vt "): # Line is a texture.
tx = [float(x) for x in tokens[1:3]]
if len(tx) != 2:
raise ValueError(
"Texture %s does not have 2 values. Line: %s" % (str(tx), str(line))
)
verts_uvs.append(tx)
elif line.startswith("vn "): # Line is a normal.
norm = [float(x) for x in tokens[1:4]]
if len(norm) != 3:
msg = "Normal %s does not have 3 values. Line: %s"
raise ValueError(msg % (str(norm), str(line)))
normals.append(norm)
elif line.startswith("f "): # Line is a face.
# Update face properties info.
_parse_face(
line,
tokens,
materials_idx,
faces_verts_idx,
faces_normals_idx,
faces_textures_idx,
faces_materials_idx,
)
return (
verts,
normals,
verts_uvs,
faces_verts_idx,
faces_normals_idx,
faces_textures_idx,
faces_materials_idx,
material_names,
mtl_path,
)