[Bf-extensions-cvs] [01186b0d] master: gltf exporter: Fix T76677 primitive extraction code refactoring

Julien Duroure noreply at git.blender.org
Fri Jul 10 12:50:18 CEST 2020


Commit: 01186b0df9c54eefea95cf8861b8f5fb9960ddf3
Author: Julien Duroure
Date:   Fri Jul 10 12:49:27 2020 +0200
Branches: master
https://developer.blender.org/rBA01186b0df9c54eefea95cf8861b8f5fb9960ddf3

gltf exporter: Fix T76677 primitive extraction code refactoring

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

M	io_scene_gltf2/__init__.py
M	io_scene_gltf2/blender/exp/gltf2_blender_extract.py
M	io_scene_gltf2/blender/imp/gltf2_blender_KHR_materials_pbrSpecularGlossiness.py

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

diff --git a/io_scene_gltf2/__init__.py b/io_scene_gltf2/__init__.py
index 3ea1ce11..2e19cbeb 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, 3, 28),
+    "version": (1, 3, 29),
     'blender': (2, 90, 0),
     'location': 'File > Import-Export',
     'description': 'Import-Export as glTF 2.0',
diff --git a/io_scene_gltf2/blender/exp/gltf2_blender_extract.py b/io_scene_gltf2/blender/exp/gltf2_blender_extract.py
index e2d224ce..5fe719ee 100755
--- a/io_scene_gltf2/blender/exp/gltf2_blender_extract.py
+++ b/io_scene_gltf2/blender/exp/gltf2_blender_extract.py
@@ -18,40 +18,22 @@
 
 from mathutils import Vector, Quaternion, Matrix
 from mathutils.geometry import tessellate_polygon
-from operator import attrgetter
 
 from . import gltf2_blender_export_keys
 from ...io.com.gltf2_io_debug import print_console
 from ...io.com.gltf2_io_color_management import color_srgb_to_scene_linear
 from io_scene_gltf2.blender.exp import gltf2_blender_gather_skins
 
-#
-# Globals
-#
-
-INDICES_ID = 'indices'
-MATERIAL_ID = 'material'
-ATTRIBUTES_ID = 'attributes'
-
-COLOR_PREFIX = 'COLOR_'
-MORPH_TANGENT_PREFIX = 'MORPH_TANGENT_'
-MORPH_NORMAL_PREFIX = 'MORPH_NORMAL_'
-MORPH_POSITION_PREFIX = 'MORPH_POSITION_'
-TEXCOORD_PREFIX = 'TEXCOORD_'
-WEIGHTS_PREFIX = 'WEIGHTS_'
-JOINTS_PREFIX = 'JOINTS_'
-
-TANGENT_ATTRIBUTE = 'TANGENT'
-NORMAL_ATTRIBUTE = 'NORMAL'
-POSITION_ATTRIBUTE = 'POSITION'
-
-GLTF_MAX_COLORS = 2
-
 
 #
 # Classes
 #
 
+class Prim:
+    def __init__(self):
+        self.verts = {}
+        self.indices = []
+
 class ShapeKey:
     def __init__(self, shape_key, vertex_normals, polygon_normals):
         self.shape_key = shape_key
@@ -110,17 +92,17 @@ def convert_swizzle_tangent(tan, armature, blender_object, export_settings):
     if (not armature) or (not blender_object):
         # Classic case. Mesh is not skined, no need to apply armature transfoms on vertices / normals / tangents
         if export_settings[gltf2_blender_export_keys.YUP]:
-            return Vector((tan[0], tan[2], -tan[1], 1.0))
+            return Vector((tan[0], tan[2], -tan[1]))
         else:
-            return Vector((tan[0], tan[1], tan[2], 1.0))
+            return Vector((tan[0], tan[1], tan[2]))
     else:
         # Mesh is skined, we have to apply armature transforms on data
         apply_matrix = armature.matrix_world.inverted() @ blender_object.matrix_world
