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
|
# SPDX-License-Identifier: Apache-2.0
# Copyright 2018-2021 The glTF-Blender-IO authors.
#
# Imports
#
import json
import struct
#
# Globals
#
#
# Functions
#
from collections import OrderedDict
def save_gltf(gltf, export_settings, encoder, glb_buffer):
indent = None
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 = (',', ' : ')
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("\n")
file.close()
binary = export_settings['gltf_binary']
if len(binary) > 0 and not export_settings['gltf_embed_buffers']:
file = open(export_settings['gltf_filedirectory'] + export_settings['gltf_binaryfilename'], "wb")
file.write(binary)
file.close()
else:
file = open(export_settings['gltf_filepath'], "wb")
gltf_data = gltf_encoded.encode()
binary = glb_buffer
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_gltf
if length_bin > 0:
length += 8 + length_bin
# Header (Version 2)
file.write('glTF'.encode())
file.write(struct.pack("I", 2))
file.write(struct.pack("I", length))
# Chunk 0 (JSON)
file.write(struct.pack("I", length_gltf))
file.write('JSON'.encode())
file.write(gltf_data)
file.write(b' ' * spaces_gltf)
# Chunk 1 (BIN)
if length_bin > 0:
file.write(struct.pack("I", length_bin))
file.write('BIN\0'.encode())
file.write(binary)
file.write(b'\0' * zeros_bin)
file.close()
return True
|