open3D工具包很好用,可是在我使用过程当中发现目前(0.12.0版本)中 o3d.io.read_triangle_mesh函数不能正常读取.ply文件中的纹理及其对应坐标,须要进行手动添加。python
import open3d as o3d mesh = o3d.io.read_triangle_mesh(file_path) mesh.compute_vertex_normals()
纹理图片已知,用一句便可读入:git
mesh.textures = [o3d.io.read_image(texture_path)]
纹理对应坐标是一个(3*triangle_num, 2)的数组,能够参考这篇帖子。我是使用另外一个包叫plyfile,读.ply里面的数据出来而后作处理的。将其赋值给mesh的trianlges_uvs属性github
mesh.triangle_uvs = o3d.utility.Vector2dVector(uv)
本觉得这样就完成了,可是在使用draw_geometries的时候并不能正确绘图,报错:数组
Process finished with exit code -1073741819 (0xC0000005)
后来在github和stack overflow里面找了很久,终于被我找到了端倪,原来还要定义一个mesh的属性,triangle_material_ids,缘由是在0.10.0版本以后每隔mesh能够同时有多个纹理文件(这大概也是为何前面在定义纹理图片的时候是使用的list做为输入)。函数
既然知道了缘由就好办了,总之就是要定义一下这个属性,通过大胆猜想,应该就是全给个0(表示都用第一个纹理文件)就好了:工具
mesh.triangle_material_ids = o3d.utility.IntVector(np.zeros((len(mesh.triangles),)).astype(int))
o3d.visualization.draw_geometries([mesh])
总结一下,一个带有纹理的mesh想要正确输出,必须包含如下几个属性:spa
---------------------------------3d
最后放一段代码,供参考(里面的v_uv实在没有耐心写了,就写了两个面)code
import numpy as np import open3d as o3d vert=[[0,0,0],[0,1,0],[1,1,0],[1,0,0], [0,0,1],[0,1,1],[1,1,1],[1,0,1]] faces=[[0, 1, 2], [0, 2, 3], [6, 5, 4], [7, 6, 4], [5, 1, 0], [0, 4, 5], [3, 2, 6], [6, 7, 3], [0, 3, 7], [0, 7, 4], [1, 5, 6], [1, 6, 2]] m=o3d.geometry.TriangleMesh(o3d.utility.Vector3dVector(vert), o3d.utility.Vector3iVector(faces))
m.textures=[o3d.io.read_image('QwIKM.png')] DX,DY=0.5/2,0.66/2 v_uv=[[DX,DY],[DX,2*DY],[2*DX,2*DY], [DX,DY],[2*DX,2*DY],[2*DX,DY], [3*DX,2*DY],[4*DX,2*DY],[4*DX,DY], [3*DX,DY],[3*DX,2*DY],[4*DX,DY], [0,DX],[DX,1],[0,DX], [DX,1],[3*DX,2*DY],[3*DX,DY], [0,DX],[DX,1],[0,DX], [DX,1],[3*DX,2*DY],[3*DX,DY], [0,DX],[DX,1],[0,DX], [DX,1],[3*DX,2*DY],[3*DX,DY], [0,DX],[DX,1],[0,DX], [DX,1],[3*DX,2*DY],[3*DX,DY]] v_uv=np.asarray(v_uv) m.triangle_uvs = o3d.utility.Vector2dVector(v_uv)
m.triangle_material_ids = o3d.utility.IntVector(np.zeros((len(m.triangles),)).astype(int))
m.compute_vertex_normals() o3d.visualization.draw_geometries([m])