跳到正文
DEV Community· Emir Mrkaljević·· 2 小時前AI 評分56

mesh2cad 將含噪 STL 網格重建為可編輯 CAD

Turning an STL back into editable CAD: fitting planes, cylinders and cones to noisy meshes in Python

AI 導讀

mesh2cad 0.4.2 改進含噪網格中窄圓錐的重建,會將斷裂成平面條帶的倒角合併為沿相鄰孔或凸台軸線的圓錐。工具可從 STL/OBJ/PLY 擬合平面、圓柱、球體及圓錐,輸出 B-rep STEP;簡單稜柱零件亦可產生參數化 CadQuery 腳本。

正文

If you've ever downloaded a bracket from Printables or Thingiverse and wanted to make one hole 2 mm bigger, you know the problem: an STL is just triangles. Your CAD tool imports it as thousands of tiny facets, and there's no "hole" to edit.

I built mesh2cad to fix that for simple mechanical parts. It takes an STL/OBJ/PLY, finds the planes, cylinders, spheres and cones hiding in the triangles, and writes a real B-rep STEP file. For simple prismatic parts it can also write a parametric CadQuery script where every dimension is a named variable.

demo

pip install mesh2cad
mesh2cad convert part.stl -o part.step --tol 0.1 --report report.md

"Make the hole 2 mm bigger"

This is the part I care about most. With --cadquery, mesh2cad writes a script like this:

# --- parameters ---
base_x           = 40.0  # base length (X)
base_y           = 30.0  # base width (Y)
base_t           = 6.0   # base thickness (Z)
hole_1_d         = 6.0   # diameter
hole_1_csk_d     = 12.0  # countersink diameter
hole_1_csk_angle = 90.0  # countersink angle

Set hole_1_d = 8.0, run python bracket.py, and you get a new STEP. Values are rounded to clean numbers (5.997 becomes 6.0) only when the rounded part still fits the mesh within --tol. Before the script is written, mesh2cad runs it and compares the result with the input mesh. If the part doesn't fit the supported shapes, or the script drifts from the mesh, it writes nothing and tells you why. I'd rather refuse than hand you a script that looks right and isn't.

How it works

  1. Clean the mesh with trimesh and keep a Taubin-smoothed copy just for normals, so noise doesn't wreck the normal estimates.
  2. Grow regions into planes. What's left (strips and leftovers) gets tried as cylinders, spheres or cones, with a robust nonlinear refinement on each fit.
  3. Build an exact B-rep with OpenCascade (through OCP): plane polygons from triple-plane intersections, circles from plane-cylinder and plane-sphere intersections, conical frustums, all sewn into a solid and validated.
  4. Fall back honestly. If exact sewing fails, you get a valid faceted solid with vertices snapped onto the fitted surfaces, and the report says so.
  5. Report fidelity: two-sided Hausdorff and RMS deviation against the input, volume error, and which method was used.

The noise problem

Real scans and exported meshes are noisy, so I test on ground-truth CadQuery parts that get tessellated and then hit with Gaussian vertex noise. Each case runs on 3 seeds and the worst one counts.

The hardest case so far is narrow cones. At 0.2 mm noise, a 2 mm chamfer or a countersink breaks into a ring of flat strips, so the cone fitter never sees a cone at all. Today's 0.4.2 release gathers those strips back into one cone locked to the axis of the neighbouring hole or boss. A chamfered boss is now exact through 0.2 mm noise on all 3 seeds.

Some numbers from the benchmark (worst of 3 seeds):

part noise σ exact Hausdorff vol err
plate with hole 0.2 mm 3/3 0.078 mm 0.18 %
ribbed plate 0.2 mm 3/3 0.108 mm 0.12 %
spherical dome 0.2 mm 3/3 0.241 mm 0.25 %
chamfered boss 0.2 mm 3/3 0.511 mm 0.49 %
countersunk plate 0.05 mm 3/3 0.055 mm 0.07 %
countersunk plate 0.2 mm 1/3 0.590 mm 0.54 %

The full table is in the README, and the same cases run in CI.

Limits (being honest)

  • Only planes, cylinders, spheres and cones. No fillets and no free-form surfaces yet, so organic models and most figurines are out.
  • Cylinders have to end on planes perpendicular to their axis (through-holes, bosses, pins).
  • A 90° countersink at 0.2 mm noise is exact on only 1 of 3 seeds. On the other two you get a valid faceted solid, not the analytic one.
  • The CadQuery script path only covers a Z-up box or plate with pads, vertical holes and vertical bosses. Everything else gets STEP only.

Using it from an AI assistant

mesh2cad also runs as an MCP server, so Claude Desktop, Cursor or any MCP client can call convert, analyze, report and to_cadquery:

{ "mcpServers": { "mesh2cad": { "command": "mesh2cad", "args": ["mcp"] } } }

Install it with pip install "mesh2cad[mcp]".

What's next

Fillets are the obvious next step, since they're everywhere on printed parts. After that I want a FreeCAD macro so you can use it without the command line.

It's MIT-licensed. If you have a simple mechanical STL that mesh2cad gets wrong, please open an issue with the file. Those are the most useful bug reports I can get.

This article was written with AI assistance. The code, benchmarks and numbers come from the repo.

來源:DEV Community · dev.to