abrasion/blender/export.py

118 lines
3.6 KiB
Python

import flatbuffers
import Q3DModel.Model
import Q3DObject.Mesh
import bpy
def export(context, objects, name='all'):
from abrasion.blender.addon import console_print
console_print(context, "Starting export...")
path = bpy.data.filepath
if path == "":
raise Exception("File must be saved")
path += f".{name}.q3dm"
builder = flatbuffers.Builder(1024)
depsgraph = context.evaluated_depsgraph_get()
nodes = []
for o in objects:
console_print(context, f"{o.type}: {o.name}")
if o.type != 'MESH':
console_print(context, " ... skipped.")
continue
mesh = o.evaluated_get(depsgraph).data
mesh.calc_loop_triangles()
fverts = []
for vertex in mesh.vertices:
Q3DObject.Vertex.VertexStart(builder)
position = Q3DObject.Vector3.CreateVector3(
builder,
x = vertex.co.x,
y = vertex.co.y,
z = vertex.co.z,
)
Q3DObject.Vertex.VertexAddPosition(builder, position)
normal = Q3DObject.Vector3.CreateVector3(
builder,
x = vertex.normal.x,
y = vertex.normal.y,
z = vertex.normal.z,
)
Q3DObject.Vertex.VertexAddNormal(builder, normal)
fverts.append(Q3DObject.Vertex.VertexEnd(builder))
nverts = len(fverts)
Q3DObject.Mesh.MeshStartVerticesVector(
builder, len(fverts))
for ivert in reversed(range(len(fverts))):
builder.PrependUOffsetTRelative(fverts[ivert])
fverts = builder.EndVector()
ntris = len(mesh.loop_triangles)
Q3DObject.Mesh.MeshStartTrianglesVector(
builder, ntris)
for triangle in mesh.loop_triangles:
Q3DObject.ITriangle.CreateITriangle(
builder,
triangle.vertices[0],
triangle.vertices[1],
triangle.vertices[2],
)
ftris = builder.EndVector()
console_print(context, f" ... {nverts} vertices, {ntris} triangles")
Q3DObject.Mesh.MeshStart(builder)
Q3DObject.Mesh.MeshAddItriangles(builder, ftris)
Q3DObject.Mesh.MeshAddVertices(builder, fverts)
fmesh = Q3DObject.Mesh.MeshEnd(builder)
Q3DModel.Node.NodeStart(builder)
Q3DModel.Node.NodeAddMesh(builder, fmesh)
c0 = o.matrix_world.col[0]
c1 = o.matrix_world.col[1]
c2 = o.matrix_world.col[2]
c3 = o.matrix_world.col[3]
Q3DModel.Node.NodeAddTransform(builder, Q3DModel.Matrix4.CreateMatrix4(
builder,
c0.x, c0.y, c0.z, c0.w,
c1.x, c1.y, c1.z, c1.w,
c2.x, c2.y, c2.z, c2.w,
c3.x, c3.y, c3.z, c3.w,
))
nodes.append(Q3DModel.Node.NodeEnd(builder))
Q3DModel.Node.NodeStartChildrenVector(builder, len(nodes))
for node in nodes:
builder.PrependUOffsetTRelative(node)
nodes = builder.EndVector()
Q3DModel.Node.NodeStart(builder)
Q3DModel.Node.NodeAddTransform(builder, Q3DModel.Matrix4.CreateMatrix4(
builder,
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1,
))
Q3DModel.Node.NodeAddChildren(builder, nodes)
root = Q3DModel.Node.NodeEnd(builder)
Q3DModel.Model.ModelStart(builder)
Q3DModel.Model.ModelAddRoot(builder, root)
model = Q3DModel.Model.ModelEnd(builder)
builder.Finish(model, file_identifier=b'Q3DM')
buf = builder.Output()
with open(path, 'wb') as f:
f.write(buf)
console_print(context, f"Saved to {path}")