OpenSCAD User Manual/The OpenSCAD Language

From Wikibooks, open books for an open world
< OpenSCAD User Manual
Jump to: navigation, search

The OpenSCAD Language [edit]

Contents


0% developed  as of November 14, 2009 General [edit]

Comments [edit]

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.

OpenSCAD uses C++-style comments:

// This is a comment
 
myvar = 10; // The rest of the line is a comment
 
/*
    Multi-line comments
    can span multiple lines.
*/

Variables [edit]

Variables in OpenSCAD are simply a name followed by an assignment via an expression

Example:

myvar = 5 + 4;

Vectors [edit]

Variables can be grouped together into Vectors by using brackets. Vectors are useful when dealing with X, Y, and Z coordinates or sizes.

Example

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

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

Selection [edit]

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

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.

Strings [edit]

Explicit double quotes or backslashes need to be escaped (\" and \\ respectively). Other escaped special characters are newlines (\n), tabs (\t) and carriage returns (\r).

NB! 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."

Variables are set at compile-time, not run-time [edit]

Note: Because OpenSCAD calculates its variable values at compile-time, not run-time, the last variable assignment will apply everywhere the variable is used. 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

This behavior however 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.

See the assign for more tightly scoped changing of values.

Getting input [edit]

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.

0% developed  as of November 14, 2009 Conditional and Iterator Functions [edit]

For Loop [edit]

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>

Range: [<start>:<end>] - iterate from start to end inclusive. Also works if if <end> is smaller than <start>
Range: [<start>:<increment>:<end>] - iterate from start to end with the given increment. The increment can be a fraction. Note: The increment is given as an absolute value and cannot be negative. If <end> is smaller than <start> the increment should remain unchanged. 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>).

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 will 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 [edit]

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.

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 [edit]

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(); // will fail to be processed without any error message

Usage example:

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

Assign Statement [edit]

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);
    }
}

0% developed  as of November 17, 2009 Mathematical Operators [edit]

Scalar Arithmetical Operators [edit]

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 [edit]

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 [edit]

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

&& Logical AND
|| Logical OR
! Logical NOT

Conditional Operator [edit]

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

Example given: x>0 ? "pos" : "neg" the result will be "pos" if x is greater then zero, else "neg"


Vector-Number Operators [edit]

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 [edit]

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 [edit]

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

* sum of vector element products

Matrix Multiplication [edit]

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

* matrix/vector multiplication

0% developed  as of November 14, 2009 Mathematical Functions [edit]

abs [edit]

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

acos [edit]

Mathematical arccosine, or inverse cosine, function.

asin [edit]

Mathematical arcsine, or inverse sine, function.

atan [edit]

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

atan2 [edit]

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

ceil [edit]

Mathematical ceiling function. See: Ceil Function

cos [edit]

Mathematical cosine function.

Usage Examples:
 for(i=[0:36])
    translate([i*10,0,0])cylinder(r=5,h=cos(i*10)*50+60);
OpenSCAD Cos Function‎

exp [edit]

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

floor [edit]

Mathematical floor function. See: Floor Function

ln [edit]

Mathematical natural logarithm. See: Natural logarithm

len [edit]

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

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

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"

log [edit]

Mathematical logarithm. See: Logarithm

lookup [edit]

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 [edit]

Returns the maximum of the two parameters.

Parameters

<a> 
Decimal.
<b> 
Decimal.

Usage Example:

max(3.0,5.0);
max(8.0,3.0);

Results:

5.0
8.0

min [edit]

Returns the minimum of the two parameters.

Parameters

<a> 
Decimal.
<b> 
Decimal.

Usage Example:

min(3.0,5.0);
min(8.0,3.0);

Results:

3.0
3.0

norm [edit]

!!Note this function is not in 2013.01 and is pending pull request https://github.com/openscad/openscad/pull/333.

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 [edit]

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));
 }
}

rands [edit]

Random number generator. Generates a constant vector of pseudo random numbers, much like an array. 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:

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);
 }
}

round [edit]

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); //-> 5
round(5.5); //-> 6
round(5.6); //-> 6

sign [edit]

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

sin [edit]

