Improved performance of PSK importer by ~40% for large meshes
This commit is contained in:
@@ -163,8 +163,11 @@ def import_psk(psk: Psk, context: Context, name: str, options: PskImportOptions)
|
|||||||
# Faces
|
# Faces
|
||||||
invalid_face_indices = set()
|
invalid_face_indices = set()
|
||||||
for face_index, face in enumerate(psk.faces):
|
for face_index, face in enumerate(psk.faces):
|
||||||
point_indices = map(lambda i: psk.wedges[i].point_index, reversed(face.wedge_indices))
|
points = (
|
||||||
points = [bm.verts[i] for i in point_indices]
|
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:
|
try:
|
||||||
bm_face = bm.faces.new(points)
|
bm_face = bm.faces.new(points)
|
||||||
bm_face.material_index = face.material_index
|
bm_face.material_index = face.material_index
|
||||||
@@ -182,40 +185,43 @@ def import_psk(psk: Psk, context: Context, name: str, options: PskImportOptions)
|
|||||||
|
|
||||||
# Texture Coordinates
|
# Texture Coordinates
|
||||||
uv_layer_data_index = 0
|
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):
|
for face_index, face in enumerate(psk.faces):
|
||||||
if face_index in invalid_face_indices:
|
if face_index in invalid_face_indices:
|
||||||
continue
|
continue
|
||||||
face_wedges = [psk.wedges[i] for i in reversed(face.wedge_indices)]
|
for wedge in map(lambda i: psk.wedges[i], reversed(face.wedge_indices)):
|
||||||
for wedge in face_wedges:
|
uv_layer_data[uv_layer_data_index] = wedge.u, 1.0 - wedge.v
|
||||||
uv_layer.data[uv_layer_data_index].uv = wedge.u, 1.0 - wedge.v
|
|
||||||
uv_layer_data_index += 1
|
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
|
# Extra UVs
|
||||||
if psk.has_extra_uvs and options.should_import_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))
|
extra_uv_channel_count = int(len(psk.extra_uvs) / len(psk.wedges))
|
||||||
wedge_index_offset = 0
|
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):
|
for extra_uv_index in range(extra_uv_channel_count):
|
||||||
uv_layer_data_index = 0
|
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):
|
for face_index, face in enumerate(psk.faces):
|
||||||
if face_index in invalid_face_indices:
|
if face_index in invalid_face_indices:
|
||||||
continue
|
continue
|
||||||
for wedge_index in reversed(face.wedge_indices):
|
for wedge in map(lambda i: psk.wedges[i], reversed(face.wedge_indices)):
|
||||||
u, v = psk.extra_uvs[wedge_index_offset + wedge_index]
|
uv_layer_data[uv_layer_data_index] = wedge.u, 1.0 - wedge.v
|
||||||
uv_layer.data[uv_layer_data_index].uv = u, 1.0 - v
|
|
||||||
uv_layer_data_index += 1
|
uv_layer_data_index += 1
|
||||||
wedge_index_offset += len(psk.wedges)
|
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
|
# Vertex Colors
|
||||||
if psk.has_vertex_colors and options.should_import_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))
|
psk_vertex_colors = np.zeros((len(psk.vertex_colors), 4))
|
||||||
for vertex_color_index in range(len(psk.vertex_colors)):
|
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':
|
if options.vertex_color_space == 'SRGBA':
|
||||||
for i in range(psk_vertex_colors.shape[0]):
|
psk_vertex_colors[:, :3] = np.vectorize(rgb_to_srgb)(psk_vertex_colors[:, :3])
|
||||||
psk_vertex_colors[i, :3] = tuple(map(lambda x: rgb_to_srgb(x), psk_vertex_colors[i, :3]))
|
|
||||||
|
|
||||||
# Map the PSK vertex colors to the face corners.
|
# Map the PSK vertex colors to the face corners.
|
||||||
face_count = len(psk.faces) - len(invalid_face_indices)
|
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.
|
# Create the vertex color attribute.
|
||||||
face_corner_color_attribute = mesh_data.attributes.new(name='VERTEXCOLOR', type='FLOAT_COLOR', domain='CORNER')
|
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
|
# Vertex Normals
|
||||||
if psk.has_vertex_normals and options.should_import_vertex_normals:
|
if psk.has_vertex_normals and options.should_import_vertex_normals:
|
||||||
|
|||||||
@@ -17,13 +17,18 @@ class Color(Structure):
|
|||||||
yield self.a
|
yield self.a
|
||||||
|
|
||||||
def __eq__(self, other):
|
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):
|
def __repr__(self):
|
||||||
return repr(tuple(self))
|
return repr(tuple(self))
|
||||||
|
|
||||||
def normalized(self) -> Tuple:
|
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):
|
class Vector2(Structure):
|
||||||
|
|||||||
@@ -7,10 +7,9 @@ from .data import Vector3, Quaternion
|
|||||||
from ..shared.data import PsxBone
|
from ..shared.data import PsxBone
|
||||||
|
|
||||||
|
|
||||||
def rgb_to_srgb(c: float):
|
def rgb_to_srgb(c: float) -> float:
|
||||||
if c > 0.0031308:
|
if c > 0.0031308:
|
||||||
return 1.055 * (pow(c, (1.0 / 2.4))) - 0.055
|
return 1.055 * (pow(c, (1.0 / 2.4))) - 0.055
|
||||||
else:
|
|
||||||
return 12.92 * c
|
return 12.92 * c
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user