Skip to main content

breptile

Blue isometric breptile cube with dimension lines

Reconstruct clean, editable STEP BREP models from meshes and engineering drawings.
Analytic surfaces stay analytic, and every drawing-derived parameter retains its provenance.

PyPI Python versions CI License: MIT

STL vs STEP comparison

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


Contents

Why breptile

STL files carry no topology and no analytic surfaces, so most "STL to STEP" converters emit one planar face per triangle. The result opens in CAD but is unusable for editing, CAM, or feature recognition.

breptile reconstructs analytic surfaces instead, under a hard guarantee: every fitted surface passes through the mesh vertices within a configurable tolerance, and dimensions are never snapped to "nice" values. Regions that cannot be fitted within tolerance fall back to faceted geometry and are flagged in a JSON report, so a conversion never silently invents geometry that isn't in the mesh.

Installation

pip install breptile

Requires Python 3.10–3.13 (bounded by the availability of OCP/build123d wheels). Dependencies — build123d, trimesh, lxml, numpy, scipy, manifold3d, rtree, networkx, matplotlib, ezdxf, and Pillow — install automatically.

Optional PDF drawing dependencies can be installed with:

pip install "breptile[drawing]"

PDF/vector extraction is not implemented in the current release; this extra installs the dependencies reserved for that upcoming stage.

From a checkout:

python3 -m venv .venv
.venv/bin/pip install -e ".[dev]"

Quick start

breptile input.stl output.step

That runs the default auto mode: fit primitives where they hold within tolerance, fall back per region where they don't. Add --report and --verify to see exactly what happened:

breptile input.stl output.step --tol 0.01 --report report.json --verify

Generate a side-by-side PNG preview while converting:

breptile input.stl output.step --preview
breptile input.stl output.step --preview comparison.png

Inspect an existing mesh or STEP model in the local browser CAD viewer, or render it to a PNG:

breptile view output.step
breptile view output.step --compare input.3mf
breptile view output.step --compare reference.webp
breptile view output.step --output preview.png
breptile view output.step --compare input.stl --output comparison.png

The browser viewer runs entirely on 127.0.0.1 and includes orbit, pan, zoom, standard views, face/edge selection, measurement, clipping planes, material controls, and a model tree. Its JavaScript and CSS are bundled with breptile, so it does not need a network connection. Geometry comparisons share one camera, with the source in blue and result in amber; image references use a dedicated panel beside the 3D model. Keep the terminal command running while viewing and press Ctrl-C to stop it.

Use --no-open to print and serve the URL without launching a browser, --port 8080 to choose a port, or --backend matplotlib for the original desktop viewer. Static PNG and side-by-side comparison output continue to use Matplotlib.

Command-line reference

breptile INPUT OUTPUT [--mode MODE] [--tol TOL] [--schema SCHEMA]
                      [--report JSON] [--max-triangles N] [--force] [--verify]
                      [--preview [PNG]]
Flag Default Meaning
--mode auto auto — fit primitives with per-region fallback; prismatic — planes only; tessellated — one face per triangle (always succeeds)
--tol bbox diagonal × 1e-4 Maximum deviation of any fitted surface from the mesh vertices
--schema AP214 STEP application protocol: AP214 or AP242
--report Write the conversion report to this JSON file
--max-triangles Decimate inputs above this triangle count before converting
--force off Convert non-watertight meshes as open shells instead of erroring
--verify off Re-tessellate the written STEP and report two-sided sampled deviation vs the input mesh
--preview [PNG] off Render a side-by-side source/STEP PNG; without a path, use OUTPUT.preview.png

Input may be any mesh format trimesh reads — STL, OBJ, 3MF, PLY. The report is printed to stdout as JSON in all cases; exit code 2 signals a mesh error (for example, non-watertight input without --force).

Drawing to CAD

breptile draw is a second, provenance-first front door for dimensioned engineering drawings. Dimension text is authoritative; sheet geometry is supporting evidence. The pipeline uses editable, versioned JSON between every stage.

breptile does not invoke Codex, Claude Code, or any other LLM. In the current release, raster dimension sheets use an explicit agent handoff: breptile prepares the page image and a starter Drawing IR, then exits with status 1 and raster_input_requires_agent. An external visual coding agent (or a person) must read the sheet and author the Drawing IR and parametric recipe. breptile then builds and verifies the STEP deterministically.

Milestone 1 supports hand-authored Drawing IR and recipe files, parametric STEP building, render-back verification, and this raster review handoff:

# 1. Prepare page-1.png, ir.json, and report.json, then stop for agent review.
breptile draw scan.png part.step --workdir part.work

# 2. After the agent or user completes part.work/ir.json and part.work/recipe.json:
breptile draw build part.work/recipe.json part.step --schema AP242
breptile draw verify part.step part.work/ir.json \
  --recipe part.work/recipe.json --png part.work/compare.png

During the handoff, the agent identifies the drawing views, transcribes dimensions and modifiers such as Ø, R, THRU, depth, tolerance, and feature count, and associates each modeled parameter with its source dimension. Ambiguities remain recorded in the JSON instead of being silently guessed. Verification checks the BREP and dimensions and writes a render-back comparison for the next iteration.

Stage commands are extract, reconstruct, build, verify, synth, and run. Automatic PDF/vector extraction, raster view and dimension understanding, and deterministic IR-to-recipe reconstruction are planned for later milestones. Supplying the optional drawing dependencies does not make those stages automatic in the current release.

