"""Generate test STL meshes for decomposition quality testing.""" import struct import math def write_stl(path, triangles): with open(path, "wb") as f: f.write(b'\0' * 80) f.write(struct.pack(' 0 else [0,0,0] f.write(struct.pack('<3f', *n)) for v in [v0, v1, v2]: f.write(struct.pack('<3f', *[float(x) for x in v])) f.write(struct.pack(' 0: tris.append((p00, p10, p01)) if i < subdivisions - 1: tris.append((p01, p10, p11)) return tris def cylinder_mesh(center, radius, height, segments=32): tris = [] half_h = height / 2.0 for i in range(segments): a0 = 2 * math.pi * i / segments a1 = 2 * math.pi * (i + 1) / segments x0, y0 = center[0] + radius * math.cos(a0), center[1] + radius * math.sin(a0) x1, y1 = center[0] + radius * math.cos(a1), center[1] + radius * math.sin(a1) top_z = center[2] + half_h bot_z = center[2] - half_h # Side tris.append(((x0, y0, bot_z), (x1, y1, bot_z), (x0, y0, top_z))) tris.append(((x1, y1, bot_z), (x1, y1, top_z), (x0, y0, top_z))) # Top cap tris.append(((center[0], center[1], top_z), (x0, y0, top_z), (x1, y1, top_z))) # Bottom cap tris.append(((center[0], center[1], bot_z), (x1, y1, bot_z), (x0, y0, bot_z))) return tris def box_mesh(center, hx, hy, hz): cx, cy, cz = center v = [ (cx-hx, cy-hy, cz-hz), (cx+hx, cy-hy, cz-hz), (cx+hx, cy+hy, cz-hz), (cx-hx, cy+hy, cz-hz), (cx-hx, cy-hy, cz+hz), (cx+hx, cy-hy, cz+hz), (cx+hx, cy+hy, cz+hz), (cx-hx, cy+hy, cz+hz), ] faces = [ (0,2,1), (0,3,2), (4,5,6), (4,6,7), (0,1,5), (0,5,4), (2,3,7), (2,7,6), (0,4,7), (0,7,3), (1,2,6), (1,6,5), ] return [(v[a], v[b], v[c]) for a, b, c in faces] # Test 1: Sphere (t=1) print("generating sphere.stl...") write_stl("examples/sphere.stl", sphere_mesh((0, 0, 0), 3.0, 24)) # Test 2: Cylinder (t=1) print("generating cylinder.stl...") write_stl("examples/cylinder.stl", cylinder_mesh((0, 0, 0), 2.0, 6.0, 48)) # Test 3: Two-box union (t=3: 2 boxes + 1 union) # Separated so no overlapping faces print("generating two_boxes.stl...") tris = box_mesh((-3, 0, 0), 2, 1, 1) + box_mesh((3, 0, 0), 1, 2, 1) write_stl("examples/two_boxes.stl", tris) # Test 4: Box with sphere cut (t=3: box + sphere + difference) print("generating box_minus_sphere.stl...") # Approximate by densely sampling the SDF and marching-cubes-like output # For simplicity, just use the box mesh (the cut won't show in a naive mesh union) # Instead generate a box mesh - the decompiler should detect it as a box tris = box_mesh((0, 0, 0), 3, 3, 3) write_stl("examples/box3.stl", tris) # Test 5: Translated sphere (t=2: sphere + translate) print("generating translated_sphere.stl...") write_stl("examples/translated_sphere.stl", sphere_mesh((5, 3, -2), 2.0, 20)) # Test 6: Box + cylinder (t=3: 2 objects + 1 union) # Separated with gap print("generating box_and_cylinder.stl...") tris = box_mesh((-4, 0, 0), 2, 2, 2) + cylinder_mesh((4, 0, 0), 1.5, 4.0, 48) write_stl("examples/box_and_cylinder.stl", tris) print("done.")