I did not start this project to make a point about AI.
I started it because I had a boring, recurring problem.
I have STL files that I want to turn back into editable CAD. Not “technically importable” CAD. Not a STEP file that opens as ten thousand little triangle faces and makes every real CAD operation feel like dental work. I mean editable CAD: holes that are cylinders, walls that are planes, seams that behave like edges, and a model that I can actually modify without recreating the whole thing by hand.
This sounds like a solved problem. STL is everywhere. STEP is everywhere. Fusion, FreeCAD, SolidWorks, OpenCASCADE, and a small civilization of mesh tools already exist. And yet the usual workflow is still: import the STL, squint at a faceted mess, swear a little, and rebuild the important parts manually.
So naturally, I thought: this seems like a perfect place for an AI agent.
By an agentic loop, I mean a model running in a cycle: inspect the current state, choose an action, call a tool, examine the result, and repeat until it decides the job is done.
It also seemed like a genuinely good use case for Temporal. The loop could run for a long time, call failure-prone geometry tools, preserve its progress, retry failed work, and leave an audit trail of what it tried. Temporal could make the agentic loop durable.
The trap was assuming that Durable Execution would make the agent’s geometric judgment better.
AI was useful throughout the project. It helped me explore APIs, sketch strategies, explain geometry failures, and scaffold experiments. But I wanted the agentic loop itself to be the clever part: look at a mesh, reason about what it should become, try things, learn from failures, and gradually get better at the tedious work I was doing by hand.
What made the project better was much less glamorous: generate candidates, validate them, inspect the written STEP, and keep the one that passes. Everything else gets deleted or demoted.
The validator beat the vibes.
The thing I wanted#
The input is a triangulated mesh, usually exported for 3D printing. The output should be a valid STEP solid that a human can edit.
“Valid STEP” is not enough. A faceted conversion can be perfectly valid and still miserable. If a rectangular wall becomes hundreds of tiny triangles, the file opens, but the model is not meaningfully editable. If a circular hole becomes a ring of flat faces, you are not working with the design anymore. You are negotiating with the aftermath.
The converter grew a lot of domain machinery:
-
planar and coplanar simplification
-
holes, cylinders, counterbores, cones, and tapers
-
segmentation and primitive fitting
-
B-spline charts for freeform regions
-
mesh healing, STEP validation, deviation checks, and editability scoring
That list sounds like the kind of thing an AI planner should orchestrate.
Early on, I let the agent inspect diagnostics, decide what to try, and build a plan. But cleverness was not the scarce resource. Evidence was.
What “good” actually meant#
Before the converter could get better, I had to decide what “better” meant. “Looks better” was not good enough. Neither was “fewer faces.” A candidate could merge broad regions, move boundaries, erase holes, and become simpler but less correct.
So the converter started treating every output as guilty until measured otherwise.
Every candidate had to write a STEP file. The converter then read it back, ran BRep checks, and measured face counts, analytic surfaces, fallback triangle-like faces, solids, shells, projection tolerance, and sampled Hausdorff deviation against the original mesh. Later, I added an editability score for face economy, analytic share, feature semantics, seam quality, and validity.
Once the system had a validator, the agent was no longer the right judge. The job became: produce a candidate and survive inspection.
The current architecture is almost aggressively boring:
evaluate_all_passes
-> build_conversion_plan
-> build_candidate_direct
-> select_best_valid_candidate
The README now says the quiet part out loud: there is no planning loop or orchestration layer in the hot conversion path.
That line is there because I learned it the hard way.
When the numbers said no#
Building with AI right now comes with a strange pressure. You know the old approach: heuristics, tests, hard-coded thresholds, fixture baselines, and a lot of “nope, that did not improve anything.” Then you look at the current tools and think: surely the clever new thing should produce a clever new approach.
Sometimes it does.
But sometimes it adds another layer of plausible output between you and the thing you can measure. An agent could explain why a region looked planar, suggest that some triangles should become a cylinder, and write code that produced a STEP file. None of it mattered until the file passed validation.
During one phase, I measured several possible improvements. Three were killed without shipping code because the numbers said they would not improve accepted output.
One proposed segmentation improvement had a theoretical ceiling of a 3.86% drop in freeform share on the file I was trying to tweak, and most of the fallback was two smooth, doubly curved shells thousands of times outside the fit band. Killed.
One extrusion idea ran into the fact that the gear teeth were not simple extrusions. They were herringbone-helical. Different surface class. Maybe future work, but not the thing we were pretending it was. Killed.
One blend recovery path measured exactly zero useful blend-like share on the audited fixtures. Killed.
That felt weirdly good.
No “maybe with more agentic reasoning.” No preserving old architecture because it had once seemed promising. This does not improve the accepted STEP output, so it does not get to stay.
By then, the project was starting to feel less like AI autonomy and more like lab work.
Fusion was not a magic escape hatch#
I ran into the same thing when I tried to use Fusion more directly.
Fusion has real tools and APIs for this. The manual workflow I use runs Generate Face Groups, then Convert Mesh with the method set to Prismatic. Prismatic uses those groups to infer features and merge triangles into CAD-like surfaces. When it works, the result is dramatically cleaner than a one-face-per-triangle conversion.
That sounds exactly like the thing I wanted.
I added Fusion as an optional candidate backend, not a replacement or an oracle. Just another candidate.