def run(self): if not self.copyData(): return if self.geo.getNumFaces() == 0 or self.geo.getNumVertexes() == 0: return mesh = self.geo.getTriangulateMesh() v = mesh.points() f = mesh.face_vertex_indices() # Find the open boundary bnd = igl.boundary_loop(f) # Map the boundary to a circle, preserving edge proportions bnd_uv = igl.map_vertices_to_circle(v, bnd) # Harmonic parametrization for the internal vertices uv = igl.harmonic_weights(v, f, bnd, bnd_uv, 1) arap = igl.ARAP(v, f, 2, np.zeros((0))) uv = arap.solve(np.zeros((0, 0)), uv) self.geo.setVertexAttribData(self.get_property("Attribute Name"), uv, attribType='vector3', defaultValue=[0, 0, 0]) if self.get_property("Show Mode") == "2d": self.geo.mesh.setVertexAttribData("pos", uv)
def test_arap1(self): v, f, _ = igl.read_off("data/camelhead.off") b = igl.boundary_loop(f) thetas = np.linspace(0, 2 * np.pi, len(b))[:, np.newaxis] bc = np.concatenate([np.cos(thetas), np.sin(thetas), np.zeros_like(thetas)], axis=1) uv_initial_guess = igl.harmonic_weights(v, f, b, bc, 1) arap1 = igl.ARAP(v, f, 2, b) vp1 = arap1.solve(bc[:, :2], uv_initial_guess[:, :2]) self.assertEqual(vp1.shape[0], v.shape[0]) self.assertTrue(vp1.flags.c_contiguous) arap2 = igl.ARAP(v, f, 3, b) vp2 = arap2.solve(bc, uv_initial_guess) self.assertEqual(vp2.shape[0], v.shape[0]) self.assertTrue(vp2.flags.c_contiguous)
def test_arap2(self): num_b = 100 thetas = np.linspace(0, 2 * np.pi, num_b)[:, np.newaxis] r = thetas / (2 * np.pi) boundary = np.concatenate( [r * np.cos(thetas), np.sin(thetas), np.zeros([num_b, 1])], axis=1) edges = np.array([(i, (i + 1) % boundary.shape[0]) for i in range(boundary.shape[0])]) v, f = igl.triangulate(boundary[:, :2], edges, np.zeros([0, 0])) v = np.concatenate([v, np.zeros([v.shape[0], 1])], axis=1) b = igl.boundary_loop(f.astype(np.int32)) thetas = np.linspace(0, 2 * np.pi, len(b))[:, np.newaxis] circle_b = np.concatenate( [np.cos(thetas), np.sin(thetas), np.zeros([len(b), 1])], axis=1) v0 = igl.harmonic_weights(v, f.astype(np.int32), b, np.asfortranarray(circle_b), 1) print(circle_b.shape, b.shape, v.shape, v.shape) arap = igl.ARAP(v, f, 2, b) v2 = arap.solve(circle_b[:, :2], v0[:, :2]) self.assertEqual(v2.shape[0], v0.shape[0])
def transform(self, v: np.ndarray, f: np.ndarray) -> Tuple[np.ndarray, np.ndarray]: num_of_vertex = v.shape[0] num_of_face = f.shape[0] maxlen = (v.max(axis=0) - v.min(axis=0)).max() # load config theta = self.config[THETA] phi = self.config[PHI] rotation = rMat(theta, phi) translation = np.array([ self.config[T_X], self.config[T_Y], self.config[T_Z] ]) * maxlen * MOVE_PORTION # load pivot norms = np.linalg.norm(v, axis=1) rank = np.argsort(norms) portion = 1 - 0.05 * self.config[PIVOTS] idx = math.floor(portion * num_of_vertex) idx = idx if idx != num_of_vertex else idx - 1 pivot = rank[idx] # 1 move, -1 flow, 0 fix s = np.zeros(num_of_vertex) for idx, p in enumerate(v): dist = np.linalg.norm(p - v[pivot]) if dist < maxlen * MOVE_PORTION: s[idx] = 1 elif dist < maxlen * FLOW_PORTION: s[idx] = -1 else: s[idx] = 0 b = np.array([[ t[0] for t in [(i, s[i]) for i in range(0, v.shape[0])] if t[1] >= 0 ]]).T arap = igl.ARAP(v, f, 3, b) bc = np.zeros((b.size, 3)) for i in range(b.shape[0]): bc[i] = v[b[i]] if s[b[i]] == 1: bc[i] = rotation @ bc[i] + translation vn = arap.solve(bc, v) """ vcp = deepcopy(v) num_of_vertex = vcp.shape[0] maxlen = (vcp.max(axis=0) - vcp.min(axis=0)).max() # load config theta = self.config[THETA] phi = self.config[PHI] rotation = rMat(theta, phi) translation = np.array([self.config[T_X], self.config[T_Y], self.config[T_Z]]) * maxlen * MOVE_PORTION # load pivot pivot = math.floor(num_of_vertex * self.config[PIVOTS]) pivot = pivot if pivot < num_of_vertex else pivot - 1 # 1 move, -1 flow, 0 fix s = np.zeros(num_of_vertex) for idx, p in enumerate(vcp): dist = np.linalg.norm(p - vcp[pivot]) if dist < maxlen * MOVE_PORTION: s[idx] = 1 elif dist < maxlen * FLOW_PORTION: s[idx] = -1 else: s[idx] = 0 b = np.array([[t[0] for t in [(i, s[i]) for i in range(0, vcp.shape[0])] if t[1] >= 0]]).T arap = igl.ARAP(vcp, f, 3, b) bc = np.zeros((b.size, 3)) for i in range(b.shape[0]): bc[i] = vcp[b[i]] if s[b[i]] == 1: bc[i] = rotation @ bc[i] + translation vn = arap.solve(bc, vcp) """ return vn, deepcopy(f)