From b2f59856817d86d2346c5f6c7fa034f3d3821774 Mon Sep 17 00:00:00 2001 From: Colin Basnett Date: Mon, 22 Jan 2024 14:56:51 -0800 Subject: [PATCH] Improved PSK vertex color importing to be per-corner instead of per-vertex Previously, the importer was storing the vertex colors in the point domain. However, the PSK itself stores colors per "wedge", which maps to corners, resulting in the "ambiguous vertex colors" warning if two corners mapped to the same vertex but had different colors. The new method is now more correct and doesn't discard data. --- io_scene_psk_psa/psk/importer.py | 49 ++++++++++++++------------------ 1 file changed, 22 insertions(+), 27 deletions(-) diff --git a/io_scene_psk_psa/psk/importer.py b/io_scene_psk_psa/psk/importer.py index f07fd11..15c0801 100644 --- a/io_scene_psk_psa/psk/importer.py +++ b/io_scene_psk_psa/psk/importer.py @@ -1,4 +1,3 @@ -from math import inf from typing import Optional, List import bmesh @@ -17,7 +16,7 @@ class PskImportOptions: self.should_import_mesh = True self.should_reuse_materials = True self.should_import_vertex_colors = True - self.vertex_color_space = 'sRGB' + self.vertex_color_space = 'SRGB' self.should_import_vertex_normals = True self.should_import_extra_uvs = True self.should_import_skeleton = True @@ -144,6 +143,7 @@ def import_psk(psk: Psk, context, options: PskImportOptions) -> PskImportResult: bm.verts.ensure_lookup_table() + # FACES invalid_face_indices = set() for face_index, face in enumerate(psk.faces): point_indices = map(lambda i: psk.wedges[i].point_index, reversed(face.wedge_indices)) @@ -192,33 +192,28 @@ def import_psk(psk: Psk, context, options: PskImportOptions) -> PskImportResult: # VERTEX COLORS if psk.has_vertex_colors and options.should_import_vertex_colors: - size = (len(psk.points), 4) - vertex_colors = np.full(size, inf) - vertex_color_data = mesh_data.vertex_colors.new(name='VERTEXCOLOR') - ambiguous_vertex_color_point_indices = [] + # Convert vertex colors to sRGB if necessary. + psk_vertex_colors = np.zeros((len(psk.vertex_colors), 4)) + for i in range(len(psk.vertex_colors)): + psk_vertex_colors[i,:] = psk.vertex_colors[i].normalized() + match options.vertex_color_space: + case 'SRGBA': + for i in range(psk_vertex_colors.shape[0]): + psk_vertex_colors[i, :3] = tuple(map(lambda x: rgb_to_srgb(x), psk_vertex_colors[i, :3])) + case _: + pass - for wedge_index, wedge in enumerate(psk.wedges): - point_index = wedge.point_index - psk_vertex_color = psk.vertex_colors[wedge_index].normalized() - if vertex_colors[point_index, 0] != inf and tuple(vertex_colors[point_index]) != psk_vertex_color: - ambiguous_vertex_color_point_indices.append(point_index) - else: - vertex_colors[point_index] = psk_vertex_color + # Map the PSK vertex colors to the face corners. + face_corner_colors = np.full((len(psk.faces * 3), 4), 1.0) + face_corner_color_index = 0 + for face_index, face in enumerate(psk.faces): + for wedge_index in reversed(face.wedge_indices): + face_corner_colors[face_corner_color_index] = psk_vertex_colors[wedge_index] + face_corner_color_index += 1 - if options.vertex_color_space == 'SRGBA': - for i in range(vertex_colors.shape[0]): - vertex_colors[i, :3] = tuple(map(lambda x: rgb_to_srgb(x), vertex_colors[i, :3])) - - for loop_index, loop in enumerate(mesh_data.loops): - vertex_color = vertex_colors[loop.vertex_index] - if vertex_color is not None: - vertex_color_data.data[loop_index].color = vertex_color - else: - vertex_color_data.data[loop_index].color = 1.0, 1.0, 1.0, 1.0 - - if len(ambiguous_vertex_color_point_indices) > 0: - result.warnings.append( - f'{len(ambiguous_vertex_color_point_indices)} vertex(es) with ambiguous vertex colors.') + # Create the vertex color attribute. + face_corner_color_attribute = mesh_data.attributes.new(name='VERTEXCOLOR', type='FLOAT_COLOR', domain='CORNER') + face_corner_color_attribute.data.foreach_set('color', face_corner_colors.flatten()) # VERTEX NORMALS if psk.has_vertex_normals and options.should_import_vertex_normals: