def load_textures(filename_obj, filename_mtl, texture_res): # load vertices vertices = [] with open(filename_obj) as f: lines = f.readlines() for line in lines: if len(line.split()) == 0: continue if line.split()[0] == 'vt': vertices.append([float(v) for v in line.split()[1:3]]) vertices = np.vstack(vertices).astype(np.float32) # load faces for textures faces = [] material_names = [] material_name = '' for line in lines: if len(line.split()) == 0: continue if line.split()[0] == 'f': vs = line.split()[1:] nv = len(vs) if '/' in vs[0] and '//' not in vs[0]: # index of vt v0 = int(vs[0].split('/')[1]) else: v0 = 0 for i in range(nv - 2): if '/' in vs[i + 1] and '//' not in vs[i + 1]: v1 = int(vs[i + 1].split('/')[1]) else: v1 = 0 if '/' in vs[i + 2] and '//' not in vs[i + 2]: v2 = int(vs[i + 2].split('/')[1]) else: v2 = 0 faces.append((v0, v1, v2)) material_names.append(material_name) if line.split()[0] == 'usemtl': material_name = line.split()[1] faces = np.vstack(faces).astype(np.int32) - 1 # faces: [BS, # of faces, 3 (idx of faces), UV value] faces = vertices[faces] faces = torch.from_numpy(faces).cuda() faces[1 < faces] = faces[1 < faces] % 1 colors, texture_filenames = load_mtl(filename_mtl) textures = torch.ones(faces.shape[0], texture_res**2, 3, dtype=torch.float32) textures = textures.cuda() # for material_name, color in list(colors.items()): color = torch.from_numpy(color).cuda() for i, material_name_f in enumerate(material_names): if material_name == material_name_f: textures[i, :, :] = color[None, :] for material_name, filename_texture in list(texture_filenames.items()): filename_texture = os.path.join(os.path.dirname(filename_obj), filename_texture) image = imread(filename_texture).astype(np.float32) / 255. # texture image may have one channel (grey color) if len(image.shape) == 2: image = np.stack((image, ) * 3, -1) # or has extral alpha channel should ignore for now if image.shape[2] == 4: image = image[:, :, :3] # pytorch does not support negative slicing for the moment image = image[::-1, :, :] image = torch.from_numpy(image.copy()).cuda() is_update = (np.array(material_names) == material_name).astype( np.int32) is_update = torch.from_numpy(is_update).cuda() textures = load_textures_cuda.load_textures(image, faces, textures, is_update) return textures
def load_textures(filename_obj, filename_mtl, texture_res): # load vertices vertices = [] with open(filename_obj) as f: lines = f.readlines() for line in lines: if len(line.split()) == 0: continue if line.split()[0] == 'vt': vertices.append([float(v) for v in line.split()[1:3]]) vertices = np.vstack(vertices).astype(np.float32) # load faces for textures faces = [] material_names = [] material_name = '' for line in lines: if len(line.split()) == 0: continue if line.split()[0] == 'f': vs = line.split()[1:] nv = len(vs) if '/' in vs[0] and '//' not in vs[0]: v0 = int(vs[0].split('/')[1]) else: v0 = 0 for i in range(nv - 2): if '/' in vs[i + 1] and '//' not in vs[i + 1]: v1 = int(vs[i + 1].split('/')[1]) else: v1 = 0 if '/' in vs[i + 2] and '//' not in vs[i + 2]: v2 = int(vs[i + 2].split('/')[1]) else: v2 = 0 faces.append((v0, v1, v2)) material_names.append(material_name) if line.split()[0] == 'usemtl': material_name = line.split()[1] faces = np.vstack(faces).astype(np.int32) - 1 faces = vertices[faces] faces = jt.array(faces).float32() colors, texture_filenames = load_mtl(filename_mtl) textures = jt.ones((faces.shape[0], texture_res**2, 3), dtype="float32") for material_name, color in colors.items(): color = jt.array(color).float32() for i, material_name_f in enumerate(material_names): if material_name == material_name_f: textures[i, :, :] = color.unsqueeze(0) for material_name, filename_texture in texture_filenames.items(): filename_texture = os.path.join(os.path.dirname(filename_obj), filename_texture) image = imread(filename_texture).astype(np.float32) / 255. # texture image may have one channel (grey color) if len(image.shape) == 2: image = np.stack((image, ) * 3, -1) # or has extral alpha channel shoule ignore for now if image.shape[2] == 4: image = image[:, :, :3] image = image[::-1, :, :] image = jt.array(image.copy()).float32() is_update = (np.array(material_names) == material_name).astype( np.int32) is_update = jt.array(is_update).int() textures = load_textures_cuda.load_textures(image, faces, textures, is_update) return textures