Your First Model
Time to make real geometry. You'll install OpenSCAD, write a six-line script, and render an STL file a slicer would accept.
Installing OpenSCAD
OpenSCAD is free and open source, and it runs on everything:
- Linux:
sudo apt install openscad(Debian/Ubuntu), or your distro's package manager. - Windows / macOS: download the installer from openscad.org.
Check: after installing, run:
openscad --version
You should see something like:
OpenSCAD version 2021.01
(The exact version doesn't matter; anything from the last few years works with this guide. Every example here was rendered with 2021.01.)
The first script
Create a file called plate.scad with this in it:
// A 40 x 30 x 5 mm plate with a 6 mm hole in the middle.
difference() {
cube([40, 30, 5]);
translate([20, 15, -1])
cylinder(d = 6, h = 7, $fn = 32);
}
Read it inside out:
cube([40, 30, 5]);— a box 40 mm in X, 30 in Y, 5 in Z, with one corner at the origin.translate([20, 15, -1])— move the next thing to the middle of the plate (20, 15), sunk 1 mm below the bottom (-1).cylinder(d = 6, h = 7, $fn = 32);— a 6 mm diameter cylinder, 7 mm tall.$fn = 32says "draw the circle with 32 segments" — smooth enough to look round, coarse enough to render fast. It pokes 1 mm below and 1 mm above the plate so the cut goes all the way through.difference() { A B }— A minus B: the plate with the cylinder's volume removed. A hole.
The pattern to memorize: difference() with the solid first
and the cutters after is how you make most holes, slots, and
pockets in OpenSCAD. You'll use it constantly.
Rendering to STL
OpenSCAD can render without opening its GUI — handy for checking your work:
openscad -o plate.stl plate.scad
Check: it exits silently (no news is good news) and plate.stl
exists. Peek at the size — a 40×30 plate with one hole should be a
few kilobytes, not zero bytes and not megabytes:
ls -la plate.stl
If you open plate.stl in your slicer, you'll see a plate with a
hole, sitting flat on the bed (Z = 0 is the bottom — remember
Thinking in 3D).
What just happened, conceptually
You did the whole CAD loop in six lines:
- Sketch (implicit): the rectangle
[40, 30]and the circled = 6. - Feature:
cubeextruded the rectangle 5 mm;differencecut the hole. - Export: a mesh (STL) your slicer understands.
The .scad file is the recipe; the .stl is the baked cake.
Keep the recipe — see What Is CAD?.
A second shape, for confidence
Add this to a new file, shapes.scad, and render it:
// Three primitives, spaced 30 mm apart.
cube([20, 20, 10]);
translate([30, 0, 0])
cylinder(d = 20, h = 10, $fn = 32);
translate([60, 0, 0])
sphere(d = 20, $fn = 32);
Check: openscad -o shapes.stl shapes.scad succeeds. In the
slicer you'll see a box, a cylinder, and a ball in a row. Notice
the sphere sits half below Z = 0 — spheres are centered on their
position, unlike cubes. (In the GUI you'd see this instantly;
headless, the STL's bounding box tells the story.)
Careful: translate() only affects the next statement. If
you write two shapes after one translate, only the first moves.
This bites everyone once.
Next: Sketches and Constraints