基于 OCCT 保持 Alias 隐藏元素(Wire -> STEP)导入一致性实践

一、问题背景

在 Alias 中,.wire 模型常通过图层控制元素显隐。

当模型导出为 STEP 后,如果在 OCCT 中直接导入,常见问题是:Alias 中已隐藏的元素被重新显示

目标是:在 OCCT 导入 STEP 时,尽可能保持 Alias 原有隐藏状态,避免错误渲染。


二、STEP 中隐藏语义的来源

Alias 导出的 STEP 一般通过以下实体表达"隐藏图层":

  • INVISIBILITY((#...))
    • 这里列出的通常是图层分配实体(layer assignment)的 id。
  • PRESENTATION_LAYER_ASSIGNMENT('id', 'layerName', (#item1,#item2,...))
    • 把几何/表示项分配到具体图层。
    • 如果该图层在 INVISIBILITY 中,则其 item 应视为隐藏。

换句话说:
先找"哪些图层隐藏",再找"这些图层下有哪些 item"。


三、为什么 OCCT 直接导入后还会显示隐藏元素

即使启用 SetLayerMode(true),仍可能出现隐藏元素可见,主要原因:

  • 图层信息并不总是自动转为"最终渲染剔除"。
  • OCCT 在 transfer 时可能把多个 item 合并为 compound。
  • 某些场景下不能只靠 label 过滤,需要同时处理 shape 子项。
  • IdentLabel(ent) 在部分路径下不稳定,需要名称映射兜底。

四、推荐实现方案

1)数据结构先定好(建议)

建议在导入流程里维护以下结构:

  • invisibleItemIds: set<int>
    • STEP 实体 id 级别的"应隐藏"集合。
  • invisibleNames: set<string>
    • invisibleItemIds 反查得到的名称集合,作为兜底。
  • invisibleLabels: TDF_LabelMap
    • XCAF label 级别隐藏集合(O(1) 查询)。
  • invisibleShapes: TopTools_MapOfShape
    • shape 级别隐藏集合(覆盖 compound 子项)。
  • nameToId: map<string, int>
    • 名称到 STEP id 的映射,用于 IdentLabel 失效场景。
  • representationItemListCache: map<int, vector<int>>
    • 缓存 SHAPE_REPRESENTATION/GEOMETRIC_SET 的 item 列表,避免重复解析。

2)文本解析阶段(导入前)

按以下顺序解析 STEP 文本(只构造一次 stepText):

  1. INVISIBILITY -> invisibleLayerIds
  2. PRESENTATION_LAYER_ASSIGNMENT -> invisibleItemIds
  3. 扩展引用(可选但推荐)
    • 例如 SHELL_BASED_SURFACE_MODEL('x',(#openShellId)),把 openShellId 也加入隐藏集合。
  4. 反查名称
    • 根据 invisibleItemIds 解析出 invisibleNames
  5. 快速路径
    • invisibleItemIds 为空,直接关闭后续隐藏逻辑。

实务建议:列表解析时注意 ",(#" 的游标偏移,漏首项会导致关键元素无法隐藏。


3)transfer 阶段(OCCT -> XCAF)

遍历 model->NbEntities(),按实体处理:

  1. 先补全 id(兜底)
    • IdentLabel(ent) == 0 且实体有名称,则用 nameToId 回填。
  2. 取 transfer 结果
    • 通过 Transfer_TransientProcess 找 binder,拿 ShapeResult
  3. 判定该实体是否隐藏
    • isInvisibleById: stepEntityNumber in invisibleItemIds
    • isInvisibleByName: reprName in invisibleNames
  4. 命中隐藏则写入两层索引
    • invisibleLabels.Add(label)(如果能搜索到 label)
    • TopExp::MapShapes(shape, invisibleShapes)(shape + 子形状)
  5. 处理 compound 聚合场景
    • COMPOUND/COMPSOLID,根据 stepEntityNumber 解析 item 列表。
    • 将"列表中命中隐藏 id 的子项 shape"写入 invisibleShapes
    • 该步骤用于解决"上层 representation 合并 transfer,子项丢失独立 label"的问题。

4)构树/渲染前统一过滤(必须双层)

建议统一使用两个判定函数:

  • isLabelInvisible(label)
    • 先按名称判定(invisibleNames
    • 再按 invisibleLabels.Contains(label) 判定
  • isShapeInvisible(shape)
    • 先按 invisibleShapes.Contains(shape) 判定
    • 再按名称 / label 做补充判定(按你项目需要)

parseRootLabelToNode -> parseLabelToNode -> parseShape 全链路都调用,确保:

  • 根节点过滤生效
  • 子节点过滤生效
  • compound 子形状过滤生效

5)伪代码(可直接对照实现)

latex 复制代码
read stepText
read occt model + transfer

invisibleItemIds = parseInvisibilityAndLayerAssignments(stepText)
if invisibleItemIds is empty:
    return buildNodeTreeWithoutVisibilityFilter()

expandInvisibleItemIdsByReferences(stepText, invisibleItemIds)
invisibleNames = parseInvisibleNames(stepText, invisibleItemIds)
nameToId = parseNameToId(stepText)

for each entity in model:
    ensure IdentLabel by nameToId if needed
    shape = transferResult(entity)
    if no shape: continue

    hiddenById = entityId in invisibleItemIds
    hiddenByName = entityName in invisibleNames

    if hiddenById or hiddenByName:
        add label to invisibleLabels
        add shape + subshapes to invisibleShapes

    if shape is compound:
        itemList = getOrCacheRepresentationItemList(entityId)
        map hidden item index -> compound child shape
        add mapped child shape to invisibleShapes

return buildNodeTreeWithFilters(invisibleLabels, invisibleNames, invisibleShapes)

五、性能优化建议(强烈推荐)

1)无 INVISIBILITY 快速路径

如果文件中没有 INVISIBILITY,直接跳过隐藏逻辑(引用扩展、隐藏集合构建、过滤判定等),减少不必要开销。

2)STEP 文本只构建一次

