Skip to content

Commit 2fc69e5

Browse files
committed
Moar models tests
1 parent 01b5e47 commit 2fc69e5

File tree

1 file changed

+155
-11
lines changed

1 file changed

+155
-11
lines changed

tests/test_models.py

Lines changed: 155 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,26 +4,37 @@
44

55
import math
66

7+
import trimesh
8+
9+
from flitter.model import Matrix44
710
from flitter.render.window.models import Model
811

912
from . import utils
1013

1114

15+
DefaultSegments = 64
16+
17+
1218
class TestPrimitives(utils.TestCase):
19+
def tearDown(self):
20+
Model.flush_caches(0, 0)
21+
1322
def test_box(self):
14-
box = Model.box()
15-
mesh = box.get_trimesh()
23+
model = Model.box()
24+
mesh = model.get_trimesh()
25+
self.assertEqual(model.name, '!box')
1626
self.assertEqual(mesh.bounds.tolist(), [[-0.5, -0.5, -0.5], [0.5, 0.5, 0.5]])
1727
self.assertEqual(len(mesh.vertices), 24)
1828
self.assertEqual(len(mesh.faces), 12)
1929
self.assertEqual(mesh.area, 6)
2030
self.assertEqual(mesh.volume, 1)
2131

2232
def test_sphere(self):
23-
for segments in (4, 64, 1024):
33+
for segments in (4, DefaultSegments, 1024):
2434
with self.subTest(segments=segments):
25-
sphere = Model.sphere(segments)
26-
mesh = sphere.get_trimesh()
35+
model = Model.sphere(segments)
36+
self.assertEqual(model.name, f'!sphere-{segments}' if segments != DefaultSegments else '!sphere')
37+
mesh = model.get_trimesh()
2738
self.assertEqual(mesh.bounds.tolist(), [[-1, -1, -1], [1, 1, 1]])
2839
nrows = segments // 4
2940
self.assertEqual(len(mesh.vertices), 4*(nrows+1)*(nrows+2))
@@ -36,10 +47,11 @@ def test_sphere(self):
3647
self.assertAlmostEqual(mesh.volume, 4/3*math.pi, places=int(math.log10(segments)))
3748

3849
def test_cylinder(self):
39-
for segments in (4, 64, 1024):
50+
for segments in (4, DefaultSegments, 1024):
4051
with self.subTest(segments=segments):
41-
cylinder = Model.cylinder(segments)
42-
mesh = cylinder.get_trimesh()
52+
model = Model.cylinder(segments)
53+
self.assertEqual(model.name, f'!cylinder-{segments}' if segments != DefaultSegments else '!cylinder')
54+
mesh = model.get_trimesh()
4355
self.assertEqual(mesh.bounds.tolist(), [[-1, -1, -0.5], [1, 1, 0.5]])
4456
self.assertEqual(len(mesh.vertices), 6*(segments+1))
4557
self.assertEqual(len(mesh.faces), 4*segments)
@@ -51,10 +63,11 @@ def test_cylinder(self):
5163
self.assertAlmostEqual(mesh.volume, math.pi, places=int(math.log10(segments)))
5264

