def main(): meshes = [ ('hand', 5, 'meshes/hand_868.obj', [10, 30], False), ('fertility', 5, 'meshes/fertility/FE_10k.off', [10, 40], False), ('bunny', 1.25, 'meshes/bunny_fixed.obj', [10, 40], False), ] result_lines = [] for mesh_name, mu, filename, Ks, scaled in meshes: verts, tris = load_mesh(filename, check=False, normalize=True) print mesh_name, len(verts), len(tris) for K in Ks: t_cmh = time() Phi_cmh, D_cmh = cmm.compressed_manifold_modes( verts, tris, K, init='varimax', mu=mu, scaled=scaled, return_D=True) t_cmh = time() - t_cmh t_mh = time() Phi_mh, D_mh = cmm.manifold_harmonics( verts, tris, K, return_D=True, scaled=scaled) t_mh = time() - t_mh Phi_mh = Phi_mh.astype(np.float64) Phi_cmh = Phi_cmh.astype(np.float64) Phi_cmh[np.abs(Phi_cmh) < 1.e-7] = 0 Phi_cmh_sp = sparse.csr_matrix(Phi_cmh, dtype=np.float64) if scaled: verts_rec_cmh = np.dot(Phi_cmh, np.dot((D_cmh * Phi_cmh).T, verts)) verts_rec_mh = np.dot(Phi_mh, np.dot((D_mh * Phi_mh).T, verts)) else: verts_rec_cmh = np.dot(Phi_cmh, np.dot(Phi_cmh.T, verts)) verts_rec_mh = np.dot(Phi_mh, np.dot(Phi_mh.T, verts)) line_format = "{mesh_name} & {num_verts:>8d} & {basis} & {K:d} & {mu:>4} & {error:>6.2f} & {size:>8} & {time:>5.2f}s" result_lines.append(line_format.format( mesh_name=mesh_name, basis='MHB', K=K, mu='-', num_verts=len(verts), error=np.linalg.norm(verts_rec_mh - verts), size=sizeof_fmt(Phi_mh.nbytes), time=t_mh, )) result_lines.append(line_format.format( mesh_name=mesh_name, basis='CMB', K=K, mu='%.2f' % mu, num_verts=len(verts), error=np.linalg.norm(verts_rec_cmh - verts), size=sizeof_fmt(Phi_cmh_sp.data.nbytes + Phi_cmh_sp.indptr.nbytes + Phi_cmh_sp.indices.nbytes), time=t_cmh, )) print "------------" print "TABLE START:" print "------------" print "mesh & basis & $K$ & $\\mu$ & error & size & time" for line in result_lines: print line
def test_convergence(verts, tris, K, mu, Phi_init, algorithm, maxiter, **kwargs): logger = Logger() Phi, info = cmm.compressed_manifold_modes( verts, tris, K, mu, algorithm=algorithm, callback=logger, init=Phi_init, tol_rel=0, tol_abs=0, scaled=False, order=False, maxiter=maxiter, return_info=True, verbose=0, **kwargs) return Phi, info, logger
def main(): experiments = [ ('meshes/fertility/FE_20k.off', 6, [0., 0.25, 0.5, 1.0], 12.5), ('meshes/bimba/bimba_cvd_10k.off', 5, [0, 0.25, 0.5, 1.0], 30), ] wvs = [] for filename, K, noise_levels, mu in experiments: verts, tris = load_mesh(filename, check=False) verts = verts / verts.std() avg_edge_len = compute_average_edge_length(verts, tris) # compute cmm for each noise level vis_meshes = [] for noise_level in noise_levels: if noise_level <= 0: verts_noisy = verts else: noise_scale = noise_level * avg_edge_len noise = np.random.normal(scale=noise_scale, size=verts.shape) verts_noisy = verts + noise Phi_cmh = cmm.compressed_manifold_modes( verts_noisy, tris, K, mu=mu, scaled=True, init='varimax', ) if noise_level <= 0: label = 'no noise' else: label = '%.0f%% gaussian noise' % (noise_level * 100) vis_meshes.append((verts_noisy, tris, Phi_cmh, label)) # initialize the visualization, show later when all experiments done wvs.append( WeightsVisualization(vis_meshes, show_labels=True, actor_options=dict(interpolation='flat'))) # show visualization windows for wv in wvs[:-1]: wv.edit_traits() wvs[-1].configure_traits()
def main(): experiments = [ ('meshes/fertility/FE_20k.off', 6, [0., 0.25, 0.5, 1.0], 12.5), ('meshes/bimba/bimba_cvd_10k.off', 5, [0, 0.25, 0.5, 1.0], 30), ] wvs = [] for filename, K, noise_levels, mu in experiments: verts, tris = load_mesh(filename, check=False) verts = verts / verts.std() avg_edge_len = compute_average_edge_length(verts, tris) # compute cmm for each noise level vis_meshes = [] for noise_level in noise_levels: if noise_level <= 0: verts_noisy = verts else: noise_scale = noise_level * avg_edge_len noise = np.random.normal(scale=noise_scale, size=verts.shape) verts_noisy = verts + noise Phi_cmh = cmm.compressed_manifold_modes( verts_noisy, tris, K, mu=mu, scaled=True, init='varimax', ) if noise_level <= 0: label = 'no noise' else: label = '%.0f%% gaussian noise' % (noise_level * 100) vis_meshes.append((verts_noisy, tris, Phi_cmh, label)) # initialize the visualization, show later when all experiments done wvs.append(WeightsVisualization( vis_meshes, show_labels=True, actor_options=dict(interpolation='flat'))) # show visualization windows for wv in wvs[:-1]: wv.edit_traits() wvs[-1].configure_traits()
def main(): experiments = [ ('meshes/fertility/FE_20k.off', 6, [0., 500], 12.5), ('meshes/bimba/bimba_cvd_10k.off', 5, [0, 100, 200], 30), ] wvs = [] for filename, K, all_n_holes, mu in experiments: verts, tris = load_mesh(filename, check=False) verts = verts / verts.std() # compute cmm for each noise level vis_meshes = [] for n_holes in all_n_holes: if n_holes <= 0: tris_holes = tris verts_holes = verts else: while True: # place holes hole_centers = np.random.randint(0, len(verts), n_holes) keep_vertex = np.ones(len(verts), np.bool) keep_vertex[hole_centers] = False keep_tri = keep_vertex[tris].all(axis=1) tris_holes = filter_reindex(keep_vertex, tris[keep_tri]) verts_holes = verts[keep_vertex] # check if mesh is still a single connected graph ij = np.r_[np.c_[tris_holes[:, 0], tris_holes[:, 1]], np.c_[tris_holes[:, 0], tris_holes[:, 2]], np.c_[tris_holes[:, 1], tris_holes[:, 2]]] n_keep = verts[keep_vertex].shape[0] G = csr_matrix( (np.ones(len(ij)), ij.T), shape=(n_keep, n_keep)) n_components, labels = connected_components(G, directed=0) if n_components == 1: break else: # mesh was torn apart by hole creation process # trying another set of random holes pass Phi_cmh = cmm.compressed_manifold_modes( verts_holes, tris_holes, K, mu=mu, scaled=True, init='varimax', ) if n_holes <= 0: label = 'no holes' else: label = '%d holes' % (n_holes) vis_meshes.append((verts_holes, tris_holes, Phi_cmh, label)) # initialize the visualization, show later when all experiments done wvs.append(WeightsVisualization(vis_meshes, show_labels=True)) # show visualization windows for wv in wvs[:-1]: wv.edit_traits() wvs[-1].configure_traits()
Phi_init2[verts2[:, 1].argmax()] = 1.0 # set parameters # NOTE: these might not give exactly the same results as in the paper # since the code was significantly changed after producing Fig. 2 # the code here still shows the same behavior of the scaling K = Phi_init1.shape[1] mu_scaled = 50. mu_unscaled = 20.0 params = dict(maxiter=5000) # compute modes Phi1_scaled = cmm.compressed_manifold_modes(verts1, tris1, K, mu_scaled, init=Phi_init1, scaled=True, **params) Phi2_scaled = cmm.compressed_manifold_modes(verts2, tris2, K, mu_scaled, init=Phi_init2, scaled=True, **params) Phi1_unscaled = cmm.compressed_manifold_modes(verts1, tris1, K,
import numpy as np from cmmlib import cmm from cmmlib.inout import load_mesh from cmmlib.vis.weights import show_many_weights scape_dir = path.join('meshes', 'scape') if not path.exists(scape_dir) or not path.exists( path.join(scape_dir, 'mesh000.off')): print "SCAPE dataset not found. You need to get it from James Davis." print "Instructions on this website: " print "http://robotics.stanford.edu/~drago/Projects/scape/scape.html" sys.exit(1) meshes = [ load_mesh(path.join(scape_dir, 'mesh%03d.off' % i), normalize=True) for i in [0, 7, 10] ] results = [] for verts, tris in meshes: Phi_cmh = cmm.compressed_manifold_modes(verts, tris, 10, mu=12.5, scaled=True, maxiter=2000) results.append((verts, tris, Phi_cmh)) show_many_weights(results)
import sys from os import path import numpy as np from cmmlib import cmm from cmmlib.inout import load_mesh from cmmlib.vis.weights import show_many_weights scape_dir = path.join('meshes', 'scape') if not path.exists(scape_dir) or not path.exists(path.join(scape_dir, 'mesh000.off')): print "SCAPE dataset not found. You need to get it from James Davis." print "Instructions on this website: " print "http://robotics.stanford.edu/~drago/Projects/scape/scape.html" sys.exit(1) meshes = [load_mesh(path.join(scape_dir, 'mesh%03d.off' % i), normalize=True) for i in [0, 7, 10]] results = [] for verts, tris in meshes: Phi_cmh = cmm.compressed_manifold_modes( verts, tris, 10, mu=12.5, scaled=True, maxiter=2000) results.append((verts, tris, Phi_cmh)) show_many_weights(results)
Phi_init = np.random.uniform(-1, 1, (len(verts), K)) Phis = [Phi_init] def callback(H, mu, Phi, E, S, **kwargs): global i i += 1 if i in at_iters: Phis.append(Phi) i = 0 cmm.compressed_manifold_modes(verts, tris, K, mu=20, init=Phi_init, scaled=True, callback=callback, tol_abs=0, tol_rel=0, maxiter=max(at_iters) + 1, check_interval=1) all_Phis.append(Phis) Phi_at_iters = np.array([np.array(Phis) for Phis in all_Phis]) show_weights( verts, tris, Phi_at_iters.reshape((num_inits * len(at_iters), len(verts), K)), [
from cmmlib import cmm from cmmlib.inout import load_mesh from cmmlib.vis.weights import show_weights K1 = 8 + 6 + 12 K2 = 4 verts, tris = load_mesh('meshes/bumpy_cube6.obj') Phi_cpr1 = cmm.compressed_manifold_modes(verts, tris, K1, mu=20., scaled=False) Phi_cpr2 = cmm.compressed_manifold_modes(verts, tris, K2, mu=20., scaled=False) Phi_vari1 = cmm.varimax_modes(verts, tris, K1) Phi_vari2 = cmm.varimax_modes(verts, tris, K2) # establish some consistent ordering of varimax modes just for visualization i = (Phi_cpr2[:, 0]**2).argmax() # select one vertex # permute according to activation strength of that vertex Phi_vari2 = Phi_vari2[:, (Phi_vari2[i]**2).argsort()[::-1]] Phi_vari1 = Phi_vari1[:, (Phi_vari1[i]**2).argsort()[::-1]] Phi_cpr2 = Phi_cpr2[:, (Phi_cpr2[i]**2).argsort()[::-1]] Phi_cpr1 = Phi_cpr1[:, (Phi_cpr1[i]**2).argsort()[::-1]] show_weights(verts, tris, (Phi_cpr1, Phi_cpr2, Phi_vari1, Phi_vari2), ('CMM, K=%d' % K1, 'CMM, K=%d' % K2, 'Variax, K=%d' % K1, 'Varimax, K=%d' % K2), contours=7, show_labels=True)
from cmmlib import cmm from cmmlib.inout import load_mesh from cmmlib.vis.weights import show_weights K1 = 8 + 6 + 12 K2 = 4 verts, tris = load_mesh('meshes/bumpy_cube6.obj') Phi_cpr1 = cmm.compressed_manifold_modes(verts, tris, K1, mu=20., scaled=False) Phi_cpr2 = cmm.compressed_manifold_modes(verts, tris, K2, mu=20., scaled=False) Phi_vari1 = cmm.varimax_modes(verts, tris, K1) Phi_vari2 = cmm.varimax_modes(verts, tris, K2) # establish some consistent ordering of varimax modes just for visualization i = (Phi_cpr2[:, 0]**2).argmax() # select one vertex # permute according to activation strength of that vertex Phi_vari2 = Phi_vari2[:, (Phi_vari2[i]**2).argsort()[::-1]] Phi_vari1 = Phi_vari1[:, (Phi_vari1[i]**2).argsort()[::-1]] Phi_cpr2 = Phi_cpr2[:, (Phi_cpr2[i]**2).argsort()[::-1]] Phi_cpr1 = Phi_cpr1[:, (Phi_cpr1[i]**2).argsort()[::-1]] show_weights( verts, tris, (Phi_cpr1, Phi_cpr2, Phi_vari1, Phi_vari2), ('CMM, K=%d' % K1, 'CMM, K=%d' % K2, 'Variax, K=%d' % K1, 'Varimax, K=%d' % K2), contours=7, show_labels=True)
from cmmlib import cmm from cmmlib.inout import load_mesh from cmmlib.vis.weights import show_many_weights mu = 2.0 K = 6 vms = [] for i, fn in enumerate(['hand_868', 'hand_868_holes2']): verts, tris = load_mesh('meshes/%s.obj' % fn) Phi_cpr = cmm.compressed_manifold_modes(verts, tris, K, mu=mu) Phi_dense = cmm.manifold_harmonics(verts, tris, K) vms += [(verts, tris, Phi_cpr, 'CMM #%d' % i), (verts, tris, Phi_dense, 'MH #%d' % i)] show_many_weights(vms, show_labels=True)
def main(input_filename, K, mu, output_dir=None, visualize=False, scaled=False, maxiter=None, ply=False, off=False): if (off or ply) and not output_dir: print "please specify an output directory" return 1 if output_dir and not path.exists(output_dir): print "%s does not exist" % output_dir return 2 verts, tris = load_mesh(input_filename, normalize=True) print "%d vertices, %d faces" % (len(verts), len(tris)) Phi_cpr, D = cmm.compressed_manifold_modes( verts, tris, K, mu=mu, scaled=scaled, maxiter=maxiter, verbose=100, return_D=True) if D is None: D_diag = np.ones(len(verts)) D = sparse.eye(len(verts)) else: D_diag = D.data if visualize: from cmmlib.vis.weights import show_weights show_weights(verts, tris, Phi_cpr) if output_dir: # save in simple text format np.savetxt(path.join(output_dir, 'phi.txt'), Phi_cpr, fmt='%f') np.savetxt(path.join(output_dir, 'D_diag.txt'), D_diag, fmt='%f') # save in matlab format savemat(path.join(output_dir, 'phi.mat'), dict(verts=verts, tris=tris+1, phi=Phi_cpr, D=D)) # save HDF5 format if possible try: import h5py except ImportError: print "Cannot save as HDF5, please install the h5py module" else: with h5py.File(path.join(output_dir, 'phi.h5'), 'w') as f: f['verts'] = verts f['tris'] = tris f['phi'] = Phi_cpr f['d_diag'] = D_diag # save NPY format np.save(path.join(output_dir, 'phi.npy'), Phi_cpr) np.save(path.join(output_dir, 'D_diag.npy'), Phi_cpr) if off or ply: # map phi scalars to colors from mayavi.core.lut_manager import LUTManager from cmmlib.vis.weights import _centered lut = LUTManager(lut_mode='RdBu').lut.table.to_array()[:, :3] colors = [ lut[(_centered(Phi_cpr[:, k]) * (lut.shape[0]-1)).astype(int)] for k in xrange(K)] # save in a single scene as a collage w = int(np.ceil(np.sqrt(K))) if K > 6 else K spacing = 1.2 * verts.ptp(axis=0) all_verts = [verts + spacing * (1.5, 0, 0)] all_tris = [tris] all_color = [np.zeros(verts.shape, np.int) + 127] for k in xrange(K): all_verts.append(verts + spacing * (-(k % w), 0, int(k / w))) all_tris.append(tris + len(verts) * (k+1)) all_color.append(colors[k]) if off: save_coff(path.join(output_dir, 'input.off'), verts.astype(np.float32), tris) for k in xrange(K): save_coff(path.join(output_dir, 'cmh_%03d.off' % k), verts.astype(np.float32), tris, colors[k]) save_coff(path.join(output_dir, 'all.off'), np.vstack(all_verts), np.vstack(all_tris), np.vstack(all_color)) if ply: from tvtk.api import tvtk pd = tvtk.PolyData( points=np.vstack(all_verts).astype(np.float32), polys=np.vstack(all_tris).astype(np.uint32)) pd.point_data.scalars = np.vstack(all_color).astype(np.uint8) pd.point_data.scalars.name = 'colors' ply = tvtk.PLYWriter( file_name=path.join(output_dir, 'all.ply'), input=pd, color=(1, 1, 1)) ply.array_name = 'colors' ply.write()
import numpy as np from cmmlib import cmm from cmmlib.align import optimal_permutation from cmmlib.inout import load_mesh from cmmlib.vis.weights import show_weights verts, tris = load_mesh('meshes/hand_4054.obj') K = 6 mus = [1/100., 1., 10.] all_Phi = [cmm.manifold_harmonics(verts, tris, K)] \ + [cmm.compressed_manifold_modes(verts, tris, K, mu, scaled=False) for mu in mus] # permute modes so we can visualize them side-by-side all_Phi_aligned = \ [np.dot(optimal_permutation(Phi.T, all_Phi[-1].T, allow_reflection=True), Phi.T).T for Phi in all_Phi[:-1]] + \ [all_Phi[-1]] show_weights(verts, tris, all_Phi_aligned, names=['dense'] + map(str, mus))
def main(): meshes = [ ('hand', 5, 'meshes/hand_868.obj', [10, 30], False), ('fertility', 5, 'meshes/fertility/FE_10k.off', [10, 40], False), ('bunny', 1.25, 'meshes/bunny_fixed.obj', [10, 40], False), ] result_lines = [] for mesh_name, mu, filename, Ks, scaled in meshes: verts, tris = load_mesh(filename, check=False, normalize=True) print mesh_name, len(verts), len(tris) for K in Ks: t_cmh = time() Phi_cmh, D_cmh = cmm.compressed_manifold_modes(verts, tris, K, init='varimax', mu=mu, scaled=scaled, return_D=True) t_cmh = time() - t_cmh t_mh = time() Phi_mh, D_mh = cmm.manifold_harmonics(verts, tris, K, return_D=True, scaled=scaled) t_mh = time() - t_mh Phi_mh = Phi_mh.astype(np.float64) Phi_cmh = Phi_cmh.astype(np.float64) Phi_cmh[np.abs(Phi_cmh) < 1.e-7] = 0 Phi_cmh_sp = sparse.csr_matrix(Phi_cmh, dtype=np.float64) if scaled: verts_rec_cmh = np.dot(Phi_cmh, np.dot((D_cmh * Phi_cmh).T, verts)) verts_rec_mh = np.dot(Phi_mh, np.dot((D_mh * Phi_mh).T, verts)) else: verts_rec_cmh = np.dot(Phi_cmh, np.dot(Phi_cmh.T, verts)) verts_rec_mh = np.dot(Phi_mh, np.dot(Phi_mh.T, verts)) line_format = "{mesh_name} & {num_verts:>8d} & {basis} & {K:d} & {mu:>4} & {error:>6.2f} & {size:>8} & {time:>5.2f}s" result_lines.append( line_format.format( mesh_name=mesh_name, basis='MHB', K=K, mu='-', num_verts=len(verts), error=np.linalg.norm(verts_rec_mh - verts), size=sizeof_fmt(Phi_mh.nbytes), time=t_mh, )) result_lines.append( line_format.format( mesh_name=mesh_name, basis='CMB', K=K, mu='%.2f' % mu, num_verts=len(verts), error=np.linalg.norm(verts_rec_cmh - verts), size=sizeof_fmt(Phi_cmh_sp.data.nbytes + Phi_cmh_sp.indptr.nbytes + Phi_cmh_sp.indices.nbytes), time=t_cmh, )) print "------------" print "TABLE START:" print "------------" print "mesh & basis & $K$ & $\\mu$ & error & size & time" for line in result_lines: print line
experiments = [ ('meshes/armadillo_61372.obj', [3, 7], 20.), ('meshes/elk.off', [3, 7], 20.), ] results = [] for filename, Ks, mu in experiments: verts, tris = load_mesh(filename, normalize=True) # for different K, compute the CMMs Phis = [] for K in Ks: Phi_cmh = cmm.compressed_manifold_modes( verts, tris, K, mu, scaled=True, init='varimax') Phis.append(Phi_cmh) # color the mesh according to the CMMs lut = LUTManager(lut_mode='hsv').lut.table.to_array() colors = [] for K, Phi in zip(Ks, Phis): # pass Phi through the lookup table depending on it's strength ti = np.linspace(0, 1, K, endpoint=False) * (lut.shape[0]-1) lut_rgb = lut[ti.astype(np.int), :3].astype(np.float) Phi = np.abs(Phi / (Phi.max(0) - Phi.min(0))[np.newaxis]) a = Phi.sum(axis=1)[:, np.newaxis] Phi_color = (lut_rgb[np.newaxis] * Phi[:, :, np.newaxis]).sum(axis=1) # mix with grey color = np.clip(Phi_color * a + 200 * (1-a), 0, 255) colors.append(color)
Phi_init1[verts1[:, 1].argmax()] = 1.0 Phi_init2 = np.zeros((len(verts2), 1)) Phi_init2[verts2[:, 1].argmax()] = 1.0 # set parameters # NOTE: these might not give exactly the same results as in the paper # since the code was significantly changed after producing Fig. 2 # the code here still shows the same behavior of the scaling K = Phi_init1.shape[1] mu_scaled = 50. mu_unscaled = 20.0 params = dict(maxiter=5000) # compute modes Phi1_scaled = cmm.compressed_manifold_modes( verts1, tris1, K, mu_scaled, init=Phi_init1, scaled=True, **params) Phi2_scaled = cmm.compressed_manifold_modes( verts2, tris2, K, mu_scaled, init=Phi_init2, scaled=True, **params) Phi1_unscaled = cmm.compressed_manifold_modes( verts1, tris1, K, mu_unscaled, init=Phi_init1, scaled=False, **params) Phi2_unscaled = cmm.compressed_manifold_modes( verts2, tris2, K, mu_unscaled, init=Phi_init2, scaled=False, **params) # visualize
from cmmlib import cmm from cmmlib.inout import load_mesh from cmmlib.vis.weights import show_weights K = 8 + 6 + 12 mu = 20.0 filename = 'meshes/bumpy_cube6.obj' verts, tris = load_mesh(filename) Phi_cpr = cmm.compressed_manifold_modes(verts, tris, K, mu=mu) Phi_dense = cmm.manifold_harmonics(verts, tris, K) Phi_vari = cmm.varimax_modes(verts, tris, K) show_weights(verts, tris, (Phi_cpr, Phi_dense, Phi_vari), ('CMM', 'MH', 'Varimax'), show_labels=True)
import numpy as np from cmmlib import cmm from cmmlib.inout import load_mesh from cmmlib.vis.weights import show_many_weights K = 6 verts, tris = load_mesh('meshes/hand_4054.obj') # compute bases Phi_cmh = cmm.compressed_manifold_modes(verts, tris, K, mu=2, scaled=False) Phi_mh = cmm.manifold_harmonics(verts, tris, K, scaled=False) # reconstruct from bases verts_rec_cmh = np.dot(Phi_cmh, np.dot(Phi_cmh.T, verts)) verts_rec_mh = np.dot(Phi_mh, np.dot(Phi_mh.T, verts)) show_many_weights( ((verts, tris, None, 'Input'), (verts_rec_mh, tris, None, 'MH reconstr.'), (verts_rec_cmh, tris, None, 'CMM reconstr.')), show_labels=True, actor_options=dict(edge_visibility=True, line_width=1.0))
def main(): experiments = [ ('meshes/fertility/FE_20k.off', 6, [0., 500], 12.5), ('meshes/bimba/bimba_cvd_10k.off', 5, [0, 100, 200], 30), ] wvs = [] for filename, K, all_n_holes, mu in experiments: verts, tris = load_mesh(filename, check=False) verts = verts / verts.std() # compute cmm for each noise level vis_meshes = [] for n_holes in all_n_holes: if n_holes <= 0: tris_holes = tris verts_holes = verts else: while True: # place holes hole_centers = np.random.randint(0, len(verts), n_holes) keep_vertex = np.ones(len(verts), np.bool) keep_vertex[hole_centers] = False keep_tri = keep_vertex[tris].all(axis=1) tris_holes = filter_reindex(keep_vertex, tris[keep_tri]) verts_holes = verts[keep_vertex] # check if mesh is still a single connected graph ij = np.r_[np.c_[tris_holes[:, 0], tris_holes[:, 1]], np.c_[tris_holes[:, 0], tris_holes[:, 2]], np.c_[tris_holes[:, 1], tris_holes[:, 2]]] n_keep = verts[keep_vertex].shape[0] G = csr_matrix((np.ones(len(ij)), ij.T), shape=(n_keep, n_keep)) n_components, labels = connected_components(G, directed=0) if n_components == 1: break else: # mesh was torn apart by hole creation process # trying another set of random holes pass Phi_cmh = cmm.compressed_manifold_modes( verts_holes, tris_holes, K, mu=mu, scaled=True, init='varimax', ) if n_holes <= 0: label = 'no holes' else: label = '%d holes' % (n_holes) vis_meshes.append((verts_holes, tris_holes, Phi_cmh, label)) # initialize the visualization, show later when all experiments done wvs.append(WeightsVisualization(vis_meshes, show_labels=True)) # show visualization windows for wv in wvs[:-1]: wv.edit_traits() wvs[-1].configure_traits()
Phi_init = -1 * (color1[:, 0] > 200).astype(np.float).reshape(len(verts), K) elif init == 1: Phi_init = 1 * (color2[:, 0] > 200).astype(np.float).reshape(len(verts), K) else: Phi_init = np.random.uniform(-1, 1, (len(verts), K)) Phis = [Phi_init] def callback(H, mu, Phi, E, S, **kwargs): global i i += 1 if i in at_iters: Phis.append(Phi) i = 0 cmm.compressed_manifold_modes( verts, tris, K, mu=20, init=Phi_init, scaled=True, callback=callback, tol_abs=0, tol_rel=0, maxiter=max(at_iters)+1, check_interval=1) all_Phis.append(Phis) Phi_at_iters = np.array([np.array(Phis) for Phis in all_Phis]) show_weights( verts, tris, Phi_at_iters.reshape((num_inits*len(at_iters), len(verts), K)), ["Iteration %d (%d)" % (it, exp) if it > 0 else "Initialization (%d)" % exp for exp, it in product(range(num_inits), at_iters)], show_labels=True, label_offset_axis=1, offset_spacing2=1.3, label_offset=0.8, num_columns=len(at_iters), )
def main(input_filename, K, mu, output_dir=None, visualize=False, scaled=False, maxiter=None, ply=False, off=False): if (off or ply) and not output_dir: print ("please specify an output directory") return 1 if output_dir and not path.exists(output_dir): print("%s does not exist" % output_dir) return 2 verts, tris = load_mesh(input_filename, normalize=True) print ("%d vertices, %d faces" % (len(verts), len(tris))) Phi_cpr, D = cmm.compressed_manifold_modes( verts, tris, K, mu=mu, scaled=scaled, maxiter=maxiter, verbose=100, return_D=True) if D is None: D_diag = np.ones(len(verts)) D = sparse.eye(len(verts)) else: D_diag = D.data if visualize: from cmmlib.vis.weights import show_weights show_weights(verts, tris, Phi_cpr) if output_dir: # save in simple text format np.savetxt(path.join(output_dir, 'phi.txt'), Phi_cpr, fmt='%f') np.savetxt(path.join(output_dir, 'D_diag.txt'), D_diag, fmt='%f') # save in matlab format savemat(path.join(output_dir, 'phi.mat'), dict(verts=verts, tris=tris+1, phi=Phi_cpr, D=D)) # save HDF5 format if possible try: import h5py except ImportError: print ("Cannot save as HDF5, please install the h5py module") else: with h5py.File(path.join(output_dir, 'phi.h5'), 'w') as f: f['verts'] = verts f['tris'] = tris f['phi'] = Phi_cpr f['d_diag'] = D_diag # save NPY format np.save(path.join(output_dir, 'phi.npy'), Phi_cpr) np.save(path.join(output_dir, 'D_diag.npy'), Phi_cpr) if off or ply: # map phi scalars to colors from mayavi.core.lut_manager import LUTManager from cmmlib.vis.weights import _centered lut = LUTManager(lut_mode='RdBu').lut.table.to_array()[:, :3] colors = [ lut[(_centered(Phi_cpr[:, k]) * (lut.shape[0]-1)).astype(int)] for k in range(K)] # save in a single scene as a collage w = int(np.ceil(np.sqrt(K))) if K > 6 else K spacing = 1.2 * verts.ptp(axis=0) all_verts = [verts + spacing * (1.5, 0, 0)] all_tris = [tris] all_color = [np.zeros(verts.shape, np.int) + 127] for k in range(K): all_verts.append(verts + spacing * (-(k % w), 0, int(k / w))) all_tris.append(tris + len(verts) * (k+1)) all_color.append(colors[k]) if off: save_coff(path.join(output_dir, 'input.off'), verts.astype(np.float32), tris) for k in range(K): save_coff(path.join(output_dir, 'cmh_%03d.off' % k), verts.astype(np.float32), tris, colors[k]) save_coff(path.join(output_dir, 'all.off'), np.vstack(all_verts), np.vstack(all_tris), np.vstack(all_color)) if ply: from tvtk.api import tvtk pd = tvtk.PolyData( points=np.vstack(all_verts).astype(np.float32), polys=np.vstack(all_tris).astype(np.uint32)) pd.point_data.scalars = np.vstack(all_color).astype(np.uint8) pd.point_data.scalars.name = 'colors' ply = tvtk.PLYWriter( file_name=path.join(output_dir, 'all.ply'), input=pd, color=(1, 1, 1)) ply.array_name = 'colors' ply.write()