expre-gen/blender/3.4/scripts/addons/io_scene_fbx/json2fbx.py
2025-10-17 09:47:23 +08:00

159 lines
3.3 KiB
Python

#!/usr/bin/env python3
# SPDX-License-Identifier: GPL-2.0-or-later
# Script copyright (C) 2014 Blender Foundation
"""
Usage
=====
json2fbx [FILES]...
This script will write a binary FBX file for each JSON argument given.
Input
======
The JSON data is formatted into a list of nested lists of 4 items:
``[id, [data, ...], "data_types", [subtree, ...]]``
Where each list may be empty, and the items in
the subtree are formatted the same way.
data_types is a string, aligned with data that spesifies a type
for each property.
The types are as follows:
* 'Y': - INT16
* 'C': - BOOL
* 'I': - INT32
* 'F': - FLOAT32
* 'D': - FLOAT64
* 'L': - INT64
* 'R': - BYTES
* 'S': - STRING
* 'f': - FLOAT32_ARRAY
* 'i': - INT32_ARRAY
* 'd': - FLOAT64_ARRAY
* 'l': - INT64_ARRAY
* 'b': - BOOL ARRAY
* 'c': - BYTE ARRAY
Note that key:value pairs aren't used since the id's are not
ensured to be unique.
"""
def elem_empty(elem, name):
import encode_bin
sub_elem = encode_bin.FBXElem(name)
if elem is not None:
elem.elems.append(sub_elem)
return sub_elem
def parse_json_rec(fbx_root, json_node):
name, data, data_types, children = json_node
ver = 0
assert(len(data_types) == len(data))
e = elem_empty(fbx_root, name.encode())
for d, dt in zip(data, data_types):
if dt == "C":
e.add_bool(d)
elif dt == "Y":
e.add_int16(d)
elif dt == "I":
e.add_int32(d)
elif dt == "L":
e.add_int64(d)
elif dt == "F":
e.add_float32(d)
elif dt == "D":
e.add_float64(d)
elif dt == "R":
d = eval('b"""' + d + '"""')
e.add_bytes(d)
elif dt == "S":
d = d.encode().replace(b"::", b"\x00\x01")
e.add_string(d)
elif dt == "i":
e.add_int32_array(d)
elif dt == "l":
e.add_int64_array(d)
elif dt == "f":
e.add_float32_array(d)
elif dt == "d":
e.add_float64_array(d)
elif dt == "b":
e.add_bool_array(d)
elif dt == "c":
e.add_byte_array(d)
if name == "FBXVersion":
assert(data_types == "I")
ver = int(data[0])
for child in children:
_ver = parse_json_rec(e, child)
if _ver:
ver = _ver
return ver
def parse_json(json_root):
root = elem_empty(None, b"")
ver = 0
for n in json_root:
_ver = parse_json_rec(root, n)
if _ver:
ver = _ver
return root, ver
def json2fbx(fn):
import os
import json
import encode_bin
fn_fbx = "%s.fbx" % os.path.splitext(fn)[0]
print("Writing: %r " % fn_fbx, end="")
json_root = []
with open(fn) as f_json:
json_root = json.load(f_json)
fbx_root, fbx_version = parse_json(json_root)
print("(Version %d) ..." % fbx_version)
encode_bin.write(fn_fbx, fbx_root, fbx_version)
# ----------------------------------------------------------------------------
# Command Line
def main():
import sys
if "--help" in sys.argv:
print(__doc__)
return
for arg in sys.argv[1:]:
try:
json2fbx(arg)
except:
print("Failed to convert %r, error:" % arg)
import traceback
traceback.print_exc()
if __name__ == "__main__":
main()