Knowhow/Vision

Trimesh to Open3d TriangleMesh

침닦는수건 2024. 7. 12. 13:56
반응형

python에서 mesh 읽고 쓸 때, 대표적으로 사용하는 Trimesh와 open3d. 
 
이 둘 간의 mesh 변환을 할 때 약간의 주의 사항이 있다. 단순히 vertex와 face 구성만 변환한다면 trimesh에서 as_open3d 라는 함수를 지원해주므로 간단하지만, texture까지 옮길 때는 조금 차이가 있다. 
 

def trimesh2open3d(mesh_path, texture_path):
	mesh = trimesh.load_mesh(mesh_path)
    vertices = mesh.vertices
    faces = mesh.faces
    uvs = mesh.visual.uv
    uvs[:,1] = 1-uvs[:,1]

    triangles_uvs = []
    for i in range(3):
        triangles_uvs.append(uvs[faces[:, i]].reshape(-1, 1, 2))

    triangles_uvs = np.concatenate(triangles_uvs, axis=1).reshape(-1, 2)
    o3d_mesh = o3d.geometry.TriangleMesh()
    o3d_mesh.vertices = o3d.utility.Vector3dVector(vertices)
    o3d_mesh.triangles = o3d.utility.Vector3iVector(faces)
    o3d_mesh.triangle_uvs = o3d.utility.Vector2dVector(triangles_uvs)
    o3d_mesh.textures = [o3d.io.read_image(texture_path)]
    o3d_mesh.triangle_material_ids = o3d.utility.IntVector([0]*len(faces))
    return o3d_mesh

 

  • trimesh의 uv는 vertex uv를 제공한다. (N, 3) 형태이지만, Open3d에서는 face uv를 필요로 한다. 즉, (N*3, 3) 형태다.
  • UV 값 자체도 상하가 뒤집혀 있다. Open3d의 경우 이미지 하단 0, 상단이 1이며 trimesh는 이미지 하단이 1, 상단이 이다.
  • triangle_material_ids도 추가해주어야 한다. 
반응형