Skip to content

Instantly share code, notes, and snippets.

@chientrm
Last active January 6, 2022 06:05
Show Gist options
  • Save chientrm/a5d407bfa465e08eb723c29106202d80 to your computer and use it in GitHub Desktop.
Save chientrm/a5d407bfa465e08eb723c29106202d80 to your computer and use it in GitHub Desktop.
Export blender model with texture to a single json file - Blender 3.0
import os
import bpy
import json
import base64
bl_info = {
"name": "json exporter",
"blender": (2, 80, 0),
"author": "Chien Tran",
"category": "Import-Export",
"location": "File > Export > json"
}
class RoundingFloat(float):
__repr__ = staticmethod(lambda x: format(x, '.3f'))
json.encoder.c_make_encoder = None
json.encoder.float = RoundingFloat
class JsonExporter(bpy.types.Operator):
"""json exporter"""
bl_idname = "export.json"
bl_label = "json exporter"
bl_options = {'REGISTER', 'UNDO'}
filepath: bpy.props.StringProperty(subtype='FILE_PATH')
def getImages(self, context):
return ((image.name, image.name, image.name) for image in bpy.data.images)
imageName: bpy.props.EnumProperty(
name="Image",
items=getImages,
description="choose image",
default=None,
options={'ANIMATABLE'},
update=None,
get=None,
set=None
)
def execute(self, context):
filePath = os.path.splitext(bpy.data.filepath)[0] + ".json"
obj = context.object
assert (obj and obj.to_mesh), "Invalid object"
mesh = obj.to_mesh()
mesh.calc_loop_triangles()
uv_layer = obj.data.uv_layers.active.data
image = bpy.data.images[self.imageName]
image.filepath_raw = '/tmp/tmp.png'
image.file_format = 'PNG'
image.save()
with open(filePath, 'w') as f:
json.dump({
"vertices": [[v.co[0], v.co[2], -v.co[1]] for v in mesh.vertices],
"normals": [[v.normal[0], v.normal[2], -v.normal[1]] for v in mesh.vertices],
"indices": [vi for t in mesh.loop_triangles for vi in t.vertices],
"texCoords": [[uv_layer[vi].uv[0], uv_layer[vi].uv[1]]
for t in mesh.loop_triangles for vi in t.loops],
"texture": "data:image/png;base64, "
+ base64.b64encode((open("/tmp/tmp.png",
"rb").read())).decode()
}, f)
return {'FINISHED'}
def invoke(self, context, event):
if not self.filepath:
self.filepath = os.path.splitext(bpy.data.filepath)[0] + ".json"
WindowManager = context.window_manager
WindowManager.fileselect_add(self)
return {'RUNNING_MODAL'}
def menu_func_export(self, context):
self.layout.operator(JsonExporter.bl_idname,
text="Json 3D Export (.json)")
def register():
bpy.utils.register_class(JsonExporter)
bpy.types.TOPBAR_MT_file_export.append(menu_func_export)
def unregister():
bpy.utils.unregister_class(JsonExporter)
bpy.types.TOPBAR_MT_file_export.remove(menu_func_export)
if __name__ == "__main__":
register()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment