A thirteen-hour print that dies at layer 40 costs you a day and most of a spool. Almost every one of those failures was already visible in the file before you pressed print. You just had to look at the right number, and no slicer shows it to you. This is a small free tool that looks at those numbers for you. I built it because I lost three prints in a week to problems that took under a second to detect once I knew what to measure.
Free, MIT licensed, no account and no telemetry. Two dependencies
(trimesh and numpy), Python 3.9 or newer.
Download the wheel (13 KB) Source tarball
pip install printcheck-0.1.1-py3-none-any.whl
Three commands:
printcheck preflight model.stl # is this orientation printable?
printcheck verify new.gcode --against known.gcode # did anything drift?
printcheck flatten "0.20mm Standard" --profiles-root ... --series ...
It exits 0 when clean and 1 when something fails. Put it in a build script and it
stops a bad plate before it ever reaches the printer.
Both of these come from the same part. The cap of a filament waste container, downloaded from a model site. It killed two prints in a row, in two completely different ways.
The cap arrived as 5 × 227 × 140.1 mm. A five-millimetre-thin wall standing 140 mm tall. That is a 28:1 ratio. It wobbled, detached mid-print, and the nozzle dragged it around the plate. It took its plate-mate down with it. About 14 g of filament and an hour gone.
Nothing warned me. The dimensions were on screen the whole time and I read straight past them. "5 × 227 × 140" does not look like a hazard until you divide it.
$ printcheck preflight cap.stl
cap.stl
size 5.0 x 227.0 x 140.12 mm
height/footprint 28.02:1 (140.12 mm tall on 5.0 mm)
[FAIL] Height/footprint ratio 28.02:1 exceeds 8.0:1 - this stands 140.12 mm
tall on a 5.0 mm footprint and is likely to detach and be dragged.
Over roughly 8:1 with no brim, stop and re-orient. Here it was a single rotation. The print time even dropped slightly.
Here is the part I want to save you. Laying it flat was not enough. The rotation put the cap horizontal, but it landed hollow-side-down. It rested on a thin rim, with 109.4 cm² of flat underside floating three millimetres in mid-air.
The slicer did exactly what it was told and bridged all of it. 1,376 bridge blocks in the first five millimetres. The bridges collapsed, the nozzle dragged the wreckage, and the print died at Z 3 to 4 mm. Then the replacement died at the same height for the same reason. I had decided the problem was stringing and gone off to tune retraction.
One more 180° flip took that number from 109.4 cm² to 0.0, and bridge blocks from 1,376 to 4. It printed clean. 25 of 25 layers, 45.6 minutes, straight through the band that killed both previous attempts.
$ printcheck preflight cap_flat.stl
flat underside in mid-air 109.39 cm2
[FAIL] 109.39 cm2 of flat underside is floating above the plate. The slicer
will bridge all of it and long bridges collapse. This usually means the
part is lying on the wrong face - try flipping it 180 degrees.
It also bins overhangs by angle. Faces at 60 to 75° from vertical genuinely need support, and you want to know that before you decide to go without.
The premise behind verify is that you already own a better specification than any
documentation. The gcode from a print that came out right. So compare against it.
$ printcheck verify new.gcode --against known-good.gcode
config: 2 of 565 keys differ from known-good.gcode
enable_support
known-good: 0
candidate: 1
per-object Z range (plate max Z hides a badly oriented part):
poop_chute.stl_id_0_copy_0 0.20 -> 162.60 mm
support vs overhang: 98% of overhang moves fall in Z bands that also contain
support (peak overhang band 80-100 mm has support).
Three checks, each of which caught something real:
EXCLUDE_OBJECT markers the slicer already emits,
and it is unmissable. 140.20 before the fix, 5.00 after. That is proof rather than inference.Overhang wall features proves
nothing. That classifies a perimeter. It does not say whether anything is underneath it. The count sat at
1,439 with supports both on and off, and I wrongly concluded supports were doing nothing. Comparing the
height distribution of support moves against overhang moves does answer the question.inheritsThis one is narrower. It applies to QIDI Studio and the Orca and Bambu Studio family it forks from. It is also the nastiest of the three, because everything appears to work.
Pass a preset to the CLI as a file path and it does not resolve the preset's inherits
chain. It silently falls back to built-in defaults for every key the file does not literally
contain. Then it reports Success.
One slice of mine came out with volumetric speed 2 instead of 24.5. Acceleration 1000 instead of 20000.
Travel 120 instead of 500. The nozzle at 200 °C instead of 210. 16 of 34 critical settings
wrong, print time inflated by 2.9×, and filament_usage_g reported as 0. That last one
is the tell.
printcheck flatten walks the chain through the vendor index and merges it into one
self-contained file. It goes through the index instead of guessing filenames. A preset's name and its
filename often differ. QIDI PLA Rapido@X4 lives in QIDI PLA Rapido.json, and
guessing fails on exactly the profiles that matter. It also warns when the flattened result has no
curr_bed_type, which quietly defaults the bed to Cool Plate at 35 °C and guarantees PLA will not
stick to a textured PEI sheet.
Only flatten is vendor-specific. preflight works on any STL.
verify works with any slicer that emits a ; key = value config block.
PrusaSlicer, OrcaSlicer, Bambu Studio and their forks all do.
The thresholds came from one real part printed in three orientations with three known outcomes. The 28:1
version that detached. The flat-but-wrong-face version that collapsed twice. The flipped version that printed
clean. That model belongs to its designer and is not mine to redistribute, so the shipped test fixtures are
synthetic parts built to reproduce the same geometry classes. Own the same model yourself and pointing
PRINTCHECK_FIXTURES at it runs the real regression tests too.
It is MIT licensed, so do what you like with it. If it saves you a spool, that is the whole point.