Fix FBX char type being interpreted as bool #104914
@ -3,7 +3,8 @@
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
BOOL = b'C'[0]
|
||||
BOOL = b'B'[0]
|
||||
CHAR = b'C'[0]
|
||||
INT8 = b'Z'[0]
|
||||
INT16 = b'Y'[0]
|
||||
INT32 = b'I'[0]
|
||||
|
@ -56,6 +56,14 @@ class FBXElem:
|
||||
self.props_type.append(data_types.BOOL)
|
||||
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):
|
||||
assert(isinstance(data, int))
|
||||
data = pack('<b', data)
|
||||
|
@ -66,7 +66,7 @@ from .fbx_utils import (
|
||||
get_blender_nodetexture_key,
|
||||
# FBX element data.
|
||||
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_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,
|
||||
@ -1900,7 +1900,8 @@ def fbx_data_leaf_bone_elements(root, scene_data):
|
||||
# object type, etc.
|
||||
elem_data_single_int32(model, b"MultiLayer", 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_props_template_finalize(tmpl, props)
|
||||
@ -1964,7 +1965,12 @@ def fbx_data_object_elements(root, ob_obj, scene_data):
|
||||
# object type, etc.
|
||||
elem_data_single_int32(model, b"MultiLayer", 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")
|
||||
|
||||
if obj_type == b"Camera":
|
||||
|
@ -30,7 +30,8 @@ The types are as follows:
|
||||
|
||||
* 'Z': - INT8
|
||||
* 'Y': - INT16
|
||||
* 'C': - BOOL
|
||||
* 'B': - BOOL
|
||||
* 'C': - CHAR
|
||||
* 'I': - INT32
|
||||
* 'F': - FLOAT32
|
||||
* 'D': - FLOAT64
|
||||
@ -109,7 +110,8 @@ def unpack_array(read, array_type, array_stride, array_byteswap):
|
||||
read_data_dict = {
|
||||
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'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'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
|
||||
@ -225,7 +227,8 @@ data_types.__dict__.update(
|
||||
dict(
|
||||
INT8 = b'Z'[0],
|
||||
INT16 = b'Y'[0],
|
||||
BOOL = b'C'[0],
|
||||
BOOL = b'B'[0],
|
||||
CHAR = b'C'[0],
|
||||
INT32 = b'I'[0],
|
||||
FLOAT32 = b'F'[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")
|
||||
|
||||
|
||||
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):
|
||||
return _elem_data_single(elem, name, value, "add_int8")
|
||||
|
||||
|
@ -29,7 +29,8 @@ The types are as follows:
|
||||
|
||||
* 'Z': - INT8
|
||||
* 'Y': - INT16
|
||||
* 'C': - BOOL
|
||||
* 'B': - BOOL
|
||||
* 'C': - CHAR
|
||||
* 'I': - INT32
|
||||
* 'F': - FLOAT32
|
||||
* 'D': - FLOAT64
|
||||
@ -64,8 +65,11 @@ def parse_json_rec(fbx_root, json_node):
|
||||
|
||||
e = elem_empty(fbx_root, name.encode())
|
||||
for d, dt in zip(data, data_types):
|
||||
if dt == "C":
|
||||
if dt == "B":
|
||||
e.add_bool(d)
|
||||
elif dt == "C":
|
||||
d = eval('b"""' + d + '"""')
|
||||
e.add_char(d)
|
||||
elif dt == "Z":
|
||||
e.add_int8(d)
|
||||
elif dt == "Y":
|
||||
|
@ -80,7 +80,8 @@ def unpack_array(read, array_type, array_stride, array_byteswap):
|
||||
read_data_dict = {
|
||||
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'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'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
|
||||
|
Loading…
Reference in New Issue
Block a user