system: [SYSTEM]

user: 4. 孔洞自动分类识别修复算法研究 针对模型孔洞的不同形态，对孔洞进行检测分类和修复，保证修复后的模型最大程度地接近原始模型。其步骤包括：根据输入模型数据，快速建立模型的面片、边和顶点的拓扑结构；根据边与面片的连接关系，获取模型中存在的所有孔洞；根据拓扑特点，将孔洞分为连续套洞和单孔洞，根据拓扑关系，将连续套洞分割为简单孔洞；根据孔洞的几何形态，识别孔洞类型，建立了缝隙→错位错误→环形孔洞→简单孔修复的基本修复步骤。该方法修复后的模型一方面保证修复后模型拓扑正确、填补孔洞区域曲率连续，另一方面保证修复后的模型最大程度的接近原始模型 [ 2 ]。 鞋模孔洞自动分类识别与修复方法，包括以下步骤： 1) 解析输入模型的三角网格模型数据，识别模型中的退化三角面片和重复面片，并将退化三角面片和重复三角面片删除，快速建立模型的面与边、边与点之间的拓扑关系。 2) 根据面与边之间的连接关系，采用区域生成法计算模型的单连通区域，计算每个单联通区域的边界。 3) 根据拓扑关系将孔洞分为单孔洞和连续套洞；将连续套洞根据拓扑和几何形态，分割为单孔洞。 4) 对步骤(3)中识别的单孔洞，根据孔洞的几何形态，划分为缝隙、错位孔洞、环形孔洞以及简单孔洞。对每一种类型的孔洞，根据其几何形态，采用特定的填充方法进行孔洞修复。 4.1. 建立模型拓扑关系 对网格模型进行顶点去重等预处理，将三角网格数据解析为不重复的顶点和面顶点索引，根据面索引，识别模型中的退化三角面片和重复面片。 退化三角形的几何形态为至少有两点相同或三点共线，通过判断三角形的索引是否重复以及三角形的面积是否为零，判断是否为退化三角形。根据三角形的面索引，判断是否有重复三角形。重复三角形的特征为两个三角形的索引相同且方向相同。删除退化面和重复面后，计算三角网格模型的拓扑关系，其中面与边的拓扑关系为三角面片的边邻接的面片，边与点的拓扑关系为三角形的顶点邻接的边。 4.2. 单连通区域边界识别 模型拓扑关系建立后，计算每个单连通区域的孔洞，先采用区域生成法计算模型的单连通区域，然后计算单连通区域的孔洞。 4.2.1. 单连通区域 区域生成法计算模型单连通区域的算法流程图如下：图5。 【1】将所有输入三角面片标记为未访问。 【2】从所有未访问的三角面片中，找出一个面片，将其中一条边作为种子边，添加到种子边集合中。当前面片添加到当前部件集合中，并设置访问标记为已访问。 图5. 单连通计算流程图 【3】从种子边集合中取出一条边，找出与该边连接的未访问面片，将该面片加入到当前部件集合中，标记为已访问。并将与种子边不同的边添加到种子边集中。 【4】循环执行【3】，直到种子边集合为空。 【5】将当前部件中的面片输出作为一个部件。部件数目加一。 【6】重复执行【2】到【5】，直到所有面片均已访问。 4.2.2. 边界识别 三角网格模型如果没有边界，则每个三角面片的边应邻接两个三角形，该类型的边称为内部边，这样的网格模型也称水密封的，是可以直接切片3D打印的。 仅邻接一个三角形的边称为自由边。将所有自由边首尾相连，就得到模型的边界。 模型边界计算算法流程图如图6。 图6. 边界计算流程图 【1】取模型中的三角面片，获取其三条边。 【2】判断边界边集合中是否存在该边。如果存在，则执行【4】，否则执行【3】。 【3】将边添加到边界集合中。 【4】将边在边界集合中删除。 【5】遍历所有面片，重复执行【1】到【4】。 【6】计算边界边集合中的所有点和边的连接关系。 【7】将所有边界首尾相连接，组成边界。 4.3. 连续套洞识别与修复 根据拓扑关系将孔洞分为单孔洞和连续套洞，本节主要介绍连续套洞的识别与修复，连续套洞的识别与修复比较困难，通过拓扑结构可以检测出所有的洞边界，根据连续套洞边界上点与边的连接关系，如果一个边界上的点连接的边超过两条，就认为该点是连续套洞的分割点，通过查找所有的分割点面，根据最短路径法将连续套洞分割为简单的孔洞，从而完成修复。连续套洞的示意图如图7所示。 图7. 连续套洞示意图 连续套洞的识别算法流程图如图8。 图8. 连续套洞识别流程图 连续套洞修复流程如图9和图10所示。 图9. 连续套洞修复流程图 图10. 分割连续套洞子流程图 流程介绍： 【1】检测连续套洞边界，可以检测出孔洞的重复点。例如图7中的A、B两点。 【2】根据重复点，对边界线进行分割。例如图7中，分割成三个单独的孔。 【3】将孔洞边界点投影到平面上，计算各位孔洞的内外位置关系。 【4】对于外部的孔，检测其内部是否有孔洞。对于内部含有孔洞的边界，将外边界与内边界合成一条边界。例如图7中，分割后为两条孔，分别为：(1) P2-A-P1-P3-P4-P6-B-P5-P2和(2) B-P9-P7-B。 【5】依据填充缝隙的方法，填充单独的孔，完成连续套洞的修复。 4.4. 单孔洞分类识别与修复 单孔洞根据几何形态识别分类的方法为：对前面识别出的单孔洞根据如下类型和几何形态划分为缝隙、错位错误、环形孔洞和简单孔洞。 4.4.1. 缝隙识别与修复 缝隙错误的几何形态和修复方法为： 缝隙在几何形态上为特别狭长的孔，通过检测边界中多个点是否共线且首尾相接构成的边是原网格模型的边，可以找到错误顶点，通过将共线边分割，对共线边所在的三角面片重新分元修复缝隙错误。 1) 缝合流程 缝合整体流程如图11。 图11. 缝合流程图 注：缝合时用到的Loop，不是我们通常意义上的闭合Loop，而是按照一定角度阈值拆开的一段段的线段(图12)。 【1】：缝合时，是对模型中的所有Loop整体处理的。文件导入时网格数据是一个面一个面分别存储的，此时如果没有合并的话，需要先进行合并。 【2】：遍历每个Loop，将其中阈值范围内的小段删除，对应删除三角形，更新拓扑关系。每个Loop最少有两个点(起始终止点)，即使两点距离也很短，此处也没有删除。即Loop的个数不变。 【3】：取出所有Loop的端点，进行顶点去重。这样距离近的端点捏在一起，使之形成可缝合的结构。 图12. LOOP示意图 【4】：起点和终点均相同的Loop放在一起，表示形成了可缝合的结构。首先判断是否可以缝合，判断条件即为：由一条Loop上的点，向另一条Loop找最近点和投影点。当到最近点和投影点的距离均大于阈值时，表示缝太大，不能缝合。 【5】：计算在Loop包围盒内的其他Loop端点，记录Loop和待切割点的对应关系。对于每一个Loop和切割点对，依次遍历每个点，计算到Loop的最近点和投影点，优先使用最近点分割Loop，最近点距离较远时，再使用投影点分割。 【6】：分割后形成了可缝合的结构，接下来与步骤【4】相同，进行缝合。 2) 缝合算法 假定待缝合的两Loop，分别为Loop1和Loop2。为与代码保持一致，这里也使用Si、Ei、Sj和Ej表示Loop上的点。Si表示Loop1上已缝合的最后一个点，Ei表示Loop1上要开始缝合的点，Ei = Si + 1。Sj表示Loop2上已缝合的最后一个点，Ej表示Loop2上要开始缝合的点，Ej ≥ Sj。 遍历Loop1中的每个点Ei，首先查找Loop2中距离Ei最近的点Ej。 【1】：首先判断是否要删除小面片。两种情况：1)、Loop1中的Ei到Loop2中的最近点，与Ei的下一个点Ei + 1到Loop2中的最近点。两个最近点是否相同且距离都小于阈值，如满足则删掉EiEi + 1连接的面片。此时Ei和Ei + 1距离应该很小(当前点与下一个点找到同一个点)。2)、Loop1中的Ei到Loop2中的最近点为Sj，且在阈值范围内，则删除SiEi连接的面片。此时Si和Ei距离应该很小(当前点与上一个点找到同一个点)。 【2】：当Ei到Ej距离小于阈值时，根据Ej的位置有两种情况：图13。 图13. Ej情况1示意图 1)、直接拖拽 Ej = Sj + 1： 直接将Ei和Ej拖拽在一起即可，即将Ei索引改为Ej。 2)、分割三角形 Ej! = Sj + 1 (图14) 图14. Ej情况2示意图 此时Sj和Ej之间有多个点。首先计算Sj到Ej之间的点Sm(多个)，每个点与Di相连，Ei和Ej合并，删掉原始三角形DiSiEi即可(图15)。 图15. 修复示意图 【3】：当Ei到Ej距离大于阈值，根据Ej的位置有三种情况： 1)、Ej == Sj (图16) 图16. Ej = Sj示意图 此时计算Ei在EjEj + 1上的投影点Proj，如果Ei到Proj的距离小于阈值，则合并点Ei和Proj，分割三角形EjEj + 1Dj。 2)、Sj! = Ej。此时计算SiEi的距离，与SjSj + 1距离的大小关系。 如果SiEi < SjSj + 1，此时即为Sj + 1 = Ej (图17)。 图17. SiEi < SjSj + 1示例图 此时计算Ei在SjSj + 1上的投影点Proj，如果Ei到Proj的距离小于阈值，则合并点Ei和Proj，分割三角形SjSj + 1Dj。 如果SiEi ≥ SjSj + 1，此时即为Sj + 1 = Ej (图18)。 图18. SiEi ≥ SjSj + 1示意图 此时计算Sj + 1在SiEi上的投影点Proj，如果Sj + 1到Proj的距离小于阈值，则合并点Sj + 1和Proj，分割三角形SiDiEi。 4.4.2. 不共顶点错误识别与修复 不共顶点错误违反了STL文件的共顶点规则，由于顶点不重合导致相邻的三角面片的重合顶点数少于两个，此时三角形的顶点落在相邻三角形的边上，但没有出现裂缝。通过检测边相邻的三角形共线点，就可以找到错误顶点，通过将该错误顶点移动到与其距离最近的顶点处修复不共顶点错误。 不共顶点错误修复流程如下图所示：图19。 图19. 不共顶点修复流程图 流程说明： 【1】输入检测出的不共顶点loop索引。 【2】通过线段方向，查找不共顶点loop的两个端点，确定不共顶点loop的大致线段。 【3】将loop上的其他顶点投影到直线上，通过投影参数计算投影的边。并查找有无重复点。 【4】根据投影点，将含有投影点的三角面片重新分元。 【5】对重复点进行去除，更新面片的索引。 4.4.3. 错位错误识别与修复 错位错误是指应该重合的顶点没有重合所导致的。错位的点表现在模型上也属于拓扑上的缝隙，通过检测点到最近边的距离，小于指定距离的点视为错位错误，通过合并顶点的方法即可以将其修复(图20)。 图20. 错位错误检查与修复流程图 流程说明： 【1】检查模型中的所有孔，检测出所有的孔洞。检查环形孔和不共顶点孔，将其他孔作为检查错位错误的输入孔。 【2】通过计算点到边的距离，查找错位点。根据错位点与最近边的位置关系，查找错位错误的起始边和点，根据起始点创建线段。 【3】判断【2】中计算的错位的起始边是否有公共点，如果有则执行【4】，否则执行【5】。 【4】将错位点投影到最近边上，并修改相应的三角面片。 【5】将错位错误的起始点投影到最近的边上，并对起始边之间的点投影，修正到起始点线段上。 【6】合并错位点，将边界，从错位点处分割开，根据不共顶点和缝隙的修复方法修复。 4.4.4. 环形孔洞的识别和修复 环形孔洞是由两条相近相似的边界组成的孔洞。其连接的是模型中两个不连续的部分。通过检测不同组件的边界之间的距离，识别环形孔洞的两条边界。对环形孔洞进行填充。 环形孔洞是由两个Loop组成。构成洞的Loop，一种是网格本身的自由边组成，另一种需要切割Loop组合而成，比如：图21。 图21. 环形孔洞示意图 此时需要分割三角形，形成孔洞Loop (图22)。 图22. 剩余孔洞分类识别修复流程图 【1】获取整个模型的Loop，计算交点，分割三角形。 【2】获取重新分元后的网格的Loop。 【3】两两Loop组合，判定是否为环形孔洞。若是，执行【4】；不是，执行【5】。 【4】使用拉链补洞方法修补环形孔洞。 【5】剩余Loop为单连通孔洞，判定是否为加工方向上形成的孔洞。若是，执行【6】；不是，执行【7】。 【6】根据Loop形态，判定是XYZ哪个方向上的孔，拆成两段，也是用拉链补洞方式补洞。 【7】使用角度方式补洞。 Loop的切割分为两类，一种是Loop之间切割，一种是Loop自身切割。以Loop之间切割为例说明，Loop自身切割类似(图23)。 图23. Loop分割流程图 【1】计算包围盒相交的两两loop组合。 【2】每组Loop中的两线段求公垂线垂足，若两线段对应的垂足都在线段上，且不在起点和终点，且距离很近。此时我们认为两线段需要在垂足处切割，记录线段索引与垂足(从两线段的垂足中任取一个)的关系map ，vector >。 【3】根据获得的map，对分割点(垂足点)排序后，切割三角形。 1) 一般性环形孔洞识别与修复 一般性环形孔洞的识别，首先计算模型的部件和每一个部件的边界。对每一个孔洞边界，在其他部件的边界中查找与其距离最近的边界，例如，边界L0的最近边界是L1，如果L1的最近边界也是L0。则认为(L0，L1)组成一个环形孔。 流程如下图所示：图24。 一般性环形孔洞识别流程介绍： 【1】计算模型中不连续的面片部件。 【2】如果部件数目小于2，表明没有环形孔洞，结束。 【3】计算每一个部件的边界。 【4】如果有边界的部件数目小于2，则表明没有环形孔洞，结束。 【5】计算每一条边界在其他部件中的最近边界，如果边界L0的最近边界是L1，且L1的最近边界是L0，则认为L0，L1组成环形孔洞。 图24. 一般性环形孔洞检查流程 一般性环形孔洞修补流程如下图所示：图25。 【1】将环形孔洞，即Loop对(Loop1、Loop2)，调整成同一旋转方向。 【2】匹配Loop1、Loop2折点，并记录匹配索引。 【3】调整Loop2中距离Loop1中第一个点最近且不超过对应折点索引点为起点。 【4】变换Loop1和Loop2，使Loop1中点个数大于等于Loop2中点个数。 【5】Loop1中点查找Loop2中最近点，不超过折点索引，取最近点索引，超过取对应折点的索引。 【6】根据索引信息，连接三角形，最终完成补洞(图26)。 图25. 一般性环形孔洞修复流程图 图26. 一般性环形孔洞修复示意图 2) 加工平面孔洞识别和修复 一般性环形孔洞修补流程如下图所示：图27。 【1】Loop分别向Z、X、Y单个方向上投影，计算投影后多边形的面积，当最小面积大于一定阈值时，认为是缺陷孔洞，否则将面积最小的方向即为加工方向。 【2】计算投影后线段间的夹角。理论上，在折回位置，两线段夹角几乎为0。实际模型中，由于设计的不标准或裁剪结果误差，导致该处夹角虽然比较小，但可能不是最小。首先根据两线段向量叉乘方向进行初步的排除，当叉乘方向与加工方向夹角很小时排除。 27. 加工平面孔洞识别与修复流程图 【3】在最小角度的两个位置处，拆开Loop。 【4】采用与环形孔洞补洞方式修复。 注：计算线段间夹角时，当夹角小于一定阈值时，作为折点存入。当折点数小于2时，取夹角最小的两个点作为折点；当折点大于2时，需分割Loop。 加工平面孔洞修复效果如图28。 图28. 加工平面环形孔洞修复示意图 4.5. 简单孔洞修复 通过上述识别，将所有孔洞中的缝隙、错位错误、环形孔洞修复后，剩余的孔洞均作为简单孔洞处理，其修复方法为：图29。 流程介绍： 【1】点拟合平面算法：根据点坐标以及点的重心，构造一个3 × 3的矩阵，使用Jacobi方法计算上述矩阵的特征值和特征向量，特征值的存储顺序是从大到小的，特征向量与特征值对应，取第一个特征向量作为x方向，最小特征值对应的特征向量，作为面法向，右手法则构建局部坐标系。 【2】根据【1】中创建的平面，将边界点投影到平面上。并通过【1】中输出的局部坐标系，将平面上的投影点变换到局部坐标系下。 【3】在局部坐标系下，将孔洞边界点连接成的多边形，进行重新分元。 【4】对分元后的网格模型进行精确整体变形，使其满足一定的连续性条件。 图29. 简单孔洞修复流程