OpenSCAD 用户手册/从源代码构建 OpenSCAD
大多数用户更喜欢从主要 http://www.openscad.org 网站下载预编译的二进制安装包。
但是,如果您愿意,可以自己编译 OpenSCAD 源代码。它允许您尝试开发版本中的新功能和错误修复。它还使您在开发过程中暴露在某些意外的故障和错误中。如果您正在尝试使用最新的源代码,强烈建议您加入 openscad 开发者邮件列表。
此页面提供一般信息。您可以在以下页面找到具体的逐步说明
- OpenSCAD 用户手册/在 Linux/UNIX 上构建
- OpenSCAD 用户手册/在 Linux 或 Mac OS X 上交叉编译 Windows
- OpenSCAD 用户手册/在 Windows 上构建
- 在 Windows 上构建(新)
- OpenSCAD 用户手册/在 Mac OS X 上构建
- 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 渲染选项。
链接
- OpenCSG 主网站
- Freenix 2005幻灯片 关于 OpenCSG、Goldfeather 和规范化
- Freenix 2005 论文,更多关于 Goldfeather、规范化等的详细信息
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 允许用户选择一个“内核” - 用于底层数据结构的数字类型。许多 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(另一个导致速度变慢的因素)。
链接
- CGAL 的主网站
- CGAL 中的数字表示
- CGAL 3d 布尔运算在 Nef 多面体上(注意到任何熟悉的颜色了吗?)
- 普通的 CGAL 多面体 3
- Nef 多面体,维基百科
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 表现出奇怪的行为或崩溃。