Files
bim_engine/docs/外部API总览.md
2026-04-24 11:16:37 +08:00

15 KiB
Raw Blame History

iflow-engine 外部 API第三方接入

1) 获取构件树 getConstructTreeData()

所属模块

  • 调用入口:bimEngine.engine
  • 源码位置:src/managers/engine-manager.ts

方法签名

getConstructTreeData(): {
  level: EngineModelData[];
  type: EngineModelData[];
  major: EngineModelData[];
}

入参

  • 无入参。

返回值

  • 返回一个对象,包含三类构件树:
    • level: 楼层树
    • type: 类型树
    • major: 专业树
type EngineTreeNode = {
  name?: string;
  id?: string | null;
  ids?: string[] | null;
  children?: EngineTreeNode[] | null;
  isLeaf?: boolean;
};

type EngineModelData = {
  name?: string;
  url: string;
  children?: EngineTreeNode[] | null;
};

行为约定

  • 当 3D 引擎未初始化(engine.initialize(...) 未成功)时,返回:
{ level: [], type: [], major: [] }

调用示例

const treeData = bimEngine.engine?.getConstructTreeData();

if (treeData) {
  console.log('level tree:', treeData.level);
  console.log('type tree:', treeData.type);
  console.log('major tree:', treeData.major);
}

2) 获取构件信息 getComponentProperties(url, id, callback)

所属模块

  • 调用入口:bimEngine.engine
  • 源码位置:src/managers/engine-manager.ts

方法签名

getComponentProperties(url: string, id: string, callback: (data: any) => void): void

入参

  • url: string:构件所属模型 URL
  • id: string:构件 ID
  • callback: (data: any) => void:异步回调,返回构件属性

调用示例

bimEngine.engine?.getComponentProperties(modelUrl, componentId, (data) => {
  console.log('component properties:', data);
});

3) 高亮指定构件 highlightModel(models)

所属模块

  • 调用入口:bimEngine.engine?.getEngineComponent()
  • 源码位置:src/components/engine/index.ts

方法签名

highlightModel(models: { url: string; ids: number[] }[]): void

入参

  • models:构件列表(可批量)
    • url: string:模型 URL
    • ids: number[]:要高亮的构件 ID 数组

调用示例

bimEngine.engine?.getEngineComponent()?.highlightModel([
  { url: modelUrl, ids: [350518] }
]);

4) 剖切指定构件(推荐流程)

当前引擎提供的是“剖切盒适配已高亮构件”的能力,推荐按两步调用:

  1. 先高亮目标构件:highlightModel(...)
  2. 再执行剖切盒适配:fitSectionBoxToModel()

方法签名

fitSectionBoxToModel(): void

调用示例

const engineComp = bimEngine.engine?.getEngineComponent();

engineComp?.highlightModel([{ url: modelUrl, ids: [350518] }]);
engineComp?.fitSectionBoxToModel();

5) 隐藏其他构件 isolateModels(models)

所属模块

  • 调用入口:bimEngine.engine?.getEngineComponent()
  • 源码位置:src/components/engine/index.ts

方法签名

isolateModels(models: { url: string; ids: number[] }[]): void

入参

  • models:要保留显示的构件(其他构件将隐藏)

调用示例

bimEngine.engine?.getEngineComponent()?.isolateModels([
  { url: modelUrl, ids: [350518] }
]);

6) 启动一键编码 startOneClickEncoding()

所属模块

  • 调用入口:bimEngine.engine?.getEngineComponent()
  • 源码位置:src/components/engine/index.ts

方法签名

startOneClickEncoding(): void

入参

  • 无入参。

行为约定

  • 调用前建议先订阅 encoding:startencoding:completeencoding:error 事件以获取编码进度和结果。
  • 若引擎未初始化或底层 oneClickEncoding 模块不可用,会在控制台输出警告并静默返回。
  • 多次调用将重复触发编码流程(底层行为由 iflow-engine-base 决定)。

调用示例

const engineComp = bimEngine.engine?.getEngineComponent();

// 订阅编码事件
bimEngine.on('encoding:start', (data) => {
  console.log('编码开始', data);
});
bimEngine.on('encoding:complete', (data) => {
  console.log('编码完成', data);
});
bimEngine.on('encoding:error', (data) => {
  console.log('编码失败', data);
});

// 启动编码
engineComp?.startOneClickEncoding();

// 需要时取消订阅
// unsubStart();
// unsubComplete();
// unsubError();

10) 视图控制(主视图保存/恢复)

所属模块

  • 调用入口:bimEngine.engine?.getEngineComponent()
  • 事件总线:bimEngine(通过 ManagerRegistry 桥接)
  • 源码位置:src/components/engine/index.ts

方法签名

// 保存主视图
saveMainView(): any

// 恢复主视图(重置)
restoreMainView(): void

// 设置主视图(传入缓存数据)
setMainViewPort(viewData: any): void

事件列表

事件名 触发时机 payload
view:main-view-saved 用户点击"将当前视图设为主视图"后 { viewData: any }
view:main-view-restored 用户点击"重置主视图"后 {}

