from collections import defaultdict import sys from obj import parse_obj_file from obj import VertexPosition from obj import VertexNormal from obj import VertexTexture from obj import ObjFile from obj import Object from obj import Face from obj import FacePTN from generate import renderer from generate_cpp import generate_obj_file global_vertex = { VertexPosition: {}, VertexNormal: {}, VertexTexture: {}, } global_names = defaultdict(int) def merge_vertex(vertex, type): d = global_vertex[type] if vertex not in d: d[vertex] = len(d) def merge_vertices(vertices, type): for vertex in vertices: merge_vertex(vertex, type) def rewrite_ptn(obj_file, ptn): return FacePTN( position=global_vertex[VertexPosition][obj_file.position[ptn.position]], normal=global_vertex[VertexNormal][obj_file.normal[ptn.normal]], texture=global_vertex[VertexTexture][obj_file.texture[ptn.texture]], ) def rewrite_face(obj_file, face): return Face( ptn=[rewrite_ptn(obj_file, face_ptn) for face_ptn in face.ptn] ) def rewrite_object(obj_file, object): global global_names global_names[object.name] += 1 name_suffix = global_names[object.name] return Object( name=f"{object.name}_{name_suffix}", faces=[rewrite_face(obj_file, face) for face in object.faces], material=object.material, ) def rewrite_objects(obj_files): for obj_file in obj_files: for object in obj_file.objects: yield rewrite_object(obj_file, object) def reorder_vertices(type): d = global_vertex[type] dd = {v: k for k, v in d.items()} for i in range(len(dd)): yield dd[i] def rewrite_obj_file(obj_files): for obj_file in obj_files: merge_vertices(obj_file.position, VertexPosition) merge_vertices(obj_file.normal, VertexNormal) merge_vertices(obj_file.texture, VertexTexture) return ObjFile( position=reorder_vertices(VertexPosition), normal=reorder_vertices(VertexNormal), texture=reorder_vertices(VertexTexture), objects=list(rewrite_objects(obj_files)) ) if __name__ == "__main__": filenames = sys.argv[2:] obj_files = [parse_obj_file(fn) for fn in filenames] obj_file = rewrite_obj_file(obj_files) render, out = renderer(indent_length=4) render(generate_obj_file(sys.argv[1], obj_file)) sys.stdout.write(out.getvalue())