Other Blogs
GrandpaCAD turns a chat message into a 3D-printable model. The AI writes CAD code, we compile it, you get a mesh. So the single biggest lever I have is which CAD language the AI writes in. Pick the wrong one and the model spends its budget fighting syntax instead of building your part.
Every time I post about this, a few people on Hacker News tell me the same thing: OpenSCAD is a toy, it can't do real CAD, and I should be using a proper parametric kernel like CadQuery or Build123d instead. They are partly right, the kernels really are more capable. So instead of arguing, I ran the experiment. If you landed here because you told me to switch, this is my answer.
I wrote earlier about why we landed on OpenSCAD after starting with a JSON schema, then JSCAD, then Blender. This is the sequel. I went back and tested the two "serious" parametric CAD engines I had skipped, CadQuery and Build123d, one after another, on the same eval suite. Here is what the numbers said.
If you want the methodology behind these runs (how I score, weight, and archive them), that is a separate post: how we test the modelling agent.
There are really two camps.
OpenSCAD is declarative and built on constructive solid geometry. You describe shapes and boolean them together with union, difference, and intersection. The language is small, so there is not much surface area for a model to get wrong.
CadQuery and Build123d are Python libraries that wrap OpenCASCADE, the same B-rep (boundary representation) kernel that sits under FreeCAD and a lot of commercial CAD. B-rep is the "real" CAD approach: exact curved surfaces, and proper fillets and chamfers that break an edge instead of inflating the whole part. On paper they are more capable than OpenSCAD, and they are Python, which every model writes fluently.
So my expectation going in was that the Python B-rep engines would win. They did not.
Every engine ran the same prompt set through the same harness on the same model tier (gemini-3.5-flash, the cheap workhorse I was benchmarking at the time), so the only variable is the CAD language. I care about three things:
Code errors are the honest signal. My harness auto-repairs them, so a user rarely sees the failure, but every repair is another model call, which means more latency and more spend. A high code-error rate is the AI quietly telling you it does not really know the language.
| Engine | Approach | Code errors / gen | Notes |
|---|---|---|---|
| OpenSCAD | Declarative CSG | ~0.4 | Meshes rarely broken, ships today |
| CadQuery | Python, B-rep (OpenCASCADE) | High | Needed a custom colored-3MF exporter; up to half of early runs failed |
| Build123d | Python, B-rep (OpenCASCADE) | ~1.4 to 1.7 | 3-4x OpenSCAD, even with a generated API reference |
On the same model and the same scenarios, OpenSCAD landed around 0.4 code errors per generation (10 across a 23-model run). Build123d, writing Python that should be easier for the model, came in at 40 code errors on the same run without help, and 33 with it, roughly three to four times OpenSCAD's rate. That is three to four times as many repair loops for the same work.
CadQuery was messier to even measure. My first runs did not fall over on syntax, they fell over on export. CadQuery's built-in 3MF writer is mesh-only and drops part colors, so I had to hand-write a colored-3MF exporter before multi-part models came out intact. Before that fix, up to half the scenarios in a run failed outright. Once the plumbing worked the failures dropped, but the underlying pattern matched Build123d: the model kept reaching for methods that do not exist.
This surprised me at first, then it made sense. The thing that makes CadQuery and Build123d powerful is also what trips the model up: a large, fluent, chainable API with hundreds of methods and strict expectations about what returns a face versus an edge versus a wire. Current models have not seen enough of it. They confidently call a method with the wrong name, the wrong argument order, or on the wrong object type. It reads like plausible Python and then does not run.
OpenSCAD has the opposite profile. The language is small and stable, and models get its declarative shape right far more often. When it does slip, a single syntax-repair pass usually fixes it.
I did try to close the gap. For Build123d I generated an exact-signature API reference straight from the library (introspected, not hand-written) and fed it to the model. It measurably helped: code errors on a full run dropped from 40 to 33. But 33 is still well above where OpenSCAD sits. A reference sheet narrows the gap, it does not erase it.
None of this means CadQuery or Build123d are bad. They are better engines. The kernel is more capable and the geometry is more exact, and the day a model writes them as reliably as it writes OpenSCAD, GrandpaCAD will switch. Running them as evals is exactly what lets me flip the engine the moment the scoreboard says it is time.
For now the answer is boring and correct: OpenSCAD is what current models write well enough to ship. I keep CadQuery and Build123d wired up and selectable in the harness so I can re-run this bake-off every time a stronger model lands, and let the numbers decide instead of the hype.
So to everyone telling me to use a real CAD kernel: you are right that it is more capable, and I did try it. The bottleneck today is not the kernel, it is what the model can write without breaking. When that changes, so will the default.
Want to see what the engine produces? Try the OpenSCAD engine.