Install
openclaw skills install openscad-automationDirect OpenSCAD scripting and rendering automation for OpenClaw - create, render, and export 3D models via CLI
openclaw skills install openscad-automationVersion: 1.1.0
Author: Klepeto 🦞
Description: Direct OpenSCAD scripting, rendering automation, and library integration
OpenSCAD is a free, open-source "Programmer's Solid 3D CAD Modeller". Instead of interactive modeling like Fusion 360 or Tinkercad, you write code that describes objects. The script is compiled into a 3D model.
.scad files are plain text, diffable in Git| Use OpenSCAD | Use Fusion 360 / Tinkercad |
|---|---|
| Parametric designs | Organic, freeform shapes |
| Precise mechanical parts | Quick prototyping |
| Mathematical surfaces | Visual, interactive design |
| Batch generation | One-off models |
| Version-controlled designs | Visual iteration |
Get OpenSCAD: https://openscad.org (Windows, macOS, Linux)
????\OpenSCAD\openscad.exe????\.openclaw\workspacebrew install openscad
# Ubuntu/Debian
sudo apt install openscad
# Fedora
sudo dnf install openscad
OpenClaw Path: ~/.openclaw/workspace
# Windows PowerShell
& "????\OpenSCAD\openscad.exe" --version
# macOS/Linux
openscad --version
Expected output: OpenSCAD version 2021.01 (or newer)
.scad files directly to workspace// comments// Variables
width = 50;
height = 30;
depth = 20;
// Primitive solids
cube([width, height, depth], center = true);
sphere(r = 10);
cylinder(h = 30, r = 5);
// Transformations
translate([x, y, z]) { ... }
rotate([x, y, z]) { ... } // degrees
scale([x, y, z]) { ... }
// Boolean operations
union() { ... } // combine
difference() { ... } // subtract
intersection() { ... } // keep overlap
$fn = 100; // Number of fragments (circles)
$fa = 5; // Minimum angle
$fs = 0.5; // Minimum size
Tip: Higher $fn = smoother curves, slower render. Default is 12.
// Conditionals
if (width > 50) {
cube(20);
} else {
sphere(10);
}
// Loops
for (i = [0:5]) {
translate([i * 10, 0, 0])
cube(5);
}
// List comprehensions
sizes = [for (i = [1:10]) i * 2];
// Module (creates geometry)
module box(w, h, d) {
cube([w, h, d], center = true);
}
box(50, 30, 20);
// Function (returns value)
function diameter(pitch, teeth) = pitch * teeth / PI;
gear_d = diameter(2, 20);
// Import STL, OFF, AMF, 3MF
import("part.stl");
// Import DXF, SVG (2D)
import("profile.dxf");
// Export via CLI (not in script)
// & openscad.exe -o output.stl input.scad
* cube(10); // Disable (comment out)
! sphere(10); // Show only (root)
# cylinder(10); // Highlight (debug, red)
% cube(10); // Background (transparent)
circle(r = 10 | d = 20);
square(size = 10, center = true);
square([w, h], center = true);
polygon([[x1,y1], [x2,y2], ...]);
text("Hello", size = 10, font = "Arial");
sphere(r = 10 | d = 20);
cube(size = 10, center = true);
cube([w, d, h], center = true);
cylinder(h = 30, r = 5 | d = 10, center = true);
cylinder(h = 30, r1 = 5, r2 = 3, center = true); // cone
polyhedron(points = [...], faces = [...]);
linear_extrude(height = 10, twist = 45, slices = 20) {
circle(10);
}
rotate_extrude(angle = 360) {
translate([10, 0]) circle(2);
}
translate([x, y, z]) { ... }
rotate([x, y, z]) { ... } // degrees around each axis
rotate(a, [x, y, z]) { ... } // rotate a degrees around vector
scale([x, y, z]) { ... }
resize([x, y, z], auto = true) { ... }
mirror([x, y, z]) { ... }
color("red") { ... }
color("#FF0000") { ... }
color([1, 0, 0, 1]) { ... } // RGBA 0-1
union() {
cube(10);
sphere(10);
}
difference() {
cube(20);
sphere(10); // subtracted from cube
}
intersection() {
cube(20);
sphere(10); // only overlapping volume
}
abs(x) // absolute value
sin(x) // sine (degrees)
cos(x) // cosine
tan(x) // tangent
acos(x) // arccosine
asin(x) // arcsine
atan2(y, x) // arctangent
floor(x) // round down
ceil(x) // round up
round(x) // round nearest
sqrt(x) // square root
pow(x, y) // x^y
ln(x) // natural log
log(x) // base-10 log
min(a, b) // minimum
max(a, b) // maximum
norm(v) // vector norm
cross(a, b) // cross product
str("Value: ", 42) // concatenate
chr(65) // character from code (A)
ord("A") // code from character (65)
len("hello") // length (5)
is_undef(x) // is undefined
is_bool(x) // is boolean
is_num(x) // is number
is_string(x) // is string
is_list(x) // is list/vector
is_function(x) // is function
& "????\OpenSCAD\openscad.exe" -o "output.stl" "model.scad"
& "????\OpenSCAD\openscad.exe" -o "preview.png" --imgsize 1024,1024 "model.scad"
& "????\OpenSCAD\openscad.exe" -o "output.svg" --projection both "model.scad"
& "????\OpenSCAD\openscad.exe" -o "out.stl" -D "width=50" -D "height=30" "parametric.scad"
& "????\OpenSCAD\openscad.exe" "model.scad"
| Option | Description |
|---|---|
-o <file> | Output file (STL, PNG, SVG, etc.) |
-D <var name="val"> | Set variable before rendering |
--imgsize W,H | PNG image size |
--projection [both] | SVG projection type |
--render | Force full CGAL render |
--enable <feature> | Enable experimental features |
--viewall | Fit model in view (PNG) |
--colorscheme <name> | Color theme (starnight, beforedawn, etc.) |
OpenSCAD has a rich ecosystem of community libraries. Import them with use <library.scad> or include <library.scad>.
Best for: Everyday modeling helpers, shapes, masks
use <BOSL2/std.scad>
use <BOSL2/rounding.scad>
rounded_cube([50,30,20], r=5);
Best for: 3D printer parts, electronics enclosures, hardware
use <NopSCADlib/screws.scad>
use <NopSCADlib/enclosures.scad>
screw_hole(3); // M3 screw hole
Best for: 3D printing workflow, mechanical parts, view helpers
use <UB.scad/UB.scad>
view_rotate(); // Animation helpers
Best for: Mathematical modeling, reduced complexity
use <dotSCAD/modeling.scad>
use <dotSCAD/math.scad>
Best for: Metric threads, bolts, nuts, augers
use <threads.scad>
metric_bolt(d=10, pitch=1.5, length=50);
metric_nut(d=10);
Best for: Filleted/rounded parts, ergonomic design
use <round-anything.scad>
round_anything(pts, radius);
Best for: Electronics project boxes with PCB mount
use <YAPP_Box.scad>
// Define PCB dimensions, generate enclosure
Best for: Board game organizers, boxes, inserts
use <boardgame_toolkit.scad>
box_with_lid(w, h, d);
Best for: Educational construction sets, compatible parts
use <stemfie.scad>
stemfie_beam(length);
stemfie_plate(width, height);
.scad files from GitHub????\Documents\OpenSCAD\libraries\~/Documents/OpenSCAD/libraries/~/.local/share/OpenSCAD/libraries/use <BOSL2/std.scad>
// cube.scad
cube([20, 20, 20], center = true);
// box_with_lid.scad
width = 80;
height = 60;
depth = 40;
wall = 2;
lip = 1;
// Box base
difference() {
cube([width, height, depth], center = true);
translate([0, 0, lip])
cube([width - wall*2, height - wall*2, depth], center = true);
}
// Lid
translate([0, 0, depth/2 + lip])
cube([width, height, 5], center = true);
// gear.scad
$fn = 100;
teeth = 20;
module_gear = 2; // module (tooth size)
pitch_diameter = teeth * module_gear;
outer_diameter = pitch_diameter + 2 * module_gear;
difference() {
cylinder(h = 10, d = outer_diameter);
cylinder(h = 12, d = pitch_diameter * 0.4); // shaft hole
}
// enclosure.scad
use <NopSCADlib/screws.scad>
width = 100;
height = 80;
depth = 30;
wall = 2;
// Outer box
difference() {
cube([width, height, depth], center = true);
translate([0, 0, 1])
cube([width - wall*2, height - wall*2, depth], center = true);
}
// Screw bosses (M3)
boss_positions = [[-40, -30], [40, -30], [-40, 30], [40, 30]];
for (pos = boss_positions) {
translate([pos[0], pos[1], -depth/2])
screw_hole(3, l = depth);
}
// phone_stand.scad
$fn = 100;
// Base
cube([80, 60, 5], center = true);
// Back support (angled)
rotate([20, 0, 0])
translate([0, -20, 30])
cube([60, 10, 50], center = true);
// Front lip
translate([0, 25, 10])
cube([60, 5, 15], center = true);
Tell the agent what you want:
"Create a parametric phone stand adjustable for 60-80mm phones"
Agent writes .scad file to workspace.
& "????\OpenSCAD\openscad.exe" -o "preview.png" --imgsize 1024,1024 "design.scad"
& "????\OpenSCAD\openscad.exe" -o "design.stl" "design.scad"
"Make the angle 15° instead of 20°, add cable slot"
Agent modifies parameters, re-render.
$fn wisely: 50-100 for visible curves, 12-24 for hidden featurescenter = true: Makes positioning easier// [10:100:10] creates Customizer sliders// Highlight problematic part
# translate([0, 0, 10])
cube(20);
// Disable temporarily
* sphere(10);
// Show only this part
! cylinder(20);
// Debug output
echo("Width =", width);
| Error | Cause | Solution |
|---|---|---|
Unexpected token | PowerShell syntax | Use & before quoted path |
File not found | Wrong path | Check relative path from workspace |
CGAL error | Non-manifold geometry | Check for holes, intersections, inverted normals |
No top level object | Empty script | Add at least one primitive |
Too many points | Excessive $fn | Reduce resolution |
Import failed | Missing file | Verify file exists and path is correct |
Circular dependency | Modules calling each other | Restructure code |
.scad files are plain text - perfect for GitCreated: 2026-05-24 | Updated: 2026-05-24 (v1.1.0 - Added full documentation, libraries, cheat sheet)
Klepeto 🦞