← Back to PrintParams

Documentation

Write parametric 3D models as code, see live previews, and share via short URLs.

How it works

PrintParams uses PPSCAD (PrintParams Scripted CAD), a simple language designed for parametric 3D modeling. Write code in the editor, click Run (or press Cmd+Enter), and the model renders in real time in the 3D viewer.

All computation happens client-side in a sandboxed Web Worker. Your code runs in the browser — nothing is sent to a server for rendering.

PPSCAD Language Reference →

Complete documentation for the PPSCAD scripting language.

Quick example

// A box with a cylindrical hole through it
param width: float = 30 [10:100] "Width (mm)"
param height: float = 20 [5:50] "Height (mm)"
param depth: float = 10 [2:30] "Depth (mm)"
param hole_radius: float = 4 [1:15] "Hole radius (mm)"

difference {
  cube(width, height, depth)
  translate(width / 2, height / 2, -1)
    cylinder(h: depth + 2, r: hole_radius)
}

This creates a box with a cylindrical hole through it. The parameters appear as sliders in the parameter panel on the right.

PPSCAD at a glance

PPSCAD is inspired by OpenSCAD and JSCAD, with a clean modern syntax:

Primitives

cube(size) or cube(x, y, z)

Axis-aligned box. Single number creates a cube.

cylinder(h: 20, r: 5)

Cylinder. Use r1/r2 for a cone. Supports named or positional args.

sphere(r)

Sphere centered at the origin.

Boolean operations

union { ... }

Combine all children into one shape.

difference { ... }

First child minus all subsequent children.

intersection { ... }

Keep only the overlapping volume.

Transforms

translate(x, y, z) child

Move geometry. Takes a single child or { block }.

rotate(x, y, z) child

Rotate around each axis in degrees.

scale(factor) child

Scale uniformly or per axis.

2D to 3D

extrude(height) circle(r)

Linear extrusion of a 2D shape.

revolve() translate(15, 0) circle(3)

Rotational sweep around the Y axis.

Parameters

Parameters let users tweak your model without editing code. Declare them with the param keyword. When you change a slider, the model re-runs automatically.

Syntax

param name: type = default [min:max:step] "Label" "Description"

Parameter types

// Number with slider
param teeth: int = 20 [6:200] "Number of teeth"

// Float with custom step
param module: float = 2.0 [0.5:10:0.01] "Module (mm)"

// Boolean toggle (checkbox)
param chamfer: bool = true "Add chamfer"

// Dropdown select
param style: choice = round ["round", "square", "hex"] "Head style"

Variables, functions, and modules

// Variables
let outer_r = teeth * module / 2

// Functions (return values)
fn gear_radius(teeth, module) = teeth * module / 2

// Modules (reusable geometry)
mod rounded_box(w, h, d, r) {
  hull {
    translate(r, r, 0) cylinder(h: d, r: r)
    translate(w - r, r, 0) cylinder(h: d, r: r)
    translate(r, h - r, 0) cylinder(h: d, r: r)
    translate(w - r, h - r, 0) cylinder(h: d, r: r)
  }
}

rounded_box(40, 20, 5, 3)

Control flow

// Conditional geometry
if (add_holes) {
  translate(10, 10, -1) cylinder(h: 22, r: 3)
}

// For loop with range (inclusive)
for (i in [0:4]) {
  translate(i * 15, 0, 0) cube(10)
}

// Range with step
for (angle in [0:30:330]) {
  rotate(0, 0, angle) translate(25, 0, 0) cylinder(h: 10, r: 3)
}

Units

All dimensions are in millimeters. The viewer shows bounding box dimensions in mm. STL exports are also in mm — most slicers (PrusaSlicer, Cura, etc.) expect this.

Keyboard shortcuts

Cmd+EnterRun code
Ctrl+EnterRun code (Windows/Linux)

Sharing

Click Save to store your design and get a short URL. Anyone with the link can open your model, adjust the parameters, and download the STL.

Parameters can also be shared via URL query strings, e.g. ?width=50&height=30.