import copy
import re
import ddg
def _read_obj(filename):
"""Read an obj file and saves the vertex coordinates and face indices in a
dictionary: `data = {"v":[], "f":[]}`
For each geometric object, a data dictionary of vertices and faces is
created. If multiple geometric objects exist in the obj file, multiples of
such dictionaries are created, one for each object. These dictionaries are
then saved in another dictionary, whose keys are the object names in the
obj file.
For the case that the obj file only contains a single geometric object and
no name is specified for it, it is saved under the name "ifs_obj" is the
nested dictionary of the output.
Parameters
----------
filename : string
Path to the obj file.
Returns
-------
dict
Nested dictionary of the obj data.
"""
objects = dict()
name = "ifs_obj"
data = {"v": [], "f": []}
objects[name] = copy.deepcopy(data)
default_name_duplicate_in_obj_flag = False
file = open(filename, "r", encoding="utf8", errors="ignore")
for line in file:
if line.startswith("o"):
name = line[2:-1]
if name == "ifs_obj":
objects[name] = copy.deepcopy(data)
default_name_duplicate_in_obj_flag = True
elif "ifs_obj" in objects and not default_name_duplicate_in_obj_flag:
objects[name] = objects.pop("ifs_obj")
else:
objects[name] = copy.deepcopy(data)
if line.startswith("v "):
objects[name][line.split()[0]].append(
[float(s) for s in re.findall(r"-?\d+(?:\.\d+)?", line)]
)
if line.startswith("f"):
objects[name]["f"].append(line[1:])
file.close()
for key in objects.keys():
objects[key]["f"] = [
[int(s[1:]) - 1 for s in re.findall(r" \d+", face)]
for face in objects[key]["f"]
]
return objects
[docs]def obj_to_ifs(filename, attribute_name):
"""
Convert an obj file into an IndexedFaceSet.
If there are multiple objects in the obj file, the output is a dictionary,
whose keys are the object names. If only one object is in the obj file, the
corresponding IndexedFaceSet is returned directly.
Parameters
----------
filename : string
(path and) name of the obj file
attribute_name : string
Name of the vertex attribute storing the coordinates
Returns
-------
dict
dict of ddg.datastructures.IndexedFaceSet for each object data in the obj file.
The keys are the names of the objects.
"""
data = _read_obj(filename)
surfaces = dict()
for key in data.keys():
faceSet = ddg.indexedfaceset.ifs.IndexedFaceSet(data[key]["f"])
faceSet.set_attribute(attribute_name, "verts", data[key]["v"])
surfaces[str(key)] = faceSet
if len(surfaces.keys()) == 1:
return list(surfaces.values())[0]
else:
return surfaces