glTF exporter: Manage all 4 types of Vertex Colors (corner/point - byte/float)
This commit is contained in:
parent
08d13c024f
commit
2fcac97522
Notes:
blender-bot
2023-02-14 18:19:19 +01:00
Referenced by issue #99005, gltf exporter does not export non-byte color and non-face-corner vertex colors in 3.3 alpha
|
@ -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',
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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,
|
||||
)
|
||||
|
|
Loading…
Reference in New Issue