【STL切片算法文献笔记】一种使用 STL 文件进行高效轮廓构造的改进切片算法

文章目录

  • 一、前言
  • 二、研究导览
  • 三、方案概述
  • 四.切片过程
    • 4.1 数据结构
    • 4.2 全局切片算法
    • 4.3 前向边和后向边判断(FBEJ-算法)
    • 4.4 高效的轮廓构造(ECC算法)
  • 五. 分析、实施和测试结果


一、前言

STL 模型是通过将实体模型曲面细分为三角形而获得的。 镶嵌的精度由弦误差控制,弦误差是镶嵌模型与原始实体模型之间的最大形状差异。 细分实体模型所需的三角形数量是可接受的弦误差和零件几何复杂性的函数。 在 STL 文件创建过程中生成的大量三角形可能会影响对模型进行切片以及随后为每个切片创建轮廓所需的时间。 制造所需的切片数量通常来自用户指定的层厚度和零件构建方向。 STL文件中定义的三角形面必须由每个切片进行切片,并且必须为每个切片构造轮廓; 因此,算法的效率在切片和轮廓创建所需的时间中起着巨大的作用。
为了减少切片时间,本文提出了一种具有高效轮廓构造的改进切片算法。该方法具有高效、健壮性和自动识别内外轮廓的能力等重要特点。


二、研究导览

三、方案概述

切片一般有两种方式。
1)给定一个切片平面,搜索相交的三角形。
2)给定一个三角形,搜索相交的切片平面。

第一种方法,通常称为扫描线/平面算法,是用于切片的常用方法。在第一种方法中,为了减少切片时间,在切片过程之前先进行拓扑信息构造和分组 。
所提出的切片方法基于第二种方法。 在不失一般性的情况下,我们可以假设对象的方向是使切片位置平行于 z 轴。 由于切片平面的间隔是离散的,因此可以通过三角形的 z 坐标和平面的 z 坐标轻松确定与每个三角形相交的平面。

三角形与切片平面的交会创建一条线段,该线段将成为定义每一层的切片几何形状轮廓的一部分。 需要注意的是,对于平面与三角形相交所产生的每条线段,只有两条相邻边会对该轮廓贡献点。 事实上,其中一边将始终是具有最大和最小 z 值的顶点的边。 另一边将是三角形的另外两条边之一。 此外,对于共享这些边的三角形,将使用相同方式来生成重复的交点。 所提出的算法试图通过以下方式消除这种重复:
(i) 利用 STL 格式的特点。虽然 STL 文件由一个无序列表的三角形组成,但三角形的三个顶点是按逆时针方向列出的。
(ii) 只计算三角形的一条边(称为前边)的交点,并标记会生成交点的第二条边。

通过以下实例说明整体方法,该示例显示三个三角形和一个切片平面(参见图 4)。假设从 STL 文件中读取的第一个三角形是三角形 1 (v1,v2,v3)。将 s1 表示为同时具有最大和最小Z坐标值的边,那么s1={v2,v3}。该边将始终与切片平面相交。相交的另一边将是三角形的另外两条边之一。通过检查 z 坐标将排除一个边。s2{v1,v2} 被识别为前向边,并且只计算交点 p1(使用第 4.3 节中提出的规则来确定前向边)。该点将成为该切片平面轮廓的一部分。接下来,考虑三角形 2。第一个相交边为 s1{v2,v4},第二个相交边为s2{v2,v5}。使用 4.3 节中提出的规则来确定前向边,将 s1 标识为前向边,并计算它与平面之间的交点(称为 p2)。然后将点 p2 插入到切片数组列表中。接下来,考虑三角形 3,边 s2{v2,v3} 被识别为前向边,点 p3 被计算为交点。然后使用第 4.4 节中提出的 ECC 算法将 p3 插入到切片数组列表中。在这个阶段,点的维护顺序将自动确定正在生成的轮廓是内轮廓还是外轮廓。

【STL切片算法文献笔记】一种使用 STL 文件进行高效轮廓构造的改进切片算法_第1张图片

