LuaCAD OpenSCAD to LuaCAD

This page is a reference guide for converting OpenSCAD code to LuaCAD. While Lua is generally a very simple and approachable language, some syntax features might be a little surprising to OpenSCAD users and are highlighted in yellow here.

One of the biggest differences is that parentheses are optional when calling functions in Lua and the argument is either a string or a {…} block (also called a table).

So following statements are equivalent:

Furthermore code is usually written with a method chaining syntax, which puts the focus on the object being manipulated rather than the function being called. This makes it easier to read and understand the code.

Syntax

Description OpenSCAD LuaCAD
Variable assignment x = value; x = value
local x = value
Conditional expression x = cond ? true_val : false_val; x = cond and true_val or false_val
Function definition x = function (a) a + a; x = function (a) return a + a end
Module definition and usage module name(…) {
  …
}
name();
function name(…)
  return …
end
name()
Function definition and usage function name(…) = …
name();
function name(…) return … end
name()
Include file include <….scad> dofile("….lua")
Use file as module use <….scad> local module = require "…"

2D

Description OpenSCAD LuaCAD
Create a circle circle(radius)
circle(r=radius)
circle(d=diameter)
circle(radius)
circle{r=radius}
circle{d=diameter}
Create a rectangle square([width, height], center) square{{width, height}, center=true}
Create a polygon from points polygon([points]) polygon{points}
Create a polygon with paths polygon([points], [paths]) polygon{points, paths}
Create text text(t, size, font,
    halign, valign, spacing,
    direction, language, script)
text(t, {size=size, font=font, ...})
Import 2D file (DXF/SVG) import("….extformats: DXF|SVG", convexity) import("file.dxf", convexity)
Project 3D model to 2D projection(cut) obj:projection(cut)

3D

Description OpenSCAD LuaCAD
Create a sphere sphere(radius)
sphere(r=radius)
sphere(d=diameter)
sphere(radius)
sphere{r=radius}
sphere{d=diameter}
Create a rectangular prism cube([width, depth, height], center) cube{{width, depth, height}, center=true}
Create a cylinder cylinder(h, r|d, center) cylinder(h, r, center)
cylinder{h=h, d=d, center=center}
Create a truncated cone cylinder(h, r1|d1, r2|d2, center) cylinder(h, r1, r2, center)
cylinder{h=h, d1=d1, d2=d2, center=center}
Create a polyhedron polyhedron(points, faces, convexity) polyhedron{points=pts, faces=fcs}
Import 3D file (STL/etc) import("….extformats: STL|OFF|AMF|3MF", convexity) import("file.stl", convexity)
Extrude 2D shape into 3D linear_extrude(height, center, convexity, twist, slices) obj:linear_extrude(height, {center=center, ...})
Rotate 2D shape around Y axis rotate_extrude(angle, convexity) obj:rotate_extrude(angle, segments)
Create a 3D surface from heightmap surface(file = "….extformats: DAT|PNG", center, convexity) surface("file.png", center, convexity)

Boolean operations

Description OpenSCAD LuaCAD
Combine objects union() { obj1; obj2; } obj1 + obj2
Subtract objects difference() { obj1; obj2; } obj1 - obj2
Keep overlapping parts intersection() { obj1; obj2; } obj1 & obj2

Transformations

Description OpenSCAD LuaCAD
Move object translate([x, y, z]) obj:translate(x, y, z)
Rotate around each axis sequentially rotate([x, y, z]) obj:rotate(x, y, z)
Rotate around vector rotate(a, [x, y, z]) obj:rotate(a, {x, y, z})
Scale object scale([x, y, z]) obj:scale(x, y, z)
Resize object to absolute dimensions resize([x, y, z], auto, convexity) obj:resize{{x, y, z}, auto, convexity}
Mirror object across plane mirror([x, y, z]) obj:mirror(x, y, z)
Apply transformation matrix multmatrix(m) obj:multmatrix(m)
Apply color by name color("colorname", alpha) obj:color("colorname", alpha)
Apply color by hex value color("#rgb|#rrggbb")
color("#rgba|#rrggbbaa")
obj:color("#rgb|#rrggbb") obj:color("#rgba|#rrggbbaa")
Apply color by RGBA values color([r, g, b, a]) obj:color(r, g, b, a)
Offset 2D shape offset(r|delta, chamfer) obj:offset(r, chamfer)
Create hull around objects hull() obj:hull()
Minkowski sum of objects minkowski() obj:minkowski()

