def plot_mesh(*meshes: Union[T_Mesh, str], save_path: str = '', ambient_color: T = T((255., 200, 255.)), light_dir: T = T((.5, .5, 1))): np_images = [render_mesh(mesh, ambient_color, light_dir) for mesh in meshes] im = make_pretty(np_images) if save_path: save_path = files_utils.add_suffix(save_path, '.png') files_utils.init_folders(save_path) im.save(save_path) return im
def export_mesh(mesh: Union[V_Mesh, T_Mesh], file_name: str): vs, faces = to(mesh, CPU) file_name = add_suffix(file_name, '.obj') init_folders(file_name) if faces is not None: faces = faces + 1 with open(file_name, 'w') as f: for vi, v in enumerate(vs): f.write("v %f %f %f\n" % (v[0], v[1], v[2])) if faces is not None: for face_id in range(faces.shape[0] - 1): f.write("f %d %d %d\n" % (faces[face_id][0], faces[face_id][1], faces[face_id][2])) f.write("f %d %d %d" % (faces[-1][0], faces[-1][1], faces[-1][2]))
def load_mesh(file_name: str) -> T_Mesh: def off_parser(): header = None def parser_(clean_line: list): nonlocal header if not clean_line: return False if len(clean_line) == 3 and not header: header = True elif len(clean_line) == 3: return 0, 0, float elif len(clean_line) > 3: return 1, -int(clean_line[0]), int return parser_ def obj_parser(clean_line: list): if not clean_line: return False elif clean_line[0] == 'v': return 0, 1, float elif clean_line[0] == 'f': return 1, 1, int def fetch(lst: list, idx: int, dtype: type): if '/' in lst[idx]: lst = [item.split('/')[0] for item in lst[idx:]] idx = 0 face_vs_ids = [dtype(c.split('/')[0]) for c in lst[idx:]] assert (len(face_vs_ids) == 3) return face_vs_ids def load_from_txt(parser) -> tuple: mesh_ = [[], []] with open(file_name, 'r') as f: for line in f: clean_line = line.strip().split() info = parser(clean_line) if not info: continue mesh_[info[0]].append(fetch(clean_line, info[1], info[2])) mesh_ = [T(mesh_[0]).float(), T(mesh_[1]).long()] if mesh_[1].min() != 0: mesh_[1] -= 1 return tuple(mesh_) for suffix in ['.obj', '.off']: file_name_tmp = add_suffix(file_name, suffix) if os.path.isfile(file_name_tmp): file_name = file_name_tmp break name, extension = os.path.splitext(file_name) if extension == '.obj': mesh = load_from_txt(obj_parser) elif extension == '.off': mesh = load_from_txt(off_parser()) else: raise ValueError(f'mesh file {file_name} is not supported') assert ((mesh[1] >= 0) * (mesh[1] < len(mesh[0]))).all() return mesh