OpenSCAD User Manual/Other Language Features

Echo As A Module

The echo() module prints its given arguments to the compilation window (aka Console), which is useful for debugging code. Any number of arguments may be given, may be of any type, and are output separated by a comma and a space. Strings are enclosed in double quotes ('"') and vectors by square brackets ("[]").

The String Function str() may be used to prepackage a number of values into a string so that values will NOT be separated by a blank. Str() also does not add quotes around strings and does not separate elements with ", ".

Numeric values are rounded off to 5 significant digits. This means that fractions smaller than 0.000001 are not displayed and that very large values are shown in scientific notation with only the first 6 digits shown.

Arguments to Echo() may be given individual labels by using the form: 'variable=variable' as will be seem in this example.

Usage examples:

 my_h=50;
 my_r=100;
 echo("a cylinder with height : ", my_h, " and radius : ", my_r);
 echo( high=my_h, rad=my_r); // will display as high=<num> rad=<num>
 cylinder(h=my_h, r=my_r);

small Decimal Fractions are Rounded Off

This example shows that the fractional part of 'b' may appear to be rounded off when printed by echo(), but is still present for use in calculations and logical comparisons:

a=1.0;
b=1.000002;
echo(a); // shows as '1'
echo(b); // also shows as '1'

if(a==b){
    echo ("a==b");
}else if(a>b){
    echo ("a>b");
}else if(a<b){
    echo ("a<b"); // will be the result
}else{
    echo ("???");
}

Shows in the Console as

ECHO: 1
ECHO: 1
ECHO: "a<b"

Very Small and Large Numbers

Echo shows very small decimal fractions, and very large values, in C Language style scientific notation.

c=1000002;
d=0.000002;
echo(c); //1e+06
echo(d); //2e-06

The syntax of values shown in this form is described in the section on [[1]]

Formatting Output

The only control over text output by echo() is the use of '\n', '\t', and '\r' characters. These are, of course, the Escape Characters for Newline, Tab, and Return and they may be used as part of a string to, respectively, begin a new line, insert blanks to the next tab stop (every 4 spaces), and return to the beginning of the line.

HTML output is not supported in development versions, starting 2025.

Echo As A Function

[Note: Requires version 2019.05 (see [Release Notes ] )]

A call to Echo() can be made as part of an expression to print information to the console just before the expression is evaluated. This means that in when the expression includes a recursive call to a function or module that echo's arguments are shown before the recursion. To be able to see values after the expression one may use a helper function as will be shown by "result()" in the second example following.

Example

 a = 3; b = 5;
 // echo() prints values before evaluating the expression
 r1 = echo(a, b) a * b; // ECHO: 3, 5
 
 // like a let(), a call to echo() may be included as part of an expression
 r2 = let(r = 2 * a * b) echo(r) r; // ECHO: 30
 
 // use echo statement for showing results 
 echo(r1, r2); // ECHO: 15, 30

A more complex example shows how echo() can be used in both the descending and ascending paths of a recursive function.

Example printing both input values and result of recursive sum()

 v = [4, 7, 9, 12];
 function result(x) = echo(result = x) x;
 function sum(x, i = 0) = echo(str("x[", i, "]=", x[i])) result(len(x) > i ? x[i] + sum(x, i + 1) : 0);
 echo("sum(v) = ", sum(v));
 
 // ECHO: "x[0]=4"
 // ECHO: "x[1]=7"
 // ECHO: "x[2]=9"
 // ECHO: "x[3]=12"
 // ECHO: "x[4]=undef"
 // ECHO: result = 0
 // ECHO: result = 12
 // ECHO: result = 21
 // ECHO: result = 28
 // ECHO: result = 32
 // ECHO: "sum(v) = ", 32

Render Operation

This operation causes meshes to be generated for surfaces in preview mode. This improves the rendered images when the normal preview renderer produces artifacts or misses parts of the image around complex bits of geometry. An issue on GitHub discusses some of these issues, and an FAQ covers more: OpenSCAD User Manual/FAQ#Why are some parts (e.g. holes) of the model not rendered correctly?

function definition
render( convexity = 1 )
convexity
an indication to the preview renderer that objects in view are not simple. See the section on the Convexity Parameter

Usage examples:

 render( convexity = 2 ) 
    difference()
        { // stretch a cube vertically
        cube([20, 20, 150], center = true);
        // make a notch in one corner 
        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);
        }

The search() function is a general-purpose function to find one or more (or all) occurrences of a value or list of values in a vector, string or more complex list-of-list construct.

Search usage

search( match_value , string_or_vector [, num_returns_per_match [, index_col_num ] ] );

Search arguments

  • match_value
  • Can be a single string value. Search loops over the characters in the string and searches for each one in the second argument. The second argument must be a string or a list of lists (this second case is not recommended). The search function does not search for substrings.
  • Can be a single numerical value.
  • Can be a list of values. The search function searches for each item on the list.
  • To search for a list or a full string give the list or string as a single element list such as ["abc"] to search for the string "abc" (See Example 9) or [[6,7,8]] to search for the list [6,7,8]. Without the extra brackets, search looks separately for each item in the list.
  • If match_value is boolean then search returns undef.
  • string_or_vector
  • The string or vector to search for matches.
  • If match_value is a string then this should be a string and the string is searched for individual character matches to the characters in match_value
  • If this is a list of lists, v=[[a0,a1,a2...],[b0,b1,b2,...],[c0,c1,c2,...],...] then search looks only at one index position of the sublists. By default this is position 0, so the search looks only at a0, b0, c0, etc. The index_col_num parameter changes which index is searched.
  • If match_value is a string and this parameter is a list of lists then the characters of the string are tested against the appropriate index entry in the list of lists. However, if any characters fail to find a match a warning message is printed and that return value is excluded from the output (if num_returns_per_match is 1). This means that the length of the output is unpredictable.
  • num_returns_per_match (default: 1)
  • By default, search only looks for one match per element of match_value to return as a list of indices
  • If num_returns_per_match > 1, search returns a list of lists of up to num_returns_per_match index values for each element of match_value.
  • See Example 8 below.
  • If num_returns_per_match = 0, search returns a list of lists of all matching index values for each element of match_value.
  • See Example 6 below.
  • index_col_num (default: 0)
  • As noted above, when searching a list of lists, search looks only at one index position of each sublist. That index position is specified by index_col_num.
  • See Example 5 below for a simple usage example.

