Files with a known answer
A measurement is only worth reading if it is right, so the tests start from files whose answer is worked out by hand. Each line below is a browser test, run in Chromium and in WebKit, Safari’s engine, on the built site:
- A 20 mm cube reads 20 × 20 × 20 mm, 8,000 mm³ and 2,400 mm², watertight, and its ASCII copy gives the same numbers.
- A box with its lid missing reports 4 open edges in 1 hole, and its volume is flagged as unreliable.
- The sample STEP assembly reads 80 × 50 × 38 mm and 69,444 mm³, both exact: they are measured on the solids, not on the mesh drawn on screen.
- A cylinder 20 mm across and 30 mm tall, at fine quality, is cut into the same 628 triangles on every run, and its rim stays within 0.002 mm of the true circle.
- A 100 mm line in a DXF drawing measures 100.00 mm.
- An SVG of a 100 mm square becomes a DXF whose corners are exactly (0, 0) and (100, 100).
- A white picture 100 pixels square becomes a plate of 100 × 0.8 × 100 mm and 8,000 mm³ on image to STL.
- On the print cost calculator, 50 g of PLA at €20 a kilogram, 3 hours at 120 W, a €600 printer, 10 minutes of work and a 30% markup, among other inputs, come to a cost of €4.95 and a price of €6.43.
There are more than 800 unit tests on the readers, writers and measurements, and more than 1,000 browser tests, each run in both engines. A change is run against the tests it can affect, and the whole suite runs in Firefox and on an emulated phone as well.
Files opened in the programs they are made for
A converted file is right when the program that reads it agrees. Each page below had its own sample saved through the site, and the file opened in other programs, on October 23, 2026: PrusaSlicer 2.9.6 for STL and 3MF files, FreeCAD 1.1.4 for STEP and DXF files, ezdxf 1.4.2 for DXF files, assimp 6.0 for OBJ, PLY and glTF files, the Khronos glTF Validator 2.0.0-dev.3.10 for GLB and glTF files, and pdfinfo for the PDF. The SVG of DXF to SVG is left out: none of these programs reads an SVG.
| Page | What was saved, and what the other program reported |
|---|---|
| 3MF to STL | The STL of a two-plate project. PrusaSlicer: 4 parts, manifold, 894 facets, the modifier parts left out |
| STL to STEP | The STEP of the bracket. FreeCAD: 1 valid solid of 152 faces, no errors from its Boolean check, 24,811.52 mm³ where the STL holds 24,811.50 |
| STEP to STL | The STL of the assembly. PrusaSlicer: 80 × 50 × 38 mm, 5 parts, manifold, 69,420.7 mm³ |
| STEP to 3MF | The 3MF of the assembly. PrusaSlicer: 5 objects, each manifold, 69,420.7 mm³ in all |
| STEP to OBJ | The OBJ and MTL of the assembly. assimp: 1,712 faces, 80 × 50 × 38 mm, 5 objects named after the parts |
| STEP to GLB | The GLB of the assembly. Validator: no errors, no warnings. assimp: 5 named meshes, 0.08 × 0.038 × 0.05 m |
| OBJ to STL | The STL of the bracket. PrusaSlicer: 60 × 40 × 30 mm, manifold, 614 facets, 24,811.5 mm³ |
| PLY to STL | The STL of the bracket. PrusaSlicer: the same numbers as from the OBJ |
| GLB to STL | The STL of the assembly. PrusaSlicer: 80 × 50 × 38 mm, 5 parts, manifold, 69,425.9 mm³ |
| FBX to STL | The STL of the desk lamp. PrusaSlicer: 320 × 160 × 230 mm, 4 parts, manifold |
| STL to 3MF | The 3MF of the bracket. PrusaSlicer: 60 × 40 × 30 mm, manifold, 24,811.5 mm³ |
| OBJ to 3MF | The 3MF of the bracket. PrusaSlicer: the same numbers as from the STL |
| STL to PLY | The PLY of the bracket. assimp: 303 vertices for 614 faces, 60 × 40 × 30 mm |
| STL to OBJ | The OBJ of the bracket. assimp: 614 faces, 60 × 40 × 30 mm, one object named bracket |
| GLB to OBJ | The OBJ and MTL of the assembly. assimp: 1,952 faces, 5 objects named after the parts, the colors of the material file |
| FBX to OBJ | The OBJ and MTL of the desk lamp. assimp: 560 faces, 4 objects named after the meshes, 320 × 230 × 160 mm |
| STL to GLB | The GLB of the bracket. Validator: no errors, no warnings. assimp: 0.06 × 0.03 × 0.04 m |
| OBJ to GLB | The GLB of the bracket. Validator: no errors, no warnings. assimp: 0.06 × 0.03 × 0.04 m |
| OBJ to glTF | The .gltf and .bin of the bracket. Validator: no errors, no warnings. assimp: 0.06 × 0.03 × 0.04 m |
| GLB to glTF | The assembly unpacked. Validator: no errors, no warnings. assimp: 5 named meshes, 1,952 faces |
| glTF to GLB | The assembly packed. Validator: no errors, no warnings. assimp: 5 named meshes, 1,952 faces |
| FBX to GLB | The GLB of the desk lamp. Validator: no errors, no warnings. assimp: 4 meshes, 1 animation, 0.32 × 0.23 × 0.16 m |
| SVG to DXF | The DXF of the gasket. ezdxf: no errors, nothing to fix, 100 × 70 mm from (0, 0). FreeCAD: the same extent |
| PNG to DXF | The DXF of the traced logo. ezdxf: no errors, 8 polylines, 100 mm wide. FreeCAD: the same extent |
| DXF to PDF | The PDF of the plate. pdfinfo: one Letter page, PDF 1.5 |
| SVG to STL | The STL of the tag. PrusaSlicer: 60 × 30 × 2 mm, manifold |
| Image to STL | The lithophane of the hills. PrusaSlicer: 100 × 3 × 75 mm, manifold, 12,997.4 mm³, the volume the page shows |
| STL repair | The broken bracket, repaired. PrusaSlicer: manifold, 24,811.5 mm³, the volume of the bracket it was broken from |
The sizes in meters are those of glTF files, which are in meters by their specification. The files are saved and checked again whenever the code that writes them changes.
Drawings compared with another renderer
The DXF viewer is held against ezdxf, an independent DXF library with its own renderer. Each test drawing is drawn by both, the two pictures are laid over each other, and the share of each one’s ink found in the other is counted:
- lines, arcs, circles, ellipses, splines, bulged polylines, mirrored entities, nested and unevenly scaled blocks, layers and hatches: 99.7% to 100% both ways;
- drawings with text: 93% to 96%, the difference being the font;
- dashed lines: 95% to 96%, the difference being where along a line the dashes start.
Leaders and multilines, which ezdxf draws, are listed by the viewer as not drawn rather than left out without a word. The DXF files the converters write pass ezdxf’s audit with no errors and nothing to fix: 42 of them, from twelve SVG drawings in three variants and three traced pictures in two.
G-code from four slicers
The G-code viewer was tested on the same 20 mm cube sliced by four slicers, from their own command lines. The layer count and the filament length are what each slicer wrote in its own comments:
| Slicer | Layers | Filament, by the slicer | Filament, by the viewer |
|---|---|---|---|
| PrusaSlicer 2.9.6 | 100 | 1,487.15 mm | 1,487.15 mm |
| Cura 5.13.0 | 99 | 1,999.15 mm | 1,999.15 mm |
| OrcaSlicer 2.4.2 | 100 | 1,307.68 mm | 1,307.68 mm |
| Bambu Studio 2.8.2 | 100 | 1,181.42 mm | 1,181.42 mm |
The same holds for files sliced with real machine profiles: a Bambu Lab P1S, a Prusa MK4S, in text and in binary G-code, and a Creality Ender 3 from Cura. Binary G-code read here gives the same points as PrusaSlicer’s text file of the same slice, byte for byte. Arcs, by center and by radius, stay within 0.01 mm of the true curve.
3MF projects from the slicers themselves
The sample project of 3MF to STL was exported by Bambu Studio’s own command line: 4 STL files, with the modifier parts left out. The converter’s volumes match Bambu Studio’s to within 0.1%, object by object.
A real project from Bambu Studio’s own repository, 8 objects each with a modifier, comes out with 12 triangles to an object, as Bambu Studio’s export does. PrusaSlicer 2.9.6 refuses that project (“Archive does not contain a valid model”) and opens the flattened 3MF this site writes from it.
The 3MF viewer splits painted triangles as the slicers do. PrusaSlicer’s own painted test file reads to the last digit of every code, and comes out as its thumbnail shows it.
Large files
Timed on a 2021 laptop (Apple M1 Pro), in the browser, from the file being chosen:
- an STL of 48 MB and 1 million triangles is on screen in 0.3 s in WebKit, and one of 238 MB and 5 million triangles is open and checked in 7.4 s;
- a 3MF of 149 MB and 12.5 million triangles converts in 19 s, and the page never stops answering for more than 72 ms;
- a DXF of 50 MB and 679,303 entities opens in 5 s, then zooms and moves at 60 frames a second;
- a G-code file of 197 MB and 4.6 million moves is open in 1.8 s;
- a STEP assembly of 58 MB and 2,600 parts takes 97 s, all of it the CAD kernel reading the file, and the page says so beside the steps.
What testing changed
Most of what the tests find is fixed before a page is published. Some of it changed what the pages say:
- A 16 mm shaft read 15.96 mm when it was measured on the mesh drawn on screen, whose straight pieces cut inside every curve. The STEP viewer now measures the exact solids of files up to 30 MB, and says when it measures the mesh instead.
- Corners that met came apart in OBJ files. The writer gave seven figures, and the last could move a corner. It now writes the fewest figures that read back as the same number, and a test reads every corner of the sample back.
- A cube with two painted colors, saved as a 3MF with a part for each color, came out as two open parts in PrusaSlicer. A 3MF is now cut by color only where every part stays closed, and a note says when it is not.
- The STEP pages said a circle had about 11, 21 and 79 sides at the three qualities, worked out from the angle alone. Counted on the sample, it has 21, 42 and 158. The pages say so now, and a test counts them.
- Two parts of one name became one in other programs. The sample assembly has two screws, both named Screw, and assimp read the OBJ’s two objects of that name as one mesh. The second is now named Screw_2, as the STL files of the parts already were.
- No page says “ready for an AMS”. Opened in Bambu Studio and PrusaSlicer, a 3MF with a part for each color has every part on the first filament: neither takes a color from the file, so the pages say what each slicer does with the parts.
- A G-code file of 4.6 million moves never finished drawing on a computer without graphics acceleration. It is drawn another way there, in about 2 s, and the page says why.
Browsers, phones and accessibility
Every browser test runs in Chromium and in WebKit, and the whole suite runs in Firefox and on an emulated phone as well. Safari on the iOS Simulator and Chrome on an Android emulator open every tool’s sample and turn it with a finger.
axe, the accessibility checker, finds nothing against WCAG 2.2 A and AA on any page, or on any tool with its sample open, in either theme. Every control is at least 24 pixels square, and at least 40 pixels high on a touch screen. Tab reaches every control of an open tool, with a visible ring on each.
The test files
- Files written for the tests, with answers worked out by hand: the cube, the open box, the cylinder, the bracket, the assembly, the desk lamp. The samples offered on each page are among them, released as CC0.
- The 3MF Consortium’s sample files, and real projects and G-code from the repositories of Bambu Studio and PrusaSlicer.
- G-code sliced from one cube by PrusaSlicer, Cura, OrcaSlicer and Bambu Studio.
- DXF drawings written with ezdxf, one for each kind of entity.
- three.js’s own FBX test files: a Mixamo character with 119 bones, which reads 1,947 × 1,805 × 364 mm, the size assimp gives it.
A file that does not work
Files from programs not named here are read by the same code, but nobody here has opened them in their maker’s program. If a tool gives a wrong number or cannot open a file it should, say so: a file that fails is the most useful thing to report, and it becomes a test.