Example #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
Example #5
0
    def initialize(self):
        self.vertices = igl.eigen.MatrixXd()
        self.faces = igl.eigen.MatrixXi()

        try:
            if not igl.read_triangle_mesh(self.mesh_path, self.vertices,
                                          self.faces):
                print("failed to read mesh\n")
        except:
            traceback.print_exc(file=sys.stdout)
            sys.exit(-1)

        self.face_normals = igl.eigen.MatrixXd()
        igl.per_face_normals(self.vertices, self.faces, self.face_normals)
        self.vertex_normals = igl.eigen.MatrixXd()
        igl.per_vertex_normals(self.vertices, self.faces,
                               igl.PER_VERTEX_NORMALS_WEIGHTING_TYPE_AREA,
                               self.vertex_normals)

        self.vertex_data = e2p(self.vertices).astype(dtype=np.float32,
                                                     order='C')
        self.index_data = e2p(self.faces).astype(dtype=np.uint32, order='C')
        self.face_normal_data = e2p(self.face_normals).astype(dtype=np.float32,
                                                              order='C')
        self.vertex_normal_data = e2p(self.vertex_normals).astype(
            dtype=np.float32, order='C')

        self.num_faces = self.index_data.shape[0]
        self.num_vertices = self.vertex_data.shape[0]
        self.center = np.mean(self.vertex_data, axis=0)
        self.max_vals = np.max(self.vertex_data, axis=0)
        self.min_vals = np.min(self.vertex_data, axis=0)
        self.extents = self.max_vals - self.min_vals

        print("min = %s, max = %s, extents = %s" %
              (self.min_vals, self.max_vals, self.extents))

        self.vertex_data = (self.vertex_data - self.center) / self.extents

        self.vertex_byte_count = ArrayDatatype.arrayByteCount(self.vertex_data)
        self.vertex_normal_byte_count = ArrayDatatype.arrayByteCount(
            self.vertex_normal_data)
        self.index_byte_count = ArrayDatatype.arrayByteCount(self.index_data)
Example #6
0
        return True
    elif key == ord('2'):
        viewer.data.set_normals(N_vertices)
        return True
    elif key == ord('3'):
        viewer.data.set_normals(N_corners)
        return True
    return False


# Load a mesh in OFF format
igl.readOFF(TUTORIAL_SHARED_PATH + "fandisk.off", V, F)

# Compute per-face normals
N_faces = igl.eigen.MatrixXd()
igl.per_face_normals(V, F, N_faces)

# Compute per-vertex normals
N_vertices = igl.eigen.MatrixXd()
igl.per_vertex_normals(V, F, igl.PER_VERTEX_NORMALS_WEIGHTING_TYPE_AREA, N_vertices)

# Compute per-corner normals, |dihedral angle| > 20 degrees --> crease
N_corners = igl.eigen.MatrixXd()
igl.per_corner_normals(V, F, 20, N_corners)

# Plot the mesh
viewer = igl.viewer.Viewer()
viewer.callback_key_pressed = key_pressed
viewer.core.show_lines = False
viewer.data.set_mesh(V, F)
viewer.data.set_normals(N_faces)
Example #7
0

print("Press [space] to toggle showing surface.")
print("Press '.'/',' to push back/pull forward slicing plane.")

# Load mesh: (V,T) tet-mesh of convex hull, F contains original surface triangles
igl.readMESH(TUTORIAL_SHARED_PATH + "bunny.mesh", V, T, F)

# Call to point_mesh_squared_distance to determine bounds
sqrD = igl.eigen.MatrixXd()
I = igl.eigen.MatrixXi()
C = igl.eigen.MatrixXd()
igl.point_mesh_squared_distance(V, V, F, sqrD, I, C)
max_distance = math.sqrt(sqrD.maxCoeff())

# Precompute signed distance AABB tree
tree.init(V, F)

# Precompute vertex, edge and face normals
igl.per_face_normals(V, F, FN)
igl.per_vertex_normals(V, F, igl.PER_VERTEX_NORMALS_WEIGHTING_TYPE_ANGLE, FN,
                       VN)
igl.per_edge_normals(V, F, igl.PER_EDGE_NORMALS_WEIGHTING_TYPE_UNIFORM, FN, EN,
                     E, EMAP)

# Plot the generated mesh
update_visualization(viewer)
viewer.callback_key_down = key_down
viewer.data().show_lines = False
viewer.launch()
Example #8
0
#device = torch.device('cuda:1')
device = torch.device('cpu')
folder_name = os.getcwd() + '/progress-%f/' % args.lr
if not os.path.isdir(folder_name):
    os.mkdir(folder_name)

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

gt_transient = setup['gt_transient']
#mesh_location = '../mesh_processing/data/bunny.obj'
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)

