trimesh icon indicating copy to clipboard operation
trimesh copied to clipboard

Breaking change in 3.10.8 causing materials not to load

Open aminya opened this issue 2 years ago • 6 comments

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?

aminya avatar Oct 27 '23 02:10 aminya

It looks like that corresponds to #1543, which format are you trying to load? Can you share the model in question?

mikedh avatar Oct 28 '23 19:10 mikedh

I think among those changes, #1537 could be the issue.

aminya avatar Oct 30 '23 17:10 aminya

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!

aminya avatar May 30 '24 19:05 aminya

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?

clemense avatar May 30 '24 21:05 clemense

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

aminya avatar May 30 '24 22:05 aminya

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.

clemense avatar Jun 08 '24 00:06 clemense