Source code for ddg.conversion.obj.halfedge

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)