def key_pressed(viewer, key, modifier):
    global V
    global U
    global F
    global L

    if key == ord('r') or key == ord('R'):
        U = V;
    elif key == ord(' '):

        # Recompute just mass matrix on each step
        M = igl.eigen.SparseMatrixd()

        igl.massmatrix(U,F,igl.MASSMATRIX_TYPE_BARYCENTRIC,M);

        # Solve (M-delta*L) U = M*U
        S = (M - 0.001*L)

        solver = igl.eigen.SimplicialLLTsparse(S)

        U = solver.solve(M*U)

        # Compute centroid and subtract (also important for numerics)
        dblA = igl.eigen.MatrixXd()
        igl.doublearea(U,F,dblA)

        print(dblA.sum())

        area = 0.5*dblA.sum()
        BC = igl.eigen.MatrixXd()
        igl.barycenter(U,F,BC)
        centroid = igl.eigen.MatrixXd([[0.0,0.0,0.0]])

        for i in range(0,BC.rows()):
            centroid += 0.5*dblA[i,0]/area*BC.row(i)

        U -= centroid.replicate(U.rows(),1)

        # Normalize to unit surface area (important for numerics)
        U = U / math.sqrt(area)
    else:
        return False

    # Send new positions, update normals, recenter
    viewer.data.set_vertices(U)
    viewer.data.compute_normals()
    viewer.core.align_camera_center(U,F)
    return True
Пример #2
0
    def construct_matrices(self):
        """
        Construct FEM matrices
        """
        V = self.vertices
        F = self.faces
        # Compute gradient operator: #F*3 by #V
        G = igl.grad(V, F).tocoo()
        L = igl.cotmatrix(V, F).tocoo()
        N = igl.per_face_normals(V, F, np.array([0., 0., 0.]))
        A = igl.doublearea(V, F)
        A = A[:, np.newaxis]
        M = igl.massmatrix(V, F, igl.MASSMATRIX_TYPE_VORONOI).tocoo()
        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 construct_mesh_matrices_de(vertices, faces):
    v_num, f_num = vertices.shape[0], faces.shape[0]
    G = igl.grad(vertices, faces)
    L = igl.cotmatrix(vertices, faces)
    A = igl.doublearea(vertices, faces)
    XN = np.array([1, 0, 0], dtype=np.float32)
    YN = np.array([0, 1, 0], dtype=np.float32)
    i = faces.ravel()
    j = np.arange(f_num).repeat(3)
    one = np.ones(f_num * 3)
    adj = sparse.csc_matrix((one, (i, j)), shape=(v_num, f_num))
    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=(v_num, f_num))
    return {'G': G, 'L': L, 'A': A, 'XN': XN, 'YN': YN, 'F2V': F2V}
def construct_mesh_matrices(vertices, faces):
    v_num, f_num = vertices.shape[0], faces.shape[0]
    G = igl.grad(vertices, faces)
    #     L = igl.cotmatrix(vertices, faces)
    L = cotmatrix_firstvonly(vertices, faces)
    A = igl.doublearea(vertices, faces)
    XN = np.array([1, 0, 0], dtype=np.float32)
    YN = np.array([0, 1, 0], dtype=np.float32)
    i = faces[:, 0].ravel()  # each triangle only belongs to the first vertex!
    j = np.arange(f_num)
    one = np.ones(f_num)
    adj = sparse.csc_matrix((one, (i, j)), shape=(v_num, f_num))
    tot_area = adj.dot(A)
    norm_area = A.ravel() / np.squeeze(tot_area[i] + 1e-6)
    F2V = sparse.csc_matrix((norm_area, (i, j)), shape=(v_num, f_num))
    return {'G': G, 'L': L, 'A': A, 'XN': XN, 'YN': YN, 'F2V': F2V}
Пример #5
0
def construct_mesh_matrices_de(vertices, faces, lat):
    v_num, f_num = vertices.shape[0], faces.shape[0]
    G = igl.grad(vertices, faces)
    L = igl.cotmatrix(vertices, faces)
    A = igl.doublearea(vertices, faces)
    N = igl.per_face_normals(vertices, faces, vertices)
    YN = np.reshape(G.dot(lat), [f_num, 3], order='F')
    YN = YN / (np.linalg.norm(YN, axis=1)[:, np.newaxis]+1e-6)
    XN = np.cross(YN, N)
    i = faces.ravel()
    j = np.arange(f_num).repeat(3)
    one = np.ones(f_num * 3)
    adj = sparse.csc_matrix((one, (i, j)), shape=(v_num, f_num))
    tot_area = adj.dot(A)
    norm_area = A.ravel().repeat(3) / np.squeeze(tot_area[i] + 1e-6)
    F2V = sparse.csc_matrix((norm_area, (i, j)), shape=(v_num, f_num))
    return {
        'G': G, 'L': L, 'A': A, 'XN': XN, 'YN': YN, 'F2V': F2V
    }
Пример #6
0
    def run(self):
        if not self.copyData():
            return

        if self.geo.getNumFaces() == 0 or self.geo.getNumVertexes() == 0:
            return

        mt = self.get_property("Method")
        if mt == "FaceCent":
            self.geo.meshFuncs.facePos(True)
        elif mt == "Area":
            area = igl.doublearea(self.geo.getVertexes(),
                                  self.geo.mesh.face_vertex_indices()) / 2.0
            self.geo.setFaceAttribData("area",
                                       area,
                                       attribType='float',
                                       defaultValue=0.0)
        elif mt == "Edge Length":
            self.geo.meshFuncs.edgeLength(True)
Пример #7
0
def construct_mesh_matrices(vertices, faces, lat):
    v_num, f_num = vertices.shape[0], faces.shape[0]
    G = igl.grad(vertices, faces)
#     L = igl.cotmatrix(vertices, faces)
    L = cotmatrix_firstvonly(vertices, faces)
    A = igl.doublearea(vertices, faces)
    N = igl.per_face_normals(vertices, faces, vertices)
#     XN = np.array([1, 0, 0], dtype=np.float32)
#     YN = np.array([0, 1, 0], dtype=np.float32)
    YN = np.reshape(G.dot(lat), [f_num, 3], order='F')
    YN = YN / (np.linalg.norm(YN, axis=1)[:, np.newaxis]+1e-6)
    XN = np.cross(YN, N)
    i = faces[:, 0].ravel() # each triangle only belongs to the first vertex!
    j = np.arange(f_num)
    one = np.ones(f_num)
    adj = sparse.csc_matrix((one, (i, j)), shape=(v_num, f_num))
    tot_area = adj.dot(A)
    norm_area = A.ravel() / np.squeeze(tot_area[i] + 1e-6)
    F2V = sparse.csc_matrix((norm_area, (i, j)), shape=(v_num, f_num))
    return {
        'G': G, 'L': L, 'A': A, 'XN': XN, 'YN': YN, 'F2V': F2V, 'N': N
    }
# Load a mesh in OFF format
igl.readOFF("../../tutorial/shared/cow.off", V, F)

# Compute Laplace-Beltrami operator: #V by #V
igl.cotmatrix(V,F,L)

# Alternative construction of same Laplacian
G = igl.eigen.SparseMatrixd()
K = igl.eigen.SparseMatrixd()

# Gradient/Divergence
igl.grad(V,F,G);

# Diagonal per-triangle "mass matrix"
dblA = igl.eigen.MatrixXd()
igl.doublearea(V,F,dblA)

# Place areas along diagonal #dim times

T = (dblA.replicate(3,1)*0.5).asDiagonal() * 1

# Laplacian K built as discrete divergence of gradient or equivalently
# discrete Dirichelet energy Hessian

temp = -G.transpose()
K = -G.transpose() * T * G
print("|K-L|: ",(K-L).norm())

def key_pressed(viewer, key, modifier):
    global V
    global U
 def test_doublearea(self):
     a = igl.doublearea(self.v1, self.f1)
     self.assertEqual(a.shape[0], self.f1.shape[0])
     self.assertEqual(a.dtype, self.v1.dtype)
     self.assertTrue(a.flags.c_contiguous)
Пример #10
0
 def test_doublearea(self):
     a = igl.doublearea(self.v1, self.f1)
     self.assertEqual(a.shape[0], self.f1.shape[0])
     self.assertEqual(a.dtype, self.v1.dtype)