Mathematical sine function.

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

sqrt [edit]

Mathematical square root function.


Usage Examples:

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

tan [edit]

Mathematical tangent function. Parameters

<degrees> 
Decimal. Angle in degrees.

Usage examples:

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);
}

0% developed  as of November 14, 2009 String Functions [edit]

str [edit]

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."

Also See [edit]

search() for text searching.

0% developed  as of November 14, 2009 Primitive Solids [edit]

cube [edit]

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);

Openscad-cube.jpg

sphere [edit]

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

Parameters

Decimal. 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
$fa 
Angle in degrees
$fs 
Angle in mm
$fn 
Resolution


Usage Examples

sphere(r = 1);
sphere(r = 5);
sphere(r = 10);
// 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); 

Openscad-sphere.jpg

cylinder [edit]

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.
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 radius of both top and bottom ends of the cylinder. Use this parameter if you want plain cylinder. 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 
Angle in degrees
$fs 
Angle in mm
$fn 
Resolution


Usage Examples

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

Openscad-cylinder.jpg

polyhedron [edit]

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

Parameters

points 
vector of points or vertexes (each a 3 vector).
triangles 
vector of point triplets (each a 3 number vector). Each number is the 0-indexed point number from the point vector.
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], ... ], triangles = [ [p1, p2, p3..], ... ], convexity = N);

Triangle points ordering 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 triangle triple. The order of triangles 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 triangles 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 
  triangles=[ [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

Ordering of triangle points 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 (triangles or compositions of triangles) 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]
               ], 
     triangles = [
                  [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]
               ], 
     triangles = [
                  [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 triangles 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 triangles. In our example, the points are annotated in black and the triangles 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 triangle 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.
* Triangles is a list of triangles 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 triangle list (0,1,2,3,... etc).

Each triangle, in the triangle list, is defined by selecting 3 of the points (using the point identifier) out of the point list.

e.g. triangles=[ [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 triangle from the outside, the triangle must list their 3 points in a clockwise order.

0% developed  as of November 14, 2009 Transformations [edit]

scale [edit]

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);

Image showing result of scale() transformation in OpenSCAD

resize [edit]

In versions >= 2013.05, the resize() command is available. It modifes the size of the child object to match the given x,y, and z.

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

OpenSCAD Resize example ellipse

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

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

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

resize([7,0,0], auto=true) cube([1,2,0.5]);  // resize the 1x2x0.5 cube to 7x14x3.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([10,0,0], auto=[true,true,false]) cube([5,4,1]); // resize to 10x8x1. Note that the z dimension is left alone.

rotate [edit]

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 above.

When a rotation is specified for multiple axes the the rotation is applied in the following order: x, y, z.

Usage:
rotate(a = deg, v = [x, y, z]) { ... }

For example, to flip an object upside-down, you might do this:

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

The above example will rotate your object 180 degrees around the 'y' axis.

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

Example with arbitrary origin.

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

This example will rotate your object 45 degrees around the axis defined by the vector [1,1,0] i.e. 45 around X and 45 around Y.

image of result of rotate() transformation in OpenSCAD

translate [edit]

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);

image of result of the translate() transformation in OpenSCAD

mirror [edit]

Mirrors the child element on a plane through the origin. The argument to mirror() is the normal vector on that plane.

Usage example:
mirror([ 0, 1, 0 ]) { ... }
rotate([0,0,10]) cube([3,2,1]);
mirror([1,0,0]) translate([1,0,0]) rotate([0,0,10]) cube([3,2,1]);

image of the result of the mirror() transformation in OpenSCAD

multmatrix [edit]

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 [edit]

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.

Usage example:
color([r, g, b, a]) { ... }

Note that the r, g, b, a values are limited to floating point values in the range { 0.0 ... 1.0 } rather than the more traditional integers { 0 ... 255 }. However you can specify the values as fractions, e.g. for R,G,B integers in {0 ... 255} you can use:

color([ R/255, G/255, B/255 ]) { ... }

As of the 2011.12 version, colors can also be chosen by name; name is not case sensitive. For example, to create a red sphere, you can use this code:

color("red") sphere(5);

Alpha is also available with 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:

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


Chart based on "Web Colors" from Wikipedia

minkowski [edit]

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 [edit]

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);
 }

