跳轉至內容

OpenSCAD 使用者手冊/從原始碼構建 OpenSCAD

來自華夏公益教科書

大多數使用者更喜歡從主要 http://www.openscad.org 網站下載預編譯的二進位制安裝包。

但是,如果您願意,可以自己編譯 OpenSCAD 原始碼。它允許您嘗試開發版本中的新功能和錯誤修復。它還使您在開發過程中暴露在某些意外的故障和錯誤中。如果您正在嘗試使用最新的原始碼,強烈建議您加入 openscad 開發者郵件列表。

此頁面提供一般資訊。您可以在以下頁面找到具體的逐步說明

OpenSCAD 的結構

[編輯 | 編輯原始碼]

截至 2011 年,OpenSCAD 很大程度上依賴於另外兩個專案:OpenCSG 庫和 CGAL 幾何庫。OpenCSG 利用 OpenGL 顯示卡的特殊技巧來快速生成計算實體幾何運算的二維“預覽”。這是正常的“F5”模式。另一方面,CGAL 是一個幾何庫,它實際上計算物件的交集和並集,允許將 .stl 匯出到 3D 印表機。這是“F6”模式。

理論上,後端庫可以被替換。OpenSCAD 是一個基於文字的 CAD 程式。只要它能正常工作並提供有用的功能,它使用的“後端”幾何無關緊要。郵件列表中的討論提到了例如使用 OpenCASCADE 庫代替 CGAL 的可能性。

OpenCSG 主要基於可以“偽造”二維螢幕上計算實體幾何運算(減法、交集、並集)的特殊演算法。它使用的兩個主要演算法是 SCS 和 Goldfeather,可以在 OpenSCAD 的“首選項”選單中選擇。這些演算法透過將 CSG 運算分解為各個部分,然後使用特殊功能(例如離屏 OpenGL 幀緩衝區物件(或 Pbuffer))將這些部分渲染到 OpenGL 圖形緩衝區中來工作,同時還大量使用 OpenGL 模板緩衝區和深度緩衝區。

OpenCSG 還要求物件被“規範化”。例如,如果您的程式碼說從一個立方體開始,減去一個球體,新增一個菱形,新增一個圓柱體,再新增兩個球體,然後減去一個甜甜圈,這並不能“規範化”。規範化將原始物件形成一個“樹”,其中每個“葉子”包含一個“正”和一個“負”物件。OpenSCAD 自己執行這種規範化,如 OpenCSG 預覽期間日誌視窗中所示。然後將規範化的 CSG 樹傳遞給 OpenCSG 進行渲染。偶爾規範化過程會“爆炸”並凍結機器,導致 CGAL 渲染成為檢視物件的唯一方法。規範化期間的物件數量是有限的,可以在 OpenSCAD 首選項中更改。

OpenCSG 有自己的示例原始碼,隨程式提供。它可以幫助您瞭解各種 OpenCSG 渲染選項。

連結

CGAL 是計算幾何演算法庫。它包含大量幾何演算法和方法,透過這些方法可以表示物件。它計算 3D 物件的實際“點集”,從而能夠輸出 STL 等 3D 格式。

OpenSCAD 使用了 CGAL 的兩個主要功能 - Nef 多面體和“普通”多面體。它還使用各種其他功能,如三角剖分等。但主要資料結構是 Nef 和“普通”多面體。

Nef 多面體

根據維基百科的 Nef 多面體文章,Nef 多面體以 Walter Nef 命名,他寫了一本關於多面體的書,名為“Beiträge zur Theorie der Polyeder”,該書於 1978 年由瑞士伯恩的 Herbert Lang 出版。該理論的粗略解釋如下:想象您可以建立一個將宇宙一分為二的“平面”。現在,想象您可以“標記”一側為“內部”,另一側為“外部”。現在想象您將這些平面中的幾個平面組合在一起,例如,就像房間的牆壁、天花板和地板一樣。現在讓我們想象一下所有這些平面的“內部”,現在想象一下您對它們執行“交集”運算 - 就像維恩圖或集合上的任何其他布林運算一樣。這個“交集”形成了一個長方體 - 從外部看它就像一個盒子。這個盒子就是 Nef 多面體。換句話說,您透過對“半空間”(宇宙的一半)執行布林運算來建立了一個多面體。

為什麼要費這麼大的勁?為什麼不直接使用空間中的“點”和三角形面就行了?好吧,Nef 多面體具有某些特性,使得對它們的布林運算比對網格之間的布林運算效果更好——理論上是這樣的。

CGAL 的 Nef 多面體程式碼計算執行 CSG 運算時生成的新形狀的最終三維點。讓我們以 OpenSCAD 示例程式中的示例 4 為例。它是一個立方體,減去一個球體。構成該“籠子”形狀的多邊形的實際座標由 CGAL 透過計算“半空間”的交集和並集來計算。然後將其轉換為“普通多面體”。然後可以將其轉換為 .stl(立體光刻)檔案,以輸出到 3D 列印系統。

普通多面體

