What Slice Maser Actually Does
It slices meshes into layers. That's the whole pitch. The library takes a watertight mesh, runs it through a slab-based intersection engine, and outputs a series of cross-sectional polygons at a given z-resolution. You feed it a model, you get back layer data. From there you can export G-code, generate support structures, or whatever pipeline you've built on top of it. People tend to overcomplicate this. It's not a full slicer. It doesn't handle extrusion widths, travel moves, or material-specific parameters. It handles geometry intersection and polygon output. If you need a complete print pipeline, you're looking at something different. But for anyone building a custom slicing frontend or doing computational geometry work, it's a reasonable starting point.
Getting Slice Maser
The package is available on PyPI. pip install slice-maser should pull it in. Check the GitHub repo for the latest version — the maintainer pushes updates semi-regularly but there's no official release schedule. If you're on Windows, you might hit compilation issues with the C++ backend. I had to compile from source with MinGW and set CC and CXX environment variables to get it to build cleanly. Linux tends to be smoother since most distros ship compatible gcc versions out of the box. The core function is straightforward. You load a mesh — OBJ, STL, whatever — and call the slice method with a range of z-values and a step size. It returns a list of slice objects, each containing the boundary polygons and any holes at that layer. Each slice object has a polygons attribute — a list of rings. The first ring is the outer boundary, subsequent rings are holes. This follows the standard even-odd winding rule used in most rendering and CNC workflows. If you're doing something with these polygons downstream, that convention matters. Don't assume everything is wound clockwise or counter-clockwise consistently across different input meshes.
The algorithm itself is an adaptive slab method. It subdivides the mesh bounds into slabs matching your step size, clips the mesh triangles against each slab plane, and constructs polygons from the resulting edges. For well-behaved meshes at reasonable resolutions it's fast — a 100k triangle model at 0.2mm steps finishes in roughly 8 seconds on my machine. Meshes with lots of near-coplanar triangles or extreme aspect ratios slow it down noticeably because the clipper has to handle more degenerate cases.
Get the Full Details

The Tolerance Problem You'll Hit
This is where people get stuck. The default floating-point tolerance in the triangulation clipper is set to 1e-6 by default. For most models that's fine. For anything with large coordinates — say a building-scale model or a part that was exported in meters instead of millimeters — that tolerance breaks things. Triangles that should share edges won't snap together, and you get stray vertices in your polygons. The fix is to scale your mesh down to a reasonable coordinate range before slicing, or override the tolerance parameter if the API exposes it in your version. I ran into this with a dental crown model exported in millimeters but with vertex coordinates in the tens of thousands due to a bad export preset from the CAD software. The slices came out garbage — overlapping polygons, duplicate edges, rings that weren't closed. I normalized the mesh to unit scale before running it through the slicer, then scaled the output polygons back afterward. Takes two extra lines and saves you from wondering whether the tool is broken when it's really just your coordinate space.
Working with Non-Watertight Meshes
Slice Maser will attempt to slice non-watertight input, but the results are undefined. If your mesh has gaps, you'll get stray polygon segments appearing at random layers. The library doesn't validate manifoldness before slicing — it just proceeds. I used to run a quick closure check using a separate mesh repair tool before passing anything in. Now I just verify visually after the first few slices. If the bottom layers look normal and then something weird appears halfway up, you know there's a gap somewhere in the upper portion of the mesh. There's a middle ground too. If you're intentionally working with open surfaces — say you're doing cross-section analysis rather than 3D printing — you can tell the slicer to treat open edges as boundaries. Set the appropriate flag and it includes those edges in the output instead of trying to fill them. This is useful for architectural sections where you want to see interior wall thickness at each floor level.
Common Pitfall: Step Size vs. Mesh Resolution
A step size smaller than your mesh's smallest feature dimension produces redundant slices. Not harmful, just wasteful. A step size larger than that dimension means you'll skip layers entirely and lose geometry. The rule of thumb is that your step should be no larger than one-third of your smallest intended feature. For a dental model with details under 0.5mm, you're looking at 0.15mm steps or finer. That's going to produce a lot of slice objects. Memory usage scales linearly with the number of layers, and each layer stores full polygon data. I learned this the hard way with a high-detail sculpture scan. Set the step to 0.05mm across a 200mm tall model. That's 4,000 layers. Each layer had thousands of polygon vertices. The process used about 3GB of RAM and took twenty minutes. Dropping the step to 0.2mm brought it down to under 200MB and forty seconds. The visual difference was negligible for my use case.

Exporting the Output
The library supports basic export to JSON and CSV. JSON gives you the full polygon hierarchy with coordinates, which is what you want if you're building a custom renderer or post-processor. CSV is flattened — one row per vertex per layer — which is easier to shove into Excel or a quick visualization script but loses the ring structure. If you need SVG output for visualization, there's no built-in exporter. I wrote a small helper that converts the polygon rings to SVG path data. It's about forty lines of code and handles the basic case fine. There's also a basic STL write function if you want to reconstruct a solid from the slices. It's not production-quality — the lofting between layers is simple and can produce artifacts on complex geometries — but it works for quick checks. I use it to verify that my sliced output can round-trip back into a solid without catastrophic topology errors.
Where It Falls Apart
The biggest limitation is that it's single-threaded. The slicing loop doesn't parallelize across layers, so large models take longer than they should. There's an open issue about adding ray-casting parallelization but nothing landed yet. If you're processing batches of models, you'll want to spin up multiple processes yourself and distribute the work. The polygon simplification is basic. It doesn't merge collinear edges or remove vertices that don't affect the shape. For visualization this is fine. For generating toolpaths it's a problem because you end up with way more vertices than you need. I run the output through a separate simplification pass using a standard Douglas-Peucker algorithm before feeding it to any CNC or laser workflow. That cuts vertex counts by 60-80% on most layers without noticeable quality loss. Another thing: the library has no built-in support for multi-material or multi-part meshes. If your input contains several disconnected meshes, it treats them as one group. The polygons from different parts will appear on the same layers but won't be separated into distinct objects. You need to split your mesh beforehand if you care about keeping parts independent in the output.
For most people building a quick prototype or doing one-off cross-sections, Slice Maser does the job. If you need a full-featured slicer with support generation, infill patterns, and material settings, look elsewhere. But for raw geometric slicing with predictable output, it's functional and the API isn't hostile once you've spent an afternoon with it.
