Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender-addons.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulien Duroure <julien.duroure@gmail.com>2020-02-23 13:55:32 +0300
committerJulien Duroure <julien.duroure@gmail.com>2020-02-23 13:55:32 +0300
commitee61a3a692d30bcb844901c87c9408db332f4265 (patch)
tree61e58774a4ce0285a5103ca5f32e5ff1e2c272ec
parentb4fc9fbcf4e2d766143d6e88b57e892a12b6fe88 (diff)
glTF importer: manage morph weights at node level
-rwxr-xr-xio_scene_gltf2/__init__.py2
-rwxr-xr-xio_scene_gltf2/blender/imp/gltf2_blender_gltf.py16
-rwxr-xr-xio_scene_gltf2/blender/imp/gltf2_blender_mesh.py12
-rwxr-xr-xio_scene_gltf2/blender/imp/gltf2_blender_node.py59
4 files changed, 34 insertions, 55 deletions
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,24 +75,12 @@ 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