-        new_tan = apply_matrix.to_quaternion() @ tan
+        new_tan = apply_matrix.to_quaternion() @ Vector((tan[0], tan[1], tan[2]))
         if export_settings[gltf2_blender_export_keys.YUP]:
-            return Vector((new_tan[0], new_tan[2], -new_tan[1], 1.0))
+            return Vector((new_tan[0], new_tan[2], -new_tan[1]))
         else:
-            return Vector((new_tan[0], new_tan[1], new_tan[2], 1.0))
+            return Vector((new_tan[0], new_tan[1], new_tan[2]))
 
 def convert_swizzle_rotation(rot, export_settings):
     """
@@ -151,173 +133,129 @@ def decompose_transition(matrix, export_settings):
 def extract_primitives(glTF, blender_mesh, library, blender_object, blender_vertex_groups, modifiers, export_settings):
     """
     Extract primitives from a mesh. Polygons are triangulated and sorted by material.
-
-    Furthermore, primitives are split up, if the indices range is exceeded.
-    Finally, triangles are also split up/duplicated, if face normals are used instead of vertex normals.
+    Vertices in multiple faces get split up as necessary.
     """
     print_console('INFO', 'Extracting primitive: ' + blender_mesh.name)
 
-    if blender_mesh.has_custom_normals:
-        # Custom normals are all (0, 0, 0) until calling calc_normals_split() or calc_tangents().
-        blender_mesh.calc_normals_split()
-
-    use_tangents = False
-    if blender_mesh.uv_layers.active and len(blender_mesh.uv_layers) > 0:
-        try:
-            blender_mesh.calc_tangents()
-            use_tangents = True
-        except Exception:
-            print_console('WARNING', 'Could not calculate tangents. Please try to triangulate the mesh first.')
-
     #
-
-    material_map = {}
-
+    # First, decide what attributes to gather (eg. how many COLOR_n, etc.)
+    # Also calculate normals/tangents now if necessary.
     #
-    # Gathering position, normal and tex_coords.
-    #
-    no_material_attributes = {
-        POSITION_ATTRIBUTE: [],
-        NORMAL_ATTRIBUTE: []
-    }
-
-    if use_tangents:
-        no_material_attributes[TANGENT_ATTRIBUTE] = []
 
-    #
-    # Directory of materials with its primitive.
-    #
-    no_material_primitives = {
-        MATERIAL_ID: 0,
-        INDICES_ID: [],
-        ATTRIBUTES_ID: no_material_attributes
-    }
+    use_normals = export_settings[gltf2_blender_export_keys.NORMALS]
+    if use_normals:
+        if blender_mesh.has_custom_normals:
+            # Custom normals are all (0, 0, 0) until calling calc_normals_split() or calc_tangents().
+            blender_mesh.calc_normals_split()
 
-    material_idx_to_primitives = {0: no_material_primitives}
-
-    #
-
-    vertex_index_to_new_indices = {}
-
-    material_map[0] = vertex_index_to_new_indices
-
-    #
-    # Create primitive for each material.
-    #
-    for (mat_idx, _) in enumerate(blender_mesh.materials):
-        attributes = {
-            POSITION_ATTRIBUTE: [],
-            NORMAL_ATTRIBUTE: []
-        }
-
-        if use_tangents:
-            attributes[TANGENT_ATTRIBUTE] = []
-
-        primitive = {
-            MATERIAL_ID: mat_idx,
-            INDICES_ID: [],
-            ATTRIBUTES_ID: attributes
-        }
-
-        material_idx_to_primitives[mat_idx] = primitive
-
-        #
-
-        vertex_index_to_new_indices = {}
-
-        material_map[mat_idx] = vertex_index_to_new_indices
+    use_tangents = False
+    if use_normals and export_settings[gltf2_blender_export_keys.TANGENTS]:
+        if blender_mesh.uv_layers.active and len(blender_mesh.uv_layers) > 0:
+            try:
+                blender_mesh.calc_tangents()
+                use_tangents = True
+            except Exception:
+                print_console('WARNING', 'Could not calculate tangents. Please try to triangulate the mesh first.')
 
     tex_coord_max = 0
-    if blender_mesh.uv_layers.active:
-        tex_coord_max = len(blender_mesh.uv_layers)
-
-    #
-
-    vertex_colors = {}
+    if export_settings[gltf2_blender_export_keys.TEX_COORDS]:
+        if blender_mesh.uv_layers.active:
+            tex_coord_max = len(blender_mesh.uv_layers)
 
-    color_index = 0
-    for vertex_color in blender_mesh.vertex_colors:
-        vertex_color_name = COLOR_PREFIX + str(color_index)
-        vertex_colors[vertex_color_name] = vertex_color
+    color_max = 0
+    if export_settings[gltf2_blender_export_keys.COLORS]:
+        color_max = len(blender_mesh.vertex_colors)
 
-        color_index += 1
-        if color_index >= GLTF_MAX_COLORS:
-            break
-    color_max = color_index
-
-    #
-
-    bone_max = 0
-    for blender_polygon in blender_mesh.polygons:
-        for loop_index in blender_polygon.loop_indices:
-            vertex_index = blender_mesh.loops[loop_index].vertex_index
-            bones_count = len(blender_mesh.vertices[vertex_index].groups)
-            if bones_count > 0:
-                if bones_count % 4 == 0:
-                    bones_count -= 1
-                bone_max = max(bone_max, bones_count // 4 + 1)
-
-    #
-
-    morph_max = 0
-
-    blender_shape_keys = []
-
-    if blender_mesh.shape_keys is not None:
+    bone_max = 0  # number of JOINTS_n sets needed (1 set = 4 influences)
+    armature = None
+    if blender_vertex_groups and export_settings[gltf2_blender_export_keys.SKINS]:
+        if modifiers is not None:
+            modifiers_dict = {m.type: m for m in modifiers}
+            if "ARMATURE" in modifiers_dict:
+                modifier = modifiers_dict["ARMATURE"]
+                armature = modifier.object
+
+        # Skin must be ignored if the object is parented to a bone of the armature
+        # (This creates an infinite recursive error)
+        # So ignoring skin in that case
+        is_child_of_arma = (
+            armature and
+            blender_object and
+            blender_object.parent_type == "BONE" and
+            blender_object.parent.name == armature.name
+        )
+        if is_child_of_arma:
+            armature = None
+
+        if armature:
+            skin = gltf2_blender_gather_skins.gather_skin(armature, export_settings)
+            if not skin:
+                armature = None
+            else:
+                joint_name_to_index = {joint.name: index for index, joint in enumerate(skin.joints)}
+                group_to_joint = [joint_name_to_index.get(g.name) for g in blender_vertex_groups]
+
+                # Find out max number of bone influences
+                for blender_polygon in blender_mesh.polygons:
+                    for loop_index in blender_polygon.loop_indices:
+                        vertex_index = blender_mesh.loops[loop_index].vertex_index
+                        groups_count = len(blender_mesh.vertices[vertex_index].groups)
+                        bones_count = (groups_count + 3) // 4
+                        bone_max = max(bone_max, bones_count)
+
+    use_morph_normals = use_normals and export_settings[gltf2_blender_export_keys.MORPH_NORMAL]
+    use_morph_tangents = use_morph_normals and use_tangents and export_settings[gltf2_blender_export_keys.MORPH_TANGENT]
+
+    shape_keys = []
+    if blender_mesh.shape_keys and export_settings[gltf2_blender_export_keys.MORPH]:
         for blender_shape_key in blender_mesh.shape_keys.key_blocks:
-            if blender_shape_key != blender_shape_key.relative_key:
-                if blender_shape_key.mute is False:
-                    morph_max += 1
-                    blender_shape_keys.append(ShapeKey(
-                        blender_shape_key,
-                        blender_shape_key.normals_vertex_get()

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-extensions-cvs mailing list