[Bf-extensions-cvs] [77aada80] master: glTF importer/exporter: fix for material_index/material slots

Julien Duroure noreply at git.blender.org
Thu Oct 8 20:25:51 CEST 2020


Commit: 77aada8057d961a3b409d7cdcfad312919b40d23
Author: Julien Duroure
Date:   Thu Oct 8 20:25:22 2020 +0200
Branches: master
https://developer.blender.org/rBA77aada8057d961a3b409d7cdcfad312919b40d23

glTF importer/exporter: fix for material_index/material slots

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

M	io_scene_gltf2/__init__.py
M	io_scene_gltf2/blender/exp/gltf2_blender_gather_nodes.py
M	io_scene_gltf2/blender/exp/gltf2_blender_gather_primitives.py
M	io_scene_gltf2/blender/imp/gltf2_blender_mesh.py

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

diff --git a/io_scene_gltf2/__init__.py b/io_scene_gltf2/__init__.py
index 2599fa21..1f9dfe61 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, Scurest, Norbert Nopper, Urs Hanselmann, Moritz Becher, Benjamin Schmithüsen, Jim Eckerlein, and many external contributors',
-    "version": (1, 4, 34),
+    "version": (1, 4, 35),
     'blender': (2, 91, 0),
     'location': 'File > Import-Export',
     'description': 'Import-Export as glTF 2.0',
diff --git a/io_scene_gltf2/blender/exp/gltf2_blender_gather_nodes.py b/io_scene_gltf2/blender/exp/gltf2_blender_gather_nodes.py
index b1317097..30058309 100755
--- a/io_scene_gltf2/blender/exp/gltf2_blender_gather_nodes.py
+++ b/io_scene_gltf2/blender/exp/gltf2_blender_gather_nodes.py
@@ -294,7 +294,8 @@ def __gather_mesh(blender_object, library, export_settings):
                 vertex_groups = None # Not needed if no armature, avoid a cache miss
                 modifiers = None
 
-    material_names = tuple([ms.material.name for ms in blender_object.material_slots if ms.material is not None])
+    materials = tuple(ms.material for ms in blender_object.material_slots)
+    material_names = tuple(None if mat is None else mat.name for mat in materials)
 
     # retrieve armature
     # Because mesh data will be transforms to skeleton space,
diff --git a/io_scene_gltf2/blender/exp/gltf2_blender_gather_primitives.py b/io_scene_gltf2/blender/exp/gltf2_blender_gather_primitives.py
index a87a9db3..8678db83 100755
--- a/io_scene_gltf2/blender/exp/gltf2_blender_gather_primitives.py
+++ b/io_scene_gltf2/blender/exp/gltf2_blender_gather_primitives.py
@@ -55,14 +55,17 @@ def gather_primitives(
         material = None
 
         if export_settings['gltf_materials'] == "EXPORT":
-            try:
-                blender_material = bpy.data.materials[material_names[material_idx]]
-                material = gltf2_blender_gather_materials.gather_material(blender_material,
-                                                                      export_settings)
-            except IndexError:
-                # no material at that index
-                pass
-
+            blender_material = None
+            if material_names:
+                i = material_idx if material_idx < len(material_names) else -1
+                material_name = material_names[i]
+                if material_name is not None:
+                    blender_material = bpy.data.materials[material_name]
+            if blender_material is not None:
+                material = gltf2_blender_gather_materials.gather_material(
+                    blender_material,
+                    export_settings,
+                )
 
         primitive = gltf2_io.MeshPrimitive(
             attributes=internal_primitive['attributes'],
diff --git a/io_scene_gltf2/blender/imp/gltf2_blender_mesh.py b/io_scene_gltf2/blender/imp/gltf2_blender_mesh.py
index d87b216f..ef26a1a5 100755
--- a/io_scene_gltf2/blender/imp/gltf2_blender_mesh.py
+++ b/io_scene_gltf2/blender/imp/gltf2_blender_mesh.py
@@ -320,33 +320,36 @@ def do_primitives(gltf, mesh_idx, skin_idx, mesh, ob):
 
     # ----
     # Assign materials to faces
+    has_materials = any(prim.material is not None for prim in pymesh.primitives)
+    if has_materials:
+        material_indices = np.empty(num_faces, dtype=np.uint32)
+        empty_material_slot_index = None
+        f = 0
 
-    # Initialize to no-material, ie. an index guaranteed to be OOB for the
-    # material slots. A mesh obviously can't have more materials than it has
-    # primitives...
-    oob_material_idx = len(pymesh.primitives)
-    material_indices = np.full(num_faces, oob_material_idx)
-
-    f = 0
-    for prim in pymesh.primitives:
-        if prim.material is not None:
-            # Get the material
-            pymaterial = gltf.data.materials[prim.material]
-            vertex_color = 'COLOR_0' if 'COLOR_0' in prim.attributes else None
-            if vertex_color not in pymaterial.blender_material:
-                BlenderMaterial.create(gltf, prim.material, vertex_color)
-            material_name = pymaterial.blender_material[vertex_color]
-
-            # Put material in slot (if not there)
-            if material_name not in mesh.materials:
-                mesh.materials.append(bpy.data.materials[material_name])
-            material_index = mesh.materials.find(material_name)
+        for prim in pymesh.primitives:
+            if prim.material is not None:
+                # Get the material
+                pymaterial = gltf.data.materials[prim.material]
+                vertex_color = 'COLOR_0' if 'COLOR_0' in prim.attributes else None
+                if vertex_color not in pymaterial.blender_material:
+                    BlenderMaterial.create(gltf, prim.material, vertex_color)
+                material_name = pymaterial.blender_material[vertex_color]
+
+                # Put material in slot (if not there)
+                if material_name not in mesh.materials:
+                    mesh.materials.append(bpy.data.materials[material_name])
+                material_index = mesh.materials.find(material_name)
+            else:
+                if empty_material_slot_index is None:
+                    mesh.materials.append(None)
+                    empty_material_slot_index = len(mesh.materials) - 1
+                material_index = empty_material_slot_index
 
             material_indices[f:f + prim.num_faces].fill(material_index)
 
-        f += prim.num_faces
+            f += prim.num_faces
 
-    mesh.polygons.foreach_set('material_index', material_indices)
+        mesh.polygons.foreach_set('material_index', material_indices)
 
     # ----
     # Normals



More information about the Bf-extensions-cvs mailing list