def save_reconstruction_data(imp_surf_dist_ms, dataset, model_out_dir, shape_ind): from source import sdf shape = dataset.shape_cache.get(shape_ind) imp_surf_dist_ms_nan = np.isnan(imp_surf_dist_ms) # the predicted distance would be greater than 1 -> not possible with tanh imp_surf_dist_ms[imp_surf_dist_ms_nan] = 1.0 # save query points os.makedirs(os.path.join(model_out_dir, 'query_pts_ms'), exist_ok=True) np.save( os.path.join(model_out_dir, 'query_pts_ms', dataset.shape_names[shape_ind] + '.xyz.npy'), shape.imp_surf_query_point_ms) # save query distance in model space os.makedirs(os.path.join(model_out_dir, 'dist_ms'), exist_ok=True) np.save( os.path.join(model_out_dir, 'dist_ms', dataset.shape_names[shape_ind] + '.xyz.npy'), imp_surf_dist_ms) # debug query points with color for distance os.makedirs(os.path.join(model_out_dir, 'query_pts_ms_vis'), exist_ok=True) sdf.visualize_query_points(query_pts_ms=shape.imp_surf_query_point_ms, query_dist_ms=imp_surf_dist_ms, file_out_off=os.path.join( model_out_dir, 'query_pts_ms_vis', dataset.shape_names[shape_ind] + '.ply'))
def _get_and_save_query_pts(file_in_mesh: str, file_out_query_pts: str, file_out_query_dist: str, file_out_query_vis: str, num_query_pts: int, patch_radius: float, far_query_pts_ratio=0.1, signed_distance_batch_size=1000, debug=False): import trimesh # random state for file name rng = np.random.RandomState(file_utils.filename_to_hash(file_in_mesh)) in_mesh = trimesh.load(file_in_mesh) # get query pts query_pts_ms = sdf.get_query_pts_for_mesh(in_mesh, num_query_pts, patch_radius, far_query_pts_ratio, rng) np.save(file_out_query_pts, query_pts_ms.astype(np.float32)) # get signed distance query_dist_ms = sdf.get_signed_distance(in_mesh, query_pts_ms, signed_distance_batch_size) # fix NaNs, Infs and truncate nan_ids = np.isnan(query_dist_ms) inf_ids = np.isinf(query_dist_ms) query_dist_ms[nan_ids] = 0.0 query_dist_ms[inf_ids] = 1.0 query_dist_ms[query_dist_ms < -1.0] = -1.0 query_dist_ms[query_dist_ms > 1.0] = 1.0 np.save(file_out_query_dist, query_dist_ms.astype(np.float32)) if debug and file_out_query_vis is not None: # save visualization sdf.visualize_query_points(query_pts_ms, query_dist_ms, file_out_query_vis)
def _get_and_save_query_pts( file_in_mesh: str, file_in_query_pts: str, file_out_query_dist: str, file_out_query_vis: str, signed_distance_batch_size=1000, debug=False): in_mesh = trimesh.load(file_in_mesh) # get query pts query_pts_ms = np.load(file_in_query_pts) # get signed distance query_dist_ms = sdf.get_signed_distance( in_mesh, query_pts_ms, signed_distance_batch_size) # fix NaNs, Infs and truncate nan_ids = np.isnan(query_dist_ms) inf_ids = np.isinf(query_dist_ms) query_dist_ms[nan_ids] = 0.0 query_dist_ms[inf_ids] = 1.0 query_dist_ms[query_dist_ms < -1.0] = -1.0 query_dist_ms[query_dist_ms > 1.0] = 1.0 np.save(file_out_query_dist, query_dist_ms.astype(np.float32)) if debug and file_out_query_vis is not None: # save visualization sdf.visualize_query_points(query_pts_ms, query_dist_ms, file_out_query_vis)
def _make_sdf_samples_from_pc(file_in_pts, file_in_normal, file_in_mesh, out_pc): # deviation from the surface in both directions, as described in the paper, section 6.3 eta = 0.01 # actual value is never mentioned, so we just assume something small pts = np.load(file_in_pts) pts = pts.astype(dtype=np.float32) # DeepSDF only accepts float, not double normals = np.loadtxt(file_in_normal) normals_length = np.linalg.norm(normals, axis=1) normals_length_repeated = np.repeat(np.expand_dims(normals_length, axis=1), 3, axis=1) normals_normalized = normals / normals_length_repeated # get sdf samples near the surface query_pts_pos = pts + eta * normals_normalized query_pts_neg = pts - eta * normals_normalized signed_dist_pos = np.full((query_pts_pos.shape[0],), -eta) signed_dist_neg = np.full((query_pts_neg.shape[0],), eta) # combine close points and signed distance to 4D vectors close_sdf_samples_pos = np.zeros((query_pts_pos.shape[0], 4), dtype=np.float32) close_sdf_samples_pos[:, 0:3] = query_pts_pos close_sdf_samples_pos[:, 3] = signed_dist_pos close_sdf_samples_neg = np.zeros((query_pts_neg.shape[0], 4), dtype=np.float32) close_sdf_samples_neg[:, 0:3] = query_pts_neg close_sdf_samples_neg[:, 3] = signed_dist_neg # get sdf samples in the unit cube (can be far away from the surface) far_samples_ratio = 0.2 num_far_samples = int((query_pts_pos.shape[0] + query_pts_neg.shape[0]) * far_samples_ratio) random_samples_unit_cube = np.random.rand(num_far_samples, 3) - 0.5 mesh = trimesh.load(file_in_mesh) random_samples_unit_cube_sd = sdf.get_signed_distance( in_mesh=mesh, query_pts_ms=random_samples_unit_cube, signed_distance_batch_size=1000 ) # split far sdf samples in pos and neg (inside and outside) random_samples_unit_cube_sd_ids_pos = random_samples_unit_cube_sd > 0.0 random_samples_unit_cube_sd_ids_neg = random_samples_unit_cube_sd < 0.0 random_samples_unit_cube_pos = random_samples_unit_cube[random_samples_unit_cube_sd_ids_pos] random_samples_unit_cube_sd_pos = random_samples_unit_cube_sd[random_samples_unit_cube_sd_ids_pos] random_samples_unit_cube_neg = random_samples_unit_cube[random_samples_unit_cube_sd_ids_neg] random_samples_unit_cube_sd_neg = random_samples_unit_cube_sd[random_samples_unit_cube_sd_ids_neg] # combine far points and signed distance to 4D vectors far_sdf_samples_pos = np.zeros((random_samples_unit_cube_pos.shape[0], 4), dtype=np.float32) far_sdf_samples_pos[:, 0:3] = random_samples_unit_cube_pos far_sdf_samples_pos[:, 3] = random_samples_unit_cube_sd_pos far_sdf_samples_neg = np.zeros((random_samples_unit_cube_neg.shape[0], 4), dtype=np.float32) far_sdf_samples_neg[:, 0:3] = random_samples_unit_cube_neg far_sdf_samples_neg[:, 3] = random_samples_unit_cube_sd_neg # # # cat close and far sdf samples # pc_sdf_pos = np.concatenate((close_sdf_samples_pos, far_sdf_samples_pos), axis=0) # pc_sdf_neg = np.concatenate((close_sdf_samples_neg, far_sdf_samples_neg), axis=0) # # np.savez(out_pc, pos=pc_sdf_pos, neg=pc_sdf_neg) # np.savez(out_pc, pos=close_sdf_samples_neg, neg=close_sdf_samples_pos) np.savez(out_pc, pos=close_sdf_samples_neg, neg=close_sdf_samples_pos, pos_far=far_sdf_samples_pos, neg_far=far_sdf_samples_neg) # debug: save visualization file_out_query_vis = out_pc + '.ply' # query_pts_ms = np.concatenate((query_pts_pos, query_pts_neg)) query_pts_ms = np.concatenate((query_pts_pos, query_pts_neg, random_samples_unit_cube_pos, random_samples_unit_cube_neg)) # query_dist_ms = np.concatenate((signed_dist_pos, signed_dist_neg)) query_dist_ms = np.concatenate((signed_dist_pos, signed_dist_neg, random_samples_unit_cube_sd_pos, random_samples_unit_cube_sd_neg)) sdf.visualize_query_points(query_pts_ms, query_dist_ms, file_out_query_vis) print('wrote vis to {}'.format(file_out_query_vis))
def visualize_result(pts_query_ms, dist_query_ms): out_vis_file = os.path.join(model_out_dir, 'vis', dataset.shape_names[shape_ind] + '.ply') file_utils.make_dir_for_file(out_vis_file) from source import sdf sdf.visualize_query_points(pts_query_ms, dist_query_ms, out_vis_file)