CGAL 的 Nef 多面體並不是 CGAL 內部唯一的 Polyhedron 表示型別。還有更基本的“CGAL Polyhedron_3”,這裡稱為“普通”多面體。事實上,OpenSCAD 的許多例程將 CGAL Nef 多面體轉換為“普通”CGAL Polyhedron_3。這裡的技巧是“普通”Polyhedron_3 有一定的限制。具體來說是:“多面體曲面始終是一個具有邊界邊的可定向和定向二維流形”。這意味著它只處理沒有自相交、孤立線和點等複雜問題的“水密”曲面。更準確的解釋可以在這裡找到:http://www.carliner-remes.com/jacob/math/project/math.htm

Nef 多面體和“普通”Polyhedron_3 之間的轉換有時會導致使用 OpenSCAD 時出現問題。

問題

理論上,CGAL 是無縫且一致的。實際上,有一些文件缺陷、錯誤等。OpenSCAD 嘗試用異常捕獲器包裝對 CGAL 的呼叫,以便每次使用者嘗試編譯某些內容時程式都不會崩潰。

另一個有趣的注意事項是比較二維和三維多面體以及 Nef 多面體函式。例如,沒有辦法 transform() 二維 Nef 多面體,因此 OpenSCAD 自己實現了它。沒有簡單的方法可以將 Nef 多面體從二維轉換為三維。遍歷二維資料結構的方法也與遍歷三維資料結構的方式完全不同 - 一個使用“瀏覽器”,而另一個提供一堆迴圈器和迭代器。

CGAL 的編譯速度也很慢 - 作為一個幾乎完全由標頭檔案組成的庫,除了獲取具有更多 RAM 的速度更快的機器,以及可能使用 clang 編譯器代替 GCC 之外,沒有好的方法可以“解決”這個問題。並行構建(make -j)可以提供幫助,但如果它使用 CGAL Minkowski 和等功能,這並不會加快您正在處理的單個檔案的編譯速度。

CGAL 和 GMPQ

[編輯 | 編輯原始碼]

CGAL 允許使用者選擇一個“核心” - 用於底層資料結構的數字型別。許多 3D 渲染引擎只使用浮點數 - 但在進行幾何運算時,這可能會出現問題,因為存在舍入誤差。CGAL 提供了其他核心和數字型別,例如來自 GNU GMP 專案的 GMPQ 數字型別。這基本上是所有有理數的集合。

有理數(兩個整數的比率)在幾何運算中是一個優勢,因為您可以對它們進行許多操作而不會出現任何舍入誤差 - 包括縮放。例如,取數字 1/3。您無法在 PC 上的 IEEE 浮點數中精確地表示它。它變成了 0.3333... 無限迴圈。同樣對於像 0.6 這樣的數字 - 在有限數量的二進位制數字中實際上沒有 0.6 的十進位制數字的二進位制表示。

在有限位機器上,二進位制數系統在除法運算下不是“封閉”的。您可以將一個有限位二進位制浮點數除以另一個數,結果卻得到一個非有限位二進位制浮點數。例如,6 除以 10,得到 0.6。實際上,這不僅僅是二進位制數的問題,而是任何使用小數點且位數有限的數字系統都會遇到的問題——從十進位制系統(小數)到十六進位制、二進位制到任何系統都是如此。但是,對於有理數來說,這種情況不會發生。您可以將任何有理數除以任何其他有理數,最終結果仍然是另一個有理數——它不是無限的,也不涉及舍入。因此,對由有理點構成的 3D 物體進行“縮小”會導致 0 個舍入誤差。對由浮點數構成的 3D 物體進行“縮小”經常會導致舍入誤差。

有理數的另一個優點是,如果您有兩條直線,它們的端點(或斜率/截距,或直線方程)是有理數,那麼它們的交點也是一個有理數,不會產生舍入誤差。有限浮點數不能保證這一點(因為求解直線方程涉及除法)。請注意,這對像 CGAL 這樣的程式很有幫助,它處理大量平面之間的交點。例如,想象一下對兩個由半徑偏移的帶面球體進行“交點”操作。

缺點是有理數很慢。現代計算機 CPU 硬體中所做的絕大多數最佳化都是基於處理普通浮點數或整數的理念,而不是基於整數的比率——這些整數可能大於機器上“long int”的大小(也稱為大整數)。

在除錯時,如果您位於程式碼內部並執行類似“std::cout << vertex->point().x()”的操作,您將獲得兩個整數的比率,而不是浮點數。對於浮點數轉換,您必須使用 CGAL::to_double( vertex->point().x() );您可能會注意到,有時,您的“double”轉換,包括其截斷和舍入,可能會顯示兩個點相等,而列印底層的 GMPQ 會顯示,實際上,這兩個點具有完全不同的座標。

最後,在 OpenSCAD 中,必須注意,它的預設數字型別通常是 C++“double”(浮點數)。因此,即使您可能具有使用有理數表示的“完美”CGAL 物件,OpenSCAD 本身也使用大量浮點數,並在編譯期間將浮點數來回轉換為 CGAL GMPQ(另一個導致速度變慢的因素)。