值得注意的是,该方法将生成的交叉点数量减少了一半,并通过不必比较通常使用其他切片方法生成的各种线段的起点和终点来进一步提高鲁棒性。 此外,轮廓构造是同时进行的,并且通过轮廓的相反的遍历方向可以容易地识别内轮廓和外轮廓。

四.切片过程

4.1 数据结构

4.1.1 相交结构(IS)
相交结构(IS)用于存储与三角形和平面相交相关的信息。 除了当前三角形 (CT) 和当前切片平面 (CS) 的交点 vinter 之外,IS 还包含其他三个元素: 指向相交边 e1 和 e2 的边指针 edge(分别称为前边和后边) ,前一个指针pre指向前一个IS,下一个指针*next指向下一个IS。 IS的结构如图5所示。
【STL切片算法文献笔记】一种使用 STL 文件进行高效轮廓构造的改进切片算法_第2张图片

为了有效地对 3D 模型进行切片,建立了如下几个规则。
规则 1 CT 的边 s1(s1={vzmin,vzmax}) 必须是 IS 中的两条边 (e1, e2) 之一。
规则 2 对于边 e1 和 e2,起始顶点 vstart 的 z 坐标必须小于或等于结束顶点 vend。 在这里,我们假设 z 轴是切片方向。
规则 3 交点 vinter 必须是前缘 e1 与当前切片平面 CS 的交点。 在求解交集过程中必须忽略后向边 e2。
规则 4 假设 s1 和 s2 或者 s1 和 s3 是边指针 *edge 应该指向的两条边,哪条边应该替换 e1,哪条边应该替换 e2 由 4.3 节中描述的“前边和后边判断规则”确定 .

【STL切片算法文献笔记】一种使用 STL 文件进行高效轮廓构造的改进切片算法_第3张图片

4.1.2 交集链表
交集链表 (ILL) 用于链接一系列交集结构,这些结构最终将在切片上形成轮廓。 ILL 的结构如图 7 所示。
交集链表可以解释如下。
(1) ILL 中第一个元素的前一个指针 pre 必须一直指向 ILL 中的最后一个元素,以便立即从 ILL 中获取第一个和最后一个元素。
(2) 除ILL中的第一个元素外,ILL中左元素的前一个指针
pre应该为NULL。
(3) ILL 中最后一个元素的下一个指针 next 必须为 NULL。
(4) 除了ILL中的最后一个元素,ILL中左元素的next指针
next必须指向它的下一个元素。
【STL切片算法文献笔记】一种使用 STL 文件进行高效轮廓构造的改进切片算法_第4张图片
4.1.3 等高线链表(CLL)
等高线链表 (CLL) 用于链接所有相交链表以创建等高线。 CLL 中的任何元素都应包括 ILL 和下一个指针 *next。 其结构如图8所示。轮廓链表是一个嵌套链表。
在这里插入图片描述
4.1.4 切片数组(SA)
切片数组 (SA) 用于存储模型的所有切片。 一个一维数组用于存储所有切片,SA 中的每个元素代表一个切片。 例如,所有切片 Si(i=0,⋯,n−1) 将被排序到切片数组 SAi 中,第 i 层切片可以写为 Si= SA[i]。

4.2 全局切片算法

假设z轴是切片方向,全局切片算法的流程图如图3所示。切片算法将在下面逐步描述。
【STL切片算法文献笔记】一种使用 STL 文件进行高效轮廓构造的改进切片算法_第5张图片

