def loop_gps(v, f, c, n): # transform to 9D dual-space vertices qq1 = np.zeros((len(v), 3)) qq2 = np.zeros((len(v), 3)) qlin = np.zeros((len(v), 3)) for i, cov in enumerate(c): ic = np.linalg.inv(cov) icf = ic.flatten() qq1[i] = [icf[0], icf[1], icf[2]] qq2[i] = [icf[4], icf[5], icf[8]] qlin[i] = ic @ v[i] # perform Gaussian-product subdivision # note: igl.loop only handles 3D subdivs, so we split the 9D meshes into three 3D ones for _ in range(n): qq1, dmy = igl.loop(qq1, f) qq2, dmy = igl.loop(qq2, f) qlin, f = igl.loop(qlin, f) # transform back to 3D v = np.zeros((len(qlin), 3)) for i, ql in enumerate(qlin): icov = [ qq1[i], [qq1[i][1], qq2[i][0], qq2[i][1]], [qq1[i][2], qq2[i][1], qq2[i][2]] ] v[i] = np.linalg.inv(icov) @ ql return v, f
def run(self): geo = self.get_input_geometry_ref(0) if geo is None: return if geo.getNumFaces() == 0 or geo.getNumVertexes() == 0: return itera = self.get_property("Iteration") if itera == 0: return mesh = geo.getTriangulateMesh() v = mesh.points() f = mesh.face_vertex_indices() mt = self.get_property("Method") if mt == "Upsample": for i in range(itera): v, f = igl.upsample(v, f) elif mt == "Loop": for i in range(itera): v, f = igl.loop(v, f) self.geo = Mesh() self.geo.addVertices(v) self.geo.addFaces(f)
def test_loop(self): nv, nf = igl.loop(self.v1, self.f1) self.assertEqual(nv.dtype, self.v1.dtype) self.assertEqual(nv.shape[1], self.v1.shape[1]) self.assertEqual(nf.dtype, self.f1.dtype) self.assertEqual(nf.shape[1], self.f1.shape[1]) self.assertTrue(nv.flags.c_contiguous) self.assertTrue(nf.flags.c_contiguous)
def transform(self, v: np.ndarray, f: np.ndarray) -> Tuple[np.ndarray, np.ndarray]: steps = int(self.config[STEPS]) nv, nf = igl.loop(v, f, steps) return nv, nf
def loop_gps(v, f, c, n): """ :param :v : ℝ^(m×3) :param :f : ℝ^(t×3) :param :c : ℝ^(3×3) :param :n : ℤ """ v = np.asarray(v, dtype=np.float64) f = np.asarray(f, dtype=np.integer) c = np.asarray(c, dtype=np.float64) m = v.shape[0] t = f.shape[0] _dim_0 = c.shape[0] assert v.shape == (m, 3) assert f.shape == (t, 3) assert c.shape == (_dim_0, 3, 3) assert np.ndim(n) == 0 icf = np.zeros(( _dim_0, 9, )) for i in range(1, _dim_0 + 1): icf[i - 1] = np.matrix.flatten(np.linalg.inv(c[i - 1]), order='F') qq1 = np.zeros(( _dim_0, 3, )) for i in range(1, _dim_0 + 1): qq1[i - 1] = np.array( [icf[i - 1][1 - 1], icf[i - 1][2 - 1], icf[i - 1][3 - 1]]) qq2 = np.zeros(( _dim_0, 3, )) for i in range(1, _dim_0 + 1): qq2[i - 1] = np.array( [icf[i - 1][5 - 1], icf[i - 1][6 - 1], icf[i - 1][9 - 1]]) qlin = np.zeros(( m, 3, )) for i in range(1, m + 1): qlin[i - 1] = np.linalg.inv(c[i - 1]) @ v[i - 1, :] # perform Gaussian-product subdivision # note: igl.loop only handles 3D subdivs, so we split the 9D meshes into three 3D ones for _ in range(n): qq1, dmy = igl.loop(qq1, f) qq2, dmy = igl.loop(qq2, f) qlin, f = igl.loop(qlin, f) # transform back to 3D m = qlin.shape[0] v_out = np.zeros(( m, 3, )) for i in range(1, m + 1): _v_out_i_2 = np.vstack( (qq1[i - 1].T.reshape(1, 3), np.array( [qq1[i - 1][2 - 1], qq2[i - 1][1 - 1], qq2[i - 1][2 - 1]]).T.reshape(1, 3), np.array( [qq1[i - 1][3 - 1], qq2[i - 1][2 - 1], qq2[i - 1][3 - 1]]).T.reshape(1, 3))) v_out[i - 1] = np.linalg.inv(_v_out_i_2) @ qlin[i - 1] return v_out, f
class Mesh: v = [] f = [] #------------------------------------------------------------------------------------------ # load input triangle mesh mesh = Mesh() mesh.v, mesh.f = igl.read_triangle_mesh(os.path.join(root_folder, "data", "tweety.off")) # perform ordinary Loop subdivison lmesh = copy.deepcopy(mesh); for _ in range(4): lmesh.v, lmesh.f = igl.loop(lmesh.v, lmesh.f) #------------------------------------------------------------------------------------------ # Gaussian Inference via product of face Gaussians (Eq. 16 and 17) cm = Mesh() cm.v = mesh.v.copy() cm.f = mesh.f.copy() # create list of empty (inverse) covariances icov = np.zeros((len(mesh.v),3,3)) # 1. infer face covs and inverse vertex covs