Beispiel #1
0
 def do_test(self, module, ret):
     from pypsim_ref.cloth1 import loadOBJ
     core, simp = _prepare(module)
     _set_single_constraint(simp, 'pin')
     V, F = loadOBJ('../assets/cloth/rect-coarse.obj')
     V *= 50.0
     TL = np.array([1.0,1.0,0.0])
     TR = np.array([-1.0,1.0,0.0])
     TL_index = np.argmax(V.dot(TL))
     TR_index = np.argmax(V.dot(TR))
     # print(f"TL_index {TL_index} TR_index {TR_index}")
     # print(f"TL {V[TL_index]} TR {V[TR_index]}")
     core.attach_mesh(V, F, scale=1.0)
     rng = np.random.default_rng(seed=0xd7fbe4d90e3df2e0)
     for t in progressbar(range(100)):
         core.attach_mesh(V, F, scale=1.0)
         off = rng.uniform(low=-1.0,high=1.0, size=3)
         # off = rng.uniform(low=-1.0,high=1.0, size=3)
         core.update_mesh_vertics(V + off)
         Q, _, _ = core.get_current_mesh()
         loss = np.linalg.norm(Q[TL_index] - V[TL_index])
         loss += np.linalg.norm(Q[TR_index] - V[TR_index])
         # print(f"[INIT] loss: {loss} TL {Q[TL_index]} TR {Q[TR_index]}")
         for i in range(4):
             core.simulate_one_step()
             Q, _, _ = core.get_current_mesh()
             loss = np.linalg.norm(Q[TL_index] - V[TL_index])
             loss += np.linalg.norm(Q[TR_index] - V[TR_index])
             # print(f"[{i:05d}] loss: {loss} TL {Q[TL_index]} TR {Q[TR_index]}")
         compare_result = np.allclose(loss, 0.0)
         ret.add_result(compare_result)
Beispiel #2
0
 def do_test(self, module, ret):
     from pypsim_ref.cloth1 import loadOBJ
     bicore = _prepare_bicore(module)
     bicore.set_single_constraint('gravity')
     V, F = loadOBJ('../assets/cloth/rect-coarse.obj')
     V *= 50.0
     bicore.attach_mesh(V, F, scale=1.0)
     for i in range(100):
         bicore.simulate_one_step()
         ret.add_result(bicore.compare())
Beispiel #3
0
 def do_test(self, module, ret):
     from pypsim_ref.cloth1 import loadOBJ
     core, simp = _prepare(module)
     _set_single_constraint(simp, 'stretch')
     V, F = loadOBJ('../assets/cloth/rect-coarse.obj')
     nfaces = F.shape[0]
     V *= 50.0
     init_surface_areas = _surface_areas(V, F)
     print()
     print(init_surface_areas)
     rng = np.random.default_rng(seed=0xd7fbe4d90e3df2e0)
     rng_faces = rng.integers(nfaces, size=100)
     for t in progressbar(range(10)):
         core.attach_mesh(V, F, scale=1.0)
         off = rng.uniform(low=-10.0,high=10.0, size=3)
         rot = Rotation.random(random_state=rng)
         Q = rot.apply(V) + off
         Q = np.copy(V)
         fi = F[rng_faces[t],:]
         while True:
             bary = rng.uniform(low=0.0,high=1.0, size=3)
             norm = np.linalg.norm(bary)
             if norm > 1e-3:
                 break
         bary /= norm
         verts = np.array([Q[fi[0]], Q[fi[1]], Q[fi[2]]])
         # print(f"fi[0]: {fi[0].shape}")
         # print(f"Q[fi[0]]: {Q[fi[0]].shape}")
         # print(f"verts: {verts.shape}")
         # print(f"bary: {bary.shape}")
         v = bary.dot(verts)
         extend = np.exp(rng.uniform(low=np.log(0.01), high=np.log(10.0), size=3))
         diag = np.diag(extend)
         # diag = np.eye(3)
         # print(diag.shape)
         # Q = (Q - v).dot(diag) + v
         # diag = np.diag([2.0, 1.0, 1.0])
         Q = (Q - v).dot(diag) + v
         core.update_mesh_vertics(Q)
         for i in range(3000):
             core.simulate_one_step()
             Q, _, _ = core.get_current_mesh()
             streching_surface_areas = _surface_areas(Q, F)
             loss = np.sum(streching_surface_areas-init_surface_areas) / nfaces
             # print(f"[{i:05d}] areas: {streching_surface_areas}")
             # print(f"[{i:05d}] loss: {loss}")
             compare_result = np.allclose(loss, 0.0, atol=1e-2)
             if compare_result:
                 break
         print(f"compare_result: {compare_result}, final loss: {loss}")
         ret.add_result(compare_result)