breptile draw synth generates a Drawing IR from a finished recipe by building the part and projecting it back into views (breptile draw synth part.work/recipe.json out/). It powers the spec-sheet parts corpus in benchmark/drawings/parts/: canonical parts that publish a dimensioned drawing but no CAD model — N20 and 28BYJ-48 gearmotors, the SG90 servo, the NEMA 17 mounting envelope, HC-SR04 and LCD1602 modules, Raspberry Pi HAT and Arduino Uno board outlines — each verified against the sheet's nominal dimensions, closed-form volume, and exact analytic face counts. python benchmark/drawings/run_benchmark.py sweeps the corpus; see benchmark/drawings/parts/README.md for the contract and how to add a part.

Drawing commands emit one JSON report on stdout. Exit 0 means verified, 1 means reviewable artifacts were written, and 2 means an input, schema, or dependency error.

Python API

from breptile import convert

report = convert(
    "input.stl",
    "output.step",
    mode="auto",          # "auto" | "prismatic" | "tessellated"
    tol=0.01,             # None → bbox diagonal * 1e-4
    schema="AP214",       # or "AP242"
    force=False,
    max_triangles=None,
)

print(report["faces"], report["segmentation"])

Verification is a separate call, so it can be run against any STEP file:

from breptile.mesh import load_mesh
from breptile.verify import deviation

print(deviation("output.step", load_mesh("input.stl", force=True)))
# {'max': 0.0043, 'mean': 0.0006}

Conversion report

convert() returns — and --report writes — a dict of the form:

{
  "input": "input.stl",
  "output": "output.step",
  "mode": "auto",
  "tolerance": 0.0182,
  "triangles": 3476,
  "watertight": true,
  "segmentation": { "plane": 35, "cylinder": 17, "sphere": 0, "freeform": 41 },
  "fit_residuals": { "max_plane": 1.2e-14, "max_cylinder": 0.0031 },
  "regions": { "plane": 35, "cylinder": 17, "sphere": 0,
               "freeform_triangles": 1902, "fallback": 3 },
  "valid_brep": true,
  "faces": 249,
  "deviation": { "max": 0.0043, "mean": 0.0006 }   // only with --verify
}

fallback counts regions whose analytic fit was rejected — the geometry they describe is still exported, faceted. Those are the regions worth rebuilding by hand (see below).

How it works

  1. Load and repair (trimesh + manifold3d) — fix normals, holes, and degenerate faces; raise a clear error on non-watertight input unless --force is given.
  2. Segment — region-grow smooth patches by dihedral angle, then 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 become single faces with hole wires;
    • full-wrap cylinders and spherical bands/caps become analytic faces with exact circular rims shared with neighboring faces, so sewing closes analytically;
    • partial cylinders and sphere patches become 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 — an honest fallback rather than a forced fit.
  4. Finalize — sew → solid → ShapeUpgrade_UnifySameDomainShapeFixBRepCheck → STEP (AP214 or AP242).

Benchmark

Run against the trimesh model corpus with python benchmark/run_benchmark.py:

Benchmark grid

17 of 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 every case — on coarse meshes the analytic surface is more accurate than the STL that described it.

Hybrid LLM workflow

breptile is not an agent harness: it never starts Codex or Claude Code and makes no model API calls. Instead, an external agent can harness breptile's CLI, editable JSON, reports, and verification loop:

  • .claude/skills/breptile/SKILL.md covers hybrid mesh-to-BREP conversion. The agent runs the automatic fitter, reads its report, rebuilds rejected regions as build123d code, and verifies the result against the source mesh. Rejected regions retain measured parameters such as axis, center, and radius, giving the agent evidence instead of guesses.
  • .claude/skills/breptile-drawing/SKILL.md covers dimension sheets. The agent authors or repairs Drawing IR and recipes at the explicit review boundaries; breptile remains responsible for deterministic modeling, STEP export, provenance, and render-back verification.

These are Claude Code project skills, but the workflow and file contracts are agent-agnostic; Codex or another visual coding agent can follow the same loop without any model-specific code inside breptile.

Limitations

  • Cones, tori, fillet blends, and freeform surfaces fall back to facets. Cone and NURBS fitting are on the roadmap.
  • Organic and 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   # regenerate the benchmark grid

Issues and pull requests are welcome at github.com/David-Feldt/breptile.

License

MIT — see LICENSE.

Release files for breptile 0.2.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.2.0
File Size Uploaded
breptile-0.2.0.tar.gz 500.8 kB Details

Built distribution (wheel)

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

Total release size: 1.0 MB

Release files / breptile-0.2.0.tar.gz

Download URL breptile-0.2.0.tar.gz
Size 500.8 kB
Tags Source
SHA-256 checksum
How to use checksums
dbe0edb5f5c5a9104540ca73810f15c9c75899ada773ef37e338d5ac81568e96
BLAKE2b-256 checksum
How to use checksums
4546c8331b51fd3b775b4fdec6acb7f87e73fcc56782379e1a491397167d08fc
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.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 Aug 23, 2026.

Transparency log

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

Download URL breptile-0.2.0-py3-none-any.whl
Size 502.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
1cceb8ff22fb92881d03758e292904fb7af8d92c76910d3f764b4d7f6e882ed3
BLAKE2b-256 checksum
How to use checksums
190fc6b737487347f4c195cce7d69a31f79dfa073491cb1f4ce9b91579a035e4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.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 Aug 23, 2026.

Transparency log

Release history Release notifications | RSS feed

0.2.1

2 release files

This release

0.2.0 This release

2 release files

0.1.0

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