glTF exporter: vertex group check enhancement + glTF file fixed order

This commit is contained in:
Julien Duroure 2019-01-23 18:30:25 +01:00
parent d09dbb28ec
commit 208eb40d55
3 changed files with 53 additions and 17 deletions

View File

@ -39,7 +39,7 @@ def save(context, export_settings):
def __export(export_settings):
export_settings['gltf_channelcache'] = dict()
exporter = GlTF2Exporter(__get_copyright(export_settings))
__add_root_objects(exporter, export_settings)
__gather_gltf(exporter, export_settings)
buffer = __create_buffer(exporter, export_settings)
exporter.finalize_images(export_settings[gltf2_blender_export_keys.FILE_DIRECTORY])
json = __fix_json(exporter.glTF.to_dict())
@ -53,7 +53,7 @@ def __get_copyright(export_settings):
return None
def __add_root_objects(exporter, export_settings):
def __gather_gltf(exporter, export_settings):
scenes, animations = gltf2_blender_gather.gather_gltf2(export_settings)
for scene in scenes:
exporter.add_scene(scene)
@ -83,6 +83,8 @@ def __fix_json(obj):
for key, value in obj.items():
if value is None:
continue
elif isinstance(value, dict) and len(value) == 0:
continue
elif isinstance(value, list) and len(value) == 0:
continue
fixed[key] = __fix_json(value)

View File

@ -208,10 +208,21 @@ def __gather_trans_rot_scale(blender_object, export_settings):
def __gather_skin(blender_object, export_settings):
modifiers = {m.type: m for m in blender_object.modifiers}
if "ARMATURE" not in modifiers:
return None
if "ARMATURE" in modifiers:
# Skins and meshes must be in the same glTF node, which is different from how blender handles armatures
return gltf2_blender_gather_skins.gather_skin(modifiers["ARMATURE"].object, export_settings)
# no skin needed when the modifier is linked without having a vertex group
vertex_groups = blender_object.vertex_groups
if len(vertex_groups) == 0:
return None
# check if any vertices in the mesh are part of a vertex group
blender_mesh = blender_object.to_mesh(bpy.context.depsgraph, True)
if not any(vertex.groups is not None and len(vertex.groups) > 0 for vertex in blender_mesh.vertices):
return None
# Skins and meshes must be in the same glTF node, which is different from how blender handles armatures
return gltf2_blender_gather_skins.gather_skin(modifiers["ARMATURE"].object, export_settings)
def __gather_weights(blender_object, export_settings):

View File

@ -26,24 +26,47 @@ import struct
#
# Functions
#
from collections import OrderedDict
def save_gltf(glTF, export_settings, encoder, glb_buffer):
def save_gltf(gltf, export_settings, encoder, glb_buffer):
indent = None
separators = separators = (',', ':')
separators = (',', ':')
if export_settings['gltf_format'] != 'GLB':
indent = 4
# The comma is typically followed by a newline, so no trailing whitespace is needed on it.
separators = separators = (',', ' : ')
separators = (',', ' : ')
glTF_encoded = json.dumps(glTF, indent=indent, separators=separators, sort_keys=True, cls=encoder, allow_nan=False)
sort_order = [
"asset",
"extensionsUsed",
"extensionsRequired",
"extensions",
"extras",
"scene",
"scenes",
"nodes",
"cameras",
"animations",
"materials",
"meshes",
"textures",
"images",
"skins",
"accessors",
"bufferViews",
"samplers",
"buffers"
]
gltf_ordered = OrderedDict(sorted(gltf.items(), key=lambda item: sort_order.index(item[0])))
gltf_encoded = json.dumps(gltf_ordered, indent=indent, separators=separators, cls=encoder, allow_nan=False)
#
if export_settings['gltf_format'] != 'GLB':
file = open(export_settings['gltf_filepath'], "w", encoding="utf8", newline="\n")
file.write(glTF_encoded)
file.write(gltf_encoded)
file.write("\n")
file.close()
@ -56,18 +79,18 @@ def save_gltf(glTF, export_settings, encoder, glb_buffer):
else:
file = open(export_settings['gltf_filepath'], "wb")
glTF_data = glTF_encoded.encode()
gltf_data = gltf_encoded.encode()
binary = glb_buffer
length_gtlf = len(glTF_data)
spaces_gltf = (4 - (length_gtlf & 3)) & 3
length_gtlf += spaces_gltf
length_gltf = len(gltf_data)
spaces_gltf = (4 - (length_gltf & 3)) & 3
length_gltf += spaces_gltf
length_bin = len(binary)
zeros_bin = (4 - (length_bin & 3)) & 3
length_bin += zeros_bin
length = 12 + 8 + length_gtlf
length = 12 + 8 + length_gltf
if length_bin > 0:
length += 8 + length_bin
@ -77,9 +100,9 @@ def save_gltf(glTF, export_settings, encoder, glb_buffer):
file.write(struct.pack("I", length))
# Chunk 0 (JSON)
file.write(struct.pack("I", length_gtlf))
file.write(struct.pack("I", length_gltf))
file.write('JSON'.encode())
file.write(glTF_data)
file.write(gltf_data)
for i in range(0, spaces_gltf):
file.write(' '.encode())