[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