跳轉到內容

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

修飾符

[編輯 | 編輯原始碼]

修飾符在位於物件之前時,會修改直譯器在預覽和渲染該物件或程式中所有其他物件時的行為。它們是使用者在設計即使是最簡單的物件時必不可少的輔助工具。


背景 (%)

[編輯 | 編輯原始碼]

除錯 (#)

[編輯 | 編輯原始碼]

停用 (*)

[編輯 | 編輯原始碼]
華夏公益教科書