Skip to content

架构总览

@modelcubes/viewer-core 的公开 API 围绕单一入口 Viewer 组织:Viewer.create(canvas) 是唯一的创建方式,功能按域拆给一组只读 manager 属性,状态变化经事件总线对外广播。理解这三件事,就理解了整个引擎的使用方式。

Viewer 单一入口与 manager 分域

Viewer 实例本身只做四件事:创建/销毁(Viewer.create() / dispose())、事件订阅(on / off / once)、尺寸同步(画布 CSS 尺寸变化引擎经 ResizeObserver 自动跟踪,resize() 是宿主显式逃生口)、把能力按域转交给 manager。所有具体功能都经 manager 属性访问:

ts
const viewer = await Viewer.create(canvas);

await viewer.model.load("/fixtures/demo.fmbv"); // 模型域
viewer.camera.fitView(); // 相机域
viewer.edges.setVisible(false); // 边线域

13 个公开 manager 一览:

属性职责
viewer.model模型加载 / 卸载、结构树查询与节点级外观控制(颜色 / 可见性 / 高亮)。
viewer.camera相机位姿、标准视图、取景适配(zoom-to-fit)与交互控制。
viewer.selection点击 / 框选 / 程序化选中与 hover 高亮。
viewer.edges全局边线显示开关、颜色与不透明度。
viewer.renderMode全局与按节点的渲染模式(实色线框 / 线框 / 实色 / 消隐)。
viewer.lights场景光源的增删与强度调整。
viewer.stats加载与渲染统计快照(fps / 帧时 / 分块进度等)。
viewer.navcube画布角落导航立方体的开关 / 停靠 / 尺寸。
viewer.background画布背景(纯色 / 渐变 / 图片 / 透明)。
viewer.export矢量 SVG 工程图导出(消隐线条)。
viewer.explode零件爆炸(散开 / 锁定 / 动画)。
viewer.section剖切 section 与盖面 / gizmo 交互。
viewer.quality渲染质量(抗锯齿 / AO / 色调映射 / 质量档)。

此外还有一个 viewer.diagnostics(LOD 等调试诊断查询),属实验性 API,面向内部排障,可能在小版本间变动,外部集成请勿依赖。

manager 都由 Viewer 在构造时装配好,不要自行 new;viewer.dispose() 之后再调用任何 manager 方法会抛 ViewerError(code 为 Disposed)。

事件总线

引擎到应用方向的状态通知全部走事件:viewer.on(event, handler) 订阅,返回一个退订函数;once 只触发一次;off 需要传入与订阅时相同的 handler 引用。

ts
// 推荐:保存 on() 返回的退订函数,清理时直接调用
const unsubscribe = viewer.on("selection-changed", (e) => {
  console.log("当前选中", e.current.length, "项");
});

// 不再需要时
unsubscribe();

事件清单与各事件 payload 见事件系统

底层渲染实现完全隐藏

viewer-core 的公开 API 不暴露任何底层渲染实现的类型:坐标用纯数据对象 Vec3 / Box3,矩阵用列主序 Float32Array,颜色用 { r, g, b, a }。这是有意的设计边界——

  • 你的集成代码不需要(也不应该)依赖引擎的底层渲染实现,渲染内核将来升级或演进不会破坏你的集成;
  • 不要试图访问 viewer 的内部对象(场景图、renderer 等),内部结构不属于兼容性承诺,任何版本都可能变。

需要的能力如果公开 API 没有覆盖,提需求而不是绕过公开 API。

渲染循环

Viewer.create() resolve 时渲染循环已经启动:由 requestAnimationFrame 驱动持续运行,每帧更新相机、流式几何与 LOD 并渲染。集成方不需要(也没有 API)手动触发渲染——相机交互、加载进展、外观修改的效果都会在下一帧自动呈现。

引擎以 render 事件作为约每秒一次的心跳,payload 中 fps 是该区间的平均帧率、frameMs 是最近一帧的渲染耗时,适合驱动状态栏一类的低频 UI;更完整的统计快照经 viewer.stats 查询。

下一步