Passing formulas to OpenSCAD modules/functions by arpruss 3d model
3dmdb logo
Thingiverse
Passing formulas to OpenSCAD modules/functions by arpruss

Passing formulas to OpenSCAD modules/functions by arpruss

by Thingiverse
Last crawled date: 3 years, 1 month ago
This page is mainly for reference. Most users will want this simpler solution which parses strings containing OpenSCAD formulas: http://www.thingiverse.com/thing:2295309
One of the features that OpenSCAD is lacking is the ability to pass functions to modules or to functions. This is a quick-and-dirty proof-of-concept solution to the not uncommon problem of wanting to pass a mathematical formula to a module or function: an eval() function that evaluates expressions in a simple LISP-inspired language that supports all of the OpenSCAD mathematical operators. The evaluation is moderately fast: about 10,000 evaluations of the sample formula below per second on my laptop. The downside is that it's pretty inconvenient to write expressions in this language.
Call the function with: eval(expression, variables). Here, variables is a table of variable values, where each line of the table has the name of the variable followed by its value, e.g., [["x", 12.3], ["y", 7]].
An expression is one the following:
a string naming a variable and expressing the value of that variable
a vector of the form ["'", value] expressing the given literal value (e.g., ["'", [12,3]] expresses the vector [12,3])
for convenience, a number expressing itself (e.g., 12.3)
a vector of the form [operator argument1 argument2 ...]
For instance, the OpenSCAD formula 3*(x*pow(y,3)-pow(x,3)*y) is expressed with ["*", 3, [ "-", ["*", "x", ["^", "y", 3]], ["*", ["^", "x", 3], "y"] ]].
The operators supported are:
The binary operations +, -, *, /, %, <, <=, >, >=, ==, !=, &&, || and the unary - and ! with the same meanings as in OpenSCAD
The binary power operator ^ or pow with the same meaning as OpenSCAD's pow(x,y)
The unary degree-based trigonometric operators cos, sin, tan, acos, asin and atan and the binary atan2 with the same meaning as in OpenSCAD
The radian-based versions COS, SIN, TAN, ACOS, ASIN, ATAN and ATAN2
The functions abs, ceil, cross, exp, floor, ln, len, log, max, min, norm, rands, round and sign with the same meanings as in OpenSCAD
The ternary operator ?, where ["?", argument1, argument2, argument3] works like OpenSCAD's argument1 ? argument2 : argument3
The binary operator # that retrieves an element from a vector: ["#", argument1, argument2] works like OpenSCAD's argument1[argument2]
The variadic operator [ that forms a vector from its arguments. E.g., ["[", 3, 4, "x"] yields the vector [3,4,x]
The unary or variadic operators max and min; when given a single argument, that argument is assumed to be a vector to calculate the maximum or minimum of; when given multiple arguments, we get the maximum or minimum of all the arguments
The variadic operator concat which concatenates all of its arguments
The binary or ternary operator range which corresponds to OpenSCAD [argument1:argument2] or [argument1:argument2:argument3]
The ternary operator gen which provides a generator expression. Do ["gen", variable, range, subexpression] to generate a vector obtained by iterating subexpression over range while varying the value of the variable indicated (variable is an expression that should evaluate to a string). (UNTESTED)
The ternary operator let: ["let", variableName, value, expression] which evaluates expression under the added assumption that variableName is a string naming a variable whose value is value; e.g., ["let", ["'", "x", 3], ["+", "x", 1]] assigns 3 to the variable named "x", and then calculates x+1

Currently, unknown operators return the operator itself, but this behavior cannot be counted on.
The OpenSCAD file contains a demo which draws Borromean rings or a (primitive) 3D function plot.
Update:
The variable system has been overhauled. The let operator has been explained.
The variable system has been overhauled again: the dollar sign operator has been removed.

Tags