from generate import renderer from obj import parse_obj_file import sys def generate_vec3(vs): for v in vs: yield f"{{{v.x.to_string()}f, {v.y.to_string()}f, {v.z.to_string()}f}}," def generate_vec2(vs): for v in vs: yield f"{{{v.x.to_string()}f, {v.y.to_string()}f}}," def generate_vec(name, type, func, vs): yield f"const vertex_{type} {name}_{type}[] = {{" yield from func(vs) yield "};" def filter_n(l, n): for a in l: if len(a.ptn) == n: yield a def generate_ptn(ptn): for p in ptn: yield f"{{{p.position}, {p.texture}, {p.normal}}}," def generate_faces(group_name, model_name, faces, type, n): yield f"const union {type} {group_name}_{model_name}_{type}[] = {{" for face in filter_n(faces, n): yield "{ .v = {" yield from generate_ptn(face.ptn) yield "}}," yield "};" def generate_lines(group_name, model_name, lines, type, n): yield f"const union {type} {group_name}_{model_name}_{type}[] = {{" for line in lines: yield "{" yield f".a = {line.a}," yield f".b = {line.b}," yield "}," yield "};" def generate_object(group_name, object): yield f"const struct object {group_name}_{object.name} = {{" yield f".triangle = &{group_name}_{object.name}_triangle[0]," yield f".quadrilateral = &{group_name}_{object.name}_quadrilateral[0]," yield f".line = &{group_name}_{object.name}_line[0]," triangle_count = sum(1 for _ in filter_n(object.faces, 3)) quadrilateral_count = sum(1 for _ in filter_n(object.faces, 4)) line_count = len(object.lines) yield f".triangle_count = {triangle_count}," yield f".quadrilateral_count = {quadrilateral_count}," yield f".line_count = {line_count}," if object.material is None: yield ".material = 0," else: yield f".material = {group_name}_{object.material.name}," yield "};" def generate_object_array(group_name, obj_file): yield f"const struct object * {group_name}_object[] = {{" for object in obj_file.objects: yield f"&{group_name}_{object.name}," yield "};" def generate_model(group_name, obj_file): yield f"const struct model {group_name}_model = {{" yield f".position = {group_name}_position," yield f".texture = {group_name}_texture," yield f".normal = {group_name}_normal," yield f".object = {group_name}_object," yield f".object_count = {len(obj_file.objects)}" yield "};" def generate_obj_file(group_name, obj_file): yield "#pragma once" yield '#include "../model.h"' yield '' yield from generate_vec(group_name, "position", generate_vec3, obj_file.position) yield from generate_vec(group_name, "texture", generate_vec2, obj_file.texture) yield from generate_vec(group_name, "normal", generate_vec3, obj_file.normal) for object in obj_file.objects: assert all(len(face.ptn) in {3, 4} for face in object.faces), object.name yield from generate_faces(group_name, object.name, object.faces, "triangle", 3) yield from generate_faces(group_name, object.name, object.faces, "quadrilateral", 4) yield from generate_lines(group_name, object.name, object.lines, "line", 4) yield from generate_object(group_name, object) yield from generate_object_array(group_name, obj_file) yield from generate_model(group_name, obj_file) if __name__ == "__main__": obj_file = parse_obj_file(sys.argv[1]) render, out = renderer(indent_length=4) render(generate_obj_file(sys.argv[2], obj_file)) sys.stdout.write(out.getvalue())