def __init__(self, mesh, signType='fast_winding_number', doPrecompute=True): self._V = mesh.V() self._F = mesh.F() self._precomputed = False if signType == 'fast_winding_number': self._signType = igl.SIGNED_DISTANCE_TYPE_FAST_WINDING_NUMBER if doPrecompute: self._tree = igl.AABB() self._fwn_bvh = igl.FastWindingNumberBVH() # print("[INFO] Precomuting bvh trees...") self._tree.init(self._V, self._F) igl.fast_winding_number(self._V, self._F, 2, self._fwn_bvh) # print("[INFO] Done precomputing") self._precomputed = True elif signType == 'pseudonormal': self._signType = igl.SIGNED_DISTANCE_TYPE_PSEUDONORMAL else: raise ("Invalid signing type given")
import sys, os import math # Add the igl library to the modules search path sys.path.insert(0, os.getcwd() + "/../") import pyigl as igl from shared import TUTORIAL_SHARED_PATH, check_dependencies dependencies = ["glfw"] check_dependencies(dependencies) V = igl.eigen.MatrixXd() F = igl.eigen.MatrixXi() T = igl.eigen.MatrixXi() tree = igl.AABB() FN = igl.eigen.MatrixXd() VN = igl.eigen.MatrixXd() EN = igl.eigen.MatrixXd() E = igl.eigen.MatrixXi() EMAP = igl.eigen.MatrixXi() max_distance = 1 slice_z = 0.5 overlay = False viewer = igl.glfw.Viewer() def append_mesh(C_vis, F_vis, V_vis, V, F, color): F_vis.conservativeResize(F_vis.rows() + F.rows(), 3)
def undeform(path_ref, path_mov, path_morph, outdir): global Vref, Sref, Fref, Smov, Fmov global vecs, k global UxLUx, Ux, UyLUy, Uy, UzLUz, Uz, L global it ''' Specific paths ''' path_vref = path_ref + "/surf.ply" path_vmov = path_mov + "/surf.ply" path_sref = path_ref + "/surf.sphere.ply" path_smov = path_mov + "/surf.sphere.ply" path_rotref = path_ref + "/rotation.txt" path_rotmov = path_mov + "/rotation.txt" ''' Load meshes ''' Vref = igl.eigen.MatrixXd() Vmov = igl.eigen.MatrixXd() Sref = igl.eigen.MatrixXd() Smov = igl.eigen.MatrixXd() Smor = igl.eigen.MatrixXd() Fref = igl.eigen.MatrixXi() Fmov = igl.eigen.MatrixXi() TMP1 = igl.eigen.MatrixXd() TMP2 = igl.eigen.MatrixXd() # load meshes igl.readPLY(path_vref, Vref, Fref, TMP1, TMP2) igl.readPLY(path_vmov, Vmov, Fmov, TMP1, TMP2) igl.readPLY(path_sref, Sref, Fref, TMP1, TMP2) igl.readPLY(path_smov, Smov, Fmov, TMP1, TMP2) igl.readPLY(path_morph, Smor, Fmov, TMP1, TMP2) # load and apply rotations rot = np.loadtxt(path_rotref) rot = p2e(rot).leftCols(3).topRows(3) Sref = (rot.transpose() * Sref.transpose()).transpose() rot = np.loadtxt(path_rotmov) rot = p2e(rot).leftCols(3).topRows(3) Smov = (rot.transpose() * Smov.transpose()).transpose() ''' Compute uniform Laplacian matrix ''' A = igl.eigen.SparseMatrixi() igl.adjacency_matrix(Fmov, A) pA = e2p(A).astype('float64') pL = scipy.sparse.csgraph.laplacian(pA).astype(float).tocsc() L = p2e(pL) ''' Eigenpairs of the uniform Laplacian ''' k = 25 print("Using " + str(k) + " eigenvectors") vals, vecs = eigsh(pL, k, sigma=0, which='LM') evecs = p2e(vecs) ''' Initial deformation field guess ''' delta = Smor - Smov a = delta.col(0).transpose() * evecs # 1 row, k columns b = delta.col(1).transpose() * evecs c = delta.col(2).transpose() * evecs abc = np.concatenate((a, b, c), axis=1).T[:, 0] ''' Constant part of the deformation energy function ''' Ux = Vmov.col(0) Uy = Vmov.col(1) Uz = Vmov.col(2) UxLUx = Ux.transpose() * L * Ux UyLUy = Uy.transpose() * L * Uy UzLUz = Uz.transpose() * L * Uz ''' Initialise AABB tree for finding closest vertices ''' tree = igl.AABB() tree.init(Sref, Fref) ''' Call the minimisation algorithm ''' it = 0 x, f, d = fmin_l_bfgs_b(energy, x0=abc, approx_grad=True, callback=iteration) ''' Save the resulting morph sphere and the resulting projected mesh ''' sph = sphere(x) igl.writePLY(outdir + "/surf.sphere.ply", sphere(x), Fmov) igl.writePLY(outdir + "/surf.ply", project(sph), Fmov)