diff options
author | Julien Duroure <julien.duroure@gmail.com> | 2022-08-06 12:52:04 +0300 |
---|---|---|
committer | Julien Duroure <julien.duroure@gmail.com> | 2022-08-06 12:52:04 +0300 |
commit | 5b2953ad0883223bf8f58cf2bd650891f759bb65 (patch) | |
tree | 4d43e804c329454efad35c587fd898fa1638adbe | |
parent | c648829f83d66969cd6afb954630b8c4c6971f3f (diff) |
glTF exporter: performance: cache parent/children data to avoid bad .children performance when used a lot
Thanks rotoglup!
-rwxr-xr-x | io_scene_gltf2/__init__.py | 2 | ||||
-rw-r--r-- | io_scene_gltf2/blender/exp/gltf2_blender_gather_tree.py | 28 |
2 files changed, 19 insertions, 11 deletions
diff --git a/io_scene_gltf2/__init__.py b/io_scene_gltf2/__init__.py index 98210e82..65cfb759 100755 --- a/io_scene_gltf2/__init__.py +++ b/io_scene_gltf2/__init__.py @@ -4,7 +4,7 @@ bl_info = { 'name': 'glTF 2.0 format', 'author': 'Julien Duroure, Scurest, Norbert Nopper, Urs Hanselmann, Moritz Becher, Benjamin Schmithüsen, Jim Eckerlein, and many external contributors', - "version": (3, 3, 17), + "version": (3, 3, 18), 'blender': (3, 3, 0), 'location': 'File > Import-Export', 'description': 'Import-Export as glTF 2.0', diff --git a/io_scene_gltf2/blender/exp/gltf2_blender_gather_tree.py b/io_scene_gltf2/blender/exp/gltf2_blender_gather_tree.py index 36772667..c654b445 100644 --- a/io_scene_gltf2/blender/exp/gltf2_blender_gather_tree.py +++ b/io_scene_gltf2/blender/exp/gltf2_blender_gather_tree.py @@ -95,10 +95,18 @@ class VExportTree: bpy.context.window.scene = blender_scene depsgraph = bpy.context.evaluated_depsgraph_get() + # Gather parent/children information once, as calling bobj.children is + # very expensive operation : takes O(len(bpy.data.objects)) time. + blender_children = dict() + for bobj in bpy.data.objects: + bparent = bobj.parent + blender_children.setdefault(bobj, []) + blender_children.setdefault(bparent, []).append(bobj) + for blender_object in [obj.original for obj in depsgraph.scene_eval.objects if obj.parent is None]: - self.recursive_node_traverse(blender_object, None, None, Matrix.Identity(4)) + self.recursive_node_traverse(blender_object, None, None, Matrix.Identity(4), blender_children) - def recursive_node_traverse(self, blender_object, blender_bone, parent_uuid, parent_coll_matrix_world, armature_uuid=None, dupli_world_matrix=None): + def recursive_node_traverse(self, blender_object, blender_bone, parent_uuid, parent_coll_matrix_world, blender_children, armature_uuid=None, dupli_world_matrix=None): node = VExportNode() node.uuid = str(uuid.uuid4()) node.parent_uuid = parent_uuid @@ -199,42 +207,42 @@ class VExportTree: # standard children if blender_bone is None and blender_object.is_instancer is False: - for child_object in blender_object.children: + for child_object in blender_children[blender_object]: if child_object.parent_bone: # Object parented to bones # Will be manage later continue else: # Classic parenting - self.recursive_node_traverse(child_object, None, node.uuid, parent_coll_matrix_world) + self.recursive_node_traverse(child_object, None, node.uuid, parent_coll_matrix_world, blender_children) # Collections if blender_object.instance_type == 'COLLECTION' and blender_object.instance_collection: for dupli_object in blender_object.instance_collection.all_objects: if dupli_object.parent is not None: continue - self.recursive_node_traverse(dupli_object, None, node.uuid, node.matrix_world) + self.recursive_node_traverse(dupli_object, None, node.uuid, node.matrix_world, blender_children) # Armature : children are bones with no parent if blender_object.type == "ARMATURE" and blender_bone is None: for b in [b for b in blender_object.pose.bones if b.parent is None]: - self.recursive_node_traverse(blender_object, b, node.uuid, parent_coll_matrix_world, node.uuid) + self.recursive_node_traverse(blender_object, b, node.uuid, parent_coll_matrix_world, blender_children, node.uuid) # Bones if blender_object.type == "ARMATURE" and blender_bone is not None: for b in blender_bone.children: - self.recursive_node_traverse(blender_object, b, node.uuid, parent_coll_matrix_world, armature_uuid) + self.recursive_node_traverse(blender_object, b, node.uuid, parent_coll_matrix_world, blender_children, armature_uuid) # Object parented to bone if blender_bone is not None: - for child_object in [c for c in blender_object.children if c.parent_bone is not None and c.parent_bone == blender_bone.name]: - self.recursive_node_traverse(child_object, None, node.uuid, parent_coll_matrix_world) + for child_object in [c for c in blender_children[blender_object] if c.parent_bone is not None and c.parent_bone == blender_bone.name]: + self.recursive_node_traverse(child_object, None, node.uuid, parent_coll_matrix_world, blender_children) # Duplis if blender_object.is_instancer is True and blender_object.instance_type != 'COLLECTION': depsgraph = bpy.context.evaluated_depsgraph_get() for (dupl, mat) in [(dup.object.original, dup.matrix_world.copy()) for dup in depsgraph.object_instances if dup.parent and id(dup.parent.original) == id(blender_object)]: - self.recursive_node_traverse(dupl, None, node.uuid, parent_coll_matrix_world, dupli_world_matrix=mat) + self.recursive_node_traverse(dupl, None, node.uuid, parent_coll_matrix_world, blender_children, dupli_world_matrix=mat) def get_all_objects(self): return [n.uuid for n in self.nodes.values() if n.blender_type != VExportNode.BONE] |