Step 1 初始时i=0,从STL文件中读取第i个三角形,按照顶点顺序将三角形顶点标志赋予每个顶点。如果 i 小于三角形的总数,则继续下一步。否则,程序终止。
步骤 2 搜索第 i 个三角形的最大和最小 z 坐标(zmax 和 zmin)。如果zmax=zmin,表示第i个三角形在切片平面上,转步骤8。否则,继续下一步。
Step 3 获取第i个三角形的三个顶点(vzmin,vzmed,vzmax),求解切片数s_min,s_med,s
_max 对应于 vzmin、vzmed 和 vzmax。继续下一步。
步骤 4 根据判断规则(4.3 节所述)判断 s1 和 s2 的前向边和后向边,然后将 s1 和 s2 放入相交结构中的相应位置。继续下一步。
步骤 5 最初 j = s min。如果 j ★步骤5.1求解前向边e1与第j个切片平面的交集vinter,然后将vinter加入到交集结构中。将 *pre 和 *next 设置为 NULL。继续下一步。
★步骤5.2 根据4.4节描述的ECC算法将IS插入到切片数组SA[j]中。继续下一步。
★步骤5.3 设j=j+1;转到第 5 步。
Step 6 根据判断规则判断 s1 和 s3 的前向边和后向边(描述见
4.3节)然后将s1和s3放到intersection结构中的对应位置。继续下一步。
步骤 7 最初 k =s
med。如果 k ★步骤7.1求解前向边e1与第k个切片平面的交集vinter,然后将vinter加入到交集结构中。将 *pre 和 *next 设置为 NULL。继续下一步。
★步骤7.2 将IS插入到切片数组SA[k]中。继续下一步。
★步骤7.3 设k=k+1;转到步骤 7。
步骤 8 设置 i=i+1;转到步骤 1。

4.3 前向边和后向边判断(FBEJ-算法)

当前三角形CT与当前切片平面CS相交时,由于与当前切片平面存在两条相交边(用交叉结构中的e1和e2表示),因此一般有两个交叉点。 如果两个交点被求解并存储在与当前切片平面相交的所有三角形的交点列表中,则交点列表中将存在冗余交点。 为了避免多余的交叉点,我们只解决交叉点结构中的前向边 e1 与当前切片平面的交叉点,而忽略交叉点结构中的后向边 e2。 为了在求解所有相交三角形的所有交点后成功实现轮廓构建,如何判断三个三角形边s1、s2和s3中的哪条边应该代替交点结构中的e1和e2是该算法的一个重要元素。

在 STL 文件中,每个三角形的法线向量都指向外面的对象。 除了以逆时针方式存储之外,三角形的顶点不以任何方式排序。 从文件中读取时,它们被依次分配三角形顶点标志 (0, 1, 2)。 根据第 3 节中的定义 2,这些边被指定为 s1、s2 和 s3。与给定切片平面相交的两个边必须是 s1 和 s2 或 s1 和 s3,如图 10 所示。

【STL切片算法文献笔记】一种使用 STL 文件进行高效轮廓构造的改进切片算法_第6张图片
基于 s1 的两个可能方向和三个可能的读取顶点序列和标志分配,存在六种可能的情况来确定交叉结构中哪条边是前向边 e1 和哪一个是后向边 e2。 图 10 中的所有情况可以根据 s1 的方向和顶点标志分为四个不同的组,如下所示。
377 / 5,000
Translation results
Group 1: s1从zmin到zmax,flagzmax>flagzmin; 那么,e1=s2(或 s3)和 e2=s1。
Group 2: s1 从 zmin 到 zmax 和 flagzmax Group 3: s1 从 zmax 到 zmin 和 flagzmax Group 4: s1从zmax到zmin,flagzmax>flagzmin; 然后,e1=s1 和 e2=s2(或 s3)。

s2(或s3)的选择由切片平面决定。
为了帮助理解 FBEJ 算法,以图 11 为例,前向和后向边如图 12 所示。

【STL切片算法文献笔记】一种使用 STL 文件进行高效轮廓构造的改进切片算法_第7张图片
【STL切片算法文献笔记】一种使用 STL 文件进行高效轮廓构造的改进切片算法_第8张图片

图 11b 中的 Ti(i=1,⋯,9) 是从左到右与给定切片平面相交的三角形。 它们对应的前边缘(有效相交边缘)如图 12 所示。 11a 和 12 是 Ti(i=1,⋯,9) 和给定切片平面之间的交点。 Ti(i=1,⋯,9) 的交集结构信息也如图 12 所示。

4.4 高效的轮廓构造(ECC算法)

