Esempio n. 1
0
    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)
Esempio n. 3
0
    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])
Esempio n. 4
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)