Closed riaqn closed 6 years ago
Hey, this actually came up very recently in this thread
OBJ supports some weird cases so its hard to guarantee ordering in all cases, but the fix in https://github.com/mikedh/trimesh/commit/c019a25874fec33ca6ec3094621743711a29623f should preserve vertex and face order in the simple cases if you load your mesh with processing disabled:
mesh = trimesh.load('stuff.OBJ', process=False)
You can get the update with:
pip install --upgrade trimesh
Oh sorry, I misread OBJ vs OFF. Disabling process should work in that case too, though its not in tests.
Thanks for the lightning reply @mikedh. This workaround works for me.
I suggest making that the default value if it won't compromise functionalities substantially.
Thank you.
I also found that when calling
path = mesh.outline()
The order of vertices attribute in mesh and path is different. I wonder if there's a way to address this issue.
Edit: I tried:
path = mesh.outline(process=False)
And this seems to be able to solve my issue!
import numpy as np
import trimesh
p = r'C:\Users\admin\Desktop\test\test_02.obj'
mesh = trimesh.load( p, process = False )
print(mesh.vertices)
the vertex order is not preserved. how to do that? I has upgraded trimesh, with pip install --upgrade trimesh, the problem is still existe.
this is ouput:
the answer should be: [[-2.5, -2.5, 2.5] [2.5, -2.5, 2.5] [-2.5, 2.5, 2.5] [ 2.5, 2.5, 2.5] [-2.5, 2.5, -2.5] [ 2.5, 2.5, -2.5] [-2.5, -2.5, -2.5] [ 2.5, -2.5, -2.5]]
the number of vertex and order is wrong.
how to fix the problem?
I found the code from wavefront.py 235 current['v'].append(attribs['v'][int(f_split[0]) - 1])
attribs['v'] store all the vertex message, include position and order. but current['v'] copy vertex base on face message. and final the return mesh include the current['v'] message is face to vertex info. the vertex's order message is miss. I hope you fix the bug maybe that is current['v'] = attribs['v'] because attribs['v'] have a right vertex's info.
I doubt setup process = False will work the problem, because the load_wavefront() return the data is miss order info, you can't rebuild it.
Yeah same here. Sometimes load_mesh gets the wrong number of vertices from an OBJ file, although I used process=False
Hey, this is likely from the way OBJ encodes vertices, vertex normals, and vertex UV's. Faces like this:
f 3//5 8//5 4//5
Will have vertices expanded as we consider 2//1
as a different vertex from 2//3
because if the position is the same but the texture coordinate is different we have to refer it differently in the simple data structure trimesh uses. I'd suggest using a different format with a more aligned data structure (i.e. GLB
) if this is a major issue for you.
I was also very confused recently by the differing number of vertices between the orig OBJ & the loaded mesh data. Any thoughts on reducing the difference?
Hey, have you tried loading with process=False
?
In [1]: import trimesh
f
In [2]: fn = 'duck.obj'
In [3]: with open(fn, 'r') as f:
...: text = f.read()
...:
In [4]: text.count('v ')
Out[4]: 2399
In [5]: m = trimesh.load(fn)
In [6]: m.vertices.shape
Out[6]: (2277, 3)
In [7]: m = trimesh.load(fn, process=False)
In [8]: m.vertices.shape
Out[8]: (2399, 3)
First thing I tried. The mesh was a level 4 icosphere directly exported from Blender. So it was well behaved.
I just checked the blender export and it's exporting faces like:
f 3//5 8//5 4//5
Which are being unmerged to provide the flat data structure. If we add Yet Another Boolean Kwarg to skip this (skip_uv
? skip_unmerge
? idk) we can get the count to match:
In [2]: a = trimesh.load('ico4.obj', process=False)
In [3]: a
Out[3]: <trimesh.Trimesh(vertices.shape=(3840, 3), faces.shape=(1280, 3))>
In [4]: a = trimesh.load('ico4.obj', process=False, skip_uv=True)
In [5]:
In [5]: a
Out[5]: <trimesh.Trimesh(vertices.shape=(642, 3), faces.shape=(1280, 3))>
In [6]: with open('ico4.obj', 'r') as f:
...: print(f.read().count('v '))
...:
642
But as far as I can tell it does generally mean discarding UV's and normals. Happy to add if it'd be useful!
Would be much appreciated! Its unfortunate that OBJ has so many edge cases.
@aluo-x I added the maintain_order
kwarg to the OBJ loader and to the unmerge_faces
function, let me know if this doesn't work for you. It's explicit enough that any reordering of vertices from the original would then be a bug we can fix as opposed to just unexpected behavior :smile::
trimesh.load('model.obj', process=False, maintain_order=True)
@aluo-x I added the
maintain_order
kwarg to the OBJ loader and to theunmerge_faces
function, let me know if this doesn't work for you. It's explicit enough that any reordering of vertices from the original would then be a bug we can fix as opposed to just unexpected behavior :
trimesh.load('model.obj', process=False, maintain_order=True)
Thanks, it's work for me
In addition to the vertices, Edge also comes in a different order. Neighbor vertices is the same mesh, Sometimes it returns differently.
I realized recently that when a mesh is loaded, the vertex order is not preserved? That is, mesh.vertices[0] is not the first vertex in the original mesh file.
the format I'm using is OFF.
I feel this is fundementally problematic, and can cause serious confusion to users.