반응형
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도 추가해주어야 한다.
반응형
'Knowhow > Vision' 카테고리의 다른 글
Ultralytics YOLOv8 NMS 포함해서 onnx로 변환하기 (0) | 2024.07.17 |
---|---|
Open3d ray casting 쉽게 하기, 2d point to mesh intersection 찾기 (0) | 2024.07.16 |
Opencv imread/imwrite vs PIL open/save speed 및 memory 비교 (0) | 2024.06.22 |
COCO bounding box format, scale factor (0) | 2024.04.25 |
Double sphere 모델 projection-failed region (0) | 2024.02.28 |