行为约定

  • saveMainView():调用底层 viewCube.saveMainViewPort() 获取视点数据,并触发 view:main-view-saved 事件。
  • restoreMainView():调用底层 viewCube.resetMainViewPort() 恢复默认主视图,并触发 view:main-view-restored 事件。
  • setMainViewPort(viewData):调用底层 viewCube.setMainViewPort(viewData) 恢复指定视点,不触发事件(用于程序初始化时恢复缓存)。
  • 所有事件经 Engine 组件桥接后冒泡到 bimEngine 事件总线。
  • 订阅方式与 SDK 其他事件一致:使用 bimEngine.on(event, handler),返回的函数可用于取消订阅。

调用示例

const engineComp = bimEngine.engine?.getEngineComponent();

// 1. 保存主视图(用户操作触发)
engineComp?.saveMainView();

// 2. 监听保存事件,持久化到 localStorage
const unsubSaved = bimEngine.on('view:main-view-saved', ({ viewData }) => {
  console.log('主视图已保存:', viewData);
  localStorage.setItem('mainView', JSON.stringify(viewData));
});

// 3. 监听重置事件,清理缓存
const unsubRestored = bimEngine.on('view:main-view-restored', () => {
  console.log('主视图已重置');
  localStorage.removeItem('mainView');
});

// 4. 模型加载完成后,自动恢复缓存的主视图
bimEngine.on('engine:model-loading-completed', () => {
  const cached = localStorage.getItem('mainView');
  if (cached) {
    engineComp?.setMainViewPort(JSON.parse(cached));
  }
});

// 需要时取消订阅
// unsubSaved();
// unsubRestored();

7) 检查模型编码 hasModelCode()

所属模块

  • 调用入口:bimEngine.engine?.getEngineComponent()
  • 源码位置:src/components/engine/index.ts

方法签名

hasModelCode(): boolean

入参

  • 无入参。

返回值

  • true:所有已加载模型均已存在编码数据。
  • false:至少有一个模型没有编码数据,或引擎未初始化、oneClickEncoding 模块不可用。

行为约定

  • 遍历当前 engine.models 数组,对每个模型调用底层 oneClickEncoding.exitModelCode(url)
  • 仅当所有模型的返回值为 true 时,才返回 true
  • 若当前没有加载任何模型,返回 false

调用示例

const hasCode = bimEngine.engine?.getEngineComponent()?.hasModelCode();
console.log('模型是否已编码:', hasCode);

8) 读取缓存编码 readModelCodeFormStoge()

所属模块

  • 调用入口:bimEngine.engine?.getEngineComponent()
  • 源码位置:src/components/engine/index.ts

方法签名

readModelCodeFormStoge(): void

入参

  • 无入参。

行为约定

  • 遍历当前 engine.models 数组,对每个模型调用底层 oneClickEncoding.readModelCodeFormStoge(url)
  • 若引擎未初始化或底层模块不可用,会在控制台输出警告并静默返回。
  • 无返回值,仅触发读取动作。

调用示例

bimEngine.engine?.getEngineComponent()?.readModelCodeFormStoge();

9) 一键编码事件

所属模块

  • 事件总线:bimEngine(通过 ManagerRegistry 桥接)
  • 源码位置:src/components/engine/index.ts

事件列表

事件名 触发时机 payload
encoding:start 编码流程开始时 { data?: any }
encoding:complete 编码流程成功完成时 { data?: any }
encoding:error 编码流程失败时 { data?: any }

行为约定

  • 事件由底层 oneClickEncoding 模块触发,经 Engine 组件桥接后冒泡到 bimEngine 事件总线。
  • 订阅方式与 SDK 其他事件一致:使用 bimEngine.on(event, handler),返回的函数可用于取消订阅。
  • 建议在调用 startOneClickEncoding() 之前完成事件订阅,避免漏掉 encoding:start 事件。

调用示例

const unsubStart = bimEngine.on('encoding:start', (data) => {
  console.log('编码开始', data);
});

const unsubComplete = bimEngine.on('encoding:complete', (data) => {
  console.log('编码完成', data);
});

const unsubError = bimEngine.on('encoding:error', (data) => {
  console.log('编码失败', data);
});

// 启动编码
bimEngine.engine?.getEngineComponent()?.startOneClickEncoding();

// 需要时取消订阅
// unsubStart();
// unsubComplete();
// unsubError();

11) 图钉DrawingPin管理

所属模块

  • 调用入口:bimEngine.engine?.getEngineComponent() / bimEngine.emit() / bimEngine.on()
  • 源码位置:src/components/engine/index.tssrc/components/component-tree-drawer/pin-tab.ts
  • 初始化要求:需先调用 bimEngine.initConstructTreeBtn() 初始化构件树面板

概述

图钉功能用于保存和展示 3D 视图中的相机视角,支持文件夹分组管理。外部系统完全掌控图钉的创建、编辑、删除和持久化SDK 仅负责渲染展示。

对接方式:

  • 批量传入配置setPinRecords() 一次性设置完整图钉列表
  • 增删改:通过 bimEngine.emit() 发送 drawingPin:create|update|delete 事件
  • 监听变更:订阅 drawingPin:list-updated 获取用户操作后的最新列表

