add_camera_rigs: refactor and cleanup
[blender-addons.git] / io_scene_fbx / json2fbx.py
blob579b45a79414e48338e91e94e7a77da7e02491da
1 #!/usr/bin/env python3
2 # ##### BEGIN GPL LICENSE BLOCK #####
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software Foundation,
16 # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 # ##### END GPL LICENSE BLOCK #####
20 # <pep8 compliant>
22 # Script copyright (C) 2014 Blender Foundation
24 """
25 Usage
26 =====
28 json2fbx [FILES]...
30 This script will write a binary FBX file for each JSON argument given.
33 Input
34 ======
36 The JSON data is formatted into a list of nested lists of 4 items:
38 ``[id, [data, ...], "data_types", [subtree, ...]]``
40 Where each list may be empty, and the items in
41 the subtree are formatted the same way.
43 data_types is a string, aligned with data that spesifies a type
44 for each property.
46 The types are as follows:
48 * 'Y': - INT16
49 * 'C': - BOOL
50 * 'I': - INT32
51 * 'F': - FLOAT32
52 * 'D': - FLOAT64
53 * 'L': - INT64
54 * 'R': - BYTES
55 * 'S': - STRING
56 * 'f': - FLOAT32_ARRAY
57 * 'i': - INT32_ARRAY
58 * 'd': - FLOAT64_ARRAY
59 * 'l': - INT64_ARRAY
60 * 'b': - BOOL ARRAY
61 * 'c': - BYTE ARRAY
63 Note that key:value pairs aren't used since the id's are not
64 ensured to be unique.
65 """
68 def elem_empty(elem, name):
69 import encode_bin
70 sub_elem = encode_bin.FBXElem(name)
71 if elem is not None:
72 elem.elems.append(sub_elem)
73 return sub_elem
76 def parse_json_rec(fbx_root, json_node):
77 name, data, data_types, children = json_node
78 ver = 0
80 assert(len(data_types) == len(data))
82 e = elem_empty(fbx_root, name.encode())
83 for d, dt in zip(data, data_types):
84 if dt == "C":
85 e.add_bool(d)
86 elif dt == "Y":
87 e.add_int16(d)
88 elif dt == "I":
89 e.add_int32(d)
90 elif dt == "L":
91 e.add_int64(d)
92 elif dt == "F":
93 e.add_float32(d)
94 elif dt == "D":
95 e.add_float64(d)
96 elif dt == "R":
97 d = eval('b"""' + d + '"""')
98 e.add_bytes(d)
99 elif dt == "S":
100 d = d.encode().replace(b"::", b"\x00\x01")
101 e.add_string(d)
102 elif dt == "i":
103 e.add_int32_array(d)
104 elif dt == "l":
105 e.add_int64_array(d)
106 elif dt == "f":
107 e.add_float32_array(d)
108 elif dt == "d":
109 e.add_float64_array(d)
110 elif dt == "b":
111 e.add_bool_array(d)
112 elif dt == "c":
113 e.add_byte_array(d)
115 if name == "FBXVersion":
116 assert(data_types == "I")
117 ver = int(data[0])
119 for child in children:
120 _ver = parse_json_rec(e, child)
121 if _ver:
122 ver = _ver
124 return ver
127 def parse_json(json_root):
128 root = elem_empty(None, b"")
129 ver = 0
131 for n in json_root:
132 _ver = parse_json_rec(root, n)
133 if _ver:
134 ver = _ver
136 return root, ver
139 def json2fbx(fn):
140 import os
141 import json
143 import encode_bin
145 fn_fbx = "%s.fbx" % os.path.splitext(fn)[0]
146 print("Writing: %r " % fn_fbx, end="")
147 json_root = []
148 with open(fn) as f_json:
149 json_root = json.load(f_json)
150 fbx_root, fbx_version = parse_json(json_root)
151 print("(Version %d) ..." % fbx_version)
152 encode_bin.write(fn_fbx, fbx_root, fbx_version)
155 # ----------------------------------------------------------------------------
156 # Command Line
158 def main():
159 import sys
161 if "--help" in sys.argv:
162 print(__doc__)
163 return
165 for arg in sys.argv[1:]:
166 try:
167 json2fbx(arg)
168 except:
169 print("Failed to convert %r, error:" % arg)
171 import traceback
172 traceback.print_exc()
175 if __name__ == "__main__":
176 main()