model_generator2/combine_obj.py
2025-04-02 12:54:43 -05:00

84 lines
2.4 KiB
Python

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