Open3D
Open3D copied to clipboard
[python] o3d.io.read_triangle_mesh changes order of faces and vertices
Hello, loading an *.obj file what does not start with face[0] = [0,1,2] gets changed on loading. The mesh is still ok. But the vertex numbers and faces gonna change. This is especially a problem, if working with labeled data. code to reproduce:
path = os.path.normpath('exp.obj')
width = round(np.random.uniform(0.5,1),6)
height = round(np.random.uniform(0.5,1),6)
depth = round(np.random.uniform(0.5,1),6)
mesh_o3d = o3d.geometry.TriangleMesh.create_box(width = width, height = height, depth = depth)
print("after creation")
print(np.array(mesh_o3d.triangles)[:3])
print(np.array(mesh_o3d.vertices)[:3])
o3d.io.write_triangle_mesh(path, mesh_o3d, write_ascii=True, \
compressed=False, write_vertex_normals=False, write_vertex_colors=False, \
write_triangle_uvs=False, print_progress=False)
mesh_o3d = o3d.io.read_triangle_mesh(path)
print("after save and load I")
print(np.array(mesh_o3d.triangles)[:3])
print(np.array(mesh_o3d.vertices)[:3])
o3d.io.write_triangle_mesh(path, mesh_o3d, write_ascii=True, \
compressed=False, write_vertex_normals=False, write_vertex_colors=False, \
write_triangle_uvs=False, print_progress=False)
mesh_o3d = o3d.io.read_triangle_mesh(path)
print("after save and load II")
print(np.array(mesh_o3d.triangles)[:3])
print(np.array(mesh_o3d.vertices)[:3])
after creation
[[4 7 5]
[4 6 7]
[0 2 4]]
[[0. 0. 0. ]
[0.946121 0. 0. ]
[0. 0. 0.853079]]
after save and load I
[[0 1 2]
[0 3 1]
[4 5 0]]
[[0. 0.64816999 0. ]
[0.94612098 0.64816999 0.85307902]
[0.94612098 0.64816999 0. ]]
after save and load II
[[0 1 2]
[0 3 1]
[4 5 0]]
[[0. 0.64816999 0. ]
[0.94612098 0.64816999 0.85307902]
[0.94612098 0.64816999 0. ]]
System: py38 windows (anaconda)
best regards mgangl
open3d: version 0.11.2
Same issue. Sometimes even the vertices number is wrong. For example, I read an object with 6658
vertices, but got 6786
vertices in open3d...
I guess the obj reader might parse the wrong slot as the vertex index from the triangle info, e.g. f 1133/4429/1133 6515/6621/6515 6658/6786/6658
.
I checked the version 0.10, and it does not have this issue.
they switch to use assimp(It's not a well thought out packages IMHO, tons of problem in our experience.) for loading obj, original using tinyobjloader. assimp loader will break every triangle to individual triangles. so vertices number tripled square in most of case. We find this problem after we switch to open3d 0.13.0. I can confirm the 0.9.0 is good. This is really a big problem. If you need do a cdist between two mesh the memory consume 100=9*9 times . The open3d 0.9.0 don't support python 3.8, and 0.13.0 break things, this is sucks. I think open3d need address this problem. +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Solution: Change one line in the source code and compile python package. in file cpp/open3d/io/TriangleMeshIO.cpp change from: {"obj", ReadTriangleMeshUsingASSIMP}, to: {"obj", ReadTriangleMeshFromOBJ}, That's it. Then you can keep peace in mind for a while, before open3d team breaking something else. Good luck.
open3d: 0.15.1 system: Windows py3.9 anaconda
I meet the same problem on the *.stl file. saving and reloading a *.stl file. But the number of vertices changed.
mesh = o3d.io.read_triangle_mesh("test.stl")
print("origin",mesh.vertices.count)
print("origin",mesh.triangles.count)
mesh.compute_triangle_normals()
print("origin", mesh.vertices.count)
print("origin", mesh.triangles.count)
o3d.io.write_triangle_mesh("test_new.stl", mesh)
mesh_2 = o3d.io.read_triangle_mesh("test_new.stl")
print("reload", mesh_2.vertices.count)
print("reload", mesh_2.triangles.count)
mesh_2.compute_triangle_normals()
print("reload",mesh_2.vertices.count)
print("reload",mesh_2.triangles.count)
rotate_matrix = transformations.random_rotation_matrix()
mesh_2.transform(rotate_matrix)
print("roated", mesh_2.vertices.count)
print("roated", mesh_2.triangles.count)
mesh_2.compute_triangle_normals()
print("roated", mesh_2.vertices.count)
print("roated", mesh_2.triangles.count)
o3d.io.write_triangle_mesh("test_new_new.stl", mesh_2)
mesh_3 = o3d.io.read_triangle_mesh("test_new_new.stl")
print("rotated and reload", mesh_3.vertices.count)
print("rotated and reload", mesh_3.triangles.count)
result:
origin <bound method PyCapsule.count of std::vector<Eigen::Vector3d> with 8948 elements.
Use numpy.asarray() to access data.>
origin <bound method PyCapsule.count of std::vector<Eigen::Vector3i> with 3336 elements.
Use numpy.asarray() to access data.>
origin <bound method PyCapsule.count of std::vector<Eigen::Vector3d> with 8948 elements.
Use numpy.asarray() to access data.>
origin <bound method PyCapsule.count of std::vector<Eigen::Vector3i> with 3336 elements.
Use numpy.asarray() to access data.>
reload <bound method PyCapsule.count of std::vector<Eigen::Vector3d> with 9008 elements.
Use numpy.asarray() to access data.>
reload <bound method PyCapsule.count of std::vector<Eigen::Vector3i> with 3336 elements.
Use numpy.asarray() to access data.>
reload <bound method PyCapsule.count of std::vector<Eigen::Vector3d> with 9008 elements.
Use numpy.asarray() to access data.>
reload <bound method PyCapsule.count of std::vector<Eigen::Vector3i> with 3336 elements.
Use numpy.asarray() to access data.>
roated <bound method PyCapsule.count of std::vector<Eigen::Vector3d> with 9008 elements.
Use numpy.asarray() to access data.>
roated <bound method PyCapsule.count of std::vector<Eigen::Vector3i> with 3336 elements.
Use numpy.asarray() to access data.>
roated <bound method PyCapsule.count of std::vector<Eigen::Vector3d> with 9008 elements.
Use numpy.asarray() to access data.>
roated <bound method PyCapsule.count of std::vector<Eigen::Vector3i> with 3336 elements.
Use numpy.asarray() to access data.>
rotated and reload <bound method PyCapsule.count of std::vector<Eigen::Vector3d> with 9009 elements.
Use numpy.asarray() to access data.>
rotated and reload <bound method PyCapsule.count of std::vector<Eigen::Vector3i> with 3336 elements.
Use numpy.asarray() to access data.>
best regards
Same problem. This is really serious and drive me crazy dealing with labelled data.
The reason is a hardcoded postprocessing flag which is always set even if enable_post_processing
parameter of read_triangle_mesh
is set to enable_post_processing=False
. This can not be turned off. And there is no real documentation what postprocessing does. Details see #6137 for more details.
EDIT
Its really at the worst, having to avoid read_triangle_mesh cause of libassimp
use.
See my solution under #6137. Any input and extension adding support for textures and combination of textures and vertex colors very welcome.
ps.: consider upvoting https://github.com/assimp/assimp/issues/5091 and motivating other to upvote in order to make libassimp team aware of the problems their loading approach causes to others.