October 26, 2026 • Fun Friday

Fun Friday: Arranging Molecules with AI

Render of the Orbit Gearwheel, attempt 10: a teal thumb ring around four gold herringbone planet gears and a white sun gear marked P

I already have AI building software at scale, so I wanted to see how much of an engineering team I can build with AI support on something physical. The test part is the Orbit Gearwheel, a 60 mm print-in-place disc where you hold a "P" sun gear, turn a thumb ring, and watch four herringbone planet gears orbit in a window. Fila designed, coded and tested it in CadQuery, and it took ten attempts and three real prints to get there. Here is the whole story, failures included, and the working pattern I expect to carry over to real engineering parts.

It started with a chat to Grok in the Tesla. Tony Stark has Jarvis, but I'm an Aussie, so my AI chief of staff on Grok Bot is Bruce. Bruce brought on a new team member, Fila, our AI 3D print builder. My wife, a kindy teacher, gave us the idea, and the new Bambu printer in the Pairti Lab meant we could make it.

The stack

Everything runs from Python scripts on one Linux machine, and a single script, run_all.sh, rebuilds the earlier attempts from source. Fila wrote all of it, including her own tests and checks, and I reviewed the results.

Fila grew her own check set as the project went. After the smooth ring bore showed up in a render, she added the teeth probe. When I asked whether the gears were held in, she wrote the escape test. When the prints came back, she wrote tougher tests to explain what the prints showed.

1. Pick a CAD tool the AI can write as code

I chose CadQuery. It's Python, so the AI writes each part as a script I can read, compare and rerun, and it exports STEP, the format engineering parts travel in. Every attempt is its own small file, attempt1.py to attempt10.py, built on shared geometry code.

2. Write the checks before the first build

The brief asked for gaps of 0.3 mm between moving parts, walls of at least 1.2 mm, a flat base, and overhangs at 45 degrees or shallower. Each one became an automatic check that runs on every build:

The checks did most of the catching. Attempt 1 stopped at its own assert, because the 45 degree lip left 0.2 mm of material where the brief asked for 1.2 mm. Attempt 2 measured 0.247 mm between sun and planet, and attempt 5 measured 0.201 mm between ring and planet. Attempt 4 produced a broken ring solid overlapping the gears, and the validity flags caught it straight away. Attempt 6 came in at 0.280 mm and slipped through, so I held it to the brief's 0.3 mm, and attempt 7 met it.

3. Read every render, then turn what you see into a check

Attempt 3 cutaway render: the teal ring's inner bore is smooth while the orange planets and white sun have teeth
In attempt 3 every number passed, and the render showed a smooth ring bore.

Attempt 3 passed every number. The cutaway render showed the ring bore came out smooth, because the ring's profile started at the tooth root radius, so the tooth cut had nothing to remove. We caught it on the render and added a teeth check that probes for ring material at the tooth tip radius. Now every build checks for teeth automatically. Each catch by eye becomes a check, and the check set grows with the project.

4. Keep an engineer in the review loop

On attempt 7 I asked whether the gears were really held in. Fila answered it with an escape test. It moves each gear in 0.05 mm steps in each direction it tests and records the first collision. The test showed the herringbone teeth were holding the planets at the bottom, after about 0.65 to 0.75 mm of travel. I wanted a solid stop as well, so attempt 8 added a bottom collar on the ring and a 45 degree cap on the sun. With the teeth ignored entirely, the planets now stop after 0.45 mm.

def first_hit(name, direction, others, max_d=25, step=0.05):
    # Slide one gear along a direction and report the first part it hits.
    for k in range(1, int(max_d / step) + 1):
        d = k * step
        moved = parts[name].translate(tuple(np.array(direction) * d))
        for other in others:
            if (moved ^ parts[other]).volume() > 1e-3:  # manifold3d intersection
                return d, other
    return None, None  # free to escape

The test also flagged one soft spot. Upward, the sun was held by its herringbone teeth alone. Hold that thought.

Cross-section of attempt 8 showing the ring's 45 degree top lip and bottom collar, a planet gear, and the sun with its 45 degree cap
Attempt 8 in section, with its top lip, bottom collar and sun cap.

