Fix FBX char type being interpreted as bool #104914
@ -5,7 +5,7 @@
|
|||||||
bl_info = {
|
bl_info = {
|
||||||
"name": "FBX format",
|
"name": "FBX format",
|
||||||
"author": "Campbell Barton, Bastien Montagne, Jens Restemeier, @Mysteryem",
|
"author": "Campbell Barton, Bastien Montagne, Jens Restemeier, @Mysteryem",
|
||||||
"version": (5, 8, 1),
|
"version": (5, 8, 2),
|
||||||
"blender": (3, 6, 0),
|
"blender": (3, 6, 0),
|
||||||
"location": "File > Import-Export",
|
"location": "File > Import-Export",
|
||||||
"description": "FBX IO meshes, UVs, vertex colors, materials, textures, cameras, lamps and actions",
|
"description": "FBX IO meshes, UVs, vertex colors, materials, textures, cameras, lamps and actions",
|
||||||
|
@ -3,7 +3,8 @@
|
|||||||
#
|
#
|
||||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
BOOL = b'C'[0]
|
BOOL = b'B'[0]
|
||||||
|
CHAR = b'C'[0]
|
||||||
INT8 = b'Z'[0]
|
INT8 = b'Z'[0]
|
||||||
INT16 = b'Y'[0]
|
INT16 = b'Y'[0]
|
||||||
INT32 = b'I'[0]
|
INT32 = b'I'[0]
|
||||||
|
@ -56,6 +56,14 @@ class FBXElem:
|
|||||||
self.props_type.append(data_types.BOOL)
|
self.props_type.append(data_types.BOOL)
|
||||||
self.props.append(data)
|
self.props.append(data)
|
||||||
|
|
||||||
|
def add_char(self, data):
|
||||||
|
assert(isinstance(data, bytes))
|
||||||
|
assert(len(data) == 1)
|
||||||
|
data = pack('<c', data)
|
||||||
|
|
||||||
|
self.props_type.append(data_types.CHAR)
|
||||||
|
self.props.append(data)
|
||||||
|
|
||||||
def add_int8(self, data):
|
def add_int8(self, data):
|
||||||
assert(isinstance(data, int))
|
assert(isinstance(data, int))
|
||||||
data = pack('<b', data)
|
data = pack('<b', data)
|
||||||
|
@ -66,7 +66,7 @@ from .fbx_utils import (
|
|||||||
get_blender_nodetexture_key,
|
get_blender_nodetexture_key,
|
||||||
# FBX element data.
|
# FBX element data.
|
||||||
elem_empty,
|
elem_empty,
|
||||||
elem_data_single_bool, elem_data_single_int16, elem_data_single_int32, elem_data_single_int64,
|
elem_data_single_char, elem_data_single_int16, elem_data_single_int32, elem_data_single_int64,
|
||||||
elem_data_single_float32, elem_data_single_float64,
|
elem_data_single_float32, elem_data_single_float64,
|
||||||
elem_data_single_bytes, elem_data_single_string, elem_data_single_string_unicode,
|
elem_data_single_bytes, elem_data_single_string, elem_data_single_string_unicode,
|
||||||
elem_data_single_bool_array, elem_data_single_int32_array, elem_data_single_int64_array,
|
elem_data_single_bool_array, elem_data_single_int32_array, elem_data_single_int64_array,
|
||||||
@ -1900,7 +1900,8 @@ def fbx_data_leaf_bone_elements(root, scene_data):
|
|||||||
# object type, etc.
|
# object type, etc.
|
||||||
elem_data_single_int32(model, b"MultiLayer", 0)
|
elem_data_single_int32(model, b"MultiLayer", 0)
|
||||||
elem_data_single_int32(model, b"MultiTake", 0)
|
elem_data_single_int32(model, b"MultiTake", 0)
|
||||||
elem_data_single_bool(model, b"Shading", True)
|
# Probably the FbxNode.EShadingMode enum. Full description in fbx_data_object_elements.
|
||||||
|
elem_data_single_char(model, b"Shading", b"\x01")
|
||||||
elem_data_single_string(model, b"Culling", b"CullingOff")
|
elem_data_single_string(model, b"Culling", b"CullingOff")
|
||||||
|
|
||||||
elem_props_template_finalize(tmpl, props)
|
elem_props_template_finalize(tmpl, props)
|
||||||
@ -1964,7 +1965,12 @@ def fbx_data_object_elements(root, ob_obj, scene_data):
|
|||||||
# object type, etc.
|
# object type, etc.
|
||||||
elem_data_single_int32(model, b"MultiLayer", 0)
|
elem_data_single_int32(model, b"MultiLayer", 0)
|
||||||
elem_data_single_int32(model, b"MultiTake", 0)
|
elem_data_single_int32(model, b"MultiTake", 0)
|
||||||
elem_data_single_bool(model, b"Shading", True)
|
# This is probably the FbxNode.EShadingMode enum. Not directly used by the FBX SDK, but the SDK guarantees that the
|
||||||
|
# value will be passed through from an imported file to an exported one. Common values are 'Y' and 'T'. 'U' and 'W'
|
||||||
|
# have also been seen in older FBX files. It's not clear which enum member each of these values corresponds to or if
|
||||||
|
# these values are actually application specific. Blender had been exporting this as a `True` bool for a long time
|
||||||
|
# seemingly without issue. The '\x01' char is the same value as `True` in raw bytes.
|
||||||
|
elem_data_single_char(model, b"Shading", b"\x01")
|
||||||
elem_data_single_string(model, b"Culling", b"CullingOff")
|
elem_data_single_string(model, b"Culling", b"CullingOff")
|
||||||
|
|
||||||
if obj_type == b"Camera":
|
if obj_type == b"Camera":
|
||||||
|
@ -30,7 +30,8 @@ The types are as follows:
|
|||||||
|
|
||||||
* 'Z': - INT8
|
* 'Z': - INT8
|
||||||
* 'Y': - INT16
|
* 'Y': - INT16
|
||||||
* 'C': - BOOL
|
* 'B': - BOOL
|
||||||
|
* 'C': - CHAR
|
||||||
* 'I': - INT32
|
* 'I': - INT32
|
||||||
* 'F': - FLOAT32
|
* 'F': - FLOAT32
|
||||||
* 'D': - FLOAT64
|
* 'D': - FLOAT64
|
||||||
@ -109,7 +110,8 @@ def unpack_array(read, array_type, array_stride, array_byteswap):
|
|||||||
read_data_dict = {
|
read_data_dict = {
|
||||||
b'Z'[0]: lambda read: unpack(b'<b', read(1))[0], # 8 bit int
|
b'Z'[0]: lambda read: unpack(b'<b', read(1))[0], # 8 bit int
|
||||||
b'Y'[0]: lambda read: unpack(b'<h', read(2))[0], # 16 bit int
|
b'Y'[0]: lambda read: unpack(b'<h', read(2))[0], # 16 bit int
|
||||||
b'C'[0]: lambda read: unpack(b'?', read(1))[0], # 1 bit bool (yes/no)
|
b'B'[0]: lambda read: unpack(b'?', read(1))[0], # 1 bit bool (yes/no)
|
||||||
|
b'C'[0]: lambda read: unpack(b'<c', read(1))[0], # char
|
||||||
b'I'[0]: lambda read: unpack(b'<i', read(4))[0], # 32 bit int
|
b'I'[0]: lambda read: unpack(b'<i', read(4))[0], # 32 bit int
|
||||||
b'F'[0]: lambda read: unpack(b'<f', read(4))[0], # 32 bit float
|
b'F'[0]: lambda read: unpack(b'<f', read(4))[0], # 32 bit float
|
||||||
b'D'[0]: lambda read: unpack(b'<d', read(8))[0], # 64 bit float
|
b'D'[0]: lambda read: unpack(b'<d', read(8))[0], # 64 bit float
|
||||||
@ -225,7 +227,8 @@ data_types.__dict__.update(
|
|||||||
dict(
|
dict(
|
||||||
INT8 = b'Z'[0],
|
INT8 = b'Z'[0],
|
||||||
INT16 = b'Y'[0],
|
INT16 = b'Y'[0],
|
||||||
BOOL = b'C'[0],
|
BOOL = b'B'[0],
|
||||||
|
CHAR = b'C'[0],
|
||||||
INT32 = b'I'[0],
|
INT32 = b'I'[0],
|
||||||
FLOAT32 = b'F'[0],
|
FLOAT32 = b'F'[0],
|
||||||
FLOAT64 = b'D'[0],
|
FLOAT64 = b'D'[0],
|
||||||
|
@ -969,6 +969,10 @@ def elem_data_single_bool(elem, name, value):
|
|||||||
return _elem_data_single(elem, name, value, "add_bool")
|
return _elem_data_single(elem, name, value, "add_bool")
|
||||||
|
|
||||||
|
|
||||||
|
def elem_data_single_char(elem, name, value):
|
||||||
|
return _elem_data_single(elem, name, value, "add_char")
|
||||||
|
|
||||||
|
|
||||||
def elem_data_single_int8(elem, name, value):
|
def elem_data_single_int8(elem, name, value):
|
||||||
return _elem_data_single(elem, name, value, "add_int8")
|
return _elem_data_single(elem, name, value, "add_int8")
|
||||||
|
|
||||||
|
@ -29,7 +29,8 @@ The types are as follows:
|
|||||||
|
|
||||||
* 'Z': - INT8
|
* 'Z': - INT8
|
||||||
* 'Y': - INT16
|
* 'Y': - INT16
|
||||||
* 'C': - BOOL
|
* 'B': - BOOL
|
||||||
|
* 'C': - CHAR
|
||||||
* 'I': - INT32
|
* 'I': - INT32
|
||||||
* 'F': - FLOAT32
|
* 'F': - FLOAT32
|
||||||
* 'D': - FLOAT64
|
* 'D': - FLOAT64
|
||||||
@ -64,8 +65,11 @@ def parse_json_rec(fbx_root, json_node):
|
|||||||
|
|
||||||
e = elem_empty(fbx_root, name.encode())
|
e = elem_empty(fbx_root, name.encode())
|
||||||
for d, dt in zip(data, data_types):
|
for d, dt in zip(data, data_types):
|
||||||
if dt == "C":
|
if dt == "B":
|
||||||
e.add_bool(d)
|
e.add_bool(d)
|
||||||
|
elif dt == "C":
|
||||||
|
d = eval('b"""' + d + '"""')
|
||||||
|
e.add_char(d)
|
||||||
elif dt == "Z":
|
elif dt == "Z":
|
||||||
e.add_int8(d)
|
e.add_int8(d)
|
||||||
elif dt == "Y":
|
elif dt == "Y":
|
||||||
|
@ -80,7 +80,8 @@ def unpack_array(read, array_type, array_stride, array_byteswap):
|
|||||||
read_data_dict = {
|
read_data_dict = {
|
||||||
b'Z'[0]: lambda read: unpack(b'<b', read(1))[0], # byte
|
b'Z'[0]: lambda read: unpack(b'<b', read(1))[0], # byte
|
||||||
b'Y'[0]: lambda read: unpack(b'<h', read(2))[0], # 16 bit int
|
b'Y'[0]: lambda read: unpack(b'<h', read(2))[0], # 16 bit int
|
||||||
b'C'[0]: lambda read: unpack(b'?', read(1))[0], # 1 bit bool (yes/no)
|
b'B'[0]: lambda read: unpack(b'?', read(1))[0], # 1 bit bool (yes/no)
|
||||||
|
b'C'[0]: lambda read: unpack(b'<c', read(1))[0], # char
|
||||||
b'I'[0]: lambda read: unpack(b'<i', read(4))[0], # 32 bit int
|
b'I'[0]: lambda read: unpack(b'<i', read(4))[0], # 32 bit int
|
||||||
b'F'[0]: lambda read: unpack(b'<f', read(4))[0], # 32 bit float
|
b'F'[0]: lambda read: unpack(b'<f', read(4))[0], # 32 bit float
|
||||||
b'D'[0]: lambda read: unpack(b'<d', read(8))[0], # 64 bit float
|
b'D'[0]: lambda read: unpack(b'<d', read(8))[0], # 64 bit float
|
||||||
|
Loading…
Reference in New Issue
Block a user