openscad-3d-modeling
OpenSCAD 3D Modeling
Overview
OpenSCAD is a programmer's solid 3D CAD modeller that uses scripts to generate 3D models. Unlike interactive 3D tools, OpenSCAD models are described declaratively in code, making them ideal for AI-driven generation. Models are built from primitives (cube, sphere, cylinder) combined with boolean operations (union, difference, intersection) and transformed (translate, rotate, scale).
Key Concepts
Constructive Solid Geometry (CSG): Combine simple shapes into complex models using boolean operations
union()- Combine multiple shapes into onedifference()- Subtract shapes from each otherintersection()- Keep only overlapping regions
Primitives: Basic building blocks
cube(size=[x,y,z])- Rectangular boxsphere(r=radius)- Spherecylinder(h=height, r=radius)- Cylinderpolyhedron(points, faces)- Arbitrary shape
Transformations: Position and orient shapes
translate([x,y,z])- Move shaperotate([x,y,z])- Rotate around axesscale([x,y,z])- Resize shaperesize([x,y,z])- Resize to specific dimensions
Render Pipeline
OpenSCAD Script (.scad)
↓
Preview (Fast, GPU, approximate)
↓
Full Render (Slow, CPU, exact)
↓
Export (STL, 3MF, OFF, DXF)
Workflow Decision Tree
User Request
↓
Is this for 3D printing?
├── YES → Generate OpenSCAD script
│ ↓
│ Validate script syntax
│ ↓
│ Render preview (openscad -o preview.png input.scad)
│ ↓
│ Full render for export (openscad -o output.stl input.scad)
│ ↓
│ Return .stl + .scad + preview image
│
└── NO → May need Three.js (different skill)
or clarify user intent
Step 1: Generate OpenSCAD Script
Syntax Basics
// Resolution control for 3D printing quality
$fa = 1; // Minimum angle (degrees)
$fs = 0.4; // Minimum size (mm)
// Simple box
cube([20, 20, 10]);
// Sphere
sphere(r=10);
// Cylinder
cylinder(h=20, r=5);
Combine Shapes with CSG
// Union - combine shapes
union() {
cube([20, 10, 10]);
translate([20, 0, 0])
cube([10, 10, 10]);
}
// Difference - subtract shapes
difference() {
cube([20, 20, 10]);
translate([5, 5, -1])
cylinder(h=12, r=3);
}
// Intersection - keep overlap
intersection() {
cube([20, 20, 20]);
sphere(r=15);
}
Transformations
// Translate
translate([10, 10, 0])
cube([10, 10, 10]);
// Rotate
rotate([90, 0, 0])
cylinder(h=20, r=5);
// Scale
scale([2, 1, 1])
sphere(r=10);
// Chain transformations
translate([10, 0, 0])
rotate([0, 90, 0])
cylinder(h=10, r=5);
Modules for Reusability
module gear(teeth=8, radius=20, thickness=5) {
union() {
cylinder(h=thickness, r=radius);
for (i = [0:teeth-1]) {
rotate([0, 0, i * 360/teeth])
translate([radius, 0, 0])
cube([5, 3, thickness], center=true);
}
}
}
// Use module
gear(teeth=12, radius=15, thickness=3);
Step 2: Validate Script
Common Validation Checks
- Syntax errors: Missing semicolons, unmatched brackets
- Valid geometry: Manifold edges, no self-intersections
- Overlap tolerance: Use 0.001mm overlap between touching surfaces
Validation Script
Use scripts/validate_openscad.py to check:
python3 scripts/validate_openscad.py model.scad
Returns:
- ✅ Valid: Script compiles successfully
- ❌ Error: Syntax error message
Step 3: Render Model
Quick Preview (for iteration)
openscad -o preview.png input.scad
- Fast GPU rendering
- Good for checking geometry
- Not export-quality
Full Render (for export)
openscad -o output.stl input.scad
- Slow CPU rendering with CGAL
- Produces exact geometry
- Ready for 3D printing
Export Formats
| Format | Use Case | Command |
|---|---|---|
| STL | 3D printing (most common) | openscad -o model.stl input.scad |
| 3MF | Modern 3D printing (metadata + color) | openscad -o model.3mf input.scad |
| OFF | Simple ASCII format | openscad -o model.off input.scad |
| DXF | 2D drawings (laser cutter) | openscad -o model.dxf input.scad |
| PNG | Preview image | openscad -o model.png input.scad |
Best Practices
1. Resolution Control
Always set resolution variables at the top:
$fa = 1; // Minimum angle: 1 degree
$fs = 0.4; // Minimum size: 0.4mm
$fa: Minimum angle for circle segments (lower = smoother)$fs: Minimum segment size (lower = finer detail)- Default values may create faceted curves
2. Overlap Tolerance
When shapes touch, ensure small overlap (0.001mm):
difference() {
cube([20, 20, 10]);
translate([5, 5, -0.001]) // Small overlap
cylinder(h=10.002, r=3);
}
3. Use Modules
Encapsulate complex geometry in modules:
module bolt_hole(length, diameter) {
cylinder(h=length, r=diameter/2);
}
// Use multiple times
difference() {
plate();
translate([10, 10, 0]) bolt_hole(10, 5);
translate([20, 10, 0]) bolt_hole(10, 5);
}
4. Parameterize Design
Make designs configurable:
module box(width=50, depth=50, height=20, wall_thick=2) {
difference() {
cube([width, depth, height]);
translate([wall_thick, wall_thick, wall_thick])
cube([width-2*wall_thick,
depth-2*wall_thick,
height]);
}
}
// Use with parameters
box(width=60, depth=40, height=15, wall_thick=3);
Common Patterns
Hollow Box
module hollow_box(width, depth, height, wall_thick) {
difference() {
cube([width, depth, height]);
translate([wall_thick, wall_thick, wall_thick])
cube([width-2*wall_thick,
depth-2*wall_thick,
height-wall_thick]);
}
}
Fillet (Rounded Edge)
module fillet(radius, length) {
difference() {
cube([radius, radius, length]);
translate([radius, radius, -1])
cylinder(h=length+2, r=radius);
}
}
Bracket
module bracket(width=40, height=30, thickness=5, hole_diameter=8) {
difference() {
// L-shape
union() {
cube([width, thickness, thickness]);
cube([thickness, height, thickness]);
}
// Holes
translate([width/2, -1, thickness/2])
rotate([-90, 0, 0])
cylinder(h=thickness+2, r=hole_diameter/2);
translate([-1, height/2, thickness/2])
rotate([0, 90, 0])
cylinder(h=thickness+2, r=hole_diameter/2);
}
}
Gear
module gear(teeth=8, radius=20, thickness=5, hole_diameter=5) {
difference() {
union() {
// Main body
cylinder(h=thickness, r=radius);
// Teeth
for (i = [0:teeth-1]) {
rotate([0, 0, i * 360/teeth])
translate([radius, 0, 0])
cube([radius/2, radius/teeth*2, thickness], center=true);
}
}
// Center hole
cylinder(h=thickness+1, r=hole_diameter/2, center=true);
}
}
Resources
scripts/
- validate_openscad.py: Validate OpenSCAD scripts for syntax errors
- Use when checking generated scripts before rendering
references/
- primitives.md: Complete list of OpenSCAD primitives with examples
- transformations.md: Transformation operations and patterns
- modules.md: Common reusable modules and patterns
- export_formats.md: Export format specifications and use cases
assets/
- templates/simple_box.scad: Basic box template
- templates/mechanical_part.scad: Mechanical part template
- templates/parametric_design.scad: Parametric design template
- templates/assembly.scad: Assembly template
Resources
See references/primitives.md for complete primitive reference. See references/modules.md for reusable module patterns. See assets/templates/ for starting templates.
Use scripts/validate_openscad.py to validate scripts before rendering.