-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathexport.py
119 lines (92 loc) · 2.94 KB
/
export.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
import bpy
import itertools
import json
import bmesh
import sys
import math
from more_itertools import flatten
from bpy_extras import io_utils
from mathutils import Matrix
def flatten_matrix(m):
return list(flatten(map(lambda x: list(x), m)))
def export_light(light, view):
match light.type:
case "AREA":
return {
"Area": {
"size": light.size,
"transform": flatten_matrix(view.transposed()),
"power": light.energy,
"color": [light.color[0], light.color[1], light.color[2], 0],
}
}
case _:
raise Exception("unsupported light type")
def export_material(material):
return {
"metalic": material.metallic,
"color": list(material.diffuse_color),
"roughness": material.roughness,
}
def export_camera(camera, view):
return {
"fov": 2.0 * math.atan2(0.5 * camera.sensor_height, camera.lens),
"aspect_ratio": bpy.context.scene.render.resolution_x
/ bpy.context.scene.render.resolution_y,
"znear": camera.clip_start,
"zfar": camera.clip_end,
"transform": flatten_matrix(view.transposed()),
}
def export_mesh(mesh):
bm = bmesh.new()
bm.from_mesh(mesh)
verts = list(map(lambda v: list(v.co), bm.verts))
normals = list(map(lambda v: list(v.normal), bm.verts))
faces = []
for face in bmesh.ops.triangulate(bm, faces=bm.faces)["faces"]:
faces.append(list(map(lambda v: v.index, face.verts)))
return {"verts": verts, "normals": normals, "faces": faces}
def export_object(object):
mesh = object.data.name
transform = flatten_matrix(object.matrix_world.transposed())
material = object.material_slots[0].name
return {"mesh": mesh, "transform": transform, "material": material}
meshes = {}
materials = {}
objects = []
lights = []
for mesh in bpy.data.meshes:
meshes[mesh.name] = export_mesh(mesh)
for material in bpy.data.materials:
materials[material.name] = export_material(material)
for obj in bpy.context.scene.objects:
match obj.type:
case "MESH":
objects.append(export_object(obj))
case "LIGHT":
light = obj.data
lights.append(export_light(light, obj.matrix_world))
camera = export_camera(
bpy.context.scene.objects["Camera"].data,
bpy.context.scene.objects["Camera"].matrix_world,
)
outfile = sys.argv[sys.argv.index("--") + 1]
with open(outfile, "w") as output:
print(
json.dumps(
{
"background": [0, 0, 0, 0],
"meshes": meshes,
"objects": objects,
"lights": lights,
"materials": materials,
"camera": camera,
}
),
file=output,
)
# Local Variables:
# fmt-executable: "black"
# fmt-args: ("-")
# eval: (add-hook 'before-save-hook 'fmt-current-buffer nil t)
# End: