Пример #1
0
    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 grad_fun(index, gt_transient, transient, v, f, opt):
  mesh = MESH()
  mesh.v = igl.eigen.MatrixXd(v)
  mesh.f = igl.eigen.MatrixXi(f)
  igl.per_face_normals(mesh.v, mesh.f, mesh.fn)
  igl.doublearea(mesh.v, mesh.f, mesh.doublearea)
  gradient = grad_collocate(index, gt_transient, transient, mesh, opt)
  return gradient
def render_all_fun(i, v, f, opt):
  mesh = MESH()
  mesh.v = igl.eigen.MatrixXd(v)
  mesh.f = igl.eigen.MatrixXi(f)
  igl.per_face_normals(mesh.v, mesh.f, mesh.fn)
  igl.doublearea(mesh.v, mesh.f, mesh.doublearea)
  transient = mesh_sampling_collocate(mesh, opt.lighting[i,:], opt.lighting_normal[i,:], opt)
  return transient
def render_all_fun(i, v, f, vn, opt):
  mesh = MESH()
  mesh.v = igl.eigen.MatrixXd(v)
  mesh.f = igl.eigen.MatrixXi(f)
  mesh.vn = vn
  igl.per_face_normals(mesh.v, mesh.f, mesh.fn)
  igl.doublearea(mesh.v, mesh.f, mesh.doublearea)
  if opt.method == 'n':
    transient = mesh_sampling_collocate(mesh, opt.lighting[int(i),:], opt.lighting_normal[int(i),:], opt)
  else:
    transient = stratified_mesh_sampling_collocate(mesh, opt.lighting[int(i),:], opt.lighting_normal[int(i),:], opt)
  return transient
Пример #5
0
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
Пример #6
0
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
Пример #7
0
# 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
Пример #8
0
    # Load meshes in OFF format
    igl.readOBJ(TUTORIAL_SHARED_PATH + "horse_quad.obj", V, F)

    # Count the number of irregular vertices, the border is ignored
    irregular = igl.is_irregular_vertex(V, F)
    vertex_count = V.rows()
    irregular_vertex_count = sum(irregular)
    irregular_ratio = irregular_vertex_count / vertex_count

    print("Irregular vertices: \n%d/%d (%.2f%%)\n" %
          (irregular_vertex_count, vertex_count, irregular_ratio * 100))

    # Compute areas, min, max and standard deviation
    area = igl.eigen.MatrixXd()
    igl.doublearea(V, F, area)
    area /= 2.0

    area_avg = area.mean()
    area_min = area.minCoeff() / area_avg
    area_max = area.maxCoeff() / area_avg
    area_ns = (area - area_avg) / area_avg
    area_sigma = math.sqrt(area_ns.squaredMean())

    print("Areas (Min/Max)/Avg_Area Sigma: \n%.2f/%.2f (%.2f)\n" %
          (area_min, area_max, area_sigma))

    # Compute per face angles, min, max and standard deviation
    angles = igl.eigen.MatrixXd()
    igl.internal_angles(V, F, angles)
    angles = 360.0 * (angles / (2 * math.pi))
Пример #9
0
import pymmgs
import numpy as np
import sys, os
sys.path.insert(0, os.path.expanduser('~/Workspace/libigl/python'))
import pyigl as igl
import pyigl.eigen as Eigen
from iglhelpers import p2e, e2p

V = igl.eigen.MatrixXd()
F = igl.eigen.MatrixXi()
igl.read_triangle_mesh('/Users/zhongshi/1399_standing_clap_000010.obj', V, F)

# SV, SVI, SVJ, SF =  igl.eigen.MatrixXd(),  igl.eigen.MatrixXi(), igl.eigen.MatrixXi(), igl.eigen.MatrixXi()
# igl.remove_duplicate_vertices(V,F,1e-10, SV, SVI, SVJ, SF)
M = igl.eigen.MatrixXd()
igl.doublearea(V, F, M)
M = e2p(M).flatten()

# F0 = e2p(F)[np.where(M > 1e-9)[0],:]

# npl = np.load('/Users/zhongshi/1006_jump_from_wall_000003.obj.npz')
V0, F0 = e2p(V), e2p(F)

# igl.writeOBJ('1399.obj',V, F)
V, F = pymmgs.MMGS(V0, F0, 0.005)
vw = igl.glfw.Viewer()
vw.data().set_mesh(p2e(V), p2e(F))
vw.launch()
Пример #10
0
# 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
Пример #11
0
  f = igl.eigen.MatrixXi()
  fn = igl.eigen.MatrixXd()
  vn = igl.eigen.MatrixXd()
  doublearea = igl.eigen.MatrixXd()

mesh_location = '../mesh_processing/data/bunny.obj'

mesh = MESH()
#mesh.v = igl.eigen.MatrixXd([[-1,-1,0.9],[1, -1, 1],[1, 1, 1.2],[-1, 1, 1],[-2, -2, 1], [2,1, 1]])
#mesh.f = igl.eigen.MatrixXd([[0,2,1],[0, 3,2], [4,3,0], [1,2,5]]).castint()

read_file = igl.readOBJ(mesh_location, mesh.v, mesh.f)

igl.per_face_normals(mesh.v, mesh.f, mesh.fn)
igl.per_vertex_normals(mesh.v, mesh.f, mesh.vn)
igl.doublearea(mesh.v, mesh.f, mesh.doublearea)

mesh.fn = np.array(mesh.fn)
mesh.vn = np.array(mesh.vn)
f = 0.5
z = -2

sensor = np.array([f, 0, z])
lighting = np.array([-f, 0, z])

sensor_normal = np.array([0, 0, 1])
lighting_normal = np.array([0, 0, 1])

opt = OPT()
opt.normal = 'n'
barycoord = rendering_igl.random_barycoord(mesh, opt.sample_num)
gt_mesh = MESH()

[x, y] = np.meshgrid(np.linspace(-1, 1, 7), np.linspace(-1, 1, 7))
x = np.concatenate(x)
y = np.concatenate(y)
z = -0.5 + np.sqrt(4 - np.multiply(x, x) - np.multiply(y, y))
v = np.vstack((x, y, z)).T
vn = -np.vstack((x, y, z + 0.5)).T / 2
tri = Delaunay(v[:, 0:2])

gt_mesh.vn = -np.vstack((x, y, z + 0.5)).T / 2
gt_mesh.f = igl.eigen.MatrixXi(tri.simplices[:, [0, 2, 1]])
gt_mesh.v = igl.eigen.MatrixXd(v)

igl.per_face_normals(gt_mesh.v, gt_mesh.f, gt_mesh.fn)
igl.doublearea(gt_mesh.v, gt_mesh.f, gt_mesh.doublearea)

gt_mesh.fn = np.array(gt_mesh.fn)
gt_render_opt = OPT(5000000)
gt_render_opt.normal = 'n'

tic = time.time()
gt_transient = rendering.render_all_collocate(gt_mesh, gt_render_opt)
print(time.time() - tic)

filename = os.getcwd() + '/setup_3.mat'
scipy.io.savemat(filename,
                 mdict={
                     'bin_width': gt_render_opt.distance_resolution,
                     'lighting': gt_render_opt.lighting,
                     'sensor': gt_render_opt.sensor,
Пример #13
0
    # Load meshes in OFF format
    igl.readOBJ(TUTORIAL_SHARED_PATH + "horse_quad.obj", V, F)

    # Count the number of irregular vertices, the border is ignored
    irregular = igl.is_irregular_vertex(V, F)
    vertex_count = V.rows()
    irregular_vertex_count = sum(irregular)
    irregular_ratio = irregular_vertex_count / vertex_count

    print("Irregular vertices: \n%d/%d (%.2f%%)\n" % (
        irregular_vertex_count, vertex_count, irregular_ratio * 100))

    # Compute areas, min, max and standard deviation
    area = igl.eigen.MatrixXd()
    igl.doublearea(V, F, area)
    area /= 2.0

    area_avg = area.mean()
    area_min = area.minCoeff() / area_avg
    area_max = area.maxCoeff() / area_avg
    area_ns = (area - area_avg) / area_avg
    area_sigma = math.sqrt(area_ns.squaredMean())

    print("Areas (Min/Max)/Avg_Area Sigma: \n%.2f/%.2f (%.2f)\n" % (
        area_min, area_max, area_sigma))

    # Compute per face angles, min, max and standard deviation
    angles = igl.eigen.MatrixXd()
    igl.internal_angles(V, F, angles)
    angles = 360.0 * (angles / (2 * math.pi))
Пример #14
0
def optimization(lr):
    folder_name = os.getcwd() + '/progress3-%f/' % lr
    if not os.path.isdir(folder_name):
        os.mkdir(folder_name)

    filename = os.getcwd() + '/setup_4.mat'
    setup = scipy.io.loadmat(filename)

    gt_transient = setup['gt_transient']
    gt_mesh = MESH()
    gt_mesh.v = igl.eigen.MatrixXd(torch.from_numpy(setup['gt_v']).numpy())
    gt_mesh.f = igl.eigen.MatrixXi(torch.from_numpy(setup['gt_f']).numpy())
    igl.per_face_normals(gt_mesh.v, gt_mesh.f, gt_mesh.fn)
    igl.doublearea(gt_mesh.v, gt_mesh.f, gt_mesh.doublearea)

    opt = OPT(5000)
    render_opt = OPT(50000)
    smooth_opt = SMOOTH_OPT()
    opt.space_carving_projection = 1

    space_carving_location = os.getcwd() + '/space_carving_mesh4.obj'
    space_carving_mesh = MESH()
    igl.readOBJ(space_carving_location, space_carving_mesh.v,
                space_carving_mesh.f)

    mesh = MESH()
    mesh_init_location = os.getcwd() + '/cnlos_5.obj'
    igl.readOBJ(mesh_init_location, mesh.v, mesh.f)
    #rendering.space_carving_initialization(mesh, space_carving_mesh, opt)

    igl.per_face_normals(mesh.v, mesh.f, mesh.fn)
    igl.doublearea(mesh.v, mesh.f, mesh.doublearea)

    mesh_optimization = MESH()
    mesh_optimization.v = torch.from_numpy(np.array(mesh.v))
    mesh_optimization.v.requires_grad_()

    l2, transient, original_l2 = rendering.evaluate_smooth_L2_collocate(
        gt_transient, mesh, render_opt, smooth_opt)
    print('%05d update time: %5.5f L2 loss: %5.5f old L2 loss: %5.5f' %
          (0, 0, l2, original_l2))

    filename = folder_name + 'init.mat'
    scipy.io.savemat(filename,
                     mdict={
                         'f': np.array(mesh.f),
                         'v': np.array(mesh.v),
                         'optim_v': mesh_optimization.v.data.numpy(),
                         'gt_v': np.array(gt_mesh.v),
                         'transient': transient,
                         'l2': l2,
                         'gt_transient': gt_transient
                     })

    optimizer = optim.Adam([mesh_optimization.v], lr=lr)

    dummy_loss = torch.sum(mesh_optimization.v)
    dummy_loss.backward()

    T = 10

    l2_record = np.empty(T)

    for t in range(T):
        if t % 30 == 0:
            if opt.w_width >= 10:
                opt.w_width -= 10
                render_opt.w_width -= 10
            opt.sample_num += 500
            render_opt.sample_num += 5000

        tic = time.time()
        optimizer.zero_grad()

        #grad = np.zeros((mesh.v.rows(),3))
        #for index in range(opt.lighting.shape[0]):
        #    grad += rendering.grad_collocate(index, gt_transient, transient, mesh, opt)
        grad = rendering.grad_parallel(gt_transient, transient, mesh, opt)
        grad += rendering.smooth_grad(mesh, smooth_opt)
        mesh_optimization.v.grad.data = torch.from_numpy(grad)
        optimizer.step()

        if opt.space_carving_projection == 1:
            mesh.v = rendering.space_carving_projection(
                mesh_optimization, space_carving_mesh)
        else:
            mesh.v = igl.eigen.MatrixXd(mesh_optimization.v.data.numpy())

        igl.per_face_normals(mesh.v, mesh.f, mesh.fn)
        igl.doublearea(mesh.v, mesh.f, mesh.doublearea)

        l2, transient, original_l2 = rendering.evaluate_smooth_L2_collocate(
            gt_transient, mesh, render_opt, smooth_opt)
        print('%05d update time: %5.5f L2 loss: %5.5f old L2 loss: %5.5f' %
              (t, time.time() - tic, l2, original_l2))
        l2_record[t] = l2
        filename = folder_name + '%05d.mat' % (t)
        scipy.io.savemat(filename,
                         mdict={
                             'v': np.array(mesh.v),
                             'transient': transient,
                             'l2': l2,
                             'origin_v': mesh_optimization.v.data.numpy(),
                             'grad': mesh_optimization.v.grad.data.numpy(),
                             'w_width': opt.w_width
                         })
        mesh_optimization.v.data = torch.from_numpy(np.array(mesh.v))

    filename = folder_name + 'loss_val.mat'
    scipy.io.savemat(filename, mdict={'l2': l2_record})