OpenSCAD 用户手册/语言指南
OpenSCAD 提供四个 3D 基本体:cube(), sphere(), cylinder() 和 polyhedron()。请注意,surface() 和 import() 也可被视为基本体。
OpenSCAD 提供四个 2D 基本图形:square(), circle(), polygon() 和 text()。
语法上,变换和基本体之间没有区别,两者都接受零个或多个数量和零个或多个子对象作为输入,并产生 2D 或 3D 对象作为输出。但是,基本体不需要输入对象(任何子对象都会被忽略),通常根据定量输入创建对象。一般来说,变换需要输入对象作为子对象。如果变换没有子对象,大多数变换会正常运行,既不产生任何输出,也不产生错误或警告。在编码用户定义模块时,了解基本体和变换之间的语法等效性非常有用,因为用户可以自由创建既像基本体又像变换的模块。
以下列出了按此分类的内置变换的完整列表
对一个对象的变换 | color, rotate, translate, mirror, multmatrix, scale, resize, offset, render |
对两个或多个对象的变换 | union, difference, intersection, hull |
对两个对象的变换 | minkowski |
2D 和 3D 之间的变换 | projection(), linear_extrude(), rotate_extrude() |
Projection() 创建 3D 对象在 X-Y 平面的横截面或投影。横截面就像一把锯子,沿着 X-Y 平面切割对象,只留下平面上的二维形状。投影就像一个无限远的太阳,以平行光线照射物体。投影是该物体在 X-Y 平面上的阴影。请注意,物体在 X-Y 平面上下方和上方的部分都会对阴影有贡献。投影() 后,原始 3D 对象会被丢弃。如果需要除了原始对象以外的横截面或投影,则必须单独重新创建该对象。这可以通过将创建 3D 对象的所有代码打包到一个模块中来最方便地实现。跳过 cut 参数或将其设置为 cut=false
以创建投影。将布尔参数 cut=true
设置为创建横截面。
为了沿任意方向创建投影或穿过任意平面的横截面,请在投影() 之前使用 rotate() 和 translate() 的组合。
投影和横截面对于拉伸和导出到 DXF 格式非常有用。
示例:考虑 example002.scad,它随 OpenSCAD 一起提供(在文件->示例->旧版中查找)
projection(cut = true) example002();
创建一个横截面。
projection(cut = false) example002();
创建一个投影。
要沿 Y 轴方向创建投影,首先围绕 X 轴旋转 90 度,projection() rotate([90,0,0]) example002();
example002(); |
|
projection(cut = true) example002(); |
|
projection(cut = false) example002(); |
|
projection() rotate([90,0,0]) example002(); |
一些额外的示例可以在
- Clifford Wolf 网站上的 example021.scad 中找到.
- 更复杂的示例 来自 Giles Bathgate 的博客
条件对象 | if (expr_Q) object_T; |
条件对象 | if (expr_Q) object_T; else object_F; |
条件对象执行一个测试(评估查询 expr_Q),并根据测试结果的 真值 渲染 object_T 或 object_F。如果 object_F 是空,则 else object_F;
部分是可选的。
更常见的是使用 if() 的复合语句形式,如下例所示
if (a1 > a2) {
// stack cube(a2) on top of cube(a1)
cube(a1);
translate([0,0,a1]) cube(a2);
} else {
// stack cube(a1) on top of cube(a2)
cube(a2);
translate([0,0,a2]) cube(a1);
}
如果条件评估的结果不是对象,而是一个量,请使用? : 条件运算符.
虽然允许在复合形式中分配变量,但这些变量的范围仅限于花括号。
a = 5;
translate([0,0,0]) sphere(a);
if (a > 0) {
echo("Let's change! a = ", a);
translate([20,0,0]) sphere(a);
a = 10;
}
echo("We don't forget! a = ", a);
结果是一个小球体和一个大球体,以及在控制台中
ECHO: "Let's change! a = ", 10
ECHO: "We don't forget! a = ", 5
请注意,"a 是 10" 在花括号的范围内,相应的语句 a = 10;
不需要出现在 echo() 和 sphere() 语句之前才能生效。在 if() 语句之后,对 a 的赋值会丢失,因此我们“回忆”a 仍然是 5。有关详细信息,请参阅 变量作用域。
- 嵌套 if
由于完整的 if() 语句是一个对象,因此它可以嵌套在另一个 if() 语句中。常见形式是多重嵌套的“else if”语句
if (a > 100) { echo("HUGE!"); sphere(a); // etc... } else if (a > 10) { echo("big."); translate([0,0,10]) sphere(a); // etc... } else if (a > 1) { echo("not so big..."); color("red") sphere(a); } else { echo("Sorry, I lost it."); }
OpenSCAD 可以解释多种文件格式,包括 DXF、STL、JPG 和 TXT,并将它们作为对象。
OpenSCAD 也可以将对象导出为多种文件格式,但是,这些操作是通过集成开发环境中的菜单命令来执行的,因此没有 export() 命令与 import() 和 surface() 命令相对应。
Echo() 是对 OpenSCAD 语句进行分类时的一个例外。它的功能与渲染对象无关,但在语法上它既不是变量赋值,也不是表达式(评估为一个量)。因此,它被归类为一个对象,就像基本形状和变换一样,但它产生一个空对象。
Echo() 将其输入参数打印为控制台(编译窗口)中的逗号分隔文本。没有提供格式化选项。字符串用双引号括起来,向量用方括号括起来。多维向量完全用适当数量的嵌套方括号表示。通常可以复制/粘贴 echo() 的输出作为 OpenSCAD 程序中的字面量使用。数值四舍五入到 5 位有效数字。
echo() 的主要目的不是将格式化并打印漂亮的文本消息给最终用户,而是为了将变量的内容公开给程序员,以便进行调试。可以通过 echo() 的一些变体形式和使用str() 函数 来改进输出消息的外观。
OpenSCAD 控制台支持 HTML 标记语言的一个子集。有关详细信息,请查看这里。
Echo() 接受 echo(var = expr, ...)
格式的参数,并生成 ECHO: var = quant, ...
格式的输出,其中 quant 是评估 expr 的结果。这种形式既美观又方便,可以复制/粘贴作为有效的 OpenSCAD 代码。
用法示例
my_h=50; my_r=100; echo("This is a cylinder with h=", my_h, " and r=", my_r); echo(my_h=my_h,my_r=my_r); // shortcut cylinder(h=my_h, r=my_r); // echo("<b>Hello</b> <i>Qt!</i>");
在控制台中显示为
ECHO: "This is a cylinder with h=", 50, " and r=", 100 ECHO: my_h = 50, my_r = 100 ECHO: "Hello Qt!"
标量算术运算符以数字作为操作数,并生成一个新的数字。
+ | 加 |
- | 减 |
- | 取反(一元) |
* | 乘 |
/ | 除 |
% | 取模 |
条件运算符 | expr_Q ? expr_T : expr_F |
一个运算符,根据查询表达式的真值返回两个表达式中的一个。例如
var = expr_Q ? expr_T : expr_F;
表达式 expr_Q 被评估,如果为真,则 expr_T 被评估并赋值给 var;否则 expr_F 被评估并赋值给 var。如果 expr_Q 评估为非布尔结果,则它会被转换为布尔值, 查看这里.
条件运算符在创建递归函数调用时至关重要,因为它用于终止递归,查看这里.
条件运算符也可以像嵌套的 if 一样使用,如下例所示
NSides = (FF=="triangular") ? 3 : (FF=="hexagonal") ? 6 (FF=="octogonal") ? 8 : (FF=="circular") ? 180 : 0;
三角函数使用 C 语言数学库函数。请记住,OpenSCAD 中的所有数字都是 IEEE 双精度浮点数。有关 C 数学库详细信息的良好参考是 (math.h) 和 (acos) 在 Open Group 网站上。有关相关数学的快速参考,请参见 三角函数。
请注意,三角函数不适用于向量。无效输入会产生 nan(例如 acos(2))或 undef(例如 sin("2"))。
函数 | 描述 | 备注 |
---|---|---|
sin(x)
|
x 的三角正弦 | -inf < x < inf 为度数,返回值为 [-1,+1] |
cos(x)
|
x 的三角余弦 | -inf < x < inf 为度数,返回值为 [-1,+1] |
tan(x)
|
x 的三角正切 | -inf < x < inf 为度数,返回值为 (-inf, inf) |
asin(x)
|
x 的反正弦 | -1 <= x <= 1,返回值为 [-90,+90](度数) |
acos(x)
|
x 的反余弦 | -1 <= x <= 1,返回值为 [0,+180](度数) |
atan(x)
|
x 的反正切 | -inf <= x <= inf,返回值为 [-90,+90](度数) |
atan2(y, x)
|
y/x 的反正切 | -inf <= x,y <= inf,返回值为 [-180,+180](度数),另见:atan2 更准确地说,返回值是从原点到点 (x,y) 的直线与 X 轴之间的角度 |
实数函数需要数值输入并生成 数字,除了 rands(),它返回一个数字向量。
函数 | 描述 | 备注 |
---|---|---|
abs(x)
|
x 的绝对值 | -inf < x < inf,返回值为 [0,+inf) |
sign(x)
|
x 的符号,另见 符号函数 | -inf < x < inf,返回值为 1、0 或 -1,如果 x 大于、等于或小于 0 |
ceil(x)
|
实数 x 的上限(整数),另见:Ceil 函数 | -inf < x < inf,返回值是不小于 x 的最小整数 也称为将数字四舍五入到 +inf |
floor(x)
|
实数 x 的下限(整数),另见:Floor 函数 | -inf < x < inf,返回值是不大于 x 的最大整数 也称为将数字四舍五入到 -inf |
round(x)
|
实数 x 的舍入函数 | -inf < x < inf,返回值是最接近 x 的整数 |
pow(x,y)
|
x 的 y 次方,即 | -inf < x,y < inf |
sqrt(x)
|
x 的平方根,即 | 0 <= x < inf,返回值是最接近 x 的整数,如果 x 为负,则返回 nan |
exp(x)
|
x 的指数函数,即 ,另见:指数 | -inf < x < inf |
ln(x)
|
x 的自然对数,即 ,另见:自然对数 | 0 <= x < inf,如果 x 为负,则返回 nan |
log(x)
|
x 的对数(以 10 为底),即 ,另见:对数 | 0 <= x < inf,如果 x 为负,则返回 nan |
rands(a,b,n)
|
伪随机数生成器,请参阅 主要文章 | 返回一个包含 n 个随机数的向量,范围为 [a, b] |
一些示例
echo(ceil(4.4),ceil(-4.4)); // ECHO: 5, -4 echo(floor(4.4),floor(-4.4)); // ECHO: 4, -5 echo(exp(1),exp(ln(3)*4)); // ECHO: 2.71828, 81 sign(-5.0); // ECHO -1 sign(0);// ECHO 0 sign(8.0);// ECHO 1 round(5.4); //-> 5 round(5.5); //-> 6 round(5.6); //-> 6 round(-5.4); //-> -5 round(-5.5); //-> -6 round(-5.6); //-> -6
生成一个伪随机数向量。可以可选地提供一个种子值。从提供种子值的那一刻起,生成的伪随机数序列是确定性的。这提供了一种方便的方法,可以使用重复执行程序之间的常数种子值来调试程序。
Rands()
始终返回一个向量,当只需要一个随机数时,这不是最方便的数据类型。为了生成单个随机值作为数字,请使用 x = rands(a,b,1)[0];
。
参数
- min_value
- 随机数范围的最小值
- max_value
- 随机数范围的最大值
- value_count
- 要作为向量返回的随机数数量
- seed_value(可选)
- 随机数生成器的种子值,用于获得可重复的结果。在 2015 年后期之前的版本中,seed_value 会四舍五入到最接近的整数
使用示例
// get a single number vec_rand = rands(0,10,1); single_rand = rands(0,10,1)[0]; echo(vec_rand); // ECHO: [4.44795] echo(single_rand); // ECHO: 7.86455 // get a vector of 4 random numbers with seed value 42 random_vect=rands(5,15,4,42); echo(random_vect); // ECHO: [8.7454, 12.9654, 14.5071, 6.83435]
cross、norm
max、min
len、concat
lookup
search()
str()、chr()
search()
dxf_cross()
dxf_dim()
function name(param_list) = expr;
请注意,在函数定义内部,主作用域中定义的变量是可访问的。参见 变量和作用域.
支持递归函数调用。使用 条件运算符 可以确保递归终止。注意:有一个内置的递归限制以防止应用程序崩溃。如果达到限制,函数将返回 undef。
- 示例
// recursion - find the sum of the values in a vector (array) by calling itself // from the start (or s'th element) to the i'th element - remember elements are zero based function sumv(v,i,s=0) = (i==s ? v[i] : v[i] + sumv(v,i-1,s)); vec=[ 10, 20, 30, 40 ]; echo("sum vec=", sumv(vec,2,1)); // calculates 20+30=50
include <>
use <>
$t
$fn 等
$vpn 等
$parent_modules
修饰符在位于对象之前时,会修改解释器在预览和渲染该对象或程序中所有其他对象时的行为。它们是用户在设计即使是最简单的对象时必不可少的辅助工具。