Page MenuHome

FBX import does not read custom bone properties
Confirmed, NormalPublicTO DO

Description

System Information
Operating system: Windows 10
Graphics card: Nvidia 1070 (8gb)

Blender Version
Broken: latest
Worked: Never?

Short description of error
Custom properties on the armature transform export and import fine, but on the bones they are ignored. I spoke with Bastien in blender.chat and he mentioned that this is a TODO that may have fallen through the cracks.

Exact steps for others to reproduce the error
Attempt to export this simple armature (attached), deform bones only, with custom properties. Import it back to see that the properties are not maintained.

Event Timeline

Bastien Montagne (mont29) renamed this task from FBX import / export do not read or write custom bone properties to FBX import does not read custom bone properties .Sep 23 2019, 8:49 PM
Bastien Montagne (mont29) removed Bastien Montagne (mont29) as the assignee of this task.
Bastien Montagne (mont29) lowered the priority of this task from 90 to Normal.
Bastien Montagne (mont29) edited a custom field.

Bone props are exported, but importer currently ignores them, yes. Added the task to T68575: FBX Known issues & TODO's, thanks.

Hi again,

Bone props are not exported, and I think I know why: it's exporting them from the bone and not the PoseBone. As any custom properties used in rigging would be on the PoseBone, it makes it look like nothing is flowing through.

I don't know what use exporting the actual bone properties is; in multiple years of production I haven't see anyone put data in that particular spot.

I ran a test by editing export_fbx_bin.py. I changed line 1517 from:

if scene_data.settings.use_custom_props:
    fbx_data_element_custom_properties(props, bo)

to:

if scene_data.settings.use_custom_props:
    fbx_data_element_custom_properties(props, bo_obj.armature.bdata.pose.bones[bo.name])
)

And low and behold, the props are now exported. However, they're not exported in a place that other apps look for them, near as I can see.

I ran a reference export from Maya and I notice that the "custom" parameters are shoved in with the regular parameters under the node, while the Blender exporter puts them in a Properties70 underneath a NodeAttribute node. I think between the above code change and a slight reorganization of where this data is stored, the bug could be put to bed.

I also noticed that even when the posebone properties are used, the exporter does not look at the min and max values, which is important if they are present in the _RNA_UI.

Attached is a file comparing the reference FBX from Maya (left) and the one I exported from Blender (right), along with that test file.

Lemme attach a reference Maya export too, while I'm at it.

Thanks, will fix that exporting issue, it's rather trivial.

Hi there,

The fix you committed in rBAcb4e5b248c8a only fixed half the problem. The other half is the props are being exported in the wrong node, as I indicated in the above image. So, the data is getting written now, but the place where it is being written means that other applications don't pick it up.

Is there a reason why those parameters are being stuck into the extra NodeAttribute chunks that do not appear when exporting from Maya?

Did you actually checked my commit? Now we export EDIT bone props in the attribute node (as expected), and POSE bone props in the model (aka 'object') node, that’s what was missing previously. Would not see any reason to write editbone props in the model, that would be only confusing… and would make separation between edit and pose ones impossible.

HI Bastien,

I did check your commit, but I'm not sure my image above was understood. Half of the problem was that the data was not getting exported, which it is now thanks to your patch. The other half of the problem is that the FBX file getting exported is malformed.

Please check the image I attached above.

The main issue is now that where the properties are landing in the FBX file is not recognized by other applications, regardless of how they're defined in Blender. The custom pose bone properties need to be showing up in the same property block as all the rest of the regular bone properties, as shown above.

I'm using a slightly modified version of this repo to introspect files:
https://github.com/nem0/OpenFBX

which is how I generated the above image and also am looking to see that data is actually getting exported.

The above file, two_bone_params_2014.fbx, should be used as a reference as it comes from Maya.

If you need any further examples of correct files, please let me know and I can send you anything you like from any version of Maya 2017-2019.

You are not addressing my points… again, new code in the FBX exporter puts pose props in the model FBX node, which afaik is the expected behavior…

If I export the example .blend above (F7718563), I get:

