Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion UnityPy/helpers/MeshHelper.py
Original file line number Diff line number Diff line change
Expand Up @@ -635,9 +635,14 @@ def decompress_compressed_mesh(self):
]

def get_triangles(self) -> List[List[Tuple[int, ...]]]:
assert self.m_IndexBuffer is not None
assert self.src.m_SubMeshes is not None

if self.m_IndexBuffer is None:
# a mesh can have vertices without indices, e.g. an empty placeholder mesh
if any(m_SubMesh.indexCount for m_SubMesh in self.src.m_SubMeshes):
raise ValueError("Failed getting triangles. The submeshes have indices, but the mesh has none.")
return [[] for _ in self.src.m_SubMeshes]

submeshes: List[List[Tuple[int, ...]]] = []

for m_SubMesh in self.src.m_SubMeshes:
Expand Down
47 changes: 47 additions & 0 deletions tests/test_mesh_helper.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import os

import pytest

import UnityPy
from UnityPy.helpers.MeshHelper import MeshHandler

SAMPLES = os.path.join(os.path.dirname(os.path.abspath(__file__)), "samples")


def load_mesh():
env = UnityPy.load(os.path.join(SAMPLES, "xinzexi_2_n_tex"))
return next(obj.parse_as_object() for obj in env.objects if obj.type.name == "Mesh")


def triangles(mesh):
handler = MeshHandler(mesh)
handler.process()
return handler.get_triangles()


def test_mesh_without_submeshes_and_indices():
# vertices only, as in a placeholder mesh
mesh = load_mesh()
mesh.m_IndexBuffer = []
mesh.m_SubMeshes = []
assert triangles(mesh) == []
obj = mesh.export()
assert "\nv " in obj or obj.startswith("v ")
assert "\nf " not in obj


def test_mesh_with_empty_submeshes_and_no_indices():
mesh = load_mesh()
mesh.m_IndexBuffer = []
for submesh in mesh.m_SubMeshes:
submesh.firstByte = 0
submesh.indexCount = 0
assert triangles(mesh) == [[] for _ in mesh.m_SubMeshes]


def test_mesh_with_submesh_indices_but_no_index_buffer():
mesh = load_mesh()
assert any(submesh.indexCount for submesh in mesh.m_SubMeshes)
mesh.m_IndexBuffer = []
with pytest.raises(ValueError):
triangles(mesh)