Trimesh를 이용해 obj 파일을 읽고, 편집 후 다시 export하는 과정에서 texture가 제대로 읽히고 저장되지 않는 문제가 있다.
obj file을 열어보면 vt 값도 제대로 있고 mtllib 또한 제대로 적혀있는데 texture가 안 읽어지거나 export 했을 때 texture map이 2x2 크기로 아무 쓰레기 값이 저장되는 상황이다.
mesh.export(..., file_type="obj", include_texture=True) 와 같이 argument를 True로 추가해도 해결되지 않는다.
Meshlab에 띄워보면 제대로 텍스처가 보이지만, trimesh로 볼 때만 안 나온다.
원인
이건 obj 파일 내부에 usemtl가 안 적혀있어서 그렇다!
trimesh가 texture loading/exporting에 실패하는 obj 파일을 보며 다음과 같다.
mtllib 014_10.mtl
v 0.364628 0.706690 0.619341
vt 0.363149 0.691417
v 0.361774 0.702356 0.620328
vt 0.363029 0.692200
v 0.361140 0.704966 0.615271
vt 0.362142 0.691814
v 0.300841 0.573348 0.550008
vt 0.652325 0.852502
...
mtl 파일이 명시되어 있기 때문에 meshlab 같은 툴에서는 그냥 알아서 읽는데, trimesh는 usemtl 이라는 추가되어야 한다.
해결법
usemtl 014_10
mtllib 014_10.mtl
v 0.364628 0.706690 0.619341
vt 0.363149 0.691417
v 0.361774 0.702356 0.620328
vt 0.363029 0.692200
v 0.361140 0.704966 0.615271
vt 0.362142 0.691814
v 0.300841 0.573348 0.550008
vt 0.652325 0.852502
...
위와 같이 첫줄에 usemtl 하고 파일명을 제대로 적어주어야 trimesh에서 읽을 수 있다.
with open(scan_path, 'r') as f:
lines = f.readlines()
with open(scan_path, 'w') as f:
f.write(f"usemtl {subj_name}\n")
f.writelines(lines)
이런 식으로 덮어쓰기 해주면 된다. (덮어쓰기 전에 혹시 모르니 테스트해보고 원본 파일 날려먹는 일 없게 하자.)
Note 1
위와 같이 했는데도 mtl, texture가 제대로 안 읽히고 써지는 문제를 발견했다. 그건 이름 문제였다. trimesh는 기본적으로 obj, mtl, jpg/png가 같은 이름으로 맞춰져 있어야 하나보다.
Note 2
이름도 다르고 usemtl도 기록 안되어 있는데 잘되는 샘플이 있다... 도대체 원인이 뭐지...
'Trouble > Vision' 카테고리의 다른 글
Open3D rendering 시 이미지 중심/principal point 안 맞는 문제 (0) | 2024.11.05 |
---|---|
pymeshlab decimation 안되는 버그 (0) | 2024.09.11 |
Open3d mesh wrong vertex count, face order (Open3d mesh 제멋대로 읽혀질 때) (0) | 2024.08.07 |
Open3D OBJ texture 안 보일 때, enable_post_processing=True로 해결 안 될 때, texture가 검정색으로 뜰 때 확인 사항 (0) | 2024.07.09 |
Opencv cornerSubPix empty array 문제 (0) | 2024.02.27 |