def uniquified_mesh(self): """This function returns a copy of the mesh in which vertices are copied such that each vertex appears in only one face, and hence has only one texture""" import numpy as np from lace.mesh import Mesh new_mesh = Mesh(v=self.v[self.f.flatten()], f=np.array(range(len(self.f.flatten()))).reshape(-1, 3)) if self.vn is None: self.reset_normals() new_mesh.vn = self.vn[self.f.flatten()] if self.vt is not None: new_mesh.vt = self.vt[self.ft.flatten()] new_mesh.ft = new_mesh.f.copy() return new_mesh
def _load(fd, mesh=None): from collections import OrderedDict from baiji import s3 from lace.mesh import Mesh from lace.cache import sc import lace.serialization.obj.objutils as objutils # pylint: disable=no-name-in-module v, vt, vn, vc, f, ft, fn, mtl_path, landm, segm = objutils.read(fd.name) if not mesh: mesh = Mesh() if v.size != 0: mesh.v = v if f.size != 0: mesh.f = f if vn.size != 0: mesh.vn = vn if vt.size != 0: mesh.vt = vt if vc.size != 0: mesh.vc = vc if fn.size != 0: mesh.fn = fn if ft.size != 0: mesh.ft = ft if segm: mesh.segm = OrderedDict([(k, v if isinstance(v, list) else v.tolist()) for k, v in segm.items()]) def path_relative_to_mesh(filename): # The OBJ file we're loading may have come from a local path, an s3 url, # or a file cached by sc. Since OBJ defines materials and texture files # with paths relative to the OBJ itself, we need to cope with the various # possibilities and if it's a cached file make sure that the material and # texture have been downloaded as well. # # If an absolute path is given and the file is missing, try looking in the same directory; # this lets you find the most common intention when an abs path is used. # # NB: We do not support loading material & texture info from objs read # from filelike objects without a location on the filesystem; what would # the relative file names mean in that case, anyway? (unless we're given # a valid absolute path, in which case go for it) import os import re # The second term here let's us detect windows absolute paths when we're running on posix if filename == os.path.abspath(filename) or re.match( r'^.\:(\\|/)', filename): if s3.exists(filename): return filename else: filename = s3.path.basename(filename) if hasattr(fd, 'remotename'): mesh_path = fd.remotename elif hasattr(fd, 'name'): mesh_path = fd.name else: return None path = s3.path.join(s3.path.dirname(mesh_path), filename) if sc.is_cachefile(mesh_path): try: return sc(path) except s3.KeyNotFound: return None return path mesh.materials_filepath = None if mtl_path: materials_filepath = path_relative_to_mesh(mtl_path.strip()) if materials_filepath and s3.exists(materials_filepath): with s3.open(materials_filepath, 'r') as f: mesh.materials_file = f.readlines() mesh.materials_filepath = materials_filepath if hasattr(mesh, 'materials_file'): mesh.texture_filepaths = { line.split(None, 1)[0].strip(): path_relative_to_mesh(line.split(None, 1)[1].strip()) for line in mesh.materials_file if line.startswith('map_K') } if 'map_Ka' in mesh.texture_filepaths: mesh.texture_filepath = mesh.texture_filepaths['map_Ka'] elif 'map_Kd' in mesh.texture_filepaths: mesh.texture_filepath = mesh.texture_filepaths['map_Kd'] if landm: mesh.landm = landm return mesh