1. Why I wanted to test this
I am a mechanical engineering student, and like most students I now see AI tools everywhere. They explain thermodynamics, debug my Python, and summarize papers. So one question kept bothering me: if an AI can write code, can it also write a mechanical design?
Code and CAD feel closely related. Tools like CadQuery and OpenSCAD let you describe a 3D part as a script, so in theory an LLM that writes the script can “design” a part from a text description.
But there is a gap between a model that runs and a part that works. A script can execute without errors and still produce a bracket with 0.3 mm walls, holes that overlap the edge, or a gear that cannot mesh with anything. In engineering, “it ran” is not the same as “it is correct.” This article is my attempt, as a student, to define how to measure that gap honestly.
This is Part 1: the method. I am publishing the plan, the rules, and a verified reference script before the results, so that nobody (including me) can bend the criteria to fit the numbers.
2. Background: how CAD represents shapes
To judge AI-generated CAD, it helps to know what CAD software actually stores. Three ideas matter here.
Boundary representation (B-rep). Most mechanical CAD systems describe a solid by its boundary: faces, edges, and vertices, plus the topology that says how they connect. This is why you can select a face and add a fillet. A classic reference for how solids are represented and built up with operations such as union, cut, and intersect is Martti Mäntylä, An Introduction to Solid Modeling (Computer Science Press, 1988).
Constructive solid geometry (CSG). Here a shape is built as a tree of Boolean operations on primitives such as boxes, cylinders, and spheres. OpenSCAD follows this style (OpenSCAD documentation. It is intuitive and very scriptable, but it is mostly used to produce meshes such as STL files, which do not carry the exact faces and edges that B-rep CAD systems use for downstream engineering work.
NURBS and freeform surfaces.
Curved surfaces in CAD are commonly described with NURBS (Non-Uniform Rational B-Splines). The standard reference is Les Piegl and Wayne Tiller, The NURBS Book, 2nd ed. (Springer, 1997). My understanding is that this is part of why operations like fillets and shells can fail on complex geometry: the kernel has to build new surfaces that stay valid and watertight.
For a broader view of the mathematics behind curves, surfaces, and solids, Michael E. Mortenson, Geometric Modeling, 3rd ed. (Industrial Press, 2006) describes and compares the important methods.
Parametric modeling and design intent
The word parametric matters a lot in this test. A parametric model is driven by named values (length, thickness, hole diameter), so changing one value updates the whole part correctly. The real skill in CAD is not drawing shapes. It is capturing design intent: which dimensions are free, which are constrained, and what must stay true when something changes. A model with hard-coded numbers scattered through the code looks like CAD but behaves like a dead drawing. I treat this as a key test.
3. Code-based CAD: CadQuery and a reference script
I am using CadQuery, a Python module for building parametric 3D CAD models that is based on the OpenCASCADE kernel and can export STEP files; shape objects expose checks such as isValid() and BoundingBox() (CadQuery documentation, I chose code-based CAD for one practical reason: it makes the test reproducible and checkable. I can run the same script on any machine, measure the result with code, and keep everything in version control.
Below is the reference part, an L-bracket with four mounting holes. It shows what “design intent in code” looks like: every dimension is a named parameter, the hole layout is derived from those parameters, and asserts stop the script if the parameters conflict.
import math import cadquery as cq # ---- Parameters (all in millimetres) ---- length = 80.0 # base length along X width = 40.0 # bracket width along Y thickness = 4.0 # base and wall thickness height = 50.0 # overall height along Z hole_dia = 6.5 # clearance hole for an M6 bolt hole_inset = 10.0 # hole centre to the free end and to each side edge hole_pitch_x = 30.0 # spacing between the two hole columns along X # ---- Hole layout, derived from the parameters ---- x_far = length - hole_inset # column nearest the free end x_near = x_far - hole_pitch_x # second column, toward the wall y_edge = width / 2 - hole_inset # two rows at +/- y_edge hole_pts = [(x_near, -y_edge), (x_near, y_edge), (x_far, -y_edge), (x_far, y_edge)] # ---- Design-intent checks: fail early if parameters conflict ---- r = hole_dia / 2 assert x_near - r > thickness, "holes would hit the vertical wall" assert y_edge + r < width / 2, "holes would break through the side edge" assert x_far + r < length, "holes would break through the free end" # ---- L-shaped profile in the XZ plane, extruded symmetrically across Y ---- bracket = ( cq.Workplane("XZ") .polyline([ (0, 0), (length, 0), (length, thickness), (thickness, thickness), (thickness, height), (0, height), ]) .close() .extrude(width / 2, both=True) ) # ---- Cut the mounting holes through the base ---- cutter = ( cq.Workplane("XY") .workplane(offset=-1) .pushPoints(hole_pts) .circle(r) .extrude(thickness + 2) ) bracket = bracket.cut(cutter) # ---- Validity checks against a hand calculation ---- solid = bracket.val() profile_area = length * thickness + (height - thickness) * thickness expected_volume = profile_area * width - len(hole_pts) * math.pi * r**2 * thickness bb = solid.BoundingBox() print("Valid solid:", solid.isValid()) print("Solids:", len(bracket.solids().vals())) print("Volume (mm^3):", round(solid.Volume(), 1), "expected:", round(expected_volume, 1)) print("Bounding box (mm):", round(bb.xlen, 1), round(bb.ylen, 1), round(bb.zlen, 1)) assert solid.isValid() assert abs(solid.Volume() - expected_volume) < 1.0 cq.exporters.export(bracket, "bracket.step") cq.exporters.export(bracket, "bracket.stl") The hand calculation is what makes the checks meaningful. The L-profile area is 80 × 4 + 46 × 4 = 504 mm², and extruding it across the 40 mm width gives 20,160 mm³. The four holes (6.5 mm diameter, 4 mm deep) remove about 531 mm³. So when the script runs correctly it should report a volume of about 19,629 mm³ and a bounding box of 80 × 40 × 50 mm. If a generated script disagrees with these numbers, something is wrong even if it runs. Change thickness from 4 to 6 and the profile, the holes, and the checks all still hold.
4. The test design
The five test parts
I picked parts in increasing order of difficulty, to see where the models start to break:
# | Part | What it tests |
|---|---|---|
1 | L-bracket with 4 mounting holes | Basic extrusion, hole placement, units |
2 | Flanged shaft coupling with keyway | Revolved geometry, standard-style features, tolerances |
3 | Spur gear (specified module, teeth, bore) | Mathematical geometry (involute profile), constraints |
4 | Electronics enclosure with lid and snap-fit | Multiple bodies, wall thickness, fits and clearances |
5 | Bolt, nut, and plate assembly | Assembly relationships, thread representation, clearances |
Each part comes with a written specification: dimensions, units, material, and intended manufacturing process (FDM 3D printing for parts 1, 4, and 5; CNC machining for parts 2 and 3).
Prompts and conditions
Every model receives the same prompt for each part, built from four pieces: the part description with all dimensions in millimetres; the target library (CadQuery) and its version; a request to put all dimensions in a parameter block at the top; and a request to include basic validity checks.
I test two conditions. In the first, the model gets one attempt. In the second, I give the model the error message or a plain description of the failed check and allow up to three repair prompts. This mirrors how people actually use these tools.
For every run I record the exact model name and version, the test date, the Python and CadQuery versions, the operating system, and any printer, slicer, and material used. All prompts and raw outputs are saved unedited in a repository.
Pass/fail criteria (fixed before testing)
I define these rules before looking at any output, so I cannot bend them to fit the results. The thresholds are my own choices for this small test.
- Executes: the script runs to the end with no exception in the recorded CadQuery version, with no manual edits.
- Valid solid: exactly one solid,
isValid()is true, and the volume is positive. - Geometry accurate: overall dimensions within 0.5 mm of the specification, and hole diameters and positions within 0.1 mm.
- Parametric: after I change each key parameter by 25 percent, the script still builds one valid solid and every dependent feature follows.
- Manufacturable (digital): passes every applicable rule in Section 5 for the stated process.
- Exports: STEP and STL files are written and open in a viewer (and in a slicer for printed parts).
Levels of human intervention
- First attempt: the model’s original output, run unedited.
- Repaired: after up to three follow-up prompts that contain only the error message or a plain description of the failed check.
- Manually corrected: I edited the code myself. I count the lines changed and report these separately, never as a model success.
The scoring rubric
I score each output from 0 to 5 on five criteria, where 0 means it fails completely, 3 means it is usable after manual edits, and 5 means it passes with no edits.
Criterion | Question I ask |
|---|---|
Executes | Does the script run without errors? |
Geometry | Do the dimensions and features match the specification? |
Parametric | Does changing a parameter update the model correctly? |
Manufacturable | Would it print or machine without redesign? |
Engineering sense | Would a reviewer accept the design decisions (fits, wall thickness, load paths)? |
5. What “manufacturable” means here
A valid CAD model or a clean STEP export does not prove that a part can be made. In this article, a digital manufacturability evaluation means I check the geometry against the process rules below. A physical evaluation means a part is actually printed or machined. Unless I say a part was physically made, every manufacturability result is digital.
I use two layers of checks. First, automated checks in code: is it one valid solid, is the volume positive and close to a hand calculation, do the bounding box dimensions match the specification, and does it export cleanly to STEP and STL?
Second, an engineering review of the kind taught in a design class.
For design for manufacturing (DFM) thinking, I lean on Geoffrey Boothroyd, Peter Dewhurst, and Winston A. Knight, Product Design for Manufacture and Assembly, 3rd ed. (CRC Press, 2011), and on Karl T. Ulrich, Steven D. Eppinger, and Maria C. Yang, Product Design and Development, 7th ed.
(McGraw-Hill Education, 2020), which has a chapter on design for manufacturing and supply chain. For additive manufacturing constraints I use Ian Gibson, David Rosen, and Brent Stucker, Additive Manufacturing Technologies: 3D Printing, Rapid Prototyping, and Direct Digital Manufacturing, 2nd ed. (Springer, 2015), which includes a chapter on design for additive manufacturing.
For dimensions and fits, I check tolerances against David A. Madsen, David P. Madsen, and Dennis A. Schwartz, Geometric Dimensioning and Tolerancing: Principles and Practices, 10th ed. (Goodheart-Willcox, 2021), which follows the ASME Y14.5-2018 standard. For basic design calculations such as bolt sizing, I use Richard G. Budynas and J. Keith Nisbett, Shigley’s Mechanical Engineering Design, 11th ed.
(McGraw-Hill Education, 2020), which includes a chapter on screws, fasteners, and nonpermanent joints.
The rules below are common rules of thumb, so always confirm the limits for your own printer, material, and machine shop.
For 3D printing (FDM):
- Wall thickness at least a small multiple of the nozzle diameter
- Overhangs steeper than roughly 45 degrees need support or redesign
- Printed holes tend to come out slightly undersized, so clearance fits need allowance
- Moving or mating parts need deliberate clearance gaps
For CNC machining:
- Internal corners need a radius because cutting tools are round
- Very deep, narrow holes are hard to drill and clear chips from
- Features must be reachable by a tool from some direction
6. Failure modes I will be looking for
These are known risks in code generation and CAD scripting, not findings from my tests. In Part 2, I will report only failures I actually observed, and for each one I will say what the model did, how I detected it, and whether the repair worked.
1. Invented or unsupported function calls. Code-generating models can produce code that reads well but fails when run. Mark Chen et al., Evaluating Large Language Models Trained on Code (arXiv:2107.03374, 2021), judged code models by functional correctness (does the program actually work?) rather than by text similarity, and reported limits such as difficulty with long chains of operations and with binding operations to variables. Calling CadQuery methods that do not exist is one form this can take in my setting.
2. Coordinate and workplane confusion. CAD scripting depends on knowing which plane you are sketching on and which way is “up.” A feature can end up on the wrong side of a part or at the wrong height.
3. Unit and dimension drift. A model may switch between millimetres and inches, or misread a diameter as a radius.
4. Hard-coded numbers. A script can look parametric because it has a parameter block, yet use raw numbers in the geometry code, which breaks design intent as soon as a value changes.
5. Operations that fail on real geometry. Fillets, chamfers, and shells can fail when the model picks the wrong edges or the geometry makes the operation invalid. This relates to the boundary-representation operations described in Section 2.
6. Looks right, but not manufacturable. A part can match the specification on paper and still have thin walls, unsupported overhangs, or no clearance for assembly.
7. Math-heavy parts. A spur gear needs a correct tooth profile, and small errors mean gears that will not mesh.
7. Evaluation Criteria
I will evaluate each generated CAD model using the same criteria to keep the comparison consistent. The evaluation will cover five test parts: an L-bracket, a shaft coupling, a spur gear, an electronics enclosure, and a bolt-nut-plate assembly.
For each part, I will check:
- Code execution: Does the generated script run without errors?
- Geometric accuracy: Do the dimensions and features match the specification?
- Solid validity: Does the model produce the expected valid geometry?
- Parametric behavior: Does the model update correctly when key dimensions change?
- Digital manufacturability: Does the geometry meet the predefined requirements for its intended manufacturing process?
- Export compatibility: Can the model be exported and opened in the required formats?
- Repair effort: How many repair prompts or manual code changes are needed?
I will evaluate the original output separately from the output produced after up to three repair prompts. Any manual corrections will be documented separately and will not count as an unmodified AI success.
No scores or comparative results are reported here because the experiments have not yet been completed. Part 2 will present the observations, measurements, and supporting evidence collected during the tests.
8. Limitations of this test
- Small sample. Five parts and a handful of models is not a statistically strong study.
- One library and one workflow. Results may differ with other CAD scripting tools or prompting styles.
- A moving target. AI models change quickly, so any results will describe only the versions and dates I record.
- My own judgment. Parts of the “engineering sense” score involve subjective review, even with a rubric.
- Digital by default. Unless I state that a part was printed or machined, manufacturability is judged on the geometry and the rules above.
- No claim about all AI models. Results will describe only the models, library versions, and parts I test.
9. Conclusion
So, can AI write CAD? My hypothesis, as a student who spends a lot of time checking dimensions, is that it can write CAD code, and sometimes that code will produce a usable part, but “usable” will still depend on a human who understands the geometry, the manufacturing process, and the design intent. The test above is how I plan to find out whether that is true or just a comfortable guess.
What I believe so far is that the hard part of CAD was never typing. It is knowing what the part needs to do, how it will be made, and what could go wrong. If AI speeds up the first draft, the fundamentals taught in design, manufacturing, and tolerancing courses matter more, not less.