furniture-3d-system-Wu/furniture-3d-system/docs/solutions/workflow-issues/CAD插件装配语义导出改造说明-20260325.md
WuYongJie 5821d73291 初始提交:3D家具安装展示系统
包含:
- furniture-3d-system:Next.js 16 全栈应用(资产中心、产品管理、3D装配动画)
- autocad-plugin:AutoCAD 家具导出插件源码
- 资产中心改造:编辑弹窗化、删除功能、Toast反馈、自定义Select组件

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-02 14:00:19 +08:00

13 KiB
Raw Blame History

CAD 插件装配语义导出改造说明(2026-03-25)

目标

本次任务的目标,不是优化爆炸图表现,而是改造 CAD 插件的导出能力,让导出数据可以支撑“真实安装方向”的自动化安装动画。

要解决的问题是:

  • 当前爆炸图使用“从模型中心向外的球形爆炸”。
  • 这个展示逻辑本身没问题。
  • 真正的问题在于:安装步骤还原时,错误复用了爆炸方向。
  • 结果是,本应沿固定轴插入、垂直装配、或从上往下压装的板件,被错误地做成了沿斜向飞回去。

本次必须按根因修复处理,不能继续在展示方向上打补丁。


根因结论

当前系统把两类完全不同的语义混在了一起:

  1. 展示语义:为了让模型更容易看清,各零件从模型中心向外散开。
  2. 安装语义:零件在真实装配中应该沿哪个方向进入、从哪里进入、依赖谁先装。

现在缺的不是“更复杂的爆炸算法”,而是“独立的装配语义数据层”。

一句话概括:

展示方向 和 安装方向 必须彻底分开。


当前现状确认

在动手前,先确认下面这些事实成立:

插件侧现状

插件源码目录:

D:\AI Code\3danzhuang\autocad-plugin\FurnitureExporter

插件发布目录:

D:\AI Code\3danzhuang\autocad-plugin\dist\家具导出插件-v2.3.1-一键安装版

插件当前已经能导出这些核心数据:

  • panels
  • holes
  • holeGroups
  • hardwareTypes
  • hardwareSummary

插件当前已具备的基础能力包括:

  • 板件位置、尺寸、法向、包围盒提取
  • 板件类型推断
  • 孔位检测与用途推断
  • 逻辑孔组
  • 五金实例与板件、孔位、孔组的绑定关系

但插件当前还没有显式导出这些数据:

  • 板件真实安装方向
  • 安装方式
  • 板件与板件的配合面关系
  • 起装偏移和装配行程
  • 板件装配依赖关系

主项目侧现状

主项目目录:

D:\AI Code\3danzhuang\furniture-3d-system

当前与问题强相关的文件:

  • D:\AI Code\3danzhuang\furniture-3d-system\src\lib\sku-cad-data.ts
  • D:\AI Code\3danzhuang\furniture-3d-system\src\lib\assembly-generator.ts
  • D:\AI Code\3danzhuang\furniture-3d-system\src\components\assembly\AssemblyAnimationPlayer.tsx
  • D:\AI Code\3danzhuang\furniture-3d-system\src\lib\3d\engine.ts
  • D:\AI Code\3danzhuang\furniture-3d-system\src\lib\3d\explosion-math.ts

当前主项目实际上只消费了这类信息:

  • panelType
  • explosionDirection
  • cadPosition
  • cadNormal
  • cadBoundingBox

当前主项目没有真正保存这类安装语义:

  • assemblyAxis
  • installDirection
  • mountMode
  • preAssembleOffset
  • travelDistance
  • dependsOn
  • mates

当前播放层的板件动画仍然属于演示级飞入,不是真实装配路径。


本次修改边界

优先级

  1. 优先改 CAD 插件导出层。
  2. 如有必要,只做最小范围的主项目类型补充和解析补充。
  3. 不要先大改前端播放逻辑。

明确禁止

  • 不要把“真实安装方向”继续塞进 explosionDirection。
  • 不要删除、重命名、破坏现有导出字段。
  • 不要为了追求快速可见效果,写死某几类板件的方向当成通用方案。
  • 不要把问题继续做成“根据 panelType 猜一个方向”的补丁式方案。

必须实现的结果

插件需要额外导出一层“装配语义数据”,至少要回答下面这些问题:

  • 这块板最终沿哪个方向装进去?
  • 它是平移插入、下压就位,还是旋转后就位?
  • 它依赖哪些板先装?
  • 它最终和哪块板的哪一面贴合?
  • 动画起点应该从目标位往哪个方向退多远?
  • 这次自动推导的结果置信度是多少?

目标不是一上来做到所有复杂场景全覆盖,而是:

  • 对大多数标准柜体板件自动推导正确方向
  • 对异常件保留清晰兜底
  • 保持向后兼容

推荐的数据结构

建议在现有 hardware.json 根对象中新增一个可选字段:

