想學習 OpenSCAD,〈OpenSCAD User Manual〉算是個蠻完整的說明,有時間其實應該好好看一下,不過老實說,我也沒有全部看完過,大部份的時間裏,我都是 查詢〈OpenSCAD CheatSheet〉,知道想使用的模組、轉換等如何使用,然後就動手做了…XD
在〈Hello,
              OpenSCAD!〉中看到了基本的 OpenSCAD 程式樣貌,像是變數、for 語法、cube、text
            模組、translate、rotate 轉換等,這邊就以 OpenSCAD
            CheatSheet 中的說明來進行。
變數
首先你看到的是變數,其說明是列在〈OpenSCAD CheatSheet〉的 Syntax 區域:
my_text = "Hello, OpenSCAD!";
step_angle = 30;
radius = 30;
height = 5;
乍看沒什麼,就像是個動態定型語言,不需要宣告變數型態,不過,在〈Variable〉 中有這麼一句話:
OpenSCAD is a Functional programming language, as such variables are bound to expressions and keep a single value during their entire lifetime due to the requirements of referential transparency.
由於我一開始是邊做邊學,確實沒有注意到 Functional programming 這件事,也因此在〈挑 戰OpenSCAD迷宮產生器〉時,讓我吃足了苦頭,不過都克服過來了,現在是用得蠻順手的,以後有人問我 Functional programming 可以用在哪,至少我可以舉 OpenSCAD 當作例子了。
不過,說是 Functional programming 語言,還是有些不同,你對同一變數多次設值,是不會產生錯誤,只是同一範圍中,只會有一個值,而同一範圍中,無論你在哪些地方取值,取得的一定是最後一次設定的值。例如:
x = 1;
echo(x); // 顯示 2
x = 2;
echo(x); // 顯示 2
你可以在 OpenSCAD 的環境右下角 Console 看到兩次的 “ECHO: 2”。至於這個行為在〈Variables are set at compile-time, not run-time〉有解釋為什麼,總之,別管這個行為,就照著 Functional programming 的基本概念,變數只能指定值一次,之後就是 Immutable 就是了。
for 迴圈
你看到的 for 迴圈,是列在 〈OpenSCAD
              CheatSheet〉 的 Other 區域中,在〈For
              Loop〉的說明中有些範例,看了就明白了。
在〈Hello,
              OpenSCAD!〉中,看到的是最基本的 for(variable = [start : end])
            形式,會產生 start 到 end 的數字,並指定給 variable,
            每次遞增 1,因此…
for (a =[3:5]) {
    echo(a);
}
會在 Console 中看到 3、4、5 的顯示,不過,別以為以下最後會顯示 12:
sum = 0;
for (a =[3:5]) {
    sum = sum + a;
    echo(sum);
}
echo(sum);
實際上的結果最後會顯示 0,該怎麼說?官方說明是說,同一範圍中,一個變數只會有一個值,這對 for
            也不例外,也就是說,for 外是一個範圍,因此,對 for 外頭來說,sum
            的值一定是剛開始設定的 0,至於 for 中就比較難理解了,比較像是每次都複製出 sum
            的值 0,然後加 a 後指定給一個新變數 sum,
            因此你會看到的顯示是 3、4、5、0。
好吧!我也覺得以上這說明有點難懂,從 Functional programming 的角度來想或許比較簡單,因為 Functional
            programming 中是沒有迴圈的,只有遞迴,因此,你可以將 for
            看成是一個遞迴的語法糖,會比較好懂,就像是:
module forLoop(range, value) {
    if(range[0] <= range[1]) {
        sum = value + range[0];
        echo(sum);
        forLoop([range[0] + 1, range[1]], value);
    } 
}
sum = 0;
forLoop([3, 5], sum);
echo(sum);
這樣的話,對最後結果會產生 3、4、5、0,也就不感到意外了,至於 module,之後還會說明,現在你可以
            暫且將之當成是其他命令式語言中的函式或方法。
3D 模組
在〈Hello,
              OpenSCAD!〉中一開始看到的 cube 模組,列在〈OpenSCAD
              CheatSheet〉的 3D 區域,顧名思義,就是建立 3D 物件用的模組,在〈cube〉
            說明中,可以看到一些範例,cube 可用來繪製立方體。
最主要的是可以記得兩點:一是當使用陣列指定時,三個數值分別是座標 x、y、z,
            大部份的情況下,總是要指定三個值,畢竟建立正立方體的機會沒那麼多;第二點是可以指定 center = true,
            這會讓模型以原點來置中,大部份的 3D 模組,多半可以有這個參數。
你也可以看到,cube 可以有 cube(size = [x,y,z], center =
              true) 這樣的指定方式,這很方便,因為可以不用管參數順序,只要記得參數名稱,也就是說,cube(center
              = true, size = [x,y,z]) 也是可以的。
2D 模組
建立文字時使用了 text 模組,這是歸類在〈OpenSCAD
              CheatSheet〉的 2D 區域,你可以在〈OpenSCAD
              User Manual/Text〉看到,可以設定的參數還蠻多的,就我目前而言,基本上只用過 text、size
            與 font 這三個參數。
text 參數沒有問題,就是你要指定的文字,不好打出來的特殊字元,也可以使用 Unicode 碼指定,例如:
text("\u20AC 10 \u263A");
這會顯示歐元符號、10 與一個笑臉:
size 參數預設是 10,單位是 mm,至於 font 則是字
              型名稱,如果你要能建立中文,第一要讓 .scad 檔案是 UTF-8
            編碼,第二是要指定中文字型,例如,來個「標楷體」的「春」字:
text("春", font = "標楷體");
這會建立以下的文字:
你也可以加粗或者是斜體,方式就如文件中說明的例子之一 font="Liberation Sans:style=Bold
              Italic",在字型名稱號加上冒號,使用 style 指定 Bold、Italic
            等。
extrude
上頭說 text 列於 2D 模組,也就是說,即使看起來有厚度,也只是看起來而已,它並不是建立 3D
            模型,只是 2D 平面上的一張圖而已,要讓 2D 變 3D,你得進行 extrude 的動作。
在〈Hello,
              OpenSCAD!〉看到的是 linear_extrude,它歸類於〈OpenSCAD
              CheatSheet〉的 Other 之中。最基本的當然是給予 2D 一個厚度,成為 3D 物件,像是…
linear_extrude(10) text("春", font = "標楷體");
注意,linear_extrude(10)
            之後不用分號,這類輔助某個模組的操作,後頭都是接上某個完成操作的模組。這會建立以下的 3D 模型:
轉換
在〈Hello,
              OpenSCAD!〉看到的 translate 與 rotate,很
            簡單,前者以陣列指定 X、Y、Z 座標對模型作平移,後者以陣列指定繞 X、Y、Z 的轉動角度,對模型做旋轉,舉例來說:
translate([-5, -5, -5])
    linear_extrude(10) 
        text("春", font = "標楷體"); 
會讓方才建立的「春」整個以原點置中,結果就是…
如果接下來再繞 X 軸轉動 90 度…
rotate([90, 0, 0])
    translate([-5, -5, -5])
        linear_extrude(10) 
            text("春", font = "標楷體");
就會產生以下的結果:
你可以看到,rotate、translate、linear_extrude
            連續對一個模組進行操作,中間不用逗號,而我喜歡將它們適當地縮排,因為這會比 rotate([90, 0, 0])
              translate([-5, -5, -5]) linear_extrude(10) text("春", font =
              "標楷體");
            容易讀得多,當然,這類操作多了之後,縮排太多層也是很困擾的,這時可以用自訂模組來處理,這就之後再說明了。


