跳转到内容

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

translate()

[编辑 | 编辑源代码]

projection(): 3D 到 2D 投影

[编辑 | 编辑源代码]

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

一些额外的示例可以在

流程控制

[编辑 | 编辑源代码]

if() ... else ...

[编辑 | 编辑源代码]
条件对象 if (expr_Q) object_T;
条件对象 if (expr_Q) object_T; else object_F;

条件对象执行一个测试(评估查询 expr_Q),并根据测试结果的 真值 渲染 object_Tobject_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.");
}

for() ...

[编辑 | 编辑源代码]

intersection_for() ...

[编辑 | 编辑源代码]

导入对象

[编辑 | 编辑源代码]

OpenSCAD 可以解释多种文件格式,包括 DXF、STL、JPG 和 TXT,并将它们作为对象。

OpenSCAD 也可以将对象导出为多种文件格式,但是,这些操作是通过集成开发环境中的菜单命令来执行的,因此没有 export() 命令与 import() 和 surface() 命令相对应。

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

调试函数

[编辑 | 编辑源代码]

parent_module()

[编辑 | 编辑源代码]

version()

[编辑 | 编辑源代码]

特殊表达式

[编辑 | 编辑源代码]

let() 表达式

[编辑 | 编辑源代码]

列表推导式

[编辑 | 编辑源代码]

函数和模块定义

[编辑 | 编辑源代码]

函数定义

[编辑 | 编辑源代码]

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

模块定义

[编辑 | 编辑源代码]

children()

[编辑 | 编辑源代码]

预处理器命令

[编辑 | 编辑源代码]

include <>

use <>

关于库管理的说明

[编辑 | 编辑源代码]

特殊变量

[编辑 | 编辑源代码]

$t

$fn 等

$vpn 等

$parent_modules

修饰符

[编辑 | 编辑源代码]

修饰符在位于对象之前时,会修改解释器在预览和渲染该对象或程序中所有其他对象时的行为。它们是用户在设计即使是最简单的对象时必不可少的辅助工具。


背景 (%)

[编辑 | 编辑源代码]

调试 (#)

[编辑 | 编辑源代码]

禁用 (*)

[编辑 | 编辑源代码]
华夏公益教科书