Skip to main content

breptile

Convert STL triangle meshes into clean, editable STEP BREP models — not just a tessellated dump. Planar regions become single planar faces; cylindrical holes and bosses become true analytic cylinders; spherical countersinks and domes become real spheres. Anything that can't be fitted within tolerance falls back to faceted geometry and is flagged in a JSON report for manual (or LLM-assisted) rebuild.

STL vs STEP comparison

Left: input STL (3,476 triangles). Right: converted STEP — 249 BREP faces with 35 planes and 17 true cylinders. Every hole selects as a single cylindrical face in CAD.

Why

STL files carry no topology and no analytic surfaces, so most "STL to STEP" converters emit one planar face per triangle — a file that opens in CAD but is unusable for editing, CAM, or feature recognition. breptile reconstructs analytic surfaces instead, with a hard guarantee: every fitted surface passes through the mesh vertices within a configurable tolerance, and dimensions are never snapped.

Install

python3 -m venv .venv
.venv/bin/pip install breptile        # or: pip install -e . from a checkout

Requires Python 3.10–3.13 (needs OCP/build123d wheels). Dependencies: build123d, trimesh, numpy, scipy, manifold3d, rtree, networkx.

Use

breptile input.stl output.step                      # auto: fit primitives, per-region fallback
breptile input.stl output.step --mode tessellated   # guaranteed success, faceted STEP
breptile input.stl output.step --mode prismatic     # planes only
breptile input.stl output.step --tol 0.01 --report report.json --verify
Flag Meaning
--tol max deviation of any fitted surface from mesh vertices (default: bbox diagonal × 1e-4)
--verify re-tessellate the STEP and report two-sided sampled deviation vs the input
--report write a JSON report: region counts, fit residuals, fallbacks
--force convert non-watertight meshes as open shells
--max-triangles N decimate large inputs first

Or from Python:

from breptile import convert
report = convert("input.stl", "output.step", mode="fit", tol=0.01)

How it works

  1. Load & repair (trimesh + manifold3d): normals, holes, degenerate faces; clear error on non-watertight input.
  2. Segment: region-grow smooth patches by dihedral angle; classify each by least-squares fit — plane → cylinder → sphere — validated against --tol. Cylinder axes come from the facet-normal cloud; fits are refined with Levenberg–Marquardt.
  3. Rebuild BREP (OpenCascade via OCP):
    • planar regions → single faces with hole wires;
    • full-wrap cylinders and spherical bands/caps → analytic faces with exact circular rims shared with neighboring faces, so sewing closes analytically;
    • partial cylinders/sphere patches → trimmed patches with the parametric seam rotated into the region's angular gap;
    • a u/v coverage check prevents a fit from claiming surface the mesh doesn't cover;
    • everything else stays faceted (honest fallback).
  4. Sew → solid → ShapeUpgrade_UnifySameDomainShapeFixBRepCheck → STEP (AP214 or AP242).

Benchmark

Run on the trimesh model corpus (python benchmark/run_benchmark.py):

Benchmark grid

Highlights — 17/18 models produce a valid STEP solid (the 18th is deliberately random triangle soup, which degrades to a flagged open shell):

Model Triangles → faces Analytic Notes
cylinder 416 → 3 100% 2 planes + 1 cylinder
unit_sphere 1,280 → 1 100% single spherical face
featuretype 3,476 → 249 89% 17 true cylinders
ADIS16480 7,436 → 600 87% 24 cylinders, 20 spheres
1002_tray_bottom 4,520 → 112 93% 22 cylinders
teapot / torus ~0% organic → faceted fallback

Verified deviation stays at or below the input mesh's own chord error in all cases — on coarse meshes the analytic surface is more accurate than the STL that described it.

Hybrid LLM workflow

.claude/skills/breptile/SKILL.md teaches Claude (or any agent) to run the pipeline, read the report, and rebuild the regions the fitter couldn't handle as build123d code — then verify the result against the original mesh. Regions carry their fitted parameters (axis/center/radius) even when rejected, giving the agent measured starting points.

Limitations

  • Cones, tori, fillet blends, and freeform surfaces fall back to facets (cone and NURBS fitting are the roadmap).
  • Organic/scanned shapes convert tessellated — a valid STEP, but not parametric.
  • Coplanar-but-disconnected regions are not merged across bodies.

Development

.venv/bin/pytest            # round-trip tests on generated fixtures
python benchmark/run_benchmark.py

MIT licensed. Issues and PRs welcome.

Release files for breptile 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for breptile 0.1.0
File Size Uploaded
breptile-0.1.0.tar.gz 18.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for breptile 0.1.0
File Interpreter ABI Platform
breptile-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 35.3 kB

Release files / breptile-0.1.0.tar.gz

Download URL breptile-0.1.0.tar.gz
Size 18.0 kB
Tags Source
SHA-256 checksum
How to use checksums
fb47d59e54923bc641d6e89a3f91951c1e8334e108f0119fd4b02fba11502c2a
BLAKE2b-256 checksum
How to use checksums
3a19a5fb79a7688e6cb8261f85156568e46074c4137799aab0a59bd25bf02c2a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 25, 2026.

Transparency log

Release files / breptile-0.1.0-py3-none-any.whl

Download URL breptile-0.1.0-py3-none-any.whl
Size 17.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
22b26866cc9a8682140a4cab3fa6b6924d7092151f6d2793801e30047efd7f66
BLAKE2b-256 checksum
How to use checksums
723d6209e29bd885eaca11df1149731605272c581a8d38ef3ba8f48d438ae045
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 25, 2026.

Transparency log

Release history Release notifications | RSS feed

0.2.1

2 release files

0.2.0

2 release files

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page