Files
bim_engine/docs/SDK使用指南.md
yuding 8d027419e4 docs: 文档中文化重命名并添加规范文档
- 将所有英文文档重命名为中文格式
- 新增 AI代码规范模板.md(通用开发规范)
- 新增 国际化实现指南.md(i18n 规范)
- 重复文档移至 .recycle 目录
2026-01-21 10:59:23 +08:00

823 lines
19 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# BIM Engine SDK 使用文档
BIM Engine SDK 是一个用于 3D BIM 模型展示的 JavaScript SDK支持原生 HTML、Vue 2/3 和 React 框架。
## 目录
- [安装](#安装)
- [原生 HTML 使用](#原生-html-使用)
- [Vue 3 使用](#vue-3-使用)
- [Vue 2 使用](#vue-2-使用)
- [React 使用](#react-使用)
- [API 参考](#api-参考)
- [类型定义](#类型定义)
---
## 安装
### NPM 安装(推荐)
```bash
npm install @fishdingding/bim-engine-sdk
```
### Yarn 安装
```bash
yarn add @fishdingding/bim-engine-sdk
```
### PNPM 安装
```bash
pnpm add @fishdingding/bim-engine-sdk
```
### CDN / 本地文件引入
如果不使用包管理器,可以直接下载 JS 文件引入:
```html
<script src="./lib/bim-engine-sdk.umd.js"></script>
```
---
## 原生 HTML 使用
### 方式一:使用 NPM + 构建工具
```html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>BIM Engine Demo</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
html, body { width: 100%; height: 100%; overflow: hidden; }
#app { width: 100%; height: 100%; }
</style>
</head>
<body>
<div id="app"></div>
<script type="module">
import { BimEngine } from '@fishdingding/bim-engine-sdk';
// 1. 创建引擎实例
const engine = new BimEngine('app', {
locale: 'zh-CN',
theme: 'light'
});
// 2. 初始化 3D 引擎
const success = engine.engine.initialize({
version: 'v2',
showStats: false,
showViewCube: true
});
if (success) {
// 3. 加载模型
engine.engine.loadModel('./model/your-model', {
position: [0, 0, 0],
rotation: [0, 0, 0],
scale: [1, 1, 1]
});
}
</script>
</body>
</html>
```
### 方式二:使用 UMD无构建工具
```html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>BIM Engine Demo</title>
<!-- 引入 UMD 版本 -->
<script src="https://unpkg.com/@fishdingding/bim-engine-sdk/dist/bim-engine-sdk.umd.js"></script>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
html, body { width: 100%; height: 100%; overflow: hidden; }
#app { width: 100%; height: 100%; }
</style>
</head>
<body>
<div id="app"></div>
<script>
// 1. 创建引擎实例
const engine = new LyzBimEngineSDK.BimEngine('app', {
locale: 'zh-CN',
theme: 'light'
});
// 2. 初始化 3D 引擎
const success = engine.engine.initialize({
version: 'v2',
showStats: false,
showViewCube: true
});
if (success) {
// 3. 加载模型
engine.engine.loadModel('./model/your-model', {
position: [0, 0, 0],
rotation: [0, 0, 0],
scale: [1, 1, 1]
});
}
</script>
</body>
</html>
```
### 完整功能示例
```javascript
let engine = null;
// 初始化
function init() {
engine = new LyzBimEngineSDK.BimEngine('app', {
locale: 'zh-CN',
theme: 'light'
});
engine.engine.initialize({
version: 'v2',
showStats: false,
showViewCube: true
});
engine.engine.loadModel('./model/building');
}
// 回到主视角
function goHome() {
engine.engine.CameraGoHome();
}
// 激活测量功能
// mode: 'distance' | 'minDistance' | 'angle' | 'elevation' | 'volume' | 'laserDistance' | 'slope' | 'spaceVolume'
function activateMeasure(mode) {
engine.engine.activateMeasure(mode);
}
// 停用测量
function deactivateMeasure() {
engine.engine.deactivateMeasure();
}
// 切换主题
function setTheme(theme) {
engine.setTheme(theme); // 'light' | 'dark'
}
// 切换语言
function setLocale(locale) {
engine.setLocale(locale); // 'zh-CN' | 'en-US'
}
// 销毁
function destroy() {
engine.destroy();
}
window.onload = init;
```
---
## Vue 3 使用
### 1. 安装
```bash
npm install @fishdingding/bim-engine-sdk
```
### 2. 组件封装
```vue
<!-- components/BimViewer.vue -->
<template>
<div ref="containerRef" class="bim-viewer"></div>
</template>
<script setup>
import { ref, onMounted, onBeforeUnmount } from 'vue';
import { BimEngine } from '@fishdingding/bim-engine-sdk';
// Props
const props = defineProps({
modelUrl: { type: String, default: '' },
modelOptions: { type: Object, default: () => ({}) },
engineOptions: { type: Object, default: () => ({}) },
locale: { type: String, default: 'zh-CN' },
theme: { type: String, default: 'light' }
});
// Emits
const emit = defineEmits(['ready', 'error']);
// Refs
const containerRef = ref(null);
let engine = null;
// 初始化引擎
const initEngine = () => {
if (!containerRef.value) return;
try {
engine = new BimEngine(containerRef.value, {
locale: props.locale,
theme: props.theme
});
const success = engine.engine?.initialize({
version: 'v2',
showStats: false,
showViewCube: true,
...props.engineOptions
});
if (success) {
emit('ready', engine);
if (props.modelUrl) {
engine.engine?.loadModel(props.modelUrl, props.modelOptions);
}
} else {
throw new Error('3D 引擎初始化失败');
}
} catch (error) {
emit('error', error);
}
};
// 暴露方法
defineExpose({
getEngine: () => engine,
loadModel: (url, options) => engine?.engine?.loadModel(url, options),
goHome: () => engine?.engine?.CameraGoHome(),
activateMeasure: (mode) => engine?.engine?.activateMeasure(mode),
deactivateMeasure: () => engine?.engine?.deactivateMeasure(),
setTheme: (theme) => engine?.setTheme(theme),
setLocale: (locale) => engine?.setLocale(locale)
});
onMounted(() => initEngine());
onBeforeUnmount(() => {
engine?.destroy();
engine = null;
});
</script>
<style scoped>
.bim-viewer {
width: 100%;
height: 100%;
}
</style>
```
### 3. 使用组件
```vue
<!-- App.vue -->
<template>
<div class="app">
<BimViewer
ref="viewerRef"
model-url="./model/building"
:model-options="{ position: [0, 0, 0] }"
locale="zh-CN"
theme="light"
@ready="onEngineReady"
@error="onEngineError"
/>
<div class="toolbar">
<button @click="goHome">主视角</button>
<button @click="measure('distance')">距离测量</button>
<button @click="stopMeasure">停止测量</button>
</div>
</div>
</template>
<script setup>
import { ref } from 'vue';
import BimViewer from './components/BimViewer.vue';
const viewerRef = ref(null);
const onEngineReady = (engine) => {
console.log('引擎已就绪', engine);
};
const onEngineError = (error) => {
console.error('引擎错误', error);
};
const goHome = () => viewerRef.value?.goHome();
const measure = (mode) => viewerRef.value?.activateMeasure(mode);
const stopMeasure = () => viewerRef.value?.deactivateMeasure();
</script>
<style>
.app {
width: 100vw;
height: 100vh;
position: relative;
}
.toolbar {
position: absolute;
top: 20px;
left: 20px;
z-index: 100;
}
</style>
```
---
## Vue 2 使用
### 1. 安装
```bash
npm install @fishdingding/bim-engine-sdk
```
### 2. 组件封装
```vue
<!-- components/BimViewer.vue -->
<template>
<div ref="container" class="bim-viewer"></div>
</template>
<script>
import { BimEngine } from '@fishdingding/bim-engine-sdk';
export default {
name: 'BimViewer',
props: {
modelUrl: { type: String, default: '' },
modelOptions: { type: Object, default: () => ({}) },
engineOptions: { type: Object, default: () => ({}) },
locale: { type: String, default: 'zh-CN' },
theme: { type: String, default: 'light' }
},
data() {
return {
engine: null
};
},
mounted() {
this.initEngine();
},
beforeDestroy() {
this.destroyEngine();
},
methods: {
initEngine() {
try {
this.engine = new BimEngine(this.$refs.container, {
locale: this.locale,
theme: this.theme
});
const success = this.engine.engine.initialize({
version: 'v2',
showStats: false,
showViewCube: true,
...this.engineOptions
});
if (success) {
this.$emit('ready', this.engine);
if (this.modelUrl) {
this.engine.engine.loadModel(this.modelUrl, this.modelOptions);
}
} else {
throw new Error('3D 引擎初始化失败');
}
} catch (error) {
this.$emit('error', error);
}
},
destroyEngine() {
if (this.engine) {
this.engine.destroy();
this.engine = null;
}
},
// 公开方法
getEngine() { return this.engine; },
loadModel(url, options) { this.engine?.engine?.loadModel(url, options); },
goHome() { this.engine?.engine?.CameraGoHome(); },
activateMeasure(mode) { this.engine?.engine?.activateMeasure(mode); },
deactivateMeasure() { this.engine?.engine?.deactivateMeasure(); },
setTheme(theme) { this.engine?.setTheme(theme); },
setLocale(locale) { this.engine?.setLocale(locale); }
}
};
</script>
<style scoped>
.bim-viewer {
width: 100%;
height: 100%;
}
</style>
```
### 3. 使用组件
```vue
<!-- App.vue -->
<template>
<div class="app">
<BimViewer
ref="viewer"
model-url="./model/building"
:model-options="{ position: [0, 0, 0] }"
locale="zh-CN"
theme="light"
@ready="onEngineReady"
@error="onEngineError"
/>
<div class="toolbar">
<button @click="goHome">主视角</button>
<button @click="measure('distance')">距离测量</button>
<button @click="stopMeasure">停止测量</button>
</div>
</div>
</template>
<script>
import BimViewer from './components/BimViewer.vue';
export default {
name: 'App',
components: { BimViewer },
methods: {
onEngineReady(engine) { console.log('引擎已就绪', engine); },
onEngineError(error) { console.error('引擎错误', error); },
goHome() { this.$refs.viewer.goHome(); },
measure(mode) { this.$refs.viewer.activateMeasure(mode); },
stopMeasure() { this.$refs.viewer.deactivateMeasure(); }
}
};
</script>
<style>
.app { width: 100vw; height: 100vh; position: relative; }
.toolbar { position: absolute; top: 20px; left: 20px; z-index: 100; }
</style>
```
---
## React 使用
### 1. 安装
```bash
npm install @fishdingding/bim-engine-sdk
```
### 2. Hook 封装
```jsx
// hooks/useBimEngine.js
import { useEffect, useRef, useState, useCallback } from 'react';
import { BimEngine } from '@fishdingding/bim-engine-sdk';
export function useBimEngine(options = {}) {
const containerRef = useRef(null);
const engineRef = useRef(null);
const [isReady, setIsReady] = useState(false);
const [error, setError] = useState(null);
useEffect(() => {
if (!containerRef.current) return;
try {
const engine = new BimEngine(containerRef.current, {
locale: options.locale || 'zh-CN',
theme: options.theme || 'light'
});
const success = engine.engine?.initialize({
version: 'v2',
showStats: false,
showViewCube: true,
...options.engineOptions
});
if (success) {
engineRef.current = engine;
setIsReady(true);
options.onReady?.(engine);
} else {
throw new Error('3D 引擎初始化失败');
}
} catch (err) {
setError(err);
options.onError?.(err);
}
return () => {
engineRef.current?.destroy();
engineRef.current = null;
setIsReady(false);
};
}, []);
const loadModel = useCallback((url, modelOptions) => {
engineRef.current?.engine?.loadModel(url, modelOptions);
}, []);
const goHome = useCallback(() => {
engineRef.current?.engine?.CameraGoHome();
}, []);
const activateMeasure = useCallback((mode) => {
engineRef.current?.engine?.activateMeasure(mode);
}, []);
const deactivateMeasure = useCallback(() => {
engineRef.current?.engine?.deactivateMeasure();
}, []);
const setTheme = useCallback((theme) => {
engineRef.current?.setTheme(theme);
}, []);
const setLocale = useCallback((locale) => {
engineRef.current?.setLocale(locale);
}, []);
return {
containerRef,
engine: engineRef.current,
isReady,
error,
loadModel,
goHome,
activateMeasure,
deactivateMeasure,
setTheme,
setLocale
};
}
```
### 3. 组件封装
```jsx
// components/BimViewer.jsx
import React, { useEffect, useImperativeHandle, forwardRef } from 'react';
import { useBimEngine } from '../hooks/useBimEngine';
export const BimViewer = forwardRef((props, ref) => {
const {
modelUrl,
modelOptions,
locale = 'zh-CN',
theme = 'light',
className,
style,
onReady,
onError
} = props;
const {
containerRef,
engine,
isReady,
loadModel,
goHome,
activateMeasure,
deactivateMeasure,
setTheme,
setLocale
} = useBimEngine({ locale, theme, onReady, onError });
useImperativeHandle(ref, () => ({
getEngine: () => engine,
loadModel,
goHome,
activateMeasure,
deactivateMeasure,
setTheme,
setLocale
}));
useEffect(() => {
if (isReady && modelUrl) {
loadModel(modelUrl, modelOptions);
}
}, [isReady, modelUrl, modelOptions, loadModel]);
return (
<div
ref={containerRef}
className={className}
style={{ width: '100%', height: '100%', ...style }}
/>
);
});
BimViewer.displayName = 'BimViewer';
```
### 4. 使用组件
```jsx
// App.jsx
import React, { useRef } from 'react';
import { BimViewer } from './components/BimViewer';
function App() {
const viewerRef = useRef(null);
const handleReady = (engine) => console.log('引擎已就绪', engine);
const handleError = (error) => console.error('引擎错误', error);
return (
<div style={{ width: '100vw', height: '100vh', position: 'relative' }}>
<BimViewer
ref={viewerRef}
modelUrl="./model/building"
modelOptions={{ position: [0, 0, 0] }}
locale="zh-CN"
theme="light"
onReady={handleReady}
onError={handleError}
/>
<div style={{ position: 'absolute', top: 20, left: 20, zIndex: 100 }}>
<button onClick={() => viewerRef.current?.goHome()}>主视角</button>
<button onClick={() => viewerRef.current?.activateMeasure('distance')}>距离测量</button>
<button onClick={() => viewerRef.current?.deactivateMeasure()}>停止测量</button>
</div>
</div>
);
}
export default App;
```
---
## API 参考
### BimEngine
主引擎类。
#### 构造函数
```javascript
import { BimEngine } from '@fishdingding/bim-engine-sdk';
new BimEngine(container, options)
```
| 参数 | 类型 | 说明 |
|------|------|------|
| container | HTMLElement \| string | 容器元素或容器 ID |
| options.locale | string | 语言:'zh-CN' \| 'en-US',默认 'zh-CN' |
| options.theme | string | 主题:'light' \| 'dark',默认 'light' |
#### 属性
| 属性 | 类型 | 说明 |
|------|------|------|
| engine | EngineManager | 3D 引擎管理器 |
| toolbar | ToolbarManager | 工具栏管理器 |
| dialog | DialogManager | 弹窗管理器 |
| measure | MeasureDialogManager | 测量面板管理器 |
#### 方法
| 方法 | 参数 | 说明 |
|------|------|------|
| setLocale(locale) | 'zh-CN' \| 'en-US' | 设置语言 |
| getLocale() | - | 获取当前语言 |
| setTheme(theme) | 'light' \| 'dark' | 设置主题 |
| destroy() | - | 销毁引擎 |
---
### EngineManager
3D 引擎管理器,通过 `engine.engine` 访问。
#### 方法
| 方法 | 参数 | 返回值 | 说明 |
|------|------|--------|------|
| initialize(options) | EngineOptions | boolean | 初始化 3D 引擎 |
| isInitialized() | - | boolean | 检查是否已初始化 |
| loadModel(url, options) | string, ModelLoadOptions | void | 加载模型 |
| CameraGoHome() | - | void | 回到主视角 |
| activateMeasure(mode) | MeasureMode | void | 激活测量功能 |
| deactivateMeasure() | - | void | 停用测量功能 |
| getCurrentMeasureType() | - | MeasureMode \| null | 获取当前测量类型 |
| getEngine() | - | any | 获取原始引擎实例 |
| destroy() | - | void | 销毁引擎 |
---
## 类型定义
### EngineOptions
```typescript
interface EngineOptions {
version?: 'v1' | 'v2'; // WebGL 版本,默认 'v2'
showStats?: boolean; // 是否显示性能统计,默认 false
showViewCube?: boolean; // 是否显示视图立方体,默认 true
}
```
### ModelLoadOptions
```typescript
interface ModelLoadOptions {
position?: [number, number, number]; // 位置,默认 [0, 0, 0]
rotation?: [number, number, number]; // 旋转(弧度),默认 [0, 0, 0]
scale?: [number, number, number]; // 缩放,默认 [1, 1, 1]
id?: string; // 模型 ID可选
}
```
### MeasureMode
```typescript
type MeasureMode =
| 'distance' // 距离测量
| 'minDistance' // 最小距离测量
| 'angle' // 角度测量
| 'elevation' // 标高测量
| 'volume' // 体积测量
| 'laserDistance' // 激光测距
| 'slope' // 坡度测量
| 'spaceVolume'; // 空间体积测量
```
---
## 注意事项
1. **容器尺寸**:确保容器元素有明确的宽度和高度
2. **销毁清理**:页面关闭或组件卸载前务必调用 `destroy()`
3. **浏览器兼容**:需要支持 WebGL 的现代浏览器
---
## 常见问题
### Q: 模型加载失败?
检查:
- 模型路径是否正确
- 网络请求是否正常F12 查看 Network
- 模型格式是否支持
### Q: 如何监听引擎事件?
```javascript
engine.on('modelLoaded', (data) => {
console.log('模型已加载', data);
});
```
---
## 技术支持
- NPM 包地址https://www.npmjs.com/package/@fishdingding/bim-engine-sdk
- 如有问题,请联系技术支持