From 7872b6e51f87d7bb8eff9f34d6632bd2293e6bb7 Mon Sep 17 00:00:00 2001 From: Thomas Barlow Date: Sun, 18 Jun 2023 15:40:44 +0100 Subject: [PATCH 1/3] FBX IO: Add support for armature data custom properties Armature data custom properties are now imported from and exported to the NodeAttribute connected to the Armature's Node. A fix is made to a feature of Empty Objects, that allows changing the exported FBX type of the NodeAttribute with a specific custom property value, to prevent it from also affecting Armatures. This implements part of #104677. --- io_scene_fbx/export_fbx_bin.py | 18 ++++++++++++++---- io_scene_fbx/import_fbx.py | 5 +++++ 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/io_scene_fbx/export_fbx_bin.py b/io_scene_fbx/export_fbx_bin.py index 2b2a393f5..62f0cd41e 100644 --- a/io_scene_fbx/export_fbx_bin.py +++ b/io_scene_fbx/export_fbx_bin.py @@ -552,14 +552,21 @@ def fbx_data_element_custom_properties(props, bid): def fbx_data_empty_elements(root, empty, scene_data): """ - Write the Empty data block (you can control its FBX datatype with the 'fbx_type' string custom property). + Write the Empty data block (you can control its FBX datatype with the 'fbx_type' string custom property) or Armature + NodeAttribute. """ empty_key = scene_data.data_empties[empty] null = elem_data_single_int64(root, b"NodeAttribute", get_fbx_uuid_from_key(empty_key)) null.add_string(fbx_name_class(empty.name.encode(), b"NodeAttribute")) - val = empty.bdata.get('fbx_type', None) - null.add_string(val.encode() if val and isinstance(val, str) else b"Null") + bdata = empty.bdata + is_armature = bdata.type == 'ARMATURE' + if is_armature: + fbx_type = b"Null" + else: + val = bdata.get('fbx_type', None) + fbx_type = val.encode() if val and isinstance(val, str) else b"Null" + null.add_string(fbx_type) elem_data_single_string(null, b"TypeFlags", b"Null") @@ -567,7 +574,10 @@ def fbx_data_empty_elements(root, empty, scene_data): props = elem_properties(null) elem_props_template_finalize(tmpl, props) - # No custom properties, already saved with object (Model). + # Empty/Armature Object custom properties have already been saved with the Model. + # Only Armature data custom properties need to be saved here with the NodeAttribute. + if is_armature: + fbx_data_element_custom_properties(props, bdata.data) def fbx_data_light_elements(root, lamp, scene_data): diff --git a/io_scene_fbx/import_fbx.py b/io_scene_fbx/import_fbx.py index 39ecc68a7..6196e19c8 100644 --- a/io_scene_fbx/import_fbx.py +++ b/io_scene_fbx/import_fbx.py @@ -2826,8 +2826,13 @@ class FbxImportHelperNode: elem_find_first(fbx_tmpl, b'Properties70', fbx_elem_nil)) if settings.use_custom_props: + # Read Armature Object custom props from the Node blen_read_custom_properties(self.fbx_elem, arm, settings) + if self.fbx_data_elem: + # Read Armature Data custom props from the NodeAttribute + blen_read_custom_properties(self.fbx_data_elem, arm_data, settings) + # instance in scene view_layer.active_layer_collection.collection.objects.link(arm) arm.select_set(True) -- 2.30.2 From e5362d9a3e922380f1433a54791c2feafb1f27a5 Mon Sep 17 00:00:00 2001 From: Thomas Barlow Date: Fri, 15 Sep 2023 00:41:29 +0100 Subject: [PATCH 2/3] Remove fix for armature NodeAttribute export type control so it can be PR-ed separately --- io_scene_fbx/export_fbx_bin.py | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/io_scene_fbx/export_fbx_bin.py b/io_scene_fbx/export_fbx_bin.py index 62f0cd41e..8da45fc45 100644 --- a/io_scene_fbx/export_fbx_bin.py +++ b/io_scene_fbx/export_fbx_bin.py @@ -560,13 +560,8 @@ def fbx_data_empty_elements(root, empty, scene_data): null = elem_data_single_int64(root, b"NodeAttribute", get_fbx_uuid_from_key(empty_key)) null.add_string(fbx_name_class(empty.name.encode(), b"NodeAttribute")) bdata = empty.bdata - is_armature = bdata.type == 'ARMATURE' - if is_armature: - fbx_type = b"Null" - else: - val = bdata.get('fbx_type', None) - fbx_type = val.encode() if val and isinstance(val, str) else b"Null" - null.add_string(fbx_type) + val = bdata.get('fbx_type', None) + null.add_string(val.encode() if val and isinstance(val, str) else b"Null") elem_data_single_string(null, b"TypeFlags", b"Null") @@ -576,7 +571,7 @@ def fbx_data_empty_elements(root, empty, scene_data): # Empty/Armature Object custom properties have already been saved with the Model. # Only Armature data custom properties need to be saved here with the NodeAttribute. - if is_armature: + if bdata.type == 'ARMATURE': fbx_data_element_custom_properties(props, bdata.data) -- 2.30.2 From 9369f897e86e5953555487c28b91002ea9dc989f Mon Sep 17 00:00:00 2001 From: Thomas Barlow Date: Tue, 19 Sep 2023 00:48:14 +0100 Subject: [PATCH 3/3] Increase FBX IO minor version --- io_scene_fbx/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/io_scene_fbx/__init__.py b/io_scene_fbx/__init__.py index 5cc0aa5f4..9ac5187ab 100644 --- a/io_scene_fbx/__init__.py +++ b/io_scene_fbx/__init__.py @@ -5,7 +5,7 @@ bl_info = { "name": "FBX format", "author": "Campbell Barton, Bastien Montagne, Jens Restemeier, @Mysteryem", - "version": (5, 7, 6), + "version": (5, 8, 0), "blender": (3, 6, 0), "location": "File > Import-Export", "description": "FBX IO meshes, UVs, vertex colors, materials, textures, cameras, lamps and actions", -- 2.30.2