3. Computer Aided design¶
I explored creating a parametric capybara model using AI assistance. The goal was to see if I could use natural language prompts to generate CAD scripts, similar to how I use Cursor for software development.
1. Raster Image Example¶
I used AI to generate reference images and diagrams for the capybara model.
Prompt used:
“generate the shape of a capybara that is easy to design in cad and add color”

2. SVG Example¶
I also generated a vector logo for the project.
Prompt used:
“generate a minimalist vector logo for a capybara project, clean lines, SVG format”
3. OpenSCAD Example¶
For my software work, I am heavily spoiled by AI where I would use tools like Cursor to write all the code and I would just need to review the code to ensure the AI didn’t hallucinate. I wanted to try the same thing with OpenSCAD and ChatGPT prompts.
Prompt used:
“Write an OpenSCAD script for a parametric capybara. Use simple primitives like ellipsoids and cylinders. Make it look like a toy with a warm brown color.”

// Parametric Simple Capybara (OpenSCAD)
// - Designed for easy CAD-style tweaking and 3D printing
// - Uses rounded capsules/ellipsoids + legs as rounded cylinders
// Units: mm
$fn = 64; // smoothness (lower for faster preview)
// -------------------------
// Parameters
// -------------------------
body_len = 160;
body_wid = 75;
body_ht = 85;
head_len = 60;
head_wid = 52;
head_ht = 52;
leg_rad = 11;
leg_ht = 30;
stance_y = 26; // how far legs are from centerline
front_leg_x= 35; // from body front
rear_leg_x = 125; // from body front
belly_clear= 25; // lifts body above ground
ear_rad = 10;
ear_ht = 8;
eye_rad = 6;
// Colors (simple + toy-like)
body_col = [0.63, 0.41, 0.22]; // warm brown
hoof_col = [0.25, 0.17, 0.10]; // darker feet
eye_col = [0.05, 0.05, 0.05]; // near-black
// -------------------------
// Helpers
// -------------------------
// Ellipsoid via scaled sphere
module ellipsoid(l, w, h) {
scale([l/2, w/2, h/2]) sphere(r=1);
}
// Rounded cylinder (a "capsule" pillar) for legs
module capsule_cyl(r=10, h=30) {
// cylinder + two spheres gives a soft toy-leg silhouette
union() {
translate([0,0,r]) cylinder(r=r, h=max(0, h - 2*r));
translate([0,0,r]) sphere(r=r);
translate([0,0,h-r]) sphere(r=r);
}
}
// Slightly flattened ear nub
module ear() {
scale([1.0, 0.8, 0.6]) sphere(r=ear_rad);
}
// -------------------------
// Capybara
// -------------------------
module capybara() {
// Define body coordinate frame:
// Body "front" at x=0, back at x=body_len.
// Centered in Y, sits above ground by belly_clear.
body_center = [body_len/2, 0, belly_clear + body_ht/2];
// --- Body + head (main mass) ---
color(body_col)
union() {
// Body: ellipsoid, slightly stretched
translate(body_center)
ellipsoid(body_len, body_wid, body_ht);
// Head: ellipsoid, placed forward and slightly higher
// Attach near body front
translate([-head_len*0.45, 0, belly_clear + body_ht*0.55])
rotate([0,0,0])
ellipsoid(head_len, head_wid, head_ht);
// Neck blend: smaller ellipsoid to smooth head-body junction
translate([body_len*0.10, 0, belly_clear + body_ht*0.55])
ellipsoid(body_len*0.35, body_wid*0.75, body_ht*0.75);
// Ears (simple nubs)
translate([-head_len*0.25, head_wid*0.25, belly_clear + body_ht*0.95])
ear();
translate([-head_len*0.25, -head_wid*0.25, belly_clear + body_ht*0.95])
ear();
}
// --- Legs (4) ---
// Put legs under the body, then color feet tips darker.
// (We model whole leg in body color, then add a "hoof cap".)
for (xPos = [front_leg_x, rear_leg_x]) {
for (yPos = [stance_y, -stance_y]) {
// leg
color(body_col)
translate([xPos, yPos, 0])
capsule_cyl(r=leg_rad, h=leg_ht);
// darker foot cap
color(hoof_col)
translate([xPos, yPos, 0])
cylinder(r=leg_rad*1.02, h=leg_ht*0.25);
}
}
// --- Eyes (simple spheres) ---
// Place one eye on visible side; duplicate if you want both.
color(eye_col) {
translate([-head_len*0.25, head_wid*0.42, belly_clear + body_ht*0.70])
sphere(r=eye_rad);
translate([-head_len*0.25, -head_wid*0.42, belly_clear + body_ht*0.70])
sphere(r=eye_rad);
}
// --- Nose dots (optional) ---
color(eye_col) {
translate([-head_len*0.55, head_wid*0.12, belly_clear + body_ht*0.62])
sphere(r=2.0);
translate([-head_len*0.55, -head_wid*0.12, belly_clear + body_ht*0.62])
sphere(r=2.0);
}
}
// Render
capybara();
4. build123d Example¶
I also used the Python library build123d to create a more refined parametric model based on the technical diagram.
Prompt used: Detailed Cursor Prompt

