Textures are not exported
Reinstalled export gltf
https://github.com/KhronosGroup/glTF-Blender-Exporter
because of the error reinstalled on
https://github.com/KhronosGroup/glTF-Blender-IO
now textures are not displayed, please tell me why so


diff --git a/addons/io_scene_gltf2/blender/com/gltf2_blender_math.py b/addons/io_scene_gltf2/blender/com/gltf2_blender_math.py
index 306bf7ea..b397581b 100644
--- a/addons/io_scene_gltf2/blender/com/gltf2_blender_math.py
+++ b/addons/io_scene_gltf2/blender/com/gltf2_blender_math.py
@@ -32,7 +32,11 @@ def list_to_mathutils(values: typing.List[float], data_path: str) -> typing.Unio
     """Transform a list to blender py object."""
     target = get_target_property_name(data_path)
 
-    if target == 'location':
+    if target == 'delta_location':
+        return Vector(values)  # TODO Should be Vector(values) - Vector(something)?
+    elif target == 'delta_rotation_euler':
+        return Euler(values).to_quaternion()  # TODO Should be multiply(Euler(values).to_quaternion(), something)?
+    elif target == 'location':
         return Vector(values)
     elif target == 'rotation_axis_angle':
         angle = values[0]
@@ -78,6 +82,8 @@ def swizzle_yup(v: typing.Union[Vector, Quaternion], data_path: str) -> typing.U
     """Manage Yup."""
     target = get_target_property_name(data_path)
     swizzle_func = {
+        "delta_location": swizzle_yup_location,
+        "delta_rotation_euler": swizzle_yup_rotation,
         "location": swizzle_yup_location,
         "rotation_axis_angle": swizzle_yup_rotation,
         "rotation_euler": swizzle_yup_rotation,
@@ -117,6 +123,8 @@ def transform(v: typing.Union[Vector, Quaternion], data_path: str, transform: Ma
     """Manage transformations."""
     target = get_target_property_name(data_path)
     transform_func = {
+        "delta_location": transform_location,
+        "delta_rotation_euler": transform_rotation,
         "location": transform_location,
         "rotation_axis_angle": transform_rotation,
         "rotation_euler": transform_rotation,
@@ -159,3 +167,8 @@ def transform_scale(scale: Vector, transform: Matrix = Matrix.Identity(4)) -> Ve
 def transform_value(value: Vector, _: Matrix = Matrix.Identity(4)) -> Vector:
     """Transform value."""
     return value
+
+
+def round_if_near(value: float, target: float) -> float:
+    """If value is very close to target, round to target."""
+    return value if abs(value - target) > 2.0e-6 else target
diff --git a/addons/io_scene_gltf2/blender/exp/gltf2_blender_extract.py b/addons/io_scene_gltf2/blender/exp/gltf2_blender_extract.py
index 09e00862..3c09cb36 100644
--- a/addons/io_scene_gltf2/blender/exp/gltf2_blender_extract.py
+++ b/addons/io_scene_gltf2/blender/exp/gltf2_blender_extract.py
@@ -648,7 +648,7 @@ def extract_primitives(glTF, blender_mesh, blender_vertex_groups, modifiers, exp
 
             bone_count = 0
 
-            if vertex.groups is not None and len(vertex.groups) > 0 and export_settings[gltf2_blender_export_keys.SKINS]:
+            if blender_vertex_groups is not None and vertex.groups is not None and len(vertex.groups) > 0 and export_settings[gltf2_blender_export_keys.SKINS]:
                 joint = []
                 weight = []
                 for group_element in vertex.groups:
@@ -668,13 +668,15 @@ def extract_primitives(glTF, blender_mesh, blender_vertex_groups, modifiers, exp
                     #
 
                     joint_index = 0
-                    modifiers_dict = {m.type: m for m in modifiers}
-                    if "ARMATURE" in modifiers_dict:
-                        armature = modifiers_dict["ARMATURE"].object
-                        skin = gltf2_blender_gather_skins.gather_skin(armature, export_settings)
-                        for index, j in enumerate(skin.joints):
-                            if j.name == vertex_group_name:
-                                joint_index = index
+
+                    if modifiers is not None:
+                        modifiers_dict = {m.type: m for m in modifiers}
+                        if "ARMATURE" in modifiers_dict:
+                            armature = modifiers_dict["ARMATURE"].object
+                            skin = gltf2_blender_gather_skins.gather_skin(armature, export_settings)
+                            for index, j in enumerate(skin.joints):
+                                if j.name == vertex_group_name:
+                                    joint_index = index
 
                     joint_weight = group_element.weight
 
diff --git a/addons/io_scene_gltf2/blender/exp/gltf2_blender_gather_animation_channel_target.py b/addons/io_scene_gltf2/blender/exp/gltf2_blender_gather_animation_channel_target.py
index 9e33f07f..39365f60 100644
--- a/addons/io_scene_gltf2/blender/exp/gltf2_blender_gather_animation_channel_target.py
+++ b/addons/io_scene_gltf2/blender/exp/gltf2_blender_gather_animation_channel_target.py
@@ -67,6 +67,8 @@ def __gather_path(channels: typing.Tuple[bpy.types.FCurve],
                   ) -> str:
     target = channels[0].data_path.split('.')[-1]
     path = {
+        "delta_location": "translation",
+        "delta_rotation_euler": "rotation",
         "location": "translation",
         "rotation_axis_angle": "rotation",
         "rotation_euler": "rotation",
diff --git a/addons/io_scene_gltf2/blender/exp/gltf2_blender_gather_animation_sampler_keyframes.py b/addons/io_scene_gltf2/blender/exp/gltf2_blender_gather_animation_sampler_keyframes.py
index b06d4afa..82b1403d 100644
--- a/addons/io_scene_gltf2/blender/exp/gltf2_blender_gather_animation_sampler_keyframes.py
+++ b/addons/io_scene_gltf2/blender/exp/gltf2_blender_gather_animation_sampler_keyframes.py
@@ -35,6 +35,8 @@ class Keyframe:
 
     def __get_target_len(self):
         length = {
+            "delta_location": 3,
+            "delta_rotation_euler": 3,
             "location": 3,
             "rotation_axis_angle": 4,
             "rotation_euler": 3,
diff --git a/addons/io_scene_gltf2/blender/exp/gltf2_blender_gather_animation_samplers.py b/addons/io_scene_gltf2/blender/exp/gltf2_blender_gather_animation_samplers.py
index ab5a8d34..a327d8eb 100644
--- a/addons/io_scene_gltf2/blender/exp/gltf2_blender_gather_animation_samplers.py
+++ b/addons/io_scene_gltf2/blender/exp/gltf2_blender_gather_animation_samplers.py
@@ -107,37 +107,40 @@ def __gather_output(channels: typing.Tuple[bpy.types.FCurve],
 
     target_datapath = channels[0].data_path
 
-    transform = Matrix.Identity(4)
+    transform = blender_object.matrix_parent_inverse
+
+    isYup = export_settings[gltf2_blender_export_keys.YUP]
 
     if blender_object.type == "ARMATURE":
         bone = blender_object.path_resolve(get_target_object_path(target_datapath))
         if isinstance(bone, bpy.types.PoseBone):
-            transform = bone.bone.matrix_local
             if bone.parent is not None:
                 parent_transform = bone.parent.bone.matrix_local
-                transform = gltf2_blender_math.multiply(parent_transform.inverted(), transform)
-                # if not export_settings[gltf2_blender_export_keys.YUP]:
-                #     transform = gltf2_blender_math.multiply(gltf2_blender_math.to_zup(), transform)
+                transform = gltf2_blender_math.multiply(transform, parent_transform.inverted())
+                # if not isYup:
+                #     transform = gltf2_blender_math.multiply(transform, gltf2_blender_math.to_zup())
             else:
                 # only apply the y-up conversion to root bones, as child bones already are in the y-up space
-                if export_settings[gltf2_blender_export_keys.YUP]:
-                    transform = gltf2_blender_math.multiply(gltf2_blender_math.to_yup(), transform)
+                if isYup:
+                    transform = gltf2_blender_math.multiply(transform, gltf2_blender_math.to_yup())
+            local_transform = bone.bone.matrix_local
+            transform = gltf2_blender_math.multiply(transform, local_transform)
 
     values = []
     for keyframe in keyframes:
         # Transform the data and extract
         value = gltf2_blender_math.transform(keyframe.value, target_datapath, transform)
-        if export_settings[gltf2_blender_export_keys.YUP] and not blender_object.type == "ARMATURE":
+        if isYup and not blender_object.type == "ARMATURE":
             value = gltf2_blender_math.swizzle_yup(value, target_datapath)
         keyframe_value = gltf2_blender_math.mathutils_to_gltf(value)
         if keyframe.in_tangent is not None:
             in_tangent = gltf2_blender_math.transform(keyframe.in_tangent, target_datapath, transform)
-            if export_settings[gltf2_blender_export_keys.YUP] and not blender_object.type == "ARMATURE":
+            if isYup and not blender_object.type == "ARMATURE":
                 in_tangent = gltf2_blender_math.swizzle_yup(in_tangent, target_datapath)
             keyframe_value = gltf2_blender_math.mathutils_to_gltf(in_tangent) + keyframe_value
         if keyframe.out_tangent is not None:
             out_tangent = gltf2_blender_math.transform(keyframe.out_tangent, target_datapath, transform)
-            if export_settings[gltf2_blender_export_keys.YUP] and not blender_object.type == "ARMATURE":
+            if isYup and not blender_object.type == "ARMATURE":
                 out_tangent = gltf2_blender_math.swizzle_yup(out_tangent, target_datapath)
             keyframe_value = keyframe_value + gltf2_blender_math.mathutils_to_gltf(out_tangent)
         values += keyframe_value
diff --git a/addons/io_scene_gltf2/blender/exp/gltf2_blender_gather_animations.py b/addons/io_scene_gltf2/blender/exp/gltf2_blender_gather_animations.py
index e0d4131a..63b13393 100644
--- a/addons/io_scene_gltf2/blender/exp/gltf2_blender_gather_animations.py
+++ b/addons/io_scene_gltf2/blender/exp/gltf2_blender_gather_animations.py
@@ -156,7 +156,7 @@ def __get_blender_actions(blender_object: bpy.types.Object
             for strip in track.strips:
                 blender_actions.append(strip.action)
 
-    if blender_object.type == "MESH"\\
+    if blender_object.type == "MESH" \\
             and blender_object.data is not None \\
             and blender_object.data.shape_keys is not None \\
             and blender_object.data.shape_keys.animation_data is not None:
diff --git a/addons/io_scene_gltf2/blender/exp/gltf2_blender_gather_materials.py b/addons/io_scene_gltf2/blender/exp/gltf2_blender_gather_materials.py
index a602992e..4e38ed18 100644
--- a/addons/io_scene_gltf2/blender/exp/gltf2_blender_gather_materials.py
+++ b/addons/io_scene_gltf2/blender/exp/gltf2_blender_gather_materials.py
@@ -41,7 +41,7 @@ def gather_material(blender_material, export_settings):
         alpha_cutoff=__gather_alpha_cutoff(blender_material, export_settings),
         alpha_mode=__gather_alpha_mode(blender_material, export_settings),
         double_sided=__gather_double_sided(blender_material, export_settings),
-        emissive_factor=__gather_emmissive_factor(blender_material, export_settings),
+        emissive_factor=__gather_emissive_factor(blender_material, export_settings),
         emissive_texture=__gather_emissive_texture(blender_material, export_settings),
         extensions=__gather_extensions(blender_material, export_settings),
         extras=__gather_extras(blender_material, export_settings),
@@ -100,8 +100,10 @@ def __gather_double_sided(blender_material, export_settings):
     return None
 
 
-def __gather_emmissive_factor(blender_material, export_settings):
+def __gather_emissive_factor(blender_material, export_settings):
     emissive_socket = gltf2_blender_get.get_socket_or_texture_slot(blender_material, "Emissive")
+    if emissive_socket is None:
+        emissive_socket = gltf2_blender_get.get_socket_or_texture_slot_old(blender_material, "EmissiveFactor")
     if isinstance(emissive_socket, bpy.types.NodeSocket) and not emissive_socket.is_linked:
         return list(emissive_socket.default_value)[0:3]
     return None
@@ -109,6 +111,8 @@ def __gather_emmissive_factor(blender_material, export_settings):
 
 def __gather_emissive_texture(blender_material, export_settings):
     emissive = gltf2_blender_get.get_socket_or_texture_slot(blender_material, "Emissive")
+    if emissive is None:
+        emissive = gltf2_blender_get.get_socket_or_texture_slot_old(blender_material, "Emissive")
     return gltf2_blender_gather_texture_info.gather_texture_info((emissive,), export_settings)
 
 
@@ -136,15 +140,19 @@ def __gather_name(blender_material, export_settings):
 
 def __gather_normal_texture(blender_material, export_settings):
     normal = gltf2_blender_get.get_socket_or_texture_slot(blender_material, "Normal")
+    if normal is None:
+        normal = gltf2_blender_get.get_socket_or_texture_slot_old(blender_material, "Normal")
     return gltf2_blender_gather_material_normal_texture_info_class.gather_material_normal_texture_info_class(
         (normal,),
         export_settings)
 
 
 def __gather_occlusion_texture(blender_material, export_settings):
-    emissive = gltf2_blender_get.get_socket_or_texture_slot(blender_material, "Occlusion")
+    occlusion = gltf2_blender_get.get_socket_or_texture_slot(blender_material, "Occlusion")
+    if occlusion is None:
+        occlusion = gltf2_blender_get.get_socket_or_texture_slot_old(blender_material, "Occlusion")
     return gltf2_blender_gather_material_occlusion_texture_info_class.gather_material_occlusion_texture_info_class(
-        (emissive,),
+        (occlusion,),
         export_settings)
 
 
diff --git a/addons/io_scene_gltf2/blender/exp/gltf2_blender_gather_materials_pbr_metallic_roughness.py b/addons/io_scene_gltf2/blender/exp/gltf2_blender_gather_materials_pbr_metallic_roughness.py
index f48cbdf8..9960c879 100644
--- a/addons/io_scene_gltf2/blender/exp/gltf2_blender_gather_materials_pbr_metallic_roughness.py
+++ b/addons/io_scene_gltf2/blender/exp/gltf2_blender_gather_materials_pbr_metallic_roughness.py
@@ -46,6 +46,8 @@ def __gather_base_color_factor(blender_material, export_settings):
     base_color_socket = gltf2_blender_get.get_socket_or_texture_slot(blender_material, "Base Color")
     if base_color_socket is None:
         base_color_socket = gltf2_blender_get.get_socket_or_texture_slot(blender_material, "BaseColor")
+    if base_color_socket is None:
+        base_color_socket = gltf2_blender_get.get_socket_or_texture_slot_old(blender_material, "BaseColorFactor")
     if isinstance(base_color_socket, bpy.types.NodeSocket) and not base_color_socket.is_linked:
         return list(base_color_socket.default_value)
     return None
@@ -54,6 +56,8 @@ def __gather_base_color_texture(blender_material, export_settings):
     base_color_socket = gltf2_blender_get.get_socket_or_texture_slot(blender_material, "Base Color")
     if base_color_socket is None:
         base_color_socket = gltf2_blender_get.get_socket_or_texture_slot(blender_material, "BaseColor")
+    if base_color_socket is None:
+        base_color_socket = gltf2_blender_get.get_socket_or_texture_slot_old(blender_material, "BaseColor")
     return gltf2_blender_gather_texture_info.gather_texture_info((base_color_socket,), export_settings)
 
 
@@ -67,6 +71,8 @@ def __gather_extras(blender_material, export_settings):
 
 def __gather_metallic_factor(blender_material, export_settings):
     metallic_socket = gltf2_blender_get.get_socket_or_texture_slot(blender_material, "Metallic")
+    if metallic_socket is None:
+        metallic_socket = gltf2_blender_get.get_socket_or_texture_slot_old(blender_material, "MetallicFactor")
     if isinstance(metallic_socket, bpy.types.NodeSocket) and not metallic_socket.is_linked:
         return metallic_socket.default_value
     return None
@@ -78,6 +84,8 @@ def __gather_metallic_roughness_texture(blender_material, export_settings):
 
     if metallic_socket is None and roughness_socket is None:
         metallic_roughness = gltf2_blender_get.get_socket_or_texture_slot(blender_material, "MetallicRoughness")
+        if metallic_roughness is None:
+            metallic_roughness = gltf2_blender_get.get_socket_or_texture_slot_old(blender_material, "MetallicRoughness")
         texture_input = (metallic_roughness,)
     else:
         texture_input = (metallic_socket, roughness_socket)
@@ -87,6 +95,8 @@ def __gather_metallic_roughness_texture(blender_material, export_settings):
 
 def __gather_roughness_factor(blender_material, export_settings):
     roughness_socket = gltf2_blender_get.get_socket_or_texture_slot(blender_material, "Roughness")
+    if roughness_socket is None:
+        roughness_socket = gltf2_blender_get.get_socket_or_texture_slot_old(blender_material, "RoughnessFactor")
     if isinstance(roughness_socket, bpy.types.NodeSocket) and not roughness_socket.is_linked:
         return roughness_socket.default_value
     return None
diff --git a/addons/io_scene_gltf2/blender/exp/gltf2_blender_gather_nodes.py b/addons/io_scene_gltf2/blender/exp/gltf2_blender_gather_nodes.py
index cf52163b..26c285e2 100644
--- a/addons/io_scene_gltf2/blender/exp/gltf2_blender_gather_nodes.py
+++ b/addons/io_scene_gltf2/blender/exp/gltf2_blender_gather_nodes.py
@@ -17,6 +17,7 @@ import bpy
 from mathutils import Quaternion
 
 from . import gltf2_blender_export_keys
+from io_scene_gltf2.blender.com import gltf2_blender_math
 from io_scene_gltf2.blender.exp.gltf2_blender_gather_cache import cached
 from io_scene_gltf2.blender.exp import gltf2_blender_gather_skins
 from io_scene_gltf2.blender.exp import gltf2_blender_gather_cameras
@@ -50,16 +51,17 @@ def gather_node(blender_object, export_settings):
     )
     node.translation, node.rotation, node.scale = __gather_trans_rot_scale(blender_object, export_settings)
 
-    if blender_object.type == 'LIGHT' and export_settings[gltf2_blender_export_keys.LIGHTS]:
-        correction_node = __get_correction_node(blender_object, export_settings)
-        correction_node.extensions = {"KHR_lights_punctual": node.extensions["KHR_lights_punctual"]}
-        del node.extensions["KHR_lights_punctual"]
-        node.children.append(correction_node)
-    if blender_object.type == 'CAMERA' and export_settings[gltf2_blender_export_keys.CAMERAS]:
-        correction_node = __get_correction_node(blender_object, export_settings)
-        correction_node.camera = node.camera
-        node.children.append(correction_node)
-    node.camera = None
+    if export_settings[gltf2_blender_export_keys.YUP]:
+        if blender_object.type == 'LIGHT' and export_settings[gltf2_blender_export_keys.LIGHTS]:
+            correction_node = __get_correction_node(blender_object, export_settings)
+            correction_node.extensions = {"KHR_lights_punctual": node.extensions["KHR_lights_punctual"]}
+            del node.extensions["KHR_lights_punctual"]
+            node.children.append(correction_node)
+        if blender_object.type == 'CAMERA' and export_settings[gltf2_blender_export_keys.CAMERAS]:
+            correction_node = __get_correction_node(blender_object, export_settings)
+            correction_node.camera = node.camera
+            node.children.append(correction_node)
+        node.camera = None
 
     return node
 
@@ -168,8 +170,21 @@ def __gather_mesh(blender_object, export_settings):
         modifiers = None
 
     if export_settings[gltf2_blender_export_keys.APPLY]:
-        blender_mesh = blender_object.to_mesh(bpy.context.depsgraph, True)
+        auto_smooth = blender_object.data.use_auto_smooth
+        if auto_smooth:
+            blender_object = blender_object.copy()
+            edge_split = blender_object.modifiers.new('Temporary_Auto_Smooth', 'EDGE_SPLIT')
+            edge_split.split_angle = blender_object.data.auto_smooth_angle
+            edge_split.use_edge_angle = not blender_object.data.has_custom_normals
+
+        if bpy.app.version < (2, 80, 0):
+            blender_mesh = blender_object.to_mesh(bpy.context.scene, True, 'PREVIEW')
+        else:
+            blender_mesh = blender_object.to_mesh(bpy.context.depsgraph, True)
         skip_filter = True
+
+        if auto_smooth:
+            bpy.data.objects.remove(blender_object)
     else:
         blender_mesh = blender_object.data
         skip_filter = False
@@ -203,6 +218,12 @@ def __gather_trans_rot_scale(blender_object, export_settings):
             trans = -gltf2_blender_extract.convert_swizzle_location(
                 blender_object.instance_collection.instance_offset, export_settings)
     translation, rotation, scale = (None, None, None)
+    trans[0], trans[1], trans[2] = gltf2_blender_math.round_if_near(trans[0], 0.0), gltf2_blender_math.round_if_near(trans[1], 0.0), \\
+                                   gltf2_blender_math.round_if_near(trans[2], 0.0)
+    rot[0], rot[1], rot[2], rot[3] = gltf2_blender_math.round_if_near(rot[0], 0.0), gltf2_blender_math.round_if_near(rot[1], 0.0), \\
+                                     gltf2_blender_math.round_if_near(rot[2], 0.0), gltf2_blender_math.round_if_near(rot[3], 1.0)
+    sca[0], sca[1], sca[2] = gltf2_blender_math.round_if_near(sca[0], 1.0), gltf2_blender_math.round_if_near(sca[1], 1.0), \\
+                             gltf2_blender_math.round_if_near(sca[2], 1.0)
     if trans[0] != 0.0 or trans[1] != 0.0 or trans[2] != 0.0:
         translation = [trans[0], trans[1], trans[2]]
     if rot[0] != 0.0 or rot[1] != 0.0 or rot[2] != 0.0 or rot[3] != 1.0:
diff --git a/addons/io_scene_gltf2/blender/exp/gltf2_blender_get.py b/addons/io_scene_gltf2/blender/exp/gltf2_blender_get.py
index 0b96483b..6c54ff21 100644
--- a/addons/io_scene_gltf2/blender/exp/gltf2_blender_get.py
+++ b/addons/io_scene_gltf2/blender/exp/gltf2_blender_get.py
@@ -43,18 +43,17 @@ def get_socket_or_texture_slot(blender_material: bpy.types.Material, name: str):
     :return: either a blender NodeSocket, if the material is a node tree or a blender Texture otherwise
     """
     if blender_material.node_tree and blender_material.use_nodes:
-        i = [input for input in blender_material.node_tree.inputs]
-        o = [output for output in blender_material.node_tree.outputs]
-        nodes = [node for node in blender_material.node_tree.nodes]
+        #i = [input for input in blender_material.node_tree.inputs]
+        #o = [output for output in blender_material.node_tree.outputs]
         if name == "Emissive":
-            nodes = filter(lambda n: isinstance(n, bpy.types.ShaderNodeEmission), nodes)
+            type = bpy.types.ShaderNodeEmission
             name = "Color"
         else:
-            nodes = filter(lambda n: isinstance(n, bpy.types.ShaderNodeBsdfPrincipled), nodes)
+            type = bpy.types.ShaderNodeBsdfPrincipled
+        nodes = [n for n in blender_material.node_tree.nodes if isinstance(n, type)]
         inputs = sum([[input for input in node.inputs if input.name == name] for node in nodes], [])
-        if not inputs:
-            return None
-        return inputs[0]
+        if inputs:
+            return inputs[0]
     elif bpy.app.version < (2, 80, 0):  # blender 2.8 removed texture_slots
         if name != 'Base Color':
             return None
@@ -72,9 +71,26 @@ def get_socket_or_texture_slot(blender_material: bpy.types.Material, name: str):
                 if blender_texture_slot.use_map_color_diffuse:
                     return blender_texture_slot
 
-        return None
-    else:
-        return None
+    return None
+
+
+def get_socket_or_texture_slot_old(blender_material: bpy.types.Material, name: str):
+    """
+    For a given material input name, retrieve the corresponding node tree socket in the special glTF Metallic Roughness nodes (which might be deprecated?).
+
+    :param blender_material: a blender material for which to get the socket/slot
+    :param name: the name of the socket/slot
+    :return: either a blender NodeSocket, if the material is a node tree or a blender Texture otherwise
+    """
+    if blender_material.node_tree and blender_material.use_nodes:
+        nodes = [n for n in blender_material.node_tree.nodes if \\
+            isinstance(n, bpy.types.ShaderNodeGroup) and \\
+            n.node_tree.name.startswith('glTF Metallic Roughness')]
+        inputs = sum([[input for input in node.inputs if input.name == name] for node in nodes], [])
+        if inputs:
+            return inputs[0]
+
+    return None
 
 
 def find_shader_image_from_shader_socket(shader_socket, max_hops=10):
['addons/io_scene_gltf2/blender/exp/gltf2_blender_gather_animation_samplers.py', 'addons/io_scene_gltf2/blender/com/gltf2_blender_math.py', 'addons/io_scene_gltf2/blender/exp/gltf2_blender_gather_nodes.py', 'addons/io_scene_gltf2/blender/exp/gltf2_blender_extract.py', 'addons/io_scene_gltf2/blender/exp/gltf2_blender_get.py', 'addons/io_scene_gltf2/blender/exp/gltf2_blender_gather_materials.py', 'addons/io_scene_gltf2/blender/exp/gltf2_blender_gather_animation_sampler_keyframes.py', 'addons/io_scene_gltf2/blender/exp/gltf2_blender_gather_animation_channel_target.py', 'addons/io_scene_gltf2/blender/exp/gltf2_blender_gather_animations.py', 'addons/io_scene_gltf2/blender/exp/gltf2_blender_gather_materials_pbr_metallic_roughness.py']