def export_triangles(path, Cs, Qs, inds, ray_ind): F = len(inds) V = 3 * F verts = zeros((V, 3), np.float32) faces = zeros((F, 3), np.uint32) for j, i in enumerate(inds): a, b, c = 3 * j, 3 * j + 1, 3 * j + 2 faces[j] = a, b, c v1, v2 = Qs[i], Qs[i + 1] verts[a] = Cs[i] verts[b] = Cs[i] + 2 * v1 verts[c] = Cs[i] + 2 * v2 IO.write_ply(path, verts=verts, faces=faces) vert3 = zeros((3, 3), np.float32) face3 = zeros((1, 3), np.uint32) v1, v2 = Qs[ray_ind], Qs[ray_ind + 1] vert3[0] = Cs[ray_ind] vert3[1] = Cs[ray_ind] + 2 * v1 vert3[2] = Cs[ray_ind] + 2 * v2 face3[:] = 0, 1, 2 IO.write_ply('tmp/cluster_main.ply', verts=vert3, faces=face3)
def reconstruct(seq, sub, cloud, config, scale=1.0): stat_path = os.path.join(seq, sub, 'segment_stats.npz') poly_path = os.path.join(seq, sub, 'poly_data.npz') # soft_dir = os.path.join(seq, 'soft_' + sub) # --- Load data --- npz = np.load(stat_path) depths = npz['depths'] score = npz['score'] radii = npz['radii'] edge_angles = npz['edge_angles'] inlier_frac = npz['inlier_frac'] neighbors = npz['neighbors'] neighbor_count = npz['neighbor_count'] reciprocated = npz['reciprocated'] # --- Prepare vars --- N = cloud.N # Valid inds start at zero. Invalids are -1 frames = cloud.frames Cs, Qs, Ns = cloud.global_rays() planes = empty((N, 4), Qs.dtype) planes[:, :3] = Ns planes[:, 3] = -(Cs * Ns).sum(axis=1) max_error = 5e-2 # --- Filter inds --- abradii = np.abs(radii) min_score = config.min_score min_radius = config.min_radius * scale min_neighbors = config.min_neighbors min_inlier = config.min_inlier max_inlier = config.max_inlier confident = (score >= min_score) & (abradii > min_radius) & ( abradii < 100) & (neighbor_count > min_neighbors) & ( inlier_frac > min_inlier) & (inlier_frac < max_inlier) inds = np.where(confident)[0] print(score.shape, cloud.N) # --- Pull out the lines and export them ---- Pa = Cs[inds] + depths[inds, 0:1] * Qs[inds] Pb = Cs[inds] + depths[inds, 1:2] * Qs[inds + 1] # Read in the fitted polylines, and remove any segments that come print("Filtering nearby") nearby = np.empty(0, int) # nearby = filter_nearby_segments(Pa, Pb, verts, starts, sizes, min_dist=1e-2, min_angle=25) # nearby = inds[nearby] print("Done", len(nearby)) # Filter outside bounding box bbox_min, bbox_max = cloud.bbox_min, cloud.bbox_max print(bbox_min, bbox_max) outside = inds[~((Pa > bbox_min).all(axis=1) & (Pa < bbox_max).all(axis=1) & (Pb > bbox_min).all(axis=1) & (Pb < bbox_max).all(axis=1))] # sel = inds[bad] filt = confident filt[nearby] = False filt[outside] = False sel = np.where(filt)[0] P1 = Cs[sel] + depths[sel, 0:1] * Qs[sel] P2 = Cs[sel] + depths[sel, 1:2] * Qs[sel + 1] print("Saving {} edges".format(len(sel))) Ps = np.vstack((P1, P2)) Es = np.r_[0:len(Ps)].reshape(2, -1).T normals = np.vstack((Ns[sel], Ns[sel])) # mesh = Render.Mesh() # mesh.verts = Ps.astype(np.float32) # mesh.edges = Es.astype(np.uint32) # mesh.normals = Ns[sel].astype(np.float32) # mesh_out = os.path.join(seq, 'occlusion_mesh.npz') # Render.save_mesh(mesh_out, mesh) # datapath = os.path.join(seq, 'occlusion_data.npz') # np.savez(datapath, verts=Ps, edges=Es, inds=sel, score=min_score, radius=min_radius, neighbor_count=min_neighbors, inlier=min_inlier) cloud_out = os.path.join(seq, sub, 'nonpersistent.ply') IO.write_ply(cloud_out, Ps, edges=Es, normals=normals) print("Cloud saved")