While using the NPHM data, I found that we can use the following code to convert .ply files to .obj files. Note that you might also need to copy texture.png into the folder where the target .obj file is located.
from plyfile import PlyData
import numpy as np
def ply_to_obj(ply_file_path, obj_file_path):
ply_data = PlyData.read(ply_file_path)
vertex_data = ply_data['vertex'].data
vertices = np.array([vertex_data['x'], vertex_data['y'], vertex_data['z']]).T
face_data = ply_data['face'].data
faces = np.array([face_data['vertex_indices'][i] for i in range(len(face_data))])
has_uv = True
uvs = np.array([list(uv) for uv in ply_data['face'].data['texcoord']], dtype=np.float32)
with open(obj_file_path, 'w') as f:
f.write(f'mtllib scan.mtl\n')
for vertex in vertices:
f.write(f'v {vertex[0]} {vertex[1]} {vertex[2]}\n')
if has_uv:
for uv in uvs:
f.write(f'vt {uv[0]} {uv[1]}\n')
f.write(f'vt {uv[2]} {uv[3]}\n')
f.write(f'vt {uv[4]} {uv[5]}\n')
count = 0
for face in faces:
if has_uv:
face_uv_indices = [i + 1 for i in face]
f.write('f '+str(face_uv_indices[0])+'/'+str(count*3+1)+' '+str(face_uv_indices[1])+'/'+str(count*3+2)+' '+str(face_uv_indices[2])+'/'+str(count*3+3)+'\n')
count = count+1
else:
face_indices = [i + 1 for i in face]
f.write(f'f {" ".join(map(str, face_indices))}\n')
with open(obj_file_path[:-4]+'.mtl', 'w') as f:
f.write(f'newmtl scan\n')
f.write(f'map_Kd texture.png\n')
Thanks for this amazing work!
While using the NPHM data, I found that we can use the following code to convert .ply files to .obj files. Note that you might also need to copy texture.png into the folder where the target .obj file is located.