0% developed  as of November 14, 2009 CSG Modeling [edit]

union [edit]

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);
}


Union


difference [edit]

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);
}


Difference


intersection [edit]

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);
}


Intersection


render [edit]

Always calculate the CSG model for this tree (even in OpenCSG preview mode). 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.

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

0% developed  as of November 14, 2009 Modifier Characters [edit]

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 [edit]

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).

 Usage example:
 % { ... }

Example code:

difference() {
        // start objects
        cylinder (h = 4, r=1, center = true, $fn=100);
        // first object that will subtracted
        % rotate ([90,0,0]) cylinder (h = 4, r=0.3, center = true, $fn=100);
        // second object that will be subtracted
        % rotate ([0,90,0]) cylinder (h = 4, r=0.9, center = true, $fn=100);
}
Background modifier example

Debug Modifier [edit]

Use this subtree as usual in the rendering process but also draw it unmodified in transparent pink.

 Usage example:
 # { ... }

Example:

difference() {
        // start objects
        cylinder (h = 4, r=1, center = true, $fn=100);
        // first object that will subtracted
        # rotate ([90,0,0]) cylinder (h = 4, r=0.3, center = true, $fn=100);
        // second object that will be subtracted
        # rotate ([0,90,0]) cylinder (h = 4, r=0.9, center = true, $fn=100);
}
OpenScad Debug Modifier example

Root Modifier [edit]

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

 Usage example:
 ! { ... }

Disable Modifier [edit]

Simply ignore this entire subtree.

 Usage example:
 * { ... }

0% developed  as of November 14, 2009 Modules [edit]

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);

The child nodes of the module instantiation can be accessed using the child() statement within the module:

module lineup(num, space) {
  for (i = [0 : num-1])
    translate([ space*i, 0, 0 ]) child(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 ]) child(i);
}

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

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]);
}

Importing Geometry [edit]

import [edit]

Imports a file for use in the current OpenSCAD model

Parameters

"<file name>" 
A string containing the path to the STL file to include. Double-quotes are required.

Usage examples:

import("example012.stl");

Notes: In the latest version of OpenSCAD, import() is now used for importing both 2D (DXF for extrusion) and 3D (STL) files.

import_stl [edit]

<DEPRECATED.. Use the command import instead..>

Imports an STL file for use in the current OpenSCAD model

Parameters

"<file name>" 
A string containing the path to the STL file to include. Double-quotes are required.
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.

Usage examples:

import_stl("example012.stl", convexity = 5);

Include Statement [edit]

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. A number of library files are included. See the OpenSCAD_User_Manual/Libraries page.

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.


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

0% developed  as of November 17, 2009 Other Language Features [edit]

Special variables [edit]

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.

$fa, $fs and $fn [edit]

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 (fn > 0.0)
                      return (int)fn;
              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 [edit]

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 and $vpt [edit]

These contain the current viewport rotation and translation - at the time of doing the rendering. Moving he 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)

It's not possible to write to them and thus change the viewport parameters (although that could be a decent enough idea).

Example

 cube([10,10,$vpr[0]/10]);

which makes the cube change size based on the view angle, if an animation loop is active (which does not need to use the $t variable)

You can also make bits of a complex model vanish as you change the view.

The menu command Edit - Paste Viewport Rotation/Translation copies the current value of the viewport, but not the current $vpd or $vpt.

User-Defined Functions [edit]

Define a function for code readability and re-use.

Usage examples:

my_d=20;
function r_from_dia(my_d) = my_d / 2;
echo("Diameter ", my_d, " is radius ", r_from_dia(my_d));

Echo Statements [edit]

This function prints the contents to the compilation window (aka Console). Useful for debugging code.

The OpenSCAD console supports a subset of HTML markup language. See here for details.

Usage examples:

my_h=50;
my_r=100;
echo("This is a cylinder with h=", my_h, " and r=", my_r);
cylinder(h=my_h, r=my_r);
echo("<b>Hello</b> <i>Qt!</i>");

