def viz_map_on_shapes(self, uv_bool=0, axis=0): if uv_bool: uv_s = viz_textmap(self.p_s) uv_t = uv_s[self.pmap] p6 = mp.plot(self.p_s, self.f_s, uv=uv_s) p5 = mp.plot(self.p_t, self.f_t, uv=uv_t) else: colmap_s = self.p_s[:, axis] #*p_s[:, 1] colmap_t = colmap_s[self.pmap] #[:-1] p6 = mp.plot(self.p_s, self.f_s, c=colmap_s) p5 = mp.plot(self.p_t, self.f_t, c=colmap_t) return
def gen_mshplot_html(brain, head, out_html, *distresults): ''' Function to generate a QC interactive HTML page rendering mesh: SurfaceMesh object for mesh to render *distresults: DistResult objects to render as lines on top of mesh ''' # Render brain model (will need sulcal information)? think about it p = mp.plot(brain.coords, brain.triangles, c=np.array([0.8, 0.8, 0.8])) # Render head model # Need to add material modification since meshplot limits shader options p.add_mesh(head.coords, head.triangles, c=np.array([0.87, 0.65, 0.4])) p._Viewer__objects[1]['material'].transparent = True p._Viewer__objects[1]['material'].opacity = 0.5 p._Viewer__objects[1]['material'].metalness = 0.1 source_lines = np.array([d.source for d in distresults]) target_lines = np.array([d.target for d in distresults]) p.add_lines(source_lines, target_lines, shading={ "line_width": 20, "line_color": "black" }) # Add text to visualization # text_adds = [ # f"Source: {d.source}, Target: {d.target}, Distance: {d.distance}" # for d in distresults # ] # [p.add_text(t) for t in text_adds] p.save(out_html)
def gen_mshplot_html(brain, head, texture, line, out_html): ''' Generate a visualization of the centroid to head projection problem Arguments: brain: SurfaceMesh of brain head: SurfaceMesh of head texture: Texture to apply to brain line: DistResult object for line to visualize projection ''' p = mp.plot(brain.coords, brain.triangles, c=texture) p.add_mesh(head.coords, head.triangles, c=np.array([0.7, 0.7, 0.7])) p._Viewer__objects[1]['material'].transparent = True p._Viewer__objects[1]['material'].opacity = 0.5 p._Viewer__objects[1]['material'].metalness = 0.1 source_line = np.array([line.source]) target_line = np.array([line.target]) p.add_lines(source_line, target_line, shading={ "line_width": 20, "line_color": "black" }) p.save(out_html)
def save_html(self, file_stem, output_folder): v, f, facet_colors = self.load_data(file_stem) if v is None: print(f"The data for {file_stem} could not be loaded. Skipping") return output_pathname = output_folder / (file_stem + ".html") mp.offline() p = mp.plot(v, f, c=facet_colors) p.save(str(output_pathname))
def plt_mesh_square(vertices, faces, xmax): m = np.array([-xmax, -xmax, -xmax]) ma = np.abs(m) # Corners of the bounding box v_box = np.array([[-xmax, -xmax, 0], [-xmax, xmax, 0], [xmax, xmax, 0], [xmax, -xmax, 0]]) # Edges of the bounding box f_box = np.array([[0, 1], [1, 2], [2, 3], [3, 0]], dtype=np.int) p = meshplot.plot(vertices, faces, return_plot=True) # plot body p.add_edges(v_box, f_box, shading={"line_color": "red"}) #p.add_points(v_box, shading={"point_color": "green"}) return p
def gen_mshplot_html(brain, texture, param_surf, out_html): ''' Generate a visualization of the centroid to head projection problem Arguments: brain: SurfaceMesh of brain param_surf: Parameteric surface to visualize out_html: Output HTML file ''' p = mp.plot(brain.coords, brain.triangles, c=texture) p.add_mesh(param_surf.coords, param_surf.triangles, c=np.array([0.7, 0.7, 0.7])) p._Viewer__objects[1]['material'].transparent = True p._Viewer__objects[1]['material'].opacity = 0.5 p._Viewer__objects[1]['material'].metalness = 0.1 p.save(out_html)
def plt_mesh(vertices, faces, xmax): m = np.array([-xmax, -xmax, -xmax]) ma = np.abs(m) # Corners of the bounding box v_box = np.array([[m[0], m[1], m[2]], [ma[0], m[1], m[2]], [ma[0], ma[1], m[2]], [m[0], ma[1], m[2]], [m[0], m[1], ma[2]], [ma[0], m[1], ma[2]], [ma[0], ma[1], ma[2]], [m[0], ma[1], ma[2]]]) # Edges of the bounding box f_box = np.array([[0, 1], [1, 2], [2, 3], [3, 0], [4, 5], [5, 6], [6, 7], [7, 4], [0, 4], [1, 5], [2, 6], [7, 3]], dtype=np.int) p = meshplot.plot(vertices, faces, return_plot=True) # plot body p.add_edges(v_box, f_box, shading={"line_color": "red"}) #p.add_points(v_box, shading={"point_color": "green"}) return p
import igl import meshplot meshplot.offline() import numpy as np import os root_folder = os.getcwd() v, f = igl.read_triangle_mesh( os.path.join(root_folder, "data", "armadillo.obj")) #sample points on a 64x64x64 grid n = 64 K = np.linspace(-1.0, 1.0, n) pts = np.array([[x, y, z] for x in K for y in K for z in K]) S, _, _ = igl.signed_distance( pts, v, f, sign_type=igl.SIGNED_DISTANCE_TYPE_FAST_WINDING_NUMBER) nV, nF = igl.marching_cubes(S, pts, n, n, n, 0.0) meshplot.plot(nV, nF)
#workspace initialization x, y, z = np.ogrid[-30:30:100j, -30:30:100j, -30:30:100j] #voxel dimensions gx = 60 / 100 gy = 60 / 100 gz = 60 / 100 #CSG tree s = Sphere(Point(5, 6, 0), 9) b = Box(Frame.worldXY(), 20, 15, 10) vs = VolSphere(s) vb = VolBox(b, 2.5) u = Subtraction(vs, vb) #sampling dm = u.get_distance_numpy(x, y, z) #generate isosurface v, f, n, l = marching_cubes(dm, 0, spacing=(gx, gy, gz)) #display mesh mp.plot(v, f, c=np.array([0, 0.57, 0.82]), shading={ "flat": False, "roughness": 0.4, "metalness": 0.01, "reflectivity": 1.0 })
def view_segmentation(self, file_stem): v, f, facet_colors = self.load_data(file_stem) if v is None: print(f"The data for {file_stem} could not be loaded") return p = mp.plot(v, f, c=facet_colors)
points, sdf = sample_sdf_near_surface(mesh, number_of_points=300000) with open("data/chair.npy", 'wb') as f: np.save(f, points) np.save(f, sdf) # colors = np.zeros(points.shape) # colors[sdf < 0, 2] = 1 # colors[sdf > 0, 0] = 1 # cloud = pyrender.Mesh.from_points(points, colors=colors) # scene = pyrender.Scene() # scene.add(cloud) # viewer = pyrender.Viewer(scene, use_raymond_lighting=True, point_size=2) # Rendering with meshplot mesh = scale_to_unit_sphere(mesh) points, sdf = sample_sdf_near_surface(mesh, number_of_points=250000) p = meshplot.plot(mesh.vertices, mesh.faces, filename="debug/test_pointsampling.html") p.add_points(points, c=sdf, shading={ "point_size": 0.08, "alpha": 0.3, "normalize": [True, True], "colormap": "jet" }) p.save("debug/test_pointsampling.html")
def show(self): meshplot.plot(self.V, self.F)
new_squannit = cor_volume(squannit) p = plt_mesh_square(new_squannit.vertices, new_squannit.faces, xmax) # In[57]: xrot = np.array([1, 0, 0]) vrot = rotate_vertices(new_squannit.vertices, xrot, np.pi / 2) p = plt_mesh_square(vrot, new_squannit.faces, xmax) # In[69]: # reduce the number of faces to something reasonable short_squannit1, info = pymesh.collapse_short_edges( new_squannit, 0.219) # if bigger then fewer faces nf_mesh(short_squannit1) meshplot.plot(short_squannit1.vertices, short_squannit1.faces) short_squannit2, info = pymesh.collapse_short_edges( new_squannit, 0.17) # if bigger then fewer faces nf_mesh(short_squannit2) meshplot.plot(short_squannit2.vertices, short_squannit2.faces) # In[70]: p = plt_mesh_square(short_squannit2.vertices, short_squannit2.faces, xmax) # In[71]: xrot = np.array([1, 0, 0]) vrot = rotate_vertices(short_squannit2.vertices, xrot, np.pi / 2) p = plt_mesh_square(vrot, short_squannit2.faces, xmax)
def main(): meshplot.offline() device = 'cuda' if torch.cuda.is_available() else 'cpu' parser = argparse.ArgumentParser() # TODO: change default values parser.add_argument("-i", "--input", help="Path to .npy file. Default: 'data/chair.npy'", default='data/chair.npy') parser.add_argument("-e", "--epochs", type=int, help="Number of training epochs. Default: 50", default=100) parser.add_argument("-b", "--batch", type=int, help="Batch size. Default: 5000", default=16384) parser.add_argument("-r", "--rate", type=float, help="learning rate. Default: 1e-4", default=1e-4) args = parser.parse_args() file_path = args.input n_epochs = args.epochs lr = args.rate bs = args.batch with open(file_path, 'rb') as f: xyz = np.load(f) dataset_size = xyz.shape[0] features = torch.from_numpy(xyz) labels = np.load(f) # balanced sampling sampler = get_balancedsampler(labels) dataset = TensorDataset(features, torch.from_numpy(labels)) trainset, valset, testset = random_split(dataset, [250000, 10000, 40000]) train_loader = DataLoader( trainset, shuffle=True, batch_size=bs) validation_loader = DataLoader( valset, shuffle=False, batch_size=bs ) test_loader = DataLoader( testset, shuffle=False, batch_size=bs ) model = SingleShapeSDF([512, 512, 512]).to(device) # loss_fn = torch.nn.MSELoss(reduction='sum') loss_fn = deepsdfloss # test_overfitting(model, train_loader, loss_fn) train_history, validation_history = test_training(model, train_loader, validation_loader, loss_fn, n_epochs=n_epochs, learning_rate=lr) model.eval() test_loss = 0 with torch.no_grad(): for i, data in enumerate(test_loader): x, y = data[0].to(device), data[1].unsqueeze(1).to(device) y_pred = model.forward(x) loss = loss_fn(y_pred, y) test_loss += loss.item() data = next(iter(test_loader)) x, y = data[0].to(device), data[1].unsqueeze(1).to(device) y_pred = model.forward(x) meshplot.plot(x.cpu().numpy(), c=y_pred.cpu().numpy(), shading={"point_size": 0.2}, filename="debug/predicted.html") meshplot.plot(x.cpu().numpy(), c=y.cpu().numpy(), shading={"point_size": 0.2}, filename="debug/target.html") print(f"TEST LOSS: {test_loss/4}") plot_training_curve(train_history, validation_history, test_loss) # TODO: validation with another metric (not deepsdf loss) # TODO: what metric do they use in the paper? visualize_voxels(model, grid_res=20) visualize_marchingcubes(model, grid_res=100) torch.save(model.state_dict(), "SingleShapeSDF-512.pt")
def viz_sp_desc_on_shapes(self, i_b, do_plot=1): self.i_b = i_b i_s = self.bi1[i_b] i_t = self.bi2[i_b] n_eig = self.n_eig print(i_s, i_t) if self.dataset == 'FAUST': # file for fetching mesh data sourcefolder = '../../../../../../../media/donati/Data1/Datasets/FAUST_r' meshname = 'tr_reg_{:03d}.off' i_s_ = i_s + 80 i_t_ = i_t + 80 p_s, f_s = readOFF( join(sourcefolder, 'off_al', meshname.format(i_s_))) p_t, f_t = readOFF( join(sourcefolder, 'off_al', meshname.format(i_t_))) print('size1 :', p_s.shape[0], 'size2 :', p_t.shape[0]) # evecs #self.ev_s = self.input_evecs[i_s] #self.ev_t = self.input_evecs[i_t] self.ev_s = sio.loadmat( join(sourcefolder, 'spectral', meshname.format(i_s_)[:-4] + '.mat'))['target_evecs'] self.ev_t = sio.loadmat( join(sourcefolder, 'spectral', meshname.format(i_t_)[:-4] + '.mat'))['target_evecs'] # spectral desc d_s = self.desc1[i_b] d_t = self.desc2[i_b] elif self.dataset == 'SCAPE': # file for fetching mesh data sourcefolder = '../../../../../../../media/donati/Data1/Datasets/SCAPE_r' meshname = 'mesh{:03d}.off' i_s_ = i_s + 52 i_t_ = i_t + 52 p_s, f_s = readOFF( join(sourcefolder, 'off_al2', meshname.format(i_s_))) p_t, f_t = readOFF( join(sourcefolder, 'off_al2', meshname.format(i_t_))) print('size1 :', p_s.shape[0], 'size2 :', p_t.shape[0]) # evecs #self.ev_s = self.input_evecs[i_s] #self.ev_t = self.input_evecs[i_t] self.ev_s = sio.loadmat( join(sourcefolder, 'spectral', meshname.format(i_s_)[:-4] + '.mat'))['target_evecs'] self.ev_t = sio.loadmat( join(sourcefolder, 'spectral', meshname.format(i_t_)[:-4] + '.mat'))['target_evecs'] # spectral desc d_s = self.desc1[i_b] d_t = self.desc2[i_b] elif self.dataset == 'SHREC': # file for fetching mesh data sourcefolder = '../../../../../../../media/donati/Data1/Datasets/SHREC_r' meshname = '{:d}.off' i_s_ = i_s + 1 i_t_ = i_t + 1 p_s, f_s = readOFF( join(sourcefolder, 'off_al2', meshname.format(i_s_))) p_t, f_t = readOFF( join(sourcefolder, 'off_al2', meshname.format(i_t_))) print('size1 :', p_s.shape[0], 'size2 :', p_t.shape[0]) # evecs #self.ev_s = self.input_evecs[i_s] #self.ev_t = self.input_evecs[i_t] self.ev_s = sio.loadmat( join(sourcefolder, 'spectral', meshname.format(i_s_)[:-4] + '.mat'))['target_evecs'] self.ev_t = sio.loadmat( join(sourcefolder, 'spectral', meshname.format(i_t_)[:-4] + '.mat'))['target_evecs'] # spectral desc d_s = self.desc1[i_b] d_t = self.desc2[i_b] else: # for surreal dfaust sourcefolder = '../../../../../../../media/donati/Data1/Datasets/surreal_dfaust' # points #p_s = input_points[i_s] #p_t = input_points[i_t] file_s = join(sourcefolder, 'points', self.testfiles[i_s]) file_t = join(sourcefolder, 'points', self.testfiles[i_t]) p_s = np.loadtxt(file_s, delimiter=' ', dtype=np.float32) p_t = np.loadtxt(file_t, delimiter=' ', dtype=np.float32) #evecs spc_data_s = sio.loadmat( join(sourcefolder, 'spectral', self.testfiles[i_s][:-4] + '.mat')) self.ev_s = spc_data_s['target_evecs'] spc_data_t = sio.loadmat( join(sourcefolder, 'spectral', self.testfiles[i_t][:-4] + '.mat')) self.ev_t = spc_data_t['target_evecs'] # spectral desc d_s = desc1[i_b] d_t = desc2[i_b] # raw desc #of_s = of1[i_b*1000: (i_b+1)*1000] #of_t = of2[i_b*1000: (i_b+1)*1000] # triangulation f = sio.loadmat( '../../../../../../../media/donati/Data1/Datasets/surreal_dfaust/TRIV2.mat' )['TRIV'] - 1 f_s = f f_t = f # colmap_s = of_s # colmap_t = of_t colmap2_s = (self.ev_s[:, :n_eig] @ d_s) # spectral desc colmap2_t = (self.ev_t[:, :n_eig] @ d_t) # spectral desc #p1 = mp.plot(p_s, f_s, colmap_s[:, 0], return_plot=True) #, s = [1, 2, 0]) #p2 = mp.plot(p_t, f_t, colmap_t[:, 0], return_plot=True) #, s = [1, 2, 1]) #p3 = mp.plot(p_s, f, colmap2_s[:, 0], return_plot=True) #, s = [1, 2, 1]) #p4 = mp.plot(p_t, f, colmap2_t[:, 0], return_plot=True) #, s = [1, 2, 1]) # Add interactive visulization #@mp.interact(level=(0, of_s.shape[1])) #def mcf(level=0): #p1.update_object(colors = colmap_s[:, level]) #p2.update_object(colors = colmap_t[:, level]) # p3.update_object(colors = colmap2_s[:, level]) # p4.update_object(colors = colmap2_t[:, level]) if do_plot: p3 = mp.plot(p_s, f_s, colmap2_s[:, 0], return_plot=True) #, s = [1, 2, 1]) p4 = mp.plot(p_t, f_t, colmap2_t[:, 0], return_plot=True) #, s = [1, 2, 1]) @mp.interact(level=(0, colmap2_s.shape[1])) def mcf(level=0): p3.update_object(colors=colmap2_s[:, level]) p4.update_object(colors=colmap2_t[:, level]) ## make the useful data part of the object self.p_s = p_s self.p_t = p_t self.f_s = f_s self.f_t = f_t self.i_s = i_s self.i_t = i_t return p_s, f_s, colmap2_s, p_t, f_t, colmap2_t
d1[v2, eId] = 1 return d1 if __name__ == '__main__': V = igl.eigen.MatrixXd() F = igl.eigen.MatrixXi() # igl.readOBJ('Circle.obj', V, F) igl.readOBJ('TorusSimplified.obj', V, F) verts = e2p(V) faces = e2p(F) mp.plot(verts, faces) print(verts.shape) print(faces.shape) mesh = Mesh(verts, faces) print(mesh.edgeIdMap) d2 = mesh.getD2() print('d2:\n', d2) d1 = mesh.getD1() print('d1:\n', d1) A = d1.astype(numpy.float64)