コード例 #1
0
def generate_frame_para_tex(obj_path,outfile):
    V_igl = igl.eigen.MatrixXd()
    t_v = igl.eigen.MatrixXd()
    n_v = igl.eigen.MatrixXd()
    v_f = igl.eigen.MatrixXi()
    n_f = igl.eigen.MatrixXi()
    t_f = igl.eigen.MatrixXi()

    igl.readOBJ(obj_path, V_igl, t_v, n_v,
                v_f, t_f, n_f)
    np_v = np.array(V_igl)
    np_t_v = np.array(t_v)
    np_n_v = np.array(n_v)
    np_v_f = np.array(v_f)
    np_n_f = np.array(n_f)
    np_t_f = np.array(t_f)
    np_v = np_v[:, 0:3]
    vertex_color = readVertexColor(obj_path)

    vertex_color[:, :] = (vertex_color[:, :] * 255)

    mesh = MetroMesh()
#    mesh.set_mesh(v=np_v, vertex_color=vertex_color, normal=np_n_v,
#                  vt=np_t_v, face=np_v_f, n_face=np_v_f, t_face=np_t_f)
    mesh.set_mesh(np_v, vertex_color, np_n_v,
                  np_t_v, np_v_f, np_v_f, np_t_f)
    FP_COLOR_TO_TEXTURE(outfile, mesh, 1024, 1024)
コード例 #2
0
def conver_mean_tex(para_objmesh, paraTexMat,outputdir):
    v = igl.eigen.MatrixXd()
    f = igl.eigen.MatrixXi()
    n = igl.eigen.MatrixXd()
    n_f = igl.eigen.MatrixXi()
    t = igl.eigen.MatrixXd()
    t_f = igl.eigen.MatrixXi()
    igl.readOBJ(para_objmesh, v, t, n, f, t_f, n_f)
    v = np.array(v)
    t = np.array(t)
    n = np.array(n)
    f = np.array(f)
    t_f = np.array(t_f)
    n_f = np.array(n_f)
    contact = mat_load(paraTexMat)
    target = contact['paraTex']
    texMU = target['texMU'][0, 0]
    cur_tex = texMU

    for i in range(0, cur_tex.size):
        if cur_tex[i] < 0.0:
            cur_tex[i] = 0.0
        if cur_tex[i] > 255.0:
            cur_tex[i] = 255.0
        cur_tex[i] /= 255.0
    cur_tex = cur_tex.reshape(cur_tex.size / 3, 3)
    output_path = outputdir + 'mean_tex' + '.obj'
    write_full_obj(v, f, n, n_f, t, t_f, cur_tex, output_path)
コード例 #3
0
def optimization(ratio):
	lr0 = 0.0001
	lr = lr0
	folder_name = os.getcwd() + '/test/'
	if not os.path.isdir(folder_name):
	  os.mkdir(folder_name)

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

	gt_transient = np.array(setup['transientsCalibrated'].T, dtype=np.double, order = 'C')

	opt = OPT(20000)
	opt.max_distance_bin = gt_transient.shape[1]
	opt.smooth_weight = 0.001
	opt.lighting = np.array(setup['coords'].T, dtype=np.float32, order='C')
	opt.sensor = np.array(setup['coords'].T, dtype=np.float32, order='C')
	opt.gt_mesh = False

	gt_mesh = MESH()
	mesh = MESH()
	mesh_init_location = os.getcwd() + '/setup/cnlos_horse_threshold.obj'
	igl.readOBJ(mesh_init_location, mesh.v, mesh.f)
	mesh.v = np.array(mesh.v, dtype=np.float32, order = 'C')
	mesh.f = np.array(mesh.f, dtype=np.int32, order = 'C')       

	transient, pathlength = rendering.forwardRendering(mesh, opt)		
	

	filename = folder_name + '1.mat'
	scipy.io.savemat(filename, mdict={'transient':transient})
コード例 #4
0
def obj2dat_vertex(filename):
    ref_name = '/raid/jzh/Featuredisentangle/data/disentangle/Mean_Face.obj'
    V = igl.eigen.MatrixXd()
    F = igl.eigen.MatrixXi()
    igl.readOBJ(ref_name, V, F)

    V1 = igl.eigen.MatrixXd()
    igl.readOBJ(filename, V1, F)

    # to dat
    e2p(V1 - V).tofile(filename[:-4] + '.dat')
コード例 #5
0
def pre_draw(viewer):
    global seq_id
    global time_step

    filename = "/Users/kostrikov/tmp/arap/results_lap/samples_epoch_{0:03d}_{1:03d}".format(
        seq_id, time_step % 20)
    if time_step < 20:
        filename += "_0curr.obj"
    else:
        filename += "_1pred.obj"

    global V, F
    global V_other, F_other
    igl.readOBJ(filename, V, F)

    if filename.find('1pred') and args.draw_gt == True:
        filename_other = filename.replace('1pred', '2targ')
        igl.readOBJ(filename_other, V_other, F_other)

        V_full = igl.cat(1, V, V_other)
        F_full = igl.cat(1, F, F_other + V.rows())
    else:
        V_full = V
        F_full = F

    viewer.data.clear()
    viewer.data.set_mesh(V_full, F_full)

    C = igl.eigen.MatrixXd(F_full.rows(), 3)

    red = igl.eigen.MatrixXd([[1.0, 0.0, 0.0]])
    blue = igl.eigen.MatrixXd([[0.0, 0.0, 1.0]])
    green = igl.eigen.MatrixXd([[0.0, 1.0, 0.0]])

    for f in range(F_full.rows()):
        if time_step < 20:
            C.setRow(f, red)
        else:
            if f < F.rows():
                C.setRow(f, blue)
            else:
                C.setRow(f, green)

    viewer.data.set_colors(C)

    time_step += 1
    if time_step == 40:
        time_step = 0
        seq_id += 1

        if seq_id == 64:
            seq_id = 0

    return False
