How the run was made
The site was built with astro build and served from dist. Headless Chrome loaded the built page, selected each 3MF through #file-input, and waited for the result panel. The download was intercepted at URL.createObjectURL, so the saved file is the exact blob the download button hands over. A separate Python script then read each STL: triangle count, bounding box, connected shells, boundary edges, non-manifold edges and signed volume. Its values are compared with the result panel in the table below; no mismatch was found.
The seven fixtures are: two cubes that differ only in the declared unit, two two-cube plates that differ only in their material assignment, a five-cube plate, a cube with its top face removed, and a cube placed by a mirrored transform. Each row below is one upload and one export.
| Fixture | Bytes 3MF → STL | Triangles | Bounds (mm) | Shells | Boundary edges |
|---|---|---|---|---|---|
| cube-20mm.3mf | 1,043 → 684 | 12 | 20 × 20 × 20 | 1 | 0 |
| cube-20in.3mf | 1,039 → 684 | 12 | 508 × 508 × 508 | 1 | 0 |
| two-parts.3mf | 1,084 → 1,284 | 24 | 40 × 20 × 20 | 2 | 0 |
| two-colours.3mf | 1,153 → 1,284 | 24 | 40 × 20 × 20 | 2 | 0 |
| plate-five.3mf | 1,311 → 3,084 | 60 | 108 × 20 × 20 | 5 | 0 |
| open-box.3mf | 1,029 → 584 | 10 | 20 × 20 × 20 | 1 | 4 |
| mirrored-cube.3mf | 1,061 → 684 | 12 | 20 × 20 × 20 | 1 | 0 |
What the readings show
The two cube fixtures hold the same 12 triangles. The inch declaration multiplies every coordinate by 25.4, so the same shape reports 508 mm instead of 20 mm (508 ÷ 20 = 25.4). Materials and names do not change the triangle count: plate-five has five objects and 60 triangles, and the converter writes one STL with five disconnected shells. Open-box arrives with 10 triangles and leaves with 10, and the four boundary edges of the missing top face are still there in the export. Mirrored-cube is placed by a build transform with a negative determinant; its signed volume is +8,000, the same as the unmirrored cube, so the winding was reversed as the transform was applied.
Signed volume is positive for every closed fixture. Open-box is not closed, and its signed volume of 5,333.333 is the volume of a cube with an open top measured from the origin, not a solid volume; it is listed for completeness only.
The panel's Vertices field counts the mesh entries the loader produced. plate-five reports 180 because the material assignment gives every triangle its own entries; the STL has no vertex table at all, so the independent parse counts unique corner positions instead, which is 40. Triangle counts and bounds agree between the panel and the parse for all seven files.
File-level checks
These commands were run on the fixtures or the exported STLs in the round-4 working directory. Each note states what the command printed; the full stdout is in the run's report.json.
unzip -l samples/two-parts.3mf 3 files: [Content_Types].xml, _rels/.rels, 3D/3dmodel.model. No Metadata/ and no 3D/Objects/ entries.
unzip -t samples/cube-20mm.3mf All three entries OK; no errors detected in compressed data.
unzip -p samples/cube-20mm.3mf 3D/3dmodel.model | head -c 220 Root element reads unit="millimeter".
unzip -l samples/plate-five.3mf Three entries; the 3D/3dmodel.model part is 4,280 bytes unzipped.
unzip -p samples/plate-five.3mf 3D/3dmodel.model | grep -o '<triangle v1=' | wc -l 60 triangle elements, matching the 60 in the exported STL.
unzip -p samples/plate-five.3mf 3D/3dmodel.model | grep -o '<object ' | wc -l 5 object elements.
unzip -p samples/two-colours.3mf 3D/3dmodel.model | grep -o '<base name' | wc -l 2 base materials; the STL has no material block.
unzip -p samples/open-box.3mf 3D/3dmodel.model | grep -o '<triangle v1=' | wc -l 10 triangle elements: the hole exists in the source.
unzip -p samples/mirrored-cube.3mf 3D/3dmodel.model | grep -o '<item [^/]*/>' Build item transform is −1 0 0 0 1 0 0 0 1 20 0 0.
xxd -l 84 results/out/cube-20mm.stl 80-byte header reads "Binary STL written in the browser"; the 4-byte count is 0c 00 00 00, which is 12.
Two packages that require an extension
The extension post uses two packages written with Python's zipfile, not by a slicer. Both declare
requiredextensions="p" on the model element. PrusaSlicer 2.9.7 opened both on 13 November 2026;
this converter returned a result for one and a visible error for the other.
| Package | Entries | PrusaSlicer 2.9.7 | This converter, Chrome |
|---|---|---|---|
cube-required-p.3mf | 3 | 12 facets, 20 × 20 × 20 mm | 12 triangles, 20 × 20 × 20 mm, 684-byte STL, no warning |
cube-production-split.3mf | 4 | 12 facets, 1 part, 20 × 20 × 20 mm | error: Could not convert this file: Maximum call stack size exceeded; no result panel |
The first file carries a core triangle mesh in its root model, so it converts despite the declaration; the
converter does not read requiredextensions at all. The second moves the mesh into
3D/Objects/object_1.model and points at it with a component p:path. The converter
follows the reference and then fails with a stack overflow instead of reporting an unsupported extension.
PrusaSlicer reads the same file as one 20 mm part, so the package is not corrupt; the failure is in this
converter's component handling.
What was not done
No file was printed. No exported STL was imported into a slicer, Bambu Studio, PrusaSlicer, Cura or any other program. The two extension packages above were opened in PrusaSlicer 2.9.7 as an input-side check, not converted by it. No part was measured with calipers, and no third-party converter was run for comparison. The numbers here are the converter's own result panel and a parse of the file it exported.
Limits of the method: one browser, one build, seven conversion fixtures plus two extension packages. The fixtures are synthetic cubes built for the test, not models from a real job. A different build can produce different millisecond timings, and a different fixture will have different bytes, so the byte counts describe these files rather than the converter in general.
Run date: 13 November 2026. The fixtures are downloadable from the first column of the table and from the converter's own sample links on the posts. The four pilot fixtures — cube-20mm, cube-20in, two-parts and two-colours — are the same files used in the earlier round of tests.