OpenSCAD User Manual is comprehensive documentation for learning OpenSCAD. It's better to go through all the documents if you have enough time. However, to be honest, I didn't read all of them. Most of the time, I just search on OpenSCAD CheatSheet, such as looking for a useful module
or function
, figuring how to do a transformation, etc. Then, try to go on my work directly.
In Hello, OpenSCAD!, you've seen several elements in a basic OpenSCAD program, such as variables, for
syntax, cube
, text
modules, translate
, rotate
transformations and so on. Here, I'll elaborate these elements according to the content of OpenSCAD CheatSheet.
Variables
The things you encountered first are OpenSCAD variables. They were classified into Syntax in OpenSCAD CheatSheet.
my_text = "Hello, OpenSCAD!";
step_angle = 30;
radius = 30;
height = 5;
At first glance, they might look unremarkable, only like variables in dynamically-typed languages. You don't have to declare types. But be aware of the description documented in Variables.
OpenSCAD is a Functional programming language,as such variables are bound to expressions and keep a single value during their entire lifetime due to the requirements of referential transparency.
Because of learning by doing, I didn't notice that OpenSCAD is Functional programming when I implemented Maze generator. I used the imperative style in the beginning. After writing some fundamental function
s, I tried to modify a vector and problems happened. I suddenly realized that it's Functional programming and needs different thinking from imperative programming, so I have to rewrite those fundamental functions.
Functional programming is not a problem. Like anything else, if you do enough of it, you eventually get the hang of it. I'm able to handle OpenSCAD with ease now. If someone asks me what Functional programming can do, OpenSCAD is one more example I can list.
OpenSCAD, however, has differences from pure Functional programming. If you assign values to a variable repeatedly, OpenSCAD will not throw an error. In the same variable scope, the variable will keep the last assigned value, no matter where you query the variable. Take the code below for example.
x = 1;
echo(x); // print 2 in the console
x = 2;
echo(x); // print 2 in the console
You can see two “ECHO: 2” in the Console, which is in the bottom of OpenSCAD. Variables are set at compile-time, not run-time explains why there's such behavior. As a beginner, it's enough to think that variables are immutable in OpenSCAD, such as variables in pure Functional programming.
for
loop
The for
loop is listed in the Other category of OpenSCAD CheatSheet. You can find some examples in For Loop. Those examples are very easy so needs no further explanation.
The example code of Hello, OpenSCAD! demonstrates a basic context of how to use for(variable = [start : end])
. OpenSCAD will evaluate each value in the range. The start
is an initial value. The end
is the final value and the increment value defaults to 1. The for
assign each iteratvalue is assigned to the variable
.
Hence:
for (a =[3:5]) {
echo(a);
}
Produces 3, 4, 5 in the Console. But don't think that the following code creates 3, 7, 12 and 12.
sum = 0;
for (a =[3:5]) {
sum = sum + a;
echo(sum);
}
echo(sum);
It prints 3, 4, 5 and 0. Why?
The for
loop creates a block scope. Every time OpenSCAD evaluates sum + a
, the value of sum
comes from the sum
variable outside of the for
loop. It's 0, so you're adding 0 and a
. Then the result is assigned to a new variable sum
on the left side of the assignment operator. When echo(sum)
is executed, the printed value is actually 0 + a
.
As for the sum
variables in sum = 0
and the last statement echo(sum)
, they are in the same scope so have the same value 0.
Because OpenSCAD doesn't throw an error when you re-assign a value to a variable, it might be hard for you to understand the above code in the beginning.
If you have experienced pure Functional programming, you'll know pure Functional programming has no loop, which only exists in imperative programming. Sometimes you might see loop-like syntaxes in pure Functional programming; they're probably syntax-sugars or recursive functions. Try to use a recursive function; you'll know why the above code printed 3, 4, 5 and 0.
module forLoop(range, value) {
if(range[0] <= range[1]) {
sum = value + range[0];
echo(sum);
forLoop([range[0] + 1, range[1]], value);
}
}
sum = 0;
forLoop([3, 5], sum);
echo(sum);
There's a module
definition in this code. I'll explain it in later documents. For now, you may think a module as a function or a method in imperative programming.
3D modules
You saw a cube
module in Hello, OpenSCAD!. It's listed in the 3D category of OpenSCAD CheatSheet. As the name implies, it creates a cube. You can find examples in cube.
There are two key points to use the cube
module. One is using a 3 value vector [x,y,z]
. It creates a cube with dimensions x, y and z. If you use a single value, the cube will have the same sides, which is a rare condition in 3D modeling. The other point is you may specify a center
parameter. It defaults to false
. Once it's true
, the object will be centered at (0, 0, 0). Some other 3D modules also have this center
parameter.
You can use named arguments, such as cube(size = [x,y,z], center = true)
. It's a convenient way to specify parameters without worrying about their sequence. that's to say that writing cube(center = true, size = [x,y,z])
is also acceptable.
2D modules
The text
module creates a text object. The cheatsheet classifies it into the 2D category. As you see in OpenSCAD User Manual/Text, the text
module have plenty of parameters. Basically, text
, size
and font
are most commonly-used parameters.
The text
parameter means the text you want to generate. To allow specification of particular Unicode characters, you can specify them in a string with escape codes. For example.
text("\u20AC 10 \u263A");
It generates a euro sign, 10 and a smiling face.
The value of the size
parameter defaults to 10. The unit is millimeter (mm). The font
parameter accepts a logical font name. If you want to generate non-ASCII characters, such as Traditionally-Chinese characters, remember that your “.scad” file should use encoding UTF-8. Then, use a font which supports the characters. The font, of course, should be installed on your computer. For example, the code below creates the "春"
text with the font name "標楷體"
.
text("春", font = "標楷體");
And you'll see an object created as below.
You text may be bold or italic. As Using Fonts & Styles said, a style
parameter can be added, such as font="Liberation Sans:style=Bold Italic"
.
Extrusion
The text
module is a 2D module. Even the generated object looks like having a thickness; it's still a 2D object. Making a 3D object from a 2D object needs an extrusion operation.
The extrusion used in Hello, OpenSCAD! is linear_extrude
, which is located in Other of OpenSCAD CheatSheet. It takes a 2D object as input and extends it in the third dimension. For example.
linear_extrude(10) text("春", font = "標楷體");
It doesn't need a semicolon between linear_extrude(10)
and text("春", font = "標楷體")
. Some operations in OpenSCAD accept a module directly, or a module after some operations. It's not required to place semicolons between those operations and the target module. The above code creates a 3D object below.
Transformations
As you saw in Hello, OpenSCAD!, using translate
and rotate
is easy. The former moves its target module along the specified vector. The later turns the target module n
degrees around the x, y and z-axis. For example.
translate([-5, -5, -5])
linear_extrude(10)
text("春", font = "標楷體");
This will centers the text("春", font = "標楷體")"
model at (0, 0, 0).
If you want to rotate it 90 degrees around the x-axis, use rotate([90, 0, 0])
.
rotate([90, 0, 0])
translate([-5, -5, -5])
linear_extrude(10)
text("春", font = "標楷體");
You get the final model below.
As you see, semicolons are not necessary when you do operations rotate
, translate
and linear_extrude
in sequence. Under this circumstance, I would use indentation properly because it looks clearer than writing rotate([90, 0, 0]) translate([-5, -5, -5]) linear_extrude(10) text("春", font = "標楷體");
. The readibility is better.
Of course, too much indentation cause problems, too. That is where a module
definition comes in, and I'll say something about it in the later documents.