diff --git a/generate_cpp.py b/generate_cpp.py index 9bd1e75..abc5375 100644 --- a/generate_cpp.py +++ b/generate_cpp.py @@ -32,14 +32,26 @@ def generate_faces(group_name, model_name, faces, type, n): 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: @@ -74,6 +86,7 @@ def generate_obj_file(group_name, obj_file): 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) diff --git a/obj.py b/obj.py index e77b3bb..87daa7c 100644 --- a/obj.py +++ b/obj.py @@ -46,6 +46,11 @@ class FacePTN: class Face: ptn: list[FacePTN] +@dataclass +class Line: + a: int + b: int + @dataclass class Material: name: str @@ -54,11 +59,13 @@ class Material: class Object: name: str faces: list[Face] + lines: list[Line] material: Material - def __init__(self, name, faces=None, material=None): + def __init__(self, name, faces=None, lines=None, material=None): self.name = name self.faces = [] if faces is None else faces + self.lines = [] if lines is None else lines self.material = material @dataclass @@ -124,6 +131,12 @@ def parse_usemtl(line): name, = line return Material(name) +def parse_polyline(line): + assert len(line) == 2 + a, b = line + return Line(int(a, 10) - 1, + int(b, 10) - 1) + def parse_line(line): t, *line = line.split(' ') if t == '#': @@ -147,7 +160,7 @@ def parse_line(line): return None if t == 'l': # polyline - return None + return parse_polyline(line) assert False, (t, line) def parse_obj_lines(lines): @@ -175,9 +188,11 @@ def parse_obj_lines(lines): file.objects.append(object) object = Object(object.name + "_mtl_" + x.name) object.material = x + elif type(x) is Line: + object.lines.append(x) else: assert False, x - if object.faces: + if object.faces or object.lines: assert object.name != None file.objects.append(object) return file