連結

Throwntogether

[edit | edit source]

“Throwntogether” 渲染器是一個“回退”快速預覽渲染器,如果 OpenCSG 不可使用,OpenSCAD 可以使用它。它應該在最小的 OpenGL 系統上都能工作。它的主要缺點是它將負空間渲染為大型的不透明綠色塊,而不是作為正空間的“切口”。這可能會隱藏形狀的許多內部細節,並使 OpenSCAD 的使用更加困難。例如,“intersection”命令不會執行任何操作——它只是將完整的交點形狀顯示為聯合體一樣。但是,透過按“F6”,使用者仍然可以將物件編譯成 CGAL 並檢視其預期的形狀。

在什麼情況下,程式會回退到 Throwntogether,而不是使用 OpenCSG 預覽?在 OpenGL 機器不支援模板緩衝區,並且無法使用“幀緩衝區物件”(FBO)繪製離屏影像的情況下。如果使用者發現 OpenCSG 支援在他們的系統上存在錯誤,他們也可以透過選單手動切換到“throwntogether”模式。

原始碼註釋

[edit | edit source]

Ifdefs

程式碼的設計理念是,理論上,CGAL 和/或 OpenCSG 可以被停用或啟用。在實踐中,這並不總是有效,需要進行調整。但是,如果有一天底層引擎要被替換,程式碼的這一特性將極大地幫助這種轉換。

Value

Value 類是 OpenSCAD 表示數字、字串、布林變數、向量等的機制。OpenSCAD 使用它來彌合 .scad 原始碼及其各種引擎核心之間的差距。value.h 和 value.cc 使用 boost 的“variant”特性(有點像 C 聯合體,但更好)。

node

最重要的部分派生自 AbstractNode 類。不同的節點之間有各種約定和模式是相同的,因此在實現新功能或修復錯誤時,透過比較節點來檢視事情的處理方式會很有幫助。例如,transformnode.h 和 transform.cc 展示了“scale()”之類的功能如何從原始碼(在“context”中)轉換為 transformnode 的成員變數(node.matrix),然後由 CGALEvaluator.cc 用於對 3D 物件資料執行“transform”操作。這可以與 colornode、lineartextrudenode 等進行比較。

Polyset

PolySet 是一種“中間”粘合類,它表示處於不同處理階段的 3D 物件。所有基本體最初都是作為 PolySet 建立的,然後在必要時轉換為 CGAL 格式。OpenSCAD 目前將所有 import() 轉換為 PolySet,然後轉換為 CGAL Nef 多面體或 CGAL“普通”多面體。

DXF 相關內容

截至 2013 年初,OpenSCAD 的 2D 子系統嚴重依賴於 DXF 格式,這是一種由 Autodesk 在 1980 年代建立的、用於 Autocad 的舊格式。DXFData 類似於 2D 物件的 PolySet——各種其他 2D 表示之間的粘合劑。

CGAL Nef 多面體

此類“封裝”了 2D 和 3D Nef 多面體。它包含諸如布林運算子、並集、交集,甚至 Minkowski 和之類的有用函式。它的編譯速度非常慢,主要是因為 CGAL minkowski 標頭檔案程式碼很大,因此它被拆分成了單獨的 .cc 檔案。您可能還會注意到,在處理 Nef 多面體時通常會避免使用指標——而是使用 boost::shared_ptr。

CGAL 普通多面體

您可能注意到,沒有“普通”CGAL 多面體的類。沒錯。它不存在。它總是“按原樣”使用,通常作為其他格式之間的中間形式。如前所述,從“普通”格式進行轉換會導致“非 2 流形”物件的出現問題。CGAL 的多面體也用於檔案匯出(請參閱 export.cc)。

GUI 與測試

截至 2013 年初,OpenSCAD 使用了兩個獨立的構建系統。一個用於 GUI 二進位制檔案,另一個用於迴歸測試。第一個基於 Qmake,第二個基於 Cmake。新增功能可能需要有人同時使用這兩個系統。有關構建和執行迴歸測試的更多資訊,請參閱 doc/testing.txt。

庫註釋

[edit | edit source]

QT

OpenSCAD 的 GUI 使用 QT 工具包。但是,對於所有非 GUI 程式碼,開發人員都會避免使用 QT 並使用 boost::filesystem 等替代方案。這有助於某些方面,例如模組化和可移植性。截至 2013 年年中,完全不需要 QT 就可以構建測試套件。

其他庫和庫版本

OpenSCAD 還依賴於 Boost、Eigen 數學庫和 GLEW OpenGL 擴充套件幫助程式庫。為了實際構建 OpenSCAD,以及編譯和執行自診斷測試,OpenSCAD 還需要“git”、“cmake”和 ImageMagick 等工具。版本號可能很重要。它們列在 OpenSCAD 原始碼根目錄中的一個 readme 檔案中。使用過舊的庫會導致 OpenSCAD 表現出奇怪的行為或崩潰。

提交補丁

[edit | edit source]

請參閱 OpenSCAD_User_Manual/Submitting_patches

華夏公益教科書