轮廓构造在完整的切片算法中起着重要作用。由于三角形在 STL 文件中随机存储且无序,因此在当前切片上为每个三角形求解的交点也是无序的。从这些无序的交叉点构造轮廓会对切片过程产生重大影响。
典型的等高线构造,其中每个三角形与平面的交点形成一条线,并存储生成的线的两个端点,需要匹配线段的顶点以创建等高线。考虑到通过两个不同三角形生成的端点可能不完全相同(浮点误差),这会给算法的鲁棒性带来问题。在所提出的算法中,由于每个三角形只计算一个交点,因此不需要顶点匹配。轮廓是通过将每个交叉点插入其位置来构造的,因为它是通过检查插入位置生成的。该算法需要检查每个插入的交点的交点链表中的第一个和最后一个元素。

假设插入的交集结构是IS,交集链表是ILL,其第一个元素是ILL.ISf,最后一个元素是ILL.IS1,检查和插入规则定义如下。
规则1 如果IS.e2=ILL.ISf.e1,表示IS是ILL.ISf的前邻交点; 因此,将 IS 插入 ILL.ISf 的前面。 在这种情况下,IS 不能是 ILL .ISf的后向相邻交点。 因此,只检查是否 IS.e2 和 ILL. ISf.e1 是相同的边,忽略 IS.e1 和 ILL.ISf.e2。
规则2 如果IS.e1=ILL.IS1.e2,则表示IS是ILL.IS1的后向相邻交点; 因此,将 IS 插入 ILL.IS1的后面。 在这种情况下,IS 不能是 ILL.ISf 的前邻交点。 因此,只检查是否 IS.e1 和 ILL。 ISl.e2 是相同的边,忽略 IS.e2 和 ILL.IS1.e1。