Search usage examples

See example023.scad included with OpenSCAD for a renderable example.

Index values return as list

Example Code Result

1

search("a","abcdabcd");

[0]

2

search("e","abcdabcd");

[]

3

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

[[0,4]]

4

data=[ ["a",1],["b",2],["c",3],["d",4],["a",5],["b",6],["c",7],["d",8],["e",9] ];

search("a", data, num_returns_per_match=0);

[[0,4]] (see also Example 6 below)

Search on different column; return Index values

Example 5:

 data= [ ["a",1],["b",2],["c",3],["d",4],["a",5],["b",6],["c",7],["d",8],["e",3] ];
 echo(search(3, data));    // Searches index 0, so it doesn't find anything
 echo(search(3, data, num_returns_per_match=0, index_col_num=1));

Outputs:

 ECHO: []
 ECHO: [2, 8]

Search on list of values

Example 6: Return all matches per search vector element.

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

Returns:

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

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

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

Returns:

   [0,1,2]

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

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

Returns:

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

Search on list of strings

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

Getting the right results

// workout which vectors get the results
v=[ ["O",2],["p",3],["e",9],["n",4],["S",5],["C",6],["A",7],["D",8] ];
//
echo(v[0]);					// -> ["O",2]
echo(v[1]);                                     // -> ["p",3]
echo(v[1][0],v[1][1]);                          // -> "p",3
echo(search("p",v));                            // find "p" -> [1]
echo(search("p",v)[0]);                         // -> 1
echo(search(9,v,0,1));                          // find  9  -> [2] 
echo(v[search(9,v,0,1)[0]]);                    // -> ["e",9]
echo(v[search(9,v,0,1)[0]][0]);                 // -> "e"
echo(v[search(9,v,0,1)[0]][1]);                 // -> 9
echo(v[search("p",v,1,0)[0]][1]);               // -> 3
echo(v[search("p",v,1,0)[0]][0]);               // -> "p"
echo(v[search("d",v,1,0)[0]][0]);               // "d" not found -> undef
echo(v[search("D",v,1,0)[0]][1]);               // -> 8

OpenSCAD version

version() and version_num() returns the OpenSCAD version number.

  • The version() function returns the OpenSCAD version as a vector of three numbers, e.g. [2011, 9, 23]
  • The version_num() function returns the OpenSCAD version as a number, e.g. 20110923

parent_module(n) and $parent_modules

$parent_modules contains the number of modules in the instantiation stack. parent_module(i) returns the name of the module i levels above the current module in the instantiation stack. The stack is independent of where the modules are defined. It's where they're instantiated that counts. This can, for example, be used to build a BOM (Bill Of Material).

Example:

 module top() {
   children();
 }
 module middle() {
   children();
 }
 top() middle() echo(parent_module(0)); // prints "middle"
 top() middle() echo(parent_module(1)); // prints "top"

assert

[Note: Requires version 2019.05 (see [Release Notes ] )]

see also Assertion (software development)

Assert evaluates a logical expression. If the expression evaluates to false, the generation of the preview/render is stopped, and an error condition is reported via the console. The report consists of a string representation of the expression and an additional string (optional) that is specified in the assert command.

 assert(condition);
 assert(condition, message);

Parameters

condition
Expression. The expression to be evaluated as check for the assertion.
message
String. Optional message to be output in case the assertion failed.

Example

The simplest example is a simple assert(false);, e.g. in a file named assert_example1.scad.

cube();
assert(false);
sphere();
  
// ERROR: Assertion 'false' failed in file assert_example1.scad, line 2

This example has little use, but the simple assert(false); can be used in code sections that should be unreachable.

Checking parameters

A useful example is checking the validity of input parameters:

module row(cnt = 3){
    // Count has to be a positive integer greater 0
    assert(cnt > 0);
    for (i = [1 : cnt]) {
        translate([i * 2, 0, 0]) sphere();
    }
}

row(0);

// ERROR: Assertion '(cnt > 0)' failed in file assert_example2.scad, line 3

Adding message

When writing a library, it could be useful to output additional information to the user in case of an failed assertion.

module row(cnt = 3){
    assert(cnt > 0, "Count has to be a positive integer greater 0");
    for(i = [1 : cnt]) {
        translate([i * 2, 0, 0]) sphere();
    }
}

row(0);

// ERROR: Assertion '(cnt > 0)': "Count has to be a positive integer greater 0" failed in file assert_example3.scad, line 2

Using assertions in function

Assert returns its children, so when using it in a function you can write

function f(a, b) =
    assert(a < 0, "wrong a") // assert input
    assert(b > 0, "wrong b") // assert input
    let (c = a + b) // derive a new value from input
    assert(c != 0, "wrong c") // assert derived value
    a * b; // calculate