Skip to content

模型数据 (.fmbv)

.fmbv 是什么

.fmbv 是 FMB 的流式可视化格式:一个二进制文件内含结构树骨架(装配层级 + 节点索引)、分块的几何数据(按 LOD 组织,可按需逐块拉取)、BREP(精确几何)边线与节点业务属性。文件布局为流式读取设计——viewer 先取骨架立即可交互,几何分块随后渐进到达。本页只讲集成视角;二进制布局不属于公开 API。

数据从哪来

.fmbv 文件由你的数据供应方 / 上游数据管线提供,通常是从 CATIA、Creo 等原生 CAD 格式离线转换而来。viewer 自身不做格式转换,本文档也不覆盖转换工具。

上手练习可下载本站示例模型:demo.fmbv(约 230 KB)。

加载方式:ModelSource 五种形态

viewer.model.load(source) 接受 ModelSource,共五种形态:

1. string — URL 字符串(最常用):

ts
await viewer.model.load("/fixtures/demo.fmbv");

2. URL 对象:

ts
await viewer.model.load(new URL("https://cdn.example.com/models/demo.fmbv"));

3. Uint8Array — 内存字节(字节已自行下载或从文件读入时):

ts
const resp = await fetch("/fixtures/demo.fmbv");
await viewer.model.load(new Uint8Array(await resp.arrayBuffer()));

4. Blob(如 <input type="file"> 选中的文件):

ts
const file = input.files![0]; // File 是 Blob 的子类
await viewer.model.load(file);

5. { fetch: RangeFetcher; size: number } — 自定义 Range fetcher:fetch 按字节区间 [start, end) 返回该段数据,size 是文件总字节数。适用于大模型按需 Range 拉取——几何分块只在需要时取回,不必整文件下载:

ts
await viewer.model.load({
  size: totalBytes,
  fetch: async ({ start, end }) => {
    const resp = await fetch(url, { headers: { Range: `bytes=${start}-${end - 1}` } });
    return new Uint8Array(await resp.arrayBuffer());
  },
});

URL 形态(string / URL)内部同样走 HTTP Range 流式拉取;Uint8Array / Blob 则全量在内存中按区间切片。

load() 之后发生什么——骨架先就绪(Promise 在此 resolve)、几何分块后台渐进到达——完整事件时序见事件系统

常见错误

加载失败时 load() 的 Promise 会 reject 一个带 codeViewerError,用 try/catch 处理:

场景code说明
传入的 source 不是五种形态之一InvalidModelSource例如传了 null 或缺 size 的对象。
URL 请求失败(404 / 网络错误)NetworkFailed底层原因挂在 error.cause 上。
数据不是合法的 .fmbv(magic / 头校验失败)NetworkFailed底层解析错误同样包装为 NetworkFailed,详情见 error.cause
加载中途被新的 load() / 卸载取代Cancelled旧 Promise 以此 reject,属正常流程。
ts
import { ViewerError } from "@modelcubes/viewer-core";

try {
  await viewer.model.load(url);
} catch (e) {
  if (e instanceof ViewerError) console.error("加载失败:", e.code, e.message);
}

注意:加载错误只经 Promise reject 传递。事件清单里的 model-error 是预留通道,当前版本没有发射点,不要依赖它做错误处理。