Benchmark
What nine 3MF to STL converters keep, drop and add
When a 3MF file is converted to STL, which converters keep its geometry right, and what do they do with units, mirrored parts, other plates, modifiers and negative parts?
Result
On simple files the geometry mostly survives. Rotation, scaling, multiple objects and repeated components came through every converter that kept millimetres. Two things did not: four converters ignored a 3MF declared in inches and wrote a box 25.4 times too small, and five wrote a mirrored part inside out. Blender at its default settings wrote every file 1000 times too small, because it exports metres into a format read as millimetres. Project files are where every converter failed. A project built and saved in Bambu Studio 02.08.02.61, with a modifier and a negative part on plate 1 and a second object on plate 2, was opened by seven of the nine converters and none produced the single correct shell. All seven wrote the plate 2 part into the same STL. Five also wrote the modifier and the negative part as solid blocks. Only Bambu Studio's own interface, when told to run a mesh boolean, and imagetostl.com cut the hole. PrusaSlicer and OrcaSlicer's command line refused the file outright.
Simple 3MF files: what each converter wrote
| Converter | Setting | Plain box | Box in inches | Rotated | Scaled x2 | Mirrored | Three objects | Components |
|---|---|---|---|---|---|---|---|---|
| PrusaSlicer | command line --export-stl | OK | OK | OK | OK | OK | OK | OK |
| trimesh | load, then export STL | OK | 25.4x too small | OK | OK | OK | OK | OK |
| Bambu Studio | command line --export-stl | OK | OK | OK | OK | inside out | OK | OK |
| OrcaSlicer | command line --export-stl | OK | OK | OK | OK | inside out | OK | OK |
| Blender + 3MF Import/Export | defaults | 1000x too small | 1000x too small | 1000x too small | 1000x too small | 1000x too small | 1000x too small | 1000x too small |
| lib3mf | read, then write STL | OK | 25.4x too small | OK | OK | inside out | OK | OK |
| Blender + 3MF Import/Export | Unit Scale 0.001 before import | OK | OK | OK | OK | OK | OK | OK |
| Bambu Studio | GUI, all objects as one STL, boolean Yes | not run | not run | not run | not run | OK | not run | not run |
| Bambu Studio | GUI, all objects as one STL, boolean No | not run | not run | not run | not run | OK | not run | not run |
| Bambu Studio | GUI, all objects as STLs, boolean Yes | not run | not run | not run | not run | not run | not run | not run |
| imagetostl.com | defaults | OK | OK | OK | OK | inside out | OK | OK |
| meshy.ai | defaults | OK | 25.4x too small | OK (readout) | OK (readout) | OK (readout) | OK (readout) | OK (readout) |
| convert3d.org | defaults | OK | 25.4x too small | OK | OK | inside out | OK | OK |
| 3dtoolwiki.com 3MF to STL (this site) | defaults: plate 1, printing parts only | OK | OK | OK | OK | OK | OK | OK |
OK means the right shape at the right size in the right place relative to the other parts. The inch column is the one that catches converters out: STL has no unit and is read as millimetres, so a converter has to multiply inch coordinates by 25.4 and four did not. Inside out means the mirror was applied without reversing the triangle winding, so the surfaces face inward; most slicers repair this on import. Readout marks meshy.ai cells taken from the page's own report of what it parsed, because it allows three conversions without an account.
Files written by Bambu Studio and PrusaSlicer
| Converter | Setting | Bambu, single part | Bambu project, two plates | PrusaSlicer project |
|---|---|---|---|---|
| PrusaSlicer | command line --export-stl | OK | refuses to open | hole not cut |
| trimesh | load, then export STL | OK | adds the plate 2 part; modifier as solid; negative part as solid | modifier as solid; negative part as solid |
| Bambu Studio | command line --export-stl | crashes | adds the plate 2 part; hole not cut | modifier as solid; negative part as solid |
| OrcaSlicer | command line --export-stl | crashes | refuses to open | modifier as solid; negative part as solid |
| Blender + 3MF Import/Export | defaults | 1000x too small | 1000x too small | 1000x too small |
| lib3mf | read, then write STL | OK | adds the plate 2 part; modifier as solid; negative part as solid | modifier as solid; negative part as solid |
| Blender + 3MF Import/Export | Unit Scale 0.001 before import | OK | adds the plate 2 part; modifier as solid; negative part as solid | modifier as solid; negative part as solid |
| Bambu Studio | GUI, all objects as one STL, boolean Yes | not run | adds the plate 2 part; hole cut | OK |
| Bambu Studio | GUI, all objects as one STL, boolean No | not run | adds the plate 2 part; hole not cut | not run |
| Bambu Studio | GUI, all objects as STLs, boolean Yes | not run | adds the plate 2 part; hole cut | not run |
| imagetostl.com | defaults | OK | adds the plate 2 part; hole cut | modifier as solid; negative part as solid |
| meshy.ai | defaults | OK (readout) | modifier, negative and other plates read as solid (readout) | modifier, negative and other plates read as solid (readout) |
| convert3d.org | defaults | OK | adds the plate 2 part; modifier as solid; negative part as solid | modifier as solid; negative part as solid |
| 3dtoolwiki.com 3MF to STL (this site) | defaults: plate 1, printing parts only | OK | hole not cut | hole not cut |
The right answer for both projects is one shell: the body with the negative part cut out, 7,360 cubic millimetres instead of 8,000, and nothing else. For the Bambu project that also means leaving out the part on plate 2, which Bambu places 307.2 mm to the right of plate 1. No row gets there.
The two-plate Bambu project, part by part
| Converter | Setting | Plate 2 part included | Modifier | Negative part | Evidence |
|---|---|---|---|---|---|
| PrusaSlicer | command line --export-stl | no output | no output | no output | stl |
| trimesh | load, then export STL | Yes | as solid | as solid | stl |
| Bambu Studio | command line --export-stl | Yes | left out | ignored, no hole | stl |
| OrcaSlicer | command line --export-stl | no output | no output | no output | stl |
| Blender + 3MF Import/Export | defaults | no output | no output | no output | stl |
| lib3mf | read, then write STL | Yes | as solid | as solid | stl |
| Blender + 3MF Import/Export | Unit Scale 0.001 before import | Yes | as solid | as solid | stl |
| Bambu Studio | GUI, all objects as one STL, boolean Yes | Yes | left out | hole cut | stl |
| Bambu Studio | GUI, all objects as one STL, boolean No | Yes | left out | ignored, no hole | stl |
| Bambu Studio | GUI, all objects as STLs, boolean Yes | Yes | left out | hole cut | stl |
| imagetostl.com | defaults | Yes | left out | hole cut | stl |
| meshy.ai | defaults | Yes | as solid | as solid | readout |
| convert3d.org | defaults | Yes | as solid | as solid | stl |
| 3dtoolwiki.com 3MF to STL (this site) | defaults: plate 1, printing parts only | No | left out | ignored, no hole | stl |
A modifier changes print settings inside its volume and is not meant to print. A negative part marks a hole to subtract. Bambu Studio writes both as 3MF objects of type other, and records which plate an object belongs to only in its own Metadata/model_settings.config, so a converter that reads just the 3MF core sees every part as printable geometry on one plate.
Why PrusaSlicer refuses the Bambu project
PrusaSlicer 2.9.6 stops at the first component that points at a type other object, with 'Error (Invalid 3MF format) while parsing 3D/3dmodel.model at line 22'. The 3MF core specification does not allow a build item to reference such an object directly or through components, and PrusaSlicer enforces that. The single part file written by Bambu Studio has no such object and opened in PrusaSlicer without complaint.
Why the command line rows are not the interface
On the three files where both were run, Bambu Studio's interface did better than its command line: it wrote the mirrored part the right way out, left the PrusaSlicer project's modifier and negative part out where the command line wrote them as solids, and cut the Bambu project's hole when told to run the boolean. Both Bambu Studio's and OrcaSlicer's command line also crashed on the single part file Bambu Studio's own command line had written. Read those rows as command line behaviour only. Their command line defaults also arrange and rotate objects, so they were run with --arrange 0 and --orient 0.
How this was measured
Ten 3MF files, each built to test one thing, with the right answer known in advance. Seven are generated model files: a 40 x 20 x 10 mm box in millimetres; the same box declared in inches; rotated 90 degrees by its build item; scaled by 2; mirrored on X; three different boxes as three objects; and one object built from two components that reuse one mesh. Two were written by Bambu Studio 02.08.02.61 itself: a single part from its command line, and a project built in its interface holding the body, a modifier and a negative part on plate 1 and a second object on plate 2. One is a PrusaSlicer 2.9.6 style project holding the same body, modifier and negative part as one mesh with triangle ranges labelled in its config. Every box has distinct dimensions, so each shell in an output is identified by its extents; layout is checked by the offsets between shells, so a converter that moves everything together is not penalised. Negative parts are checked by volume, because a hole that was not cut leaves the bounding box unchanged.
- Software and versions
- Windows 11, PrusaSlicer 2.9.6, Bambu Studio 02.08.02.61, OrcaSlicer 2.4.2, Blender 5.2.2 with 3MF Import/Export 2.7.7, lib3mf 2.5.0, trimesh 5.1.0, imagetostl.com, meshy.ai and convert3d.org on 2026-10-09
- Date measured
- 2026-10-09
- Script
scripts/measure-3mf-to-stl.py- Raw data
- 3mf-to-stl-2026-10-09.json
This data is published under CC BY 4.0. Reuse the numbers freely, with a link back so a reader can check the method.
What this does not show
Stated so the result is not read wider than it goes.
- OrcaSlicer's GUI. Its command line gave the same result as Bambu Studio's on every case it could open, which is expected of a fork, so the GUI was not run. Opening the Bambu-saved project in OrcaSlicer 2.4.2's GUI did show a warning worth knowing: the file was made by a newer Bambu Studio (2.8.2.61) than Orca's compatible version (2.6.0.51), and some settings were not recognised. Its command line refuses the same file.
- The command line of Bambu Studio and OrcaSlicer is not a reliable stand-in for their GUI. Both crash (exit 0xC0000005) on the single-part file that Bambu Studio's own command line wrote, while Bambu Studio's command line opens the GUI-saved project; and where both ran, the GUI handled modifiers and negative parts that the command line did not. Read the CLI rows as CLI behaviour only.
- Bambu Studio's GUI on the generated fixtures other than prusa-project and mirrored. The GUI was run where its command line went wrong or could not run.
- meshy.ai beyond three conversions. Anonymous use is capped at three; the remaining cases use the page's own readout of what it parsed, marked as readout in the data.
- Colour, multi-material painting, painted supports, seams and print settings. STL has no field for any of them, so every converter drops them by definition; there is nothing to measure.
- Real project files downloaded from MakerWorld or Printables. The two Bambu files here were written by Bambu Studio itself and the PrusaSlicer project follows PrusaSlicer's own writer, but none of them is a project with hundreds of thousands of triangles, painted colours and years of format drift behind it.