assembly

不要破坏任何已有字段。

ExportData 新增字段

public AssemblyData? Assembly { get; set; }

AssemblyData 建议结构

{
  "assembly": {
    "version": "1.0",
    "panelAssemblies": [],
    "connections": []
  }
}

PanelAssemblyInfo 最少字段

  • panelId
  • mountMode
  • assemblyAxis
  • assemblyDirection
  • preAssembleOffset
  • travelDistance
  • dependsOn
  • primarySupportPanelId
  • targetPanelIds
  • mates
  • confidence
  • warnings
  • autoGenerated

推荐语义

mountMode

至少支持:

  • slide_in
  • drop_in
  • rotate_into_place
  • unknown

assemblyAxis

长度为 3 的单位向量,例如:

[1, 0, 0]

assemblyDirection

离散标签,例如:

  • +X
  • -X
  • +Y
  • -Y
  • +Z
  • -Z

preAssembleOffset

从最终安装位往外退的偏移向量,单位 mm。

travelDistance

沿安装方向需要走的距离,单位 mm。

AssemblyMateInfo 最少字段

  • targetPanelId
  • selfFace
  • targetFace
  • connectionType
  • confidence

可选增强字段

如果你判断后续会用到,可以增加:

  • rotationAxis
  • pivotPoint
  • inferenceReason

推导逻辑要求

总原则

严禁再使用“模型中心到板中心”的方向来推安装方向。

真实安装方向必须优先从以下两类信息中推导:

  1. 连接关系
  2. 配合关系

优先级

第一优先级:孔位、孔组、五金绑定

如果一块板与另一块板之间存在明显的孔组配对、连接件绑定、木榫、三合一、偏心件等关系,则安装方向优先由这些连接关系推导。

要求:

  • 优先使用孔轴线、孔法向、孔组法向判断推进方向。
  • 若连接关系明显指向某一主轴,则该方向优先于 panel.normal。
  • panel.normal 只能视为板厚方向参考,不能直接当安装方向。

第二优先级:板件配合面

通过板件的 boundingBox 与 position,寻找相邻板件和配合面关系。

要求:

  • 找出哪两个轴重叠明显、哪一个轴面距最小。
  • 明确导出 selfFace 和 targetFace。
  • 安装方向应取“朝向配合面的反向推进”。

第三优先级:板件类型和空间位置兜底

当连接关系不够强时,再使用以下信息兜底:

  • panelType
  • 板件在整体空间中的位置
  • 是否位于顶部、底部、侧边、中间层

这部分只能做兜底,不能成为主逻辑。


建议的判定规则

建议把这些常量集中管理,不要散落在多个文件里:

FACE_GAP_TOLERANCE_MM = 3
FACE_OVERLAP_RATIO_MIN = 0.25
HOLE_ASSOCIATION_TOLERANCE_MM = 5
OUTSIDE_MARGIN_MM = 30
MIN_PREASSEMBLE_DISTANCE_MM = 80

相邻板候选判定

建议规则:

  • 两块板在两个轴上的投影重叠比例大于等于 0.25
  • 在剩余一个轴上的最近面间距小于等于 3 mm
  • 满足后,视为存在面接触候选

配合面识别

建议规则:

  • 若最近面在 X 轴方向,则候选面为 left / right
  • 若最近面在 Y 轴方向,则候选面为 front / back
  • 若最近面在 Z 轴方向,则候选面为 top / bottom

注意:

  • selfFace 和 targetFace 都要导出
  • 不要只导一个方向标签

安装方向识别

建议规则:

  • 有明确孔组或连接件时,优先取孔轴线或连接件主方向
  • 有明确配合面时,取“指向配合面的反方向推进”
  • 无强连接时,再用 panelType 兜底
  • 严禁直接使用“模型中心 -> 板中心”

MountMode 判定

V1 先覆盖大多数标准柜体板件,不要过度设计。

建议规则:

  • assemblyAxis 近似 X 或 Y 主轴,优先判为 slide_in
  • assemblyAxis 近似 Z 主轴,且板件明显从上往下落位,优先判为 drop_in
  • 若单轴平移无法解释主要配合关系,再考虑 rotate_into_place
  • V1 对 rotate_into_place 要谨慎输出,宁可少判,不要乱判
  • 无法高置信推断时,输出 unknown,并给出 warnings

DependsOn 推导

建议规则:

  • 与当前板存在主要配合或支撑关系的板,进入 dependsOn
  • primarySupportPanelId 选主要承载或主要配合对象
  • targetPanelIds 保存所有主要装配目标板

本轮不要求做绝对完美的全局装配排序,但至少要导出局部依赖关系。

PreAssembleOffset 与 TravelDistance

严禁直接写死固定值。