参考 4.1 节介绍的数据结构,我们知道每个 CLL 中的数据元素就是 ILL。 假设ILLi(0≤i 初始化:bool check forward = false, bool check forward = false, int position = 0, and i=0
变量check_forward和check_backward用来标记是否已经找到IS的前向相邻交集结构或后向相邻交集结构。 变量位置用于标记已找到IS的后向相邻交集结构的位置。

第1步:
如果check_backward=false,则使用上述规则1检查first_elei是否为IS的后向相邻交集结构,否则转步骤2。
如果first_elei是IS的后向相邻交集结构,做(1) check_backward=true, position=i; (2) 在first_elei前面插入IS; (3) 如果check_forward=true,删除CLLi,程序终止。 否则,转至步骤 2。

第2步:
如果check_forward=false,使用上述规则2检查last_elei是否为IS的前向相邻交集结构,否则转步骤3。
如果last_elei是IS的前向相邻交集结构,则执行以下操作: (1)如果position=i,表示IS的后向相邻交集结构和前向相邻交集结构在同一个ILL中,不要在last_elei后面插入IS, 程序终止。 (2) 如果位置≠i,则执行以下步骤。

  • & check_forward=真。
  • 将 IS 插入 last_elei 的后面。
  • 如果check_backward=true,删除 CLLposition ,程序终止。 否则,转至步骤 3。

第 3 步:
i=i+1,转到第 1 步。
为了帮助理解ECC算法,下面以图11为例,简单介绍一下ECC算法。
考虑图 11 的例子。假设图 11b 中的 Ti(i=1,⋯,9) 在 STL 文件中按顺序 (T3,T5,T1,T7,T2,T6,T4,T8,T9) 排序 而ISj(j =1,⋯,9)→{pre, pj,*edge,next}是每个三角形Ti(i=1,⋯,9)对应的插入交集结构。 为了描述方便,ISj(j=1,⋯,9)可以写成
ISj(j=1,⋯,9)→{pre,Dj,next},其中,Dj 包括两个元素 pj 和 *edge。
逐步描述 ECC 算法,每个步骤如图 13 所示。

【STL切片算法文献笔记】一种使用 STL 文件进行高效轮廓构造的改进切片算法_第9张图片

(1) 插入 IS3→{pre,D3,next}。
由于IS3是CLL的第一个插入元素,所以IS3.next指向NULL,IS3.pre指向自身,不做任何判断就将其插入CLL1。
(2) 插入 IS5→{pre,D5,next}。
根据以上两条规则判断,我们知道IS5既不是IS3的前向相邻交集结构,也不是IS3的后向相邻交集结构;因此,让 IS5.pre 指向自身并将其插入 CLL2。
(3) 插入 IS1→{pre,D1,next}。
与 IS5 类似,让 IS1.pre 指向自身并将其插入到 CLL3 中。
(4) 插入 IS7→{pre,D7,next}。
与 IS5 类似,让 IS7.pre 指向自身并将其插入 CLL4。
(5) 插入 IS2→{pre,D2,next}。
由于IS2是IS1的后向相邻交集结构和IS3的前向相邻交集结构;因此,在 IS1 和 IS3 之间插入 IS2。同时,将IS1.pre从原来的指向最后一个元素IS3改变。
删除图 13(4) 中的 CLL1。
(6) 插入 IS6→{pre,D6,next}。
与 IS2 类似,在 IS5 和 IS7 之间插入 IS2。
删除图13(5)中的CLL3。
(7) 插入 IS4→{pre,D4,next}。
与 IS2 类似,在 IS3 和 IS5 之间插入 IS4。
删除图13(6)中的CLL1。
(8) 插入 IS8→{pre,D8,next}。
使用以上两条规则,只判断是否
插入的IS8是图13(7)中CLL1中第一个元素IS1的前向相邻交集结构,插入的IS8是否是图13(7)中CLL1中最后一个元素IS7的后向相邻交集结构。忽略图 13(7) 中 CLL1 中的 ISi(i=2,⋯,6)。

基于上述过程,
算法如下。

  • 保持第一个元素 first_elei 的前一个指针 *pre 指向 CLLi 中 ILLi 的最后一个元素 last_elei,因为 ECC 算法只检查每个插入的交集在 ILLi 中的第一个和最后一个交集结构。这样,当ILLi中存在多个交集结构时,我们可以立即搜索第一个交集结构和最后一个交集结构,并在最短的时间内搜索插入的交集结构的对应位置。

  • 当插入交集结构的不同ILL中发现前向相邻交集结构和后向交集结构时,必须进行删除操作。例如,图 13(5)、图 13(6)、图 13(7)。否则,表示它们在同一个ILL中,将IS插入第一个元素first_elei的前面,不要将IS插入最后一个元素last_elei的后面(例如,图13(9))

  • 所有插入操作和删除操作都可以通过改变指针来完成,而不是移动链表中的元素位置。


五. 分析、实施和测试结果

切片算法已使用 Visual C++ 实现。 提供了几个测试结果来证明该算法的主要特点和效率。 切片方向沿 z 轴固定。 该算法在如下两种不同的测试环境中进行了测试。

测试环境 (TN) I:32 位 Windows 7 系统 PC,配备 Intel® Core™ i3-2310M、[email protected] G、2.10 GHz、NVIDIA NVS 4200M 和 2 G RAM,这是最常见的配置 笔记本电脑
测试环境 (TN) II:64 位 Windows 8 系统 PC,配备 Intel® Core™ i7-3520M、[email protected] G、2.90 GHz、NVIDIA NVS 5400M 和 8 G RAM

表 4 显示了四种不同弦误差 λ 下的比较结果。 Rhinoceros 和 InfinySlice 的切片时间由参考文献 [22] 的作者测试。 从表 4 可以看出,0.0001 弦误差的 STL 模型的数量达到了超过一百万(1,401,978),并且对于具有不同弦误差 λ 的四种 STL 模型,我们的算法比三种不同的切片方法更快。 为了清楚地显示切片轮廓,我们将“ring”模型切片时的切片厚度设置为 0.2 mm,弦误差为 0.001,切片结果如图 19b、c 所示。
【STL切片算法文献笔记】一种使用 STL 文件进行高效轮廓构造的改进切片算法_第10张图片
【STL切片算法文献笔记】一种使用 STL 文件进行高效轮廓构造的改进切片算法_第11张图片

你可能感兴趣的:(3D打印切片算法研究,c++,算法,数据结构,动态规划,排序算法)