Page MenuHome

FBX Import crashes due to parentship circle (RecursionError)
Confirmed, NormalPublicBUG

Description

System Information
Operating system: Windows 10
Graphics card: NVIDIA GeForce GTX 1080 Ti

Blender Version
version: 2.81 (sub 16), branch: master, commit date: 2019-12-04 11:32, hash: f1aa4d18d49d, type: Release
build date: 2019-12-04, 14:30:40

Description of error

First of all, sorry for the long post. I thought it may help to quickly track down the issue when I attach some more information of what is going on. To the bug:
It seems like the some parent <-> child relationships get changed during import, which in my case results in an parentship circle and a crash due to recursion depth exceeded:

Traceback (most recent call last):
  File "F:\blender-2.81a-windows64\2.81\scripts\addons\io_scene_fbx\__init__.py", line 216, in execute
    if import_fbx.load(self, context, filepath=path, **keywords) == {'FINISHED'}:
  File "F:\blender-2.81a-windows64\2.81\scripts\addons\io_scene_fbx\import_fbx.py", line 2813, in load
    _(); del _
  File "F:\blender-2.81a-windows64\2.81\scripts\addons\io_scene_fbx\import_fbx.py", line 2801, in _
    root_helper.collect_armature_meshes()
  File "F:\blender-2.81a-windows64\2.81\scripts\addons\io_scene_fbx\import_fbx.py", line 1923, in collect_armature_meshes
    child.collect_armature_meshes()
  File "F:\blender-2.81a-windows64\2.81\scripts\addons\io_scene_fbx\import_fbx.py", line 1923, in collect_armature_meshes
    child.collect_armature_meshes()
  File "F:\blender-2.81a-windows64\2.81\scripts\addons\io_scene_fbx\import_fbx.py", line 1923, in collect_armature_meshes
    child.collect_armature_meshes()
  File "F:\blender-2.81a-windows64\2.81\scripts\addons\io_scene_fbx\import_fbx.py", line 1916, in collect_armature_meshes
    m.matrix = armature_matrix_inv @ m.get_world_matrix()
  File "F:\blender-2.81a-windows64\2.81\scripts\addons\io_scene_fbx\import_fbx.py", line 1860, in get_world_matrix
    matrix = self.parent.get_world_matrix_as_parent() if self.parent else Matrix()
  File "F:\blender-2.81a-windows64\2.81\scripts\addons\io_scene_fbx\import_fbx.py", line 1854, in get_world_matrix_as_parent
    matrix = self.parent.get_world_matrix_as_parent() if self.parent else Matrix()
  File "F:\blender-2.81a-windows64\2.81\scripts\addons\io_scene_fbx\import_fbx.py", line 1854, in get_world_matrix_as_parent
    matrix = self.parent.get_world_matrix_as_parent() if self.parent else Matrix()
  File "F:\blender-2.81a-windows64\2.81\scripts\addons\io_scene_fbx\import_fbx.py", line 1854, in get_world_matrix_as_parent
    matrix = self.parent.get_world_matrix_as_parent() if self.parent else Matrix()
  [Previous line repeated 989 more times]
RecursionError: maximum recursion depth exceeded

Jumped into io_scene_fbx/import.fbx and called the FbxImportHelperNode::PrintInfo method before collect_armature_meshes get's called.
This is the hierarchy it spits out (for the fbx attached):

Unknown[root][HBC]
 DummyRoot[HBC]
  rep_inf_ep3trooper[HBC]
   bone_root[armature][HBC]
    root_a_spine[armature][bone][HBC]
     bone_a_spine[bone][HBC]
      bone_b_spine[bone][HBC]
       bone_ribcage[bone][HBC]
        eff_ribcage[bone][HBC]
         root_l_clavicle[bone][HBC]
          bone_l_clavicle[bone][HBC]
           eff_l_clavicle[bone][HBC]
            root_l_upperarm[bone][HBC]
             bone_l_upperarm[bone][HBC]
              bone_l_forearm[bone][HBC]
               eff_l_forearm[bone][HBC]
                root_l_hand[bone][HBC]
                 bone_l_hand[bone][HBC]
                  eff_l_hand[bone]
         root_r_clavicle[bone][HBC]
          bone_r_clavicle[bone][HBC]
           eff_r_clavicle[bone][HBC]
            root_r_upperarm[bone][HBC]
             bone_r_upperarm[bone][HBC]
              bone_r_forearm[bone][HBC]
               eff_r_forearm[bone][HBC]
                root_r_hand[bone][HBC]
                 bone_r_hand[bone][HBC]
                  eff_r_hand[bone]
                  hp_weapons
         root_neck[bone][HBC]
          bone_neck[bone][HBC]
           bone_head[bone][HBC]
            eff_head[bone]
    bone_pelvis[bone][HBC]
     root_r_thigh[bone][HBC]
      bone_r_thigh[bone][HBC]
       bone_r_calf[bone][HBC]
        eff_r_calf[bone][HBC]
         root_r_foot[bone][HBC]
          bone_r_foot[bone][HBC]
           bone_r_toe[bone][HBC]
            eff_r_toe[bone]
     root_l_thigh[bone][HBC]
      bone_l_thigh[bone][HBC]
       bone_l_calf[bone][HBC]
        eff_l_calf[bone][HBC]
         root_l_foot[bone][HBC]
          bone_l_foot[bone][HBC]
           bone_l_toe[bone][HBC]
            eff_l_toe[bone]

This is the exact hierarchy as expected.
Since the error occoured in get_world_matrix_as_parent : 1857, I added two print instructions to see what the child <-> parent relationship at that point is:

def get_world_matrix_as_parent(self):
    # lets see what's going on here...
    print("self:     " + str(self))
    print("  parent: " + str(self.parent))

    matrix = self.parent.get_world_matrix_as_parent() if self.parent else Matrix()
    if self.matrix_as_parent:
        matrix = matrix @ self.matrix_as_parent
    return matrix

Turns out, at some point rep_inf_ep3trooper is no longer parented to DummyRoot, but root_a_spine (Log output):

self:     rep_inf_ep3trooper Model
  parent: DummyRoot Model
self:     DummyRoot Model
  parent: None
self:     None
  parent: None
self:     bone_root Model
  parent: rep_inf_ep3trooper Model
self:     rep_inf_ep3trooper Model
  parent: DummyRoot Model
self:     DummyRoot Model
  parent: None
self:     None
  parent: None
self:     DummyRoot Model
  parent: None
self:     None
  parent: None
self:     root_a_spine Model
  parent: bone_root Model
self:     bone_root Model
  parent: rep_inf_ep3trooper Model
self:     rep_inf_ep3trooper Model
  parent: root_a_spine Model
self:     root_a_spine Model
  parent: bone_root Model
self:     bone_root Model
  parent: rep_inf_ep3trooper Model
self:     rep_inf_ep3trooper Model
  parent: root_a_spine Model

Which of course results in a parentship circle.
Went back to the collect_armature_meshes method and removed the T70244 fix (maybe the fix introduced this?). Import was successfull, but no amature and no mesh imported...

Tried something else, commented out m.parent = self in import_fbx.py : 1919, everything imports (yay!), but my animations are broken.

for m in meshes:
    old_matrix = m.matrix
    m.matrix = armature_matrix_inv @ m.get_world_matrix()
    m.anim_compensation_matrix = old_matrix.inverted_safe() @ m.matrix
    m.is_global_animation = True
    #m.parent = self   # no no

So I don't know where to go from here. Thought I should share my results, so that some developer can fix this properly (better than simply commenting out a line that's probably there for a reason).
Respective FBX file is attached. Note that it works just fine in Maya, Autodesk FBX Review and Unity.

Exact steps for others to reproduce the error
Import the fbx file attached{F8338792}

Event Timeline

Ben (Ben1138) updated the task description. (Show Details)
Philipp Oeser (lichtwerk) changed the task status from Needs Triage to Confirmed.Fri, Feb 14, 1:53 PM
Philipp Oeser (lichtwerk) edited projects, added Add-ons; removed BF Blender.

could be related to T47344: Binary FBX (Version 7.3) with parented root bone does not import at all? (in that the root bone is itself parented? not sure though...)

Aaron Carlisle (Blendify) changed the subtype of this task from "Report" to "Bug".Mon, Feb 17, 8:50 PM