📖 功能概述
该组件通过"原始截面→SuperExtrude扫掠→布尔差运算"的链路重建型材的纯净实体。与Unhole(去孔)的名称一致,它的核心目的是:
- 去除所有开孔:包括圆孔、沉头孔、机丝孔等——这些是型材被添加的孔洞特征,重建时完全去除。
- 控制铣切特征:通过右键菜单切换"保留铣切"或"去除铣切"模式,决定端部切割体和内部切割体是否保留。
该组件使用 ButtonComponent(双状态按钮),提供两个输入参数。布尔输入控制是否执行重建,右键按钮控制铣切处理模式。
🧠 核心算法详解
一、属性校验与降级
检查型材物件的UserDictionary是否包含以下五个必需键名:
拉伸-路径 · 拉伸-截面 · 起端切面 · 终端切面 · 内部切割体
如果缺少任意一项,组件不报错,而是直接输出原物件并给出Remark提示"当前物件不包含LK系统属性,输出原物件"。
这与其他组件(如BrepLength、LKExportStp)直接报错的方式不同——UnholeBrep采用了更宽容的降级策略。
二、截面扫掠重建(SuperExtrude)
1 读取 拉伸-截面(Brep)和 拉伸-路径(Curve)
2 将截面Brep包装为 IGH_GeometricGoo
3 使用 SuperExtrude 将截面沿路径扫掠
→ 生成的是完整截面形状沿路径的实体
→ 这个实体保留了截面的所有细节(包括可能有的内部腔体)
→ 但它没有任何开孔特征,因为这些孔是后期添加的,不在原始截面中
关键区别:与ProfileBox使用截面外矩形进行扫掠不同,UnholeBrep使用原始截面本身进行扫掠,所以保留了截面内部的腔体结构,但去除了后期添加的孔洞。
三、铣切处理(双模式)
通过右键菜单按钮切换:保留铣切 / 去除铣切
模式一:保留铣切(btnState1 = true 或布尔输入触发)
在此模式下,除了起端切面和终端切面之外,还会将内部切割体列表中的所有Brep一并加入布尔切割工具集:
1 读取 内部切割体(ArchivableDictionary),转换为List<Brep>
2 将内部切割体Brep加入切割工具列表 qts(与起端切面、终端切面一起)
3 对扫掠实体执行 BrepBooleanDifference.Execute,用完整的切割工具集做布尔差
→ 结果保留了端部铣切的造型和内部切割体的造型
模式二:去除铣切(btnState1 = false 且布尔输入未触发)
在此模式下,切割工具仅包含起端切面和终端切面两个Brep:
1 切割工具列表 = {起端切面, 终端切面}
2 对扫掠实体执行布尔差运算
→ 结果只做了端部切割,内部切割体的铣切造型也被去除
→ 型材的内部是"完整的原始截面扫掠体",没有任何铣切痕迹
模式的触发逻辑:
• saveIncut || btnState1(布尔输入为True 或 按钮状态为"保留铣切")→ 保留内部切割体
• 两者都不满足 → 去除内部切割体
四、布尔差运算
使用 BrepBooleanDifference.Execute(扫掠体, 切割工具列表, 容差) 执行布尔差运算:
• 扫掠体 - (切割体1 ∪ 切割体2 ∪ ...) = 最终型材
• 切割工具列表中的每个Brep从扫掠体中减去
• 容差使用 RhinoDoc.ActiveDoc.ModelAbsoluteTolerance(当前文档的绝对容差)
• 取运算结果的 ResultBreps.FirstOrDefault() 作为最终输出
注意:这里使用 Execute 静态方法(而非类的实例方法),直接在一个调用中完成多Brep的布尔差运算。
⚙️ 完整执行流程
1. 数据获取:读取型材Brep和布尔触发信号。Brep为空则退出。
2. 属性检查:检查五个必需属性。缺失任意一个→输出原物件+Remark提示,结束。
3. 属性提取:读取拉伸-路径、拉伸-截面、起端切面、终端切面、内部切割体。
4. 铣切模式判定:
• 如果 saveIncut || btnState1(布尔输入True 或 按钮状态为保留铣切)
→ 从内部切割体属性中解析所有Brep,加入切割工具列表
• 否则
→ 切割工具列表仅包含起端切面和终端切面
5. SuperExtrude扫掠:截面沿路径扫掠生成纯净实体。
6. BooleanDifference:扫掠体与切割工具列表做布尔差运算。
7. 结果输出:取运算结果的第一个(或唯一一个)Brep输出。