# Introduction

OpenSCAD is a software for creating solid 3D CAD objects.
It is free software and available for GNU/Linux, MS Windows and Apple OS X.

Unlike most free software for creating 3D models (such as the well-known application Blender), OpenSCAD does not focus on the artistic aspects of 3D modelling, but instead focuses on the CAD aspects. So it might be the application you are looking for when you are planning to create 3D models of machine parts, but probably is not what you are looking for when you are more interested in creating computer-animated movies.

OpenSCAD is not an interactive modeller. Instead it is something like a 3D interpreter that reads in a script file that describes the object and renders the 3D model from the script file. This gives you (the designer) full control over the modelling process and enables you to easily change any step in the modelling process, or even to produce designs that are defined by configurable parameters.

OpenSCAD provides two main modelling techniques: First, constructive solid geometry (CSG) and second, extrusion of 2D outlines. Autocad DXF files are used as the data exchange format for the 2D outlines. In addition to 2D paths for extrusion, it is also possible to read design parameters from DXF files. In addition to reading DXF files, OpenSCAD can also read and create 3D models in the STL and OFF file formats.

OpenSCAD can be downloaded from http://openscad.org/. You may find extra information in the mailing list.

People who don't want to (or can't) install new software on their computer may be able to use OpenJSCAD ( http://OpenJSCAD.org/ ), a port of OpenSCAD that runs in a web browser, if your browser supports WebGL

A pt_BR translation of this document is avaliable on GitHub repository (not completed/on development) [1]

# First Steps

For our first model we will create a simple 2 x 3 x 4 cuboid. In the openSCAD editor, type the following one line command:

 Usage example 1 - simple cuboid: cube([2,3,4]);  OpenSCAD Simple Cuboid

### Compiling and rendering our first model

The cuboid can now be compiled and rendered by pressing F6 while the openSCAD editor has focus.

Positioning an object

Open one of the many examples that come with OpenSCAD (File, Examples, e.g. example004.scad). Or you can copy and paste this simple example into the OpenSCAD window:

 Usage example 1 - example004.scad: difference() { cube(30, center=true); sphere(20); } translate([0, 0, 30]) { cylinder(h=40, r=10); }  OpenSCAD after pasting the example code and pressing F5

Then press F5 to get a graphical preview of what you typed (or press F6 to get a graphical view).

You get three types of movement in the preview frame:

1. Drag with left mouse button to rotate the view. The bottom line will change the rotate values.
2. Drag with an other mouse button (or control-drag under OSX) to translate (move) the view. The bottom line will change translate values.
3. Use the mouse scroll to zoom in and out. Alternatively you can use the + and - keys, or right-drag with the mouse while pressing a shift key (or control-shift-drag under OSX). The Viewport line at the bottom of the window will show a change in the distance value.

We have already seen how to create a simple cuboid. Our next task is to attempt to use the translate positioning command to place an identical cuboid next to the existing cuboid:

 Usage example 1 - positioning an object: cube([2,3,4]); translate([3,0,0]) { cube([2,3,4]); }  OpenSCAD positioning an object

### There is no semicolon following the translate command

Notice that there is no semicolon following the translate command. This is because the translate command relates to the following object. If the semicolon was not omitted, then the effect of the position translation would end, and the second cuboid would be placed at the same position as the first cuboid. We can change the color of an object by giving it RGB values. Instead of the traditional RGB values from 0 to 255 floating point values are used from 0.0 to 1.0.

 Usage example 1 - changing the color of an object: color([1,0,0]) cube([2,3,4]); translate([3,0,0]) color([0,1,0]) cube([2,3,4]); translate([6,0,0]) color([0,0,1]) cube([2,3,4]);  OpenSCAD changing the color of an object

Color names can be used in the 2011.12 version (and newer). The names are the same used for Web colors. For example: color("red") cube();

If you think of the entire command as a sentence, then color() is an "adjective" that describes the "object" of the sentence (which is a "noun"). In this case, the object is the cube() to be created. The adjective is placed before the noun in the sentence, like so: color() cube();. In the same way, translate() can be thought of as a "verb" that acts upon the object, and is placed like this: translate() color() cube();. The following code will produce the same result:

translate([6,0,0])
{
color([0,0,1])    // notice that there is NO semicolon
cube([2,3,4]);    // notice the semicolon is at the end of all related commands
}


Changing the colors only works in Preview mode (F5). Render mode (F6) does not currently support color.

The openscad model view window provides a variety of view options.

## CGAL Surfaces

The surface view is the initial model view that appears when the model code is first rendered.

## CGAL Grid Only

The Grid Only view presents only the "scaffolding" beneath the surface, also known as a wireframe. Think of the Eiffel Tower.

A wire frame is a visual presentation of a three dimensional or physical object. Using a wire frame model allows visualization of the underlying design structure of a 3D model. Since wireframe renderings are relatively simple and fast to calculate, they are often used in cases where a high screen frame rate is needed (for instance, when working with a particularly complex 3D model, or in real-time systems that model exterior phenomena). When greater graphical detail is desired, surface textures can be added automatically after completion of the initial rendering of the wireframe. This allows the designer to quickly review changes or rotate the object to new desired views without long delays associated with more realistic rendering. The wire frame format is also well suited and widely used in programming tool paths for DNC (Direct Numerical Control) machine tools. Wireframe models are also used as the input for CAM (computer-aided manufacturing). Wireframe is the most abstract and least realistic of the three main CAD models. This method of modelling consists only of lines, points and curves defining the edges of an object. (From Wikipedia: http://en.wikipedia.org/wiki/Wire-frame_model)

## The OpenCSG View

This view mode utilizes the open constructive solid geometry library to generate the model view utilizing OpenGL. If the OpenCSG library is not available or the video card or drivers do not support OpenGL, then this view will produce no visible output.

## The thrown together view

The thrown together view provides all the previous views, in the same screen.

# The OpenSCAD User Interface

## User Interface

Main Window of OpenSCAD with a small script generating the OpenSCAD-Logo.

The user interface of OpenSCAD has three parts

• The viewing area
• The console window
• The text editor

### Viewing area

Preview and rendering output goes into the viewing area. Using the Show Axes menu entry an indicator for the coordinate axes can be enabled.

### Console window

Status information, warnings and errors are displayed in the console window.

### Text editor

The built-in text editor provides basic editing features like text search & replace and also supports syntax highlighting. There are predefined color schemes which can be selected in the Preferences dialog.

OpenSCAD Editor with Find / Replace functionality.

The viewing area is navigated primarily using the mouse:

• Dragging with the left mouse button rotates the view along the axes of the viewing area. It preserves the vertical axis' direction.
• Dragging with the left mouse button when the shift key is pressed rotates the view along the vertical axis and the axis pointing towards the user.
• Dragging with the right mouse button moves the viewing area.
• For zooming, there are four ways:
• using the scroll wheel
• dragging with the middle mouse button
• dragging with the right or middle mouse button and the shift key pressed
• the keys + and -

Rotation can be reset using the shortcut Ctrl+0. Movement can be reset using the shortcut Ctrl+P.

## View setup

The viewing area can be configured to use different rendering methods and other options using the View menu. Most of the options described here are available using shortcuts as well.

### Render modes

#### OpenCSG (F9)

This method produces instantaneous results, but has low frame rates when working with highly nonconvex objects.

Note that selecting the OpenCSG mode using F9 will switch to the last generated OpenCSG view, but will not re-evaluate the source code. You may want to use the Compile function (F5, found in the Design menu) to re-evaluate the source code, build the OpenCSG objects and then switch to OpenCSG view.

##### Implementation Details

In OpenCSG mode, the OpenCSG library is used for generating the visible model. This library uses advanced OpenGL features (2.0) like the Z buffer and does not require an explicit description of the resulting mesh – instead, it tracks how objects are to be combined. For example, when rendering a spherical dent in a cube, it will first render the cube on the graphics card and then render the sphere, but instead of using the Z buffer to hide the parts of the sphere that are covered by the cube, it will render only those parts of the sphere, visually resulting in a cube with a spherical dent.

#### CGAL (Surfaces and Grid, F10 and F11)

This method might need some time when first used with a new program, but will then have higher framerates.

As before with OpenCSG, F10 and F11 only enable CGAL display mode and don't update the underlying objects; for that, use the Compile and Render function (F6, found in the Design menu).

To combine the benefits of those two display methods, you can selectively wrap parts of your program in a render function and force them to be baken into a mesh even with OpenCSG mode enabled.

##### Implementation Details

The acronym CGAL refers to The Open Source Computational Geometry Algorithms Library.

In CGAL mode, the CGAL library is used to compute the mesh of the root object, which is then displayed using simple OpenGL.

### View options

#### Show Edges (Ctrl+1)

The difference between the CGAL and OpenCSG approaches can be seen at edges created by boolean operations.

If Show Edges is enabled, both OpenCSG and CGAL mode will render edges as well as faces, CGAL will even show vertices. In CGAL grid mode, this option has no effect.

Enabling this option shows the difference between OpenCSG and CGAL quite clearly: While in CGAL mode you see an edge drawn everywhere it "belongs", OpenCSG will not show edges resulting from boolean operations – this is because they were never explicitly calculated but are just where one object's Z clipping begins or ends.

#### Show Axes (Ctrl+2)

If Show Axes is enabled, the origin of the global coordinate system will be indicated by an orthogonal axes indicator. Additionally, a smaller axes indicator with axes names will be shown in the lower left corner of the viewing area. The smaller axes indicator is marked x, y, z and coloured red, green, blue respectively.

#### Show Crosshairs (Ctrl+3)

If Show Crosshairs is enabled, the center of the viewport will be indicated by four lines pointing in the room diagonal directions of the global coordinate system. This is useful when aligning the viewing area to a particular point in the model to keep it centered on screen during rotation.

### Animation

The Animate option adds an animation bar to the lower edge of the screen. As soon as FPS and Steps are set (reasonable values to begin with are 10 and 100, respectively), the current Time is incremented by 1/Steps, FPS times per second, until it reaches 1, when it wraps back to 0.

Every time Time is changed, the program is re-evaluated with the variable $t set to the current time. Read more about how$t is used in section Other_Language_Features

### View alignment

The menu items Top, Bottom, …, Diagonal and Center (Ctrl+4, Ctrl+5, …, Ctrl+0, Ctrl+P) align the view to the global coordinate system.

Top, Bottom, Left, Right, Front and Back align it in parallel to the axes, the Diagonal option aligns it diagonally as it is aligned when OpenSCAD starts.

The Center option will put the coordinate center in the middle of the screen (but not rotate the view).

By default, the view is in Perspective mode, meaning that distances far away from the viewer will look shorter, as it is common with eyes or cameras. When the view mode is changed to Orthogonal, visible distances will not depend on the camera distance (the view will simulate a camera in infinite distance with infinite focal length). This is especially useful in combination with the Top etc. options described above, as this will result in a 2D image similar to what one would see in an engineering drawing.

# The OpenSCAD Language

OpenSCAD uses a programming language to create the models that are later displayed on the screen. Comments are a way of leaving notes within the code (either to yourself or to future programmers) describing how the code works, or what it does. Comments are not evaluated by the compiler, and should not be used to describe self-evident code.

// This is a comment

myvar = 10; // The rest of the line is a comment

/*
can span multiple lines.
*/


### Values and Data Types

A value in OpenSCAD is either a Number (like 42), a Boolean (like true), a String (like "foo"), a Vector (like [1,2,3]), or the Undefined value (undef). Values can be stored in variables, passed as function arguments, and returned as function results.

[OpenSCAD is a dynamically typed language with a fixed set of data types. There are no type names, and no user defined types. Functions are not values. In fact, variables and functions occupy disjoint namespaces.]

#### Numbers

Numbers are the most important type of value in OpenSCAD, and they are written in the familiar decimal notation used in other languages. Eg, -1, 42, 0.5, 2.99792458e+8. [OpenSCAD does not support octal or hexadecimal notation for numbers.]

In additional to decimal numerals, the following names for special numbers are defined:

• PI

OpenSCAD has only a single kind of number, which is an IEEE floating point number. [OpenSCAD does not distinguish integers and floating point numbers as two different types, nor does it support complex numbers.] Because OpenSCAD uses the IEEE floating point standard, there are a few deviations from the behaviour of numbers in mathematics:

• The largest representable number is about 1e308. If a numeric result is too large, then the result can be infinity (printed as inf by echo).
• The smallest representable number is about -1e308. If a numeric result is too small, then the result can be -infinity (printed as -inf by echo).
• If a numeric result is invalid, then the result can be Not A Number (printed as nan by echo).
• If a non-zero numeric result is too close to zero to be representable, then the result will be -0 if the result is negative, otherwise it will be 0. Zero (0) and negative zero (-0) are treated as two distinct numbers by some of the math operations, and are printed differently by 'echo', although they compare equal.

Note that 'inf' and 'nan' are not supported as numeric constants by OpenSCAD, even though you can compute numbers that are printed this way by 'echo'. You can define variables with these values by using:

inf = 1e200 * 1e200;
nan = 0 / 0;
echo(inf,nan);


Note that 'nan' is the only OpenSCAD value that is not equal to any other value, including itself. Although you can test if a variable 'x' has the undefined value using 'x == undef', you can't use 'x == 0/0' to test if x is Not A Number. Instead, you must use 'x != x' to test if x is nan.

#### Boolean Values

Boolean values are truth values. There are two Boolean values, named 'true' and 'false'. A Boolean value is passed as the 'center' argument to the 'cube' and 'cylinder' primitives, as the argument to 'if', and as the arguments to the logical operators '!' (not), '&&' (and), and '||' (or).

In all of these contexts, you can actually pass any type of value. Most values, when used in a Boolean context, are equivalent to 'true', but there are a few that are equivalent to 'false'. The values that count as false are:

• false
• 0 and -0
• ""
• []
• undef

Note that nan (Not A Number) counts as true.

#### Strings

A string is a sequence of zero or more unicode characters. String values are used to specify file names when importing a file, and to display text for debugging purposes when using 'echo

A string literal is written as a sequence of characters enclosed in quotation marks ("), like this: "", or "this is a string".

To include a " character in a string literal, use \". To include a \ character in a string literal, use \\. The following escape sequences beginning with \ can be used within string literals:

• \" → "
• \\ → \
• \t → tab
• \n → newline
• \r → carriage return

Note: This behavior is new since OpenSCAD-2011.04. You can upgrade old files using the following sed command: sed 's/\\/\\\\/' non-escaped.scad > escaped.scad

Example:

 echo("The quick brown fox \tjumps \"over\" the lazy dog.\rThe quick brown fox.\nThe \\lazy\\ dog.");


Output:
ECHO: "The quick brown fox jumps "over" the lazy dog.
The quick brown fox.
The \lazy\ dog."

Output: in OpenSCAD version 2013.02.28
ECHO: "The quick brown fox \tjumps \"over\" the lazy dog.
The quick brown fox.\nThe \\lazy\\ dog."

#### Vectors

A vector is a sequence of zero or more OpenSCAD values. Vectors are most commonly used to represent points in 3-space (as [x,y,z] triples), to represent lists of points, and to represent the size of a cuboid (also as an [x,y,z] triple).

A vector is written as a list of zero or more expressions, separated by commas, and enclosed in square brackets, Eg, [] or [10,20,30].

Example

deck = [64, 89, 18];
cube(deck);


Output A cube with the sizes: X = 64, Y = 89, Z = 18.

##### Vectors selection

You can also refer to individual values in a vector with vector[number]. number starts from 0.

Example

deck = [64, 89, 18];
translate([0,0,deck[2]]) cube(deck);


Output The same cube as the previous example would be raised by 18 on the Z axis, since vector indices are numbered [0,1,2] for [X,Y,Z] respectively.

##### Matrix

A matrix is a vector of vectors.

Example

mr = [
[cos(angle), -sin(angle)],
[sin(angle),  cos(angle)]
];


Output Define a 2D rotation matrix.

#### Ranges

Ranges define a series of numerical values.

Range: [<start>:<end>] - iterate from start to end inclusive with a fixed increment of 1. Both start and end can be fractions. It also works if end is smaller than start but as of Version 2014.03 this usage is deprecated and will produce a warning message.

Range: [<start>:<increment>:<end>] - iterate from start to end with the given increment. The increment can be a fraction.
It's valid to use a negative increment, in this case end must be smaller than (or equal to) start.

Warning: If the increment is not an even divider of <end>-<start>, the iterator value for the last iteration will be <end>-(<end>-<start> mod <increment>).

Note for Version < 2014.03: The increment is given as an absolute value and cannot be negative. If <end> is smaller than <start> the increment should remain unchanged.

Example

r = [0.5 : 2.5];
for (n = r) echo(n);


Output
ECHO: 0.5
ECHO: 1.5
ECHO: 2.5

#### The Undefined Value

The undefined value is a special value written as 'undef'. It's the initial value of a variable that hasn't been assigned a value, and it is often returned as a result by functions or operations that are passed illegal arguments. Finally, 'undef' can be used as a null value, equivalent to 'null' or 'NULL' in other programming languages.

Note that numeric operations may also return nan to indicate an illegal argument. For example, 0/false is undef, but 0/0 is nan. Relational operators like < and > return false if passed illegal arguments.

### Variables

Variables in OpenSCAD are simply a name followed by an assignment via an expression (but see below for an important note about variables!)

Example:

myvar = 5 + 4;


Currently it's not possible to do assignments at any place (the only places are file top-level and module top-level). If you need it inside the for loop, for example, you need to use the assign() module.

#### Undefined variable

A non assigned variable has the special value undef. It could be tested in conditional expression, and returned by a function. Example

echo("Variable a is ", a); // output 'Variable a is undef'
if (a==undef) {
echo("Variable a is tested undefined");
}


Output Variable a is undef Variable a is tested undefined

#### Variables are set at compile-time, not run-time

Because OpenSCAD calculates its variable values at compile-time, not run-time, the last variable assignment will apply everywhere the variable is used (with some exceptions, mentioned below). It may be helpful to think of them as override-able constants rather than as variables.

Example:

 // The value of 'a' reflects only the last set value
a = 0;
echo(a);

a = 5;
echo(a);


Output

ECHO: 5
ECHO: 5


This also means that you can not reassign a variable inside an "if" block:

Example:

a=0;
if (a==0)
{
a=1; // <- this line will generate an error.
}


Output Compile Error

##### Exception #1

This behavior is scoped to either the root or to a specific call to a module, meaning you can re-define a variable within a module without affecting its value outside of it. However, all instances within that call will behave as described above with the last-set value being used throughout.

Example:

p = 4;
test(5);
echo(p);
/*
* we start with p = 4.  We step to the next command 'test(5)', which calls the 'test' module.
* The 'test' module calculates two values for 'p', but the program will ONLY display the final value.
* There will be two executions of echo(p) inside 'test' module, but BOTH will display '9' because it is the FINAL
* calculated value inside the module. ECHO: 9   ECHO: 9
*
* Even though the 'test' module calculated value changes for 'p', those values remained inside the module.
* Those values did not continue outside the 'test' module.  The program has now finished 'test(5)' and moves to the next command 'echo(p)'.
* The call 'echo(p)' would normally display the original value of 'p'=4.
* Remember that the program will only show the FINAL values.  It is the next set of commands that produce the final values....which is ECHO: 6
*/
p = 6;
test(8);
echo(p);
/*
* We now see 'p=6', which is a change from earlier.  We step to the next command 'test(8)', which calls the 'test' module.
* Again, the 'test' module calculates two values for 'p', but the program will ONLY display the final value.
* There will be two executions of echo(p) inside 'test' module, but BOTH will display '12' because it is the FINAL
* compiled value that was calculated inside the module.
* Therefore, both echo(p) statements will show the final value of '12' ;
* Remember that the 'test' module final values for 'p' will remain inside the module.  They do not continue outside the 'test' module.
* ECHO:12   ECHO:  12
*
* The program has now finished 'test(8)' and moves to the next command 'echo(p)'.
* Remember at compile that the pgm will show the FINAL values.  The first value of 'echo(p)' would have showed a value of '4'...
* However, at compile time the final value of 'echo(p)' was actually '6'.  Therefore, '6' will be shown on both echo(p) statements.
* ECHO 6
*/

module test(q)
{
p = 2 + q;
echo(p);

p = 4 + q;
echo(p);
}


Output

ECHO: 9
ECHO: 9
ECHO: 6
ECHO: 12
ECHO: 12
ECHO: 6


While this appears to be counter-intuitive, it allows you to do some interesting things: For instance, if you set up your shared library files to have default values defined as variables at their root level, when you include that file in your own code, you can 're-define' or override those constants by simply assigning a new value to them.

##### Exception #2

See the assign, which provides for a more tightly scoped changing of values.

### Getting input

Now we have variables, it would be nice to be able to get input into them instead of setting the values from code. There are a few functions to read data from DXF files, or you can set a variable with the -D switch on the command line.

Getting a point from a drawing

Getting a point is useful for reading an origin point in a 2D view in a technical drawing. The function dxf_cross will read the intersection of two lines on a layer you specify and return the intersection point. This means that the point must be given with two lines in the DXF file, and not a point entity.

OriginPoint = dxf_cross(file="drawing.dxf", layer="SCAD.Origin",
origin=[0, 0], scale=1);


Getting a dimension value

You can read dimensions from a technical drawing. This can be useful to read a rotation angle, an extrusion height, or spacing between parts. In the drawing, create a dimension that does not show the dimension value, but an identifier. To read the value, you specify this identifier from your script:

TotalWidth = dxf_dim(file="drawing.dxf", name="TotalWidth",
layer="SCAD.Origin", origin=[0, 0], scale=1);


For a nice example of both functions, see Example009 and the image on the homepage of OpenSCAD.

### For Loop

Iterate over the values in a vector or range.

Vector version: for (variable=<vector>) <do_something> - <variable> is assigned to each successive value in the vector
Range version: for (variable=<range>) <do_something>

Nested loops : for ( variable1 = <range or vector>, variable2 = <range or vector> ) <do something, using both variables>
for loops can be nested, just as in normal programs. A shorthand is that both iterations can be given in the same for statement

 Usage example 1 - iteration over a vector: for (z = [-1, 1]) // two iterations, z = -1, z = 1 { translate([0, 0, z]) cube(size = 1, center = false); }  OpenSCAD iteration over a vector
 Usage example 2a - iteration over a range: for ( i = [0 : 5] ) { rotate( i * 360 / 6, [1, 0, 0]) translate([0, 10, 0]) sphere(r = 1); }  OpenSCAD iteration over a range)
 Usage example 2b - iteration over a range specifying an increment: // Note: The middle parameter in the range designation // ('0.2' in this case) is the 'increment-by' value // Warning: Depending on the 'increment-by' value, the // real end value may be smaller than the given one. for ( i = [0 : 0.2 : 5] ) { rotate( i * 360 / 6, [1, 0, 0]) translate([0, 10, 0]) sphere(r = 1); } 
 Usage example 3 - iteration over a vector of vectors (rotation): for(i = [ [ 0, 0, 0], [ 10, 20, 300], [200, 40, 57], [ 20, 88, 57] ]) { rotate(i) cube([100, 20, 20], center = true); }  OpenSCAD for loop (rotation)
 Usage example 4 - iteration over a vector of vectors (translation):  for(i = [ [ 0, 0, 0], [10, 12, 10], [20, 24, 20], [30, 36, 30], [20, 48, 40], [10, 60, 50] ]) { translate(i) cube([50, 15, 10], center = true); }  OpenSCAD for loop (translation)

Nested loop example

  for (xpos=[0:3], ypos = [2,4,6]) // do twelve iterations, using each xpos with each ypos
translate([xpos*ypos, ypos, 0]) cube([0.5, 0.5, 0.5]);


### Intersection For Loop

Iterate over the values in a vector or range and take an intersection of the contents.

Note: intersection_for() is a work around because of an issue that you cannot get the expected results using a combination of the standard for() and intersection() statements. The reason is that for() do a implicit union() of the contents.

Parameters

<loop variable name>
Name of the variable to use within the for loop.
 Usage example 1 - loop over a range: intersection_for(n = [1 : 6]) { rotate([0, 0, n * 60]) { translate([5,0,0]) sphere(r=12); } }  OpenSCAD Intersection for
 Usage example 2 - rotation :  intersection_for(i = [ [ 0, 0, 0], [ 10, 20, 300], [200, 40, 57], [ 20, 88, 57] ]) { rotate(i) cube([100, 20, 20], center = true); }  OpenSCAD Intersection for (rotation)

### If Statement

Conditionally evaluate a sub-tree.

Parameters

• The boolean expression that should be used as condition

NOTE:

Do not confuse the assignment operator '=' with the equal operator '=='

 if (a=b) dosomething();  // WRONG - this will FAIL to be processed without any error message
if (a==b) dosomething(); // CORRECT - this will do something if a equals b


NOTE:

Assignment is not allowed within either branch of an if statement. Consider using the ternary operator 'condition ? consequent: alternative'.

// WRONG - this will FAIL to be processed with a syntax error message
if (condition)
{
x = consequent;
} else {
x = alternative;
}

// CORRECT - this will set 'x' to either 'consequent' or 'alternative'
x = condition ? consequent : alternative;


Usage example:

if (x > y)
{
cube(size = 1, center = false);
} else {
cube(size = 2, center = true);
}


### Assign Statement

Set variables to a new value for a sub-tree.

Parameters

• The variables that should be (re-)assigned

Usage example:

for (i = [10:50])
{
assign (angle = i*360/20, distance = i*10, r = i*2)
{
rotate(angle, [1, 0, 0])
translate([0, distance, 0])
sphere(r = r);
}
}


### Scalar Arithmetical Operators

The scalar arithmetical operators take numbers as operands and produce a new number.

 + add - subtract * multiply / divide % modulo

The "-" can also be used as prefix operator to negate a number.

### Relational Operators

All relational operator take numbers as operands and produce a Boolean value. The equal and not-equal operators can also compare Boolean values.

 < less than <= less equal == equal != not equal >= greater equal > greater than

### Logical Operators

All logical operators take Boolean values as operands and produce a Boolean value.

 && Logical AND || Logical OR ! Logical NOT

### Conditional Operator

The ?: operator can be used to conditionally evaluate one or another expression. It works like the ?: operator from the family of C-like programming languages.

 ? : Conditional operator
 Usage Example: a=1; b=2; c= a==b ? 4 : 5;  If a equals b, then c is set to 4, else c is set to 5. The part "a==b" must be something that evaluates to a boolean value.

### Vector-Number Operators

The vector-number operators take a vector and a number as operands and produce a new vector.

 * multiply all vector elements by number / divide all vector elements by number

### Vector Operators

The vector operators take vectors as operands and produce a new vector.

 + add element-wise - subtract element-wise

The "-" can also be used as prefix operator to element-wise negate a vector.

### Vector Dot-Product Operator

The vector dot-product operator takes two vectors as operands and produces a scalar.

 * sum of vector element products

### Matrix Multiplication

Multiplying a matrix by a vector, vector by matrix and matrix by matrix

 * matrix/vector multiplication

## Trigonometric Functions

The trig functions use the C Language mathematics functions, which are based in turn on Binary Floating Point mathematics, which use approximations of Real Numbers during calculation. OpenSCAD's math functions use the C++ 'double' type, inside Value.h/Value.cc,

A good resource for the specifics of the C library math functions, such as valid inputs/output ranges, can be found at the Open Group website math.h & acos

### cos

Mathematical cosine function of degrees. See Cosine

Parameters

<degrees>
Decimal. Angle in degrees.
 Usage Example:  for(i=[0:36]) translate([i*10,0,0]) cylinder(r=5,h=cos(i*10)*50+60);  OpenSCAD Cos Function‎

### sin

Mathematical sine function. See Sine

Parameters

<degrees>
Decimal. Angle in degrees.
 Usage example 1:  for (i = [0:5]) { echo(360*i/6, sin(360*i/6)*80, cos(360*i/6)*80); translate([sin(360*i/6)*80, cos(360*i/6)*80, 0 ]) cylinder(h = 200, r=10); } 

 Usage example 2:  for(i=[0:36]) translate([i*10,0,0]) cylinder(r=5,h=sin(i*10)*50+60);  OpenSCAD Sin Function

### tan

Mathematical tangent function. See Tangent

Parameters

<degrees>
Decimal. Angle in degrees.
 Usage example:  for (i = [0:5]) { echo(360*i/6, tan(360*i/6)*80); translate([tan(360*i/6)*80, 0, 0 ]) cylinder(h = 200, r=10); } 

### acos

Mathematical arccosine, or inverse cosine, expressed in degrees. See: Inverse trigonometric functions

### asin

Mathematical arcsine, or inverse sine, expressed in degrees. See: Inverse trigonometric functions

### atan

Mathematical arctangent, or inverse tangent, function. Returns the principal value of the arc tangent of x, expressed in degrees. See: Inverse trigonometric functions

### atan2

Mathematical two-argument atan function, taking y as its first argument. Returns the principal value of the arc tangent of y/x, expressed in degrees. See: atan2

## Other Mathematical Functions

### abs

Mathematical absolute value function. Returns the positive value of a signed decimal number.

Usage examples:

abs(-5.0);
abs(0);
abs(8.0);


Results:

5.0
0.0
8.0


### ceil

Mathematical ceiling function. ceil(x) is the smallest integer not less than x.

See: Ceil Function

echo(ceil(4.4),ceil(-4.4));     // produces ECHO: 5, -4


### cross

Calculates the cross product of two vectors in 3D space. The result is a vector that is perpendicular to both of the input vectors.

Using invalid input parameters (e.g. vectors with a length different from 3 or other types) will produce an undefined result.

Usage examples:

echo(cross([2, 3, 4], [5, 6, 7]));     // produces ECHO: [-3, 6, -3]
echo(cross([2, 1, -3], [0, 4, 5]));    // produces ECHO: [17, -10, 8]
echo(cross([2, 3, 4], "5"));           // produces ECHO: undef


### exp

Mathematical exp function. Returns the base-e exponential function of x, which is the number e raised to the power x. See: Exponent

### floor

Mathematical floor function. floor(x) = is the largest integer not greater than x

See: Floor Function

echo(floor(4.4),floor(-4.4));    // produces ECHO: 4, -5


### ln

Mathematical natural logarithm. See: Natural logarithm

### len

Mathematical length function. Returns the length of an array, a vector or a string parameter.

Usage examples:

str1="abcdef"; len_str1=len(str1);
echo(str1,len_str1);

a=6; len_a=len(a);
echo(a,len_a);

array1=[1,2,3,4,5,6,7,8]; len_array1=len(array1);
echo(array1,len_array1);

array2=[[0,0],[0,1],[1,0],[1,1]]; len_array2=len(array2);
echo(array2,len_array2);

len_array2_2=len(array2[2]);
echo(array2[2],len_array2_2);


Results:

ECHO: "abcdef", 6
ECHO: 6, undef
ECHO: [1, 2, 3, 4, 5, 6, 7, 8], 8
ECHO: [[0, 0], [0, 1], [1, 0], [1, 1]], 4
ECHO: [1, 0], 2


This function allows (e.g.) the parsing of an array, a vector or a string.

Usage examples:

str2="4711";
for (i=[0:len(str2)-1])
echo(str("digit ",i+1,"  :  ",str2[i]));


Results:

ECHO: "digit 1  :  4"
ECHO: "digit 2  :  7"
ECHO: "digit 3  :  1"
ECHO: "digit 4  :  1"


Note that the len() function is not defined when a simple variable is passed as the parameter.

This is useful when handling parameters to a module, similar to how shapes can be defined as a single number, or as an [x,y,z] vector; i.e. cube(5) or cube([5,5,5])

For example

module doIt(size) {
if (len(size) == undef) {
// size is a number, use it for x,y & z. (or could be undef)
do([size,size,size]);
} else {
// size is a vector, (could be a string but that would be stupid)
do(size);
}
}

doIt(5);        // equivalent to [5,5,5]
doIt([5,5,5]);  // similar to cube(5) v's cube([5,5,5])


### log

Mathematical logarithm. See: Logarithm

### lookup

Look up value in table, and linearly interpolate if there's no exact match. The first argument is the value to look up. The second is the lookup table -- a vector of key-value pairs.

Parameters

key
A lookup key
<key,value> array
keys and values

Notes
There is a bug where out-of-range keys will return the first value in the list. Newer versions of Openscad should use the top or bottom end of the table as appropriate instead.

 Usage example: Will create a sort of 3D chart made out of cylinders of different height.  function get_cylinder_h(p) = lookup(p, [ [ -200, 5 ], [ -50, 20 ], [ -20, 18 ], [ +80, 25 ], [ +150, 2 ] ]); for (i = [-100:5:+100]) { // echo(i, get_cylinder_h(i)); translate([ i, 0, -30 ]) cylinder(r1 = 6, r2 = 2, h = get_cylinder_h(i)*3); }  OpenSCAD Lookup Function

### max

Returns the maximum of the parameters. If a single vector is given as parameter, returns the maximum element of that vector.

Parameters

max(n,n{,n}...)
max(vector)

<n>
Two or more decimals
<vector>
Single vector of decimals (requires OpenSCAD version 2014.06 or later).

Usage Example:

max(3.0,5.0)
max(8.0,3.0,4.0,5.0)
max([8,3,4,5])


Results:

5
8
8


### min

Returns the minimum of the parameters. If a single vector is given as parameter, returns the minimum element of that vector.

Parameters

min(n,n{,n}...)
min(vector)

<n>
Two or more decimals
<vector>
Single vector of decimals (requires OpenSCAD version 2014.06 or later).

Usage Example:

min(3.0,5.0)
min(8.0,3.0,4.0,5.0)
min([8,3,4,5])


Results:

3
3
3


Looking for mod - it's not a function, see modulo operator (%)

### norm

Returns the euclidean norm of a vector. Note this returns is the actual numeric length while len returns the number of elements in the vector or array.

Usage examples:

a=[1,2,3,4];
b="abcd";
c=[];
d="";
e=[[1,2,3,4],[1,2,3],[1,2],[1]];
echo(norm(a)); //5.47723
echo(norm(b)); //undef
echo(norm(c)); //0
echo(norm(d)); //undef
echo(norm(e[0])); //5.47723
echo(norm(e[1])); //3.74166
echo(norm(e[2])); //2.23607
echo(norm(e[3])); //1


Results:

ECHO: 5.47723
ECHO: undef
ECHO: 0
ECHO: undef
ECHO: 5.47723
ECHO: 3.74166
ECHO: 2.23607
ECHO: 1


### pow

Mathematical power function.

Parameters

<base>
Decimal. Base.
<exponent>
Decimal. Exponent.

Usage examples:

for (i = [0:5]) {
translate([i*25,0,0]) {
cylinder(h = pow(2,i)*5, r=10);
echo (i, pow(2,i));
}
}

echo(pow(10,2)); // means 10^2 or 10*10
// result: ECHO: 100

echo(pow(10,3)); // means 10^3 or 10*10*10
// result: ECHO: 1000

echo(pow(125,1/3)); // means 125^(0.333...) which equals calculating the cube root of 125
// result: ECHO: 5


### rands

Random number generator. Generates a constant vector of pseudo random numbers, much like an array. The numbers are doubles not integers. When generating only one number, you still call it with variable[0]

Parameters

min_value
Minimum value of random number range
max_value
Maximum value of random number range
value_count
Number of random numbers to return as a vector
seed_value (optional)
Seed value for random number generator for repeatable results.

Usage Examples:

// get a single number
single_rand = rands(0,10,1)[0];
echo(single_rand);

// get a vector of 4 numbers
seed=42;
random_vect=rands(5,15,4,seed);
echo( "Random Vector: ",random_vect);
sphere(r=5);
for(i=[0:3]) {
rotate(360*i/4) {
translate([10+random_vect[i],0,0])
sphere(r=random_vect[i]/2);
}
}
// ECHO: "Random Vector: ", [8.7454, 12.9654, 14.5071, 6.83435]


### round

The "round" operator returns the greatest or least integer part, respectively, if the numeric input is positive or negative.

Some examples:

round(x.5) = x+1.round(x.49) = x.round(-(x.5)) = -(x+1).round(-(x.49)) = -x.round(5.4); //-> 5round(5.5); //-> 6round(5.6); //-> 6


### sign

Mathematical signum function. Returns a unit value that extracts the sign of a value see: Signum function

Parameters

<x>
Decimal. Value to find the sign of.

Usage examples:

sign(-5.0);
sign(0);
sign(8.0);


Results:

-1.0
0.0
1.0


### sqrt

Mathematical square root function.

Usage Examples:

translate([sqrt(100),0,0])sphere(100);


### str

Convert all arguments to strings and concatenate.

Usage examples:

number=2;
echo ("This is ",number,3," and that's it.");
echo (str("This is ",number,3," and that's it."));


Results:

ECHO: "This is ", 2, 3, " and that's it."
ECHO: "This is 23 and that's it."


### chr

[Note: Requires version 2014.QX(see [2])]

Convert numbers to a string containing character with the corresponding code. OpenSCAD uses Unicode, so the number is interpreted as Unicode code point. Numbers outside the valid code point range will produce an empty string.

Parameters

chr(Number)
Convert one code point to a string of length 1 (number of bytes depending on UTF-8 encoding) if the code point is valid.
chr(Vector)
Convert all code points given in the argument vector to a string.
chr(Range)
Convert all code points produced by the range argument to a string.

Examples

echo(chr(65), chr(97));      // ECHO: "A", "a"
echo(chr(65, 97));           // ECHO: "Aa"
echo(chr([66, 98]));         // ECHO: "Bb"
echo(chr([97 : 2 : 102]));   // ECHO: "ace"
echo(chr(-3));               // ECHO: ""
echo(chr(9786), chr(9788));  // ECHO: "☺", "☼"
echo(len(chr(9788)));        // ECHO: 1


Note: When used with echo() the output to the console for character codes greater than 127 is platform dependent.

### Also See search()

search() for text searching.

### cube

Creates a cube at the origin of the coordinate system. When center is true the cube will be centered on the origin, otherwise it is created in the first octant. The argument names are optional if the arguments are given in the same order as specified in the parameters

Parameters

size
Decimal or 3 value array. If a single number is given, the result will be a cube with sides of that length. If a 3 value array is given, then the values will correspond to the lengths of the X, Y, and Z sides. Default value is 1.
center
Boolean. This determines the positioning of the object. If true, object is centered at (0,0,0). Otherwise, the cube is placed in the positive quadrant with one corner at (0,0,0). Defaults to false

Usage examples:

cube(size = 1, center = false);
cube(size = [1,2,3], center = true);


### sphere

Creates a sphere at the origin of the coordinate system. The argument name is optional.

Parameters

Radius. This is the radius of the sphere. The resolution of the sphere will be based on the size of the sphere and the $fa,$fs and $fn variables. For more information on these special variables look at: OpenSCAD_User_Manual/Other_Language_Features Diameter. This is the diameter of the sphere. (NOTE: d is only available in versions later than 2014.03. Debian is currently know to be behind this)$fa
Fragment angle in degrees
$fs Fragment size in mm$fn
Resolution

Usage Examples

sphere(r = 1);
sphere(r = 5);
sphere(r = 10);
sphere(d = 2);
sphere(d = 10);
sphere(d = 20);

// this will create a high resolution sphere with a 2mm radius
sphere(2, $fn=100);  // will also create a 2mm high resolution sphere but this one // does not have as many small triangles on the poles of the sphere sphere(2,$fa=5, $fs=0.1);  ### cylinder Creates a cylinder or cone at the origin of the coordinate system. A single radius (r) makes a cylinder, two different radi (r1, r2) make a cone. Parameters Decimal. This is the height of the cylinder. Default value is 1. Decimal. The radius of both top and bottom ends of the cylinder. Use this parameter if you want plain cylinder. Default value is 1. r1 Decimal. This is the radius of the cone on bottom end. Default value is 1. r2 Decimal. This is the radius of the cone on top end. Default value is 1. Decimal. The diameter of both top and bottom ends of the cylinder. Use this parameter if you want plain cylinder. Default value is 1. d1 Decimal. This is the diameter of the cone on bottom end. Default value is 1. d2 Decimal. This is the diameter of the cone on top end. Default value is 1. center boolean. If true will center the height of the cone/cylinder around the origin. Default is false, placing the base of the cylinder or r1 radius of cone at the origin.$fa
The angle (in degrees) from one fragment to the next. See OpenSCAD_User_Manual/Other_Language_Features.
$fs The circumferential length of each fragment. See OpenSCAD_User_Manual/Other_Language_Features.$fn
The fixed number of fragments to use. See OpenSCAD_User_Manual/Other_Language_Features.

(NOTE: d,d1,d2 are only available in version later than 2014.03. Debian is currently know to be behind this)

Usage Examples

cylinder(h = 10, r=20);
cylinder(h = 10, r=20, $fs=6); cylinder(h = 10, r1 = 10, r2 = 20, center = false); cylinder(h = 10, r1 = 20, r2 = 10, center = true); cylinder(h = 10, d=40); cylinder(h = 10, d=40,$fs=6);
cylinder(h = 10, d1 = 20, d2 = 40, center = false);
cylinder(h = 10, d1 = 40, d2 = 20, center = true);


### polyhedron

Create a polyhedron with a list of points and a list of faces. The point list is all the vertices of the shape, the faces list is how the points relates to the surfaces of the polyhedron.

note: if your version of OpenSCAD is lower than 2014.03 replace "faces" with "triangles" in the below examples

Parameters

points
vector of points or vertices (each a 3 vector).
triangles
(deprecated in version 2014.03, use faces) vector of point triplets (each a 3 number vector). Each number is the 0-indexed point number from the point vector.
faces
(introduced in version 2014.03) vector of point n-tuples with n >= 3. Each number is the 0-indexed point number from the point vector. That is, faces=0,1,4 specifies a triangle made from the first, second, and fifth point listed in points. When referencing more than 3 points in a single tuple, the points must all be on the same plane.
convexity
Integer. The convexity parameter specifies the maximum number of front sides (back sides) a ray intersecting the object might penetrate. This parameter is only needed for correctly displaying the object in OpenCSG preview mode and has no effect on the polyhedron rendering.

Syntax example

 polyhedron(points = [ [x, y, z], ... ], faces = [ [p1, p2, p3..], ... ], convexity = N);


Point ordering for faces When looking at the face from the outside inwards, the points must be clockwise. You can rearrange the order of the points or the order they are referenced in each tuple. The order of faces is immaterial. Note that if your polygons are not all oriented the same way OpenSCAD will either print an error or crash completely, so pay attention to the vertex ordering. Again, remember that the 'pN' components of the faces vector are 0-indexed references to the elements of the points vector.

Example, a square base pyramid:

polyhedron(
points=[ [10,10,0],[10,-10,0],[-10,-10,0],[-10,10,0], // the four points at base
[0,0,10]  ],                                 // the apex point
faces=[ [0,1,4],[1,2,4],[2,3,4],[3,0,4],              // each triangle side
[1,0,3],[2,1,3] ]                         // two triangles for square base
);

A simple polyhedron, square based pyramid

An example of a more complex polyhedron, and showing how to fix polyhedrons with badly oriented polygons.

When you select 'Thrown together' from the view menu and compile the design (not compile and render!) you will see a preview with the mis-oriented polygons highlighted. Unfortunately this highlighting is not possible in the OpenCSG preview mode because it would interfere with the way the OpenCSG preview mode is implemented.)

Below you can see the code and the picture of such a problematic polyhedron, the bad polygons (faces or compositions of faces) are in pink.

// Bad polyhedron
polyhedron
(points = [
[0, -10, 60], [0, 10, 60], [0, 10, 0], [0, -10, 0], [60, -10, 60], [60, 10, 60],
[10, -10, 50], [10, 10, 50], [10, 10, 30], [10, -10, 30], [30, -10, 50], [30, 10, 50]
],
faces = [
[0,2,3],   [0,1,2],  [0,4,5],  [0,5,1],   [5,4,2],  [2,4,3],
[6,8,9],  [6,7,8],  [6,10,11], [6,11,7], [10,8,11],
[10,9,8], [0,3,9],  [9,0,6], [10,6, 0],  [0,4,10],
[3,9,10], [3,10,4], [1,7,11],  [1,11,5], [1,7,8],
[1,8,2],  [2,8,11], [2,11,5]
]
);

Polyhedron with badly oriented polygons

A correct polyhedron would be the following:

polyhedron
(points = [
[0, -10, 60], [0, 10, 60], [0, 10, 0], [0, -10, 0], [60, -10, 60], [60, 10, 60],
[10, -10, 50], [10, 10, 50], [10, 10, 30], [10, -10, 30], [30, -10, 50], [30, 10, 50]
],
faces = [
[0,3,2],  [0,2,1],  [4,0,5],  [5,0,1],  [5,2,4],  [4,2,3],
[6,8,9],  [6,7,8],  [6,10,11],[6,11,7], [10,8,11],
[10,9,8], [3,0,9],  [9,0,6],  [10,6, 0],[0,4,10],
[3,9,10], [3,10,4], [1,7,11], [1,11,5], [1,8,7],
[2,8,1],  [8,2,11], [5,11,2]
]
);


Beginner's tip:

If you don't really understand "orientation", try to identify the mis-oriented pink faces and then permute the references to the points vectors until you get it right. E.g. in the above example, the third triangle ([0,4,5]) was wrong and we fixed it as [4,0,5]. In addition, you may select "Show Edges" from the "View Menu", print a screen capture and number both the points and the faces. In our example, the points are annotated in black and the faces in blue. Turn the object around and make a second copy from the back if needed. This way you can keep track.

Clockwise Technique:

Orientation is determined by clockwise indexing. This means that if you're looking at the triangle (in this case [4,0,5]) from the outside you'll see that the path is clockwise around the center of the face. The winding order [4,0,5] is clockwise and therefore good. The winding order [0,4,5] is counter-clockwise and therefore bad. Likewise, any other clockwise order of [4,0,5] works: [5,4,0] & [0,5,4] are good too. If you use the clockwise technique, you'll always have your faces outside (outside of OpenSCAD, other programs do use counter-clockwise as the outside though).

Think of it as a Left Hand Rule:

If you hold the face and the fingers of your hand curls is the same order as the points, then your thumb points outwards.

Polyhedron with badly oriented polygons

Succinct description of a 'Polyhedron'

* Points define all of the points/vertices in the shape.
* Faces is a list of flat polygons that connect up the points/vertices.


Each point, in the point list, is defined with a 3-tuple x,y,z position specification. Points in the point list are automatically given an identifier starting at zero for use in the faces list (0,1,2,3,... etc).

Each face, in the faces list, is defined by selecting 3 or more of the points (using the point identifier) out of the point list.

e.g. faces=[ [0,1,2] ] defines a triangle from the first point (points are zero referenced) to the second point and then to the third point.

When looking at any face from the outside, the face must list all points in a clockwise order.

Transformation affect the child nodes and as the name implies transforms them in various ways such as moving/rotating or scaling the child. Cascading transformations are used to apply a variety of transforms to a final child. Cascading is achieved by nesting statements i.e.

 transform()             e.g.  rotate([45,45,45])
transform()                   translate([10,20,30])
child()                       cube(10);


Note: child(...) is deprecated by children(...) in master. (2013.06 still uses child(...)).

Transformations can be applied to a group of child nodes by using '{' & '}' to enclose the subtree e.g.

 translate([0,0,-5])    or the more compact      translate([0,0,-5]) {
{                                                 cube(10);
cube(10);                                       cylinder(r=5,h=10);
cylinder(r=5,h=10);                           }
}


As OpenSCAD uses different libraries to implement capabilities this can introduce some inconsistencies to the F5 preview behaviour of transformations. Traditional transforms (translate, rotate, scale, mirror & multimatrix) are performed using OpenGL in preview, while other more advanced transforms, such as resize, perform a CGAL operation, behaving like a CSG operation affecting the underlying object, not just transforming it. In particular this can affect the display of modifier characters, specifically "#" and "%", where the highlight may not display intuitively, such as highlighting the pre-resized object, but highlighting the post-scaled object.

### scale

Scales its child elements using the specified vector. The argument name is optional.

Usage Example:
scale(v = [x, y, z]) { ... }

cube(10);
translate([15,0,0]) scale([0.5,1,2]) cube(10);


### resize

resize() is available since OpenSCAD 2013.06. It modifies the size of the child object to match the given x,y, and z.

There is a bug with shrinking in the 2013.06 release, that will be fixed in the next release.

Usage Example:

// resize the sphere to extend 30 in x, 60 in y, and 10 in the z directions.
resize(newsize=[30,60,10]) sphere(r=10);


If x,y, or z is 0 then that dimension is left as-is.

// resize the 1x1x1 cube to 2x2x1
resize([2,2,0]) cube();


If the 'auto' parameter is set to true, it will auto-scale any 0-dimensions to match. For example.

// resize the 1x2x0.5 cube to 7x14x3.5
resize([7,0,0], auto=true) cube([1,2,0.5]);


The 'auto' parameter can also be used if you only wish to auto-scale a single dimension, and leave the other as-is.

// resize to 10x8x1. Note that the z dimension is left alone.
resize([10,0,0], auto=[true,true,false]) cube([5,4,1]);


### rotate

Rotates its child 'a' degrees about the origin of the coordinate system or around an arbitrary axis. The argument names are optional if the arguments are given in the same order as specified.

Usage:
rotate(a = deg_a, v = [x, y, z]) { ... }
// or
rotate(deg_a, [x, y, z]) { ... }
rotate(a = [deg_x, deg_y, deg_z]) { ... }
rotate([deg_x, deg_y, deg_z]) { ... }


The 'a' argument (deg_a) can be an array, as expressed in the later usage above; when deg_a is an array, the 'v' argument is ignored. Where 'a' specifies multiple axes then the rotation is applied in the following order: x, y, z.

The optional argument 'v' is a vector and allows you to set an arbitrary axis about which the object will be rotated.

For example, to flip an object upside-down, you can rotate your object 180 degrees around the 'y' axis.

rotate(a=[0,180,0]) { ... }


This is frequently simplified to

rotate([0,180,0]) { ... }


When specifying a single axis the 'v' argument allows you to specify which axis is the basis for rotation. For example, the equivalent to the above, to rotate just around y

rotate(a=180, v=[0,1,0]) { ... }


When specifying mutiple axis, 'v'is a vector defining an arbitrary axis for rotation; this is different from the multiple axis above. For example, rotate your object 45 degrees around the axis defined by the vector [1,1,0],

rotate(a=45, v=[1,1,0]) { ... }


Rotate with a single scalar argument rotates around the Z axis. This is useful in 2D contexts where that is the only axis for rotation. For example:

rotate(45) square(10);


##### If this is all a bit confusing, this might, or might not, help.
Right-hand grip rule

For the case of:

rotate([a, b, c]) { ... };


"a" is a rotation about the X axis, from the +Z axis, toward the -Y axis. NOTE: NEGATIVE Y.
"b" is a rotation about the Y axis, from the +Z axis, toward the +X axis.
"c" is a rotation about the Z axis, from the +X axis, toward the +Y axis.

These are all cases of the Right Hand Rule. Point your right thumb along the positive axis, your fingers show the direction of rotation.

Thus if "a" is fixed to zero, and "b" and "c" are manipulated appropriately, this is the spherical coordinate system.
So, to construct a cylinder from the origin to some other point (x,y,z):

%cube(10);
x= 10; y = 10; z = 10; // point coordinates of corner of cube
//
length = sqrt( pow(x, 2) + pow(y, 2) + pow(z, 2) );
b = acos(z/length);
c = (x==0) ? 90 : ( (x>0) ? atan(y/x) : atan(y/x)+180 );
//
rotate([0, b, c])
cylinder(h=length, r=0.5);


### translate

Translates (moves) its child elements along the specified vector. The argument name is optional.

IExample

translate(v = [x, y, z]) { ... }

cube(2,center = true);
translate([5,0,0])
sphere(1,center = true);


### mirror

Mirrors the child element on a plane through the origin. The argument to mirror() is the normal vector of a plane intersecting the origin through which to mirror the object.

#### Function signature:

mirror( [x, y, z] ) { ... }


#### Examples

rotate([0,0,10]) cube([3,2,1]);
mirror([1,0,0]) translate([1,0,0]) rotate([0,0,10]) cube([3,2,1]);


### multmatrix

Multiplies the geometry of all child elements with the given 4x4 transformation matrix.

Usage: multmatrix(m = [...]) { ... }

Example (translates by [10, 20, 30]):

multmatrix(m = [ [1, 0, 0, 10],
[0, 1, 0, 20],
[0, 0, 1, 30],
[0, 0, 0,  1]
]) cylinder();


Example (rotates by 45 degrees in XY plane and translates by [10,20,30]):

angle=45;
multmatrix(m = [ [cos(angle), -sin(angle), 0, 10],
[sin(angle), cos(angle), 0, 20],
[0, 0, 1, 30],
[0, 0, 0,  1]
]) union() {
cylinder(r=10.0,h=10,center=false);
cube(size=[10,10,10],center=false);
}


### color

Displays the child elements using the specified RGB color + alpha value. This is only used for the F5 preview as CGAL and STL (F6) do not currently support color. The alpha value will default to 1.0 (opaque) if not specified.

#### Function signature:

color( [r, g, b, a] ) { ... }
color( [r, g, b], a=1.0 ) { ... } // since v. 2011.12 (?)
color( colorname, a=1.0 ) { ... } // since v. 2011.12 ( fails in 2014.03; use color( colorname, #) were # is the alpha )


Note that the r, g, b, a values are limited to floating point values in the range [0,1] rather than the more traditional integers { 0 ... 255 }. However, nothing prevents you to using R, G, B values from {0 ... 255} with appropriate scaling: color([ R/255, G/255, B/255 ]) { ... }

Since version 2011.12, colors can also be defined by name (case insensitive). For example, to create a red sphere, you can write color("red") sphere(5);. Alpha is specified as an extra parameter for named colors: color("Blue",0.5) cube(5);

The available color names are taken from the World Wide Web consortium's SVG color list. A chart of the color names is as follows,
(note that both spellings of grey/gray including slategrey/slategray etc are valid):

 Purples Lavender Thistle Plum Violet Orchid Fuchsia Magenta MediumOrchid MediumPurple BlueViolet DarkViolet DarkOrchid DarkMagenta Purple Indigo DarkSlateBlue SlateBlue MediumSlateBlue Pinks Pink LightPink HotPink DeepPink MediumVioletRed PaleVioletRed
 Blues Aqua Cyan LightCyan PaleTurquoise Aquamarine Turquoise MediumTurquoise DarkTurquoise CadetBlue SteelBlue LightSteelBlue PowderBlue LightBlue SkyBlue LightSkyBlue DeepSkyBlue DodgerBlue CornflowerBlue RoyalBlue Blue MediumBlue DarkBlue Navy MidnightBlue Reds IndianRed LightCoral Salmon DarkSalmon LightSalmon Red Crimson FireBrick DarkRed
 Greens GreenYellow Chartreuse LawnGreen Lime LimeGreen PaleGreen LightGreen MediumSpringGreen SpringGreen MediumSeaGreen SeaGreen ForestGreen Green DarkGreen YellowGreen OliveDrab Olive DarkOliveGreen MediumAquamarine DarkSeaGreen LightSeaGreen DarkCyan Teal Oranges LightSalmon Coral Tomato OrangeRed DarkOrange Orange
 Yellows Gold Yellow LightYellow LemonChiffon LightGoldenrodYellow PapayaWhip Moccasin PeachPuff PaleGoldenrod Khaki DarkKhaki Browns Cornsilk BlanchedAlmond Bisque NavajoWhite Wheat BurlyWood Tan RosyBrown SandyBrown Goldenrod DarkGoldenrod Peru Chocolate SaddleBrown Sienna Brown Maroon
 Whites White Snow Honeydew MintCream Azure AliceBlue GhostWhite WhiteSmoke Seashell Beige OldLace FloralWhite Ivory AntiqueWhite Linen LavenderBlush MistyRose Grays Gainsboro LightGrey Silver DarkGray Gray DimGray LightSlateGray SlateGray DarkSlateGray Black

#### Example

A 3-D multicolor sine wave

Here's a code fragment that draws a wavy multicolor object

 for(i=[0:36]) {
for(j=[0:36]) {
color( [0.5+sin(10*i)/2, 0.5+sin(10*j)/2, 0.5+sin(10*(i+j))/2] )
translate( [i, j, 0] )
cube( size = [1, 1, 11+10*cos(10*i)*sin(10*j)] );
}
}


Being that -1<=sin(x)<=1 then 0<=(1/2 + sin(x)/2)<=1 , allowing for the RGB components assigned to color to remain within the [0,1] interval.

Chart based on "Web Colors" from Wikipedia

### minkowski

A box and a cylinder
Minkowski sum of the box and cylinder

Displays the minkowski sum of child nodes.

Usage example:

Say you have a flat box, and you want a rounded edge. There are many ways to do this, but minkowski is very elegant. Take your box, and a cylinder:

$fn=50; cube([10,10,1]); cylinder(r=2,h=1);  Then, do a minkowski sum of them: $fn=50;
minkowski()
{
cube([10,10,1]);
cylinder(r=2,h=1);
}


### hull

Two cylinders
Convex hull of two cylinders

Displays the convex hull of child nodes.

Usage example:

hull() {
translate([15,10,0]) circle(10);
circle(10);
}


### union

Creates a union of all its child nodes. This is the sum of all children.

Usage example:
union() {
cylinder (h = 4, r=1, center = true, $fn=100); rotate ([90,0,0]) cylinder (h = 4, r=0.9, center = true,$fn=100);
}


Remark: union is implicit when not used. But it is mandatory, for example, in difference to group first child nodes into one.

### difference

Subtracts the 2nd (and all further) child nodes from the first one.

Usage example:
difference() {
cylinder (h = 4, r=1, center = true, $fn=100); rotate ([90,0,0]) cylinder (h = 4, r=0.9, center = true,$fn=100);
}


### intersection

Creates the intersection of all child nodes. This keeps the overlapping portion

Usage example:
intersection() {
cylinder (h = 4, r=1, center = true, $fn=100); rotate ([90,0,0]) cylinder (h = 4, r=0.9, center = true,$fn=100);
}


### render

Always calculate the CSG model for this tree (even in OpenCSG preview mode).

Usage example:
render(convexity = 1) { ... }


 convexity Integer. The convexity parameter specifies the maximum number of front sides (back sides) a ray intersecting the object might penetrate. This parameter is only needed for correctly displaying the object in OpenCSG preview mode and has no effect on the polyhedron rendering.

This image shows a 2D shape with a convexity of 4, as the ray indicated in red crosses the 2D shape a maximum of 4 times. The convexity of a 3D shape would be determined in a similar way. Setting it to 10 should work fine for most cases.

Modifier characters are used to change the appearance or behaviours of child nodes. They are particularly useful in debugging where they can be used to highlight specific objects, or include or exclude them from rendering.

As OpenSCAD uses different libraries to implement capabilities this can introduce some inconsistencies to the F5 preview behaviour of transformations. Traditional transforms (translate, rotate, scale, mirror & multimatrix) are performed using OpenGL in preview, while other more advanced transforms, such as resize, perform a CGAL operation, behaving like a CSG operation affecting the underlying object, not just transforming it. In particular this can affect the display of modifier characters, specifically "#" and "%", where the highlight may not display intuitively, such as highlighting the pre-resized object, but highlighting the post-scaled object.

Note: The color changes triggered by character modifiers will only be shown in "Compile" mode not "Compile and Render (CGAL)" mode. (As per the color section.)

### Background Modifier

Ignore this subtree for the normal rendering process and draw it in transparent gray (all transformations are still applied to the nodes in this tree).

Because the marked subtree is completely ignored, it might have unexpected effects in case it's used for example with the first object in a difference(). In that case this object will be rendered in transparent gray, but it will not be the base for the difference()!

Usage

 % { ... }


Example

difference() {
cylinder (h = 12, r=5, center = true, $fn=100); // first object that will subtracted rotate ([90,0,0]) cylinder (h = 15, r=1, center = true,$fn=100);
// second object that will be subtracted
%rotate ([0,90,0]) cylinder (h = 15, r=3, center = true, $fn=100); }  Example Output Output without the modifer. Output with modifier added. Rendered Model. ### Debug Modifier Use this subtree as usual in the rendering process but also draw it unmodified in transparent pink. Usage  # { ... }  Example difference() { // start objects cylinder (h = 12, r=5, center = true,$fn=100);
// first object that will subtracted
#rotate ([90,0,0]) cylinder (h = 15, r=1, center = true, $fn=100); // second object that will be subtracted #rotate ([0,90,0]) cylinder (h = 15, r=3, center = true,$fn=100);
}


Example Output

Output without the modifer.
Output with modifier added.

### Root Modifier

Ignore the rest of the design and use this subtree as design root.

Usage

 ! { ... }


Example

difference() {
cube(10, center = true);
translate([0, 0, 5]) {
!rotate([90, 0, 0]) {
#cylinder(r = 2, h = 20, center = true, $fn = 40); } } }  Example Output Output without the modifer. Output with modifier added. As shown in the example output with the root modifier active, the rotate() is executed as it's part of the subtree marked with the root modifier, but the translate() has no effect. ### Disable Modifier Simply ignore this entire subtree. Usage  * { ... }  Example difference() { cube(10, center = true); translate([0, 0, 5]) { rotate([0, 90, 0]) { cylinder(r = 2, h = 20, center = true,$fn = 40);
}
*rotate([90, 0, 0]) {
#cylinder(r = 2, h = 20, center = true, $fn = 40); } } }  Example Output Output without the modifer. Output with modifier added. The disable modifier allows to comment out one or multiple subtrees. Compared to using the usual line or multi-line comments, it's aware of the hierarchical structure which makes it easier to disable even larger trees without the need to search for the end of the subtree. ### usage Defining your own module (roughly comparable to a macro or a function in other languages) is a powerful way to reuse procedures.  module hole(distance, rot, size) { rotate(a = rot, v = [1, 0, 0]) { translate([0, distance, 0]) { cylinder(r = size, h = 100, center = true); } } }  In this example, passing in the parameters distance, rot, and size allow you to reuse this functionality multiple times, saving many lines of code and rendering your program much easier to read. You can instantiate the module by passing values (or formulas) for the parameters just like a C function call:  hole(0, 90, 10);  ### children The child nodes of the module instantiation can be accessed using the children() statement within the module. The number of module children can be accessed using the$children variable.

Parameters

empty
select all the children
index
integer. select one child, at index value. Index start at 0 and should be less than $children-1. vector vector of integer. select children with index in vector. Index should be between 0 and$children-1.
range
[<start>:<end>] or [<start>:<increment>:<end>]. select children between <start> to <end>, incremented by <increment> (default 1).

Deprecated child() module

Up to release 2013.06 the now deprecated child() module was used instead. This can be translated to the new children() according to the table:

up to 2013.06 2014.03 and later
child() children(0)
child(x) children(x)
for (a = [0:$children-1]) child(a) children([0:$children-1])

Examples

Transfer all children to another module:

 // rotate to other center point:
module rz(angle, center=undef) {
translate(center)
rotate(angle)
translate(-center)
children();
}

rz(15, [10,0]) sphere(30);


Use the first child, multiple time:

 module lineup(num, space) {
for (i = [0 : num-1])
translate([ space*i, 0, 0 ]) children(0);
}

lineup(5, 65) sphere(30);


If you need to make your module iterate over all children you will need to make use of the $children variable, e.g.:  module elongate() { for (i = [0 :$children-1])
scale([10 , 1, 1 ]) children(i);
}

elongate() { sphere(30); cube([10,10,10]); cylinder(r=10,h=50); }


### arguments

One can specify default values for the arguments:

 module house(roof="flat",paint=[1,0,0]){
color(paint)
if(roof=="flat"){
translate([0,-1,0])
cube();
} else if(roof=="pitched"){
rotate([90,0,0])
linear_extrude(height=1)
polygon(points=[[0,0],[0,1],[0.5,1.5],[1,1],[1,0]],paths=[ [0,1,2,3,4] ]);
} else if(roof=="domical"){
translate([0,-1,0])
union(){
translate([0.5,0.5,1]) sphere(r=0.5,$fn=20); cube(); } } }  And then use one of the following ways to supply the arguments  union(){ house(); translate([2,0,0]) house("pitched"); translate([4,0,0]) house("domical",[0,1,0]); translate([6,0,0]) house(roof="pitched",paint=[0,0,1]); translate([8,0,0]) house(paint=[0,0,0],roof="pitched"); translate([10,0,0]) house(roof="domical"); translate([12,0,0]) house(paint=[0,0.5,0.5]); }  For including code from external files in OpenSCAD, there are two commands available: • include <filename> acts as if the contents of the included file were written in the including file, and • use <filename> imports modules and functions, but does not execute any commands other than those definitions. Library files are searched for in the same folder as the design was open from, or in the library folder of the OpenSCAD installation. You can use a relative path specification to either. If they lie elsewhere you must give the complete path. Newer versions have predefined user libraries, see the OpenSCAD_User_Manual/Libraries page, which also documents a number of library files included in OpenSCAD. Windows and Linux/Mac use different separators for directories. Windows uses \, e.g. directory\file.ext, while the others use /, e.g. directory/file.ext. This could lead to cross platform issues. However OpenSCAD on Windows correctly handles the use of /, so using / in all include or use statements will work on all platforms. Using include <filename> allows default variables to be specified in the library. These defaults can be overridden in the main code. An openscad variable only has one value during the life of the program. When there are multiple assignments it takes the last value, but assigns when the variable is first created. This has an effect when assigning in a library, as any variables which you later use to change the default, must be assigned before the include statement. See the second example below. A library file for generating rings might look like this (defining a function and providing an example): ring.scad: module ring(r1, r2, h) { difference() { cylinder(r = r1, h = h); translate([ 0, 0, -1 ]) cylinder(r = r2, h = h+2); } } ring(5, 4, 10);  Including the library using include <ring.scad>; rotate([90, 0, 0]) ring(10, 1, 1);  would result in the example ring being shown in addition to the rotated ring, but use <ring.scad>; rotate([90, 0, 0]) ring(10, 1, 1);  only shows the rotated ring. If using the use function, make sure to place the use statements at top of the file, or at least not within a module! This will work fine:  // a.scad use <ring.scad>; module a() { ring(); }  but this will result in an syntax error:  //a.scad module a() { use <ring.scad>; ring(); }  Default variables in an include can be overridden, for example lib.scad i=1; k=3; module x() { echo("hello world"); echo("i=",i,"j=",j,"k=",k); }  hello.scad j=4; include <lib.scad>; x(); i=5; x(); k=j; x();  Produces the following ECHO: "hello world" ECHO: "i=", 5, "j=", 4, "k=", 4 ECHO: "hello world" ECHO: "i=", 5, "j=", 4, "k=", 4 ECHO: "hello world" ECHO: "i=", 5, "j=", 4, "k=", 4  However, placing j=4; after the include fails, producing ECHO: "hello world" ECHO: "i=", 5, "j=", 4, "k=", undef ECHO: "hello world" ECHO: "i=", 5, "j=", 4, "k=", undef ECHO: "hello world" ECHO: "i=", 5, "j=", 4, "k=", undef  ### Special variables All variables starting with a '$' are special variables. The semantic is similar to the special variables in lisp: they have dynamic instead of lexical scoping.

What that means is that they're effectively automatically passed onward as arguments. Comparing a normal with a special variable:

     normal=2;
module doesnt_pass_it()
{   echo(normal); }
module normal_mod()
{   doesnt_pass_it(); }
normal_mod(normal=1); //Should echo 2

$special=3;$another=5;
module passes_it()
{   echo($special,$another); }
module special_mod()
{   $another=6; passes_it(); } special_mod($special=4); //Should echo 4,6


So basically it is useful when you do not want to pass many parameters all the time.

#### $fa,$fs and $fn The$fa, $fs and$fn special variables control the number of facets used to generate an arc:

$fa is the minimum angle for a fragment. Even a huge circle does not have more fragments than 360 divided by this number. The default value is 12 (i.e. 30 fragments for a full circle). The minimum allowed value is 0.01. Any attempt to set a lower value will cause a warning.$fs is the minimum size of a fragment. Because of this variable very small circles have a smaller number of fragments than specified using $fa. The default value is 2. The minimum allowed value is 0.01. Any attempt to set a lower value will cause a warning.$fn is usually 0. When this variable has a value greater than zero, the other two variables are ignored and full circle is rendered using this number of fragments. The default value is 0.

When $fa and$fs are used to determine the number of fragments for a circle, then OpenSCAD will never use less than 5 fragments.

This is the C code that calculates the number of fragments in a circle:

      int get_fragments_from_r(double r, double fn, double fs, double fa)
{
if (r < GRID_FINE) return 3;
if (fn > 0.0) return (int)(fn >= 3 ? fn : 3);
return (int)ceil(fmax(fmin(360.0 / fa, r*2*M_PI / fs), 5));
}


Spheres are first sliced into as many slices as the number of fragments being used to render a circle of the sphere's radius, and then every slice is rendered into as many fragments as are needed for the slice radius. You might have recognized already that the pole of a sphere is usually a pentagon. This is why.

The number of fragments for a cylinder is determined using the greater of the two radii.

The method is also used when rendering circles and arcs from DXF files.

You can generate high resolution spheres by resetting the $fX values in the instantiating module: $fs = 0.01;
sphere(2);


or simply by passing the special variable as parameter:

      sphere(2, $fs = 0.01);  You can even scale the special variable instead of resetting it:  sphere(2,$fs = $fs * 0.01);  ####$t

The $t variable is used for animation. If you enable the animation frame with view->animate and give a value for "FPS" and "Steps", the "Time" field shows the current value of$t. With this information in mind, you can animate your design. The design is recompiled every 1/"FPS" seconds with $t incremented by 1/"Steps" for "Steps" times, ending at either$t=1 or $t=1-1/steps. If "Dump Pictures" is checked, then images will be created in the same directory as the .scad file, using the following$t values, and saved in the following files:

• $t=0/Steps filename="frame00001.png" •$t=1/Steps filename="frame00002.png
• $t=2/Steps filename="frame00003.png" • . . . •$t=1-3/Steps filename="frame<Steps-2>.png"
• $t=1-2/Steps filename="frame<Steps-1>.png" •$t=1-1/Steps filename="frame00000.png"

Or, for other values of Steps, it follows this pattern:

• $t=0/Steps filename="frame00001.png" •$t=1/Steps filename="frame00002.png
• $t=2/Steps filename="frame00003.png" • . . . •$t=1-3/Steps filename="frame<Steps-2>.png"
• $t=1-2/Steps filename="frame<Steps-1>.png" •$t=1-1/Steps filename="frame<Steps-0>.png"
• $t=1-0/Steps filename="frame00000.png" Which pattern it chooses appears to be an unpredictable, but consistent, function of Steps. For example, when Steps=4, it follows the first pattern, and outputs a total of 4 files. When Steps=3, it follows the second pattern, and also outputs 4 files. It will always output either Steps or Steps+1 files, though it may not be predictable which. When finished, it will wrap around and recreate each of the files, looping through and recreating them forever. ####$vpr, $vpt and$vpd

These contain the current viewport rotation and translation and camera distance - at the time of doing the rendering. Moving the viewport does not update them. During an animation they are updated for each frame.

• $vpr shows rotation •$vpt shows translation (i.e. won't be affected by rotate and zoom)
• $vpd shows the camera distance [Note: Requires version 2014.QX(see [3])] Example  cube([10, 10,$vpr[0] / 10]);


$parent_module contains the number of modules in the instantiation stack. parent_module(i) returns the name of the module i levels about the current module in the instantiation stack. The stack is independent on where the modules are defined. It's where they're instantiated that counts. This can be used to e.g. build BOMs. Example:  module top() { children(); } module middle() { children(); } top() middle() echo(parent_module(0)); // prints "middle" top() middle() echo(parent_module(1)); // prints "top"  # Using the 2D Subsystem All 2D primitives can be transformed with 3D transformations. Usually used as part of a 3D extrusion. Although infinitely thin, they are rendered with a 1 thickness. ### square Creates a square at the origin of the coordinate system. When center is true the square will be centered on the origin, otherwise it is created in the first quadrant. The argument names are optional if the arguments are given in the same order as specified in the parameters Parameters size Decimal or 2 value array. If a single number is given, the result will be a square with sides of that length. If a 2 value array is given, then the values will correspond to the lengths of the X and Y sides. Default value is 1. center Boolean. This determines the positioning of the object. If true, object is centered at (0,0). Otherwise, the square is placed in the positive quadrant with one corner at (0,0). Defaults to false. Example square ([2,2],center = true);  ### circle Creates a circle at the origin of the coordinate system. The argument name is optional. Parameters Decimal. This is the radius of the circle. The resolution of the circle will be based on the size of the circle. If you need a small, high resolution circle you can get around this by making a large circle, then scaling it down by an appropriate factor, or you could set$fn or other special variables. Default value is 1.
Decimal. This is the diameter of the circle. The resolution of the circle will be based on the size of the circle. If you need a small, high resolution circle you can get around this by making a large circle, then scaling it down by an appropriate factor, or you could set $fn or other special variables. Default value is 1. (NOTE: d is only available in versions later than 2014.03. Debian is currently know to be behind this) Examples circle(); // uses default radius, r=1  circle(r = 10); circle(d = 20);  scale([1/100, 1/100, 1/100]) circle(200); // this will create a high resolution circle with a 2mm radius circle(2,$fn=50); // Another way to create a high-resolution circle with a radius of 2.


### polygon

Create a polygon with the specified points and paths.

Parameters

points
vector of 2 element vectors, ie. the list of points of the polygon
paths
Either a single vector, enumerating the point list, ie. the order to traverse the points, or, a vector of vectors, ie a list of point lists for each seperate curve of the polygon. The latter is required if the polygon has holes. The parameter is optional and if omitted the points are assumed in order. (The 'pN' components of the paths vector are 0-indexed references to the elements of the points vector.)
convexity
Integer. Number of "inward" curves, ie. expected path crossings of an arbitraty line through the polygon. See below.

Usage

polygon(points = [ [x, y], ... ], paths = [ [p1, p2, p3..], ...], convexity = N);


Example

polygon(points=[[0,0],[100,0],[0,100],[10,10],[80,10],[10,80]], paths=[[0,1,2],[3,4,5]]);

Polygon example

In this example, we have 6 points (three for the "outer" triangle, and three for the "inner" one). We connect each one with two 2 path. In plain English, each element of a path must correspond to the position of a point defined in the points vector, e.g. "1" refers to [100,0].

Notice: In order to get a 3D object, you either extrude a 2D polygon (linear or (rotation ) or directly use the polyhedron primitive solid. When using extrusion to form solids, its important to realize that the winding direction of the polygon is significant. If a polygon is wound in the wrong direction with respect to the axis of rotation, the final solid (after extrusion) may end up invisible. This problem can be checked for by flipping the polygon using scale([-1,1]) (assuming that extrusion is being done about the Z axis as it is by default).

Notice: Althought the 2D drawing commands operate in axes labeled as X and Y, the extrusion commands implicitly translate these objects in X-Z coordinates and rotate about the Z axis.

Example:

 polygon([[0,0],[10,90],[11,-10]], convexity = N);


convexity

The convexity parameter specifies the maximum number of front sides (back sides) a ray intersecting the object might penetrate. This parameter is only needed for correctly displaying the object in OpenCSG preview mode and has no effect on the polyhedron rendering.

This image shows a 2D shape with a convexity of 4, as the ray indicated in red crosses the 2D shape a maximum of 4 times. The convexity of a 3D shape would be determined in a similar way. Setting it to 10 should work fine for most cases.

### import_dxf

DEPRECATED: The import_dxf() module will be removed in future releases. Use import() instead.

Read a DXF file and create a 2D shape.

Example

linear_extrude(height = 5, center = true, convexity = 10)
import_dxf(file = "example009.dxf", layer = "plate");


Using the projection() function, you can create 2d drawings from 3d models, and export them to the dxf format. It works by projecting a 3D model to the (x,y) plane, with z at 0. If cut=true, only points with z=0 will be considered (effectively cutting the object), with cut=false, points above and below the plane will be considered as well (creating a proper projection).

Example: Consider example002.scad, that comes with OpenSCAD.

Then you can do a 'cut' projection, which gives you the 'slice' of the x-y plane with z=0.

projection(cut = true) example002();


You can also do an 'ordinary' projection, which gives a sort of 'shadow' of the object onto the xy plane.

projection(cut = false) example002();


Another Example

You can also use projection to get a 'side view' of an object. Let's take example002, and move it up, out of the X-Y plane, and rotate it:

translate([0,0,25]) rotate([90,0,0]) example002();


Now we can get a side view with projection()

projection() translate([0,0,25]) rotate([90,0,0]) example002();


It is possible to use extrusion commands to convert 2D objects to 3D objects. This can be done with the built-in 2D primitives, like squares and circles, but also with arbitrary polygons.

### Linear Extrude

Linear Extrusion is a modeling operation that takes a 2D polygon as input and extends it in the third dimension. This way a 3D shape is created.

#### Usage

linear_extrude(height = fanwidth, center = true, convexity = 10, twist = -fanrot, slices = 20, scale = 1.0) {...}


You must use parameter names due to a backward compatibility issue.

If the extrusion fails for a non-trival 2D shape, try setting the convexity parameter (the default is not 10, but 10 is a "good" value to try). See explanation further down.

#### Twist

Twist is the number of degrees of through which the shape is extruded. Setting the parameter twist = 360 will extrude through one revolution. The twist direction follows the left hand rule.

0° of Twist

linear_extrude(height = 10, center = true, convexity = 10, twist = 0)
translate([2, 0, 0])
circle(r = 1);


-100° of Twist

linear_extrude(height = 10, center = true, convexity = 10, twist = -100)
translate([2, 0, 0])
circle(r = 1);


100° of Twist

linear_extrude(height = 10, center = true, convexity = 10, twist = 100)
translate([2, 0, 0])
circle(r = 1);


-500° of Twist

linear_extrude(height = 10, center = true, convexity = 10, twist = -500)
translate([2, 0, 0])
circle(r = 1);


#### Center

Center determines if the object is centered on the Z-axis after extrusion, so it does not extrude up and down from the center as you might expect.

center = true

linear_extrude(height = 10, center = true, convexity = 10, twist = -500)
translate([2, 0, 0])
circle(r = 1);


center = false

linear_extrude(height = 10, center = false, convexity = 10, twist = -500)
translate([2, 0, 0])
circle(r = 1);


#### Mesh Refinement

The slices parameter can be used to improve the output.

linear_extrude(height = 10, center = false, convexity = 10, twist = 360, slices = 100)
translate([2, 0, 0])
circle(r = 1);


The special variables $fn,$fs and $fa can also be used to improve the output. linear_extrude(height = 10, center = false, convexity = 10, twist = 360,$fn = 100)
translate([2, 0, 0])
circle(r = 1);


#### Scale

Scales the 2D shape by this value over the height of the extrusion. Scale can be a scalar or a vector:

 linear_extrude(height = 10, center = true, convexity = 10, scale=3)
translate([2, 0, 0])
circle(r = 1);


 linear_extrude(height = 10, center = true, convexity = 10, scale=[1,5], $fn=100) translate([2, 0, 0]) circle(r = 1);  ### Rotate Extrude A rotational extrusion is a Linear Extrusion with a twist, literally. Unfortunately, it can not be used to produce a helix for screw threads as the 2D outline must be normal to the axis of rotation, ie they need to be flat in 2D space. The 2D shape needs to be either completely on the positive or negative side of the X axis. If the shape crosses the X axis a warning will be shown in the console windows and the rotate_extrude() will be ignored. #### Examples A simple torus can be constructed using a rotational extrude. rotate_extrude(convexity = 10) translate([2, 0, 0]) circle(r = 1);  #### Mesh Refinement Increasing the number of fragments that the 2D shape is composed of will improve the quality of the mesh, but take longer to render. rotate_extrude(convexity = 10) translate([2, 0, 0]) circle(r = 1,$fn = 100);


The number of fragments used by the extrusion can also be increased.

rotate_extrude(convexity = 10, $fn = 100) translate([2, 0, 0]) circle(r = 1,$fn = 100);


#### Extruding a Polygon

Extrusion can also be performed on polygons with points chosen by the user.

Here is a simple polygon and its (fine-grained: $fn=200) rotational extrusion (profile and lathe). (Note it has been rotated 90 degrees to show how the rotation will look, the rotate_extrude() needs it flat). rotate([90,0,0]) polygon( points=[[0,0],[2,1],[1,2],[1,3],[3,4],[0,5]] ); // --------------------------------------------------------------------------- ; rotate_extrude($fn=200) polygon( points=[[0,0],[2,1],[1,2],[1,3],[3,4],[0,5]] );


For more information on polygons, please see: 2D Primitives: Polygon.

### Description of extrude parameters

#### Extrude parameters for all extrusion modes

 convexity Integer. The convexity parameter specifies the maximum number of front sides (back sides) a ray intersecting the object might penetrate. This parameter is only needed for correctly displaying the object in OpenCSG preview mode and has no effect on the polyhedron rendering.

This image shows a 2D shape with a convexity of 4, as the ray indicated in red crosses the 2D shape a maximum of 4 times. The convexity of a 3D shape would be determined in a similar way. Setting it to 10 should work fine for most cases.

openscad -m make -o $@ -d$@.deps $<  When make my_example.stl is run for the first time, it finds no .deps files, and will just depend on my_example.scad; since my_example.stl is not yet preset, it will be created unconditionally. If OpenSCAD finds missing files, it will call make to build them, and it will list all used files in my_example.stl.deps. When make my_example.stl is called subsequently, it will find and include my_example.stl.deps and check if any of the files listed there, including my_example.scad, changed since my_example.stl was built, based on their time stamps. Only if that is the case, it will build my_example.stl again. #### Automatic targets When building similar .stl files from a single .scad file, there is a way to automate that too: # match "module foobar() { // make me" TARGETS=$(shell sed '/^module [a-z0-9_-]*().*make..\?me.*/!d;s/module //;s/().*/.stl/' base.scad)

all: ${TARGETS} # auto-generated .scad files with .deps make make re-build always. keeping the # scad files solves this problem. (explanations are welcome.) .SECONDARY:$(shell echo "${TARGETS}" | sed 's/\.stl/.scad/g') # explicit wildcard expansion suppresses errors when no files are found include$(wildcard *.deps)

echo -n 'use <base.scad>\n$*();' >$@



# Building OpenSCAD from Sources

## Prebuilt binary packages

As of 2013, prebuilt OpenSCAD packages are available on many recent Linux and BSD distributions, including Debian, Ubuntu, Fedora, Arch, NetBSD and OpenBSD. Check your system's package manager for details.

For Ubuntu systems you can also try chrysn's Ubuntu packages at his launchpad PPA, or you can just copy/paste the following onto the command line:

sudo add-apt-repository ppa:chrysn/openscad
sudo apt-get update
sudo apt-get install openscad


His repositories for OpenSCAD and OpenCSG are here and here.

There is also a generic linux binary package at http://www.openscad.org that can be unpacked and run from within most linux systems. It is self contained and includes the required libraries.

## Building OpenSCAD yourself

If you wish to build OpenSCAD for yourself, start by installing git on your system using your package manager. Git is often packaged under the name 'scmgit' or 'git-core'. Then, get the OpenSCAD source code

 cd ~/


Then get the MCAD library, which is now included with OpenSCAD binary distributions

 git submodule init
git submodule update


### Installing dependencies

Now download and install the dependency libraries and tools using your package manager. This includes Qt4, CGAL, GMP, cmake, MPFR, boost, OpenCSG, GLEW, Eigen2, GCC C++ Compiler, Bison, and Flex. OpenSCAD comes with a helper script that will try to fetch and install these automatically for you (note: you must have 'sudo' working for this script to work).

 ./scripts/uni-get-dependencies.sh


Now check the version numbers against the openscad/README.md file to see if the version numbers are high enough and that no packages were accidentally missed. OpenSCAD comes with another helper script to assist in this process.

 ./scripts/check-dependencies.sh


(Note that this detects a 'lower bound' on GLEW, not the actual version you have)

If your system passes all checks, continue to the 'Building OpenSCAD' section below. If you are missing libraries, try to search your package manager to see if it might have them under different names. If your package manager has the package but it is just too old, then read the next section on building your own dependencies.

On systems that lack updated dependency libraries or tools, you can download and build your own. As of 2013, OpenSCAD comes with scripts that can do this automatically, without interfering with any system libraries, and without requiring root access, by putting everything under $HOME/openscad_deps. (It however will not build X11, Qt4, gcc, bash or other basics). First, set up the environment variables (if you don't use bash, replace "source" with a single ".")  source scripts/setenv-unibuild.sh  Then, download and build.  ./scripts/uni-build-dependencies.sh  If you only need CGAL or OpenCSG, you can just run ' ./scripts/uni-build-dependencies.sh cgal' or opencsg and it will only build a single library. The complete download and build process can take anywhere from half an hour to several hours, depending on your network connection speed and system speed. It is recommended to have at least 1.5 Gigabyte of free disk space to do the full dependency build. Each time you log into a new shell and wish to re-compile OpenSCAD you need to re-run the 'source scripts/setenv-unibuild.sh' script After completion, re-check (while running under the same shell, with the same environment variables set) to see if it worked.  ./scripts/check-dependencies.sh  ### Build the OpenSCAD binary Once you have either downloaded or built the dependencies, you can build OpenSCAD.  qmake # or qmake-qt4, depending on your distribution make  You can also install OpenSCAD to /usr/local/ if you wish. The 'openscad' binary will be put under /usr/local/bin, the libraries and examples will be under something like /usr/local/share/openscad possibly depending on your system. Note that if you have previously installed a binary linux package of openscad, you should take care to delete /usr/local/lib/openscad and /usr/local/share/openscad because they are not the same paths as what the standard qmake-built 'install' target uses.  sudo make install   Note: on Debian-based systems create a package and install OpenSCAD using:  sudo checkinstall -D make install  If you prefer not to install you can run "./openscad" directly whilst still in the ~/openscad directory. ## Compiling the test suite OpenSCAD comes with over 740 regression tests. To build and run them, it is recommended to first build the GUI version of OpenSCAD by following the steps above, including the downloading of MCAD. Then, from the same login, run these commands:  cd tests mkdir build && cd build cmake .. make ctest -C All  The file 'openscad/doc/testing.txt' has more information. Full test logs are under tests/build/Testing/Temporary. A pretty-printed index.html web view of the tests can be found under a machine-specific subdirectory thereof and opened with a browser. ## Troubleshooting If you encounter any errors when building, please file an issue report at https://github.com/openscad/openscad/issues/ . ### Errors about incompatible library versions This may be caused by old libraries living in /usr/local/lib like boost, CGAL, OpenCSG, etc, (often left over from previous experiments with OpenSCAD). You are advised to remove them. To remove, for example, CGAL, run rm -rf /usr/local/include/CGAL && rm -rf /usr/local/lib/*CGAL*. Then erase$HOME/openscad_deps, remove your openscad source tree, and restart fresh. As of 2013 OpenSCAD's build process does not advise nor require anything to be installed in /usr/local/lib nor /usr/local/include.

Note that CGAL depends on Boost and OpenCSG depends on GLEW - interdependencies like this can really cause issues if there are stray libraries in unusual places.

Another source of confusion can come from running from within an 'unclean shell'. Make sure that you don't have LD_LIBRARY_PATH set to point to any old libraries in any strange places. Also don't mix a Mingw windows cross build with your linux build process - they use different environment variables and may conflict.

### OpenCSG didn't automatically build

If for some reason the recommended build process above fails to work with OpenCSG, please file an issue on the OpenSCAD github. In the meantime, you can try building it yourself.

  wget http://www.opencsg.org/OpenCSG-1.3.2.tar.gz
sudo apt-get purge libopencsg-dev libopencsg1 # or your system's equivalent
tar -xvf OpenCSG-1.3.2.tar.gz
cd OpenCSG-1.3.2
# edit the Makefile and remove 'example'
make
sudo cp -d lib/lib* $HOME/openscad_deps/lib/ sudo cp include/opencsg.h$HOME/openscad_deps/include/

 Note: on Debian-based systems (such as Ubuntu), you can add the 'install' target to the OpenCSG Makefile, and then use checkinstall to create a clean .deb package for install/removal/upgrade. Add this target to Makefile:  install: # !! THESE LINES PREFIXED WITH ONE TAB, NOT SPACES !! cp -d lib/lib* /usr/local/lib/ cp include/opencsg.h /usr/local/include/ ldconfig  Then:  sudo checkinstall -D make install  .. to create and install a clean package.

If this happens, you can try to compile CGAL yourself. It is recommended to install to $HOME/openscad_deps and otherwise follow the build process as outlined above. ### Compiling is horribly slow and/or grinds the disk It is recommended to have at least 1.2 Gbyte of RAM to compile OpenSCAD. There are a few workarounds in case you don't. The first is to use the experimental support for the Clang Compiler (described below) as Clang uses much less RAM than GCC. Another workaround is to edit the Makefile generated by qmake and search/replace the optimization flags (-O2) with -O1 or blank, and to remove any '-g' debug flags from the compiler line, as well as '-pipe'. If you have plenty of RAM and just want to speed up the build, you can try a paralell multicore build with  make -jx  Where 'x' is the number of cores you want to use. Remember you need x times the amount of RAM to avoid possible disk thrashing. The reason the build is slow is because OpenSCAD uses template libraries like CGAL, Boost, and Eigen, which use large amounts of RAM to compile - especially CGAL. GCC may take up 1.5 Gigabytes of RAM on some systems during the build of certain CGAL modules. There is more information at StackOverflow.com. ### BSD issues The build instructions above are designed to work unchanged on FreeBSD and NetBSD. However the BSDs typically require special environment variables set up to build any QT project - you can set them up automatically by running  source ./scripts/setenv-unibuild.sh  NetBSD 5.x, requires a patched version of CGAL. It is recommended to upgrade to NetBSD 6 instead as it has all dependencies available from pkgin. NetBSD also requires the X Sets to be installed when the system was created (or added later). On OpenBSD it may fail to build after running out of RAM. OpenSCAD requires at least 1 Gigabyte to build with GCC. You may have need to be a user with 'staff' level access or otherwise alter required system parameters. The 'dependency build' sequence has also not been ported to OpenBSD so you will have to rely on the standard OpenBSD system package tools (in other words you have to have root). ### Test suite problems Headless server The test suite will try to automatically detect if you have an X11 DISPLAY environment variable set. If not, it will try to automatically start Xvfb or Xvnc (virtual X framebuffers) if they are available. If you want to run these servers manually, you can attempt the following: $ Xvfb :5 -screen 0 800x600x24 &
$DISPLAY=:5 ctest  Alternatively: $ xvfb-run --server-args='-screen 0 800x600x24' ctest


There are some cases where Xvfb/Xvnc won't work. Some older versions of Xvfb may fail and crash without warning. Sometimes Xvfb/Xvnc have been built without GLX (OpenGL) support and OpenSCAD won't be able to generate any images.

Image-based tests takes a long time, they fail, and the log says 'return -11'

Imagemagick may have crashed while comparing the expected images to the test-run generated (actual) images. You can try using the alternate ImageMagick comparison method by by erasing CMakeCache, and re-running cmake with -DCOMPARATOR=ncc. This will enable the Normalized Cross Comparison method which is more stable, but possibly less accurate and may give false positives or negatives.

Testing images fails with 'morphology not found" for ImageMagick in the log

Your version of imagemagick is old. Upgrade imagemagick, or pass -DCOMPARATOR=old to cmake. The comparison will be of lowered reliability.

### I moved the dependencies I built and now openscad won't run

It isn't advised to move them because the build is using RPATH hard coded into the openscad binary. You may try to workaround by setting the LD_LIBRARY_PATH environment variable to place yourpath/lib first in the list of paths it searches. If all else fails, you can re-run the entire dependency build process but export the BASEDIR environment variable to your desired location, before you run the script to set environment variables.

## Tricks and tips

After you have built the dependencies you can free up space by removing the $BASEDIR/src directory - where$BASEDIR defaults to $HOME/openscad_deps. ### Preferences OpenSCAD's config file is kept in ~/.config/OpenSCAD/OpenSCAD.conf. ### Setup environment to start developing OpenSCAD in Ubuntu 11.04 The following paragraph describes an easy way to setup a development environment for OpenSCAD in Ubuntu 11.04. After executing the following steps QT Creator can be used to graphically start developing/debugging OpenSCAD. • Add required PPA repositories: # sudo add-apt-repository ppa:chrysn/openscad  • Update and install required packages: # sudo apt-get update # sudo apt-get install git build-essential qtcreator libglew1.5-dev libopencsg-dev libcgal-dev libeigen2-dev bison flex  • Get the OpenSCAD sources: # mkdir ~/src # cd ~/src # git clone https://github.com/openscad/openscad.git  • Build OpenSCAD using the command line: # cd ~/src/openscad # qmake # make  • Build OpenSCAD using QT Creator: Just open the project file openscad.pro (CTRL+O) in QT Creator and hit the build all (CTRL+SHIFT+B) and run button (CTRL+R). ### The Clang Compiler There is experimental support for building with the Clang compiler under linux. Clang is faster, uses less RAM, and has different error messages than GCC. To use it, first of all you will need CGAL of at least version 4.0.2, as prior versions have a bug that makes clang unusable. Then, run this script before you build OpenSCAD.  source scripts/setenv-unibuild.sh clang  Clang support depends on your system's QT installation having a clang enabled qmake.conf file. For example, on Ubuntu, this is under /usr/share/qt4/mkspecs/unsupported/linux-clang/qmake.conf. BSD clang-building may require a good deal of fiddling and is untested, although eventually it is planned to move in this direction as the BSDs (not to mention OSX) are moving towards favoring clang as their main compiler. OpenSCAD includes convenience scripts to cross-build Windows installer binaries using the MXE system (http://mxe.cc). If you wish to use them, you can first install the MXE Requirements such as cmake, perl, scons, using your system's package manager (click to view a complete list of requirements). Then you can perform the following commands to download OpenSCAD source and build a windows installer:  git clone https://github.com/openscad/openscad.git cd openscad source ./scripts/setenv-mingw-xbuild.sh ./scripts/mingw-x-build-dependencies.sh ./scripts/release-common.sh mingw32  The x-build-dependencies process takes several hours, mostly to cross-build QT. It also requires several gigabytes of disk space. If you have multiple CPUs you can speed up things by running export NUMCPU=x before running the dependency build script. By default it builds the dependencies in$HOME/openscad_deps/mxe. You can override the mxe installation path by setting the BASEDIR environment variable before running the scripts. The OpenSCAD binaries are built into a separate build path, openscad/mingw32.

Note that if you want to then build linux binaries, you should log out of your shell, and log back in. The 'setenv' scripts, as of early 2013, required a 'clean' shell environment to work.

If you wish to cross-build manually, please follow the steps below and/or consult the release-common.sh source code.

## Setup

The easiest way to cross-compile OpenSCAD for Windows on Linux or Mac is to use mxe (M cross environment). You will need to install git to get it. Once you have git, navigate to where you want to keep the mxe files in a terminal window and run:

git clone git://github.com/mxe/mxe.git


Add the following line to your ~/.bashrc file:

• Mac OS X: $HOME/Documents/OpenSCAD/libraries 3. The User-Defined library path can be created using the OPENSCADPATH Environment Variable to point to the library(s). OPENSCADPATH can contain multiple directories in case you have library collections in more than one place, separate directories with a semi-colon for Windows, and a colon for Linux/Mac OS. For example: Windows: C:\Users\A_user\Documents\OpenSCAD\MyLib;C:\Thingiverse Stuff\OpenSCAD Things;D:\test_stuff (Note: For Windows, in versions prior to 2014.02.22 there is a bug preventing multiple directories in OPENSCADPATH as described above, it uses a colon (:) to separate directories. A workaround, if your libraries are on C: is to leave off the drive letter & colon, e.g. \Thingiverse Stuff\OpenSCAD Things:\stuff Linux/Mac OS: /usr/lib:/home/mylib:. OpenSCAD will need to be restarted to recognise any change to the OPENSCADPATH Environment Variable. Where you specify a non-fully qualified path & filename in the use <...> or include <...> statement that path/file is checked against the directory of the calling .scad file, the User-Defined library paths (OPENSCADPATH), the Built-In library (i.e. the O/S dependent locations above), and the Installation library, in that order. NOTE: In the case of a library file itself having use <...> or include <...> the directory of the library .scad file is the 'calling' file, i.e. when looking for libraries within a library, it does not check the directory of the top level .scad file. For example, with the following locations & files defined: (with OPENSCADATH=/usr/lib:/home/lib_os:.) 1. <installation library>/lib1.scad 2. <built-in library>/lib2.scad 3. <built-in library>/sublib/lib2.scad 4. <built-in library>/sublib/lib3.scad 5. /usr/lib/lib2.scad 6. /home/lib_os/sublib/lib3.scad  The following include <...> statements will match to the nominated library files include <lib1.scad> // #1. include <lib2.scad> // #5. include <sublib/lib2.scad> // #3. include <sublib/lib3.scad> // #6.  Since 2014.03, the currently active list of locations can be verified in the "Help->Library Info" dialog. The details info shows both the content of the OPENSCADPATH variable and the list of all library locations. The locations will be searched in the order they appear in this list. For example; OPENSCADPATH: /data/lib1:/data/lib2 OpenSCAD library path: /data/lib1 /data/lib2 /home/user/.local/share/OpenSCAD/libraries /opt/OpenSCAD/libraries  ### Setting OPENSCADPATH In Windows, Environment Variables are set via the Control panel, select System, then Advanced System Settings, click Environment Variables. Create a new User Variable, or edit OPENSCADPATH if it exists. On Linux (probably also on Mac), to simply add the environment variable to all users, you can type in terminal: sudo sh -c 'echo "OPENSCADPATH=$HOME/openscad/libraries" >>/etc/profile' to set the OPENSCADPATH to openscad/libraries under each user's home directory. For more control on environment variables, you'll need to edit the configuration files; see for example this page.

There are many different forks floating around (e.g.[9], [10], [11]) many of them unmaintained.

MCAD bundles a lot of stuff, of varying quality, including:

• Many common shapes like rounded boxes, regular polygons and polyeders in 2D and 3D
• Gear generator for involute gears and bevel gears.
• Stepper motor mount helpers, stepper and servo outlines
• Nuts, bolts and bearings
• Screws and augers
• Material definitions for common materials
• Mathematical constants, curves
• Teardrop holes and polyholes

The git repo also contains python ncode to scrape OpenSCAD code, a testing framework and SolidPython, an external python library for solid cad.

# Other Libraries

• BOLTS tries to build a standard part and vitamin library that can be used with OpenSCAD and other CAD tools: [12]
• Obiscad contains various useful tools, notably a framework for attaching modules on other modules in a simple and modular way: [13]
• This library provides tools to create proper 2D technical drawings of your 3D objects: [14]
• Stephanie Shaltes wrote a fairly comprehensive fillet library (https://github.com/StephS/i2_xends/blob/master/inc/fillets.scad)
• The shapes library contains many shapes like rounded boxes, regular polygons. It is also included in MCAD.
• Also Giles Bathgates shapes library provides regular polygons and polyeders and is included in MCAD.
• The OpenSCAD threads library provides ISO conform metric and imperial threads and support internal and external threads and multiple starts.
• Sprockets for ANSI chains and motorcycle chains can be created with the Roller Chain Sprockets OpenSCAD Module. Contains hard coded fudge factors, may require tweaking.
• The Pinball Library provides many components for pinball design work, including models for 3d printing of the parts, 3d descriptions of mount holes for CNC drilling and 2d descriptions of parts footprint
• For the generation of celtic knots there is the Celtic knot library
• The 2D connection library helps with connections between 2D sheets, which is useful for laser cut designs.
• local.scad provides a flexible method for positioning parts of a design. Is also used in BOLTS.
• SCADBoard is a library for designing 3D printed PCBs in OpenSCAD.
• A Ruler for determining the size of things in OpenSCAD.

There is also a list with more libraries here: [15]

# Command Glossary

This is a Quick Reference; a short summary of all the commands without examples, just the basic syntax. The headings are links to the full chapters.

## Mathematical Operators

+
-   // also as unary negative
*
/
%

<
<=
==
!=
>=
>

&&   // logical and
||   // logical or
!    // logical not

<boolean> ? <valIfTrue> : <valIfFalse>


## Mathematical Functions

abs ( <value> )

cos ( <degrees> )
sin ( <degrees> )
tan ( <degrees> )
asin ( <value> )
acos ( <value> )
atan ( <value> )
atan2 ( <y_value>, <x_value> )

pow( <base>, <exponent> )

len ( <string> )   len ( <vector> )   len ( <vector_of_vectors> )
min ( <value1>, <value2> )
max ( <value1>, <value2> )
sqrt ( <value> )
round ( <value> )
ceil ( <value> )
floor ( <value> )
lookup( <in_value>, <vector_of_vectors> )


## String Functions

str(string, value, ...)


## Primitive Solids

cube(size = <value or vector>, center = <boolean>);

sphere(r = <radius>);

cylinder(h = <height>, r1 = <bottomRadius>, r2 = <topRadius>, center = <boolean>);
cylinder(h = <height>, r = <radius>);

polyhedron(points = [[x, y, z], ... ], triangles = [[p1, p2, p3..], ... ], convexity = N);


## Transformations

scale(v = [x, y, z]) { ... }

(In versions > 2013.03)
resize(newsize=[x,y,z], auto=(true|false) { ... }
resize(newsize=[x,y,z], auto=[xaxis,yaxis,zaxis]) { ... }  // #axis is true|false
resize([x,y,z],[xaxis,yaxis,zaxis]) { ... }
resize([x,y,z]) { ... }

rotate(a = deg, v = [x, y, z]) { ... }
rotate(a=[x_deg,y_deg,z_deg]) { ... }

translate(v = [x, y, z]) { ... }

mirror([ 0, 1, 0 ]) { ... }

multmatrix(m = [tranformationMatrix]) { ... }

color([r, g, b, a]) { ... }
color([ R/255, G/255, B/255, a]) { ... }
color("blue",a) { ... }


## Conditional and Iterator Functions

for (<loop_variable_name> = <vector> ) {...}

intersection_for (<loop_variable_name> = <vector_of_vectors>) {...}

if (<boolean condition>) {...} else {...}

assign (<var1>= <val1>, <var2>= <val2>, ...) {...}


## CSG Modelling

union() {...}

difference() {...}

intersection() {...}

render(convexity = <value>) { ... }


## Modifier Characters

! { ... } // Ignore the rest of the design and use this subtree as design root
* { ... } // Ignore this subtree
% { ... } // Ignore CSG of this subtree and draw it in transparent gray
# { ... } // Use this subtree as usual but draw it in transparent pink


## Modules

module name(<var1>, <var2>, ...) { ...<module code>...}


Variables can be default initialized <var1>=<defaultvalue>

In module you can use children() to refer to all child nodes, or children(i) where i is between 0 and $children. ## Include Statement After 2010.02 include <filename.scad> (appends whole file)  use <filename.scad> (appends ONLY modules and functions)  filename could use directory (with / char separator). Prior to 2010.02 <filename.scad>  ## Other Language Features $fa is the minimum angle for a fragment. The default value is 12 (degrees)

$fs is the minimum size of a fragment. The default value is 1.  $fn is the number of fragments. The default value is 0.


When $fa and$fs are used to determine the number of fragments for a circle, then OpenSCAD will never use less than 5 fragments.


rotate_extrude(convexity = <val>[, $fn = ...]){...}  ## DXF Extrusion linear_extrude(height = <val>, center = <boolean>, convexity = <val>, twist = <degrees>[...]) import (file = "filename.dxf", layer = "layername")  rotate_extrude(origin = [x,y], convexity = <val>[,$fn = ...])
import (file = "filename.dxf", layer = "layername")


## STL Import

import("filename.stl", convexity = <val>);