数据类型

interface DrawingPinRecord {
  id: string;                    // 唯一标识(外部生成)
  parentId?: string | null;      // 父文件夹 IDnull/undefined 表示根节点
  name: string;                  // 显示名称
  type: 'pin' | 'folder';        // 类型:图钉 或 文件夹
  seq: number;                   // 排序序号(同级内排序)
  data?: any;                    // 视角数据(仅 type='pin' 时有值,由外部系统生成)
}

API 列表

A. 批量传入图钉配置

bimEngine.engine?.getEngineComponent()?.setPinRecords(
  records: DrawingPinRecord[]
): void
  • 作用外部一次性传入完整图钉列表平铺结构SDK 内部自动构建树形层级。
  • 场景:初始化时从后端/缓存加载已有图钉配置。
  • 注意:会触发 drawingPin:list-updated 事件。

B. 创建 / 更新 / 删除(事件接口)

外部通过 bimEngine.emit() 向 SDK 发送操作指令:

事件 payload 说明
drawingPin:create { record: DrawingPinRecord } 创建图钉或文件夹
drawingPin:update { id: string; patch: Partial<Pick<DrawingPinRecord, 'name' | 'parentId' | 'seq' | 'data'>> } 编辑图钉/文件夹
drawingPin:delete { id: string } 删除图钉或文件夹

C. 监听列表变更

事件 方向 payload 说明
drawingPin:list-updated SDK → 外部 { records: DrawingPinRecord[] } 列表发生任何变更时触发(含用户界面操作)

调用示例

1. 初始化时批量传入图钉配置

const engineComp = bimEngine.engine?.getEngineComponent();

// 从后端获取已有配置
const pinRecords: DrawingPinRecord[] = [
  {
    id: 'folder_001',
    parentId: null,
    name: '一层图钉',
    type: 'folder',
    seq: 0,
  },
  {
    id: 'pin_001',
    parentId: 'folder_001',
    name: '入口视角',
    type: 'pin',
    seq: 0,
    data: { /* 外部系统保存的视角数据 */ },
  },
  {
    id: 'pin_002',
    parentId: 'folder_001',
    name: '大厅视角',
    type: 'pin',
    seq: 1,
    data: { /* 外部系统保存的视角数据 */ },
  },
];

// 一次性传入
engineComp?.setPinRecords(pinRecords);

2. 创建图钉(外部生成视角数据)

// 外部系统自行生成视角数据
const viewData = { /* 外部系统生成的视角数据 */ };

const record: DrawingPinRecord = {
  id: `pin_${Date.now()}`,
  parentId: null,           // 或指定文件夹 ID实现分组
  name: '新图钉',
  type: 'pin',
  seq: 0,
  data: viewData,
};

bimEngine.emit('drawingPin:create', { record });

3. 创建文件夹

const record: DrawingPinRecord = {
  id: `folder_${Date.now()}`,
  parentId: null,             // 或指定父文件夹 ID实现嵌套
  name: '新文件夹',
  type: 'folder',
  seq: 0,
};

bimEngine.emit('drawingPin:create', { record });

4. 编辑(重命名 / 移动分组 / 调序)

// 重命名
bimEngine.emit('drawingPin:update', {
  id: 'pin_001',
  patch: { name: '入口视角(已更新)' },
});

// 移动到另一个文件夹
bimEngine.emit('drawingPin:update', {
  id: 'pin_001',
  patch: { parentId: 'folder_002' },
});

// 调整排序
bimEngine.emit('drawingPin:update', {
  id: 'pin_001',
  patch: { seq: 2 },
});

5. 删除

bimEngine.emit('drawingPin:delete', { id: 'pin_001' });

6. 监听变更并持久化

bimEngine.on('drawingPin:list-updated', ({ records }) => {
  console.log('图钉列表已更新:', records);
  // 同步到后端或 localStorage
  localStorage.setItem('drawingPins', JSON.stringify(records));
});

7. 完整对接示例(初始化 + 双向同步)

const engineComp = bimEngine.engine?.getEngineComponent();

// 1. 监听变更,持久化到后端
bimEngine.on('drawingPin:list-updated', ({ records }) => {
  fetch('/api/save-pins', {
    method: 'POST',
    body: JSON.stringify(records),
  });
});

// 2. 模型加载完成后,从后端恢复图钉配置
bimEngine.on('engine:model-loading-completed', () => {
  fetch('/api/get-pins')
    .then((res) => res.json())
    .then((records: DrawingPinRecord[]) => {
      engineComp?.setPinRecords(records);
    });
});

// 3. 业务层提供"添加图钉"按钮
function onAddPinClick() {
  // 外部系统自行生成视角数据
  const viewData = { /* 外部系统生成的视角数据 */ };

  const record: DrawingPinRecord = {
    id: `pin_${Date.now()}`,
    parentId: null,
    name: '新视角',
    type: 'pin',
    seq: 0,
    data: viewData,
  };
  bimEngine.emit('drawingPin:create', { record });
}