def load_textures(filename_obj, filename_mtl, texture_size): # 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]: v0 = int(vs[0].split('/')[1]) else: v0 = 0 for i in range(nv - 2): if '/' in vs[i + 1]: v1 = int(vs[i + 1].split('/')[1]) else: v1 = 0 if '/' 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 = torch.from_numpy(faces).cuda() faces[1 < faces] = faces[1 < faces] % 1 colors, texture_filenames = load_mtl(filename_mtl) textures = torch.zeros(faces.shape[0], texture_size, texture_size, texture_size, 3, dtype=torch.float32) + 0.5 textures = textures.cuda() # for material_name, color in 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, None, None, :] 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. # 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_size, texture_wrapping='REPEAT', use_bilinear=True): # 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 = torch.from_numpy(faces).cuda() colors, texture_filenames = load_mtl(filename_mtl) textures = torch.zeros(faces.shape[0], texture_size, texture_size, texture_size, 3, dtype=torch.float32) + 0.5 textures = textures.cuda() # for material_name, color in 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, None, None, :] 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] # 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, texture_wrapping_dict[texture_wrapping], use_bilinear) return textures