diff --git a/docs/SDK_USAGE.md b/docs/SDK_USAGE.md new file mode 100644 index 0000000..70ea086 --- /dev/null +++ b/docs/SDK_USAGE.md @@ -0,0 +1,984 @@ +# 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 bim-engine-sdk +``` + +### CDN / 本地引入 + +```html + +``` + +--- + +## 原生 HTML 使用 + +### 基础示例 + +```html + + + + + + BIM Engine Demo + + + + + +
+ + + + +``` + +### 完整功能示例 + +```html + +``` + +--- + +## Vue 3 使用 + +### 安装依赖 + +```bash +npm install bim-engine-sdk +``` + +### 组件封装 + +```vue + + + + + + +``` + +### 使用组件 + +```vue + + + + + + +``` + +--- + +## Vue 2 使用 + +### 安装依赖 + +```bash +npm install bim-engine-sdk +``` + +### 组件封装 + +```vue + + + + + + +``` + +### 使用组件 + +```vue + + + + + + +``` + +--- + +## React 使用 + +### 安装依赖 + +```bash +npm install bim-engine-sdk +``` + +### Hook 封装 + +```tsx +// hooks/useBimEngine.ts +import { useEffect, useRef, useState, useCallback } from 'react'; +import { BimEngine } from 'bim-engine-sdk'; +import type { EngineOptions, ModelLoadOptions } from 'bim-engine-sdk'; + +type MeasureMode = 'distance' | 'minDistance' | 'angle' | 'elevation' | 'volume' | 'laserDistance' | 'slope' | 'spaceVolume'; + +interface UseBimEngineOptions { + locale?: 'zh-CN' | 'en-US'; + theme?: 'light' | 'dark'; + engineOptions?: Omit; + onReady?: (engine: BimEngine) => void; + onError?: (error: Error) => void; +} + +export function useBimEngine(options: UseBimEngineOptions = {}) { + 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' + }); + + // 初始化 3D 引擎 + 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) { + const error = err as Error; + setError(error); + options.onError?.(error); + } + + // 清理 + return () => { + engineRef.current?.destroy(); + engineRef.current = null; + setIsReady(false); + }; + }, []); + + // 加载模型 + const loadModel = useCallback((url: string, modelOptions?: ModelLoadOptions) => { + engineRef.current?.engine?.loadModel(url, modelOptions); + }, []); + + // 回到主视角 + const goHome = useCallback(() => { + engineRef.current?.engine?.CameraGoHome(); + }, []); + + // 激活测量 + const activateMeasure = useCallback((mode: MeasureMode) => { + engineRef.current?.engine?.activateMeasure(mode); + }, []); + + // 停用测量 + const deactivateMeasure = useCallback(() => { + engineRef.current?.engine?.deactivateMeasure(); + }, []); + + // 切换主题 + const setTheme = useCallback((theme: 'light' | 'dark') => { + engineRef.current?.setTheme(theme); + }, []); + + // 切换语言 + const setLocale = useCallback((locale: 'zh-CN' | 'en-US') => { + engineRef.current?.setLocale(locale); + }, []); + + return { + containerRef, + engine: engineRef.current, + isReady, + error, + loadModel, + goHome, + activateMeasure, + deactivateMeasure, + setTheme, + setLocale + }; +} +``` + +### 组件封装 + +```tsx +// components/BimViewer.tsx +import React, { useEffect } from 'react'; +import { useBimEngine } from '../hooks/useBimEngine'; +import type { ModelLoadOptions } from 'bim-engine-sdk'; + +interface BimViewerProps { + modelUrl?: string; + modelOptions?: ModelLoadOptions; + locale?: 'zh-CN' | 'en-US'; + theme?: 'light' | 'dark'; + className?: string; + style?: React.CSSProperties; + onReady?: (engine: any) => void; + onError?: (error: Error) => void; +} + +export const BimViewer = React.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 + }); + + // 暴露方法给父组件 + React.useImperativeHandle(ref, () => ({ + getEngine: () => engine, + loadModel, + goHome, + activateMeasure, + deactivateMeasure, + setTheme, + setLocale + })); + + // 加载模型 + useEffect(() => { + if (isReady && modelUrl) { + loadModel(modelUrl, modelOptions); + } + }, [isReady, modelUrl, modelOptions, loadModel]); + + return ( +
+ ); +}); + +BimViewer.displayName = 'BimViewer'; +``` + +### 使用组件 + +```tsx +// App.tsx +import React, { useRef } from 'react'; +import { BimViewer } from './components/BimViewer'; + +function App() { + const viewerRef = useRef(null); + + const handleReady = (engine: any) => { + console.log('引擎已就绪', engine); + }; + + const handleError = (error: Error) => { + console.error('引擎错误', error); + }; + + const goHome = () => { + viewerRef.current?.goHome(); + }; + + const measure = (mode: string) => { + viewerRef.current?.activateMeasure(mode); + }; + + const stopMeasure = () => { + viewerRef.current?.deactivateMeasure(); + }; + + return ( +
+ + +
+ + + +
+
+ ); +} + +export default App; +``` + +--- + +## API 参考 + +### BimEngine + +主引擎类,用于创建和管理 BIM 引擎实例。 + +#### 构造函数 + +```typescript +new BimEngine(container: HTMLElement | string, options?: { + locale?: 'zh-CN' | 'en-US'; + theme?: 'light' | 'dark'; +}) +``` + +| 参数 | 类型 | 说明 | +|------|------|------| +| container | HTMLElement \| string | 容器元素或容器 ID | +| options.locale | string | 语言设置,默认 'zh-CN' | +| options.theme | string | 主题设置,默认 'light' | + +#### 属性 + +| 属性 | 类型 | 说明 | +|------|------|------| +| engine | EngineManager | 3D 引擎管理器 | +| toolbar | ToolbarManager | 工具栏管理器 | +| dialog | DialogManager | 弹窗管理器 | +| measure | MeasureDialogManager | 测量面板管理器 | + +#### 方法 + +| 方法 | 参数 | 返回值 | 说明 | +|------|------|--------|------| +| setLocale | locale: 'zh-CN' \| 'en-US' | void | 设置语言 | +| getLocale | - | string | 获取当前语言 | +| setTheme | theme: 'light' \| 'dark' | void | 设置主题 | +| setCustomTheme | theme: ThemeConfig | void | 设置自定义主题 | +| destroy | - | void | 销毁引擎 | + +--- + +### EngineManager + +3D 引擎管理器,通过 `engine.engine` 访问。 + +#### 方法 + +| 方法 | 参数 | 返回值 | 说明 | +|------|------|--------|------| +| initialize | options?: EngineOptions | boolean | 初始化 3D 引擎 | +| isInitialized | - | boolean | 检查是否已初始化 | +| loadModel | url: string, options?: ModelLoadOptions | void | 加载模型 | +| CameraGoHome | - | void | 回到主视角 | +| activateMeasure | mode: MeasureMode | void | 激活测量功能 | +| deactivateMeasure | - | void | 停用测量功能 | +| getCurrentMeasureType | - | MeasureMode \| null | 获取当前测量类型 | +| getEngine | - | any | 获取原始引擎实例 | +| destroy | - | void | 销毁引擎 | + +--- + +## 类型定义 + +### EngineOptions + +```typescript +interface EngineOptions { + container: HTMLElement; // 容器元素 + backgroundColor?: number | string; // 背景色 + version?: 'v1' | 'v2'; // WebGL 版本 + showStats?: boolean; // 是否显示性能统计 + showViewCube?: boolean; // 是否显示视图立方体 +} +``` + +### ModelLoadOptions + +```typescript +interface ModelLoadOptions { + position?: [number, number, number]; // 位置 [x, y, z] + rotation?: [number, number, number]; // 旋转 [x, y, z](弧度) + scale?: [number, number, number]; // 缩放 [x, y, z] + id?: string; // 模型 ID +} +``` + +### MeasureMode + +```typescript +type MeasureMode = + | 'distance' // 距离测量 + | 'minDistance' // 最小距离测量 + | 'angle' // 角度测量 + | 'elevation' // 标高测量 + | 'volume' // 体积测量 + | 'laserDistance' // 激光测距 + | 'slope' // 坡度测量 + | 'spaceVolume'; // 空间体积测量 +``` + +--- + +## 注意事项 + +1. **容器尺寸**:确保容器元素有明确的宽度和高度,否则 3D 引擎可能无法正常渲染。 + +2. **模型路径**:模型路径应为相对于 HTML 页面的路径,或者完整的 URL。 + +3. **销毁清理**:在组件卸载或页面关闭前,务必调用 `destroy()` 方法释放资源。 + +4. **浏览器兼容性**:SDK 需要浏览器支持 WebGL。建议使用现代浏览器(Chrome、Firefox、Safari、Edge)。 + +5. **静态资源**:确保 Draco 解码器等静态资源正确部署: + ``` + /static/js/draco/ + ├── DRACOLoader.js + ├── draco_decoder.js + ├── draco_decoder.wasm + ├── draco_encoder.js + └── draco_wasm_wrapper.js + ``` + +--- + +## 常见问题 + +### Q: 模型加载失败怎么办? + +A: 检查以下几点: +- 模型路径是否正确 +- 模型格式是否支持 +- 网络请求是否正常(F12 查看 Network) +- Draco 解码器是否正确部署 + +### Q: 如何自定义主题? + +A: 使用 `setCustomTheme` 方法: + +```javascript +engine.setCustomTheme({ + background: '#1a1a2e', + textPrimary: '#ffffff', + textSecondary: '#cccccc', + // ... 更多配置 +}); +``` + +### Q: 如何监听引擎事件? + +A: 使用 `on` 方法监听事件: + +```javascript +engine.on('modelLoaded', (data) => { + console.log('模型已加载', data); +}); +``` + +--- + +## 技术支持 + +如有问题,请联系技术支持或提交 Issue。