glTF exporter: vertex group check enhancement + glTF file fixed order
This commit is contained in:
parent
d09dbb28ec
commit
208eb40d55
|
@ -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)
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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())
|
||||
|
||||
|
|
Loading…
Reference in New Issue