コード例 #6
0
def write_align_mesh(src, tar, filename, index = None):
	src_mesh=om.read_trimesh(src)
	tar_mesh=om.read_trimesh(tar)
	point_array_src = src_mesh.points()
	point_array_tar = tar_mesh.points()
	R, t = rigid_registeration(point_array_src, point_array_tar, index)
	register_array_src = np.dot(R, point_array_src.T).T + np.tile(t,point_array_src.shape[0]).reshape(-1,3)
	new_V = igl.eigen.MatrixXd(register_array_src.astype(np.float64))
	V = igl.eigen.MatrixXd()
	F = igl.eigen.MatrixXi()
	igl.readOBJ(src, V,F)
	igl.writeOBJ(filename, new_V, F)
コード例 #7
0
ファイル: compare_error.py プロジェクト: dilevin/AutoDef
def load_obj_verts(dir):
    Vs = []
    filenames = sorted(os.listdir(dir))

    for filename in filenames:
        path = os.path.join(dir, filename)
        V = igl.eigen.MatrixXd()
        F = igl.eigen.MatrixXi()
        igl.readOBJ(path, V, F)

        Vs.append(e2p(V))

    return numpy.array(Vs)
コード例 #8
0
def convert_para_tex(para_objmesh, paraTexMat):

    v = igl.eigen.MatrixXd()

    f = igl.eigen.MatrixXi()
    n = igl.eigen.MatrixXd()
    n_f = igl.eigen.MatrixXi()
    t = igl.eigen.MatrixXd()
    t_f = igl.eigen.MatrixXi()
    igl.readOBJ(para_objmesh, v, t, n, f, t_f, n_f)
    v = np.array(v)
    t = np.array(t)
    n = np.array(n)
    f = np.array(f)
    t_f = np.array(t_f)
    n_f = np.array(n_f)
    contact = mat_load(paraTexMat)
    target = contact['paraTex']
    texPC = target['texPC'][0, 0]
    texMU = target['texMU'][0, 0]
    texEV = target['texEV'][0, 0]

    for i_pc in range(0, 1):
        '''
        coff = np.zeros((199,1))
        coff[i_pc] = 5e3
        cur_tex = texMU+np.dot(texPC,coff)
        cur_tex = cur_tex.reshape(cur_tex.size/3,3)
        output_path = './texpc/' + 'pc_' + str(i_pc) + '_coff_' + str(float(coff[i_pc])) + '.obj'
        write_full_obj(v,f,n,n_f,t,t_f,cur_tex/255.0,output_path)
        '''
        coff = np.zeros((199, 1))
        coff[i_pc] = 4.1031792e3 * 10
        print coff.shape
        coff.reshape(coff.size, 1)
        print coff.shape
        cur_tex = texMU + np.dot(texPC, coff)
        for i in range(0, cur_tex.size):
            if cur_tex[i] < 0.0:
                cur_tex[i] = 0.0
            if cur_tex[i] > 255.0:
                cur_tex[i] = 255.0
            cur_tex[i] /= 255.0

        cur_tex = cur_tex.reshape(cur_tex.size / 3, 3)

        output_path = './texpc/' + 'pc_' + str(i_pc) + '_coff_' + str(
            float(coff[i_pc])) + '.obj'
        write_full_obj(v, f, n, n_f, t, t_f, cur_tex, output_path)
    '''
コード例 #9
0
def write_landmark_to_obj(file_path, landmark, size=1000):
    sphere_v = igl.eigen.MatrixXd()
    sphere_f = igl.eigen.MatrixXi()
    igl.readOBJ('sphere.obj', sphere_v, sphere_f)
    sphere_v = np.array(sphere_v)
    sphere_f = np.array(sphere_f)
    lmk_num = landmark.shape[0]
    sphere_v_move = np.array([])
    all_v = np.array([])
    all_f = np.array([])
    for i in range(0, lmk_num):
        sphere_v_move = size * sphere_v + landmark[i, :]
        all_v, all_f = add_vertex_faces(all_v, all_f, sphere_v_move, sphere_f)
    igl.writeOBJ(file_path, igl.eigen.MatrixXd(all_v),
                 igl.eigen.MatrixXi(all_f.astype('intc')))
コード例 #10
0
def read_igl_obj(para_objmesh):
    v = igl.eigen.MatrixXd()
    f = igl.eigen.MatrixXi()
    n = igl.eigen.MatrixXd()
    n_f = igl.eigen.MatrixXi()
    t = igl.eigen.MatrixXd()
    t_f = igl.eigen.MatrixXi()
    igl.readOBJ(para_objmesh, v, t, n, f, t_f, n_f)
    v = np.array(v)
    t = np.array(t)
    n = np.array(n)
    f = np.array(f)
    t_f = np.array(t_f)
    n_f = np.array(n_f)
    return v, f, t, t_f, n, n_f
コード例 #11
0
def V2M2(
        array,
        filename,
        ref_name='/raid/jzh/Featuredisentangle/data/disentangle/Mean_Face.obj',
        v_num=11510):
    def p2e(m):
        if isinstance(m, np.ndarray):
            if not (m.flags['C_CONTIGUOUS'] or m.flags['F_CONTIGUOUS']):
                raise TypeError('p2e support either c-order or f-order')
            if m.dtype.type in [np.int32, np.int64]:
                return igl.eigen.MatrixXi(m.astype(np.int32))
            elif m.dtype.type in [np.float64, np.float32]:
                return igl.eigen.MatrixXd(m.astype(np.float64))
            elif m.dtype.type == np.bool:
                return igl.eigen.MatrixXb(m)
            raise TypeError(
                "p2e only support dtype float64/32, int64/32 and bool")
        if sparse.issparse(m):
            # convert in a dense matrix with triples
            coo = m.tocoo()
            triplets = np.vstack((coo.row, coo.col, coo.data)).T

            triples_eigen_wrapper = igl.eigen.MatrixXd(triplets)

            if m.dtype.type == np.int32:
                t = igl.eigen.SparseMatrixi()
                t.fromcoo(triples_eigen_wrapper)
                return t
            elif m.dtype.type == np.float64:
                t = igl.eigen.SparseMatrixd()
                t.fromCOO(triples_eigen_wrapper)
                return t

        raise TypeError("p2e only support numpy.array or scipy.sparse")

    # read reference mesh
    V = igl.eigen.MatrixXd()
    F = igl.eigen.MatrixXi()
    igl.readOBJ(ref_name, V, F)
    #igl.readOBJ('/home/jzh/Featuredisentangle/src/Mean_Face.obj',V,F)
    # read dat file and add to V matrix, then write mesh
    tar_v = array.copy()  #np.fromfile('0_1008.dat')
    tar_v = tar_v.reshape(v_num, 3)
    new_v = p2e(tar_v)
    igl.writeOBJ(filename, new_v, F)
コード例 #12
0
def convert_para_tex(para_objmesh, paraTexMat,outputdir,ev_std=5):

    v = igl.eigen.MatrixXd()
    f = igl.eigen.MatrixXi()
    n = igl.eigen.MatrixXd()
    n_f = igl.eigen.MatrixXi()
    t = igl.eigen.MatrixXd()
    t_f = igl.eigen.MatrixXi()
    igl.readOBJ(para_objmesh, v,t,n,f,t_f,n_f)
    v = np.array(v)
    t = np.array(t)
    n = np.array(n)
    f = np.array(f)
    t_f = np.array(t_f)
    n_f = np.array(n_f)
    contact = mat_load(paraTexMat)
    target = contact['paraTex']
    texPC = target['texPC'][0, 0]
    texMU = target['texMU'][0, 0]
    texEV = target['texEV'][0, 0]
    for i_pc in range(0,len(texEV)):

        def dir(plus=True):
            coff = np.zeros((len(texEV),1))
            if plus:
                coff[i_pc] =texEV[i_pc]*ev_std  #使用5倍的方差
            else:
                coff[i_pc] = -texEV[i_pc] * ev_std  # 使用5倍的方差
            coff.reshape(coff.size,1)
            cur_tex = texMU+np.dot(texPC,coff)
            for i in range(0,cur_tex.size):
                if cur_tex[i]<0.0:
                    cur_tex[i] =0.0
                if cur_tex[i] > 255.0:
                    cur_tex[i] = 255.0
                cur_tex[i]/=255.0
            cur_tex = cur_tex.reshape(cur_tex.size/3,3)
            if plus:
                output_path = outputdir + 'pc_' + str(i_pc).zfill(3) + 'std_'+str(ev_std) + '+'+'.obj'
            else:
                output_path = outputdir + 'pc_' + str(i_pc).zfill(3) + 'std_' + str(ev_std) + '-' + '.obj'
            write_full_obj(v,f,n,n_f,t,t_f,cur_tex,output_path)

        dir(True)
        dir(False)
コード例 #13
0
def convertObj2Mat(objpath, matpath, istarget):
    v = igl.eigen.MatrixXd()
    f = igl.eigen.MatrixXi()
    n = igl.eigen.MatrixXd()
    n_f = igl.eigen.MatrixXi()
    t = igl.eigen.MatrixXd()
    t_f = igl.eigen.MatrixXi()
    igl.readOBJ(objpath, v, t, n, f, t_f, n_f)
    v = np.array(v)
    f = np.array(f)
    n = np.array(n)
    if istarget:
        Target = {'vertices': v, 'faces': f + 1, 'normals': n}
        Target = {'Target': Target}
        mat_save(Target, matpath)
    else:
        Source = {'vertices': v, 'faces': f + 1, 'normals': n}
        Source = {'Source': Source}
        mat_save(Source, matpath)
コード例 #14
0
ファイル: timewarp.py プロジェクト: itsvismay/Basis
def time_warp(meshF, meshC, E_0=None, K_0=None, seconds=1, timestep=1e-3):
    time_in_secs = 0
    E_i = solver.solve(meshF, meshC, E_0=E_0)
    some_epsilon = 2
    Vf = igl.eigen.MatrixXd()
    Ff = igl.eigen.MatrixXi()
    for i in range(int(seconds / timestep)):
        meshC.step()
        time_in_secs = timestep * i
        if (i % 100):
            #Check meshes and re-solve
            name = "checkmeshes/mesh@" + str(
                GV.Global_Youngs) + "E@" + str(time_in_secs) + "s.obj"
            igl.readOBJ(name, Vf, Ff)
            n = np.linalg.norm(meshC.get_embedded_mesh() -
                               np.delete(Vf, -1, 1))
            print("n", n, "DOF", meshC.nonDupSize, "elem",
                  len(meshC.activeElems))
            exit()
            if (n > some_epsilon):
                E_i = solver.solve(meshF, meshC, E_0=E_i)
コード例 #15
0
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)
コード例 #16
0
def generate_mean_face():
    print("generating mean face shapes")
    V = igl.eigen.MatrixXd()
    F = igl.eigen.MatrixXi()
    igl.readOBJ('../data/disentangle/Mean_Face.obj', V, F)
    try:
        os.makedirs('../data/FWH/Mean_Face')
    except:
        pass

    pool = ThreadPool()
    for i in tqdm(range(47)):

        def process(j):
            return om.read_trimesh(
                '../data/FaceWarehouse_Data/Tester_{}/Blendshape/shape_{}.obj'.
                format(j, i)).points()

        gather_mesh = pool.map(process, range(1, 151))
        mean_mesh = igl.eigen.MatrixXd(
            (sum(gather_mesh) / len(gather_mesh)).astype(np.float64))
        igl.writeOBJ('../data/FWH/Mean_Face/shape_{}.obj'.format(i), mean_mesh,
                     F)
コード例 #17
0
def generate_para_frame_obj(frame_para_objmesh,outputdir):

    v = igl.eigen.MatrixXd()
    f = igl.eigen.MatrixXi()
    n = igl.eigen.MatrixXd()
    n_f = igl.eigen.MatrixXi()
    t = igl.eigen.MatrixXd()
    t_f = igl.eigen.MatrixXi()
    igl.readOBJ(frame_para_objmesh, v, t, n, f, t_f, n_f)
    v = np.array(v)
    t = np.array(t)
    n = np.array(n)
    f = np.array(f)
    t_f = np.array(t_f)
    n_f = np.array(n_f)

    ev_std =5
    for i_pc in range(0,199):
        output_path = outputdir +'frame_pc_' + str(i_pc).zfill(3) + 'std_' + str(ev_std) + '+' + '.obj'
        write_full_obj(v, f, n, n_f, t, t_f, np.array([]), output_path,generate_mtl=True,verbose=False,
                       img_name = 'pc_' + str(i_pc).zfill(3) + 'std_' + str(ev_std) + '+'+ '.png')
        output_path = outputdir + 'frame_pc_' + str(i_pc).zfill(3) + 'std_' + str(ev_std) + '-' + '.obj'
        write_full_obj(v, f, n, n_f, t, t_f, np.array([]), output_path, generate_mtl=True, verbose=False,
                       img_name='pc_' + str(i_pc).zfill(3) + 'std_' + str(ev_std) + '-' + '.png')
コード例 #18
0
    v = igl.eigen.MatrixXd()
    f = igl.eigen.MatrixXi()
    fn = igl.eigen.MatrixXd()


#mesh = MESH()
#z = .38
#v = np.array([[-.25, -.25, z], [.25, -.25, z], [.25, .25, z], [-.25, .25, z], [0, -.25, z], [.25, 0, z], [0, .25, z], [-.25,0,z], [0,0,.7]])
#f = np.array([[0, 1, 2], [0,2,3]])
#mesh.v = np.array(v, dtype=np.float32, order = 'C')
#mesh.f = np.array(f, dtype=np.int32, order = 'C')

bunny_location = os.getcwd(
) + '/../../mesh_processing/data/bunny_parallel_T.obj'
gt_mesh = MESH()
igl.readOBJ(bunny_location, gt_mesh.v, gt_mesh.f)

v = np.array(gt_mesh.v.leftCols(3) / 100, dtype=np.float32, order='C')
v[:, 2] = v[:, 2] - 0.5
faces = np.array(gt_mesh.f, dtype=np.int32, order='C')

numBins = 1200
num_sample = 50000
lower_bound = 0
resolution = 0.0012
upper_bound = numBins * resolution

transient = np.zeros((1, numBins), dtype=np.double, order='C')
data = np.zeros((1, numBins), dtype=np.double, order='C')
weight = np.ones((1, numBins), dtype=np.double, order='C')
pathlengths = np.zeros(numBins, dtype=np.double, order='C')
コード例 #19
0
sys.path.insert(0, '/home/chiayint/research/libigl/python/')

import pyigl as igl

import embree_intersector


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


mesh_location = '../../mesh_processing/data/bunny.obj'
mesh = MESH()
read_file = igl.readOBJ(mesh_location, mesh.v, mesh.f)
v = np.array(mesh.v, dtype=np.float32, order='C')
f = np.array(mesh.f, dtype=np.int32, order='C')

test_mesh = embree_intersector.PyMesh(v, f)

resolution = 625 * 8
#resolution = 10
[x, y] = np.meshgrid(np.linspace(-0.5, 0.5, resolution),
                     np.linspace(-0.5, 0.5, resolution))
x = np.concatenate(x)
y = np.concatenate(y)
o = np.vstack((x, y, -1 * np.ones_like(x))).T
o_igl = igl.eigen.MatrixXd(o)
o = np.array(o, dtype=np.float32, order='C')
コード例 #20
0
    return False


def key_down(viewer, key, mods):
    global bc_frac, bc_dir, deformation_field, V, U, V_bc, U_bc, F, b

    if key == ord(' '):
        viewer.core.is_animating = not viewer.core.is_animating
        return True
    if key == ord('D') or key == ord('d'):
        deformation_field = not deformation_field
        return True
    return False


igl.readOBJ(TUTORIAL_SHARED_PATH + "decimated-max.obj", V, F)
U = igl.eigen.MatrixXd(V)

# S(i) = j: j<0 (vertex i not in handle), j >= 0 (vertex i in handle j)
S = igl.eigen.MatrixXd()
igl.readDMAT(TUTORIAL_SHARED_PATH + "decimated-max-selection.dmat", S)

S = S.castint()

b = igl.eigen.MatrixXi([[
    t[0] for t in [(i, S[i]) for i in range(0, V.rows())] if t[1] >= 0
]]).transpose()

# Boundary conditions directly on deformed positions
U_bc.resize(b.rows(), V.cols())
V_bc.resize(b.rows(), V.cols())
コード例 #21
0
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)

mesh.f = gt_mesh.f
igl.per_face_normals(mesh.v, mesh.f, mesh.fn)

mesh_optimization = MESH()
mesh_optimization.v = torch.from_numpy(np.array(mesh.v)).to(device)
mesh_optimization.v.requires_grad_()
コード例 #22
0
    BE = igl.eigen.MatrixXi()
    P = igl.eigen.MatrixXi()
    W = igl.eigen.MatrixXd()
    M = igl.eigen.MatrixXd()

    sea_green = igl.eigen.MatrixXd([[70. / 255., 252. / 255., 167. / 255.]])

    anim_t = 0.0
    anim_t_dir = 0.015
    use_dqs = False
    recompute = True
    animation = False  # Flag needed as there is some synchronization problem with viewer.core.is_animating

    poses = [[]]

    igl.readOBJ(TUTORIAL_SHARED_PATH + "arm.obj", V, F)
    U = igl.eigen.MatrixXd(V)
    igl.readTGF(TUTORIAL_SHARED_PATH + "arm.tgf", C, BE)

    # retrieve parents for forward kinematics
    igl.directed_edge_parents(BE, P)
    rest_pose = igl.RotationList()
    igl.directed_edge_orientations(C, BE, rest_pose)
    poses = [[igl.eigen.Quaterniond.Identity() for i in range(4)]
             for j in range(4)]

    twist = igl.eigen.Quaterniond(pi, igl.eigen.MatrixXd([1, 0, 0]))
    poses[1][2] = rest_pose[2] * twist * rest_pose[2].conjugate()
    bend = igl.eigen.Quaterniond(-pi * 0.7, igl.eigen.MatrixXd([0, 0, 1]))
    poses[3][2] = rest_pose[2] * bend * rest_pose[2].conjugate()
コード例 #23
0
ファイル: 701_Statistics.py プロジェクト: bbrrck/libigl
import math

sys.path.insert(0, os.getcwd() + "/../")
import pyigl as igl

from shared import TUTORIAL_SHARED_PATH, check_dependencies

dependencies = []
check_dependencies(dependencies)

if __name__ == "__main__":
    V = igl.eigen.MatrixXd()
    F = igl.eigen.MatrixXi()

    # 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
コード例 #24
0
ファイル: my_utils.py プロジェクト: dilevin/AutoDef
def load_obj(path):
    V = igl.eigen.MatrixXd()
    F = igl.eigen.MatrixXi()
    igl.readOBJ(path, V, F)

    return e2p(V)
コード例 #25
0
    global z_max, z_dir, k, resolve, V, U, Z, F, b, bc

    if key == ord(' '):
        viewer.core.is_animating = not viewer.core.is_animating
    elif key == ord('.'):
        k = k + 1
        k = (4 if k > 4 else k)
        resolve = True
    elif key == ord(','):
        k = k - 1
        k = (1 if k < 1 else k)
        resolve = True
    return True


igl.readOBJ(TUTORIAL_SHARED_PATH + "bump-domain.obj", V, F)
U = igl.eigen.MatrixXd(V)

# Find boundary vertices outside annulus

Vrn = V.rowwiseNorm()
is_outer = [Vrn[i] - 1.00 > -1e-15 for i in range(0, V.rows())]
is_inner = [Vrn[i] - 0.15 < 1e-15 for i in range(0, V.rows())]
in_b = [is_outer[i] or is_inner[i] for i in range(0, len(is_outer))]

b = igl.eigen.MatrixXi([[i for i in range(0, V.rows())
                         if (in_b[i])]]).transpose()

bc.resize(b.size(), 1)

for bi in range(0, b.size()):
コード例 #26
0
def optimization(ratio):
    lr0 = 0.0005
    lr = lr0
    folder_name = os.getcwd() + '/progress-b-1-%f/' % ratio
    if not os.path.isdir(folder_name):
        os.mkdir(folder_name)

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

    gt_transient = np.array(setup['gt_transient'], dtype=np.double, order='C')

    gt_mesh = MESH()
    gt_mesh.v = igl.eigen.MatrixXd(np.array(setup['gt_v'], dtype=np.double))
    gt_mesh.f = igl.eigen.MatrixXd(np.array(setup['gt_f'],
                                            dtype=np.double)).castint()

    opt = OPT(20000)
    opt.max_distance_bin = gt_transient.shape[1]
    opt.smooth_weight = 0.001

    mesh = MESH()
    mesh_init_location = os.getcwd() + '/init/cnlos_bunny_threshold.obj'

    igl.readOBJ(mesh_init_location, mesh.v, mesh.f)
    mesh.v = np.array(mesh.v, dtype=np.float32, order='C')
    mesh.f = np.array(mesh.f, dtype=np.int32, order='C')

    opt.resolution = 64
    opt.smooth_ratio = ratio

    rendering.isotropic_remeshing(mesh, .5 / opt.resolution)
    old_v = np.array(mesh.v)

    rendering.compute_mesh_affinity(mesh)
    rendering.border_indicator(mesh)

    weight = rendering.create_weighting_function(gt_transient, opt.gamma)

    global_counter = 0

    old_v = np.array(mesh.v)
    old_f = np.array(mesh.f)
    global_counter, convergence_flag, l2_record = optimize_parameters.optimize_shape(
        mesh, gt_transient, weight, opt, 15, lr, gt_mesh, global_counter,
        folder_name)
    grad_v = np.array(mesh.v)

    rendering.el_topo_gradient(mesh, old_v)
    rendering.el_topo_remeshing(mesh, .5 / opt.resolution)
    eltopo_v = np.array(mesh.v)
    eltopo_f = np.array(mesh.f)

    rendering.isotropic_remeshing(mesh, .5 / opt.resolution)

    isotropic_v = np.array(mesh.v)
    isotropic_f = np.array(mesh.f)

    filename = folder_name + 'data.mat'
    scipy.io.savemat(filename,
                     mdict={
                         'old_v': old_v,
                         'old_f': old_f,
                         'grad_v': grad_v,
                         'eltopo_v': eltopo_v,
                         'eltopo_f': eltopo_f,
                         'isotropic_v': isotropic_v,
                         'isotropic_f': isotropic_f
                     })
コード例 #27
0
    viewer.data.compute_normals()
    return False

def key_down(viewer, key, mods):
    global bc_frac, bc_dir,deformation_field, V, U, V_bc, U_bc, F, b

    if key == ord(' '):
        viewer.core.is_animating = not viewer.core.is_animating
        return True
    if key == ord('D') or key == ord('d'):
        deformation_field = not deformation_field;
        return True
    return False


igl.readOBJ("../../tutorial/shared/decimated-max.obj",V,F)
U = igl.eigen.MatrixXd(V)

# S(i) = j: j<0 (vertex i not in handle), j >= 0 (vertex i in handle j)
S = igl.eigen.MatrixXd()
igl.readDMAT("../../tutorial/shared/decimated-max-selection.dmat",S)

S = S.castint()

b = igl.eigen.MatrixXi([[t[0] for t in [(i,S[i]) for i in range(0,V.rows())] if t[1] >= 0]]).transpose()

# Boundary conditions directly on deformed positions
U_bc.resize(b.rows(),V.cols())
V_bc.resize(b.rows(),V.cols())

for bi in range(0,b.rows()):
コード例 #28
0
    global z_max, z_dir, k, resolve, V, U, Z, F, b, bc

    if key == ord(' '):
        viewer.core.is_animating = not viewer.core.is_animating
    elif key == ord('.'):
        k = k + 1
        k = (4 if k>4 else k)
        resolve = True
    elif key == ord(','):
        k = k - 1
        k = (1 if k<1 else k)
        resolve = True
    return True


igl.readOBJ("../../tutorial/shared/bump-domain.obj",V,F)
U = igl.eigen.MatrixXd(V)

# Find boundary vertices outside annulus

Vrn = V.rowwiseNorm()
is_outer = [Vrn[i]-1.00 > -1e-15 for i in range(0,V.rows())]
is_inner = [Vrn[i]-0.15 <  1e-15 for i in range(0,V.rows())]
in_b = [ is_outer[i] or is_inner[i] for i in range(0,len(is_outer))]

b = igl.eigen.MatrixXi([[i for i in range(0,V.rows()) if (in_b[i])]]).transpose();

bc.resize(b.size(),1)

for bi in range(0,b.size()):
    bc[bi] = (0.0 if is_outer[b[bi]] else 1.0)
コード例 #29
0
def optimization(ratio):
    lr0 = 0.0001
    lr = lr0
    folder_name = os.getcwd() + '/progress-b-1-%f/' % ratio
    if not os.path.isdir(folder_name):
        os.mkdir(folder_name)

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

    gt_transient = np.array(setup['transient'], dtype=np.double, order='C')

    opt = OPT(20000)
    opt.max_distance_bin = gt_transient.shape[1]
    opt.smooth_weight = 0.001
    opt.lighting = np.array(setup['lighting'], dtype=np.float32, order='C')
    opt.sensor = np.array(setup['lighting'], dtype=np.float32, order='C')
    opt.gt_mesh = False

    gt_mesh = MESH()
    mesh = MESH()
    mesh_init_location = os.getcwd() + '/cnlos_s_threshold.obj'
    igl.readOBJ(mesh_init_location, mesh.v, mesh.f)
    mesh.v = np.array(mesh.v, dtype=np.float32, order='C')
    mesh.f = np.array(mesh.f, dtype=np.int32, order='C')

    opt.resolution = 64
    opt.smooth_ratio = ratio

    rendering.isotropic_remeshing(mesh, .5 / opt.resolution)
    old_v = np.array(mesh.v)

    rendering.compute_mesh_affinity(mesh)
    rendering.border_indicator(mesh)

    weight = rendering.create_weighting_function(gt_transient, opt.gamma)

    mesh.albedo = optimize_parameters.initial_fitting_albedo(
        mesh, gt_transient, weight, opt)

    global_counter = 0
    l2 = np.empty(400)
    albedo = np.empty(400)
    resolution_cnt = 0
    for t in range(400):
        if mesh.f.shape[0] > 250000:
            break

        if t < 30 or resolution_cnt < 5:
            global_counter, l2_record = optimize_parameters.optimize_albedo(
                mesh, gt_transient, weight, opt, 50, global_counter,
                folder_name)

        if t == 0:
            l2_0 = l2_record

        opt.albedo_lr = (l2_reccord / l2_0) * opt_albedo_lr0 * (
            (0.99)**(t / 5))
        lr = (l2_record / l2_0) * lr0 * ((0.99)**(t / 5))
        print('new lr %f' % lr)

        old_v = np.array(mesh.v)
        global_counter, convergence_flag, l2_record = optimize_parameters.optimize_shape(
            mesh, gt_transient, weight, opt, 15, lr, gt_mesh, global_counter,
            folder_name)

        resolution_cnt += 1
        if resolution_cnt == 50:
            resolution_cnt = 0
            opt.resolution *= 1.5
            opt.sample_num *= 1.5

        if convergence_flag:
            if opt.testing_flag == 1:
                opt.testing_flag = 0
                opt.smooth_ratio = ratio / 10 + t / 100
                print('shading')
            else:
                opt.testing_flag = 1
                opt.smooth_ratio = ratio + t / 10

        rendering.el_topo_gradient(mesh, old_v)
        rendering.el_topo_remeshing(mesh, .5 / opt.resolution)
        rendering.isotropic_remeshing(mesh, .5 / opt.resolution)

        rendering.compute_mesh_affinity(mesh)
        rendering.removeTriangle(mesh, opt)

        rendering.compute_mesh_affinity(mesh)
        rendering.border_indicator(mesh)

        filename = folder_name + '%05d.mat' % (t)
        scipy.io.savemat(filename,
                         mdict={
                             'v': mesh.v,
                             'f': mesh.f,
                             'albedo': mesh.albedo
                         })
        l2[t] = l2_record
        albedo[t] = mesh.albedo

    filename = folder_name + 'progress.mat'
    scipy.io.savemat(filename, mdict={'albedo': albedo, 'l2': l2})
コード例 #30
0
    global z_max, z_dir, k, resolve, V, U, Z, F, b, bc

    if key == ord(' '):
        viewer.core.is_animating = not viewer.core.is_animating
    elif key == ord('.'):
        k = k + 1
        k = (4 if k > 4 else k)
        resolve = True
    elif key == ord(','):
        k = k - 1
        k = (1 if k < 1 else k)
        resolve = True
    return True


igl.readOBJ(TUTORIAL_SHARED_PATH + "bump-domain.obj", V, F)
U = igl.eigen.MatrixXd(V)

# Find boundary vertices outside annulus

Vrn = V.rowwiseNorm()
is_outer = [Vrn[i] - 1.00 > -1e-15 for i in range(0, V.rows())]
is_inner = [Vrn[i] - 0.15 < 1e-15 for i in range(0, V.rows())]
in_b = [is_outer[i] or is_inner[i] for i in range(0, len(is_outer))]

b = igl.eigen.MatrixXi([[i for i in range(0, V.rows()) if (in_b[i])]]).transpose()

bc.resize(b.size(), 1)

for bi in range(0, b.size()):
    bc[bi] = (0.0 if is_outer[b[bi]] else 1.0)
コード例 #31
0
ファイル: 507_PolyVectorField.py プロジェクト: Emisage/libigl
            VF.setRow(b[i],bc.block(i,n*3,1,3))

        for i in range(0,samples.rows()):
            VF.setRow(samples[i],pvf.block(samples[i],n*3,1,3))

        c = VF.rowwiseNorm()

        C2 = igl.eigen.MatrixXd()
        igl.jet(c,1,1+rand_factor,C2)
        viewer.data.add_edges(B - global_scale*VF, B + global_scale*VF , C2)

    return False


# Load a mesh in OBJ format
igl.readOBJ("../../tutorial/shared/lilium.obj", V, F)
samples = readSamples("../../tutorial/shared/lilium.samples.0.2")

# Compute local basis for faces
igl.local_basis(V,F,B1,B2,B3)

# Compute face barycenters
igl.barycenter(V, F, B)

# Compute scale for visualizing fields
global_scale = 0.2*igl.avg_edge_length(V, F)

# Make the example deterministic
random.seed(0)

viewer = igl.viewer.Viewer()
コード例 #32
0
    f = igl.eigen.MatrixXi()
    vn = 0


folder_name = os.getcwd() + '/gradient_test/'
if not os.path.isdir(folder_name):
    os.mkdir(folder_name)

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

gt_transient = np.array(setup['gt_transient'], dtype=np.double, order='C')

mesh = MESH()
mesh_init_location = os.getcwd() + '/cnlos_bunny_threshold.obj'
igl.readOBJ(mesh_init_location, mesh.v, mesh.f)
mesh.v = np.array(mesh.v, dtype=np.float32, order='C')
mesh.f = np.array(mesh.f, dtype=np.int32, order='C')

T = 10
#T = 150
for power in range(4, 7):

    opt = OPT(10**power)

    for t in range(T):
        print('t = %d' % t)
        tic = time.time()
        transient, grad, pathlength = rendering.inverseRendering(
            mesh, gt_transient, opt)
        print(time.time() - tic)
コード例 #33
0
def optimization(ratio):
    lr0 = 0.0001
    lr = lr0
    folder_name = os.getcwd() + '/progress-b-3-%f/' % ratio
    if not os.path.isdir(folder_name):
        os.mkdir(folder_name)

    test_num = 1
    filename = os.getcwd() + '/setup/bunny_transient_64_0_%d.mat' % test_num
    setup = scipy.io.loadmat(filename)

    gt_transient = np.array(setup['gt_transient'], dtype=np.double, order='C')

    gt_mesh = MESH()
    gt_mesh.v = igl.eigen.MatrixXd(np.array(setup['gt_v'], dtype=np.double))
    gt_mesh.f = igl.eigen.MatrixXd(np.array(setup['gt_f'],
                                            dtype=np.double)).castint()

    opt = OPT(20000)
    opt.max_distance_bin = gt_transient.shape[1]
    opt.smooth_weight = 0.001

    mesh = MESH()

    mesh_init_location = os.getcwd(
    ) + '/init/cnlos_bunny_threshold_64_0_%d.obj' % test_num
    igl.readOBJ(mesh_init_location, mesh.v, mesh.f)
    mesh.v = np.array(mesh.v, dtype=np.float32, order='C')
    mesh.f = np.array(mesh.f, dtype=np.int32, order='C')

    opt.resolution = 64
    opt.smooth_ratio = ratio

    rendering.isotropic_remeshing(mesh, .5 / opt.resolution)
    old_v = np.array(mesh.v)

    rendering.compute_mesh_affinity(mesh)
    rendering.border_indicator(mesh)

    weight = rendering.create_weighting_function(gt_transient, opt.gamma)

    global_counter = 0

    l2 = np.empty(500)
    alpha = np.empty(500)
    for t in range(500):
        if mesh.f.shape[0] > 250000:
            break

        global_counter, l2_record = optimize_parameters.optimize_alpha(
            mesh, gt_transient, weight, opt, 50, global_counter)
        if t == 0:
            l2_0 = l2_record

        lr = (l2_record / l2_0) * lr0 * ((0.99)**(t / 2))
        print('new lr %f' % lr)

        old_v = np.array(mesh.v)
        global_counter, convergence_flag, l2_record = optimize_parameters.optimize_shape(
            mesh, gt_transient, weight, opt, 15, lr, gt_mesh, global_counter)
        if convergence_flag:
            if opt.testing_flag == 1:
                opt.testing_flag = 0
                opt.smooth_ratio = ratio / 10 + t / 100
                print('shading')
            else:
                opt.testing_flag = 1
                opt.smooth_ratio = ratio + t / 10

        rendering.el_topo_gradient(mesh, old_v)
        rendering.el_topo_remeshing(mesh, .5 / opt.resolution)
        rendering.isotropic_remeshing(mesh, .5 / opt.resolution)

        rendering.compute_mesh_affinity(mesh)
        rendering.removeTriangle(mesh, opt)

        rendering.compute_mesh_affinity(mesh)
        rendering.border_indicator(mesh)

        filename = folder_name + '%05d.mat' % (t)
        scipy.io.savemat(filename,
                         mdict={
                             'v': mesh.v,
                             'f': mesh.f,
                             'alpha': mesh.alpha
                         })
        l2[t] = l2_record
        alpha[t] = mesh.alpha

    filename = folder_name + 'progress.mat'
    scipy.io.savemat(filename, mdict={'alpha': alpha, 'l2': l2})
コード例 #34
0
def optimization(ratio):
    lr0 = 0.0001
    lr = lr0
    folder_name = os.getcwd() + '/progress-b-1-%f/' % ratio
    if not os.path.isdir(folder_name):
        os.mkdir(folder_name)

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

    gt_transient = np.array(setup['gt_transient'], dtype=np.double, order='C')

    gt_mesh = MESH()
    gt_mesh.v = igl.eigen.MatrixXd(np.array(setup['gt_v'], dtype=np.double))
    gt_mesh.f = igl.eigen.MatrixXd(np.array(setup['gt_f'],
                                            dtype=np.double)).castint()

    opt = OPT(20000)
    opt.max_distance_bin = gt_transient.shape[1]
    opt.smooth_weight = 0.001

    mesh = MESH()

    mesh_init_location = os.getcwd() + '/init/cnlos_bunny_threshold_64.obj'
    igl.readOBJ(mesh_init_location, mesh.v, mesh.f)
    mesh.v = np.array(mesh.v, dtype=np.float32, order='C')
    mesh.f = np.array(mesh.f, dtype=np.int32, order='C')

    opt.resolution = 64
    opt.smooth_ratio = ratio

    rendering.isotropic_remeshing(mesh, .5 / opt.resolution)
    old_v = np.array(mesh.v)

    rendering.compute_mesh_affinity(mesh)
    rendering.border_indicator(mesh)

    weight = rendering.create_weighting_function(gt_transient, opt.gamma)

    optimization_alpha = torch.Tensor([mesh.alpha])
    optimization_alpha.requires_grad_()
    optimizer_alpha = optim.Adam([optimization_alpha], lr=opt.alpha_lr)

    dummy_loss2 = optimization_alpha**2
    dummy_loss2.backward()

    global_counter = 0

    for t in range(3):
        if mesh.f.shape[0] > 250000:
            break

        global_counter, l2_record = optimize_parameters.optimize_alpha(
            mesh, gt_transient, weight, optimization_alpha, optimizer_alpha,
            opt, 50, global_counter)
        if t == 0:
            l2_0 = l2_record

        lr = (l2_record / l2_0) * lr0 * ((0.99)**(t / 50))
        print('new lr %f' % lr)

        old_v = np.array(mesh.v)
        global_counter, convergence_flag = optimize_parameters.optimize_shape(
            mesh, gt_transient, weight, opt, 15, lr, gt_mesh, global_counter)
        if convergence_flag:
            if opt.testing_flag == 1:
                opt.testing_flag = 0
            else:
                opt.testing_flag = 1

        rendering.el_topo_gradient(mesh, old_v)
        rendering.el_topo_remeshing(mesh, .5 / opt.resolution)
        rendering.isotropic_remeshing(mesh, .5 / opt.resolution)

        rendering.compute_mesh_affinity(mesh)
        rendering.removeTriangle(mesh, opt)

        rendering.compute_mesh_affinity(mesh)
        rendering.border_indicator(mesh)
コード例 #35
0
    return False


def key_down(viewer, key, mods):
    global bc_frac, bc_dir, deformation_field, V, U, V_bc, U_bc, F, b

    if key == ord(' '):
        viewer.core.is_animating = not viewer.core.is_animating
        return True
    if key == ord('D') or key == ord('d'):
        deformation_field = not deformation_field
        return True
    return False


igl.readOBJ(TUTORIAL_SHARED_PATH + "decimated-max.obj", V, F)
U = igl.eigen.MatrixXd(V)

# S(i) = j: j<0 (vertex i not in handle), j >= 0 (vertex i in handle j)
S = igl.eigen.MatrixXd()
igl.readDMAT(TUTORIAL_SHARED_PATH + "decimated-max-selection.dmat", S)

S = S.castint()

b = igl.eigen.MatrixXd([[t[0] for t in [(i, S[i]) for i in range(0, V.rows())] if t[1] >= 0]]).transpose().castint()

# Boundary conditions directly on deformed positions
U_bc.resize(b.rows(), V.cols())
V_bc.resize(b.rows(), V.cols())

for bi in range(0, b.rows()):
コード例 #36
0
    BE = igl.eigen.MatrixXi()
    P = igl.eigen.MatrixXi()
    W = igl.eigen.MatrixXd()
    M = igl.eigen.MatrixXd()

    sea_green = igl.eigen.MatrixXd([[70. / 255., 252. / 255., 167. / 255.]])

    anim_t = 0.0
    anim_t_dir = 0.015
    use_dqs = False
    recompute = True
    animation = False  # Flag needed as there is some synchronization problem with viewer.core.is_animating

    poses = [[]]

    igl.readOBJ(TUTORIAL_SHARED_PATH + "arm.obj", V, F)
    U = igl.eigen.MatrixXd(V)
    igl.readTGF(TUTORIAL_SHARED_PATH + "arm.tgf", C, BE)

    # retrieve parents for forward kinematics
    igl.directed_edge_parents(BE, P)
    rest_pose = igl.RotationList()
    igl.directed_edge_orientations(C, BE, rest_pose)
    poses = [[igl.eigen.Quaterniond.Identity() for i in range(4)] for j in range(4)]

    twist = igl.eigen.Quaterniond(pi, igl.eigen.MatrixXd([1, 0, 0]))
    poses[1][2] = rest_pose[2] * twist * rest_pose[2].conjugate()
    bend = igl.eigen.Quaterniond(-pi * 0.7, igl.eigen.MatrixXd([0, 0, 1]))
    poses[3][2] = rest_pose[2] * bend * rest_pose[2].conjugate()

    igl.readDMAT(TUTORIAL_SHARED_PATH + "arm-weights.dmat", W)
コード例 #37
0
import math

sys.path.insert(0, os.getcwd() + "/../")
import pyigl as igl

from shared import TUTORIAL_SHARED_PATH, check_dependencies

dependencies = []
check_dependencies(dependencies)

if __name__ == "__main__":
    V = igl.eigen.MatrixXd()
    F = igl.eigen.MatrixXi()

    # 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