Knowhow/Vision

obj 파일 v, vt, f 등 직접 저장하기, obj save

침닦는수건 2024. 8. 28. 18:39
반응형

obj 파일은 v, vn (normal), vt(texture uv), f 등 vertex 위치와 face 구성 외에 몇가지 정보를 같이 들고 있을 수 있다. 

https://en.wikipedia.org/wiki/Wavefront_.obj_file

 

Wavefront .obj file - Wikipedia

From Wikipedia, the free encyclopedia Geometry definition file format OBJ (or .OBJ) is a geometry definition file format first developed by Wavefront Technologies for its Advanced Visualizer animation package. The file format is open and has been adopted b

en.wikipedia.org

 

그런데 open3d 나 trimesh에 의존해서 들고 있는 obj file을 다시 저장하면 v, f만 덜렁 저장되고 나머지 값이 날아갈 때가 있다. 특히 texture uv coordinate를 저장하려고 할 때 open3d 는 texture map이 지정 안되어 있으면 write_triangle_uvs=True로 두어도 vt 값을 저장하지 않는다. 이게 종종 되게 귀찮은 상황을 많이 만든다. 

 

이런 경우 답답해서 그냥 file write로 obj 파일 포맷에 맞추어서 직접 작성하는게 더 편하다. 

 

def save_obj(obj_path, verts, faces, uvs):
    obj_name = obj_path.split("/")[-1][:-4]
    obj_dir = os.path.dirname(obj_path)
    save_path = os.path.join(obj_dir, obj_name+"_subdiv1.obj")
    faces = faces+1
    with open(save_path, 'w') as f:
        f.write(f"mtllib ./{obj_name}.obj.mtl\n")
        for item in verts:
            f.write("v {0:.5f} {1:.5f} {2:.5f}\n".format(item[0], item[1], item[2]))

        for item in uvs:
            f.write("vt {0:.5f} {1:.5f}\n".format(item[0], item[1]))

        for item in faces:
            f.write("f {0}/{0} {1}/{1} {2}/{2}\n".format(item[0], item[1], item[2]))

 

face + 1 해주는 이유는 코드 상에서 우리는 vertex index를 0부터 쓰지만 obj file format에서는 vertex index를 1부터 쓰기 때문이다.

 

mtllib로 texture mtl/png 파일이 어딨는지 직접 적어주고 vt 값도 직접 적어주는거니까 저장된 obj 파일 안에 uv 값이 사라져있을 일 없다. 

반응형