1
0
chip8-zig/src/assets/models/export_obj.py

107 lines
3.1 KiB
Python

import bpy
from os import path
import os
from dataclasses import dataclass
import shutil
@dataclass
class OBJMetadata:
materials: list[str]
objects: list[str]
D = bpy.data
C = bpy.context
def select_one_object(obj):
bpy.ops.object.select_all(action='DESELECT')
bpy.context.view_layer.objects.active = obj # type: ignore
obj.select_set(True)
def iter_buttons():
object_names = D.objects.keys()
assert object_names
for name in object_names:
print(name)
if name.startswith("Buttons "):
yield D.objects[name]
def extract_metadata(obj_path):
mtl_filename = None
objects = []
with open(obj_path, "r") as f:
for line in f.readlines():
if line.startswith("mtllib"):
mtl_filename = line.removeprefix("mtllib ")
elif line.startswith("o"):
object_name = line.strip().removeprefix("o ")
objects.append(object_name)
materials = []
if mtl_filename:
mtl_path = path.join(path.dirname(obj_path), mtl_filename).strip()
with open(mtl_path, "r") as f:
for line in f.readlines():
if not line.startswith("newmtl"): continue
material_name = line.strip().removeprefix("newmtl ")
materials.append(material_name)
return OBJMetadata(materials, objects)
def write_list_to_file(filename, values):
with open(filename, "w") as f:
for i in range(len(values)):
if i > 0: f.write("\n")
f.writelines(values[i])
export_options = {
"use_triangles": True,
"use_materials": True,
"use_normals": True,
"use_vertex_groups": True,
"path_mode": "RELATIVE",
}
bpy.ops.object.select_all(action="SELECT")
for btn in iter_buttons():
btn.select_set(False)
bpy.ops.export_scene.obj(
filepath="emulator.obj",
use_selection=True,
**export_options
)
metadata = extract_metadata("emulator.obj")
write_list_to_file("emulator.mtls.txt", metadata.materials)
write_list_to_file("emulator.objs.txt", metadata.objects)
object_names = D.objects.keys()
assert object_names
for name in object_names:
if name.startswith("Buttons "):
button_name = name.removeprefix("Buttons ")
button_obj_path = f"buttons/Button {button_name}.obj"
button_mtl_path = f"buttons/Button {button_name}.mtl"
select_one_object(D.objects[name])
bpy.ops.export_scene.obj(
filepath=button_obj_path,
use_selection=True,
**export_options
)
tmp_file = "/tmp/blender_export"
with open(button_obj_path, "r") as src:
with open(tmp_file, "w") as dst:
for line in src.readlines():
if line.startswith("mtllib"):
dst.write("mtllib Button.mtl\n")
else:
dst.write(line)
os.remove(button_obj_path)
shutil.move(tmp_file, button_obj_path)
if button_name == "0":
os.rename("buttons/Button 0.mtl", "buttons/Button.mtl")
else:
os.remove(button_mtl_path)