def construct_matrices(self): """ Construct FEM matrices """ V = p2e(self.vertices) F = p2e(self.faces) # Compute gradient operator: #F*3 by #V G = igl.eigen.SparseMatrixd() L = igl.eigen.SparseMatrixd() M = igl.eigen.SparseMatrixd() N = igl.eigen.MatrixXd() A = igl.eigen.MatrixXd() igl.grad(V, F, G) igl.cotmatrix(V, F, L) igl.per_face_normals(V, F, N) igl.doublearea(V, F, A) igl.massmatrix(V, F, igl.MASSMATRIX_TYPE_VORONOI, M) G = e2p(G) L = e2p(L) N = e2p(N) A = e2p(A) M = e2p(M) M = M.data # Compute latitude and longitude directional vector fields NS = np.reshape(G.dot(self.lat), [self.nf, 3], order='F') EW = np.cross(NS, N) # Compute F2V matrix (weigh by area) # adjacency i = self.faces.ravel() j = np.arange(self.nf).repeat(3) one = np.ones(self.nf * 3) adj = sparse.csc_matrix((one, (i, j)), shape=(self.nv, self.nf)) tot_area = adj.dot(A) norm_area = A.ravel().repeat(3) / np.squeeze(tot_area[i]) F2V = sparse.csc_matrix((norm_area, (i, j)), shape=(self.nv, self.nf)) # Compute interpolation matrix if self.level > 0: intp = self.intp[self.nv_prev:] i = np.concatenate( (np.arange(self.nv), np.arange(self.nv_prev, self.nv))) j = np.concatenate((np.arange(self.nv_prev), intp[:, 0], intp[:, 1])) ratio = np.concatenate( (np.ones(self.nv_prev), 0.5 * np.ones(2 * intp.shape[0]))) intp = sparse.csc_matrix((ratio, (i, j)), shape=(self.nv, self.nv_prev)) else: intp = sparse.csc_matrix(np.eye(self.nv)) # Compute vertex mean matrix self.G = G # gradient matrix self.L = L # laplacian matrix self.N = N # normal vectors (per-triangle) self.NS = NS # north-south vectors (per-triangle) self.EW = EW # east-west vectors (per-triangle) self.F2V = F2V # map face quantities to vertices self.M = M # mass matrix (area of voronoi cell around node. for integration) self.Seq = self._rotseq(self.vertices) self.Intp = intp
def global_para(ref_mesh_filename): """ return some global parameters used in generating mesh including : Mesh Face list, Laplacian matrix of face(two formats of sparse matrix), reference mesh """ # get Laplacian matrix global F, A, B, ref_mesh V = igl.eigen.MatrixXd() F = igl.eigen.MatrixXi() igl.readOBJ(ref_mesh_filename, V, F) L = igl.eigen.SparseMatrixd() # Laplacian Matrix igl.cotmatrix(V, F, L) A = e2p(L) c = A.col r = A.row adj = sparse.coo_matrix((np.ones(c.shape[0]), (c, r)), shape=(A.shape[0], A.shape[0]), dtype=np.float32).tocsr()-sparse.eye(A.shape[0]) adj = adj + adj.T.multiply(adj.T > adj) - adj.multiply(adj.T > adj) A = sparse.diags(np.power(np.array(adj.sum(1)), 1).flatten(), 0) - adj B = A.tocsr() ref_mesh = openmesh.read_trimesh(ref_mesh_filename)
F = igl.eigen.MatrixXi() igl.readOFF("../../tutorial/shared/cheburashka.off",V,F) # Two fixed points # Left hand, left foot b = igl.eigen.MatrixXi([[4331],[5957]]) bc = igl.eigen.MatrixXd([[1],[-1]]) # Construct Laplacian and mass matrix L = igl.eigen.SparseMatrixd() M = igl.eigen.SparseMatrixd() Minv = igl.eigen.SparseMatrixd() Q = igl.eigen.SparseMatrixd() igl.cotmatrix(V,F,L) igl.massmatrix(V,F,igl.MASSMATRIX_TYPE_VORONOI,M) igl.invert_diag(M,Minv) # Bi-Laplacian Q = L * (Minv * L); # Zero linear term B = igl.eigen.MatrixXd.Zero(V.rows(),1); Z = igl.eigen.MatrixXd() Z_const = igl.eigen.MatrixXd() # Alternative, short hand mqwf = igl.min_quad_with_fixed_data()
F = igl.eigen.MatrixXi() c = 0 bbd = 1.0 twod = False if not igl.read_triangle_mesh(TUTORIAL_SHARED_PATH + "beetle.off", V, F): print("failed to load mesh") twod = V.col(2).minCoeff() == V.col(2).maxCoeff() bbd = (V.colwiseMaxCoeff() - V.colwiseMinCoeff()).norm() L = igl.eigen.SparseMatrixd() M = igl.eigen.SparseMatrixd() igl.cotmatrix(V, F, L) L = -L igl.massmatrix(V, F, igl.MASSMATRIX_TYPE_DEFAULT, M) k = 5 D = igl.eigen.MatrixXd() if not igl.eigs(L, M, k + 1, igl.EIGS_TYPE_SM, U, D): print("Eigs failed.") U = (U - U.minCoeff()) / (U.maxCoeff() - U.minCoeff()) viewer = igl.viewer.Viewer() def key_down(viewer, key, mod): global U, c