["Objects", [], "", [
    ["NodeAttribute", [134216079, "Armature::NodeAttribute", "Null"], "LSS", [
        ["TypeFlags", ["Null"], "S", []],
        ["Properties70", [], "", [
            ["P", ["Color", "ColorRGB", "Color", "", 0.8, 0.8, 0.8], "SSSSDDD", []],
            ["P", ["Size", "double", "Number", "", 100.0], "SSSSD", []],
            ["P", ["Look", "enum", "", "", 1], "SSSSI", []]]]]],
    ["Model", [527288446, "Armature::Model", "Null"], "LSS", [
        ["Version", [232], "I", []],
        ["Properties70", [], "", [
            ["P", ["Lcl Rotation", "Lcl Rotation", "", "A", -90.00000250447816, 0.0, 0.0], "SSSSDDD", []],
            ["P", ["Lcl Scaling", "Lcl Scaling", "", "A", 100.0, 100.0, 100.0], "SSSSDDD", []],
            ["P", ["DefaultAttributeIndex", "int", "Integer", "", 0], "SSSSI", []],
            ["P", ["InheritType", "enum", "", "", 1], "SSSSI", []],
            ["P", ["atoms_rabbits", "int", "Integer", "U", 1], "SSSSI", []]]],
        ["MultiLayer", [0], "I", []],
        ["MultiTake", [0], "I", []],
        ["Shading", [true], "C", []],
        ["Culling", ["CullingOff"], "S", []]]],
    ["Model", [800197842, "root::Model", "LimbNode"], "LSS", [
        ["Version", [232], "I", []],
        ["Properties70", [], "", [
            ["P", ["Lcl Rotation", "Lcl Rotation", "", "A", 90.00000250447816, -0.0, 0.0], "SSSSDDD", []],
            ["P", ["DefaultAttributeIndex", "int", "Integer", "", 0], "SSSSI", []],
            ["P", ["InheritType", "enum", "", "", 1], "SSSSI", []],
            ["P", ["atoms_rootX", "int", "Integer", "U", 15], "SSSSI", []],
            ["P", ["atoms_name", "KString", "", "U", "bunny"], "SSSSS", []],
            ["P", ["atoms_direction", "Vector", "", "U", 4.0, 5.0, 6.0], "SSSSDDD", []]]],
        ["MultiLayer", [0], "I", []],
        ["MultiTake", [0], "I", []],
        ["Shading", [true], "C", []],
        ["Culling", ["CullingOff"], "S", []]]],
    ["Model", [317641670, "bone.L::Model", "LimbNode"], "LSS", [
        ["Version", [232], "I", []],
        ["Properties70", [], "", [
            ["P", ["Lcl Translation", "Lcl Translation", "", "A", 0.08174820244312286, 0.7119274139404297, -0.9106079936027527], "SSSSDDD", []],
            ["P", ["DefaultAttributeIndex", "int", "Integer", "", 0], "SSSSI", []],
            ["P", ["InheritType", "enum", "", "", 1], "SSSSI", []],
            ["P", ["atoms_position", "Vector", "", "U", 0.08174820244312286, 0.9106079936027527, 0.7119274139404297], "SSSSDDD", []]]],
        ["MultiLayer", [0], "I", []],
        ["MultiTake", [0], "I", []],
        ["Shading", [true], "C", []],
        ["Culling", ["CullingOff"], "S", []]]],
    ["Model", [217646028, "bone.R::Model", "LimbNode"], "LSS", [
        ["Version", [232], "I", []],
        ["Properties70", [], "", [
            ["P", ["Lcl Translation", "Lcl Translation", "", "A", -0.5032442212104797, 0.6660205721855164, 0.755639374256134], "SSSSDDD", []],
            ["P", ["DefaultAttributeIndex", "int", "Integer", "", 0], "SSSSI", []],
            ["P", ["InheritType", "enum", "", "", 1], "SSSSI", []],
            ["P", ["atoms_position", "Vector", "", "U", -0.5032442212104797, -0.755639374256134, 0.6660205721855164], "SSSSDDD", []]]],
        ["MultiLayer", [0], "I", []],
        ["MultiTake", [0], "I", []],
        ["Shading", [true], "C", []],
        ["Culling", ["CullingOff"], "S", []]]],
    ["Model", [23984158, "center::Model", "LimbNode"], "LSS", [
        ["Version", [232], "I", []],
        ["Properties70", [], "", [
            ["P", ["Lcl Translation", "Lcl Translation", "", "A", -0.32658660411834717, 1.9007091522216797, -0.22112268209457397], "SSSSDDD", []],
            ["P", ["DefaultAttributeIndex", "int", "Integer", "", 0], "SSSSI", []],
            ["P", ["InheritType", "enum", "", "", 1], "SSSSI", []],
            ["P", ["atoms_position", "Vector", "", "U", -0.32658660411834717, 0.22112268209457397, 1.9007091522216797], "SSSSDDD", []]]],
        ["MultiLayer", [0], "I", []],
        ["MultiTake", [0], "I", []],
        ["Shading", [true], "C", []],
        ["Culling", ["CullingOff"], "S", []]]],
    ["NodeAttribute", [858517680, "root::NodeAttribute", "LimbNode"], "LSS", [
        ["TypeFlags", ["Skeleton"], "S", []],
        ["Properties70", [], "", [
            ["P", ["Size", "double", "Number", "", 3.300000049173832], "SSSSD", []]]]]],
    ["NodeAttribute", [889009370, "bone.L::NodeAttribute", "LimbNode"], "LSS", [
        ["TypeFlags", ["Skeleton"], "S", []],
        ["Properties70", [], "", [
            ["P", ["Size", "double", "Number", "", 3.300000786781311], "SSSSD", []]]]]],
    ["NodeAttribute", [752467253, "bone.R::NodeAttribute", "LimbNode"], "LSS", [
        ["TypeFlags", ["Skeleton"], "S", []],
        ["Properties70", [], "", [
            ["P", ["Size", "double", "Number", "", 3.3000020161271095], "SSSSD", []]]]]],
    ["NodeAttribute", [863475931, "center::NodeAttribute", "LimbNode"], "LSS", [
        ["TypeFlags", ["Skeleton"], "S", []],
        ["Properties70", [], "", [
            ["P", ["Size", "double", "Number", "", 3.3000020161271095], "SSSSD", []]]]]],
    ["NodeAttribute", [489810650, "bone.L_end::NodeAttribute", "LimbNode"], "LSS", [
        ["TypeFlags", ["Skeleton"], "S", []],
        ["Properties70", [], "", [
            ["P", ["Size", "double", "Number", "", 330.0000786781311], "SSSSD", []]]]]],
    ["Model", [771529387, "bone.L_end::Model", "LimbNode"], "LSS", [
        ["Version", [232], "I", []],
        ["Properties70", [], "", [
            ["P", ["Lcl Translation", "Lcl Translation", "", "A", 0.0, 1.0, 0.0], "SSSSDDD", []],
            ["P", ["DefaultAttributeIndex", "int", "Integer", "", 0], "SSSSI", []],
            ["P", ["InheritType", "enum", "", "", 1], "SSSSI", []]]],
        ["MultiLayer", [0], "I", []],
        ["MultiTake", [0], "I", []],
        ["Shading", [true], "C", []],
        ["Culling", ["CullingOff"], "S", []]]],
    ["NodeAttribute", [258117085, "bone.R_end::NodeAttribute", "LimbNode"], "LSS", [
        ["TypeFlags", ["Skeleton"], "S", []],
        ["Properties70", [], "", [
            ["P", ["Size", "double", "Number", "", 330.00020161271095], "SSSSD", []]]]]],
    ["Model", [818407871, "bone.R_end::Model", "LimbNode"], "LSS", [
        ["Version", [232], "I", []],
        ["Properties70", [], "", [
            ["P", ["Lcl Translation", "Lcl Translation", "", "A", 0.0, 1.0, 0.0], "SSSSDDD", []],
            ["P", ["DefaultAttributeIndex", "int", "Integer", "", 0], "SSSSI", []],
            ["P", ["InheritType", "enum", "", "", 1], "SSSSI", []]]],
        ["MultiLayer", [0], "I", []],
        ["MultiTake", [0], "I", []],
        ["Shading", [true], "C", []],
        ["Culling", ["CullingOff"], "S", []]]],
    ["NodeAttribute", [785742408, "center_end::NodeAttribute", "LimbNode"], "LSS", [
        ["TypeFlags", ["Skeleton"], "S", []],
        ["Properties70", [], "", [
            ["P", ["Size", "double", "Number", "", 330.00020161271095], "SSSSD", []]]]]],
    ["Model", [573886366, "center_end::Model", "LimbNode"], "LSS", [
        ["Version", [232], "I", []],
        ["Properties70", [], "", [
            ["P", ["Lcl Translation", "Lcl Translation", "", "A", 0.0, 1.0, 0.0], "SSSSDDD", []],
            ["P", ["DefaultAttributeIndex", "int", "Integer", "", 0], "SSSSI", []],
            ["P", ["InheritType", "enum", "", "", 1], "SSSSI", []]]],
        ["MultiLayer", [0], "I", []],
        ["MultiTake", [0], "I", []],
        ["Shading", [true], "C", []],
        ["Culling", ["CullingOff"], "S", []]]]]],