避免在多个解析函数里重复 vector<uint8_t> -> string 拷贝。

3)使用哈希容器做 O(1) 查找

  • Label 集合:TDF_LabelMap
  • Shape 集合:TopTools_MapOfShape

替换线性遍历结构,降低大模型导入成本。

4)缓存 representation item 列表

缓存 entityId -> itemList,避免同一实体反复解析文本。


六、常见坑位(实战高频)

  • 解析 ",(#" 时偏移错误,导致漏掉列表首项(极易漏判隐藏)。
  • 只过滤根 label,不过滤 compound 子形状。
  • 只按 id 过滤,不做 name 兜底。
  • 每次判断都做全量扫描,导致大文件导入变慢明显。

七、验收建议

建议准备 2 组测试:

  1. 有隐藏图层的 STEP
    • 抽查若干已知隐藏元素(例如 cyl_body#82rail_surf#161)是否确实不渲染。
  2. 无隐藏图层的 STEP
    • 验证快速路径是否生效,导入耗时是否明显下降。

八、结论

要在 OCCT 中保持 Alias 隐藏状态,关键不是单点配置,而是完整链路:

  • 正确解析 STEP 隐藏语义(图层 + item);
  • 在 transfer 与渲染构树阶段双重过滤;
  • 用名称兜底提高稳定性;
  • 用快速路径和哈希容器保障性能。

这样可以在复杂 Alias 模型导入时同时做到:

  • 隐藏结果正确
  • 大模型性能可控
相关推荐
Mintopia1 个月前
TrustLink |战略人员招募公告(创始团队首批)
人工智能·掘金技术征文·trae
云舟吖1 个月前
从一行行雕琢到与代码共舞:我的古法开发到 Vibe Coding 跃迁之路
敏捷开发·掘金技术征文·沸点
何贤1 个月前
2026 年程序员自救指南
人工智能·程序员·掘金技术征文
星析互联3 个月前
SWIFT报文难解析?揭秘正则表达式自动化处理方案
运营·掘金技术征文
舒一笑4 个月前
大模型时代的程序员成长悖论:如何在AI辅助下不失去竞争力
后端·程序员·掘金技术征文
舒一笑5 个月前
TorchV知识库安全解决方案:基于智能环境感知的动态权限控制
后端·安全·掘金技术征文
Lei活在当下6 个月前
2025 年再读《人月神话》
敏捷开发·团队管理·掘金技术征文
Hilaku7 个月前
写了8年代码,我发现决定你薪水的,往往不是技术
前端·面试·掘金技术征文
于顾而言1 年前
从0带你开始搭建ebpf开发环境
后端·掘金技术征文