|
| 1 | +import numpy as np |
| 2 | +import scipy |
| 3 | + |
| 4 | +import find_ipctk |
| 5 | +from ipctk import CollisionMesh |
| 6 | + |
| 7 | + |
| 8 | +def test_collision_mesh(): |
| 9 | + V = np.array([[0, 0], [1, 0], [0, 1], [1, 1]], dtype=float) |
| 10 | + E = np.array([[0, 1], [1, 3], [3, 2], [2, 0]], dtype=int) |
| 11 | + |
| 12 | + W = scipy.sparse.lil_matrix((4, 3), dtype=float) |
| 13 | + W[0, 0] = W[1, 1] = W[2, 2] = W[3, 1] = W[3, 2] = 1 |
| 14 | + |
| 15 | + mesh = CollisionMesh(V, E, displacement_map=W) |
| 16 | + |
| 17 | + U = np.array([[0, 0], [1, 1], [0, 0]], dtype=float) |
| 18 | + |
| 19 | + Uc = mesh.map_displacements(U) |
| 20 | + expected_Uc = np.array([[0, 0], [1, 1], [0, 0], [1, 1]], dtype=float) |
| 21 | + assert (Uc == expected_Uc).all() |
| 22 | + |
| 23 | + Vc = mesh.displace_vertices(U) |
| 24 | + expected_Vc = np.array([[0, 0], [2, 1], [0, 1], [2, 2]], dtype=float) |
| 25 | + assert (Vc == expected_Vc).all() |
| 26 | + |
| 27 | + g = np.array([1, 1, -1, 1, 1, -1, -1, -1], dtype=float) |
| 28 | + gf = mesh.to_full_dof(g) |
| 29 | + expected_gf = np.array([1, 1, -2, 0, 0, -2], dtype=float) |
| 30 | + assert (gf == expected_gf).all() |
| 31 | + |
| 32 | + H = np.eye(8) |
| 33 | + Hf = mesh.to_full_dof(scipy.sparse.csc_matrix(H)).toarray() |
| 34 | + expected_Hf = np.array([ |
| 35 | + [1, 0, 0, 0, 0, 0], |
| 36 | + [0, 1, 0, 0, 0, 0], |
| 37 | + [0, 0, 2, 0, 1, 0], |
| 38 | + [0, 0, 0, 2, 0, 1], |
| 39 | + [0, 0, 1, 0, 2, 0], |
| 40 | + [0, 0, 0, 1, 0, 2], |
| 41 | + ], dtype=float) |
| 42 | + assert (Hf == expected_Hf).all() |
| 43 | + |
| 44 | + |
| 45 | +def check_faces_to_edges(E, expected_F2E): |
| 46 | + F = np.array([[0, 1, 2]]) |
| 47 | + assert (CollisionMesh.construct_faces_to_edges(F, E) == expected_F2E).all() |
| 48 | + |
| 49 | + |
| 50 | +def test_faces_to_edges(): |
| 51 | + yield check_faces_to_edges, np.array([[0, 1], [1, 2], [2, 0]]), np.array([0, 1, 2]) |
| 52 | + yield check_faces_to_edges, np.array([[2, 0], [2, 1], [1, 0]]), np.array([2, 1, 0]) |
| 53 | + yield check_faces_to_edges, np.array([[0, 1], [2, 0], [2, 1]]), np.array([0, 2, 1]) |
| 54 | + # Shouldnt work |
| 55 | + try: |
| 56 | + check_faces_to_edges(np.array([[0, 1], [1, 2], [0, 3]]), None) |
| 57 | + assert False |
| 58 | + except RuntimeError as e: |
| 59 | + assert str(e) == "Unable to find edge!" |
| 60 | + except: |
| 61 | + assert False |
| 62 | + |
| 63 | + |
| 64 | +def test_codim_points_collision_mesh(): |
| 65 | + V = np.array([[0, 0], [1, 0], [0, 1], [1, 1]], dtype=float) |
| 66 | + mesh = CollisionMesh(V) |
| 67 | + expected_codim_vertices = np.array([0, 1, 2, 3], dtype=int) |
| 68 | + assert (mesh.codim_vertices == expected_codim_vertices).all() |
| 69 | + |
| 70 | + |
| 71 | +def test_collision_mesh_no_faces(): |
| 72 | + # Based on https://github.com/ipc-sim/ipc-toolkit/issues/103 |
| 73 | + points = np.array([[-0.5, 0.5], [0.5, 0.5], [0.5, -0.5]]) |
| 74 | + edges = np.array([[0, 1], [1, 2], [2, 0]]) |
| 75 | + mesh = CollisionMesh(points, edges) |
| 76 | + assert mesh.faces.size == 0 |
| 77 | + |
| 78 | + |
| 79 | +def test_collision_mesh_does_not_segfault(): |
| 80 | + # Based on https://github.com/ipc-sim/ipc-toolkit/issues/102 |
| 81 | + points = np.array([[-0.5, 0.5], [0.5, 0.5], [0.5, -0.5]]) |
| 82 | + edges = np.array([[0, 1], [1, 2], [2, 0]]) |
| 83 | + faces = np.array([[0, 1, 2]]) |
| 84 | + mesh = CollisionMesh(points, edges, faces) |
| 85 | + assert (mesh.rest_positions == points).all() |
| 86 | + assert (mesh.edges == edges).all() |
| 87 | + assert (mesh.faces == faces).all() |
0 commit comments