5365
def test_cone(self):
54-
for segments in (4, 64, 1024):
66+
for segments in (4, DefaultSegments, 1024):
5567
with self.subTest(segments=segments):
56-
cone = Model.cone(segments)
57-
mesh = cone.get_trimesh()
68+
model = Model.cone(segments)
69+
self.assertEqual(model.name, f'!cone-{segments}' if segments != DefaultSegments else '!cone')
70+
mesh = model.get_trimesh()
5871
self.assertEqual(mesh.bounds.tolist(), [[-1, -1, -0.5], [1, 1, 0.5]])
5972
self.assertEqual(len(mesh.vertices), 4*(segments+1))
6073
self.assertEqual(len(mesh.faces), 2*segments)
@@ -64,3 +77,134 @@ def test_cone(self):
6477
else:
6578
self.assertAlmostEqual(mesh.area, (1+math.sqrt(2))*math.pi, places=int(math.log10(segments)))
6679
self.assertAlmostEqual(mesh.volume, math.pi/3, places=int(math.log10(segments)))
80+
81+
82+
class TestManifoldPrimitives(utils.TestCase):
83+
def tearDown(self):
84+
Model.flush_caches(0, 0)
85+
86+
def test_box(self):
87+
mesh = Model.box().get_manifold().to_mesh()
88+
mesh = trimesh.Trimesh(vertices=mesh.vert_properties, faces=mesh.tri_verts, process=False)
89+
self.assertEqual(mesh.bounds.tolist(), [[-0.5, -0.5, -0.5], [0.5, 0.5, 0.5]])
90+
self.assertEqual(len(mesh.vertices), 8)
91+
self.assertEqual(len(mesh.faces), 12)
92+
self.assertEqual(mesh.area, 6)
93+
self.assertEqual(mesh.volume, 1)
94+
95+
def test_sphere(self):
96+
for segments in (4, DefaultSegments, 1024):
97+
with self.subTest(segments=segments):
98+
mesh = Model.sphere(segments).get_manifold().to_mesh()
99+
mesh = trimesh.Trimesh(vertices=mesh.vert_properties, faces=mesh.tri_verts, process=False)
100+
self.assertEqual(mesh.bounds.tolist(), [[-1, -1, -1], [1, 1, 1]])
101+
nrows = segments // 2
102+
self.assertEqual(len(mesh.vertices), 2+nrows*nrows)
103+
self.assertEqual(len(mesh.faces), 2*nrows*nrows)
104+
if segments == 4:
105+
self.assertAlmostEqual(mesh.area, 4*math.sqrt(3))
106+
self.assertAlmostEqual(mesh.volume, 4/3)
107+
else:
108+
self.assertAlmostEqual(mesh.area, 4*math.pi, places=int(math.log10(segments)))
109+
self.assertAlmostEqual(mesh.volume, 4/3*math.pi, places=int(math.log10(segments)))
110+
111+
def test_cylinder(self):
112+
for segments in (4, DefaultSegments, 1024):
113+
with self.subTest(segments=segments):
114+
mesh = Model.cylinder(segments).get_manifold().to_mesh()
115+
mesh = trimesh.Trimesh(vertices=mesh.vert_properties, faces=mesh.tri_verts, process=False)
116+
self.assertEqual(mesh.bounds.tolist(), [[-1, -1, -0.5], [1, 1, 0.5]])
117+
self.assertEqual(len(mesh.vertices), 2*segments)
118+
self.assertEqual(len(mesh.faces), 4*(segments-1))
119+
if segments == 4:
120+
self.assertAlmostEqual(mesh.area, 4*(1+math.sqrt(2)))
121+
self.assertAlmostEqual(mesh.volume, 2)
122+
else:
123+
self.assertAlmostEqual(mesh.area, 4*math.pi, places=int(math.log10(segments)))
124+
self.assertAlmostEqual(mesh.volume, math.pi, places=int(math.log10(segments)))
125+
126+
def test_cone(self):
127+
for segments in (4, DefaultSegments, 1024):
128+
with self.subTest(segments=segments):
129+
mesh = Model.cone(segments).get_manifold().to_mesh()
130+
mesh = trimesh.Trimesh(vertices=mesh.vert_properties, faces=mesh.tri_verts, process=False)
131+
self.assertEqual(mesh.bounds.tolist(), [[-1, -1, -0.5], [1, 1, 0.5]])
132+
self.assertEqual(len(mesh.vertices), segments+1)
133+
self.assertEqual(len(mesh.faces), 2*(segments-1))
134+
if segments == 4:
135+
self.assertAlmostEqual(mesh.area, 2*(1+math.sqrt(3)))
136+
self.assertAlmostEqual(mesh.volume, 2/3)
137+
else:
138+
self.assertAlmostEqual(mesh.area, (1+math.sqrt(2))*math.pi, places=int(math.log10(segments)))
139+
self.assertAlmostEqual(mesh.volume, math.pi/3, places=int(math.log10(segments)))
140+
141+
142+
class TestTransform(utils.TestCase):
143+
def tearDown(self):
144+
Model.flush_caches(0, 0)
145+
146+
def assertTransform(self, base_model, matrix):
147+
transformed_model = base_model.transform(matrix)
148+
self.assertEqual(transformed_model.name, f'{base_model.name}@{hex(matrix.hash(False))[2:]}')
149+
base_mesh = base_model.get_trimesh()
150+
transformed_mesh = transformed_model.get_trimesh()
151+
self.assertEqual(len(base_mesh.vertices), len(transformed_mesh.vertices))
152+
self.assertEqual(base_mesh.faces.tolist(), transformed_mesh.faces.tolist())
153+
for vertex1, vertex2 in zip(base_mesh.vertices.tolist(), transformed_mesh.vertices.tolist()):
154+
self.assertAllAlmostEqual(vertex2, matrix @ vertex1, places=6)
155+
base_mesh = base_model.get_manifold().to_mesh()
156+
transformed_mesh = transformed_model.get_manifold().to_mesh()
157+
self.assertEqual(len(base_mesh.vert_properties), len(transformed_mesh.vert_properties))
158+
self.assertEqual(base_mesh.tri_verts.tolist(), transformed_mesh.tri_verts.tolist())
159+
for vertex1, vertex2 in zip(base_mesh.vert_properties.tolist(), transformed_mesh.vert_properties.tolist()):
160+
self.assertAllAlmostEqual(vertex2, matrix @ vertex1, places=6)
161+
162+
def test_translate(self):
163+
self.assertTransform(Model.cylinder(), Matrix44.translate((1, 2, 3)))
164+
165+
def test_rotate(self):
166+
self.assertTransform(Model.cylinder(), Matrix44.rotate(1/3))
167+
168+
def test_scale(self):
169+
self.assertTransform(Model.cylinder(), Matrix44.scale((2, 3, 4)))
170+
171+
172+
class TestCache(utils.TestCase):
173+
def tearDown(self):
174+
Model.flush_caches(0, 0)
175+
176+
def test_cached_trimesh(self):
177+
model = Model.box()
178+
bounds = model.get_bounds()
179+
mesh = model.get_trimesh()
180+
manifold = model.get_manifold()
181+
self.assertIs(model.get_bounds(), bounds)
182+
self.assertIs(model.get_trimesh(), mesh)
183+
self.assertIs(model.get_manifold(), manifold)
184+
185+
def test_invalidate(self):
186+
model = Model.box()
187+
bounds = model.get_bounds()
188+
mesh = model.get_trimesh()
189+
manifold = model.get_manifold()
190+
self.assertIs(model.get_bounds(), bounds)
191+
self.assertIs(model.get_trimesh(), mesh)
192+
self.assertIs(model.get_manifold(), manifold)
193+
model.invalidate()
194+
self.assertIsNot(model.get_bounds(), bounds)
195+
self.assertIsNot(model.get_trimesh(), mesh)
196+
self.assertIsNot(model.get_manifold(), manifold)
197+
198+
def test_invalidate_dependency(self):
199+
dependency = Model.box()
200+
model = dependency.transform(Matrix44())
201+
bounds = model.get_bounds()
202+
mesh = model.get_trimesh()
203+
manifold = model.get_manifold()
204+
self.assertIs(model.get_bounds(), bounds)
205+
self.assertIs(model.get_trimesh(), mesh)
206+
self.assertIs(model.get_manifold(), manifold)
207+
dependency.invalidate()
208+
self.assertIsNot(model.get_bounds(), bounds)
209+
self.assertIsNot(model.get_trimesh(), mesh)
210+
self.assertIsNot(model.get_manifold(), manifold)

0 commit comments

Comments
 (0)