#!/usr/bin/env python3
"""
Parametric Capybara model using build123d
Refined to match technical diagram: bf22da9c-4340-47e1-a050-bdc506f55deb.png
"""
try:
from build123d import *
from ocp_vscode import show, show_object, set_port
import math
print("✓ build123d is available!")
set_port(3939)
# --- Dimensions from Diagram ---
TOTAL_LENGTH = 140
WIDTH = 72 # Max Width
HEIGHT = 78 # Max Height
# Side View Keypoints (X, Z_bottom, Z_top)
# Nose starts at X=0, Z_bottom=24.
# Ear plane at X=34. Height at ear plane is ~72.
# Max height at X ~ 80-90 is 78.
# Leg Dimensions
LEG_INNER_GAP_X = 80
LEG_INNER_GAP_Y = 26
# From front view: Total width 72. Leg inner gap 26.
# Leg Width = (72 - 26) / 2 = 23mm.
LEG_WIDTH = 23
LEG_DEPTH = 23 # Assume roughly square/circular legs
# Leg Center Y
LEG_CENTER_Y = (LEG_INNER_GAP_Y + LEG_WIDTH) / 2 # (26 + 23)/2 = 24.5
with BuildPart() as capybara:
# --- Body ---
# Profiles for loft - "loaf" shape
# Profile Data: (X, Width, Height_Bottom, Height_Top)
# Note: Z=0 is ground.
profiles = [
(0, 18, 24, 42), # Nose Tip (Z_bot=24 from diagram)
(15, 45, 22, 58), # Snout
(34, 72, 20, 72), # At Ears (Width 72, Height 72 from diagram)
(70, 72, 18, 78), # Mid Body (Max Height 78)
(110, 68, 18, 70), # Hips
(140, 20, 24, 45), # Tail End
]
sections = []
for x, w, z_bot, z_top in profiles:
h = z_top - z_bot
z_center = (z_top + z_bot) / 2
with BuildSketch(Plane.YZ.offset(x)) as sk:
with Locations((0, z_center)):
# Squircle profile
RectangleRounded(w, h, radius=min(w, h) * 0.45)
sections.append(sk.sketch)
loft(sections)
# --- Legs ---
# Leg Profile: Rounded Square (Squircle)
# Adjust X positions to fit within 140mm length visually
leg_centers_x = [45, 115] # 45 to 115 is 70mm span.
leg_locs = [
(leg_centers_x[0], LEG_CENTER_Y),
(leg_centers_x[0], -LEG_CENTER_Y),
(leg_centers_x[1], LEG_CENTER_Y),
(leg_centers_x[1], -LEG_CENTER_Y),
]
for x, y in leg_locs:
with BuildPart() as leg:
with Locations((x, y, 0)):
# Leg shaft
Box(LEG_DEPTH, LEG_WIDTH, 40, align=(Align.CENTER, Align.CENTER, Align.MIN))
# Round the legs (vertical edges) to match body style
fillet(leg.edges().filter_by(Axis.Z), radius=8)
# Round the feet (bottom edges)
foot_edges = leg.edges().filter_by(lambda e: e.center().Z < 0.1)
fillet(foot_edges, radius=4)
add(leg.part)
# --- Ears ---
ear_x = 34
ear_z = 70 # Slightly embedded
ear_y = 25 # Wide apart
with Locations((ear_x, ear_y, ear_z), (ear_x, -ear_y, ear_z)):
with BuildPart() as ear:
Sphere(6)
add(ear.part)
# --- Eyes ---
eye_x = 22
eye_y = 28
eye_z = 55
with Locations((eye_x, eye_y, eye_z), (eye_x, -eye_y, eye_z)):
Sphere(3.5)
# --- Export ---
if capybara.part:
export_stl(capybara.part, "capybara.stl")
export_step(capybara.part, "capybara.step")