5. Let the printer mark the homework

Attempt 8: beautiful gears, and they fell apart

Attempt 8 came off the P2S with crisp teeth and clean gaps, and it turned. It also came apart in my hand. Fila went back to the model with a tougher escape test that moves gears together, tilts them, and keeps going after one part leaves. It failed attempt 8 in the order the photos suggest, with the sun out the top first and then the planets. The first escape test moved one gear at a time with everything else held in place, and the print showed us that real hands move everything at once.

Photo of the printed Orbit Gearwheel, attempt 8, from above: a clear ring around three dark grey planet gears and a teal sun cap embossed with a P
Attempt 8 off the P2S, with a clear ring, three grey planets and a teal sun, all in one print.
Photo of attempt 8 in pieces: the clear ring, the teal sun with its P cap and herringbone teeth, and three grey herringbone planet gears
In attempt 8 the gears printed beautifully, and they came apart in your hand.

Attempt 9: it holds, with a rattle

Attempt 9 wraps each planet in a V-groove, with a ring collar and a new sun flange underneath and the ring lip and sun cap above, all on 45 degree cones. Each planet is now held by two parts in each direction. I printed it in one colour, and it held together. It also had about 1 mm of play up and down and side to side, enough for the teeth to slip out of mesh.

Photo of attempt 9 printed in one colour pale blue PLA, assembled, on a ribbed fabric surface
Attempt 9 holds together, with about 1 mm of play.

Fila wrote a new play analysis that lets every part move at once to find the worst case. Four things added up:

What changed in attempt 10

Fila tried the easy routes first. Four planets at the brief's 0.3 mm gaps helped, and a taller part barely moved the numbers. Every remaining term was a gap in series, so the gap itself was the lever. Attempt 10 brings:

In the model's worst case, from attempt 9 to attempt 10, with every part shifted the worst way at once:

Stacked cross-sections: attempt 9 above with a 3 mm full-depth tooth band and 15 mm height, attempt 10 below with a 7 mm band of 45 degree herringbone teeth, sun cap, sun flange, ring lip and ring collar labelled
Attempt 9 above and attempt 10 below, with steeper teeth, 7 mm of full-height tooth and a snugger cage.

A tighter gap is a bet on the printer, so Fila also designed a 16 minute test coupon with discs at 0.15, 0.20 and 0.25 mm, to print before the full part. If the 0.20 disc spins free, the 0.20 design is good to go.

Attempt 10: it purrs

I printed attempt 10 in one colour grey at 0.20 mm gaps. The slicer had it at 1 hour 19 minutes and 25 g of filament. It prints in one piece with no supports, and it spins like this straight off the printer. The moment it came off the printer, I said, "That version is perfect. Spins perfectly, almost no slack play in the mechanism."

Photo of attempt 10 printed in one colour grey: a knurled ring around four herringbone planet gears and a sun cap embossed with a P
Attempt ten has four planets and 0.2 mm gaps, and it finally purrs.
Straight off the printer with no supports, a little wiggle, then a flick and it spins.

Print your own

Download the Orbit Gearwheel 3MF (attempt 10, 0.20 mm gaps, 1.3 MB), and the gap test coupon STL.

Print tips: print it in one piece with no supports at 0.20 mm gaps, about 1 hour 19 minutes and 25 g in one colour on a Bambu P2S, and print the gap test coupon first if your printer runs tight.

6. Keep every attempt

Every attempt script, build log and check result stays in the project, all ten of them. The record of what failed and why is as useful as the final part, and it lets me rerun the history whenever a check changes.

7. Price the colours in the slicer before you choose them

Fila sliced attempt 10 with the Bambu Studio command line and the official P2S profiles. In four colours, the slicer reports 6 hours 20 minutes, 109 g of filament and 160 filament changes. In one colour, it's 1 hour 19 minutes and 25 g. That's about 84 g more filament for the same part, spent on the colour changes.

The short version Write the checks first, read every render, and turn each human catch into a new check. When parts nest inside each other, count how the gaps stack up in series, because the play adds up along the chain. Print a gap test coupon before the full part, then let the real print mark the model's homework. Ten attempts, three prints, one very happy fidget.