opt = OPT(5000)
render_opt = OPT(50000)

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

mesh = MESH()
#mesh.v = space_carving_mesh.v
#mesh.f = space_carving_mesh.f
mesh.v = np.array(gt_mesh.v)
#mesh.v[:,2] -= 0.1
#mesh.v += np.random.normal(0,0.1,mesh.v.shape)
mesh.v = igl.eigen.MatrixXd(mesh.v)
Example #9
0
    update_visualization(viewer)
    return True


print("Press [space] to toggle showing surface.")
print("Press '.'/',' to push back/pull forward slicing plane.")

# Load mesh: (V,T) tet-mesh of convex hull, F contains original surface triangles
igl.readMESH(TUTORIAL_SHARED_PATH + "bunny.mesh", V, T, F)

# Call to point_mesh_squared_distance to determine bounds
sqrD = igl.eigen.MatrixXd()
I = igl.eigen.MatrixXi()
C = igl.eigen.MatrixXd()
igl.point_mesh_squared_distance(V, V, F, sqrD, I, C)
max_distance = math.sqrt(sqrD.maxCoeff())

# Precompute signed distance AABB tree
tree.init(V, F)

# Precompute vertex, edge and face normals
igl.per_face_normals(V, F, FN)
igl.per_vertex_normals(V, F, igl.PER_VERTEX_NORMALS_WEIGHTING_TYPE_ANGLE, FN, VN)
igl.per_edge_normals(V, F, igl.PER_EDGE_NORMALS_WEIGHTING_TYPE_UNIFORM, FN, EN, E, EMAP)

# Plot the generated mesh
update_visualization(viewer)
viewer.callback_key_down = key_down
viewer.core.show_lines = False
viewer.launch()
Example #10
0
if __name__ == "__main__":
    mesh_path = sys.argv[1]
    print("mesh_path = %s\n" % mesh_path)
    vertices = igl.eigen.MatrixXd()
    faces = igl.eigen.MatrixXi()

    try:
        if not igl.read_triangle_mesh(mesh_path, vertices, faces):
            print("failed to read mesh\n")
    except:
        traceback.print_exc(file=sys.stdout)
        sys.exit(-1)

    face_normals = igl.eigen.MatrixXd()
    igl.per_face_normals(vertices, faces, face_normals)
    vertex_normals = igl.eigen.MatrixXd()
    igl.per_vertex_normals(vertices, faces,
                           igl.PER_VERTEX_NORMALS_WEIGHTING_TYPE_AREA,
                           vertex_normals)

    vertex_data = e2p(vertices).flatten('C').astype(dtype=np.float32,
                                                    order='C')
    index_data = e2p(faces).flatten('C').astype(dtype=np.uint32, order='C')
    face_normal_data = e2p(face_normals).flatten('C').astype(dtype=np.float32,
                                                             order='C')
    vertex_normal_data = e2p(vertex_normals).flatten('C').astype(
        dtype=np.float32, order='C')

    num_faces = len(index_data) / 3
    num_vertices = len(vertex_data) / 3
Example #11
0

import pyigl as igl


class MESH:
  v = igl.eigen.MatrixXd()
  f = igl.eigen.MatrixXi()
  fn = igl.eigen.MatrixXd()


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

igl.per_face_normals(space_carving_mesh.v, space_carving_mesh.f, space_carving_mesh.fn)

P = igl.eigen.MatrixXd([[0,0,0], [0,0,0.2], [0,0.1,2]])
print(P)
S = igl.eigen.MatrixXd()
I = igl.eigen.MatrixXi()
C = igl.eigen.MatrixXd()
N = igl.eigen.MatrixXd()
igl.signed_distance(P, space_carving_mesh.v, space_carving_mesh.f, igl.SignedDistanceType(0), S,I,C,N)


for x in list(compress(range(P.rows()), S>0)):
    P.setRow(x, C.row(x))

print(P) 
Example #12
0
from utils import save_to_stl
import trimesh
import stl

if len(sys.argv) < 2:
    print(
        "Usage: verify_feasibility.py [filename] (Optional: robot name in XML file)"
    )
    exit()

FNAME = sys.argv[1]
# Step 0: Load in an XML file robot as CSG
csg_graph, last_name = parse_csg_graph(FNAME)
robot_name = last_name
VLast, FLast = csg_graph[robot_name]
# Face normals
FN = igl.eigen.MatrixXd()
igl.per_face_normals(VLast, FLast, FN)

## Vertices
V = np.array(VLast)
## Faces
F = np.array(FLast, dtype=np.int32)
## Face Normals
FN = np.array(FN)
## Making the mesh
robot = trimesh.base.Trimesh(V, F, FN)

# Step 1: Show the robot design to the user (using libigl to show triangle mesh)
robot.show()
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})