建议规则:

  1. 取当前板的目标包围盒
  2. 取 dependsOn 或 targetPanelIds 对应参考板的合并包围盒
  3. 沿 assemblyAxis 的反方向,将当前板虚拟退到“完全脱离参考包围盒 + 30 mm 安全边距”的位置
  4. 该退出来的向量即为 preAssembleOffset
  5. 该向量长度即为 travelDistance
  6. 若结果过小,则至少保证 80 mm 的最小预装距离

覆盖与兜底机制

目标是最大化自动化,但不要假设所有模型都能 100% 自动判断。

必须预留人工覆盖机制,但默认不要求设计师参与。

原则:

  • 没有覆盖标记时,插件必须全自动运行
  • 有覆盖标记时,以覆盖结果为准
  • 被覆盖的结果也必须写回导出 JSON
  • 被覆盖的结果必须标记 autoGenerated = false

推荐支持的覆盖字段:

  • AssemblyDirectionOverride
  • MountModeOverride
  • DependsOnOverride
  • PreAssembleOffsetOverride

覆盖承载方式可自行选择一种稳定方案,例如:

  • 图层命名约定
  • 块属性
  • XData
  • Extension Dictionary

实现建议

建议新增独立分析器,不要把全部逻辑硬塞进现有 PanelAnalyzer。

推荐结构:

  • AssemblySemanticAnalyzer.cs
  • AssemblyInferenceHelpers.cs
  • BoundingBoxMath.cs
  • FaceRelationHelper.cs

最低建议是新增:

  • AssemblySemanticAnalyzer.cs

建议输入:

  • List<PanelInfo> panels
  • List<HoleInfo> holes
  • List<HoleGroupInfo> holeGroups
  • List<HardwareType> hardwareTypes

建议输出:

  • AssemblyData

导出链路建议:

  1. 先按现有流程完成几何与五金数据导出
  2. 再执行装配语义分析
  3. 将结果挂到 ExportData.Assembly
  4. 最终仍输出到同一个 hardware.json

主项目侧的最小改动原则

如果为了验证新导出结构,需要顺带让主项目先能读取这些字段,只做最小必要改动:

  • 更新 sku-cad-data.ts 的类型定义
  • 增加 assembly 字段的解析与归一化
  • 使用可选字段保证旧数据不报错

这次不要优先做:

  • 大改 assembly-generator.ts
  • 大改 AssemblyAnimationPlayer.tsx
  • 把临时规则直接写死进播放器

本次主战场是插件导出层,不是前端动画层。


向后兼容要求

必须满足以下兼容条件:

  • 原有 panels / holes / holeGroups / hardwareTypes / hardwareSummary 不破坏
  • 原有导出样例仍能导出成功
  • 新增字段为空时,不影响旧链路
  • 老版本 hardware.json 没有 assembly 字段时,主项目仍可读取旧数据
  • 如果补了主项目类型定义,必须使用可选字段处理

验证要求

必须使用这个样例做最小必要验证:

D:\AI Code\3danzhuang\素材\BJ0124(1)_export.zip

验证至少包括:

  1. 解压并检查当前 hardware.json
  2. 修改插件后,重新生成或模拟生成新的导出结构
  3. 确认新增 assembly 字段结构完整
  4. 至少输出每个 panel 的以下结果:
    • panelId
    • mountMode
    • assemblyDirection
    • dependsOn 数量
    • travelDistance
    • confidence
  5. 对明显标准板件,确认安装方向不是“从模型中心往回飞”的结果
  6. 明确哪些板件属于高置信自动推导,哪些属于兜底推导

如果当前样例缺少真实五金实例,必须明确写出:

  • 本轮验证主要覆盖板件装配语义
  • 五金参与的复杂装配仍需后续拿带真实五金实例的样例继续验证

不能假装已经完整验证复杂五金场景。


验收标准

只有同时满足以下条件,才算本次任务完成:

  1. 插件可以额外导出装配语义,而不只有几何数据
  2. 真实安装方向不再依赖球形爆炸方向
  3. 安装方向优先基于连接关系和配合面推导
  4. 对大多数标准柜体板件,能自动给出合理的 slide_in / drop_in 方向
  5. 导出结果保留置信度和警告信息
  6. 对异常件具备兜底能力
  7. 对现有结构保持向后兼容
  8. 做了最小但有效的验证,而不是只改代码不验证

交付要求

完成后请按下面顺序汇报:

  1. 改了什么
  2. 验证结果是什么
  3. 还剩什么风险
  4. 哪些场景已经覆盖
  5. 哪些场景还需要更多样例验证
  6. 是否改动了主项目消费层
  7. 是否生成了新的插件产物

除非明确要求,不要主动 commit。


一句最终提醒

这次要解决的是“安装语义缺失”,不是“爆炸动画不够漂亮”。

不要把问题做成:

  • 继续强化 explosionDirection
  • 继续按 panelType 猜方向
  • 在前端播放器里堆临时特判

必须把“展示方向”和“安装方向”彻底分层。