As you can see, all the atoms Pose custom props are in the Model FBX nodes…

Only Edit bones custom props would now be put in the NodeAttribute FBX nodes (don't want to mix those with the Pose custom props on one hand, and on the other, afaik Edit bone custom props are not very commonly used…).

Ahh interesting. I think that I might not have had it installed correctly-- a clean build today and I'm seeing the attributes in the correct place! My apologies. But Maya is still not picking them up. [captain picard facepalm gif]

Something else I noticed: the tagging for the parameters is slightly different. At first I thought it is because the props I was exporting aren't integers, but I exported integers from Maya and they do come up differently. Attached are two more images. Could it be that the A+U tag (whatever that means) is what's causing Maya to not recognize the parameters properly?

I'm also attaching one more example file from Maya, a single joint with the six main property types on it, for reference.

Afaik, A tag means 'animated', and U means 'user-defined data' (this is just assumptions from older FBX I analyzed during main development phase of the add-on, think there are no official info about those anywhere)…

But yeah, maybe customprops all need that mysterious A+U set of tags, FBX has never ever been known for its consistency, so… Will try adding those and we'll see. Thanks for the investigation work, btw! ;)

Hey, thank you for listening and helping out!

auto-parsing of commits in 2.81 branches is still not fully working it seems… Changed those 'flags' in rBA2476c0b4b2789e65f1ef95989d4e42dfd784be45 (and merged it in master), so this should be testable in next daily build.

Just pulled and rebuilt-- the properties are getting through!

Now that this is working in Maya I hope some folks chime in who might want to use it in another package (I hear some people use properties like these to send data into Unity).

Animation on the custom properties is not coming through yet.

As mentioned in the first part of this report the custom properties are not getting read back in if I import the FBX file I just exported. But this is awesome progress!