trimesh
trimesh copied to clipboard
Breaking change in 3.10.8 causing materials not to load
I have a library that uses Trimesh for mesh loading and modification. After I updated Trimesh to the latest version from 3.9.34 to 4.0.0 I noticed that the materials are no longer loaded correctly. They are replaced with material_0.
The issue is that when I reexport an obj file loaded by trimesh using export, it loses its material properties, and instead material_0 is added.
Here's a minimal reproduction of the bug https://github.com/aminya/trimesh-bug
import trimesh
def main():
"""
Load a obj mesh that has a material and export it back to obj.
"""
asset_dir = "./trimesh-bug/assets"
mesh = trimesh.load_mesh(f"{asset_dir}/cube.obj")
if isinstance(mesh, list):
raise RuntimeError("Multiple meshes found.")
# cast Geometry to the more specific Trimesh type
if not isinstance(mesh, trimesh.Trimesh) and not isinstance(mesh, trimesh.Scene):
raise RuntimeError(
"The mesh geometry is not a trimesh.Trimesh or trimesh.Scene."
)
obj_content = mesh.export(file_type="obj")
if not isinstance(obj_content, str):
raise RuntimeError("The obj_content is not a string.")
with open(f"{asset_dir}/cube_rexport.obj", "w", encoding="utf-8") as f:
f.write(obj_content)
if __name__ == "__main__":
main()
Reexported-mesh
# https://github.com/mikedh/trimesh
mtllib material.mtl
usemtl material_0
v 1.00000000 1.00000000 -1.00000000
v 1.00000000 -1.00000000 -1.00000000
v 1.00000000 1.00000000 1.00000000
v 1.00000000 -1.00000000 1.00000000
v -1.00000000 1.00000000 -1.00000000
v -1.00000000 -1.00000000 -1.00000000
v -1.00000000 1.00000000 1.00000000
v -1.00000000 -1.00000000 1.00000000
f 1 5 7
f 4 3 7
f 8 7 5
f 6 2 4
f 2 1 3
f 6 5 1
f 7 3 1
f 7 8 4
f 5 6 8
f 4 8 6
f 3 4 2
f 1 2 6
Original mesh
mtllib cube.mtl
o Cube
v 1.000000 1.000000 -1.000000
v 1.000000 -1.000000 -1.000000
v 1.000000 1.000000 1.000000
v 1.000000 -1.000000 1.000000
v -1.000000 1.000000 -1.000000
v -1.000000 -1.000000 -1.000000
v -1.000000 1.000000 1.000000
v -1.000000 -1.000000 1.000000
vt 0.625000 0.500000
vt 0.875000 0.500000
vt 0.875000 0.750000
vt 0.625000 0.750000
vt 0.375000 0.750000
vt 0.625000 1.000000
vt 0.375000 1.000000
vt 0.375000 0.000000
vt 0.625000 0.000000
vt 0.625000 0.250000
vt 0.375000 0.250000
vt 0.125000 0.500000
vt 0.375000 0.500000
vt 0.125000 0.750000
vn 0.0000 1.0000 0.0000
vn 0.0000 0.0000 1.0000
vn -1.0000 0.0000 0.0000
vn 0.0000 -1.0000 0.0000
vn 1.0000 0.0000 0.0000
vn 0.0000 0.0000 -1.0000
usemtl green
s off
f 1/1/1 5/2/1 7/3/1 3/4/1
f 4/5/2 3/4/2 7/6/2 8/7/2
f 8/8/3 7/9/3 5/10/3 6/11/3
f 6/12/4 2/13/4 4/5/4 8/14/4
f 2/13/5 1/1/5 3/4/5 4/5/5
f 6/11/6 5/10/6 1/1/6 2/13/6
After spending an hour trying all the versions by doing a bisect, I found the buggy version: 3.10.8. The changes in this version break the material loading for me compared to 3.10.7:
https://github.com/mikedh/trimesh/compare/3.10.7...3.10.8
Workaround
I have temporarily fixed the issue by setting mesh.export(file_type="obj", include_texture=False) in obj export.
Another option is pinning the version in
[tool.poetry.dependencies]
trimesh = "=3.10.7" # 3.10.8 breaks the material loading resulting in no colours
Do you know if this breaking change was documented anywhere or was it unexpected? Is there a way I can resolve this or get more information about how the changes affect the materials?
It looks like that corresponds to #1543, which format are you trying to load? Can you share the model in question?
I think among those changes, #1537 could be the issue.
The issue is with this line where it exports the textures even if the uv size is not 2 (introduced in #1537 cc: @clemense)
https://github.com/mikedh/trimesh/blob/7853a5ebae3b35275f4d8d65cbc48bcd3a3c8a40/trimesh/exchange/obj.py#L867
My workaround has been to set include_texture=False when exporting the obj meshes.
I don't know why exporting the texture breaks the mlt file colors causing them to be material_0!
Just to understand better: The initial report states that load_mesh behaves differently but the referenced line above points to the export function. Could you write down an MWE?
The OP was outdated, not matching my latest findings about the bug. I have added a minimal reproduction of the bug in this repository and the OP:
https://github.com/aminya/trimesh-bug
I still don't fully understand the problem, the material property is preserved:
In [1]: import trimesh
In [2]: x = trimesh.load('cube.obj')
In [3]: !cat cube.obj
mtllib cube.mtl
o Cube
v 1.000000 1.000000 -1.000000
v 1.000000 -1.000000 -1.000000
v 1.000000 1.000000 1.000000
v 1.000000 -1.000000 1.000000
v -1.000000 1.000000 -1.000000
v -1.000000 -1.000000 -1.000000
v -1.000000 1.000000 1.000000
v -1.000000 -1.000000 1.000000
vt 0.625000 0.500000
vt 0.875000 0.500000
vt 0.875000 0.750000
vt 0.625000 0.750000
vt 0.375000 0.750000
vt 0.625000 1.000000
vt 0.375000 1.000000
vt 0.375000 0.000000
vt 0.625000 0.000000
vt 0.625000 0.250000
vt 0.375000 0.250000
vt 0.125000 0.500000
vt 0.375000 0.500000
vt 0.125000 0.750000
vn 0.0000 1.0000 0.0000
vn 0.0000 0.0000 1.0000
vn -1.0000 0.0000 0.0000
vn 0.0000 -1.0000 0.0000
vn 1.0000 0.0000 0.0000
vn 0.0000 0.0000 -1.0000
usemtl green
s off
f 1/1/1 5/2/1 7/3/1 3/4/1
f 4/5/2 3/4/2 7/6/2 8/7/2
f 8/8/3 7/9/3 5/10/3 6/11/3
f 6/12/4 2/13/4 4/5/4 8/14/4
f 2/13/5 1/1/5 3/4/5 4/5/5
f 6/11/6 5/10/6 1/1/6 2/13/6
In [4]: !cat cube.mtl
newmtl green
Ka 0.0000 0.0000 0.0000
Kd 0.0 1.0 0.0
Ks 0.0000 0.0000 0.0000
Tf 0.0000 0.0000 0.0000
d 1
Ns 0
In [5]: _ = x.export('/tmp/test.obj')
In [6]: !cat /tmp/test.obj
# https://github.com/mikedh/trimesh
mtllib material.mtl
usemtl material_0
v 1.00000000 1.00000000 -1.00000000
v 1.00000000 -1.00000000 -1.00000000
v 1.00000000 1.00000000 1.00000000
v 1.00000000 -1.00000000 1.00000000
v -1.00000000 1.00000000 -1.00000000
v -1.00000000 -1.00000000 -1.00000000
v -1.00000000 1.00000000 1.00000000
v -1.00000000 -1.00000000 1.00000000
f 1 5 7
f 4 3 7
f 8 7 5
f 6 2 4
f 2 1 3
f 6 5 1
f 7 3 1
f 7 8 4
f 5 6 8
f 4 8 6
f 3 4 2
f 1 2 6
In [7]: !cat /tmp/material.mtl
# https://github.com/mikedh/trimesh
newmtl material_0
Ka 0.00000000 0.00000000 0.00000000
Kd 0.00000000 1.00000000 0.00000000
Ks 0.00000000 0.00000000 0.00000000
Ns 0.00000000
It's true that vt is not exported. But that's because it's not used. There's no texture.