-
Notifications
You must be signed in to change notification settings - Fork 28
/
Copy pathpackglb.py
executable file
·110 lines (94 loc) · 3.37 KB
/
packglb.py
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
107
108
109
110
#!/usr/bin/env python3
#------------------------------------
# packglb.py: GLB to I3DM/B3DM converter
# (c) 2018 - 2021 Geopipe, Inc.
# All rights reserved. See LICENSE.
#------------------------------------
import sys, os
import argparse
import base64
import json
import re
import struct
import b3dm, i3dm
def main():
""" Pack GLB into another container, with optional additional I3DM or B3DM encoding"""
# Parse options and get results
parser = argparse.ArgumentParser(description='Converts GLTF to GLB')
parser.add_argument("-i", "--i3dm", type=str, \
help="Export i3dm, with required path to input JSON instance table data. Supports only embedded GLTFs")
parser.add_argument("-b", "--b3dm", type=str, \
help="Export b3dm, with optional path to input JSON batch table data")
parser.add_argument("--objectwise", action='store_true', \
help="If b3dm is specified and this is set, assume list of dicts. Defaults otherwise to dict of lists")
parser.add_argument("-o", "--output", required=False, default=None, \
help="Optional output path (defaults to the path of the input file")
parser.add_argument("-u", "--unpack", action='store_true', \
help="Unpack rather than create b3dm file")
parser.add_argument("filename")
args = parser.parse_args()
if args.unpack and args.filename:
if args.b3dm:
b3dm_decoder = b3dm.B3DM()
with open(args.filename, 'rb') as f:
data = f.read()
b3dm_decoder.readBinary(data)
with open(args.filename + '.glb', 'wb') as f:
output_data = b3dm_decoder.getGLTFBin()
f.write(output_data)
elif args.i3dm:
i3dm_decoder = i3dm.I3DM()
with open(args.filename, 'rb') as f:
data = f.read()
i3dm_decoder.readBinary(data)
with open(args.filename + '.glb', 'wb') as f:
output_data = i3dm_decoder.getGLTFBin()
f.write(output_data)
else:
raise ValueError('Must specify -b (--b3dm) or -i (--i3dm) to unpack')
sys.exit(0)
# Make sure the input file is *.glb
if not args.filename.endswith('.glb'):
print("Failed to create packed binary GLB file: input is not *.glb")
sys.exit(-1)
with open(args.filename, 'rb') as f:
glb = f.read()
if args.b3dm != None:
ext = 'b3dm'
elif args.i3dm != None:
ext = 'i3dm'
else:
ext = 'glb'
fname_out = os.path.splitext(os.path.basename(args.filename))[0] + '.' + ext
if None != args.output:
if "" == os.path.basename(args.output):
fname_out = os.path.join(fname_out, fname_out)
else:
fname_out = args.output
else:
fname_out = os.path.join(os.path.dirname(args.filename), fname_out)
if args.b3dm != None:
b3dm_encoder = b3dm.B3DM()
if len(args.b3dm):
with open(args.b3dm, 'r') as f:
b3dm_json = json.loads(f.read())
#print b3dm_json
b3dm_encoder.loadJSONBatch(b3dm_json, args.objectwise)
with open(fname_out, 'wb') as f:
f.write(b3dm_encoder.writeBinary(glb))
elif args.i3dm != None:
i3dm_encoder = i3dm.I3DM()
if not(len(args.i3dm)):
raise ValueError("-i/--i3dm requires a JSON instance table")
else:
with open(args.i3dm, 'r') as f:
i3dm_json = json.loads(f.read())
i3dm_encoder.loadJSONInstances(i3dm_json, False)
with open(fname_out, 'wb') as f:
f.write(i3dm_encoder.writeBinary(glb, True)) # Second arg: embed gltf
else:
# This is kinda pointless
with open(fname_out, 'wb') as f:
f.write(glb)
if __name__ == "__main__":
main()