使用Open3D与Trimesh读取同一.obj文件顶点数差异原因排查
我分别使用Open3D和Trimesh模块读取同一OBJ网格文件,代码如下:
import open3d as o3d import trimesh mesh = o3d.io.read_triangle_mesh(meshfile) print(mesh) mesh_ = trimesh.load_mesh(meshfile) print(mesh_)
输出结果为:
TriangleMesh with 224946 points and 74996 triangles. <trimesh.Trimesh(vertices.shape=(37486, 3), faces.shape=(74996, 3))>
可见Open3D获取到224946个顶点,而Trimesh仅获取到37486个顶点,二者三角形数量均为74996。我输出了两者的顶点与三角面数据:
____mesh_vert____: [[-0.77349651 -0.17361518 -0.5339487 ] [-0.77405303 -0.17450994 -0.52660068] [-0.77472924 -0.17558702 -0.51311542] ... [ 0.85712222 0.03432839 0.45968683] [ 0.8533449 0.04001502 0.4399732 ] [ 0.85333683 0.04001284 0.44043044]] ____mesh_vertices____: [[-0.77714473 -0.16696896 -0.52666056] [-0.77481598 -0.16823091 -0.53799069] [-0.77349651 -0.17361517 -0.53394872] ... [ 0.85654795 0.03840274 0.44923028] [ 0.85598844 0.03371801 0.43383372] [ 0.85334492 0.04001502 0.43997321]] ____mesh_triangles____: [[ 0 1 2] [ 3 4 5] [ 6 7 8] ... [224937 224938 224939] [224940 224941 224942] [224943 224944 224945]] ____mesh_faces____: [[ 8 7 0] [ 0 1 8] [ 9 8 1] ... [37465 37466 37485] [37484 37485 37482] [37482 37481 37484]]
请问造成该顶点数差异的原因是什么?
解答:
核心原因是两个库对OBJ文件中顶点属性(如UV、法线)的处理逻辑不同:
Open3D默认保留所有带不同属性的顶点副本:OBJ文件中,同一个空间位置的顶点如果绑定了不同的UV坐标或法线,会被拆分成多个独立顶点存储。比如一个顶点在不同三角面里有不同的UV,Open3D会把它当成多个顶点,这就导致顶点数大幅增加,和三角面的顶点索引一一对应。
Trimesh默认合并空间位置完全相同的顶点:不管顶点的UV、法线属性是否不同,只要空间坐标一致,Trimesh就会自动合并成一个顶点,同时调整三角面的索引指向合并后的顶点。这就是为什么Trimesh的顶点数远少于Open3D,但三角面数量不变。
从输出的三角面数据也能佐证这点:Open3D的三角面索引是连续递增的(每个三角面用3个新索引),而Trimesh的索引是重复复用的,说明很多顶点被合并了。
如果要让Open3D的顶点数和Trimesh一致,可以调用mesh.remove_duplicated_vertices()方法合并重复顶点;如果要让Trimesh保留所有属性拆分的顶点,可以在加载时指定process=False参数:trimesh.load_mesh(meshfile, process=False)。
内容的提问来源于stack exchange,提问作者Keddrick Yue

