Skip to content

Commit f1b7716

Browse files
committed
add test from #2483 and fix triangulation check
1 parent 3e53f19 commit f1b7716

File tree

2 files changed

+33
-17
lines changed

2 files changed

+33
-17
lines changed

tests/test_creation.py

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -321,18 +321,37 @@ def test_truncated(count=10):
321321
assert all(s.volume > 0 for s in split)
322322

323323

324+
def test_revolve_lowres():
325+
line = g.np.array([[1.0, 0.0], [1.0, 1.0], [1.0, 2.0], [1.0, 3.0]])
326+
t = g.trimesh.creation.revolve(line, cap=False, sections=6)
327+
assert t.vertices.shape == (24, 3)
328+
assert t.faces.shape == (36, 3)
329+
330+
324331
def test_revolve():
325-
# create a cross section and revolve it to form some volumes
326-
cross_section = [[0, 0], [10, 0], [10, 10], [0, 10]]
332+
# create a cross section of a cylinder and revolve it
333+
r = 10.0
334+
h = 20.0
335+
cross_section = [[0, 0], [r, 0], [r, h], [0, h]]
336+
337+
# use a fine-grained revolution so the area and volume are closer
338+
mesh = g.trimesh.creation.revolve(cross_section, sections=100)
339+
340+
# area of one end-cap
341+
area_cap = g.np.pi * r**2
342+
# area of a cylinder
343+
area = g.np.pi * 2 * r * h + (area_cap * 2)
344+
345+
# volume should match a theoretical cylinder
346+
assert g.np.isclose(mesh.volume, area_cap * h, rtol=0.01)
347+
# area should match a theoretical cylinder
348+
assert g.np.isclose(mesh.area, area, rtol=0.1), f"{mesh.area} != {area}"
327349

328-
# high sections needed so volume is close to theoretical value for perfect revoulution
329-
mesh360 = g.trimesh.creation.revolve(cross_section, 2 * g.np.pi, sections=360)
330-
mesh360_volume = g.np.pi * 10**2 * 10
331-
assert g.np.isclose(mesh360.volume, mesh360_volume, rtol=0.1)
332-
assert mesh360.is_volume, "mesh360 should be a valid volume"
350+
# should be a watertight solid
351+
assert mesh.is_volume, "mesh360 should be a valid volume"
333352

334353
mesh180 = g.trimesh.creation.revolve(cross_section, g.np.pi, sections=180, cap=True)
335-
assert g.np.isclose(mesh180.volume, mesh360.volume / 2, rtol=0.1), (
354+
assert g.np.isclose(mesh180.volume, mesh.volume / 2, rtol=0.1), (
336355
"mesh180 should be half of mesh360 volume"
337356
)
338357
assert mesh180.is_volume, "mesh180 should be a valid volume"
@@ -388,4 +407,5 @@ def test_torus():
388407

389408

390409
if __name__ == "__main__":
391-
test_torus()
410+
# test_torus()
411+
test_revolve()

trimesh/creation.py

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -159,9 +159,6 @@ def revolve(
159159
# offset stacked and wrap vertices
160160
faces = (stacked + offset) % len(vertices)
161161

162-
# if 'process' not in kwargs:
163-
# kwargs['process'] = False
164-
165162
# Handle capping before applying any transformation
166163
if not closed and cap:
167164
# Use the triangulated linestring as the base cap faces (cap_0), assuming no new vertices
@@ -172,11 +169,10 @@ def revolve(
172169

173170
if tol.strict:
174171
# make sure we didn't screw up triangulation
175-
_, idx = np.unique(cap_0_vertices, return_index=True)
176-
cap_0_uvtxs = cap_0_vertices[np.sort(idx)]
177-
_, idx = np.unique(linestring, return_index=True)
178-
line_uvtxs = linestring[np.sort(idx)]
179-
assert np.allclose(cap_0_uvtxs, line_uvtxs)
172+
unique = grouping.unique_rows(cap_0_vertices)[0]
173+
assert set(unique) == set(range(len(linestring))), (
174+
"Triangulation added vertices!"
175+
)
180176

181177
# Use the last set of vertices as the top cap contour (cap_angle)
182178
offset = len(vertices) - per

0 commit comments

Comments
 (0)