1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
|
try:
from . import generic as g
except BaseException:
import generic as g
# minimum number of faces to test
# permutations on
MIN_FACES = 50
class PermutateTest(g.unittest.TestCase):
def test_permutate(self):
def close(a, b):
if len(a) == len(b) == 0:
return False
if a.shape != b.shape:
return False
return g.np.allclose(a, b)
def make_assertions(mesh, test, rigid=False):
if (
close(test.face_adjacency, mesh.face_adjacency)
and len(mesh.faces) > MIN_FACES
):
g.log.error(f"face_adjacency unchanged: {test.face_adjacency!s}")
raise ValueError(
"face adjacency of %s the same after permutation!",
mesh.metadata["file_name"],
)
if (
close(test.face_adjacency_edges, mesh.face_adjacency_edges)
and len(mesh.faces) > MIN_FACES
):
g.log.error(
f"face_adjacency_edges unchanged: {test.face_adjacency_edges!s}"
)
raise ValueError(
"face adjacency edges of %s the same after permutation!",
mesh.metadata["file_name"],
)
assert not close(test.faces, mesh.faces)
assert not close(test.vertices, mesh.vertices)
assert not test.__hash__() == mesh.__hash__()
# rigid transforms don't change area or volume
if rigid:
assert g.np.allclose(mesh.area, test.area)
# volume is very dependent on meshes being watertight and sane
if (
mesh.is_watertight
and test.is_watertight
and mesh.is_winding_consistent
and test.is_winding_consistent
):
assert g.np.allclose(mesh.volume, test.volume, rtol=0.05)
for mesh in g.get_meshes(5):
if len(mesh.faces) < MIN_FACES:
continue
# warp the mesh to be a unit cube
mesh.vertices /= mesh.extents
original = mesh.copy()
for _i in range(5):
mesh = original.copy()
noise = g.trimesh.permutate.noise(mesh, magnitude=mesh.scale / 50.0)
# make sure that if we permutate vertices with no magnitude
# area and volume remain the same
no_noise = g.trimesh.permutate.noise(mesh, magnitude=0.0)
transform = g.trimesh.permutate.transform(mesh)
tessellate = g.trimesh.permutate.tessellation(mesh)
make_assertions(mesh, noise, rigid=False)
make_assertions(mesh, no_noise, rigid=True)
make_assertions(mesh, transform, rigid=True)
make_assertions(mesh, tessellate, rigid=True)
# make sure permutate didn't alter the original mesh
assert original.__hash__() == mesh.__hash__()
def test_tesselation(self):
for mesh in g.get_meshes(5):
tess = g.trimesh.permutate.tessellation(mesh)
# g.log.debug(tess.area-mesh.area)
assert abs(tess.area - mesh.area) < g.tol.merge
volume_check = abs(tess.volume - mesh.volume) / mesh.scale
assert volume_check < g.tol.merge
assert len(mesh.faces) < len(tess.faces)
if mesh.is_winding_consistent:
assert tess.is_winding_consistent
if mesh.is_watertight:
assert tess.is_watertight
def test_base(self):
for mesh in g.get_meshes(1):
tess = mesh.permutate.tessellation() # NOQA
noise = mesh.permutate.noise()
noise = mesh.permutate.noise(magnitude=mesh.scale / 10) # NOQA
transform = mesh.permutate.transform() # NOQA
if __name__ == "__main__":
g.trimesh.util.attach_to_log()
g.unittest.main()
|