import ddg
def _initialize(surface, filename="obj_file.obj", co_attr="co"):
data = {
"hds": surface,
"filename": filename,
"filetype": None,
"co": co_attr,
"vt": {},
"vn": {},
}
_initialize_vt_and_vn(data)
return data
def _initialize_vt_and_vn(data):
for e in data["hds"].edges:
if hasattr(e, "vt"):
data["vt"][tuple(e.vt)] = -1
if hasattr(e, "vn"):
data["vn"][tuple(e.vn)] = -1
if data["vt"] == {} and data["vn"] == {}:
data["filetype"] = "0"
if data["vt"] != {} and data["vn"] == {}:
data["filetype"] = "T"
if data["vt"] == {} and data["vn"] != {}:
data["filetype"] = "N"
if data["vt"] != {} and data["vn"] != {}:
data["filetype"] = "TN"
data["vt"] = {vt: i for i, vt in enumerate(sorted(data["vt"].keys()))}
data["vn"] = {vn: i for i, vn in enumerate(sorted(data["vn"].keys()))}
def _write_obj(data):
"""
Write the data on an obj file. The path of the obj file must be given as a
key of the data dictionary.
"""
with open(data["filename"], "w+") as f:
f.write("Obj file created by halfedge data structure \n\n")
for v in data["hds"].verts:
if not hasattr(v, data["co"]):
raise ValueError("Vertex has not the specified coordinate attribute")
f.write(
"v {0} {1} {2}\n".format(
getattr(v, data["co"])[0],
getattr(v, data["co"])[1],
getattr(v, data["co"])[2],
)
)
f.write("\n")
for attr in ["vt", "vn"]:
for coords in sorted(data[attr], key=data[attr].get):
line = " ".join(str(x) for x in coords)
f.write("{0} {1}\n".format(attr, line))
if data[attr] != {}:
f.write("\n")
for face in data["hds"].faces:
f.write("f")
for e in ddg.datastructures.halfedge.get.get_edge_loop(face.edge):
if data["filetype"] == "0":
f.write(" {0}".format(e.pre.head.index + 1))
if data["filetype"] == "T":
f.write(
" {0}/{1}".format(
e.pre.head.index + 1, data["vt"][tuple(e.pre.vt)] + 1
)
)
if data["filetype"] == "N":
f.write(
" {0}//{1}".format(
e.pre.head.index + 1, data["vn"][tuple(e.pre.vn)] + 1
)
)
if data["filetype"] == "TN":
f.write(
" {0}/{1}/{2}".format(
e.pre.head.index + 1,
data["vt"][tuple(e.pre.vt)] + 1,
data["vn"][tuple(e.pre.vn)] + 1,
)
)
f.write("\n")
[docs]def hds_to_obj(surface, filename="obj_file.obj", co_attr="co"):
"""
| Converts a ddg.halfedge.Surface to an obj file.
| If 'vn' and/or 'vt' are given as halfedge attributes, they will be
| written in the obj file format.
| The vertices need to have an attribute storing the coordinates.
| Results in obj file with given v and faces of the form f 1 2 3
| or given v,vt and faces of the form f 1/1 2/1 3/1
| or given v,vn and faces of the form f 1//1 2//1 3//1
| or given v,vt,vn and faces of the form f 1/1/2 2/1/2 3/1/2.
| Vertices will be ordered by indices and vt and vn coordinates in increasing order.
Parameters
----------
surface: ddg.halfedge.Surface
halfedge data structure to be converted
filename : str (default='obj_file.obj')
Name for the resulting obj file
a file path can be specified here
default is 'obj_file' which will be saved in the cwd
co_attr : str (default='co')
string of the vertx attribute that stores the coordinates
Notes
-----
* Indexing in obj files starts at 1.
"""
encoder = _initialize(surface, filename, co_attr)
_write_obj(encoder)