Trouble/Vision

Trimesh load_mesh, export 시 texture 제대로 안 읽히고 저장 안될 때

침닦는수건 2024. 9. 2. 15:47
반응형

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도 기록 안되어 있는데 잘되는 샘플이 있다... 도대체 원인이 뭐지...

반응형