Beispiel #4
0
 def do_test(self, module, ret):
     from pypsim_ref.cloth1 import loadOBJ
     core, simp = _prepare(module)
     _set_single_constraint(simp, 'pulling')
     V, F = loadOBJ('../assets/cloth/rect-coarse.obj')
     nverts = V.shape[0]
     V *= 50.0
     rng = np.random.default_rng(seed=0xf1bf30cc0f25ae6d)
     for trial in range(100):
         core.attach_mesh(V, F, scale=1.0)
         vert_index = rng.integers(low=0, high=nverts, endpoint=True)
         '''
         Suppose we need a curve f_{x,y,z}(t).
         We start with generating a 3x3 matrix [a b c], where
         f_x(t) = a_x t^3 + b_x t^2 + c_x t + x0
         f_y(t) = a_y t^3 + b_y t^2 + c_y t + y0
         f_z(t) = a_z t^3 + b_z t^2 + c_z t + z0
         '''
         curve_matrix = rng.uniform(low=-10, high=10, size=(3,3))
         '''
         '''
         M = np.empty(shape=(3,4))
         M[:3, :3] = curve_matrix
         M[:, 3] = V[vert_index, :]
         speed = np.exp(rng.uniform(low=np.log(0.01), high=np.log(10.0)))
         core.hold(vert_index, V[vert_index, :]);
         for i in range(0, 100):
             t = speed * float(i) / 100.0
             coe = np.array([t ** 3, t ** 2, t, 1])
             p = M.dot(coe)
             core.update_hold(p)
             for k in range(3):
                 core.simulate_one_step()
             Q, _, _ = core.get_current_mesh()
             val = Q[vert_index]
             exp = p
             compare_result = np.allclose(val, exp, rtol=1e-2)
             print(f"compare_result {compare_result} val {val} expect {exp}")
             ret.add_result(compare_result)
Beispiel #5
0
    def do_test(self, module, ret):
        from pypsim_ref.cloth1 import loadOBJ, saveOBJ, principal_curvature
        core, simp = _prepare(module)
        _set_single_constraint(simp, 'bending')
        # simp.bendingWeight = 1.0
        V, F = loadOBJ('../assets/cloth/rect-coarse.obj')
        nfaces = F.shape[0]
        nverts = F.shape[0]
        V *= 50.0
        rng = np.random.default_rng(seed=0xd7fbe4d90e3df2e0)
        def get_loss(Q):
            _,_,PV1, PV2, bad = principal_curvature(Q, F)
            # Mean principle curvature, doesn't work very well
            # return np.sum(np.abs(PV1) + np.abs(PV2)) / nfaces
            # Maximum principle curvature, also doesn't work very well
            ret = max(np.max(np.abs(PV1)), np.max(np.abs(PV2)))
            return ret
            _, ret, _, _ = np.linalg.lstsq(Q[:, :2], Q[:,2], rcond=None)
            return ret
        for t in range(10):
            core.attach_mesh(V, F, scale=1.0)
            found = False
            while not found:
                fi = rng.integers(nfaces, endpoint=False)
                vi = F[fi]
                bary = rng.uniform(low=0.0,high=1.0, size=3)
                norm = np.linalg.norm(bary)
                if norm <= 1e-3:
                    continue
                bary /= norm
                verts = np.array([V[vi[0]], V[vi[1]], V[vi[2]]])
                v = bary.dot(verts)
                for i in range(4):
                    cut_angle = rng.uniform(math.pi / 8, math.pi / 2)
                    cut_axis = np.array([math.cos(cut_angle), math.sin(cut_angle), 0.0])
                    side = np.cross(V - v, cut_axis).dot(np.array([0,0,1])) > 0
                    size_int = side.astype(int)
                    nsep = np.sum(size_int)
                    print(f"nsep {nsep} nverts {nverts}")
                    if nsep < nverts * 0.05 or nsep > nverts * 0.95:
                        '''
                        reject tiny cuts.
                        '''
                        continue
                    bend_angle = rng.uniform(math.pi / 8, math.pi / 2)
                    bend_angle *= rng.choice([-1.0, 1.0])
                    bend_array = (bend_angle * size_int).reshape((1, size_int.shape[0]))
                    print(f"verts: {verts}")
                    print(f"v : {v}")
                    print(f"bend_angle : { bend_angle}")
                    print(f"bend_array : { bend_array.shape}")
                    rotvec_array = cut_axis.reshape((3,1)).dot(bend_array).transpose()
                    rots = Rotation.from_rotvec(rotvec_array)
                    Q = rots.apply(V - v) + v
                    if get_loss(Q) < 0.1:
                        continue
                    found = True
                    break
            init_loss = get_loss(Q)
            print(f"Init loss {init_loss}")
            # continue
            # Q = rots.apply(V - v)
            # z_delta = np.zeros(shape=(size_int.shape[0], 3))
            # z_delta[:, 2] = size_int
            # z_delta[:, 2] = bend_array[0,:]
            # Q = (V - v) # + z_delta
            # saveOBJ(Q, F, '0.obj')
            # exit()

            core.update_mesh_vertics(Q)
            for i in range(30000):
                core.simulate_one_step()
                # print(f"[{i:05d}] areas: {streching_surface_areas}")
                if (i + 1) % 100 == 0:
                    Q, _, _ = core.get_current_mesh()
                    # _,_,PV1, PV2, bad = principal_curvature(Q, F)
                    # Mean principle curvature, doesn't work very well
                    # loss = np.sum(np.abs(PV1) + np.abs(PV2)) / nfaces
                    # Maximum principle curvature, also doesn't work very well
                    # loss = max(np.max(np.abs(PV1)), np.max(np.abs(PV2)))
                    # _, loss, _, _ = np.linalg.lstsq(Q[:, :2], Q[:,2], rcond=None)
                    loss = get_loss(Q)
                    # compare_result = np.allclose(loss, init_loss * 0.10, atol=1e-2)
                    compare_result = (loss <= init_loss * 0.05)
                    print(f"[{(i+1):05d}] compare_result: {compare_result}, final loss: {loss}, bendingWeight {simp.bendingWeight}")
                    # saveOBJ(Q, F, f'{(i+1)//100}.obj')
                    # simp.bendingWeight *= 0.99
                    if compare_result:
                        break
            ret.add_result(compare_result)