def create_objects(): from util import ensure_directory from rendering.raymarching import render_image from rendering.math import get_rotation_matrix import os ensure_directory('generated_objects/') image_filename = 'generated_objects/chair-{:03d}.png' mesh_filename = 'generated_objects/chair-{:03d}.stl' index = 0 while True: if os.path.exists(image_filename.format(index)) or os.path.exists( mesh_filename.format(index)): index += 1 continue latent_code = standard_normal_distribution.sample( (LATENT_CODE_SIZE, )).to(device) image = render_image(sdf_net, latent_code, resolution=128, sdf_offset=-SURFACE_LEVEL, ssaa=2, radius=1.4, color=(0.7, 0.7, 0.7)) image.save(image_filename.format(index)) mesh = sdf_net.get_mesh(latent_code, voxel_resolution=256, sphere_only=False, level=SURFACE_LEVEL) mesh.apply_transform(get_rotation_matrix(90, 'x')) mesh.apply_translation((0, 0, -np.min(mesh.vertices[:, 2]))) mesh.export(mesh_filename.format(index)) print("Created mesh for index {:d}".format(index)) index += 1
def sample_point_clouds(sdf_net, sample_count, point_cloud_size, voxel_resolution=128, rescale='half_unit_sphere', latent_codes=None): result = np.zeros((sample_count, point_cloud_size, 3)) if latent_codes is None: latent_codes = standard_normal_distribution.sample( (sample_count, LATENT_CODE_SIZE)).to(device) for i in tqdm(range(sample_count)): try: point_cloud = sdf_net.get_uniform_surface_points( latent_codes[i, :], point_count=point_cloud_size, voxel_resolution=voxel_resolution, sphere_only=False, level=LEVEL) rescale_point_cloud(point_cloud, method=rescale) result[i, :, :] = point_cloud except AttributeError: print("Warning: Empty mesh.") return result
def encode(self, x, return_mean_and_log_variance=False): x = x.reshape((-1, 1, 32, 32, 32)) x = self.encoder(x) if not self.is_variational: return x mean = self.encode_mean(x).squeeze() if self.training or return_mean_and_log_variance: log_variance = self.encode_log_variance(x).squeeze() standard_deviation = torch.exp(log_variance * 0.5) eps = standard_normal_distribution.sample(mean.shape).to(x.device) if self.training: x = mean + standard_deviation * eps else: x = mean if return_mean_and_log_variance: return x, mean, log_variance else: return x
sdf_net = SDFNet() sdf_net.filename = 'hybrid_gan_generator.to' sdf_net.load() sdf_net.eval() clouds = sample_point_clouds(sdf_net, 1000, 2048, voxel_resolution=32) np.save('data/generated_point_cloud_sample.npy', clouds) if 'checkpoints' in sys.argv: import glob from tqdm import tqdm torch.manual_seed(1234) files = glob.glob( 'models/checkpoints/hybrid_progressive_gan_generator_2-epoch-*.to', recursive=True) latent_codes = standard_normal_distribution.sample( (50, LATENT_CODE_SIZE)).to(device) for filename in tqdm(files): epoch_id = filename[61:-3] sdf_net = SDFNet() sdf_net.filename = filename[7:] sdf_net.load() sdf_net.eval() clouds = sample_point_clouds(sdf_net, 50, 2048, voxel_resolution=64, latent_codes=latent_codes) np.save('data/chairs/results/voxels_{:s}.npy'.format(epoch_id), clouds) if 'dataset' in sys.argv:
(STEPS - 1)) + code_end * i / (STEPS - 1) reconstructed_vae = vae.decode(codes_vae) plot = ImageGrid(STEPS) for i in range(STEPS): plot.set_voxels(reconstructed_vae[i, :, :, :], i) plot.save("plots/vae-interpolation.pdf") if "gan_tsne" in sys.argv: generator = load_generator(is_wgan='wgan' in sys.argv) from util import standard_normal_distribution shape = torch.Size([500, LATENT_CODE_SIZE]) x = standard_normal_distribution.sample(shape).to(device) with torch.no_grad(): voxels = generator(x).squeeze() codes = x.squeeze().cpu().numpy() filename = "plots/gan-images.pdf" if 'wgan' in sys.argv else "plots/wgan-images.pdf" create_tsne_plot(codes, voxels, labels=None, filename=filename) if "gan_examples" in sys.argv: generator = load_generator(is_wgan='wgan' in sys.argv) COUNT = 5 with torch.no_grad(): voxels = generator.generate(sample_size=COUNT) plot = ImageGrid(COUNT) for i in range(COUNT):
def generate(self, sample_size=1): shape = torch.Size((sample_size, LATENT_CODE_SIZE)) x = standard_normal_distribution.sample(shape).to(self.device) return self(x)
def sample_latent_codes(): latent_codes = standard_normal_distribution.sample( sample_shape=[BATCH_SIZE, LATENT_CODE_SIZE]).to(device) latent_codes = latent_codes.repeat( (1, 1, VOXEL_RESOLUTION**3)).reshape(-1, LATENT_CODE_SIZE) return latent_codes
def get_random(): return standard_normal_distribution.sample( sample_shape=(LATENT_CODE_SIZE, )).to(device)
def sample_latent_codes(current_batch_size): latent_codes = standard_normal_distribution.sample( sample_shape=[current_batch_size, LATENT_CODE_SIZE]).to(device) latent_codes = latent_codes.repeat( (1, 1, grid_points.shape[0])).reshape(-1, LATENT_CODE_SIZE) return latent_codes
SAMPLE_COUNT = 30 # Number of distinct objects to generate and interpolate between TRANSITION_FRAMES = 60 ROTATE_MODEL = False USE_HYBRID_GAN = True SURFACE_LEVEL = 0.04 if USE_HYBRID_GAN else 0.011 sdf_net = SDFNet() if USE_HYBRID_GAN: sdf_net.filename = 'hybrid_progressive_gan_generator_3.to' sdf_net.load() sdf_net.eval() if USE_HYBRID_GAN: codes = standard_normal_distribution.sample((SAMPLE_COUNT + 1, LATENT_CODE_SIZE)).numpy() else: latent_codes = torch.load(LATENT_CODES_FILENAME).detach().cpu().numpy() indices = random.sample(list(range(latent_codes.shape[0])), SAMPLE_COUNT + 1) codes = latent_codes[indices, :] codes[0, :] = codes[-1, :] # Make animation periodic spline = scipy.interpolate.CubicSpline(np.arange(SAMPLE_COUNT + 1), codes, axis=0, bc_type='periodic') def create_image_sequence(): ensure_directory('images') frame_index = 0 viewer = MeshRenderer(size=1080, start_thread=False) progress_bar = tqdm(total=SAMPLE_COUNT * TRANSITION_FRAMES) for sample_index in range(SAMPLE_COUNT):