[Bf-extensions-cvs] [ee61a3a6] master: glTF importer: manage morph weights at node level

Julien Duroure noreply at git.blender.org
Sun Feb 23 11:56:14 CET 2020


Commit: ee61a3a692d30bcb844901c87c9408db332f4265
Author: Julien Duroure
Date:   Sun Feb 23 11:55:32 2020 +0100
Branches: master
https://developer.blender.org/rBAee61a3a692d30bcb844901c87c9408db332f4265

glTF importer: manage morph weights at node level

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

M	io_scene_gltf2/__init__.py
M	io_scene_gltf2/blender/imp/gltf2_blender_gltf.py
M	io_scene_gltf2/blender/imp/gltf2_blender_mesh.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 e13b4cfc..3b586598 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, 27),
+    "version": (1, 2, 28),
     'blender': (2, 82, 7),
     'location': 'File > Import-Export',
     'description': 'Import-Export as glTF 2.0',
diff --git a/io_scene_gltf2/blender/imp/gltf2_blender_gltf.py b/io_scene_gltf2/blender/imp/gltf2_blender_gltf.py
index 33f3ff57..8e6c1950 100755
--- a/io_scene_gltf2/blender/imp/gltf2_blender_gltf.py
+++ b/io_scene_gltf2/blender/imp/gltf2_blender_gltf.py
@@ -96,21 +96,10 @@ class BlenderGlTF():
             # Something is wrong in file, there is no nodes
             return
 
-        for node_idx, node in enumerate(gltf.data.nodes):
-
+        for node in gltf.data.nodes:
             # Weight animation management
             node.weight_animation = False
 
-            # skin management
-            if node.skin is not None and node.mesh is not None:
-                if not hasattr(gltf.data.skins[node.skin], "node_ids"):
-                    gltf.data.skins[node.skin].node_ids = []
-
-                gltf.data.skins[node.skin].node_ids.append(node_idx)
-
-            # Lights management
-            node.correction_needed = False
-
         # Dispatch animation
         if gltf.data.animations:
             for node_idx, node in enumerate(gltf.data.nodes):
@@ -138,8 +127,7 @@ class BlenderGlTF():
         # Meshes
         if gltf.data.meshes:
             for mesh in gltf.data.meshes:
-                mesh.blender_name = {}  # cache Blender mesh (keyed by skin_idx)
-                mesh.is_weight_animated = False
+                mesh.blender_name = {}  # caches Blender mesh name
 
         # Calculate names for each mesh's shapekeys
         for mesh in gltf.data.meshes or []:
diff --git a/io_scene_gltf2/blender/imp/gltf2_blender_mesh.py b/io_scene_gltf2/blender/imp/gltf2_blender_mesh.py
index 04af71b2..adf05281 100755
--- a/io_scene_gltf2/blender/imp/gltf2_blender_mesh.py
+++ b/io_scene_gltf2/blender/imp/gltf2_blender_mesh.py
@@ -75,23 +75,11 @@ class BlenderMesh():
 
         set_extras(mesh, pymesh.extras, exclude=['targetNames'])
 
-        pymesh.blender_name[skin_idx] = mesh.name
-
         # Clear accessor cache after all primitives are done
         gltf.accessor_cache = {}
 
         return mesh
 
-    @staticmethod
-    def set_mesh(gltf, pymesh, obj):
-        """Sets mesh data after creation."""
-        # set default weights for shape keys, and names, if not set by convention on extras data
-        if pymesh.weights is not None:
-            for i in range(len(pymesh.weights)):
-                if pymesh.shapekey_names[i] is None: # No default value if shapekeys was not created
-                    continue
-                obj.data.shape_keys.key_blocks[pymesh.shapekey_names[i]].value = pymesh.weights[i]
-
     @staticmethod
     def bmesh_to_mesh(gltf, pymesh, bme, mesh):
         bme.to_mesh(mesh)
diff --git a/io_scene_gltf2/blender/imp/gltf2_blender_node.py b/io_scene_gltf2/blender/imp/gltf2_blender_node.py
index 590a4fa5..d1ffdbe9 100755
--- a/io_scene_gltf2/blender/imp/gltf2_blender_node.py
+++ b/io_scene_gltf2/blender/imp/gltf2_blender_node.py
@@ -174,39 +174,42 @@ class BlenderNode():
 
     @staticmethod
     def create_mesh_object(gltf, pynode, name):
-        instance = False
-        if gltf.data.meshes[pynode.mesh].blender_name.get(pynode.skin) is not None:
-            # Mesh is already created, only create instance
-            # Except is current node is animated with path weight
-            # Or if previous instance is animation at node level
-            if pynode.weight_animation is True:
-                instance = False
-            else:
-                if gltf.data.meshes[pynode.mesh].is_weight_animated is True:
-                    instance = False
-                else:
-                    instance = True
-                    mesh = bpy.data.meshes[gltf.data.meshes[pynode.mesh].blender_name[pynode.skin]]
-
-        if instance is False:
-            if pynode.name:
-                gltf.log.info("Blender create Mesh node " + pynode.name)
+        pymesh = gltf.data.meshes[pynode.mesh]
+        name = pymesh.name or name
+
+        # Key to cache the Blender mesh by.
+        # Same cache key = instances of the same Blender mesh.
+        cache_key = None
+        if not pymesh.shapekey_names:
+            cache_key = (pynode.skin,)
+        else:
+            # Unlike glTF, all instances of a Blender mesh share shapekeys.
+            # So two instances that might have different morph weights need
+            # different cache keys.
+            if pynode.weight_animation is False:
+                cache_key = (pynode.skin, tuple(pynode.weights or []))
             else:
-                gltf.log.info("Blender create Mesh node")
+                cache_key = None  # don't use the cache at all
 
+        if cache_key is not None and cache_key in pymesh.blender_name:
+            mesh = bpy.data.meshes[pymesh.blender_name[cache_key]]
+        else:
+            gltf.log.info("Blender create Mesh node %s", name)
             mesh = BlenderMesh.create(gltf, pynode.mesh, pynode.skin)
-
-        if pynode.weight_animation is True:
-            # flag this mesh instance as created only for this node, because of weight animation
-            gltf.data.meshes[pynode.mesh].is_weight_animated = True
-
-        mesh_name = gltf.data.meshes[pynode.mesh].name
-        if not name and mesh_name:
-            name = mesh_name
+            if cache_key is not None:
+                pymesh.blender_name[cache_key] = mesh.name
 
         obj = bpy.data.objects.new(name, mesh)
 
-        if instance == False:
-            BlenderMesh.set_mesh(gltf, gltf.data.meshes[pynode.mesh], obj)
+        if pymesh.shapekey_names:
+            BlenderNode.set_morph_weights(gltf, pynode, obj)
 
         return obj
+
+    @staticmethod
+    def set_morph_weights(gltf, pynode, obj):
+        pymesh = gltf.data.meshes[pynode.mesh]
+        weights = pynode.weights or pymesh.weights or []
+        for i, weight in enumerate(weights):
+            if pymesh.shapekey_names[i] is not None:
+                obj.data.shape_keys.key_blocks[pymesh.shapekey_names[i]].value = weight



More information about the Bf-extensions-cvs mailing list