model_generator2/generate_cpp.py

99 lines
3.5 KiB
Python

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 ''
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())