Shows in the Console as

ECHO:Hello Qt!

Render [edit]

Forces the generation of a mesh even in preview mode. Useful when the boolean operations become too slow to track.

Needs description.

Usage examples:

render(convexity = 2) difference() {
 cube([20, 20, 150], center = true);
 translate([-10, -10, 0])
  cylinder(h = 80, r = 10, center = true);
 translate([-10, -10, +40])
  sphere(r = 10);
 translate([-10, -10, -40])
  sphere(r = 10);
}

Surface [edit]

Example 1:

//surface.scad
surface(file = "surface.dat", center = true, convexity = 5);
%translate([0,0,5])cube([10,10,10], center =true);
#surface.dat
10 9 8 7 6 5 5 5 5 5 
9 8 7 6 6 4 3 2 1 0 
8 7 6 6 4 3 2 1 0 0
7 6 6 4 3 2 1 0 0 0
6 6 4 3 2 1 1 0 0 0
6 6 3 2 1 1 1 0 0 0
6 6 2 1 1 1 1 0 0 0
6 6 1 0 0 0 0 0 0 0
3 1 0 0 0 0 0 0 0 0
3 0 0 0 0 0 0 0 0 0

Result:

Openscad surface example x1.png

Example 2

 // example010.dat generated using octave:
 // d = (sin(1:0.2:10)' * cos(1:0.2:10)) * 10;
 // save("example010.dat", "d");
 intersection() {
   surface(file = "example010.dat", center = true, convexity = 5);
   rotate(45, [0, 0, 1]) surface(file = "example010.dat", center = true, convexity = 5); 
 }

Openscad surface example x2.png

Search [edit]

Usage Pattern:

 "search" "(" ( match_value | list_of_match_values ) "," vector_of_vectors
       ("," num_returns_per_match
         ("," index_col_num )? )?
       ")";
 match_value : ( Value::NUMBER | Value::STRING );
 list_of_match_values : "[" match_value ("," match_value)* "]";
 vector_of_vectors : "[" ("[" Value ("," Value)* "]")+ "]";
 num_returns_per_match : int;
 index_col_num : int;

The following are some usage examples.

Index values return as list [edit]

Example Code Result

1

search("a","abcdabcd");

[0,4]

2

search("a","abcdabcd",1);

[0]

3

search("e","abcdabcd",1);

[]

4

search("a",[ ["a",1],["b",2],["c",3],["d",4],["a",5],["b",6],["c",7],["d",8],["e",9] ]);

[0,4]

Search on different column; return Index values [edit]

Example 5:

 search(3,[ ["a",1],["b",2],["c",3],["d",4],["a",5],["b",6],["c",7],["d",8],["e",3] ], 0, 1);

Returns:

   [2,8]

Search on list of values [edit]

Example 6: Return all matches per search vector element.

 search("abc",[ ["a",1],["b",2],["c",3],["d",4],["a",5],["b",6],["c",7],["d",8],["e",9] ], 0);

Returns:

   [[0,4],[1,5],[2,6]]

Example 7: Return first match per search vector element; special case return vector.

 search("abc",[ ["a",1],["b",2],["c",3],["d",4],["a",5],["b",6],["c",7],["d",8],["e",9] ], 1);

Returns:

   [0,1,2]

Example 8: Return first two matches per search vector element; vector of vectors.

 search("abce",[ ["a",1],["b",2],["c",3],["d",4],["a",5],["b",6],["c",7],["d",8],["e",9] ], 2);

Returns:

 [[0,4],[1,5],[2,6],[8]]

Search on list of strings [edit]

Example 9:

 lTable2=[ ["cat",1],["b",2],["c",3],["dog",4],["a",5],["b",6],["c",7],["d",8],["e",9],["apple",10],["a",11] ];
 lSearch2=["b","zzz","a","c","apple","dog"];
 l2=search(lSearch2,lTable2);
 echo(str("Default list string search (",lSearch2,"): ",l2));

Returns

 ECHO: "Default list string search ([\"b\", \"zzz\", \"a\", \"c\", \"apple\", \"dog\"]): [1, [], 4, 2, 9, 3]"