Modifier Characters

Description OpenSCAD LuaCAD
Disable * s(…)
obj:skip()
Show only ! o(…)
obj:only()
Highlight / debug # d(…)
obj:debug()
Transparent / background % t(…)
obj:transparent()

Math Operators

Arithmetic operators are the same in both languages: +, -, *, /, %, ^. Comparison operators <, <=, ==, >=, > are also identical. The differences are:

Description OpenSCAD LuaCAD
Not Equal b != c b ~= c
Logical And b && c b and c
Logical Or b || c b or c
Negation !b not b

Constants

Description OpenSCAD LuaCAD
Undefined value undef nil
Mathematical constant π (~3.14159) PI PI

Special variables

Description OpenSCAD LuaCAD
Minimum angle $fa settings.fa
Minimum size $fs settings.fs
Number of fragments $fn settings.fn
Animation step $t settings.t
Viewport rotation angles in degrees $vpr settings.vpr
Viewport translation $vpt settings.vpt
Viewport camera distance $vpd settings.vpd
Viewport camera field of view $vpf settings.vpf
Number of module children $children settings.children
True in preview mode, false for render $preview settings.preview

Lists

Description OpenSCAD LuaCAD
Create a list list = […, …, …]; list = {…, …, …}
Index a list (Lua is 1-indexed) x = list[2]; x = list[3]

List Comprehensions

Description OpenSCAD LuaCAD
Generate array with values [ for (i = range|list) i ] local result = {}
for i = start, stop do
  table.insert(result, i)
end
Generate with for loop [ for (init;condition;next) i ] local result = {}
for i = init, max, step do
  if condition then
    table.insert(result, i)
  end
end
Flatten array [ each i ] table.unpack(table)
Filter array with condition [ for (i = …) if (condition(i)) i ] local result = {}
for _, i in ipairs(list) do
  if condition(i) then
    table.insert(result, i)
  end
end
Conditional values in comprehension [ for (i = …) if (condition(i)) x else y ] local result = {}
for _, i in ipairs(list) do
  table.insert(result, condition(i) and x or y)
end
Local assignments in comprehension [ for (i = …) let (assignments) a ] local result = {}
for _, i in ipairs(list) do
  local x = expression
  table.insert(result, a)
end

Flow Control

Description OpenSCAD LuaCAD
For loop with range for (i = [start:end]) { … } for i = start, stop do … end
For loop with step for (i = [start:step:end]) { … } for i = start, stop, step do … end
For loop with list for (i = […,…,…]) { … } for _, i in ipairs({…,…,…}) do … end
For loop with multiple variables for (i = …, j = …, …) { … } for _, item in ipairs(list) do local i, j = item[1], item[2] … end
Intersect multiple iterations intersection_for(i = [start:end]) { … } local models = {} for i = start, stop do table.insert(models, …) end cad.intersection(models)
Intersect with step intersection_for(i = [start:step:end]) { … } local models = {} for i = start, stop, step do table.insert(models, …) end cad.intersection(models)
Intersect list iterations intersection_for(i = […,…,…]) { … } local models = {} for _, i in ipairs({…,…,…}) do table.insert(models, …) end cad.intersection(models)
Conditional execution if (…) { … } if … then … end
Local variable definition let (…) { … } local … = … …

Type test functions

is_bool(), is_num(), and is_list() use the same name in both languages. The differences:

Description OpenSCAD LuaCAD
Check if undefined is_undef(x) x == nil
Check if string is_string(x) is_str(x)
Check if function is_function(x) is_func(x)

Functions

Some functions use the same signature: assert, lookup, version, concat. Note that concat uses {} tables instead of [] arrays.

Description OpenSCAD LuaCAD
Print message to console echo(…) print(…)
Force rendering render(convexity) obj:render_node(convexity)
Convert to string str(123) tostring(123)
Get character from code chr(65) string.char(65)
Get code from character ord("a") string.byte("a")
Search for value search() string.find()
Get parent module name parent_module(idx) debug.getinfo(2, "n").name

Mathematical

Most math functions use the same name and signature in both languages: abs, sign, sin, cos, tan, asin, acos, atan, atan2, floor, ceil, round, sqrt, exp, ln, log, min, max, rands, norm, cross. Trig functions use degrees in both languages.

Description OpenSCAD LuaCAD
Length of array len(list) #list
Local variable declaration let(x = 123) local x = 123
Power function pow(x, y) pow(x, y) or x ^ y