[Bf-extensions-cvs] [39e2149b] master: glTF importer: performance: create bones in batches instead of switching edit/pose mode for each bone

Julien Duroure noreply at git.blender.org
Wed Jan 29 21:50:01 CET 2020


Commit: 39e2149b6c62e5e919f26e2c8e87ff0427fb1389
Author: Julien Duroure
Date:   Wed Jan 29 21:49:29 2020 +0100
Branches: master
https://developer.blender.org/rBA39e2149b6c62e5e919f26e2c8e87ff0427fb1389

glTF importer: performance: create bones in batches instead of switching edit/pose mode for each bone

===================================================================

M	io_scene_gltf2/__init__.py
M	io_scene_gltf2/blender/imp/gltf2_blender_node.py

===================================================================

diff --git a/io_scene_gltf2/__init__.py b/io_scene_gltf2/__init__.py
index 144fd655..cadab7a3 100755
--- a/io_scene_gltf2/__init__.py
+++ b/io_scene_gltf2/__init__.py
@@ -15,7 +15,7 @@
 bl_info = {
     'name': 'glTF 2.0 format',
     'author': 'Julien Duroure, Norbert Nopper, Urs Hanselmann, Moritz Becher, Benjamin Schmithüsen, Jim Eckerlein, and many external contributors',
-    "version": (1, 2, 14),
+    "version": (1, 2, 15),
     'blender': (2, 81, 6),
     'location': 'File > Import-Export',
     'description': 'Import-Export as glTF 2.0',
diff --git a/io_scene_gltf2/blender/imp/gltf2_blender_node.py b/io_scene_gltf2/blender/imp/gltf2_blender_node.py
index 2f5d893a..8f138251 100755
--- a/io_scene_gltf2/blender/imp/gltf2_blender_node.py
+++ b/io_scene_gltf2/blender/imp/gltf2_blender_node.py
@@ -37,9 +37,12 @@ class BlenderNode():
 
         if vnode.type == VNode.Object:
             BlenderNode.create_object(gltf, vnode_id)
+            if vnode.is_arma:
+                BlenderNode.create_bones(gltf, vnode_id)
 
         elif vnode.type == VNode.Bone:
-            BlenderNode.create_bone(gltf, vnode_id)
+            # These are created with their armature
+            pass
 
         elif vnode.type == VNode.DummyRoot:
             # Don't actually create this
@@ -101,49 +104,68 @@ class BlenderNode():
         return obj
 
     @staticmethod
-    def create_bone(gltf, vnode_id):
-        vnode = gltf.vnodes[vnode_id]
-        blender_arma = gltf.vnodes[vnode.bone_arma].blender_object
+    def create_bones(gltf, arma_id):
+        arma = gltf.vnodes[arma_id]
+        blender_arma = arma.blender_object
         armature = blender_arma.data
 
-        # Switch into edit mode to create edit bone
+        # Find all bones for this arma
+        bone_ids = []
+        def visit(id):  # Depth-first walk
+            if gltf.vnodes[id].type == VNode.Bone:
+                bone_ids.append(id)
+                for child in gltf.vnodes[id].children:
+                    visit(child)
+        for child in arma.children:
+            visit(child)
+
+        # Switch into edit mode to create all edit bones
+
         if bpy.context.mode != 'OBJECT':
             bpy.ops.object.mode_set(mode='OBJECT')
         bpy.context.window.scene = bpy.data.scenes[gltf.blender_scene]
         bpy.context.view_layer.objects.active = blender_arma
         bpy.ops.object.mode_set(mode="EDIT")
-        editbone = armature.edit_bones.new(vnode.name)
-        vnode.blender_bone_name = editbone.name
-
-        # Set extras (if came from a glTF node)
-        if isinstance(vnode_id, int):
-            pynode = gltf.data.nodes[vnode_id]
-            set_extras(editbone, pynode.extras)
 
-        # TODO
-        editbone.use_connect = False
-
-        # Give the position of the bone in armature space
-        arma_mat = vnode.bone_arma_mat
-        editbone.head = arma_mat @ Vector((0, 0, 0))
-        editbone.tail = arma_mat @ Vector((0, 1, 0))
-        editbone.align_roll(arma_mat @ Vector((0, 0, 1)) - editbone.head)
-
-        # Set parent
-        parent_vnode = gltf.vnodes[vnode.parent]
-        if parent_vnode.type == VNode.Bone:
-            editbone.parent = armature.edit_bones[parent_vnode.blender_bone_name]
+        for id in bone_ids:
+            vnode = gltf.vnodes[id]
+            editbone = armature.edit_bones.new(vnode.name)
+            vnode.blender_bone_name = editbone.name
+            editbone.use_connect = False  # TODO?
+
+            # Give the position of the bone in armature space
+            arma_mat = vnode.bone_arma_mat
+            editbone.head = arma_mat @ Vector((0, 0, 0))
+            editbone.tail = arma_mat @ Vector((0, 1, 0))
+            editbone.align_roll(arma_mat @ Vector((0, 0, 1)) - editbone.head)
+
+            if isinstance(id, int):
+                pynode = gltf.data.nodes[id]
+                set_extras(editbone, pynode.extras)
+
+        # Set all bone parents
+        for id in bone_ids:
+            vnode = gltf.vnodes[id]
+            parent_vnode = gltf.vnodes[vnode.parent]
+            if parent_vnode.type == VNode.Bone:
+                editbone = armature.edit_bones[vnode.blender_bone_name]
+                parent_editbone = armature.edit_bones[parent_vnode.blender_bone_name]
+                editbone.parent = parent_editbone
 
+        # Switch back to object mode and do pose bones
         bpy.ops.object.mode_set(mode="OBJECT")
-        pose_bone = blender_arma.pose.bones[vnode.blender_bone_name]
 
-        # Put scale on the pose bone (can't go on the edit bone)
-        _, _, s = vnode.trs
-        pose_bone.scale = s
+        for id in bone_ids:
+            vnode = gltf.vnodes[id]
+            pose_bone = blender_arma.pose.bones[vnode.blender_bone_name]
 
-        if isinstance(vnode_id, int):
-            pynode = gltf.data.nodes[vnode_id]
-            set_extras(pose_bone, pynode.extras)
+            # Put scale on pose bone (edit bones have no scale)
+            _, _, s = vnode.trs
+            pose_bone.scale = s
+
+            if isinstance(id, int):
+                pynode = gltf.data.nodes[id]
+                set_extras(pose_bone, pynode.extras)
 
     @staticmethod
     def create_mesh_object(gltf, pynode, name):



More information about the Bf-extensions-cvs mailing list