trimesh icon indicating copy to clipboard operation
trimesh copied to clipboard

Export mtl for obj without texture doesn't work

Open clemense opened this issue 3 years ago • 3 comments

Hi!

I am very convinced that this recent change https://github.com/mikedh/trimesh/commit/5abdb9fcdf0f860667980bf1fa27338d1a86a19a#diff-b0fd95d2b4cd76b3a3ba885804d392e28913e1e78423883a0881cc88054160f8 (and the commit before) created a new problem: If a mesh with material (but without texture) is exported to obj, no mtl will be created. This also relates to what I observed here: #1499

I propose the following changes to fix this:

  1. Return to the original condition: if include_texture and hasattr(mesh.visual, 'uv'): in obj.py.
  2. A few lines afterwards add the condition: if len(np.shape(getattr(mesh.visual, 'uv', None))) == 2: to avoid writing an empty vt field in the obj file (which was the motivation for the original commit, see above).

Let me know if an MR is needed. Thanks!

clemense avatar Mar 14 '22 07:03 clemense

I'm not totally sure I understand this issue but PR's with a test very welcome! The test matrix/correct behavior looks like this (but one of these conditions isn't true?):

  • mesh without UV coordinates, but has a material: should create MTL but no VT
  • mesh without UV coordinates, no material: no MTL, no VT
  • mesh with UV coordinates, no material: no MTL, VT in file
  • mesh with UV but with material: MTL and VT in file

mikedh avatar Mar 16 '22 19:03 mikedh

Correct, the following condition is not true:

mesh without UV coordinates, but has a material: should create MTL but no VT

This is because https://github.com/mikedh/trimesh/blob/4671ead1432819e8da2f595c4636df429ee3acaf/trimesh/exchange/obj.py#L854 in this case is False (it used to be True before https://github.com/mikedh/trimesh/pull/1488 because mesh without UV coordinates but with material has an empty uv variable). Because of that tex_data is None, which in turn will not enter the material writer https://github.com/mikedh/trimesh/blob/4671ead1432819e8da2f595c4636df429ee3acaf/trimesh/exchange/obj.py#L907

I can write a test, basically it would look like this:

sphere = trimesh.creation.uv_sphere()
sphere.visual = trimesh.visual.TextureVisuals(uv=None, material=trimesh.visual.material.empty_material())
output = sphere.export('sphere.obj')
assert('usemtl' in output)

clemense avatar Mar 16 '22 20:03 clemense

Oh thanks, I understand now. Yeah PR's welcome!

mikedh avatar Mar 16 '22 21:03 mikedh