[Bf-extensions-cvs] [2fcac975] master: glTF exporter: Manage all 4 types of Vertex Colors (corner/point - byte/float)

Julien Duroure noreply at git.blender.org
Wed Jul 13 12:15:36 CEST 2022


Commit: 2fcac97522dee91d8f444055b9a996fea7d36e40
Author: Julien Duroure
Date:   Wed Jul 13 12:15:28 2022 +0200
Branches: master
https://developer.blender.org/rBA2fcac97522dee91d8f444055b9a996fea7d36e40

glTF exporter: Manage all 4 types of Vertex Colors (corner/point - byte/float)

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

M	io_scene_gltf2/__init__.py
M	io_scene_gltf2/blender/exp/gltf2_blender_extract.py
M	io_scene_gltf2/blender/exp/gltf2_blender_gather_primitive_attributes.py

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

diff --git a/io_scene_gltf2/__init__.py b/io_scene_gltf2/__init__.py
index be8aa8ed..98210e82 100755
--- a/io_scene_gltf2/__init__.py
+++ b/io_scene_gltf2/__init__.py
@@ -4,7 +4,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": (3, 3, 16),
+    "version": (3, 3, 17),
     'blender': (3, 3, 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 d4f34126..93947acb 100755
--- a/io_scene_gltf2/blender/exp/gltf2_blender_extract.py
+++ b/io_scene_gltf2/blender/exp/gltf2_blender_extract.py
@@ -39,6 +39,18 @@ def extract_primitives(blender_mesh, uuid_for_skined_data, blender_vertex_groups
     if export_settings[gltf2_blender_export_keys.COLORS]:
         color_max = len(blender_mesh.vertex_colors)
 
+    colors_attributes = []
+    rendered_color_idx = blender_mesh.attributes.render_color_index
+
+    if color_max > 0:
+        colors_attributes.append(rendered_color_idx)
+        # Then find other ones
+        colors_attributes.extend([
+            i for i in range(len(blender_mesh.color_attributes)) if i != rendered_color_idx \
+                and blender_mesh.vertex_colors.find(blender_mesh.color_attributes[i].name) != -1
+        ])
+
+
     armature = None
     skin = None
     if blender_vertex_groups and export_settings[gltf2_blender_export_keys.SKINS]:
@@ -110,7 +122,7 @@ def extract_primitives(blender_mesh, uuid_for_skined_data, blender_vertex_groups
         dot_fields += [('tx', np.float32), ('ty', np.float32), ('tz', np.float32), ('tw', np.float32)]
     for uv_i in range(tex_coord_max):
         dot_fields += [('uv%dx' % uv_i, np.float32), ('uv%dy' % uv_i, np.float32)]
-    for col_i in range(color_max):
+    for col_i, _ in enumerate(colors_attributes):
         dot_fields += [
             ('color%dr' % col_i, np.float32),
             ('color%dg' % col_i, np.float32),
@@ -163,8 +175,12 @@ def extract_primitives(blender_mesh, uuid_for_skined_data, blender_vertex_groups
         dots['uv%dy' % uv_i] = uvs[:, 1]
         del uvs
 
-    for col_i in range(color_max):
-        colors = __get_colors(blender_mesh, col_i)
+    colors_types = []
+    for col_i, blender_col_i in enumerate(colors_attributes):
+        colors, colors_type, domain = __get_colors(blender_mesh, col_i, blender_col_i)
+        if domain == "POINT":
+            colors = colors[dots['vertex_index']]
+        colors_types.append(colors_type)
         dots['color%dr' % col_i] = colors[:, 0]
         dots['color%dg' % col_i] = colors[:, 1]
         dots['color%db' % col_i] = colors[:, 2]
@@ -251,13 +267,16 @@ def extract_primitives(blender_mesh, uuid_for_skined_data, blender_vertex_groups
             uvs[:, 1] = prim_dots['uv%dy' % tex_coord_i]
             attributes['TEXCOORD_%d' % tex_coord_i] = uvs
 
-        for color_i in range(color_max):
+        for color_i, _ in enumerate(colors_attributes):
             colors = np.empty((len(prim_dots), 4), dtype=np.float32)
             colors[:, 0] = prim_dots['color%dr' % color_i]
             colors[:, 1] = prim_dots['color%dg' % color_i]
             colors[:, 2] = prim_dots['color%db' % color_i]
             colors[:, 3] = prim_dots['color%da' % color_i]
-            attributes['COLOR_%d' % color_i] = colors
+            attributes['COLOR_%d' % color_i] = {}
+            attributes['COLOR_%d' % color_i]["data"] = colors
+
+            attributes['COLOR_%d' % color_i]["norm"] = colors_types[color_i] == "BYTE_COLOR"
 
         if skin:
             joints = [[] for _ in range(num_joint_sets)]
@@ -525,13 +544,15 @@ def __get_uvs(blender_mesh, uv_i):
     return uvs
 
 
-def __get_colors(blender_mesh, color_i):
-    colors = np.empty(len(blender_mesh.loops) * 4, dtype=np.float32)
-    layer = blender_mesh.vertex_colors[color_i]
-    blender_mesh.color_attributes[layer.name].data.foreach_get('color', colors)
-    colors = colors.reshape(len(blender_mesh.loops), 4)
+def __get_colors(blender_mesh, color_i, blender_color_i):
+    if blender_mesh.color_attributes[blender_color_i].domain == "POINT":
+        colors = np.empty(len(blender_mesh.vertices) * 4, dtype=np.float32) #POINT
+    else:
+        colors = np.empty(len(blender_mesh.loops) * 4, dtype=np.float32) #CORNER
+    blender_mesh.color_attributes[blender_color_i].data.foreach_get('color', colors)
+    colors = colors.reshape(-1, 4)
     # colors are already linear, no need to switch color space
-    return colors
+    return colors, blender_mesh.color_attributes[blender_color_i].data_type, blender_mesh.color_attributes[blender_color_i].domain
 
 
 def __get_bone_data(blender_mesh, skin, blender_vertex_groups):
diff --git a/io_scene_gltf2/blender/exp/gltf2_blender_gather_primitive_attributes.py b/io_scene_gltf2/blender/exp/gltf2_blender_gather_primitive_attributes.py
index 72f0268c..f28a1f10 100755
--- a/io_scene_gltf2/blender/exp/gltf2_blender_gather_primitive_attributes.py
+++ b/io_scene_gltf2/blender/exp/gltf2_blender_gather_primitive_attributes.py
@@ -124,28 +124,34 @@ def __gather_colors(blender_primitive, export_settings):
         color_index = 0
         color_id = 'COLOR_' + str(color_index)
         while blender_primitive["attributes"].get(color_id) is not None:
-            colors = blender_primitive["attributes"][color_id]
+            colors = blender_primitive["attributes"][color_id]["data"]
 
             if type(colors) is not np.ndarray:
                 colors = np.array(colors, dtype=np.float32)
                 colors = colors.reshape(len(colors) // 4, 4)
 
-            # Convert to normalized ushorts
-            colors *= 65535
-            colors += 0.5  # bias for rounding
-            colors = colors.astype(np.uint16)
+            if blender_primitive["attributes"][color_id]["norm"] is True:
+                comp_type = gltf2_io_constants.ComponentType.UnsignedShort
+
+                # Convert to normalized ushorts
+                colors *= 65535
+                colors += 0.5  # bias for rounding
+                colors = colors.astype(np.uint16)
+
+            else:
+                comp_type = gltf2_io_constants.ComponentType.Float
 
             attributes[color_id] = gltf2_io.Accessor(
                 buffer_view=gltf2_io_binary_data.BinaryData(colors.tobytes()),
                 byte_offset=None,
-                component_type=gltf2_io_constants.ComponentType.UnsignedShort,
+                component_type=comp_type,
                 count=len(colors),
                 extensions=None,
                 extras=None,
                 max=None,
                 min=None,
                 name=None,
-                normalized=True,
+                normalized=blender_primitive["attributes"][color_id]["norm"],
                 sparse=None,
                 type=gltf2_io_constants.DataType.Vec4,
             )



More information about the Bf-extensions-cvs mailing list