Improved performance of PSK importer by ~40% for large meshes

This commit is contained in:
Colin Basnett
2025-05-18 01:16:20 -07:00
parent 00d9e3996c
commit 29831d7f09
3 changed files with 30 additions and 20 deletions

View File

@@ -163,8 +163,11 @@ def import_psk(psk: Psk, context: Context, name: str, options: PskImportOptions)
# 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))
points = [bm.verts[i] for i in point_indices]
points = (
bm.verts[psk.wedges[face.wedge_indices[2]].point_index],
bm.verts[psk.wedges[face.wedge_indices[1]].point_index],
bm.verts[psk.wedges[face.wedge_indices[0]].point_index],
)
try:
bm_face = bm.faces.new(points)
bm_face.material_index = face.material_index
@@ -182,40 +185,43 @@ def import_psk(psk: Psk, context: Context, name: str, options: PskImportOptions)
# Texture Coordinates
uv_layer_data_index = 0
uv_layer = mesh_data.uv_layers.new(name='UVMap')
uv_layer_data = np.zeros((len(psk.faces) * 3, 2), dtype=np.float32)
for face_index, face in enumerate(psk.faces):
if face_index in invalid_face_indices:
continue
face_wedges = [psk.wedges[i] for i in reversed(face.wedge_indices)]
for wedge in face_wedges:
uv_layer.data[uv_layer_data_index].uv = wedge.u, 1.0 - wedge.v
for wedge in map(lambda i: psk.wedges[i], reversed(face.wedge_indices)):
uv_layer_data[uv_layer_data_index] = wedge.u, 1.0 - wedge.v
uv_layer_data_index += 1
uv_layer = mesh_data.uv_layers.new(name='UVMap')
uv_layer.uv.foreach_set('vector', uv_layer_data.ravel())
# Extra UVs
if psk.has_extra_uvs and options.should_import_extra_uvs:
extra_uv_channel_count = int(len(psk.extra_uvs) / len(psk.wedges))
wedge_index_offset = 0
uv_layer_data = np.zeros((len(psk.faces) * 3, 2), dtype=np.float32)
for extra_uv_index in range(extra_uv_channel_count):
uv_layer_data_index = 0
uv_layer = mesh_data.uv_layers.new(name=f'EXTRAUV{extra_uv_index}')
for face_index, face in enumerate(psk.faces):
if face_index in invalid_face_indices:
continue
for wedge_index in reversed(face.wedge_indices):
u, v = psk.extra_uvs[wedge_index_offset + wedge_index]
uv_layer.data[uv_layer_data_index].uv = u, 1.0 - v
for wedge in map(lambda i: psk.wedges[i], reversed(face.wedge_indices)):
uv_layer_data[uv_layer_data_index] = wedge.u, 1.0 - wedge.v
uv_layer_data_index += 1
wedge_index_offset += len(psk.wedges)
uv_layer = mesh_data.uv_layers.new(name=f'EXTRAUV{extra_uv_index}')
uv_layer.uv.foreach_set('vector', uv_layer_data.ravel())
# Vertex Colors
if psk.has_vertex_colors and options.should_import_vertex_colors:
# Convert vertex colors to sRGB if necessary.
psk_vertex_colors = np.zeros((len(psk.vertex_colors), 4))
for vertex_color_index in range(len(psk.vertex_colors)):
psk_vertex_colors[vertex_color_index,:] = psk.vertex_colors[vertex_color_index].normalized()
psk_vertex_colors[vertex_color_index] = tuple(psk.vertex_colors[vertex_color_index])
psk_vertex_colors /= 255.0
# Convert vertex colors to sRGB if necessary.
if options.vertex_color_space == '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]))
psk_vertex_colors[:, :3] = np.vectorize(rgb_to_srgb)(psk_vertex_colors[:, :3])
# Map the PSK vertex colors to the face corners.
face_count = len(psk.faces) - len(invalid_face_indices)
@@ -230,7 +236,7 @@ def import_psk(psk: Psk, context: Context, name: str, options: PskImportOptions)
# 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())
face_corner_color_attribute.data.foreach_set('color', face_corner_colors.ravel())
# Vertex Normals
if psk.has_vertex_normals and options.should_import_vertex_normals:

View File

@@ -17,13 +17,18 @@ class Color(Structure):
yield self.a
def __eq__(self, other):
return all(map(lambda x: x[0] == x[1], zip(self, other)))
return self.r == other.r and self.g == other.g and self.b == other.b and self.a == other.a
def __repr__(self):
return repr(tuple(self))
def normalized(self) -> Tuple:
return tuple(map(lambda x: x / 255.0, iter(self)))
return (
self.r / 255.0,
self.g / 255.0,
self.b / 255.0,
self.a / 255.0
)
class Vector2(Structure):

View File

@@ -7,10 +7,9 @@ from .data import Vector3, Quaternion
from ..shared.data import PsxBone
def rgb_to_srgb(c: float):
def rgb_to_srgb(c: float) -> float:
if c > 0.0031308:
return 1.055 * (pow(c, (1.0 / 2.4))) - 0.055
else:
return 12.92 * c