KhronosGroup / glTF-Blender-IO

Blender glTF 2.0 importer and exporter
https://docs.blender.org/manual/en/latest/addons/import_export/scene_gltf2.html
Apache License 2.0
1.5k stars 320 forks source link

Exporter fails when exporting an armature with one or more non-deforming root bones with "Export Deformation Bones Only" and "Remove Armature Object" options enabled #2394

Open samcook5343 opened 3 weeks ago

samcook5343 commented 3 weeks ago

Describe the bug When exporting a scene containing an armature with one or more non-deforming root bones with both the "Export Deformation Bones Only" and "Remove Armature Object" options enabled, the exporter raises the following error:

Python: Traceback (most recent call last):
  File "/snap/blender/5438/4.2/scripts/addons_core/io_scene_gltf2/__init__.py", line 1289, in execute
    res = gltf2_blender_export.save(context, export_settings)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/snap/blender/5438/4.2/scripts/addons_core/io_scene_gltf2/blender/exp/gltf2_blender_export.py", line 37, in save
    json, buffer = __export(export_settings)
                   ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/snap/blender/5438/4.2/scripts/addons_core/io_scene_gltf2/blender/exp/gltf2_blender_export.py", line 55, in __export
    __gather_gltf(exporter, export_settings)
  File "/snap/blender/5438/4.2/scripts/addons_core/io_scene_gltf2/blender/exp/gltf2_blender_export.py", line 202, in __gather_gltf
    active_scene_idx, scenes, animations = gltf2_blender_gather.gather_gltf2(export_settings)
                                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/snap/blender/5438/4.2/scripts/addons_core/io_scene_gltf2/blender/exp/gltf2_blender_gather.py", line 31, in gather_gltf2
    scenes.append(__gather_scene(blender_scene, export_settings))
                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/snap/blender/5438/4.2/scripts/addons_core/io_scene_gltf2/blender/exp/gltf2_blender_gather_cache.py", line 37, in wrapper_cached
    result = func(*args, **kwargs)
             ^^^^^^^^^^^^^^^^^^^^^
  File "/snap/blender/5438/4.2/scripts/addons_core/io_scene_gltf2/blender/exp/gltf2_blender_gather.py", line 94, in __gather_scene
    node = gltf2_blender_gather_nodes.gather_node(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/snap/blender/5438/4.2/scripts/addons_core/io_scene_gltf2/blender/exp/gltf2_blender_gather_nodes.py", line 48, in gather_node
    children=__gather_children(vnode, export_settings),
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/snap/blender/5438/4.2/scripts/addons_core/io_scene_gltf2/blender/exp/gltf2_blender_gather_nodes.py", line 130, in __gather_children
    joint = gltf2_blender_gather_joints.gather_joint_vnode(bone_uuid, export_settings)
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/snap/blender/5438/4.2/scripts/addons_core/io_scene_gltf2/blender/exp/gltf2_blender_gather_cache.py", line 37, in wrapper_cached
    result = func(*args, **kwargs)
             ^^^^^^^^^^^^^^^^^^^^^
  File "/snap/blender/5438/4.2/scripts/addons_core/io_scene_gltf2/blender/exp/gltf2_blender_gather_joints.py", line 52, in gather_joint_vnode
    blender_bone = vtree.nodes[vnode].blender_bone
                   ~~~~~~~~~~~^^^^^^^
KeyError: 'cdfb2ad9-b573-4109-8c2b-f91abed960dd'

To Reproduce Steps to reproduce the behavior:

  1. Open the attached example.blend
  2. Go to the glTF exporter (File > Export > glTF 2.0 (.glb/.gltf))
  3. Enable both the "Export Deformation Bones Only" and "Remove Armature Object" options under Data > Armature in the exporter properties
  4. Attempt to export the file

Expected behavior The export should not fail and, if removing the non-deforming bones from the armature yields an armature with a single root bone, the Armature object should not be present in the exported glTF file.

.blend file/ .gltf (mandatory) example.zip

Version

julienduroure commented 3 weeks ago

Confirmed

julienduroure commented 3 weeks ago

Root cause: Check if we can remove the armature object use some functions that bakes bone lists. This check is done before the filter of non deformation bone. So when we want to get this list, as it's cached, we get the list with non deformation bones, so try to access a bone that is filtered

Additional bug when we want to export only DEF bones : the check is done on all bugs, not only deformation bones, if we want to get only def bones. So having at root a DEF and a nonDEF bone => Check will failed and said we can't remove armature